cscope.out
.DS_Store
xcuserdata
+._*
+build
--- /dev/null
+#ifndef LocalKeychainAnalytics_h
+#define LocalKeychainAnalytics_h
+
+#include <CoreFoundation/CoreFoundation.h>
+
+typedef enum {
+ LKAKeychainUpgradeOutcomeSuccess,
+ LKAKeychainUpgradeOutcomeUnknownFailure,
+ LKAKeychainUpgradeOutcomeLocked,
+ LKAKeychainUpgradeOutcomeInternal,
+ LKAKeychainUpgradeOutcomeNewDb,
+ LKAKeychainUpgradeOutcomeObsoleteDb,
+ LKAKeychainUpgradeOutcomeNoSchema,
+ LKAKeychainUpgradeOutcomeIndices,
+ LKAKeychainUpgradeOutcomePhase1AlterTables,
+ LKAKeychainUpgradeOutcomePhase1DropIndices,
+ LKAKeychainUpgradeOutcomePhase1CreateSchema,
+ LKAKeychainUpgradeOutcomePhase1Items,
+ LKAKeychainUpgradeOutcomePhase1NonItems,
+ LKAKeychainUpgradeOutcomePhase1DropOld,
+ LKAKeychainUpgradeOutcomePhase2,
+} LKAKeychainUpgradeOutcome;
+
+void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome);
+void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error);
+
+#if __OBJC2__
+
+#import <Foundation/Foundation.h>
+#import <Security/SFAnalytics.h>
+
+typedef NSString* LKAnalyticsFailableEvent NS_STRING_ENUM;
+extern LKAnalyticsFailableEvent const LKAEventUpgrade;
+
+@interface LocalKeychainAnalytics : SFAnalytics
+
+- (void)reportKeychainUpgradeFrom:(int)oldVersion to:(int)newVersion outcome:(LKAKeychainUpgradeOutcome)result error:(NSError*)error;
+
+@end
+
+#endif // OBJC2
+#endif // LocalKeychainAnalytics_h
--- /dev/null
+#include "LocalKeychainAnalytics.h"
+
+#if __OBJC2__
+
+#import "Security/SFAnalyticsDefines.h"
+
+#include <sys/stat.h>
+#include <notify.h>
+
+#include <utilities/SecFileLocations.h>
+#include <utilities/SecAKSWrappers.h>
+
+@interface LKAUpgradeOutcomeReport : NSObject
+@property LKAKeychainUpgradeOutcome outcome;
+@property NSDictionary* attributes;
+- (instancetype) initWithOutcome:(LKAKeychainUpgradeOutcome)outcome attributes:(NSDictionary*)attributes;
+@end
+
+@implementation LKAUpgradeOutcomeReport
+- (instancetype) initWithOutcome:(LKAKeychainUpgradeOutcome)outcome attributes:(NSDictionary*)attributes {
+ if (self = [super init]) {
+ self.outcome = outcome;
+ self.attributes = attributes;
+ }
+ return self;
+}
+@end
+
+// Public consts
+// rdar://problem/41745059 SFAnalytics: collect keychain upgrade outcome information
+LKAnalyticsFailableEvent const LKAEventUpgrade = (LKAnalyticsFailableEvent)@"LKAEventUpgrade";
+
+// Internal consts
+NSString* const LKAOldSchemaKey = @"oldschema";
+NSString* const LKANewSchemaKey = @"newschema";
+NSString* const LKAUpgradeOutcomeKey = @"upgradeoutcome";
+
+@implementation LocalKeychainAnalytics {
+ BOOL _probablyInClassD;
+ NSMutableArray<LKAUpgradeOutcomeReport*>* _pendingReports;
+ dispatch_queue_t _queue;
+ int _notificationToken;
+}
+
+- (instancetype __nullable)init {
+ if (self = [super init]) {
+ _probablyInClassD = YES;
+ _pendingReports = [NSMutableArray<LKAUpgradeOutcomeReport*> new];
+ _queue = dispatch_queue_create("LKADataQueue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+ _notificationToken = NOTIFY_TOKEN_INVALID;
+ }
+ return self;
+}
+
++ (NSString*)databasePath {
+ return [self defaultAnalyticsDatabasePath:@"localkeychain"];
+}
+
+// MARK: Client-specific functionality
+
+- (BOOL)canPersistMetrics {
+ @synchronized(self) {
+ if (!_probablyInClassD) {
+ return YES;
+ }
+ }
+
+ // If this gets busy we should start caching if AKS tells us no
+ bool hasBeenUnlocked = false;
+ if (!SecAKSGetHasBeenUnlocked(&hasBeenUnlocked, NULL) || !hasBeenUnlocked) {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ notify_register_dispatch(kUserKeybagStateChangeNotification, &self->_notificationToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) {
+ // For side effect of processing pending messages if out of class D
+ [self canPersistMetrics];
+ });
+ });
+ return NO;
+ }
+
+ @synchronized(self) {
+ _probablyInClassD = NO;
+ if (_notificationToken != NOTIFY_TOKEN_INVALID) {
+ notify_cancel(_notificationToken);
+ }
+ }
+
+ [self processPendingMessages];
+ return YES;
+}
+
+- (void)processPendingMessages {
+ dispatch_async(_queue, ^{
+ for (LKAUpgradeOutcomeReport* report in self->_pendingReports) {
+ [self reportKeychainUpgradeOutcome:report.outcome attributes:report.attributes];
+ }
+ });
+}
+
+- (void)reportKeychainUpgradeFrom:(int)oldVersion to:(int)newVersion outcome:(LKAKeychainUpgradeOutcome)outcome error:(NSError*)error {
+
+ NSMutableDictionary* attributes = [@{LKAOldSchemaKey : @(oldVersion),
+ LKANewSchemaKey : @(newVersion),
+ LKAUpgradeOutcomeKey : @(outcome),
+ } mutableCopy];
+ if (error) {
+ [attributes addEntriesFromDictionary:@{SFAnalyticsAttributeErrorDomain : error.domain,
+ SFAnalyticsAttributeErrorCode : @(error.code)}];
+ }
+
+ if (![self canPersistMetrics]) {
+ dispatch_async(_queue, ^{
+ [self->_pendingReports addObject:[[LKAUpgradeOutcomeReport alloc] initWithOutcome:outcome attributes:attributes]];
+ });
+ } else {
+ [self reportKeychainUpgradeOutcome:outcome attributes:attributes];
+ }
+}
+
+- (void)reportKeychainUpgradeOutcome:(LKAKeychainUpgradeOutcome)outcome attributes:(NSDictionary*)attributes {
+ if (outcome == LKAKeychainUpgradeOutcomeSuccess) {
+ [self logSuccessForEventNamed:LKAEventUpgrade];
+ } else {
+ // I could try and pick out the recoverable errors but I think we're good treating these all the same
+ [self logHardFailureForEventNamed:LKAEventUpgrade withAttributes:attributes];
+ }
+}
+
+@end
+
+// MARK: C Bridging
+
+void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome) {
+ [[LocalKeychainAnalytics logger] reportKeychainUpgradeFrom:fromversion to:toversion outcome:outcome error:NULL];
+}
+
+void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error) {
+ [[LocalKeychainAnalytics logger] reportKeychainUpgradeFrom:fromversion to:toversion outcome:outcome error:(__bridge NSError*)error];
+}
+
+#else // not __OBJC2__
+
+void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome) {
+ // nothing to do on 32 bit
+}
+
+void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error) {
+ // nothing to do on 32 bit
+}
+
+#endif // __OBJC2__
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];
+ return [SOSAnalytics defaultAnalyticsDatabasePath:@"sos_analytics"];
}
+ (instancetype)logger
--- /dev/null
+/*
+ * 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 SFAnalytics_Internal_h
+#define SFAnalytics_Internal_h
+
+#if __OBJC2__
+
+#import "SFAnalytics.h"
+#import "SFAnalyticsSQLiteStore.h"
+@interface SFAnalytics (SignIn)
+/* Typical SFA clients do not need this. SignIn Metrics needs this */
+@property (nonatomic) SFAnalyticsSQLiteStore* database;
+/*queue from SFA exposed for testing only, this queue is used to protected db accesses and should NOT be used directly*/
+@property (nonatomic) dispatch_queue_t queue;
+@end
+
+#endif // objc2
+#endif /* SFAnalytics_Internal_h */
+
+ (NSInteger)fuzzyDaysSinceDate:(NSDate*)date;
+ (void)addOSVersionToEvent:(NSMutableDictionary*)event;
+// Help for the subclass to pick a prefered location
++ (NSString *)defaultAnalyticsDatabasePath:(NSString *)basename;
// 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
#import "SFAnalyticsMultiSampler+Internal.h"
#import "SFAnalyticsSQLiteStore.h"
#import "utilities/debugging.h"
+#import <utilities/SecFileLocations.h>
#import <objc/runtime.h>
+#import <sys/stat.h>
#import <CoreFoundation/CFPriv.h>
// SFAnalyticsDefines constants
NSUInteger const SFAnalyticsMaxEventsToReport = 1000;
+NSString* const SFAnalyticsErrorDomain = @"com.apple.security.sfanalytics";
+
// Local constants
NSString* const SFAnalyticsEventBuild = @"build";
NSString* const SFAnalyticsEventProduct = @"product";
@interface SFAnalytics ()
@property (nonatomic) SFAnalyticsSQLiteStore* database;
+@property (nonatomic) dispatch_queue_t queue;
@end
@implementation SFAnalytics {
return nil;
}
++ (NSString *)defaultAnalyticsDatabasePath:(NSString *)basename
+{
+ 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);
+ });
+ NSString *path = [NSString stringWithFormat:@"Analytics/%@.db", basename];
+ return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)path) path];
+}
+
+ (NSInteger)fuzzyDaysSinceDate:(NSDate*)date
{
// Sentinel: it didn't happen at all
{
if (!_database) {
_database = [SFAnalyticsSQLiteStore storeWithPath:self.class.databasePath schema:SFAnalyticsTableSchema];
+ if (!_database) {
+ seccritical("Did not get a database! (Client %@)", NSStringFromClass([self class]));
+ }
}
return _database;
}
}
__weak __typeof(self) weakSelf = self;
- dispatch_sync(_queue, ^{
+ dispatch_async(_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
}
__weak __typeof(self) weakSelf = self;
- dispatch_sync(_queue, ^{
+ dispatch_async(_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
return nil;
}
SFAnalyticsActivityTracker* tracker = [[SFAnalyticsActivityTracker alloc] initWithName:eventName clientClass:[self class]];
- if (action)
+ if (action) {
[tracker performAction:action];
+ }
return tracker;
}
}
__weak __typeof(self) weakSelf = self;
- dispatch_sync(_queue, ^{
+ dispatch_async(_queue, ^{
__strong __typeof(self) strongSelf = weakSelf;
if (strongSelf && !strongSelf->_disableLogging) {
if (once) {
}
if (self = [super init]) {
- _queue = dispatch_queue_create("SFAnalyticsActivityTracker queue", DISPATCH_QUEUE_SERIAL);
+ _queue = dispatch_queue_create("SFAnalyticsActivityTracker queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
_name = name;
_clientClass = className;
_measurement = nil;
- (void)performAction:(void (^)(void))action
{
- _start = mach_absolute_time();
- action();
+ [self start];
+ dispatch_sync(_queue, ^{
+ action();
+ });
[self stop];
}
- (void)start
{
- if (_canceled)
+ if (_canceled) {
return;
+ }
NSAssert(_start == 0, @"SFAnalyticsActivityTracker user called start twice");
_start = mach_absolute_time();
}
- (void)stop
{
uint64_t end = mach_absolute_time();
+
+ if (_canceled) {
+ _start = 0;
+ return;
+ }
+ NSAssert(_start != 0, @"SFAnalyticsActivityTracker user called stop w/o calling start");
+
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)dealloc
{
+ if (_start != 0) {
+ [self stop];
+ }
if (!_canceled && _measurement != nil) {
[[_clientClass logger] logMetric:_measurement withName:_name];
}
// We can only send this many events in total to splunk per upload
extern NSUInteger const SFAnalyticsMaxEventsToReport;
+extern NSString* const SFAnalyticsErrorDomain;
+
#endif /* __OBJC2__ */
#endif /* SFAnalyticsDefines_h */
+ (instancetype)storeWithPath:(NSString*)path schema:(NSString*)schema
{
+ if (![path length]) {
+ seccritical("Cannot init db with empty path");
+ return nil;
+ }
+ if (![schema length]) {
+ seccritical("Cannot init db without schema");
+ return nil;
+ }
+
SFAnalyticsSQLiteStore* store = nil;
@synchronized([SFAnalyticsSQLiteStore class]) {
static NSMutableDictionary* loggingStores = nil;
NSMutableDictionary* _unitTestOverrides;
#endif
BOOL _hasMigrated;
- BOOL _shouldVacuum;
BOOL _corrupt;
BOOL _traced;
}
@property (nonatomic, assign) SFSQLiteSynchronousMode synchronousMode;
@property (nonatomic, readonly) BOOL isOpen;
@property (nonatomic, readonly) BOOL hasMigrated;
-@property (nonatomic, assign) BOOL shouldVacuum; // vacuum the db on open (default:YES)
@property (nonatomic, assign) BOOL traced;
@property (nonatomic, strong) id<SFSQLiteDelegate> delegate;
#define kSFSQLiteBusyTimeout (5*60*1000)
-// Vaccuum our databases approximately once a week
-#define kCKSQLVacuumInterval ((60*60*24)*7)
-#define kSFSQLiteLastVacuumKey @"LastVacuum"
-
#define kSFSQLiteSchemaVersionKey @"SchemaVersion"
#define kSFSQLiteCreatedDateKey @"Created"
+#define kSFSQLiteAutoVacuumFull 1
static NSString *const kSFSQLiteCreatePropertiesTableSQL =
@"create table if not exists Properties (\n"
@synthesize userVersion = _userVersion;
@synthesize synchronousMode = _synchronousMode;
@synthesize hasMigrated = _hasMigrated;
-@synthesize shouldVacuum = _shouldVacuum;
@synthesize traced = _traced;
@synthesize db = _db;
@synthesize openCount = _openCount;
#endif
- (instancetype)initWithPath:(NSString *)path schema:(NSString *)schema {
+ if (![path length]) {
+ seccritical("Cannot init db with empty path");
+ return nil;
+ }
+ if (![schema length]) {
+ seccritical("Cannot init db without schema");
+ return nil;
+ }
+
if ((self = [super init])) {
- NSAssert([path length], @"Can't init a database with a zero-length path");
_path = path;
_schema = schema;
_schemaVersion = [self _createSchemaHash];
_objectClassPrefix = @"CK";
_synchronousMode = SFSQLiteSynchronousModeNormal;
_hasMigrated = NO;
- _shouldVacuum = YES;
}
return self;
}
return _db != NULL;
}
-- (void)_periodicVacuum {
- // "When the auto-vacuum mode is 1 or "full", the freelist pages are moved to the end of the database file and the database file is truncated to remove the freelist pages at every transaction commit.
- // Note, however, that auto-vacuum only truncates the freelist pages from the file. Auto-vacuum does not defragment the database nor repack individual database pages the way that the VACUUM command does.
- // In fact, because it moves pages around within the file, auto-vacuum can actually make fragmentation worse."
- // https://sqlite.org/pragma.html#pragma_auto_vacuum
- NSDate *lastVacuumDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[[self propertyForKey:kSFSQLiteLastVacuumKey] floatValue]];
- if ([lastVacuumDate timeIntervalSinceNow] < -(kCKSQLVacuumInterval)) {
- @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,
if (![self executeSQL:@"pragma synchronous = %@", [self _synchronousModeString]]) {
goto done;
}
- if (![self executeSQL:@"pragma auto_vacuum = FULL"]) {
- goto done;
+ if ([self autoVacuumSetting] != kSFSQLiteAutoVacuumFull) {
+ /* After changing the auto_vacuum setting the DB must be vacuumed */
+ if (![self executeSQL:@"pragma auto_vacuum = FULL"] || ![self executeSQL:@"VACUUM"]) {
+ goto done;
+ }
}
// rdar://problem/32168789
}
#endif
- if (self.shouldVacuum) [self _periodicVacuum];
-
if (create || _hasMigrated) {
[self setProperty:self.schemaVersion forKey:kSFSQLiteSchemaVersionKey];
if (self.userVersion) {
}
- (NSString *)propertyForKey:(NSString *)key {
- NSAssert(key, @"Null key");
+ if (![key length]) {
+ secerror("SFSQLite: attempt to retrieve property without a key");
+ return nil;
+ }
NSString *value = nil;
}
- (void)setProperty:(NSString *)value forKey:(NSString *)key {
- NSAssert(key, @"Null key");
+ if (![key length]) {
+ secerror("SFSQLite: attempt to set property without a key");
+ return;
+ }
if (value) {
SFSQLiteStatement *statement = [self statementForSQL:@"insert or replace into Properties (key, value) values (?,?)"];
}
- (void)removePropertyForKey:(NSString *)key {
- NSAssert(key, @"Null key");
+ if (![key length]) {
+ return;
+ }
SFSQLiteStatement *statement = [self statementForSQL:@"delete from Properties where key = ?"];
[statement bindText:key atIndex:0];
}
- (void)update:(NSString *)tableName set:(NSString *)setSQL where:(NSString *)whereSQL bindings:(NSArray *)whereBindings limit:(NSNumber *)limit {
+ if (![setSQL length]) {
+ return;
+ }
+
NSMutableString *SQL = [[NSMutableString alloc] init];
[SQL appendFormat:@"update %@", tableName];
-
- NSAssert(setSQL.length > 0, @"null set expression");
[SQL appendFormat:@" set %@", setSQL];
if (whereSQL.length) {
return userVersion;
}
+- (SInt32)autoVacuumSetting {
+ SInt32 vacuumMode = 0;
+ SFSQLiteStatement *statement = [self statementForSQL:@"pragma auto_vacuum"];
+ while ([statement step]) {
+ vacuumMode = [statement intAtIndex:0];
+ }
+ [statement reset];
+
+ return vacuumMode;
+}
+
@end
#endif
#import "NSURL+SOSPlistStore.h"
#include <Security/SecureObjectSync/SOSARCDefines.h>
+#include <Security/SecureObjectSync/SOSKVSKeys.h>
#include <utilities/SecCFWrappers.h>
#include <utilities/SecPLWrappers.h>
#import "XPCNotificationDispatcher.h"
-CFStringRef const CKDAggdIncreaseThrottlingKey = CFSTR("com.apple.cloudkeychainproxy.backoff.increase");
-CFStringRef const CKDAggdDecreaseThrottlingKey = CFSTR("com.apple.cloudkeychainproxy.backoff.decrease");
-
@interface NSSet (CKDLogging)
- (NSString*) logKeys;
- (NSString*) logIDs;
static NSString *kMonitorFourthMinute = @"DFourthMinute";
static NSString *kMonitorFifthMinute = @"EFifthMinute";
static NSString *kMonitorWroteInTimeSlice = @"TimeSlice";
-const CFStringRef kSOSKVSKeyParametersKey = CFSTR(">KeyParameters");
-const CFStringRef kSOSKVSInitialSyncKey = CFSTR("^InitialSync");
-const CFStringRef kSOSKVSAccountChangedKey = CFSTR("^AccountChanged");
-const CFStringRef kSOSKVSRequiredKey = CFSTR("^Required");
-const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID");
#define kSecServerKeychainChangedNotification "com.apple.security.keychainchanged"
<dict>
<key>ProcessType</key>
<string>Adaptive</string>
- <key>LimitLoadToSessionType</key>
- <string>Background</string>
<key>EnablePressuredExit</key>
<true/>
<key>ProgramArguments</key>
error:error] ? decrypted : nil;
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void) finalize {
if (self.send) {
ccgcm_ctx_clear(sizeof(*self.send), self.send);
}
[super finalize];
}
+#pragma clang diagnostic pop
@end
return self;
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void) finalize {
ccsrp_ctx_clear(ccsrp_ctx_di(self.context),
ccsrp_ctx_gp(self.context),
free(self.context);
}
+#pragma clang diagnostic pop
- (NSData*) getKey {
size_t key_length = 0;
/* for tests cases only */
- (void)setXPCConnectionObject:(NSXPCConnection *)connection;
++ (bool)isSupportedPlatform;
@end
if (size == 0)
return;
- uint8_t buffer[size];
+ NSMutableData *buffer = [NSMutableData dataWithLength:size];
error = nil;
- uint8_t* beginning = kcder_encode_data(data, &error, buffer, buffer + sizeof(buffer));
+ uint8_t* beginning = kcder_encode_data(data, &error, [buffer mutableBytes], [buffer mutableBytes] + size);
XCTAssert(beginning != NULL, "Error encoding: %@", error);
if (beginning == NULL)
return;
- XCTAssertEqual(beginning, &buffer[0], @"Size != buffer use");
+ XCTAssertEqual(beginning, [buffer mutableBytes], @"Size != buffer use");
NSData* recovered = nil;
error = nil;
- const uint8_t* end = kcder_decode_data(&recovered, &error, buffer, buffer + sizeof(buffer));
+ const uint8_t* end = kcder_decode_data(&recovered, &error, [buffer mutableBytes], [buffer mutableBytes] + size);
XCTAssert(end != NULL, "Error decoding: %@", error);
if (end == NULL)
return;
- XCTAssertEqual(end, buffer + sizeof(buffer), @"readback didn't use all the buffer");
+ XCTAssertEqual(end, [buffer mutableBytes] + size, @"readback didn't use all the buffer");
XCTAssertEqualObjects(data, recovered, @"Didn't get equal object");
if (size == 0)
return;
- uint8_t buffer[size];
+ NSMutableData *buffer = [NSMutableData dataWithLength:size];
error = nil;
- uint8_t* beginning = kcder_encode_string(string, &error, buffer, buffer + sizeof(buffer));
+ uint8_t* beginning = kcder_encode_string(string, &error, [buffer mutableBytes], [buffer mutableBytes] + size);
XCTAssert(beginning != NULL, "Error encoding: %@", error);
if (beginning == NULL)
return;
- XCTAssertEqual(beginning, &buffer[0], @"Size != buffer use");
+ XCTAssertEqual(beginning, [buffer mutableBytes], @"Size != buffer use");
NSString* recovered = nil;
error = nil;
- const uint8_t* end = kcder_decode_string(&recovered, &error, buffer, buffer + sizeof(buffer));
+ const uint8_t* end = kcder_decode_string(&recovered, &error, [buffer mutableBytes], [buffer mutableBytes] + size);
XCTAssert(end != NULL, "Error decoding: %@", error);
if (end == NULL)
return;
- XCTAssertEqual(end, buffer + sizeof(buffer), @"readback didn't use all the buffer");
+ XCTAssertEqual(end, [buffer mutableBytes] + size, @"readback didn't use all the buffer");
XCTAssertEqualObjects(string, recovered, @"Didn't get equal object");
{
complete(@{});
}
-- (void)idsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))complete
-{
- complete(@{});
-}
+
- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary <NSString *, NSString *> *))complete
{
complete(@{});
- (void)testSecPairBasicTest
{
+ if (![KCPairingChannel isSupportedPlatform]) {
+ return;
+ }
+
bool sp1compete = false, sp2compete = false;
NSData *sp1data = NULL;
NSData *sp2data = NULL;
#include <utilities/SecCFRelease.h>
#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
+#import "OT.h"
@implementation KeychainSyncAccountNotification
#endif
}
+// this is where we initialize SOS and OT for account sign-in
+// the complement to this logic where we turn off SOS and OT is in KeychainDataclassOwner
+// in the future we may bring this logic over there and delete KeychainSyncAccountNotification, but accounts people say that's a change that today would require coordination across multiple teams
+// was asked to file this radar for accounts: <rdar://problem/40176124> Invoke DataclassOwner when enabling or signing into an account
- (BOOL)account:(ACAccount *)account willChangeWithType:(ACAccountChangeType)changeType inStore:(ACDAccountStore *)store oldAccount:(ACAccount *)oldAccount {
- NSString* oldAccountIdentifier = oldAccount.identifier;
- NSString* accountIdentifier = account.identifier;
-
+
if((changeType == kACAccountChangeTypeAdded) &&
[account.accountType.identifier isEqualToString: ACAccountTypeIdentifierAppleAccount] &&
[self accountIsPrimary:account]) {
}
#endif
}
+
if ((changeType == kACAccountChangeTypeDeleted) && [oldAccount.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) {
- if(oldAccountIdentifier != NULL && oldAccount.username !=NULL) {
+
+ NSString *accountIdentifier = oldAccount.identifier;
+ NSString *username = oldAccount.username;
+
+ if(accountIdentifier != NULL && username !=NULL) {
if ([self accountIsPrimary:oldAccount]) {
CFErrorRef removalError = NULL;
-
- secinfo("accounts", "Performing SOS circle credential removal for account %@: %@", oldAccountIdentifier, oldAccount.username);
-
+
+ secinfo("accounts", "Performing SOS circle credential removal for account %@: %@", accountIdentifier, username);
+
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");
- }
- }
+ secerror("Account %@ could not leave the SOS circle: %@", accountIdentifier, removalError);
}
- else{
- secerror("Octagon not enabled!");
- }
-#endif
- } else {
- secinfo("accounts", "NOT performing SOS circle credential removal for secondary account %@: %@", accountIdentifier, account.username);
+
}
- } else{
- secinfo("accounts", "Already logged out of account");
}
}
+
return YES;
}
+++ /dev/null
-/*
- * 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@
- */
-
-//
-// IDSPersistentState.h
-//
-
-#import <Foundation/NSString.h>
-
-@interface KeychainSyncingOverIDSProxyPersistentState : NSObject
-{
-}
-
-+ (id)read:(NSURL *)path error:(NSError **)error;
-+ (BOOL)write:(NSURL *)path data:(id)plist error:(NSError **)error;
-+ (NSString *)dictionaryDescription: (NSDictionary *)state;
-+ (NSMutableDictionary *)idsState;
-+ (void)setUnhandledMessages: (NSDictionary *)unhandledMessages;
-+ (NSURL *)registrationFileURL;
-
-@end
-
+++ /dev/null
-/*
- * 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@
- */
-
-//
-// IDSPersistentState.m
-//
-
-#import <Security/Security.h>
-#import <Foundation/NSPropertyList.h>
-#import <Foundation/NSArray.h>
-#import <Foundation/NSPropertyList.h>
-#import <Foundation/NSData.h>
-#import <Foundation/NSDictionary.h>
-#import <utilities/debugging.h>
-#import <utilities/SecFileLocations.h>
-
-#import "IDSPersistentState.h"
-
-#if ! __has_feature(objc_arc)
-#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag
-#endif
-
-static CFStringRef kRegistrationFileName = CFSTR("com.apple.security.keychainsyncingoveridsproxy.unhandledMessages.plist");
-
-@implementation KeychainSyncingOverIDSProxyPersistentState
-
-+ (BOOL)write:(NSURL *)path data:(id)plist error:(NSError **)error
-{
- if (![NSPropertyListSerialization propertyList: plist isValidForFormat: NSPropertyListXMLFormat_v1_0])
- {
- secerror("can't save PersistentState as XML");
- return false;
- }
-
- NSData *data = [NSPropertyListSerialization dataWithPropertyList: plist
- format: NSPropertyListXMLFormat_v1_0 options: 0 error: error];
- if (data == nil)
- {
- secerror("error serializing PersistentState to xml: %@", *error);
- return false;
- }
-
- BOOL writeStatus = [data writeToURL: path options: NSDataWritingAtomic error: error];
- if (!writeStatus)
- secerror("error writing PersistentState to file: %@", *error);
-
- return writeStatus;
-}
-
-+ (id)read: (NSURL *)path error:(NSError **)error
-{
- NSData *data = [NSData dataWithContentsOfURL: path options: 0 error: error];
- if (data == nil)
- {
- secdebug("unhandledmessages", "error reading PersistentState from %@: %@", path, *error);
- return nil;
- }
-
- // Now the deserializing:
-
- NSPropertyListFormat format;
- id plist = [NSPropertyListSerialization propertyListWithData: data
- options: NSPropertyListMutableContainersAndLeaves format: &format error: error];
-
- if (plist == nil)
- secerror("could not deserialize PersistentState from %@: %@", path, *error);
-
- return plist;
-}
-
-+ (NSURL *)registrationFileURL
-{
- return (NSURL *)CFBridgingRelease(SecCopyURLForFileInPreferencesDirectory(kRegistrationFileName));
-}
-
-+ (NSString *)dictionaryDescription: (NSDictionary *)state
-{
- NSMutableArray *elements = [NSMutableArray array];
- [state enumerateKeysAndObjectsUsingBlock: ^(NSString *key, id obj, BOOL *stop) {
- [elements addObject: [key stringByAppendingString: @":"]];
- if ([obj isKindOfClass:[NSArray class]]) {
- [elements addObject: [(NSArray *)obj componentsJoinedByString: @" "]];
- } else {
- [elements addObject: [NSString stringWithFormat:@"%@", obj]];
- }
- }];
- return [elements componentsJoinedByString: @" "];
-}
-
-+ (NSMutableDictionary *)idsState
-{
- NSError *error = NULL;
- id stateDictionary = [KeychainSyncingOverIDSProxyPersistentState read:[[self class] registrationFileURL] error:&error];
- secdebug("keyregister", "Read registeredKeys: <%@>", [self dictionaryDescription: stateDictionary]);
- // Ignore older states with an NSArray
- if (![stateDictionary isKindOfClass:[NSDictionary class]])
- return NULL;
- return [NSMutableDictionary dictionaryWithDictionary:stateDictionary];
-}
-
-+ (void)setUnhandledMessages: (NSDictionary *)unhandledMessages
-{
- NSError *error = NULL;
- secdebug("IDS unhandled message", "Write unhandled Messages and monitor state: <%@>", [self dictionaryDescription: unhandledMessages]);
- [KeychainSyncingOverIDSProxyPersistentState write:[[self class] registrationFileURL] data:unhandledMessages error:&error];
-}
-
-@end
+++ /dev/null
-/*
- * Copyright (c) 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@
- */
-
-#import <Foundation/Foundation.h>
-#import <dispatch/queue.h>
-#import <xpc/xpc.h>
-#import <IDS/IDS.h>
-#import "SOSCloudKeychainClient.h"
-#import <utilities/debugging.h>
-#import <Security/SecureObjectSync/SOSInternal.h>
-
-typedef enum {
- kIDSStartPingTestMessage = 1,
- kIDSEndPingTestMessage= 2,
- kIDSSendOneMessage = 3,
- kIDSPeerReceivedACK = 4,
- kIDSPeerAvailability = 6,
- kIDSPeerAvailabilityDone = 7,
- kIDSKeychainSyncIDSFragmentation = 8,
-} idsOperation;
-
-@interface KeychainSyncingOverIDSProxy : NSObject <IDSServiceDelegate>
-{
- IDSService *_service;
- NSString *deviceID;
- NSMutableDictionary *deviceIDFromAuthToken;
-}
-
-@property (retain, nonatomic) NSMutableDictionary *deviceIDFromAuthToken;
-@property (retain, nonatomic) NSString *deviceID;
-@property (retain, nonatomic) NSMutableDictionary *shadowPendingMessages;
-@property (retain, nonatomic) NSMutableDictionary *allFragmentedMessages;
-@property (retain, atomic) NSMutableDictionary *pingTimers;
-@property (retain, nonatomic) NSMutableDictionary *peerNextSendCache; //dictionary of device ID -> time stamp of when to send next
-
-// 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 (atomic) dispatch_source_t penaltyTimer;
-@property (atomic) bool penaltyTimerScheduled;
-@property (retain, atomic) NSDictionary *queuedMessages;
-
-@property (retain, atomic) NSMutableDictionary *counterValues;
-@property (atomic) NSInteger outgoingMessages;
-@property (atomic) NSInteger incomingMessages;
-
-
-
-
-
-@property (atomic) bool isIDSInitDone;
-@property (atomic) bool shadowDoInitializeIDSService;
-@property (atomic) bool isSecDRunningAsRoot;
-@property (atomic) bool doesSecDHavePeer;
-
-@property (atomic) dispatch_queue_t calloutQueue;
-@property (atomic) dispatch_queue_t pingQueue;
-@property dispatch_queue_t dataQueue;
-
-@property (atomic) bool isLocked;
-@property (atomic) bool unlockedSinceBoot;
-@property (atomic) dispatch_source_t retryTimer;
-@property (atomic) bool retryTimerScheduled;
-@property (atomic) bool inCallout;
-@property (atomic) bool setIDSDeviceID;
-@property (atomic) bool shadowDoSetIDSDeviceID;
-
-@property (atomic) bool handleAllPendingMessages;
-@property (atomic) bool shadowHandleAllPendingMessages;
-@property (atomic) bool sendRestoredMessages;
-@property (atomic) bool allowKVSFallBack;
-
-+ (KeychainSyncingOverIDSProxy *) idsProxy;
-
-- (id)init;
-
-- (void) doSetIDSDeviceID;
-- (void) doIDSInitialization;
-- (void) calloutWith: (void(^)(NSMutableDictionary *pending,
- bool handlePendingMesssages,
- bool doSetDeviceID,
- dispatch_queue_t queue,
- void(^done)(NSMutableDictionary *handledMessages,
- bool handledPendingMessage,
- bool handledSettingDeviceID))) callout;
-- (void) sendKeysCallout: (NSMutableDictionary *(^)(NSMutableDictionary* pending, NSError** error)) handleMessages;
-- (void) persistState;
-- (void) sendPersistedMessagesAgain;
-- (NSDictionary*) retrievePendingMessages;
-- (NSDictionary*) collectStats;
-- (void) scheduleRetryRequestTimer;
-- (BOOL) haveMessagesInFlight;
--(void) printMessage:(NSDictionary*) message state:(NSString*)state;
-
-@end
-
-NSString* createErrorString(NSString* format, ...)
- NS_FORMAT_FUNCTION(1, 2);
-
-
+++ /dev/null
-/*
- * Copyright (c) 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@
- */
-
-#import <Foundation/NSArray.h>
-#import <Foundation/Foundation.h>
-
-#import <Security/SecBasePriv.h>
-#import <Security/SecItemPriv.h>
-#import <utilities/debugging.h>
-#import <notify.h>
-
-#include <Security/CKBridge/SOSCloudKeychainConstants.h>
-#include <Security/SecureObjectSync/SOSARCDefines.h>
-#include <Security/SecureObjectSync/SOSCloudCircle.h>
-#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
-
-#import <IDS/IDS.h>
-#import <os/activity.h>
-
-#include <utilities/SecAKSWrappers.h>
-#include <utilities/SecCFWrappers.h>
-#include <utilities/SecCFRelease.h>
-#include <AssertMacros.h>
-
-#import "IDSProxy.h"
-#import "KeychainSyncingOverIDSProxy+ReceiveMessage.h"
-#import "KeychainSyncingOverIDSProxy+SendMessage.h"
-#import "IDSPersistentState.h"
-
-#define kSecServerKeychainChangedNotification "com.apple.security.keychainchanged"
-#define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable"
-
-#define IDSServiceNameKeychainSync "com.apple.private.alloy.keychainsync"
-static NSString *kMonitorState = @"MonitorState";
-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";
-
-NSString *const IDSSendMessageOptionForceEncryptionOffKey = @"IDSSendMessageOptionForceEncryptionOff";
-static const int64_t kRetryTimerLeeway = (NSEC_PER_MSEC * 250); // 250ms leeway for handling unhandled messages.
-static const int64_t kMinMessageRetryDelay = (NSEC_PER_SEC * 8);
-
-CFIndex SECD_RUN_AS_ROOT_ERROR = 1041;
-
-#define IDSPROXYSCOPE "IDSProxy"
-
-@implementation KeychainSyncingOverIDSProxy
-
-@synthesize deviceID = deviceID;
-@synthesize deviceIDFromAuthToken = deviceIDFromAuthToken;
-
-+ (KeychainSyncingOverIDSProxy *) idsProxy
-{
- static KeychainSyncingOverIDSProxy *idsProxy;
- if (!idsProxy) {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- idsProxy = [[self alloc] init];
- });
- }
- return idsProxy;
-}
-
--(NSDictionary*) exportState
-{
- return @{ kMonitorState:self.monitor,
- kExportUnhandledMessages:self.unhandledMessageBuffer,
- kMessagesInFlight:self.messagesInFlight
- };
-
-}
-
--(NSDictionary*) retrievePendingMessages
-{
- NSDictionary * __block messages;
- dispatch_sync(self.dataQueue, ^{
- messages = [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight copy];
- });
- return messages;
-}
-
-@synthesize unhandledMessageBuffer = _unhandledMessageBuffer;
-
-- (NSMutableDictionary *) unhandledMessageBuffer {
- dispatch_assert_queue(self.dataQueue);
- return _unhandledMessageBuffer;
-}
-
-- (void) setUnhandledMessageBuffer:(NSMutableDictionary *)unhandledMessageBuffer {
- dispatch_assert_queue(self.dataQueue);
- _unhandledMessageBuffer = unhandledMessageBuffer;
-}
-
-@ synthesize messagesInFlight = _messagesInFlight;
-
-- (NSMutableDictionary *) messagesInFlight {
- dispatch_assert_queue(self.dataQueue);
- return _messagesInFlight;
-}
-
-- (void) setMessagesInFlight:(NSMutableDictionary *)messagesInFlight {
- dispatch_assert_queue(self.dataQueue);
- _messagesInFlight = messagesInFlight;
-}
-
-@synthesize monitor = _monitor;
-
-- (NSMutableDictionary *) monitor {
- dispatch_assert_queue(self.dataQueue);
- return _monitor;
-}
-
-- (void) setMonitor:(NSMutableDictionary *)monitor {
- dispatch_assert_queue(self.dataQueue);
- _monitor = monitor;
-}
-
-- (void) persistState
-{
- dispatch_sync(self.dataQueue, ^{
- [KeychainSyncingOverIDSProxyPersistentState setUnhandledMessages:[self exportState]];
- });
-}
-
-- (BOOL) haveMessagesInFlight {
- BOOL __block inFlight = NO;
- dispatch_sync(self.dataQueue, ^{
- inFlight = [self.messagesInFlight count] > 0;
- });
- return inFlight;
-}
-
-- (void) sendPersistedMessagesAgain
-{
- NSMutableDictionary * __block copy;
-
- dispatch_sync(self.dataQueue, ^{
- copy = [NSMutableDictionary dictionaryWithDictionary:self.messagesInFlight];
- });
-
- if(copy && [copy count] > 0){
- [copy enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
- NSDictionary* idsMessage = (NSDictionary*)obj;
- NSString *uniqueMessageID = (NSString*)key;
-
- 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];
- });
-
- if (!peerID || !ID) {
- return;
- }
- [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 && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){
- secnotice("IDS Transport", "setting timer!");
- [self setMessageTimer:uniqueMessageID deviceID:ID message:idsMessage];
- }
- }
- }];
- }
-}
-
-- (id)init
-{
- if (self = [super init])
- {
- secnotice("event", "%@ start", self);
-
- _isIDSInitDone = false;
- _service = nil;
- _calloutQueue = dispatch_queue_create("IDSCallout", DISPATCH_QUEUE_SERIAL);
- _pingQueue = dispatch_queue_create("PingQueue", DISPATCH_QUEUE_SERIAL);
- _dataQueue = dispatch_queue_create("DataQueue", DISPATCH_QUEUE_SERIAL);
- _pingTimers = [[NSMutableDictionary alloc] init];
- deviceIDFromAuthToken = [[NSMutableDictionary alloc] init];
- _peerNextSendCache = [[NSMutableDictionary alloc] init];
- _counterValues = [[NSMutableDictionary alloc] init];
- _outgoingMessages = 0;
- _incomingMessages = 0;
- _isSecDRunningAsRoot = false;
- _doesSecDHavePeer = true;
- _allowKVSFallBack = true;
- secdebug(IDSPROXYSCOPE, "%@ done", self);
-
- [self doIDSInitialization];
- if(_isIDSInitDone)
- [self doSetIDSDeviceID];
-
- // Register for lock state changes
- xpc_set_event_stream_handler(kStreamName, dispatch_get_main_queue(),
- ^(xpc_object_t notification){
- [self streamEvent:notification];
- });
-
- _retryTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
- dispatch_source_set_timer(_retryTimer, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, kRetryTimerLeeway);
- dispatch_source_set_event_handler(_retryTimer, ^{
- [self timerFired];
- });
- dispatch_resume(_retryTimer);
- NSMutableDictionary *state = [KeychainSyncingOverIDSProxyPersistentState idsState];
-
- _unhandledMessageBuffer = state[kExportUnhandledMessages];
- if (!_unhandledMessageBuffer) {
- _unhandledMessageBuffer = [NSMutableDictionary dictionary];
- }
- _messagesInFlight = state[kMessagesInFlight];
- if(_messagesInFlight == nil) {
- _messagesInFlight = [NSMutableDictionary dictionary];
- }
- _monitor = state[kMonitorState];
- if(_monitor == nil) {
- _monitor = [NSMutableDictionary dictionary];
- }
-
- if([_messagesInFlight count ] > 0)
- _sendRestoredMessages = true;
- int notificationToken;
- notify_register_dispatch(kSecServerKeychainChangedNotification, ¬ificationToken, self.dataQueue,
- ^ (int token __unused)
- {
- secinfo("backoff", "keychain changed, wiping backoff monitor state");
- self.monitor = [NSMutableDictionary dictionary];
- });
- int peerInfo;
- notify_register_dispatch(kSecServerPeerInfoAvailable, &peerInfo, dispatch_get_main_queue(),
- ^ (int token __unused)
- {
- secinfo("IDS Transport", "secd has a peer info");
- if(self.doesSecDHavePeer == false){
- self.doesSecDHavePeer = true;
- [self doSetIDSDeviceID];
- }
- });
-
- [self updateUnlockedSinceBoot];
- [self updateIsLocked];
- if (!_isLocked)
- [self keybagDidUnlock];
-
-
- }
- return self;
-}
-
-- (void)streamEvent:(xpc_object_t)notification
-{
-#if (!TARGET_IPHONE_SIMULATOR)
- const char *notificationName = xpc_dictionary_get_string(notification, "Notification");
- if (!notificationName) {
- } else if (strcmp(notificationName, kUserKeybagStateChangeNotification)==0) {
- return [self keybagStateChange];
- }
- const char *eventName = xpc_dictionary_get_string(notification, "XPCEventName");
- char *desc = xpc_copy_description(notification);
- secnotice("event", "%@ event: %s name: %s desc: %s", self, eventName, notificationName, desc);
- if (desc)
- free((void *)desc);
-#endif
-}
-
-- (void) keybagDidLock
-{
- secnotice("IDS Transport", "%@ locking!", self);
-}
-
-- (void) keybagDidUnlock
-{
- secnotice("IDS Transport", "%@ unlocking!", self);
- [self handleAllPendingMessage];
-}
-
-- (BOOL) updateUnlockedSinceBoot
-{
- CFErrorRef aksError = NULL;
- if (!SecAKSGetHasBeenUnlocked(&_unlockedSinceBoot, &aksError)) {
- secerror("%@ Got error from SecAKSGetHasBeenUnlocked: %@", self, aksError);
- CFReleaseSafe(aksError);
- return NO;
- }
- return YES;
-}
-
-- (BOOL) updateIsLocked
-{
- CFErrorRef aksError = NULL;
- if (!SecAKSGetIsLocked(&_isLocked, &aksError)) {
- secerror("%@ Got error querying lock state: %@", self, aksError);
- CFReleaseSafe(aksError);
- return NO;
- }
- secerror("updateIsLocked: %d", _isLocked);
- if (!_isLocked)
- _unlockedSinceBoot = YES;
- return YES;
-}
-
-- (void) keybagStateChange
-{
- os_activity_initiate("keybagStateChanged", OS_ACTIVITY_FLAG_DEFAULT, ^{
- secerror("keybagStateChange! was locked: %d", self->_isLocked);
- BOOL wasLocked = self->_isLocked;
- if ([self updateIsLocked]) {
- if (wasLocked == self->_isLocked)
- secdebug("IDS Transport", "%@ still %s ignoring", self, self->_isLocked ? "locked" : "unlocked");
- else if (self->_isLocked)
- [self keybagDidLock];
- else
- [self keybagDidUnlock];
- }
- });
-}
-
-
-- (void)timerFired
-{
- NSUInteger __block messagecount = 0;
- dispatch_sync(self.dataQueue, ^{
- if(self.unhandledMessageBuffer) {
- secnotice("IDS Transport", "%@ attempting to hand unhandled messages to securityd, here is our message queue: %@", self, self.unhandledMessageBuffer);
- messagecount = [self.unhandledMessageBuffer count];
- }
- });
-
- if(self.isLocked) {
- self.retryTimerScheduled = NO;
- } else if(messagecount == 0) {
- self.retryTimerScheduled = NO;
- } else if (self.retryTimerScheduled && !self.isLocked) {
- [self handleAllPendingMessage];
- } else {
- [[KeychainSyncingOverIDSProxy idsProxy] scheduleRetryRequestTimer];
- }
-}
-
-- (void)scheduleRetryRequestTimer
-{
- secnotice("IDS Transport", "scheduling unhandled messages timer");
- dispatch_source_set_timer(_retryTimer, dispatch_time(DISPATCH_TIME_NOW, kMinMessageRetryDelay), DISPATCH_TIME_FOREVER, kRetryTimerLeeway);
- _retryTimerScheduled = YES;
-}
-
-- (void)doIDSInitialization
-{
-
- dispatch_async(self.calloutQueue, ^{
- secnotice("IDS Transport", "doIDSInitialization!");
-
- self->_service = [[IDSService alloc] initWithService: @IDSServiceNameKeychainSync];
-
- if( self->_service == nil ){
- self->_isIDSInitDone = false;
- secerror("Could not create ids service");
- }
- else{
- secnotice("IDS Transport", "IDS Transport Successfully set up IDS!");
- [self->_service addDelegate:self queue: dispatch_get_main_queue()];
-
- self->_isIDSInitDone = true;
- if(self->_isSecDRunningAsRoot == false)
- [self doSetIDSDeviceID];
- }
- });
-}
-
-- (void) doSetIDSDeviceID
-{
- NSInteger code = 0;
- NSString *errorMessage = nil;
-
- if(!_isIDSInitDone){
- [self doIDSInitialization];
- }
- _setIDSDeviceID = YES;
-
- if(_isSecDRunningAsRoot != false)
- {
- errorMessage = @"cannot set IDS device ID, secd is running as root";
- code = SECD_RUN_AS_ROOT_ERROR;
- secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code);
-
- }
- else if(_doesSecDHavePeer != true)
- {
- errorMessage = @"cannot set IDS deviceID, secd does not have a full peer info for account";
- code = kSOSErrorPeerNotFound;
- secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code);
-
- }
- else if(!_isIDSInitDone){
- errorMessage = @"KeychainSyncingOverIDSProxy can't set up the IDS service";
- code = kSecIDSErrorNotRegistered;
- secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code);
- }
- else if(_isLocked){
- errorMessage = @"KeychainSyncingOverIDSProxy can't set device ID, device is locked";
- code = kSecIDSErrorDeviceIsLocked;
- secerror("Setting device ID error: %@, code: %ld", errorMessage, (long)code);
- }
-
- else{
- [self calloutWith:^(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *, bool, bool)) {
- CFErrorRef localError = NULL;
- bool handledSettingID = false;
- NSString *ID = IDSCopyLocalDeviceUniqueID();
- self->deviceID = ID;
-
- if(ID){
- handledSettingID = SOSCCSetDeviceID((__bridge CFStringRef) ID, &localError);
-
- if(!handledSettingID && localError != NULL){
- if(CFErrorGetCode(localError) == SECD_RUN_AS_ROOT_ERROR){
- secerror("SETTING RUN AS ROOT ERROR: %@", localError);
- self->_isSecDRunningAsRoot = true;
- }
- else if (CFErrorIsMalfunctioningKeybagError(localError)) {
- secnotice("IDS Transport", "system is unavailable, cannot set device ID, error: %@", localError);
- self->_isLocked = true;
- }
- else if (CFErrorGetCode(localError) == kSOSErrorPeerNotFound && CFStringCompare(CFErrorGetDomain(localError), kSOSErrorDomain, 0) == 0){
- secnotice("IDS Transport","securityd does not have a peer yet , error: %@", localError);
- self->_doesSecDHavePeer = false;
- }
- }
- else
- self->_setIDSDeviceID = NO;
-
- CFReleaseNull(localError);
- dispatch_async(queue, ^{
- done(nil, NO, YES);
- });
- } else {
- dispatch_async(queue, ^{
- done(nil, NO, NO);
- });
- }
- if(errorMessage != nil){
- secerror("Setting device ID error: KeychainSyncingOverIDSProxy could not retrieve device ID from keychain, code: %ld", (long)kSecIDSErrorNoDeviceID);
- }
- }];
- }
-}
-
-- (void) calloutWith: (void(^)(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *handledMessages, bool handledPendingMessage, bool handledSettingDeviceID))) callout
-{
- // In KeychainSyncingOverIDSProxy serial queue
- dispatch_queue_t idsproxy_queue = dispatch_get_main_queue();
-
- // dispatch_get_global_queue - well-known global concurrent queue
- // dispatch_get_main_queue - default queue that is bound to the main thread
- xpc_transaction_begin();
- dispatch_async(_calloutQueue, ^{
- __block NSMutableDictionary *myPending;
- __block bool myHandlePendingMessage;
- __block bool myDoSetDeviceID;
- __block bool wasLocked;
- dispatch_sync(idsproxy_queue, ^{
- dispatch_sync(self.dataQueue, ^{
- myPending = [self.unhandledMessageBuffer copy];
- });
- myHandlePendingMessage = self.handleAllPendingMessages;
- myDoSetDeviceID = self.setIDSDeviceID;
- wasLocked = self.isLocked;
-
- self.inCallout = YES;
-
- self.shadowHandleAllPendingMessages = NO;
- });
-
- callout(myPending, myHandlePendingMessage, myDoSetDeviceID, idsproxy_queue, ^(NSMutableDictionary *handledMessages, bool handledPendingMessage, bool handledSetDeviceID) {
- secdebug("event", "%@ %s%s before callout handled: %s%s", self, myHandlePendingMessage ? "P" : "p", myDoSetDeviceID ? "D" : "d", handledPendingMessage ? "H" : "h", handledSetDeviceID ? "I" : "i");
-
- // In IDSKeychainSyncingProxy's serial queue
- self->_inCallout = NO;
-
- // Update setting device id
- self->_setIDSDeviceID = ((myDoSetDeviceID && !handledSetDeviceID));
-
- self->_shadowDoSetIDSDeviceID = NO;
-
- xpc_transaction_end();
- });
- });
-}
-
-- (void) sendKeysCallout: (NSMutableDictionary*(^)(NSMutableDictionary* pending, NSError** error)) handleMessages {
- [self calloutWith: ^(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *, bool, bool)) {
- NSError* error = NULL;
-
- NSMutableDictionary* handled = handleMessages(pending, &error);
-
- dispatch_async(queue, ^{
- if (!handled && error) {
- secerror("%@ did not handle message: %@", self, error);
- }
-
- done(handled, NO, NO);
- });
- }];
-}
-
-NSString* createErrorString(NSString* format, ...)
-{
- va_list va;
- va_start(va, format);
- NSString* errorString = ([[NSString alloc] initWithFormat:format arguments:va]);
- va_end(va);
- return errorString;
-
-}
-
-- (NSDictionary*) collectStats{
- [_counterValues setObject:[NSNumber numberWithInteger:[KeychainSyncingOverIDSProxy idsProxy].outgoingMessages] forKey:kOutgoingMessages];
- [_counterValues setObject:[NSNumber numberWithInteger:[KeychainSyncingOverIDSProxy idsProxy].incomingMessages] forKey:kIncomingMessages];
-
- 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
+++ /dev/null
-/*
- * Copyright (c) 2012-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 "IDSProxy.h"
-
-@interface KeychainSyncingOverIDSProxy (ReceiveMessage)
-//receive message routines
--(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 shouldSendAck:(NSString *)useAck peerID:(NSString*)peerID messageID:(NSString*)messageID deviceID:(NSString*)deviceID;
-- (void) handleAllPendingMessage;
-
-@end
+++ /dev/null
-/*
- * Copyright (c) 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@
- */
-
-
-#import <Foundation/Foundation.h>
-#import <Foundation/NSArray.h>
-#import <Foundation/Foundation.h>
-
-#import <Security/SecBasePriv.h>
-#import <Security/SecItemPriv.h>
-#import <utilities/debugging.h>
-#import <notify.h>
-
-#include <Security/CKBridge/SOSCloudKeychainConstants.h>
-#include <Security/SecureObjectSync/SOSARCDefines.h>
-#include <Security/SecureObjectSync/SOSCloudCircle.h>
-#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
-#include <utilities/SecCFWrappers.h>
-
-#import <IDS/IDS.h>
-#import <os/activity.h>
-
-#include <utilities/SecAKSWrappers.h>
-#include <utilities/SecCFRelease.h>
-#include <AssertMacros.h>
-
-#import "IDSPersistentState.h"
-#import "KeychainSyncingOverIDSProxy+ReceiveMessage.h"
-#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;
- [fragmentsForDeviceID enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * _Nonnull stop) {
- if(obj != [NSNull null]){
- count++;
- }
- }];
- return count;
-}
-
--(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]];
- for (int i = 0; i <[idsNumberOfFragments longValue] ; i++) {
- [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
-{
- 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];
-
- [messagesForUUID enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- NSData *messageFragment = (NSData*)obj;
-
- [completeMessage appendData: messageFragment];
- }];
- //we've combined the message, now remove it from the fragmented messages dictionary
- [arrayOfFragmentedMessagesByUUID removeObjectForKey:uuid];
-
- return [NSMutableDictionary dictionaryWithObjectsAndKeys: completeMessage, dataKey, ID, deviceIDKey, peerID, peerIDKey, nil];
-}
-
--(void) handleTestMessage:(NSString*)operation id:(NSString*)ID messageID:(NSString*)uniqueID senderPeerID:(NSString*)senderPeerID
-{
- int operationType = [operation intValue];
- switch(operationType){
- case kIDSPeerAvailabilityDone:
- {
- //set current timestamp to indicate success!
- [self.peerNextSendCache setObject:[NSDate date] forKey:ID];
-
- secnotice("IDS Transport","!received availability response!: %@", ID);
- notify_post(kSOSCCPeerAvailable);
- break;
- }
- case kIDSEndPingTestMessage:
- secnotice("IDS Transport","received pong message from other device: %@, ping test PASSED", ID);
- break;
- case kIDSSendOneMessage:
- secnotice("IDS Transport","received ping test message, dropping on the floor now");
- break;
-
- case kIDSPeerAvailability:
- case kIDSStartPingTestMessage:
- {
- char* messageCharS;
- if(operationType == kIDSPeerAvailability){
- secnotice("IDS Transport","Received Availability Message from:%@!", ID);
- asprintf(&messageCharS, "%d",kIDSPeerAvailabilityDone);
- }
- else{
- secnotice("IDS Transport","Received PingTest Message from: %@!", ID);
- asprintf(&messageCharS, "%d", kIDSEndPingTestMessage);
- }
-
- NSString *operationString = [[NSString alloc] initWithUTF8String:messageCharS];
- NSString* messageString = @"peer availability check finished";
- 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" senderDeviceID:NULL];
-
- free(messageCharS);
-
- break;
- }
- case kIDSPeerReceivedACK:
- {
- //set current timestamp to indicate success!
- [self.peerNextSendCache setObject:[[NSDate alloc] init] forKey:ID];
-
- //cancel timer!
- secnotice("IDS Transport", "received ack for: %@", uniqueID);
- dispatch_async(self.pingQueue, ^{
- //remove timer for message id
- dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:uniqueID];
- if(timer != nil){
- dispatch_cancel(timer);
- [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:uniqueID];
- dispatch_sync(self.dataQueue, ^{
- [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight removeObjectForKey:uniqueID];
- });
- [[KeychainSyncingOverIDSProxy idsProxy] persistState];
- }
- });
- //call out to securityd to set a NULL
- [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) {
-
- CFErrorRef localError = NULL;
- SOSCCClearPeerMessageKeyInKVS((__bridge CFStringRef)senderPeerID, &localError);
- return NULL;
- }];
- break;
- }
- default:
- break;
- }
-}
-
-- (void)sendACK:(NSString*)ID peerID:(NSString*)sendersPeerID uniqueID:(NSString*)uniqueID senderDeviceID:(NSString*)senderDeviceID
-{
- char* messageCharS;
- NSString* messageString = @"ACK";
-
- asprintf(&messageCharS, "%d",kIDSPeerReceivedACK);
- NSString *operationString = [[NSString alloc] initWithUTF8String:messageCharS];
-
- NSDictionary* messageDictionary = @{(__bridge NSString*)kIDSOperationType:operationString, (__bridge NSString*)kIDSMessageToSendKey:messageString, (__bridge NSString*)kIDSMessageUniqueID:uniqueID};
-
- [self sendIDSMessage:messageDictionary name:ID peer:sendersPeerID senderDeviceID:senderDeviceID];
-
- free(messageCharS);
-
-}
-
-- (void)updateDeviceList
-{
- self.deviceIDFromAuthToken = nil;
- self.deviceIDFromAuthToken = [NSMutableDictionary dictionary];
- [self calloutWith:^(NSMutableDictionary *pending, bool handlePendingMesssages, bool doSetDeviceID, dispatch_queue_t queue, void(^done)(NSMutableDictionary *, bool, bool)) {
- }];
-}
-- (void)service:(IDSService *)service account:(IDSAccount *)account incomingMessage:(NSDictionary *)message fromID:(NSString *)fromID context:(IDSMessageContext *)context
-{
- NSString *dataKey = [ NSString stringWithUTF8String: kMessageKeyIDSDataMessage ];
- NSString *deviceIDKey = [ NSString stringWithUTF8String: kMessageKeyDeviceID ];
- NSString *peerIDKey = [ NSString stringWithUTF8String: kMessageKeyPeerID ];
- NSString *sendersPeerIDKey = [NSString stringWithUTF8String: kMessageKeySendersPeerID];
-
- [KeychainSyncingOverIDSProxy idsProxy].incomingMessages++;
-
- dispatch_async(self.calloutQueue, ^{
- NSString* messageID = nil;
- uint32_t operationType;
- bool hadError = false;
- CFStringRef errorMessage = NULL;
- __block NSString* myPeerID = @"";
- __block NSData *messageData = nil;
- NSString* operationTypeAsString = nil;
- NSMutableDictionary *messageDictionary = nil;
- NSString *useAck = 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){
- senderDeviceID = device.uniqueID;
- break;
- }
- }
- [[KeychainSyncingOverIDSProxy idsProxy] printMessage:message state:[NSString stringWithFormat:@"received message from: %@", senderDeviceID]];
- NSString *sendersPeerID = [message objectForKey: sendersPeerIDKey];
-
- if(sendersPeerID == nil)
- sendersPeerID = [NSString string];
-
- 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];
-
- messageID = [message objectForKey:(__bridge NSString*)kIDSMessageUniqueID];
- useAck = [message objectForKey:kIDSMessageUseACKModel];
-
- if(useAck != nil && [useAck compare:@"YES"] == NSOrderedSame)
- require_quiet(messageID != nil, fail);
-
- secnotice("IDS Transport","from peer %@, operation: %@", senderDeviceID, operationTypeAsString);
- operationType = [operationTypeAsString intValue];
-
- if(operationType != kIDSKeychainSyncIDSFragmentation)
- {
- [self handleTestMessage:operationTypeAsString id:senderDeviceID messageID:messageID senderPeerID:sendersPeerID];
- }
- else{
-
- [messageDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
- myPeerID = (NSString*)key;
- messageData = (NSData*)obj;
- }];
-
- 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:senderDeviceID peerID:myPeerID uuid:uuid];
- //update next sequence number
- }
- else if(readyToHandOffToSecD){
- messageAndFromID = [NSMutableDictionary dictionaryWithObjectsAndKeys: messageData, dataKey, senderDeviceID, deviceIDKey, myPeerID, peerIDKey, nil];
- }
- else
- return;
-
- //set the sender's peer id so we can check it in securityd
- [messageAndFromID setObject:sendersPeerID forKey:sendersPeerIDKey];
-
- if([KeychainSyncingOverIDSProxy idsProxy].isLocked){
- //hang on to the message and set the retry deadline
- dispatch_sync(self.dataQueue, ^{
- [self.unhandledMessageBuffer setObject: messageAndFromID forKey: fromID];
- });
- }
- else{
- [self sendMessageToSecurity:messageAndFromID fromID:fromID shouldSendAck:useAck peerID:myPeerID messageID:messageID deviceID:senderDeviceID];
-
- }
- }
-
- fail:
- if(hadError)
- secerror("error:%@", errorMessage);
- });
-}
-
-
-- (void) handleAllPendingMessage
-{
- secnotice("IDS Transport", "Attempting to handle pending messsages");
-
- NSMutableDictionary * __block copyOfUnhandled = nil;
- dispatch_sync(self.dataQueue, ^{
- if ([self.unhandledMessageBuffer count] > 0) {
- secnotice("IDS Transport", "handling messages: %@", self.unhandledMessageBuffer);
- copyOfUnhandled = [NSMutableDictionary dictionaryWithDictionary:self.unhandledMessageBuffer];
- }
- });
-
- [copyOfUnhandled enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
- {
- NSMutableDictionary *messageAndFromID = (NSMutableDictionary*)obj;
- NSString *fromID = (NSString*)key;
- //remove the message from the official message buffer (if it fails to get handled it'll be reset again in sendMessageToSecurity)
- dispatch_sync(self.dataQueue, ^{
- [self.unhandledMessageBuffer removeObjectForKey: fromID];
- });
- [self sendMessageToSecurity:messageAndFromID fromID:fromID shouldSendAck:nil peerID:nil messageID:nil deviceID:nil];
- }];
-}
-
-- (bool) shouldPersistMessage:(NSDictionary*) newMessageAndFromID id:(NSString*)fromID
-{
- //get the dictionary of messages for a particular device id
- NSDictionary* __block messagesFromBuffer;
- dispatch_sync(self.dataQueue, ^{
- messagesFromBuffer = [self.unhandledMessageBuffer valueForKey:fromID];
- });
-
- if([messagesFromBuffer isEqual:newMessageAndFromID])
- return false;
-
- return true;
-}
-
--(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;
-
- [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) {
-
- success = SOSCCHandleIDSMessage(((__bridge CFDictionaryRef)messageAndFromID), &cf_error);
- //turns out the error needs to be evaluated as sync_and_do returns bools
- if(cf_error != NULL)
- {
- if(CFErrorIsMalfunctioningKeybagError(cf_error)){
- success = kHandleIDSMessageLocked;
- }
- }
-
- if(success == kHandleIDSMessageLocked){
- secnotice("IDS Transport","cannot handle messages from: %@ when locked, error:%@", fromID, cf_error);
- // I don't think this is ever nil but it was like this when I got here
- dispatch_sync(self.dataQueue, ^{
- if(!self.unhandledMessageBuffer) {
- self.unhandledMessageBuffer = [NSMutableDictionary dictionary];
- }
- });
-
- //write message to disk if message is new to the unhandled queue
- if([self shouldPersistMessage:messageAndFromID id:fromID]) {
- [self persistState];
- }
-
- dispatch_sync(self.dataQueue, ^{
- [self.unhandledMessageBuffer setObject: messageAndFromID forKey: fromID];
- secnotice("IDS Transport", "unhandledMessageBuffer: %@", self.unhandledMessageBuffer);
- });
-
- return NULL;
- }
- else if(success == kHandleIDSMessageNotReady){
- secnotice("IDS Transport","not ready to handle message from: %@, error:%@", fromID, cf_error);
- dispatch_sync(self.dataQueue, ^{
- if(!self.unhandledMessageBuffer) {
- self.unhandledMessageBuffer = [NSMutableDictionary dictionary];
- }
- [self.unhandledMessageBuffer setObject: messageAndFromID forKey: fromID];
- secnotice("IDS Transport","unhandledMessageBuffer: %@", self.unhandledMessageBuffer);
- });
- //write message to disk if message is new to the unhandled queue
- if([self shouldPersistMessage:messageAndFromID id:fromID])
- [self persistState];
-
- [[KeychainSyncingOverIDSProxy idsProxy] scheduleRetryRequestTimer];
- return NULL;
- }
- else if(success == kHandleIDSmessageDeviceIDMismatch){
- secnotice("IDS Transport","message for a ghost! dropping message. error:%@", cf_error);
- return NULL;
- }
- else if(success == kHandleIDSMessageDontHandle){
- secnotice("IDS Transport","error in message, dropping message. error:%@", cf_error);
- return NULL;
- }
- 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;
- }
-
- CFReleaseNull(cf_error);
- }];
-}
-
-@end
+++ /dev/null
-/*
- * Copyright (c) 2012-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 "IDSProxy.h"
-
-@interface KeychainSyncingOverIDSProxy (SendMessage)
--(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;
--(void) pingDevices:(NSArray*)list peerID:(NSString*)peerID;
-@end
+++ /dev/null
-/*
- * Copyright (c) 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@
- */
-
-
-#import <Foundation/NSArray.h>
-#import <Foundation/Foundation.h>
-
-#import <Security/SecBasePriv.h>
-#import <Security/SecItemPriv.h>
-#import <utilities/debugging.h>
-#import <notify.h>
-
-#include <Security/CKBridge/SOSCloudKeychainConstants.h>
-#include <Security/SecureObjectSync/SOSARCDefines.h>
-#include <Security/SecureObjectSync/SOSCloudCircle.h>
-#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
-
-#import <IDS/IDS.h>
-#import <os/activity.h>
-
-#include <utilities/SecAKSWrappers.h>
-#include <utilities/SecADWrapper.h>
-#include <utilities/SecCFRelease.h>
-#include <AssertMacros.h>
-
-#import "IDSProxy.h"
-#import "IDSPersistentState.h"
-#import "KeychainSyncingOverIDSProxy+SendMessage.h"
-#include <Security/SecItemInternal.h>
-
-
-static NSString *const IDSSendMessageOptionForceEncryptionOffKey = @"IDSSendMessageOptionForceEncryptionOff";
-
-static NSString *const kIDSNumberOfFragments = @"NumberOfIDSMessageFragments";
-static NSString *const kIDSFragmentIndex = @"kFragmentIndex";
-static NSString *const kIDSMessageUseACKModel = @"UsesAckModel";
-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 = 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 senderDeviceID:(NSString*)senderDeviceID
- error:(NSError**) error
-{
- __block BOOL result = true;
-
- NSUInteger keychainDataLength = [keychainData length];
- int fragmentIndex = 0;
- int startingPosition = 0;
-
- NSUInteger totalNumberOfFragments = (keychainDataLength + kMaxIDSMessagePayloadSize - 1)/kMaxIDSMessagePayloadSize;
- secnotice("IDS Transport", "sending %lu number of fragments to: %@", (unsigned long)totalNumberOfFragments, deviceName);
- NSMutableDictionary* fragmentDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- deviceName, kIDSDeviceID,
- [NSNumber numberWithUnsignedInteger:totalNumberOfFragments], kIDSNumberOfFragments,
- [NSNumber numberWithInt:fragmentIndex], kIDSFragmentIndex,
- deviceName, kIDSMessageRecipientDeviceID, theirPeerID, kIDSMessageRecipientPeerID,
- operationTypeAsString, kIDSOperationType,
- uuidString, kIDSMessageUniqueID,
- nil];
-
- NSUInteger remainingLength = keychainDataLength;
- while(remainingLength > 0 && result == true){
- NSUInteger fragmentLength = MIN(remainingLength, kMaxIDSMessagePayloadSize);
- NSData *fragment = [keychainData subdataWithRange:NSMakeRange(startingPosition, fragmentLength)];
-
- // Insert the current fragment data in dictionary with key peerID and message key.
- [fragmentDictionary setObject:@{theirPeerID:fragment}
- forKey:(__bridge NSString*)kIDSMessageToSendKey];
- // Insert the fragment number in the dictionary
- [fragmentDictionary setObject:[NSNumber numberWithInt:fragmentIndex]
- forKey:kIDSFragmentIndex];
-
- result = [self sendIDSMessage:fragmentDictionary name:deviceName peer:ourPeerID senderDeviceID:senderDeviceID];
- if(!result)
- secerror("Could not send fragmented message");
-
- startingPosition+=fragmentLength;
- remainingLength-=fragmentLength;
- fragmentIndex++;
- }
-
- return result;
-}
-
-- (void)sendToKVS: (NSString*) theirPeerID message: (NSData*) message
-{
- [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) {
- CFErrorRef cf_error = NULL;
-
- bool success = SOSCCRequestSyncWithPeerOverKVS(((__bridge CFStringRef)theirPeerID), (__bridge CFDataRef)message, &cf_error);
-
- if(success){
- secnotice("IDS Transport", "rerouting message %@", message);
- }
- else{
- secerror("could not route message to %@, error: %@", theirPeerID, cf_error);
- }
-
- CFReleaseNull(cf_error);
- return NULL;
- }];
-}
-
-- (void) sendMessageToKVS: (NSDictionary<NSString*, NSDictionary*>*) encapsulatedKeychainMessage
-{
- SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.kvsreroute"), 1);
- [encapsulatedKeychainMessage enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
- if ([key isKindOfClass: [NSString class]] && [obj isKindOfClass:[NSData class]]) {
- [self sendToKVS:key message:obj];
- } else {
- secerror("Couldn't send to KVS key: %@ obj: %@", key, obj);
- }
- }];
-}
-
-
-- (void)pingTimerFired:(NSString*)IDSid peerID:(NSString*)peerID identifier:(NSString*)identifier
-{
- //setting next time to send
- [self updateNextTimeToSendFor5Minutes:IDSid];
-
- secnotice("IDS Transport", "device ID: %@ !!!!!!!!!!!!!!!!Ping timeout is up!!!!!!!!!!!!", IDSid);
- //call securityd to sync with device over KVS
- __block CFErrorRef cf_error = NULL;
- __block bool success = kHandleIDSMessageSuccess;
-
- //cleanup timers
- dispatch_async(self.pingQueue, ^{
- dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:IDSid]; //remove timer
- dispatch_cancel(timer); //cancel timer
- [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:IDSid];
- });
-
- [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) {
-
- success = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(((__bridge CFStringRef)IDSid), &cf_error);
-
- if(success){
- secnotice("IDS Transport", "rerouting message for %@", peerID);
- }
- else{
- secerror("Could not hand peerID: %@ to securityd, error: %@", IDSid, cf_error);
- }
-
- return NULL;
- }];
- CFReleaseSafe(cf_error);
-}
-
--(void) pingDevices:(NSArray*)list peerID:(NSString*)peerID
-{
- NSDictionary *messageDictionary = @{(__bridge NSString*)kIDSOperationType : [NSString stringWithFormat:@"%d", kIDSPeerAvailability], (__bridge NSString*)kIDSMessageToSendKey : @"checking peers"};
-
- [list enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * top) {
- NSString* IDSid = (NSString*)obj;
- NSString* identifier = [NSString string];
- bool result = false;
- secnotice("IDS Transport", "sending to id: %@", IDSid);
-
- result = [self sendIDSMessage:messageDictionary name:IDSid peer:peerID senderDeviceID:[NSString string]];
-
- if(!result){
- secerror("Could not send message over IDS");
- [self sendKeysCallout:^NSMutableDictionary *(NSMutableDictionary *pending, NSError** error) {
- CFErrorRef kvsError = nil;
- bool success = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(((__bridge CFStringRef)IDSid), &kvsError);
-
- if(success){
- secnotice("IDS Transport", "sent peerID: %@ to securityd to sync over KVS", IDSid);
- }
- else{
- secerror("Could not hand peerID: %@ to securityd, error: %@", IDSid, kvsError);
- }
- CFReleaseNull(kvsError);
- return NULL;
- }];
- }
- else{
- dispatch_async(self.pingQueue, ^{
- //create a timer!
- if( [self.pingTimers objectForKey:IDSid] == nil){
- 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, timeout * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, kRetryTimerLeeway);
- dispatch_source_set_event_handler(timer, ^{
- [self pingTimerFired:IDSid peerID:peerID identifier:identifier];
- });
- dispatch_resume(timer);
-
- [self.pingTimers setObject:timer forKey:IDSid];
- }
- });
- }
- }];
-}
-
--(BOOL) shouldProxySendMessage:(NSString*)deviceName
-{
- BOOL result = false;
-
- //checking peer cache to see if the message should be sent over IDS or back to KVS
- if(self.peerNextSendCache == nil)
- {
- self.peerNextSendCache = [[NSMutableDictionary alloc]initWithCapacity:0];
- }
- NSDate *nextTimeToSend = [self.peerNextSendCache objectForKey:deviceName];
- if(nextTimeToSend != nil)
- {
- //check if the timestamp is stale or set sometime in the future
- NSDate *currentTime = [[NSDate alloc] init];
- //if the current time is greater than the next time to send -> time to send!
- if([[nextTimeToSend laterDate:currentTime] isEqual:currentTime]){
- result = true;
- }
- }
- else{ //next time to send is not set yet
- result = true;
- }
- return result;
-}
-
--(BOOL) isMessageAPing:(NSDictionary*)data
-{
- NSDictionary *messageDictionary = [data objectForKey: (__bridge NSString*)kIDSMessageToSendKey];
- BOOL isPingMessage = false;
-
- if(messageDictionary && ![messageDictionary isKindOfClass:[NSDictionary class]])
- {
- NSString* messageString = [data objectForKey: (__bridge NSString*)kIDSMessageToSendKey];
- if(messageString && [messageString isKindOfClass:[NSString class]])
- isPingMessage = true;
- }
- else if(!messageDictionary){
- secerror("IDS Transport: message is null?");
- }
-
- return isPingMessage;
-}
-
--(BOOL) sendFragmentedIDSMessages:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) ourPeerID senderDeviceID:(NSString*)senderDeviceID error:(NSError**) error
-{
- BOOL result = false;
- BOOL isPingMessage = false;
-
- NSError* localError = nil;
-
- NSString* operationTypeAsString = [data objectForKey: (__bridge NSString*)kIDSOperationType];
- NSMutableDictionary *messageDictionary = [data objectForKey: (__bridge NSString*)kIDSMessageToSendKey];
-
- isPingMessage = [self isMessageAPing:data];
-
- //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] && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack)
- {
- if(isPingMessage){
- secnotice("IDS Transport", "peer negative cache check: peer cannot send yet. not sending ping message");
- return true;
- }
- else{
- [self sendMessageToKVS:messageDictionary];
- return true;
- }
- }
-
- if(isPingMessage){ //foward the ping message, no processing
- result = [self sendIDSMessage:data
- name:deviceName
- peer:ourPeerID
- senderDeviceID:senderDeviceID];
- if(!result){
- secerror("Could not send ping message");
- }
- return result;
- }
-
- NSString *localMessageIdentifier = [[NSUUID UUID] UUIDString];
-
- bool fragment = [operationTypeAsString intValue] == kIDSKeychainSyncIDSFragmentation;
- bool useAckModel = fragment && [[data objectForKey:kIDSMessageUseACKModel] compare: @"YES"] == NSOrderedSame;
-
- __block NSData *keychainData = nil;
- __block NSString *theirPeerID = nil;
-
- [messageDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
- if ([key isKindOfClass:[NSString class]] && [obj isKindOfClass:[NSData class]]) {
- theirPeerID = (NSString*)key;
- keychainData = (NSData*)obj;
- }
- *stop = YES;
- }];
-
- if(fragment && keychainData && [keychainData length] >= kMaxIDSMessagePayloadSize){
- secnotice("IDS Transport","sending chunked keychain messages");
- result = [self chunkAndSendKeychainPayload:keychainData
- deviceID:deviceName
- ourPeerID:ourPeerID
- 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
- senderDeviceID:senderDeviceID];
- }
-
- 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;
-}
-
--(void) updateNextTimeToSendFor5Minutes:(NSString*)ID
-{
- secnotice("IDS Transport", "Setting next time to send in 5 minutes for device: %@", ID);
-
- NSTimeInterval backOffInterval = (KVS_BACKOFF * 60);
- NSDate *nextTimeToTransmit = [NSDate dateWithTimeInterval:backOffInterval sinceDate:[NSDate date]];
-
- [self.peerNextSendCache setObject:nextTimeToTransmit forKey:ID];
-}
-
-- (void)ackTimerFired:(NSString*)identifier deviceID:(NSString*)ID
-{
- secnotice("IDS Transport", "IDS device id: %@, Ping timeout is up for message identifier: %@", ID, identifier);
-
- //call securityd to sync with device over KVS
- NSMutableDictionary * __block message;
- dispatch_sync(self.dataQueue, ^{
- message = [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight objectForKey:identifier];
- [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight removeObjectForKey:identifier];
- });
- if(!message){
- return;
- }
- NSDictionary *mesageInFlight = [message objectForKey:(__bridge NSString*)kIDSMessageToSendKey];
-
- [[KeychainSyncingOverIDSProxy idsProxy] printMessage:mesageInFlight state:@"timeout occured, rerouting to KVS"];
-
- //cleanup timers
- dispatch_async(self.pingQueue, ^{
- dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:identifier]; //remove timer
- if(timer != nil)
- dispatch_cancel(timer); //cancel timer
- [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:identifier];
- });
-
- [self sendMessageToKVS:mesageInFlight];
-
- //setting next time to send
- [self updateNextTimeToSendFor5Minutes:ID];
-
- [[KeychainSyncingOverIDSProxy idsProxy] persistState];
-}
-
--(void) setMessageTimer:(NSString*)identifier deviceID:(NSString*)ID message:(NSDictionary*)message
-{
- 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, timeout * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, kRetryTimerLeeway);
-
- dispatch_source_set_event_handler(timer, ^{
- [self ackTimerFired:identifier deviceID:ID];
- });
- dispatch_resume(timer);
- //restructure message in flight
-
-
- //set the timer for message id
- dispatch_async(self.pingQueue, ^{
- [self.pingTimers setObject:timer forKey:identifier];
- });
-
- dispatch_sync(self.dataQueue, ^{
- [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight setObject:message forKey:identifier];
- });
- [[KeychainSyncingOverIDSProxy idsProxy] persistState];
-}
-
-//had an immediate error, remove it from messages in flight, and immediately send it over KVS
--(void) cleanupAfterHardIDSError:(NSDictionary*)data
-{
- NSString *messageIdentifier = [data objectForKey:(__bridge NSString*)kIDSMessageUniqueID];
- NSMutableDictionary * __block messageToSendToKVS = nil;
-
- if(messageIdentifier != nil){
- secerror("removing message id: %@ from message timers", messageIdentifier);
- dispatch_sync(self.dataQueue, ^{
- messageToSendToKVS = [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight objectForKey:messageIdentifier];
- [[KeychainSyncingOverIDSProxy idsProxy].messagesInFlight removeObjectForKey:messageIdentifier];
- });
- if(!messageToSendToKVS){
- secnotice("IDS Transport", "no message for identifier: %@", messageIdentifier);
- return;
- }
- [[KeychainSyncingOverIDSProxy idsProxy] printMessage:messageToSendToKVS state:@"IDS rejected send, message rerouted to KVS"];
-
- //cleanup timer for message
- dispatch_async(self.pingQueue, ^{
- dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:messageIdentifier]; //remove timer
- if(timer)
- dispatch_cancel(timer); //cancel timer
- [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:messageIdentifier];
- });
- }
-
- 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 senderDeviceID:(NSString*)senderDeviceID
-{
-
- if(!self->_service){
- secerror("Could not send message to peer: %@: IDS delegate uninitialized, can't use IDS to send this message", deviceName);
- 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];
-
- NSDictionary *options = @{IDSSendMessageOptionForceEncryptionOffKey : [NSNumber numberWithBool:encryptionOff] };
-
- //set our peer id and a unique id for this message
- [dataCopy setObject:peerID forKey:sendersPeerIDKey];
- [dataCopy setObject:senderDeviceIDCopy forKey:kIDSMessageSendersDeviceID];
- secnotice("IDS Transport","Our device Name: %@", senderDeviceID);
- [[KeychainSyncingOverIDSProxy idsProxy] printMessage:dataCopy state:@"sending"];
-
- NSDictionary *info;
- NSInteger errorCode = 0;
- NSUInteger numberOfDevices = 0;
- NSString *errMessage = nil;
- NSMutableSet *destinations = nil;
- NSError *localError = nil;
- NSString *identifier = nil;
- IDSDevice *device = nil;
- 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 < numberOfDevices; i++){
- device = listOfDevices[i];
- if( [ deviceName compare:device.uniqueID ] == 0){
- [destinations addObject: IDSCopyIDForDevice(device)];
- }
- }
- require_action_quiet([destinations count] != 0, fail, errorCode = kSecIDSErrorCouldNotFindMatchingAuthToken; errMessage = createErrorString(@"Could not send message to peer: %@: IDS device ID for peer does not match any devices within an IDS Account", deviceName));
-
- bool result = [self->_service sendMessage:dataCopy toDestinations:destinations priority:priority options:options identifier:&identifier error:&localError ] ;
-
- [KeychainSyncingOverIDSProxy idsProxy].outgoingMessages++;
- require_action_quiet(localError == nil && result, fail, errorCode = kSecIDSErrorFailedToSend; errMessage = createErrorString(@"Had an error sending IDS message to peer: %@", deviceName));
-
- [[KeychainSyncingOverIDSProxy idsProxy] printMessage:dataCopy state:@"sent!"];
- fail:
-
- if(errMessage != nil){
- info = [ NSDictionary dictionaryWithObjectsAndKeys:errMessage, NSLocalizedDescriptionKey, nil ];
- localError = [[NSError alloc] initWithDomain:@"com.apple.security.ids.error" code:errorCode userInfo:info ];
- secerror("%@", localError);
- [self cleanupAfterHardIDSError: data];
- }
- });
-
- return YES;
-}
-
-@end
+++ /dev/null
-/*
- * Copyright (c) 2012-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 "IDSProxy.h"
-
-@interface KeychainSyncingOverIDSProxy (Throttle)
-
-- (dispatch_source_t)setNewTimer:(int)timeout key:(NSString*)key deviceName:(NSString*)deviceName peerID:(NSString*)peerID;
-- (NSDictionary*)filterForWritableValues:(NSDictionary *)values;
-- (void)recordTimestampForAppropriateInterval:(NSMutableDictionary**)timeTable key:(NSString*)key consecutiveWrites:(NSNumber**)consecutiveWrites;
-- (void)recordTimestampOfWriteToIDS:(NSDictionary *)values deviceName:(NSString*)name peerID:(NSString*)peerid;
-
-
-@end
+++ /dev/null
-/*
- * Copyright (c) 2012-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 <Foundation/NSArray.h>
-#import <Foundation/Foundation.h>
-
-#import <Security/SecBasePriv.h>
-#import <Security/SecItemPriv.h>
-#import <utilities/debugging.h>
-#import <notify.h>
-
-#include <Security/CKBridge/SOSCloudKeychainConstants.h>
-#include <Security/SecureObjectSync/SOSARCDefines.h>
-#include <Security/SecureObjectSync/SOSCloudCircle.h>
-#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
-
-#import <IDS/IDS.h>
-#import <os/activity.h>
-
-#include <utilities/SecAKSWrappers.h>
-#include <utilities/SecCFRelease.h>
-#include <AssertMacros.h>
-
-#import "IDSPersistentState.h"
-#import "KeychainSyncingOverIDSProxy+SendMessage.h"
-#import "KeychainSyncingOverIDSProxy+Throttle.h"
-#import <utilities/SecADWrapper.h>
-
-
-static NSString *kExportUnhandledMessages = @"UnhandledMessages";
-static NSString *kMonitorState = @"MonitorState";
-
-static NSString *kMonitorPenaltyBoxKey = @"Penalty";
-static NSString *kMonitorMessageKey = @"Message";
-static NSString *kMonitorConsecutiveWrites = @"ConsecutiveWrites";
-static NSString *kMonitorLastWriteTimestamp = @"LastWriteTimestamp";
-static NSString *kMonitorMessageQueue = @"MessageQueue";
-static NSString *kMonitorPenaltyTimer = @"PenaltyTimer";
-static NSString *kMonitorDidWriteDuringPenalty = @"DidWriteDuringPenalty";
-
-static NSString *kMonitorTimeTable = @"TimeTable";
-static NSString *kMonitorFirstMinute = @"AFirstMinute";
-static NSString *kMonitorSecondMinute = @"BSecondMinute";
-static NSString *kMonitorThirdMinute = @"CThirdMinute";
-static NSString *kMonitorFourthMinute = @"DFourthMinute";
-static NSString *kMonitorFifthMinute = @"EFifthMinute";
-static NSString *kMonitorWroteInTimeSlice = @"TimeSlice";
-
-static int max_penalty_timeout = 32;
-static int seconds_per_minute = 60;
-static int queue_depth = 1;
-
-CFStringRef const IDSPAggdIncreaseThrottlingKey = CFSTR("com.apple.security.idsproxy.increasethrottle");
-CFStringRef const IDSPAggdDecreaseThrottlingKey = CFSTR("com.apple.security.idsproxy.decreasethrottle");
-
-static const int64_t kRetryTimerLeeway = (NSEC_PER_MSEC * 250); // 250ms leeway for handling unhandled messages.
-
-@implementation KeychainSyncingOverIDSProxy (Throttle)
-
--(dispatch_source_t)setNewTimer:(int)timeout key:(NSString*)key deviceName:(NSString*)deviceName peerID:(NSString*)peerID
-{
-
- __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, timeout * NSEC_PER_SEC * seconds_per_minute), DISPATCH_TIME_FOREVER, kRetryTimerLeeway);
- dispatch_source_set_event_handler(timer, ^{
- [self penaltyTimerFired:key deviceName:deviceName peerID:peerID];
- });
- dispatch_resume(timer);
- return timer;
-}
-
--(void) increasePenalty:(NSNumber*)currentPenalty key:(NSString*)key keyEntry:(NSMutableDictionary**)keyEntry deviceName:(NSString*)deviceName peerID:(NSString*)peerID
-{
- SecADAddValueForScalarKey((IDSPAggdIncreaseThrottlingKey), 1);
-
- secnotice("backoff", "increasing penalty!");
- int newPenalty = 0;
-
- if ([currentPenalty intValue] <= 0)
- newPenalty = 1;
- else
- newPenalty = fmin([currentPenalty intValue]*2, max_penalty_timeout);
-
- secnotice("backoff", "key %@, waiting %d minutes long to send next messages", key, newPenalty);
-
- NSNumber* penalty_timeout = [[NSNumber alloc]initWithInt:newPenalty];
- dispatch_source_t existingTimer = [*keyEntry objectForKey:kMonitorPenaltyTimer];
-
- if(existingTimer != nil){
- [*keyEntry removeObjectForKey:kMonitorPenaltyTimer];
- dispatch_suspend(existingTimer);
- dispatch_source_set_timer(existingTimer,dispatch_time(DISPATCH_TIME_NOW, newPenalty * NSEC_PER_SEC * seconds_per_minute), DISPATCH_TIME_FOREVER, kRetryTimerLeeway);
- dispatch_resume(existingTimer);
- [*keyEntry setObject:existingTimer forKey:kMonitorPenaltyTimer];
- }
- else{
- dispatch_source_t timer = [self setNewTimer:newPenalty key:key deviceName:deviceName peerID:peerID];
- [*keyEntry setObject:timer forKey:kMonitorPenaltyTimer];
- }
-
- [*keyEntry setObject:penalty_timeout forKey:kMonitorPenaltyBoxKey];
- [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:*keyEntry forKey:key];
-}
-
--(void) decreasePenalty:(NSNumber*)currentPenalty key:(NSString*)key keyEntry:(NSMutableDictionary**)keyEntry deviceName:(NSString*)deviceName peerID:(NSString*)peerID
-{
- SecADAddValueForScalarKey((IDSPAggdDecreaseThrottlingKey), 1);
-
- int newPenalty = 0;
- secnotice("backoff","decreasing penalty!");
- if([currentPenalty intValue] == 0 || [currentPenalty intValue] == 1)
- newPenalty = 0;
- else
- newPenalty = [currentPenalty intValue]/2;
-
- secnotice("backoff","key %@, waiting %d minutes long to send next messages", key, newPenalty);
-
- NSNumber* penalty_timeout = [[NSNumber alloc]initWithInt:newPenalty];
-
- dispatch_source_t existingTimer = [*keyEntry objectForKey:kMonitorPenaltyTimer];
- if(existingTimer != nil){
- [*keyEntry removeObjectForKey:kMonitorPenaltyTimer];
- dispatch_suspend(existingTimer);
- if(newPenalty != 0){
- dispatch_source_set_timer(existingTimer,dispatch_time(DISPATCH_TIME_NOW, newPenalty * NSEC_PER_SEC * seconds_per_minute), DISPATCH_TIME_FOREVER, kRetryTimerLeeway);
- dispatch_resume(existingTimer);
- [*keyEntry setObject:existingTimer forKey:kMonitorPenaltyTimer];
- }
- else{
- dispatch_resume(existingTimer);
- dispatch_source_cancel(existingTimer);
- }
- }
- else{
- if(newPenalty != 0){
- dispatch_source_t timer = [self setNewTimer:newPenalty key:key deviceName:deviceName peerID:peerID];
- [*keyEntry setObject:timer forKey:kMonitorPenaltyTimer];
- }
- }
-
- [*keyEntry setObject:penalty_timeout forKey:kMonitorPenaltyBoxKey];
- [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:*keyEntry forKey:key];
-
-}
-
-- (void)penaltyTimerFired:(NSString*)key deviceName:(NSString*)deviceName peerID:(NSString*)peerID
-{
- secnotice("backoff", "key: %@, !!!!!!!!!!!!!!!!penalty timeout is up!!!!!!!!!!!!", key);
- NSMutableDictionary *keyEntry = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:key];
- if(!keyEntry){
- [self initializeKeyEntry:key];
- keyEntry = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:key];
- }
- NSMutableArray *queuedMessages = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:kMonitorMessageQueue];
- secnotice("backoff","key: %@, queuedMessages: %@", key, queuedMessages);
- if(queuedMessages && [queuedMessages count] != 0){
- secnotice("backoff","key: %@, message queue not empty, writing to IDS!", key);
- [queuedMessages enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
- NSError* error = nil;
- NSDictionary* message = (NSDictionary*) obj;
- [self sendFragmentedIDSMessages:message name:deviceName peer:peerID error:&error];
- }];
-
- [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:[NSMutableArray array] forKey:kMonitorMessageQueue];
- }
- //decrease timeout since we successfully wrote messages out
- NSNumber *penalty_timeout = [keyEntry objectForKey:kMonitorPenaltyBoxKey];
- secnotice("backoff", "key: %@, current penalty timeout: %@", key, penalty_timeout);
-
- NSString* didWriteDuringTimeout = [keyEntry objectForKey:kMonitorDidWriteDuringPenalty];
- if( didWriteDuringTimeout && [didWriteDuringTimeout isEqualToString:@"YES"] )
- {
- //increase timeout since we wrote during out penalty timeout
- [self increasePenalty:penalty_timeout key:key keyEntry:&keyEntry deviceName:deviceName peerID:peerID];
- }
- else{
- //decrease timeout since we successfully wrote messages out
- [self decreasePenalty:penalty_timeout key:key keyEntry:&keyEntry deviceName:deviceName peerID:peerID];
- }
-
- //resetting the check
- [keyEntry setObject: @"NO" forKey:kMonitorDidWriteDuringPenalty];
-
- //recompute the timetable and number of consecutive writes to IDS
- NSMutableDictionary *timetableForKey = [keyEntry objectForKey:kMonitorTimeTable];
- if(timetableForKey == nil){
- timetableForKey = [self initializeTimeTable:key];
- }
- NSNumber *consecutiveWrites = [keyEntry objectForKey:kMonitorConsecutiveWrites];
- if(consecutiveWrites == nil){
- consecutiveWrites = [[NSNumber alloc] initWithInt:0];
- }
- [self recordTimestampForAppropriateInterval:&timetableForKey key:key consecutiveWrites:&consecutiveWrites];
-
- [keyEntry setObject:consecutiveWrites forKey:kMonitorConsecutiveWrites];
- [keyEntry setObject:timetableForKey forKey:kMonitorTimeTable];
- [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:keyEntry forKey:key];
-
-}
-
--(NSMutableDictionary*)initializeTimeTable:(NSString*)key
-{
- NSDate *currentTime = [NSDate date];
- NSMutableDictionary *firstMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute], kMonitorFirstMinute, @"YES", kMonitorWroteInTimeSlice, nil];
- NSMutableDictionary *secondMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 2],kMonitorSecondMinute, @"NO", kMonitorWroteInTimeSlice, nil];
- NSMutableDictionary *thirdMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 3], kMonitorThirdMinute, @"NO",kMonitorWroteInTimeSlice, nil];
- NSMutableDictionary *fourthMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 4],kMonitorFourthMinute, @"NO", kMonitorWroteInTimeSlice, nil];
- NSMutableDictionary *fifthMinute = [NSMutableDictionary dictionaryWithObjectsAndKeys:[currentTime dateByAddingTimeInterval: seconds_per_minute * 5], kMonitorFifthMinute, @"NO", kMonitorWroteInTimeSlice, nil];
-
- NSMutableDictionary *timeTable = [NSMutableDictionary dictionaryWithObjectsAndKeys: firstMinute, kMonitorFirstMinute,
- secondMinute, kMonitorSecondMinute,
- thirdMinute, kMonitorThirdMinute,
- fourthMinute, kMonitorFourthMinute,
- fifthMinute, kMonitorFifthMinute, nil];
- return timeTable;
-}
-
-- (void)initializeKeyEntry:(NSString*)key
-{
- NSMutableDictionary *timeTable = [[KeychainSyncingOverIDSProxy idsProxy] initializeTimeTable:key];
- NSDate *currentTime = [NSDate date];
-
- NSMutableDictionary *keyEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys: key, kMonitorMessageKey, @0, kMonitorConsecutiveWrites, currentTime, kMonitorLastWriteTimestamp, @0, kMonitorPenaltyBoxKey, timeTable, kMonitorTimeTable,[NSMutableArray array], kMonitorMessageQueue, nil];
-
- [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:keyEntry forKey:key];
-
-}
-
-- (void)recordTimestampForAppropriateInterval:(NSMutableDictionary**)timeTable key:(NSString*)key consecutiveWrites:(NSNumber**)consecutiveWrites
-{
- NSDate *currentTime = [NSDate date];
- __block int cWrites = [*consecutiveWrites intValue];
- __block BOOL foundTimeSlot = NO;
- __block NSMutableDictionary *previousTable = nil;
-
- NSArray *sortedTimestampKeys = [[*timeTable allKeys] sortedArrayUsingSelector:@selector(compare:)];
- NSMutableDictionary* timeTableStrong = *timeTable;
-
- [sortedTimestampKeys enumerateObjectsUsingBlock:^(id arrayObject, NSUInteger idx, BOOL *stop)
- {
- if(foundTimeSlot == YES)
- return;
-
- NSString *sortedKey = (NSString*)arrayObject;
-
- //grab the dictionary containing write information
- //(date, boolean to check if a write occured in the timeslice,
- NSMutableDictionary *minutesTable = [timeTableStrong objectForKey: sortedKey];
- if(minutesTable == nil)
- minutesTable = [[KeychainSyncingOverIDSProxy idsProxy] initializeTimeTable:key];
-
- NSString *minuteKey = (NSString*)sortedKey;
- NSDate *timeStampForSlice = [minutesTable objectForKey:minuteKey];
-
- if(timeStampForSlice && [timeStampForSlice compare:currentTime] == NSOrderedDescending){
- foundTimeSlot = YES;
- NSString* written = [minutesTable objectForKey:kMonitorWroteInTimeSlice];
- //figure out if we have previously recorded a write in this time slice
- if([written isEqualToString:@"NO"]){
- [minutesTable setObject:@"YES" forKey:kMonitorWroteInTimeSlice];
- if(previousTable != nil){
- //if we wrote in the previous time slice count the current time as in the consecutive write count
- written = [previousTable objectForKey:kMonitorWroteInTimeSlice];
- if([written isEqualToString:@"YES"]){
- cWrites++;
- }
- else if ([written isEqualToString:@"NO"]){
- cWrites = 0;
- }
- }
- }
- return;
- }
- previousTable = minutesTable;
- }];
-
- if(foundTimeSlot == NO){
- //reset the time table
- secnotice("backoff","didn't find a time slot, resetting the table");
-
- //record if a write occured between the last time slice of
- //the time table entries and now.
- NSMutableDictionary *lastTable = [*timeTable objectForKey:kMonitorFifthMinute];
- NSDate *lastDate = [lastTable objectForKey:kMonitorFifthMinute];
-
- if(lastDate && ((double)[currentTime timeIntervalSinceDate: lastDate] >= seconds_per_minute)){
- *consecutiveWrites = [[NSNumber alloc]initWithInt:0];
- }
- else{
- NSString* written = [lastTable objectForKey:kMonitorWroteInTimeSlice];
- if(written && [written isEqualToString:@"YES"]){
- cWrites++;
- *consecutiveWrites = [[NSNumber alloc]initWithInt:cWrites];
- }
- else{
- *consecutiveWrites = [[NSNumber alloc]initWithInt:0];
- }
- }
-
- *timeTable = [[KeychainSyncingOverIDSProxy idsProxy] initializeTimeTable:key];
- return;
- }
- *consecutiveWrites = [[NSNumber alloc]initWithInt:cWrites];
-}
-- (void)recordTimestampOfWriteToIDS:(NSDictionary *)values deviceName:(NSString*)name peerID:(NSString*)peerid
-{
- if([[KeychainSyncingOverIDSProxy idsProxy].monitor count] == 0){
- [values enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
- {
- [self initializeKeyEntry: key];
- }];
- }
- else{
- [values enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
- {
- NSMutableDictionary *keyEntry = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:key];
- if(keyEntry == nil){
- [self initializeKeyEntry: key];
- }
- else{
- NSNumber *penalty_timeout = [keyEntry objectForKey:kMonitorPenaltyBoxKey];
- NSDate *lastWriteTimestamp = [keyEntry objectForKey:kMonitorLastWriteTimestamp];
- NSMutableDictionary *timeTable = [keyEntry objectForKey: kMonitorTimeTable];
- NSNumber *existingWrites = [keyEntry objectForKey: kMonitorConsecutiveWrites];
- NSDate *currentTime = [NSDate date];
-
- //record the write happened in our timetable structure
- [self recordTimestampForAppropriateInterval:&timeTable key:key consecutiveWrites:&existingWrites];
-
- int consecutiveWrites = [existingWrites intValue];
- secnotice("backoff","consecutive writes: %d", consecutiveWrites);
- [keyEntry setObject:existingWrites forKey:kMonitorConsecutiveWrites];
- [keyEntry setObject:timeTable forKey:kMonitorTimeTable];
- [keyEntry setObject:currentTime forKey:kMonitorLastWriteTimestamp];
- [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:keyEntry forKey:key];
-
- if( (penalty_timeout && [penalty_timeout intValue] != 0 ) || ((double)[currentTime timeIntervalSinceDate: lastWriteTimestamp] <= 60 && consecutiveWrites >= 5)){
-
- if( (penalty_timeout == nil || [penalty_timeout intValue] == 0) && consecutiveWrites == 5){
- secnotice("backoff","written for 5 consecutive minutes, time to start throttling");
- [self increasePenalty:penalty_timeout key:key keyEntry:&keyEntry deviceName:name peerID:peerid];
- }
- else
- secnotice("backoff","monitor: keys have been written for 5 or more minutes, recording we wrote during timeout");
-
- //record we wrote during a timeout
- [keyEntry setObject: @"YES" forKey:kMonitorDidWriteDuringPenalty];
- }
- else if((double)[currentTime timeIntervalSinceDate: lastWriteTimestamp] <= 60 && consecutiveWrites < 5){
- //for debugging purposes
- secnotice("backoff","monitor: still writing freely");
- [keyEntry setObject: @"NO" forKey:kMonitorDidWriteDuringPenalty];
- }
- else if([penalty_timeout intValue] != 0 && ((double)[currentTime timeIntervalSinceDate: lastWriteTimestamp] > 60 && consecutiveWrites > 5) ){
-
- //encountered a write even though we're in throttle mode
- [keyEntry setObject: @"YES" forKey:kMonitorDidWriteDuringPenalty];
- }
- }
- }];
- }
-}
-
-- (NSDictionary*)filterForWritableValues:(NSDictionary *)values
-{
- secnotice("backoff", "filterForWritableValues: %@", values);
- NSMutableDictionary *keyEntry_operationType = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:@"IDSMessageOperation"];
-
- secnotice("backoff", "keyEntry_operationType: %@", keyEntry_operationType);
-
- NSNumber *penalty = [keyEntry_operationType objectForKey:kMonitorPenaltyBoxKey];
-
- if(penalty && [penalty intValue] != 0){
-
- NSMutableArray *queuedMessage = [[KeychainSyncingOverIDSProxy idsProxy].monitor objectForKey:kMonitorMessageQueue];
- if(queuedMessage == nil)
- queuedMessage = [[NSMutableArray alloc] initWithCapacity:queue_depth];
-
- secnotice("backoff", "writing to queuedMessages: %@", queuedMessage);
-
- if([queuedMessage count] == 0)
- [queuedMessage addObject:values];
- else
- [queuedMessage replaceObjectAtIndex:(queue_depth-1) withObject: values];
-
- [[KeychainSyncingOverIDSProxy idsProxy].monitor setObject:queuedMessage forKey:kMonitorMessageQueue];
- return NULL;
- }
-
- return values;
-}
-
-@end
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Application-Group</key>
- <array>
- <string>InternetAccounts</string>
- </array>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleExecutable</key>
- <string>${EXECUTABLE_NAME}</string>
- <key>CFBundleIconFile</key>
- <string></string>
- <key>CFBundleIdentifier</key>
- <string>com.apple.security.keychainsyncingoveridsproxy</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>${PRODUCT_NAME}</string>
- <key>CFBundlePackageType</key>
- <string>BNDL</string>
- <key>CFBundleShortVersionString</key>
- <string>1.0</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>${CURRENT_PROJECT_VERSION}</string>
- <key>LSBackgroundOnly</key>
- <true/>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright © 2013 Apple, Inc. All rights reserved.</string>
-</dict>
-</plist>
+++ /dev/null
-.Dd November 02, 2016
-.Dt KeychainSyncingOverIDSProxy 8
-.Os
-.Sh NAME
-.Nm KeychainSyncingOverIDSProxy
-.Nd part of iCloud Keychain syncing.
-.Sh DESCRIPTION
-.Nm
-part of iCloud Keychain syncing.
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>EnablePressuredExit</key>
- <true/>
- <key>EnvironmentVariables</key>
- <dict>
- <key>DEBUGSCOPE</key>
- <string>all</string>
- <key>WAIT4DEBUGGER</key>
- <string>NO</string>
- </dict>
- <key>Label</key>
- <string>com.apple.security.keychainsyncingoveridsproxy</string>
- <key>LaunchEvents</key>
- <dict>
- <key>com.apple.notifyd.matching</key>
- <dict>
- <key>com.apple.mobile.keybagd.first_unlock</key>
- <dict>
- <key>Notification</key>
- <string>com.apple.mobile.keybagd.first_unlock</string>
- </dict>
- <key>com.apple.mobile.keybagd.lock_status</key>
- <dict>
- <key>Notification</key>
- <string>com.apple.mobile.keybagd.lock_status</string>
- </dict>
- <key>com.apple.keystore.lockstatus</key>
- <dict>
- <key>Notification</key>
- <string>com.apple.keystore.lockstatus</string>
- </dict>
- </dict>
- </dict>
- <key>MachServices</key>
- <dict>
- <key>com.apple.private.alloy.keychainsync-idswake</key>
- <true/>
- <key>com.apple.security.keychainsyncingoveridsproxy</key>
- <true/>
- </dict>
- <key>Program</key>
- <string>/System/Library/Frameworks/Security.framework/KeychainSyncingOverIDSProxy.bundle/KeychainSyncingOverIDSProxy</string>
- <key>ProgramArguments</key>
- <array>
- <string>/System/Library/Frameworks/Security.framework/KeychainSyncingOverIDSProxy.bundle/KeychainSyncingOverIDSProxy</string>
- </array>
- <key>enabletransactions</key>
- <true/>
-</dict>
-</plist>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>LaunchEvents</key>
- <dict>
- <key>com.apple.notifyd.matching</key>
- <dict>
- <key>com.apple.keystore.lockstatus</key>
- <dict>
- <key>Notification</key>
- <string>com.apple.keystore.lockstatus</string>
- </dict>
- </dict>
- </dict>
- <key>Program</key>
- <string>/System/Library/Frameworks/Security.framework/Versions/A/Resources/KeychainSyncingOverIDSProxy.bundle/Contents/MacOS/KeychainSyncingOverIDSProxy</string>
- <key>Label</key>
- <string>com.apple.security.keychainsyncingoveridsproxy</string>
- <key>EnvironmentVariables</key>
- <dict>
- <key>DEBUGSCOPE</key>
- <string>all</string>
- <key>WAIT4DEBUGGER</key>
- <string>NO</string>
- </dict>
- <key>ProcessType</key>
- <string>Adaptive</string>
- <key>MachServices</key>
- <dict>
- <key>com.apple.private.alloy.keychainsync-idswake</key>
- <true/>
- <key>com.apple.security.keychainsyncingoveridsproxy</key>
- <true/>
- </dict>
- <key>ProgramArguments</key>
- <array>
- <string>/System/Library/Frameworks/Security.framework/Versions/A/Resources/KeychainSyncingOverIDSProxy.bundle/Contents/MacOS/KeychainSyncingOverIDSProxy</string>
- </array>
- <key>EnablePressuredExit</key>
- <true/>
-</dict>
-</plist>
+++ /dev/null
-/* Localized versions of Info.plist keys */
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>keychain-cloud-circle</key>
- <true/>
- <key>com.apple.wifi.manager-access</key>
- <true/>
- <key>com.apple.private.ids.remoteurlconnection</key>
- <true/>
- <key>com.apple.private.ids.force-encryption-off</key>
- <array>
- <string>com.apple.private.alloy.keychainsync</string>
- </array>
- <key>com.apple.private.ids.messaging.high-priority</key>
- <array>
- <string>com.apple.private.alloy.keychainsync</string>
- </array>
- <key>com.apple.private.ids.messaging</key>
- <array>
- <string>com.apple.private.alloy.keychainsync</string>
- </array>
- <key>keychain-access-groups</key>
- <array>
- <string>apple</string>
- <string>IMCore</string>
- <string>InternetAccounts</string>
- </array>
- <key>application-identifier</key>
- <string>com.apple.security.keychainsyncingoveridsproxy</string>
-</dict>
-</plist>
+++ /dev/null
-/*
- * 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@
- */
-
-#include <AssertMacros.h>
-
-#import <Foundation/Foundation.h>
-#import <Security/Security.h>
-#import <utilities/SecCFRelease.h>
-#import <xpc/xpc.h>
-#import <xpc/private.h>
-#import <CoreFoundation/CFXPCBridge.h>
-#import <sysexits.h>
-#import <syslog.h>
-#import <CommonCrypto/CommonDigest.h>
-#include <utilities/SecXPCError.h>
-#include <TargetConditionals.h>
-#include "SOSCloudKeychainConstants.h"
-#import <Security/SecureObjectSync/SOSInternal.h>
-#import "KeychainSyncingOverIDSProxy+SendMessage.h"
-
-int idsproxymain(int argc, const char *argv[]);
-
-#define PROXYXPCSCOPE "idsproxy"
-
-static void describeXPCObject(char *prefix, xpc_object_t object)
-{
- // This is useful for debugging.
- if (object)
- {
- char *desc = xpc_copy_description(object);
- secdebug(PROXYXPCSCOPE, "%s%s\n", prefix, desc);
- free(desc);
- }
- else
- secdebug(PROXYXPCSCOPE, "%s<NULL>\n", prefix);
-
-}
-
-static void idskeychainsyncingproxy_peer_dictionary_handler(const xpc_connection_t peer, xpc_object_t event)
-{
- bool result = false;
- int err = 0;
-
- require_action_string(xpc_get_type(event) == XPC_TYPE_DICTIONARY, xit, err = -51, "expected XPC_TYPE_DICTIONARY");
-
- const char *operation = xpc_dictionary_get_string(event, kMessageKeyOperation);
- require_action(operation, xit, result = false);
-
- // Check protocol version
- uint64_t version = xpc_dictionary_get_uint64(event, kMessageKeyVersion);
- secdebug(PROXYXPCSCOPE, "Reply version: %lld\n", version);
- require_action(version == kCKDXPCVersion, xit, result = false);
-
- // Operations
- secdebug(PROXYXPCSCOPE, "Handling %s operation", operation);
-
-
- if(operation && !strcmp(operation, kOperationGetDeviceID)){
- [[KeychainSyncingOverIDSProxy idsProxy] doSetIDSDeviceID];
- xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
- xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, true);
- xpc_connection_send_message(peer, replyMessage);
- secdebug(PROXYXPCSCOPE, "Set our IDS Device ID message sent");
-
- }
- else if(operation && !strcmp(operation, kOperationGetIDSPerfCounters)){
- NSDictionary *counters = [[KeychainSyncingOverIDSProxy idsProxy] collectStats];
- xpc_object_t xMessages = _CFXPCCreateXPCObjectFromCFObject((__bridge CFDictionaryRef)(counters));
-
- xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
- xpc_dictionary_set_value(replyMessage, kMessageKeyValue, xMessages);
- xpc_connection_send_message(peer, replyMessage);
- secdebug(PROXYXPCSCOPE, "Retrieved counters");
- }
- else if (operation && !strcmp(operation, kOperationGetPendingMesages))
- {
- NSDictionary* messages = [[KeychainSyncingOverIDSProxy idsProxy] retrievePendingMessages];
- xpc_object_t xMessages = _CFXPCCreateXPCObjectFromCFObject((__bridge CFDictionaryRef)(messages));
-
- xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
- xpc_dictionary_set_value(replyMessage, kMessageKeyValue, xMessages);
-
- xpc_connection_send_message(peer, replyMessage);
- secdebug(PROXYXPCSCOPE, "retrieved pending messages");
-
- }
- else if(operation && !strcmp(operation, kOperationSendDeviceList)) //IDS device availability check
- {
- xpc_object_t xidsDeviceList = xpc_dictionary_get_value(event, kMessageKeyValue);
- xpc_object_t xPeerID = xpc_dictionary_get_value(event, kMessageKeyPeerID);
-
- NSArray *idsList = (__bridge_transfer NSArray*)(_CFXPCCreateCFObjectFromXPCObject(xidsDeviceList));
- NSString *peerID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xPeerID));
-
- bool isMessageArray = (CFGetTypeID((__bridge CFTypeRef)(idsList)) == CFArrayGetTypeID());
- bool isPeerIDString = (CFGetTypeID((__bridge CFTypeRef)(peerID)) == CFStringGetTypeID());
-
- require_quiet(isMessageArray, xit);
- require_quiet(isPeerIDString, xit);
-
- [[KeychainSyncingOverIDSProxy idsProxy] pingDevices:idsList peerID:peerID];
-
- xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
- xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, true);
-
- xpc_connection_send_message(peer, replyMessage);
- secdebug(PROXYXPCSCOPE, "IDS device list sent");
- }
- else if (operation && !strcmp(operation, kOperationSendFragmentedIDSMessage))
- {
- 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 senderDeviceID:senderDeviceID error:&error];
-
- xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
- xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, object);
-
- if(error){
- xpc_object_t xerrobj = SecCreateXPCObjectWithCFError((__bridge CFErrorRef)(error));
- xpc_dictionary_set_value(replyMessage, kMessageKeyError, xerrobj);
- }
- xpc_connection_send_message(peer, replyMessage);
- secdebug(PROXYXPCSCOPE, "IDS message sent");
- }
- else if (operation && !strcmp(operation, kOperationSendIDSMessage)) //for IDS tests
- {
- 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 senderDeviceID:senderDeviceID])
- {
- object = true;
- NSString *useAckModel = [messageDictionaryCopy objectForKey:(__bridge NSString*)(kIDSMessageUsesAckModel)];
- if(object && [useAckModel compare:@"YES"] == NSOrderedSame && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){
- secnotice("IDS Transport", "setting timer!");
- [[KeychainSyncingOverIDSProxy idsProxy] setMessageTimer:localMessageIdentifier deviceID:deviceName message:messageDictionaryCopy];
- }
- }
- else{
- SOSErrorCreate(kSecIDSErrorFailedToSend, &error, NULL, CFSTR("Failed to send keychain data message over IDS"));
- secerror("Could not send message");
- }
-
- xpc_object_t replyMessage = xpc_dictionary_create_reply(event);
- xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, object);
-
- if(error){
- xpc_object_t xerrobj = SecCreateXPCObjectWithCFError(error);
- xpc_dictionary_set_value(replyMessage, kMessageKeyError, xerrobj);
- }
- CFReleaseNull(error);
- xpc_connection_send_message(peer, replyMessage);
- secdebug(PROXYXPCSCOPE, "IDS message sent");
- }
-
- else
- {
- char *description = xpc_copy_description(event);
- secdebug(PROXYXPCSCOPE, "Unknown op=%s request from pid %d: %s", operation, xpc_connection_get_pid(peer), description);
- free(description);
- }
- result = true;
-xit:
- if (!result)
- describeXPCObject("handle_operation fail: ", event);
-}
-
-static void idskeychainsyncingproxy_peer_event_handler(xpc_connection_t peer, xpc_object_t event)
-{
- xpc_type_t type = xpc_get_type(event);
- if (type == XPC_TYPE_ERROR) {
- if (event == XPC_ERROR_CONNECTION_INVALID) {
- // The client process on the other end of the connection has either
- // crashed or canceled the connection. After receiving this error,
- // the connection is in an invalid state, and you do not need to
- // call xpc_connection_cancel(). Just tear down any associated state
- // here.
- } else if (event == XPC_ERROR_TERMINATION_IMMINENT) {
- // Handle per-connection termination cleanup.
- }
- } else {
- assert(type == XPC_TYPE_DICTIONARY);
- dispatch_async(dispatch_get_main_queue(), ^{
- idskeychainsyncingproxy_peer_dictionary_handler(peer, event);
- });
- }
-}
-
-static void idskeychainsyncingproxy_event_handler(xpc_connection_t peer)
-{
- // By defaults, new connections will target the default dispatch
- // concurrent queue.
-
- if (xpc_get_type(peer) != XPC_TYPE_CONNECTION)
- {
- secdebug(PROXYXPCSCOPE, "expected XPC_TYPE_CONNECTION");
- return;
- }
-
- xpc_connection_set_event_handler(peer, ^(xpc_object_t event)
- {
- idskeychainsyncingproxy_peer_event_handler(peer, event);
- });
-
- // This will tell the connection to begin listening for events. If you
- // have some other initialization that must be done asynchronously, then
- // you can defer this call until after that initialization is done.
- 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");
- char *wait4debugger = getenv("WAIT4DEBUGGER");
-
- if (wait4debugger && !strcasecmp("YES", wait4debugger))
- {
- syslog(LOG_ERR, "Waiting for debugger");
- kill(getpid(), SIGTSTP);
- }
-
- // DISPATCH_TARGET_QUEUE_DEFAULT
- xpc_connection_t listener = xpc_connection_create_mach_service(xpcIDSServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
- xpc_connection_set_event_handler(listener, ^(xpc_object_t object){ idskeychainsyncingproxy_event_handler(object); });
-
- [KeychainSyncingOverIDSProxy idsProxy];
-
- if([[KeychainSyncingOverIDSProxy idsProxy] haveMessagesInFlight] &&
- [KeychainSyncingOverIDSProxy idsProxy].isIDSInitDone &&
- [KeychainSyncingOverIDSProxy idsProxy].sendRestoredMessages) {
- [[KeychainSyncingOverIDSProxy idsProxy] sendPersistedMessagesAgain];
- [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);
-
- @autoreleasepool
- {
- secdebug(PROXYXPCSCOPE, "Starting mainRunLoop");
- NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
- [runLoop run];
- }
-
- secdebug(PROXYXPCSCOPE, "Exiting KeychainSyncingOverIDSProxy");
-
- return EXIT_FAILURE;
-}
-
-int main(int argc, const char *argv[])
-{
- return idsproxymain(argc, argv);
-}
--- /dev/null
+//
+// ClientInfoByNotification.m
+// Security
+//
+// Created by murf on 4/12/18.
+//
+
+#import <XCTest/XCTest.h>
+#import <Foundation/Foundation.h>
+#import <Foundation/NSXPCConnection_Private.h>
+#import <Security/Security.h>
+#include <Security/SecureObjectSync/SOSCloudCircle.h>
+#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
+
+#undef DOVIEWMACRO
+#define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULTSETTING, INITIALSYNCSETTING, ALWAYSONSETTING, BACKUPSETTING, V0SETTING) \
+const CFStringRef k##SYSTEM##View##VIEWNAME = CFSTR(DEFSTRING);
+#include "Security/SecureObjectSync/ViewList.list"
+
+#import "DeviceSimulatorProtocol.h"
+#import "MultiDeviceNetworking.h"
+#import <objc/runtime.h>
+
+
+#if 1
+@interface MDDevice2 : NSObject<DeviceSimulatorProtocol>
+@property NSXPCConnection *connection;
+@property NSString *name;
+- (instancetype)initWithConnection:(NSXPCConnection *)connection;
+@end
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wprotocol"
+@implementation MDDevice2
+
+- (instancetype)initWithConnection:(NSXPCConnection *)connection
+{
+ self = [super init];
+ if (self) {
+ self.connection = connection;
+ }
+ return self;
+}
+
+/* Oh, ObjC, you are my friend */
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ struct objc_method_description desc = protocol_getMethodDescription(@protocol(DeviceSimulatorProtocol), [invocation selector], true, true);
+ if (desc.name == NULL) {
+ [super forwardInvocation:invocation];
+ } else {
+ __block bool dooooooEeeeetExclamationPoint = true;
+ id object = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
+ NSLog(@"peer failed with: %@", error);
+ dooooooEeeeetExclamationPoint = false;
+ //abort();
+ }];
+ if(dooooooEeeeetExclamationPoint) {
+ [invocation invokeWithTarget:object];
+ }
+ }
+}
+@end
+#pragma clang diagnostic pop
+#endif
+
+@interface ClientInfoByNotification : XCTestCase
+@property NSMutableDictionary<NSString *,MDDevice2 *> *connections;
+@property MultiDeviceNetworking *network;
+@property MDDevice2 *masterDevice;
+@end
+
+static NSString *testInstanceUUID;
+
+@implementation ClientInfoByNotification
+
+
++ (void)setUp
+{
+ testInstanceUUID = [[NSUUID UUID] UUIDString];
+}
+
+- (void)setUp
+{
+ self.connections = [NSMutableDictionary dictionary];
+ self.network = [[MultiDeviceNetworking alloc] init];
+ [self runSigninWithAdditionalDevices:0];
+}
+
+- (void)tearDown
+{
+ __block uint64_t totalUserUsec = 0, totalSysUsec = 0;
+ NSMutableDictionary *result = [NSMutableDictionary dictionary];
+
+ for (NSString *name in self.connections) {
+ MDDevice2 *device = self.connections[name];
+ NSLog(@"device: %@", name);
+ [device diagnosticsCPUUsage:^(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error) {
+ NSLog(@"%@: %d: u:%llu s:%llu", device.name, success, (unsigned long long)user_usec, (unsigned long long)sys_usec);
+ totalUserUsec += user_usec;
+ totalSysUsec += sys_usec;
+ result[[NSString stringWithFormat:@"cpu-%@", name]] = @{ @"user_usec" : @(user_usec), @"system_usec" : @(sys_usec)};
+ }];
+ }
+
+ result[@"cpu-total"] = @{ @"user_usec" : @(totalUserUsec), @"system_usec" : @(totalSysUsec)};
+
+ NSLog(@"Total: u:%llu s:%llu", (unsigned long long)totalUserUsec, (unsigned long long)totalSysUsec);
+
+ /* XXX check for leaks in all devices */
+ for (NSString *name in self.connections) {
+ MDDevice2 *device = self.connections[name];
+ [device.connection invalidate];
+ }
+ self.connections = NULL;
+ [self.network dumpKVSState];
+ [self.network dumpCounters];
+ [self.network disconnectAll];
+ self.network = NULL;
+
+ NSData * jsonData = [NSJSONSerialization dataWithJSONObject:result options:0 error:NULL];
+
+ [jsonData writeToFile:[NSString stringWithFormat:@"/tmp/test-result-%@", [self name]] atomically:NO];
+
+}
+
+//MARK: - Device logic
+
+- (MDDevice2 *)device:(NSString *)name model:(NSString *)model version:(NSString *)version
+{
+ MDDevice2 *device = self.connections[name];
+ if (device != NULL) {
+ return NULL;
+ }
+
+ NSXPCConnection *conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.Security.DeviceSimulator"];
+ conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(DeviceSimulatorProtocol)];
+ [conn _setUUID:[NSUUID UUID]]; // select a random instance
+ [conn resume];
+
+ device = [[MDDevice2 alloc] initWithConnection:conn];
+ device.name = name;
+
+ self.connections[name] = device;
+
+ [device setDevice:name
+ version:version
+ model:model
+ testInstance:testInstanceUUID
+ network:[self.network endpoint]
+ complete:^(BOOL success) {
+ if (!success) {
+ abort();
+ }
+ }];
+ return device;
+}
+
+- (void)runSigninWithAdditionalDevices:(unsigned)additionalDeviceCount {
+ signal(SIGPIPE, SIG_IGN);
+ _masterDevice = [self device:@"ipad" model:@"iPad" version:@"15E143a"];
+ NSMutableArray<MDDevice2 *> *otherDevices = [NSMutableArray array];
+
+ [_masterDevice setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ }];
+
+ [_masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+
+ sleep(4); // give "kvs" a chance to get the word out.
+ for (unsigned n = 0; n < additionalDeviceCount; n++) {
+ MDDevice2 *dev = [self device:[NSString stringWithFormat:@"mac-%u", n] model:@"Mac Pro" version:@"17E121"];
+
+ [dev setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
+ XCTAssert(success, "%u: Expect success: %@", n, error);
+ }];
+
+ __block NSString *devPeerID = NULL;
+ [dev sosRequestToJoin:^(bool success, NSString *peerID, NSError *error) {
+ XCTAssert(success, "%u: Expect success: %@", n, error);
+ XCTAssertNotEqual(peerID, NULL, @"%u: expected to find peerID for peer2", n);
+ devPeerID = peerID;
+ }];
+
+ __block NSError *localErr = nil;
+ __block bool done = false;
+ for(int tries=0; tries < 5; tries++) {
+
+ [_masterDevice sosApprovePeer:devPeerID complete:^(BOOL success, NSError *error) {
+ localErr = [error copy];
+ if(success) {
+ localErr = nil;
+ done = true;
+ }
+ }];
+ if(done) break;
+ sleep(10);
+ }
+ XCTAssert(done, "%u: Expect success (for approve of %@): %@", n, devPeerID, localErr);
+
+ [otherDevices addObject:dev];
+ }
+}
+
+- (void)testSOSIsThisDeviceInCircle
+{
+ [self measureBlock:^{
+ for(int i=0; i<100; i++) {
+ [self.masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+ }
+ }];
+}
+
+- (void)testSOSIsThisDeviceInCircleNonCached
+{
+ [self measureBlock:^{
+ for(int i=0; i<100; i++) {
+ [self.masterDevice sosCircleStatusNonCached:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+ }
+ }];
+}
+
+
+#if TARGET_OS_IPHONE
+- (void)testSOSViews2
+{
+ [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewAutofillPasswords withCompletion: ^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCViewNotMember, @"expected to be not in view: %@", error);
+ }];
+ [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewHomeKit withCompletion: ^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error);
+ }];
+ [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewWiFi withCompletion: ^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCViewNotMember, @"expected to be not in view: %@", error);
+ }];
+ [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewContinuityUnlock withCompletion: ^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error);
+ }];
+
+ [self.masterDevice sosEnableAllViews:^(BOOL success, NSError *error) {
+ XCTAssert(success, "Expected to enable all views");
+ }];
+
+ //uint64_t bitmask = [self.masterDevice sosCachedCircleBitmask];
+ //XCTAssertEqual(bitmask, 0, "Expected bitmask to be %llx", bitmask);
+
+
+ [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewWiFi withCompletion: ^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error);
+ }];
+
+ [self.masterDevice sosCachedViewBitmask:^(uint64_t bitmask) {
+ XCTAssertEqual(bitmask, 33554367, @"expected bitmask of %llx", bitmask);
+ }];
+
+ [self measureBlock:^{
+ for(int i=0; i<100; i++) {
+ [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewHomeKit withCompletion: ^void(SOSCCStatus status, NSError *error) {
+ }];
+ }
+ }];
+}
+#endif
+
+
+- (void)testSOSMultiView
+{
+ [self.masterDevice sosEnableAllViews:^(BOOL success, NSError *error) {
+ XCTAssert(success, "Expected to enable all views");
+ }];
+
+ [self.masterDevice sosICKStatus: ^void(bool status) {
+ XCTAssert(status, "Expected to enable iCloud Keychain");
+ }];
+
+ [self measureBlock:^{
+ for(int i=0; i<100; i++) {
+ [self.masterDevice sosICKStatus: ^void(bool status) {
+ }];
+ }
+ }];
+}
+
+- (void) testMaster2
+{
+ [self testSOSMultiView];
+}
+
+@end
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.private.aps-connection-initiate</key>
+ <true/>
+ <key>aps-connection-initiate</key>
+ <true/>
+ <key>aps-environment</key>
+ <string>serverPreferred</string>
+ <key>com.apple.aps-environment</key>
+ <string>serverPreferred</string>
+ <key>com.apple.private.cloudkit.setEnvironment</key>
+ <true/>
+ <key>com.apple.developer.icloud-container-identifiers</key>
+ <array>
+ <string>iCloud.com.apple.security.keychain</string>
+ </array>
+ <key>com.apple.developer.icloud-services</key>
+ <array>
+ <string>CloudKit</string>
+ </array>
+ <key>com.apple.developer.icloud-container-environment</key>
+ <string>Development</string>
+ <key>com.apple.private.cloudkit.systemService</key>
+ <true/>
+ <key>com.apple.private.cloudkit.buddyAccess</key>
+ <true/>
+ <key>com.apple.private.appleaccount.app-hidden-from-icloud-settings</key>
+ <true/>
+ <key>com.apple.private.tcc.allow</key>
+ <array>
+ <string>kTCCServiceLiverpool</string>
+ </array>
+ <key>com.apple.application-identifier</key>
+ <string>com.apple.securityd</string>
+ <key>application-identifier</key>
+ <string>com.apple.securityd</string>
+ <key>com.apple.private.keychain.sysbound</key>
+ <true/>
+ <key>keychain-cloud-circle</key>
+ <true/>
+ <key>com.apple.keystore.access-keychain-keys</key>
+ <true/>
+ <key>com.apple.keystore.lockassertion</key>
+ <true/>
+ <key>com.apple.keystore.device</key>
+ <true/>
+ <key>modify-anchor-certificates</key>
+ <true/>
+ <key>com.apple.private.system-keychain</key>
+ <true/>
+ <key>keychain-access-groups</key>
+ <array>
+ <string>com.apple.security.regressions</string>
+ <string>lockdown-identities</string>
+ <string>apple</string>
+ <string>com.apple.security.sos</string>
+ <string>com.apple.cfnetwork</string>
+ <string>123456.test.group</string>
+ <string>123456.test.group2</string>
+ </array>
+</dict>
+</plist>
--- /dev/null
+//
+// DeviceSimulator.h
+// DeviceSimulator
+//
+//
+
+#import <Foundation/Foundation.h>
+#import "DeviceSimulatorProtocol.h"
+
+extern NSString *deviceInstance;
+void boot_securityd(NSXPCListenerEndpoint *network);
+
+// This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection.
+@interface DeviceSimulator : NSObject <DeviceSimulatorProtocol>
+@property NSXPCConnection *conn;
+@property NSString *name;
+@end
--- /dev/null
+//
+// DeviceSimulator.m
+// DeviceSimulator
+//
+
+#import <Foundation/Foundation.h>
+#import <Foundation/NSXPCConnection_Private.h>
+#import <securityd/SOSCloudCircleServer.h>
+#import <Security/SecureObjectSync/SOSPeerInfo.h>
+#import <Security/SecureObjectSync/SOSCloudCircleInternal.h>
+#import <Security/SecureObjectSync/SOSViews.h>
+#import <Security/SecureObjectSync/SOSInternal.h>
+
+#import <stdlib.h>
+#import <unistd.h>
+#import <libproc.h>
+
+#import "keychain/ckks/CKKS.h"
+#import "SOSCloudKeychainClient.h"
+
+#import "DeviceSimulatorProtocol.h"
+#import "DeviceSimulator.h"
+
+
+@implementation DeviceSimulator
+
+- (void)setDevice:(NSString *)name
+ version:(NSString *)version
+ model:(NSString *)model
+ testInstance:(NSString *)testUUID
+ network:(NSXPCListenerEndpoint *)network
+ complete:(void(^)(BOOL success))complete
+{
+ self.name = name;
+
+ SecCKKSDisable(); // for now
+ SecCKKSContainerName = [NSString stringWithFormat:@"com.apple.test.p01.B.%@.com.apple.security.keychain", testUUID];
+
+ SOSCCSetGestalt_Server((__bridge CFStringRef)name, (__bridge CFStringRef)version,
+ (__bridge CFStringRef)model, (__bridge CFStringRef)deviceInstance);
+
+ boot_securityd(network);
+
+ complete(TRUE);
+}
+
+
+- (void)secItemAdd:(NSDictionary *)input complete:(void (^)(OSStatus, NSDictionary *))reply
+{
+ NSMutableDictionary *attributes = [input mutableCopy];
+ CFTypeRef data = NULL;
+
+ attributes[(__bridge NSString *)kSecReturnAttributes] = @YES;
+ attributes[(__bridge NSString *)kSecReturnPersistentRef] = @YES;
+ attributes[(__bridge NSString *)kSecReturnData] = @YES;
+
+ OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, &data);
+ NSDictionary *returnData = CFBridgingRelease(data);
+
+ reply(status, returnData);
+}
+
+- (void)secItemCopyMatching:(NSDictionary *)input complete:(void (^)(OSStatus, NSArray<NSDictionary *>*))reply
+{
+ NSMutableDictionary *attributes = [input mutableCopy];
+ CFTypeRef data = NULL;
+
+ attributes[(__bridge NSString *)kSecReturnAttributes] = @YES;
+ attributes[(__bridge NSString *)kSecReturnData] = @YES;
+ attributes[(__bridge NSString *)kSecReturnPersistentRef] = @YES;
+ attributes[(__bridge NSString *)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll;
+
+ OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &data);
+ NSArray<NSDictionary *>* array = CFBridgingRelease(data);
+ NSMutableArray *result = [NSMutableArray array];
+ for (NSDictionary *d in array) {
+ NSMutableDictionary *r = [d mutableCopy];
+ r[@"accc"] = nil;
+ [result addObject:r];
+ }
+
+ reply(status, result);
+}
+
+- (void)setupSOSCircle:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *error))complete
+{
+ CFErrorRef cferror = NULL;
+ bool result = SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef)username,
+ (__bridge CFDataRef)[password dataUsingEncoding:NSUTF8StringEncoding],
+ CFSTR("1"), &cferror);
+ if (result) {
+ SOSCCStatus circleStat = SOSCCThisDeviceIsInCircle(&cferror);
+ if (circleStat == kSOSCCCircleAbsent) {
+ result = SOSCCResetToOffering(&cferror);
+ }
+ }
+ complete(result, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+}
+
+- (void)sosCircleStatus:(void(^)(SOSCCStatus status, NSError *error))complete
+{
+ SOSCloudKeychainFlush(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef __unused returnedValues, CFErrorRef __unused sync_error) {
+ CFErrorRef cferror = NULL;
+ SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror);
+ complete(status, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+ });
+}
+
+- (void)sosCircleStatusNonCached:(void(^)(SOSCCStatus status, NSError *error))complete
+{
+ SOSCloudKeychainFlush(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef __unused returnedValues, CFErrorRef __unused sync_error) {
+ CFErrorRef cferror = NULL;
+ SOSCCStatus status = SOSCCThisDeviceIsInCircleNonCached(&cferror);
+ complete(status, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+ });
+}
+
+
+- (void)sosViewStatus:(NSString *) viewName withCompletion: (void(^)(SOSViewResultCode status, NSError *error))complete
+{
+ CFErrorRef cferror = NULL;
+ SOSViewResultCode status = SOSCCView((__bridge CFStringRef)(viewName), kSOSCCViewQuery, &cferror);
+ complete(status, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+}
+
+
+- (void)sosICKStatus: (void(^)(bool status))complete
+{
+ CFErrorRef cferror = NULL;
+ bool status = SOSCCIsIcloudKeychainSyncing();
+ complete(status);
+ CFReleaseNull(cferror);
+}
+
+- (void)sosPeerID:(void (^)(NSString *))complete
+{
+ CFErrorRef cferror = NULL;
+ CFStringRef peerID = NULL;
+ SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo(&cferror);
+ if (peerInfo)
+ peerID = SOSPeerInfoGetPeerID(peerInfo);
+
+ complete((__bridge NSString *)peerID);
+ CFReleaseNull(peerInfo);
+}
+
+- (void)sosRequestToJoin:(void(^)(bool success, NSString *peerID, NSError *error))complete
+{
+ CFErrorRef cferror = NULL;
+
+ os_log(NULL, "[%@] sosRequestToJoin", self.name);
+
+ SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror);
+ if (status == kSOSCCCircleAbsent) {
+ cferror = CFErrorCreate(NULL, CFSTR("MDCircleAbsent"), 1, NULL);
+ complete(false, NULL, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+ } else if (status == kSOSCCNotInCircle) {
+ CFReleaseNull(cferror);
+ NSString *peerID = NULL;
+ bool result = SOSCCRequestToJoinCircle(&cferror);
+ if (result) {
+ SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo(&cferror);
+ if (peerInfo) {
+ peerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peerInfo);
+ }
+ CFReleaseNull(peerInfo);
+ CFReleaseNull(cferror);
+ }
+ complete(result, peerID, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+ } else {
+ if(!cferror) {
+ cferror = CFErrorCreate(NULL, CFSTR("MDGeneralJoinError"), 1, NULL);
+ }
+ complete(false, NULL, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+ }
+}
+
+- (void)sosLeaveCircle: (void(^)(bool success, NSError *error))complete {
+ CFErrorRef cferror = NULL;
+ bool retval = false;
+
+ os_log(NULL, "[%@] sosLeaveCircle", self.name);
+
+ SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror);
+ if(status == kSOSCCInCircle || status == kSOSCCRequestPending) {
+ retval = SOSCCRemoveThisDeviceFromCircle(&cferror);
+ }
+ complete(retval, (__bridge NSError *) cferror);
+ CFReleaseNull(cferror);
+}
+
+
+- (void)sosApprovePeer:(NSString *)peerID complete:(void(^)(BOOL success, NSError *error))complete
+{
+ CFErrorRef cferror = NULL;
+ os_log(NULL, "[%@] sosApprovePeer: %@", self.name, peerID);
+ NSArray *applicants = CFBridgingRelease(SOSCCCopyApplicantPeerInfo(&cferror));
+ if ([applicants count] == 0) {
+ CFReleaseNull(cferror);
+ cferror = CFErrorCreate(NULL, CFSTR("MDNoApplicant"), 1, NULL);
+ complete(false, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+ return;
+ }
+ NSMutableArray *approvedApplicants = [NSMutableArray array];
+ for (id peer in applicants) {
+ SOSPeerInfoRef peerInfo = (__bridge SOSPeerInfoRef)peer;
+ NSString *applicantPeerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peerInfo);
+ if (peerID == NULL || [peerID isEqualToString:applicantPeerID]){
+ [approvedApplicants addObject:(__bridge id)peerInfo];
+ }
+ }
+ bool result = false;
+ if ([approvedApplicants count]) {
+ result = SOSCCAcceptApplicants((__bridge CFArrayRef)approvedApplicants, &cferror);
+ } else {
+ cferror = CFErrorCreate(NULL, CFSTR("MDNoApplicant"), 1, NULL);
+ }
+ complete(result, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+}
+
+- (void)sosWaitForInitialSync:(void(^)(bool success, NSError *error))complete
+{
+ CFErrorRef cferror = NULL;
+ bool success = SOSCCWaitForInitialSync(&cferror);
+ complete(success, (__bridge NSError *)cferror);
+ CFReleaseNull(cferror);
+}
+
+- (void)sosEnableAllViews:(void(^)(BOOL success, NSError *error))complete
+{
+ CFMutableSetRef viewsToEnable = SOSViewCopyViewSet(kViewSetAll);
+ CFMutableSetRef viewsToDisable = CFSetCreateMutable(NULL, 0, NULL);
+
+ bool success = SOSCCViewSet(viewsToEnable, viewsToDisable);
+ CFRelease(viewsToEnable);
+ CFRelease(viewsToDisable);
+ complete(success, NULL);
+
+}
+
+- (void) sosCachedViewBitmask: (void(^)(uint64_t bitmask))complete {
+ uint64_t result = SOSCachedViewBitmask();
+ complete(result);
+}
+
+
+
+//PRAGMA mark: - Diagnostics
+
+- (void)diagnosticsLeaks:(void(^)(bool success, NSString *outout, NSError *error))complete
+{
+ complete(true, NULL, NULL);
+}
+
+- (void)diagnosticsCPUUsage:(void(^)(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error))complete
+{
+ struct rusage usage;
+ getrusage(RUSAGE_SELF, &usage);
+ uint64_t user_usec = usage.ru_utime.tv_sec * USEC_PER_SEC + usage.ru_utime.tv_usec;
+ uint64_t sys_usec = usage.ru_stime.tv_sec * USEC_PER_SEC + usage.ru_stime.tv_usec;
+
+ complete(true, user_usec, sys_usec, NULL);
+}
+
+- (void)diagnosticsDiskUsage:(void(^)(bool success, uint64_t usage, NSError *error))complete
+{
+ rusage_info_current rusage;
+
+ if (proc_pid_rusage(getpid(), RUSAGE_INFO_CURRENT, (rusage_info_t *)&rusage) == 0) {
+ complete(true, rusage.ri_logical_writes, NULL);
+ } else {
+ complete(false, 0, NULL);
+ }
+}
+
+@end
--- /dev/null
+//
+// main.m
+// DeviceSimulator
+//
+//
+
+#import <Foundation/Foundation.h>
+#import <Foundation/NSXPCConnection_Private.h>
+#import <SOSCircle/CKBridge/SOSCloudKeychainConstants.h>
+#import <objc/runtime.h>
+#import <utilities/debugging.h>
+
+#import <securityd/SOSCloudCircleServer.h>
+#import <Security/SecureObjectSync/SOSPeerInfo.h>
+#import <Security/SecureObjectSync/SOSCloudCircleInternal.h>
+#import <Security/SecureObjectSync/SOSViews.h>
+#import <Security/SecureObjectSync/SOSInternal.h>
+
+#import "DeviceSimulator.h"
+#import "SOSCloudKeychainClient.h"
+#import "MultiDeviceNetworkingProtocol.h"
+#import "SecCFWrappers.h"
+#import "spi.h"
+
+struct SOSCloudTransport MDNTransport;
+
+@class MDNetwork;
+
+NSString *deviceInstance = NULL;
+static NSString *deviceHomeDir = NULL;
+static MDNetwork *deviceNetwork = NULL;
+
+@interface MDNetwork : NSObject<MultiDeviceNetworkingProtocol,MultiDeviceNetworkingCallbackProtocol,NSXPCListenerDelegate>
+@property NSXPCConnection *connection;
+@property NSXPCListener *callbackListener;
+@property dispatch_queue_t flushQueue;
+@property NSMutableDictionary *pendingKeys;
+@property NSSet *registeredKeys;
+- (instancetype)initWithConnection:(NSXPCConnection *)connection;
+@end
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wprotocol"
+@implementation MDNetwork
+
+- (instancetype)initWithConnection:(NSXPCConnection *)connection
+{
+ self = [super init];
+ if (self) {
+ self.connection = connection;
+ self.callbackListener = [NSXPCListener anonymousListener];
+ self.callbackListener.delegate = self;
+ [self.callbackListener resume];
+
+ __typeof(self) weakSelf = self;
+ self.connection.invalidationHandler = ^{
+ __typeof(self) strongSelf = weakSelf;
+ [strongSelf.callbackListener invalidate];
+ strongSelf.callbackListener = nil;
+
+ exit(0);
+ };
+
+ self.flushQueue = dispatch_queue_create("MDNetwork.flushqueue", 0);
+ self.pendingKeys = [NSMutableDictionary dictionary];
+ self.registeredKeys = [NSSet set];
+
+ [[self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
+ NSLog(@"network register callback failed with: %@", error);
+ //abort();
+ }] MDNRegisterCallback:[self.callbackListener endpoint] complete:^void(NSDictionary *values, NSError *error) {
+ ;
+ }];
+
+ }
+ return self;
+}
+
+- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
+{
+ newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingCallbackProtocol)];
+ newConnection.exportedObject = self;
+ [newConnection resume];
+ return YES;
+}
+
+- (void)MDNCItemsChanged:(NSDictionary *)values complete:(MDNComplete)complete
+{
+ NSMutableDictionary *requestedKeys = [NSMutableDictionary dictionary];
+ @synchronized(self.pendingKeys) {
+ secnotice("MDN", "items update: %@ (already pending: %@)", values, self.pendingKeys);
+
+ [self.pendingKeys addEntriesFromDictionary:values];
+ for (NSString *key in self.registeredKeys) {
+ id data = self.pendingKeys[key];
+ if (data) {
+ requestedKeys[key] = data;
+ self.pendingKeys[key] = nil;
+ }
+ }
+ }
+ if (requestedKeys.count) {
+ dispatch_async(self.flushQueue, ^{
+ secnotice("MDN", "engine processing keys: %@", requestedKeys);
+ NSArray *handled = CFBridgingRelease(SOSCCHandleUpdateMessage((__bridge CFDictionaryRef)requestedKeys));
+ /*
+ * Ok, our dear Engine might not have handled all messages.
+ * So put them back unless there are new messages around that
+ * have overwritten the previous message.
+ */
+ for (NSString *key in handled) {
+ requestedKeys[key] = NULL;
+ }
+ if (requestedKeys.count) {
+ @synchronized(self.pendingKeys) {
+ for (NSString *key in requestedKeys) {
+ if (self.pendingKeys[key] == nil) {
+ self.pendingKeys[key] = requestedKeys[key];
+ }
+ }
+ }
+ }
+ });
+ }
+ complete(NULL, NULL);
+}
+
+/* Oh, ObjC, you are my friend */
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ struct objc_method_description desc = protocol_getMethodDescription(@protocol(MultiDeviceNetworkingProtocol), [invocation selector], true, true);
+ if (desc.name == NULL) {
+ [super forwardInvocation:invocation];
+ } else {
+ __block bool gogogo = true;
+ id object = [self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
+ gogogo = false;
+ NSLog(@"network failed with: %@", error);
+ //abort();
+ }];
+ if(gogogo) [invocation invokeWithTarget:object];
+ }
+}
+@end
+#pragma clang diagnostic pop
+
+#define HANDLE_NO_NETWORK(_replyBlock) \
+ if (deviceNetwork == NULL) { \
+ replyBlock((__bridge CFDictionaryRef)@{}, (__bridge CFErrorRef)[NSError errorWithDomain:@"MDNNetwork" code:1 userInfo:NULL]); \
+ return; \
+ }
+
+
+static void
+DSCloudPut(SOSCloudTransportRef transport, CFDictionaryRef valuesToPut, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ @autoreleasepool {
+ HANDLE_NO_NETWORK(replyBlock);
+ secnotice("MDN", "CloudPut: %@", valuesToPut);
+
+ [deviceNetwork MDNCloudPut:(__bridge NSDictionary *)valuesToPut complete:^(NSDictionary *returnedValues, NSError *error) {
+ dispatch_async(processQueue, ^{
+ replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error);
+ });
+ }];
+ }
+}
+
+static NSString *nKeyAlwaysKeys = @"AlwaysKeys";
+static NSString *nKeyFirstUnlockKeys = @"FirstUnlockKeys";
+static NSString *nKeyUnlockedKeys = @"UnlockedKeys";
+static NSString *nMessageKeyParameter = @"KeyParameter";
+static NSString *nMessageCircle = @"Circle";
+static NSString *nMessageMessage = @"Message";
+
+
+static void
+DSCloudUpdateKeys(SOSCloudTransportRef transport, CFDictionaryRef cfkeys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ /*
+ * Currently doesn't deal with lock state, just smash (HULK!) them all together
+ */
+ @autoreleasepool {
+ NSDictionary *keys = (__bridge NSDictionary *)cfkeys;
+ NSMutableSet *newSet = [NSMutableSet set];
+
+ @synchronized(deviceNetwork.pendingKeys) {
+ for (NSString *type in @[ nMessageKeyParameter, nMessageCircle, nMessageMessage]) {
+ NSDictionary *typeDict = keys[type];
+
+ for (NSString *lockType in @[ nKeyAlwaysKeys, nKeyFirstUnlockKeys, nKeyUnlockedKeys]) {
+ NSArray *lockArray = typeDict[lockType];
+ if (lockArray) {
+ [newSet unionSet:[NSMutableSet setWithArray:lockArray]];
+ }
+ }
+ }
+ deviceNetwork.registeredKeys = newSet;
+ }
+ /* update engine with stuff */
+ [deviceNetwork MDNCItemsChanged:@{} complete:^(NSDictionary *returnedValues, NSError *error) {
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error);
+ }];
+ }
+}
+
+static void
+DSCloudGetDeviceID(SOSCloudTransportRef transport, CloudKeychainReplyBlock replyBlock)
+{
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+}
+
+// Debug calls
+static void
+DSCloudGet(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+}
+
+static void
+DSCloudGetAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+}
+
+static void
+DSCloudsynchronize(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+}
+
+static void
+DSCloudsynchronizeAndWait(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ @autoreleasepool {
+ HANDLE_NO_NETWORK(replyBlock);
+
+ [deviceNetwork MDNCloudsynchronizeAndWait:@{} complete:^(NSDictionary *returnedValues, NSError *error) {
+ dispatch_async(processQueue, ^{
+ replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error);
+ });
+ }];
+ }
+}
+
+static void
+DSCloudRemoveObjectForKey(SOSCloudTransportRef transport, CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ if (keyToRemove == NULL) {
+ dispatch_async(processQueue, ^{
+ replyBlock(NULL, NULL);
+ });
+ return;
+ }
+
+ @autoreleasepool {
+ HANDLE_NO_NETWORK(replyBlock);
+ [deviceNetwork MDNCloudRemoveKeys:@[(__bridge NSString *)keyToRemove] complete:^(NSDictionary *returnedValues, NSError *error) {
+ dispatch_async(processQueue, ^{
+ replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error);
+ });
+ }];
+ }
+}
+
+static void DSCloudremoveKeys(SOSCloudTransportRef transport, CFArrayRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ @autoreleasepool {
+ HANDLE_NO_NETWORK(replyBlock);
+ [deviceNetwork MDNCloudRemoveKeys:(__bridge NSArray *)keys complete:^(NSDictionary *returnedValues, NSError *error) {
+ dispatch_async(processQueue, ^{
+ replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error);
+ });
+ }];
+ }
+}
+
+static void
+DSCloudclearAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ @autoreleasepool {
+ HANDLE_NO_NETWORK(replyBlock);
+ [deviceNetwork MDNCloudRemoveKeys:NULL complete:^(NSDictionary *returnedValues, NSError *error) {
+ dispatch_async(processQueue, ^{
+ replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error);
+ });
+ }];
+ }
+}
+
+static bool
+DSCloudhasPendingKey(SOSCloudTransportRef transport, CFStringRef keyName, CFErrorRef* error)
+{
+ bool status = false;
+ @synchronized(deviceNetwork.pendingKeys) {
+ status = deviceNetwork.pendingKeys[(__bridge NSString *)keyName] != nil;
+ }
+ return status;
+}
+
+
+static void
+DSCloudrequestSyncWithPeers(SOSCloudTransportRef transport, CFArrayRef /* CFStringRef */ peers, CFArrayRef /* CFStringRef */ backupPeers, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ CFSetRef sPeers = CFSetCreateCopyOfArrayForCFTypes(peers);
+ CFSetRef sBackupPeers = CFSetCreateCopyOfArrayForCFTypes(backupPeers);
+
+ if (sPeers == NULL || sBackupPeers == NULL) {
+ CFReleaseNull(sPeers);
+ CFReleaseNull(sBackupPeers);
+ } else {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ CFErrorRef error = NULL;
+ CFSetRef result = SOSCCProcessSyncWithPeers_Server(sPeers, sBackupPeers, &error);
+
+ CFRelease(sPeers);
+ CFRelease(sBackupPeers);
+ CFReleaseNull(result);
+ CFReleaseNull(error);
+ });
+ }
+ if (replyBlock) {
+ dispatch_async(processQueue, ^{
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+ });
+ }
+}
+
+static bool
+DSCloudhasPeerSyncPending(SOSCloudTransportRef transport, CFStringRef peerID, CFErrorRef* error)
+{
+ return false;
+}
+
+static void
+DSCloudrequestEnsurePeerRegistration(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ CFErrorRef eprError = NULL;
+ if (!SOSCCProcessEnsurePeerRegistration_Server(&eprError)) {
+ secnotice("coder", "SOSCCProcessEnsurePeerRegistration failed with: %@", eprError);
+ }
+ CFReleaseNull(eprError);
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+ });
+}
+
+static void DSCloudrequestPerfCounters(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+}
+
+static void DSCloudflush(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ @autoreleasepool {
+ HANDLE_NO_NETWORK(replyBlock);
+
+ [deviceNetwork MDNCloudFlush:^(NSDictionary *returnedValues, NSError *error) {
+ dispatch_async(deviceNetwork.flushQueue, ^{
+ dispatch_async(processQueue, ^{
+ replyBlock((__bridge CFDictionaryRef)returnedValues, (__bridge CFErrorRef)error);
+ });
+ });
+ }];
+ }
+}
+
+static void DSCloudcounters(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
+{
+ if (replyBlock)
+ replyBlock((__bridge CFDictionaryRef)@{}, NULL);
+}
+
+@interface ServiceDelegate : NSObject <NSXPCListenerDelegate>
+@end
+
+@implementation ServiceDelegate
+
+- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
+ newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(DeviceSimulatorProtocol)];
+
+ DeviceSimulator *exportedObject = [DeviceSimulator new];
+ exportedObject.conn = newConnection;
+ newConnection.exportedObject = exportedObject;
+
+ [newConnection resume];
+
+ return YES;
+}
+
+@end
+
+void
+boot_securityd(NSXPCListenerEndpoint *network)
+{
+ secLogDisable();
+ securityd_init((__bridge CFURLRef)[NSURL URLWithString:deviceHomeDir]);
+
+ NSXPCConnection *connection = [[NSXPCConnection alloc] initWithListenerEndpoint:network];
+ connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingProtocol)];
+ [connection resume];
+
+ deviceNetwork = [[MDNetwork alloc] initWithConnection:connection];
+
+}
+
+/*
+ * Make sure each of th peers don't trample on each's others state
+ */
+
+@interface SOSCachedNotification (override)
+@end
+
+@implementation SOSCachedNotification (override)
++ (NSString *)swizzled_notificationName:(const char *)notificationName
+{
+ return [NSString stringWithFormat:@"%@-%@",
+ [SOSCachedNotification swizzled_notificationName:notificationName], deviceInstance];
+}
+
++ (void)load {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ Method orignal = class_getClassMethod(self, @selector(notificationName:));
+ Method swizzled = class_getClassMethod(self, @selector(swizzled_notificationName:));
+ method_exchangeImplementations(orignal, swizzled);
+ });
+}
+@end
+
+
+int main(int argc, const char *argv[])
+{
+ struct sigaction action;
+ memset(&action, 0, sizeof(action));
+
+ deviceInstance = [[NSXPCListener _UUID] UUIDString];
+
+ NSURL *tempPath = [[NSFileManager defaultManager] temporaryDirectory];
+ deviceHomeDir = [[tempPath path] stringByAppendingPathComponent:deviceInstance];
+
+ [[NSFileManager defaultManager] createDirectoryAtPath:deviceHomeDir
+ withIntermediateDirectories:NO
+ attributes:NULL
+ error:NULL];
+
+ MDNTransport.put = DSCloudPut;
+ MDNTransport.updateKeys = DSCloudUpdateKeys;
+ MDNTransport.getDeviceID = DSCloudGetDeviceID;
+ MDNTransport.get = DSCloudGet;
+ MDNTransport.getAll = DSCloudGetAll;
+ MDNTransport.synchronize = DSCloudsynchronize;
+ MDNTransport.synchronizeAndWait = DSCloudsynchronizeAndWait;
+ MDNTransport.clearAll = DSCloudclearAll;
+ MDNTransport.removeObjectForKey = DSCloudRemoveObjectForKey;
+ MDNTransport.hasPendingKey = DSCloudhasPendingKey;
+ MDNTransport.requestSyncWithPeers = DSCloudrequestSyncWithPeers;
+ MDNTransport.hasPeerSyncPending = DSCloudhasPeerSyncPending;
+ MDNTransport.requestEnsurePeerRegistration = DSCloudrequestEnsurePeerRegistration;
+ MDNTransport.requestPerfCounters = DSCloudrequestPerfCounters;
+ MDNTransport.flush = DSCloudflush;
+ MDNTransport.itemsChangedBlock = CFBridgingRetain(^CFArrayRef(CFDictionaryRef values) {
+ // default change block doesn't handle messages, keep em
+ return CFBridgingRetain(@[]);
+ });
+ MDNTransport.removeKeys = DSCloudremoveKeys;
+ MDNTransport.counters = DSCloudcounters;
+
+ SOSCloudTransportSetDefaultTransport(&MDNTransport);
+
+ // Create the delegate for the service.
+ ServiceDelegate *delegate = [ServiceDelegate new];
+ signal(SIGPIPE, SIG_IGN);
+
+ // Set up the one NSXPCListener for this service. It will handle all incoming connections.
+ NSXPCListener *listener = [NSXPCListener serviceListener];
+ listener.delegate = delegate;
+
+ // Resuming the serviceListener starts this service. This method does not return.
+ [listener resume];
+ return 0;
+}
--- /dev/null
+//
+// DeviceSimulatorProtocol.h
+// DeviceSimulator
+//
+
+#import <Foundation/Foundation.h>
+#import <Security/SecureObjectSync/SOSCloudCircle.h>
+
+@protocol DeviceSimulatorProtocol
+
+- (void)setDevice:(NSString *)name
+ version:(NSString *)version
+ model:(NSString *)model
+ testInstance:(NSString *)testUUID
+ network:(NSXPCListenerEndpoint *)network
+ complete:(void(^)(BOOL success))complete;
+
+// Local Keychain
+- (void)secItemAdd:(NSDictionary *)input complete:(void (^)(OSStatus, NSDictionary *))reply;
+- (void)secItemCopyMatching:(NSDictionary *)input complete:(void (^)(OSStatus, NSArray<NSDictionary *>*))replyreply;
+
+// SOS trust
+- (void)setupSOSCircle:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *error))complete;
+- (void)sosCircleStatus:(void(^)(SOSCCStatus status, NSError *error))complete;
+- (void)sosCircleStatusNonCached:(void(^)(SOSCCStatus status, NSError *error))complete;
+- (void)sosViewStatus:(NSString *) view withCompletion: (void(^)(SOSViewResultCode status, NSError *error))complete;
+- (void)sosICKStatus: (void(^)(bool status))complete;
+- (void)sosCachedViewBitmask: (void(^)(uint64_t bitmask))complete;
+- (void)sosPeerID:(void(^)(NSString *peerID))complete;
+- (void)sosRequestToJoin:(void(^)(bool success, NSString *peerID, NSError *error))complete;
+- (void)sosLeaveCircle: (void(^)(bool success, NSError *error))complete;
+- (void)sosApprovePeer:(NSString *)peerID complete:(void(^)(BOOL success, NSError *error))complete;
+
+// SOS syncing
+- (void)sosWaitForInitialSync:(void(^)(bool success, NSError *error))complete;
+- (void)sosEnableAllViews:(void(^)(BOOL success, NSError *error))complete;
+
+// Diagnostics
+- (void)diagnosticsLeaks:(void(^)(bool success, NSString *outout, NSError *error))complete;
+- (void)diagnosticsCPUUsage:(void(^)(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error))complete;
+- (void)diagnosticsDiskUsage:(void(^)(bool success, uint64_t usage, NSError *error))complete;
+
+@end
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleDisplayName</key>
+ <string>DeviceSimulator</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>XPC!</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>XPCService</key>
+ <dict>
+ <key>ServiceType</key>
+ <string>Application</string>
+ <key>_MultipleInstances</key>
+ <true/>
+ <key>JoinExistingSession</key>
+ <true/>
+ </dict>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
--- /dev/null
+//
+// MultiDeviceNetworking.h
+// Security
+//
+
+#import <Foundation/Foundation.h>
+#import <XCTest/XCTest.h>
+
+@interface MDNCounters : NSObject
+//- (NSDictionary *)summary;
+@end
+
+@interface MultiDeviceNetworking : NSObject
+- (instancetype)init;
+- (NSXPCListenerEndpoint *)endpoint;
+- (void)dumpKVSState;
+- (void)dumpCounters;
+- (void)disconnectAll;
+
+- (void)setTestExpectation:(XCTestExpectation *)expectation forKey:(NSString *)key;
+- (void)fulfill:(NSString *)key;
+- (void)clearTestExpectations;
+
+@end
--- /dev/null
+//
+// MultiDeviceNetworking.m
+// Security
+//
+
+#import "MultiDeviceNetworking.h"
+#import "MultiDeviceNetworkingProtocol.h"
+
+@interface MDNCounters ()
+@property (assign) unsigned long kvsSyncAndWait;
+@property (assign) unsigned long kvsFlush;
+@property (assign) unsigned long kvsSend;
+@property (assign) unsigned long kvsRecv;
+@property (assign) unsigned long kvsRecvAll;
+@property (strong) NSMutableDictionary<NSString *,NSNumber *> *kvsKeys;
+
+- (void)addCountToKey:(NSString *)key;
+@end
+
+
+@interface MDNConnection : NSObject <MultiDeviceNetworkingProtocol>
+@property (weak) MultiDeviceNetworking *network;
+@property NSXPCConnection *inConnection;
+@property NSXPCConnection *outConnection;
+@property MDNCounters *counters;
+@end
+
+@interface MultiDeviceNetworking () <NSXPCListenerDelegate>
+@property NSXPCListener *networkListener;
+@property NSMutableDictionary *kvs;
+@property NSMutableArray<MDNConnection *> *connections;
+@property dispatch_queue_t serialQueue;
+@property NSMutableDictionary<NSString *, XCTestExpectation *> *expectations;
+@end
+
+@implementation MDNCounters
+
+- (instancetype)init {
+ if ((self = [super init]) == NULL) {
+ return nil;
+ }
+ self.kvsKeys = [NSMutableDictionary dictionary];
+ return self;
+}
+
+- (NSDictionary *)summary{
+ NSDictionary *kvsKeys = @{};
+ @synchronized(self.kvsKeys) {
+ kvsKeys = [self.kvsKeys copy];
+ }
+ return @{
+ @"kvsSyncAndWait" : @(self.kvsSyncAndWait),
+ @"kvsFlush" : @(self.kvsFlush),
+ @"kvsSend" : @(self.kvsSend),
+ @"kvsRecv" : @(self.kvsRecv),
+ @"kvsRecvAll" : @(self.kvsRecvAll),
+ @"kvsKeys" : kvsKeys,
+ };
+}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<MDNCounters: %@>", [self summary]];
+}
+- (void)addCountToKey:(NSString *)key
+{
+ @synchronized(self.kvsKeys) {
+ NSNumber *number = self.kvsKeys[key];
+ self.kvsKeys[key] = @([number longValue] + 1);
+ }
+}
+
+@end
+
+@implementation MultiDeviceNetworking
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self) {
+ self.networkListener = [NSXPCListener anonymousListener];
+ self.networkListener.delegate = self;
+ [self.networkListener resume];
+ self.kvs = [[NSMutableDictionary alloc] init];
+ self.connections = [NSMutableArray array];
+ self.serialQueue = dispatch_queue_create("MultiDeviceNetworking.flushQueue", NULL);
+ self.expectations = [NSMutableDictionary dictionary];
+ }
+ return self;
+}
+
+- (NSXPCListenerEndpoint *)endpoint
+{
+ return [self.networkListener endpoint];
+}
+
+- (void)dumpKVSState
+{
+ @synchronized(self.kvs) {
+ puts("KVS STATE");
+ [self.kvs enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull __unused stop) {
+ puts([[NSString stringWithFormat:@"%@ - %@", key, obj] UTF8String]);
+ }];
+ }
+}
+
+- (void)dumpCounters
+{
+ @synchronized(self.connections) {
+ puts("Network counters:");
+ for (MDNConnection *conn in self.connections) {
+ puts([[NSString stringWithFormat:@"%@", conn.counters] UTF8String]);
+ }
+ }
+}
+
+
+- (void)disconnectAll
+{
+ @synchronized(self.connections) {
+ for (MDNConnection *conn in self.connections) {
+ [conn.inConnection invalidate];
+ [conn.outConnection invalidate];
+ }
+ self.connections = [NSMutableArray array];
+ }
+}
+
+- (void)setTestExpectation:(XCTestExpectation *)expectation forKey:(NSString *)key
+{
+ self.expectations[key] = expectation;
+}
+
+- (void)clearTestExpectations
+{
+ self.expectations = [NSMutableDictionary dictionary];
+}
+
+- (void)fulfill:(NSString *)key
+{
+ [self.expectations[key] fulfill];
+}
+
+
+
+//MARK: - setup listener
+
+- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
+{
+ newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingProtocol)];
+
+ MDNConnection *conn = [[MDNConnection alloc] init];
+ conn.network = self;
+ conn.inConnection = newConnection;
+ newConnection.exportedObject = conn;
+
+ [self.connections addObject:conn];
+ [newConnection resume];
+
+ return YES;
+}
+
+@end
+
+
+//MARK: - KVS fun
+
+@implementation MDNConnection
+
+- (instancetype)init
+{
+ if ((self = [super init]) == nil)
+ return nil;
+ _counters = [[MDNCounters alloc] init];
+ return self;
+}
+
+- (void)MDNRegisterCallback:(NSXPCListenerEndpoint *)callback complete:(MDNComplete)complete
+{
+ self.outConnection = [[NSXPCConnection alloc] initWithListenerEndpoint:callback];
+ self.outConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MultiDeviceNetworkingCallbackProtocol)];
+
+ __typeof(self) weakSelf = self;
+ self.outConnection.invalidationHandler = ^{
+ __typeof(self) strongSelf = weakSelf;
+ strongSelf.outConnection = nil;
+ };
+
+
+ [self.outConnection resume];
+ complete(NULL, NULL);
+}
+
+- (void)MDNCloudPut:(NSDictionary *)values complete:(MDNComplete)complete {
+ MultiDeviceNetworking *network = self.network;
+ @synchronized(network.kvs) {
+ [network.kvs setValuesForKeysWithDictionary:values];
+ }
+ /* interact with test expections so that tests can check that something happned in KVS */
+ [network fulfill:@"Network"];
+ for (NSString *key in values.allKeys) {
+ NSString *dataSummary = @"";
+ id value = values[key];
+ if ([value isKindOfClass:[NSString class]]) {
+ dataSummary = [NSString stringWithFormat:@" = string[%ld]", [(NSString *)value length]];
+ } else if ([value isKindOfClass:[NSData class]]) {
+ NSUInteger length = [(NSData *)value length];
+ NSData *subdata = [(NSData *)value subdataWithRange:NSMakeRange(0, MIN(length, 4))];
+ dataSummary = [NSString stringWithFormat:@" = data[%lu][%@]", (unsigned long)length, subdata];
+ } else {
+ dataSummary = [NSString stringWithFormat:@" = other(%@)", [value description]];
+ }
+ NSLog(@"KVS key update: %@%@", key, dataSummary);
+ [network fulfill:key];
+ [self.counters addCountToKey:key];
+ }
+
+
+ self.counters.kvsSend++;
+ for (MDNConnection *conn in network.connections) {
+ if (conn == self || conn.outConnection == NULL) {
+ continue;
+ }
+ conn.counters.kvsRecv++;
+ [[conn.outConnection remoteObjectProxy] MDNCItemsChanged:values complete:^(NSDictionary *returnedValues, NSError *error) {
+ ;
+ }];
+ }
+ complete(@{}, NULL);
+}
+
+- (void)MDNCloudsynchronizeAndWait:(NSDictionary *)values complete:(MDNComplete)complete {
+ MultiDeviceNetworking *network = self.network;
+ NSDictionary *kvsCopy = NULL;
+ @synchronized(network.kvs) {
+ kvsCopy = [network.kvs copy];
+ }
+ self.counters.kvsSyncAndWait++;
+ [[self.outConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
+ NSLog(@"foo: %@", error);
+ //abort();
+ }] MDNCItemsChanged:kvsCopy complete:^(NSDictionary *returnedValues, NSError *error) {
+ }];
+ dispatch_async(network.serialQueue, ^{
+ complete(@{}, NULL);
+ });
+}
+
+- (void)MDNCloudGet:(NSArray *)keys complete:(MDNComplete)complete{
+ MultiDeviceNetworking *network = self.network;
+ NSLog(@"asking for: %@", keys);
+ self.counters.kvsRecv++;
+ NSMutableDictionary *reply = [NSMutableDictionary dictionary];
+ @synchronized(network.kvs) {
+ for (id key in keys) {
+ reply[key] = network.kvs[key];
+ }
+ }
+ complete(reply, NULL);
+}
+
+- (void)MDNCloudGetAll:(MDNComplete)complete
+{
+ MultiDeviceNetworking *network = self.network;
+ NSDictionary *kvsCopy = NULL;
+ self.counters.kvsRecvAll++;
+ @synchronized(network.kvs) {
+ kvsCopy = [network.kvs copy];
+ }
+ complete(kvsCopy, NULL);
+}
+
+- (void)MDNCloudRemoveKeys:(NSArray<NSString *> *)keys complete:(MDNComplete)complete
+{
+ MultiDeviceNetworking *network = self.network;
+ @synchronized(network.kvs) {
+ if (keys) {
+ for (NSString *key in keys) {
+ network.kvs[key] = NULL;
+ }
+ } else {
+ network.kvs = [NSMutableDictionary dictionary];
+ }
+ }
+ complete(NULL, NULL);
+}
+
+- (void)MDNCloudFlush:(MDNComplete)complete
+{
+ self.counters.kvsFlush++;
+ dispatch_async(self.network.serialQueue, ^{
+ complete(@{}, NULL);
+ });
+}
+
+@end
--- /dev/null
+//
+// DeviceSimulatorProtocol.h
+// DeviceSimulator
+//
+
+#import <Foundation/Foundation.h>
+
+typedef void (^MDNComplete)(NSDictionary * returnedValues, NSError *error);
+
+@protocol MultiDeviceNetworkingCallbackProtocol
+- (void)MDNCItemsChanged:(NSDictionary *)values complete:(MDNComplete)complete;
+@end
+
+@protocol MultiDeviceNetworkingProtocol
+
+- (void)MDNRegisterCallback:(NSXPCListenerEndpoint *)callback complete:(MDNComplete)complete;
+- (void)MDNCloudPut:(NSDictionary *)values complete:(MDNComplete)complete;
+- (void)MDNCloudsynchronizeAndWait:(NSDictionary *)values complete:(MDNComplete)complete;
+- (void)MDNCloudGet:(NSArray *)keys complete:(MDNComplete)complete;
+- (void)MDNCloudGetAll:(MDNComplete)complete;
+- (void)MDNCloudRemoveKeys:(NSArray<NSString *> *)keys complete:(MDNComplete)complete;
+- (void)MDNCloudFlush:(MDNComplete)complete;
+
+@end
+
+
--- /dev/null
+//
+// MultiDeviceSimulatorTests.m
+// MultiDeviceSimulatorTests
+//
+//
+
+#import <XCTest/XCTest.h>
+#import <Foundation/Foundation.h>
+#import <Foundation/NSXPCConnection_Private.h>
+#import <Security/Security.h>
+
+#import "DeviceSimulatorProtocol.h"
+#import "MultiDeviceNetworking.h"
+#import <objc/runtime.h>
+
+@interface MDDevice : NSObject<DeviceSimulatorProtocol>
+@property NSXPCConnection *connection;
+@property NSString *name;
+- (instancetype)initWithConnection:(NSXPCConnection *)connection;
+@end
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wprotocol"
+@implementation MDDevice
+
+- (instancetype)initWithConnection:(NSXPCConnection *)connection
+{
+ self = [super init];
+ if (self) {
+ self.connection = connection;
+ }
+ return self;
+}
+
+/* Oh, ObjC, you are my friend */
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ struct objc_method_description desc = protocol_getMethodDescription(@protocol(DeviceSimulatorProtocol), [invocation selector], true, true);
+ if (desc.name == NULL) {
+ [super forwardInvocation:invocation];
+ } else {
+ __block bool dooooooEeeeetExclamationPoint = true;
+ NSLog(@"forwarding to [%@]: %s", self.name, sel_getName(desc.name));
+ id object = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
+ NSLog(@"peer failed with: %@", error);
+ dooooooEeeeetExclamationPoint = false;
+ //abort();
+ }];
+ if(dooooooEeeeetExclamationPoint) {
+ [invocation invokeWithTarget:object];
+ }
+ }
+}
+@end
+#pragma clang diagnostic pop
+
+
+@interface MultiDeviceSimulatorTests : XCTestCase <NSXPCListenerDelegate>
+@property NSMutableDictionary<NSString *,MDDevice *> *connections;
+@property MultiDeviceNetworking *network;
+@property MDDevice *masterDevice;
+@property NSMutableArray <MDDevice *> *minionDevices;
+@end
+
+static NSString *testInstanceUUID;
+
+@implementation MultiDeviceSimulatorTests
+
++ (void)setUp
+{
+ testInstanceUUID = [[NSUUID UUID] UUIDString];
+}
+
+- (void)setUp
+{
+ signal(SIGPIPE, SIG_IGN);
+ self.connections = [NSMutableDictionary dictionary];
+ self.network = [[MultiDeviceNetworking alloc] init];
+
+ self.minionDevices = [NSMutableArray array];
+}
+
+- (void)tearDown
+{
+ __block uint64_t totalUserUsec = 0, totalSysUsec = 0, totalDiskUsage = 0;
+ NSMutableDictionary *result = [NSMutableDictionary dictionary];
+
+ for (NSString *name in self.connections) {
+ MDDevice *device = self.connections[name];
+ NSLog(@"device: %@", name);
+ [device diagnosticsCPUUsage:^(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error) {
+ NSLog(@"cpu %@: %d: u:%llu s:%llu", device.name, success, (unsigned long long)user_usec, (unsigned long long)sys_usec);
+ totalUserUsec += user_usec;
+ totalSysUsec += sys_usec;
+ result[[NSString stringWithFormat:@"cpu-%@", name]] = @{ @"user_usec" : @(user_usec), @"system_usec" : @(sys_usec)};
+ }];
+ [device diagnosticsDiskUsage:^(bool success, uint64_t usage, NSError *error) {
+ NSLog(@"disk %@: %d: %llu", device.name, success, (unsigned long long)usage);
+ totalDiskUsage += usage;
+ result[[NSString stringWithFormat:@"disk-%@", name]] = @{ @"usage" : @(usage) };
+ }];
+ }
+
+ for(MDDevice *dev in self.minionDevices) {
+ [dev sosLeaveCircle:^(bool success, NSError *error) {
+ ;
+ }];
+ }
+ [self.masterDevice sosLeaveCircle:^(bool success, NSError *error) {
+ ;
+ }];
+
+ self.minionDevices = NULL;
+ self.masterDevice = NULL;
+
+ result[@"cpu-total"] = @{ @"user_usec" : @(totalUserUsec), @"system_usec" : @(totalSysUsec)};
+ result[@"disk-total"] = @{ @"disk" : @(totalDiskUsage) };
+
+ NSLog(@"Total cpu: u:%llu s:%llu", (unsigned long long)totalUserUsec, (unsigned long long)totalSysUsec);
+ NSLog(@"Total disk: %llu", (unsigned long long)totalDiskUsage);
+
+ /* XXX check for leaks in all devices */
+ for (NSString *name in self.connections) {
+ MDDevice *device = self.connections[name];
+ [device.connection invalidate];
+ }
+ self.connections = NULL;
+ [self.network dumpKVSState];
+ [self.network dumpCounters];
+ [self.network disconnectAll];
+ [self.network clearTestExpectations];
+ self.network = NULL;
+
+ NSData * jsonData = [NSJSONSerialization dataWithJSONObject:result options:0 error:NULL];
+
+ [jsonData writeToFile:[NSString stringWithFormat:@"/tmp/test-result-%@", [self name]] atomically:NO];
+
+}
+
+- (void)setupMasterDevice
+{
+ self.masterDevice = [self device:@"ipad" model:@"iPad" version:@"15E143a"];
+
+ [self.masterDevice setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ }];
+
+ [self.masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+}
+
+//MARK: - Device logic
+
+- (MDDevice *)device:(NSString *)name model:(NSString *)model version:(NSString *)version {
+ MDDevice *device = self.connections[name];
+ if (device != NULL) {
+ return NULL;
+ }
+
+ NSXPCConnection *conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.Security.DeviceSimulator"];
+ conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(DeviceSimulatorProtocol)];
+ [conn _setUUID:[NSUUID UUID]]; // select a random instance
+ [conn resume];
+
+ device = [[MDDevice alloc] initWithConnection:conn];
+ device.name = name;
+
+ self.connections[name] = device;
+
+ [device setDevice:name
+ version:version
+ model:model
+ testInstance:testInstanceUUID
+ network:[self.network endpoint]
+ complete:^(BOOL success) {
+ if (!success) {
+ abort();
+ }
+ }];
+ return device;
+}
+
+- (bool)addDeviceToCircle: (MDDevice *) dev {
+ __block bool added = false;
+ __block NSString *devPeerID = NULL;
+ __block NSError *localErr = nil;
+
+ [dev setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ added = success;
+ }];
+
+ if(added) {
+ [dev sosRequestToJoin:^(bool success, NSString *peerID, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ XCTAssertNotEqual(peerID, NULL, "Expected to find peerID for peer2");
+ devPeerID = peerID;
+ added &= success;
+ }];
+ }
+
+ if(added) {
+ __block bool done = false;
+ for(int tries=0; tries < 5; tries++) {
+ sleep(2);
+
+ [self.masterDevice sosApprovePeer:devPeerID complete:^(BOOL success, NSError *error) {
+ localErr = [error copy];
+ if(success) {
+ localErr = nil;
+ done = true;
+ }
+ }];
+ if(done) break;
+ }
+ added &= done;
+ }
+ XCTAssert(added, "Expect success (for approve of %@): %@", devPeerID, localErr);
+ return added;
+}
+
+- (void)addKeychainItems:(unsigned long)items toDevice:(MDDevice *)device
+{
+ NSDictionary *addItem = @{
+ (__bridge id)kSecClass :(__bridge id)kSecClassInternetPassword,
+ (__bridge id)kSecValueData : [@"foo" dataUsingEncoding:NSUTF8StringEncoding],
+ (__bridge id)kSecAttrAccessGroup: @"com.apple.cfnetwork",
+ (__bridge id)kSecAttrSyncViewHint: @"PCS-MasterKey",
+ (__bridge id)kSecAttrDescription: @"delete me if found",
+ (__bridge id)kSecAttrServer: @"server",
+ (__bridge id)kSecAttrAccount: @"account",
+ (__bridge id)kSecAttrSynchronizable: @YES,
+ (__bridge id)kSecAttrPath: @"/path",
+ (__bridge id)kSecAttrIsInvisible: @YES,
+ };
+
+ [device secItemAdd:addItem complete:^void(OSStatus status, NSDictionary *result) {
+ NSLog(@"Result string was dev1: %d %@", (int)status, result);
+ XCTAssertEqual(status, 0, "Expect success");
+ }];
+
+}
+
+- (void)runSigninWithAdditionalDevices:(unsigned)additionalDeviceCount keychainItems:(unsigned long)items {
+
+ for (unsigned n = 0; n < additionalDeviceCount; n++) {
+ MDDevice *dev = [self device:[NSString stringWithFormat:@"mac-%u", n] model:@"Mac Pro" version:@"17E121"];
+ if(dev) {
+ [self addDeviceToCircle: dev];
+ [self.minionDevices addObject:dev];
+ }
+ }
+
+ if (items) {
+ [self addKeychainItems:items toDevice:self.masterDevice];
+ }
+}
+
+
+- (void)testPref3Devices {
+ [self setupMasterDevice];
+
+ [self measureBlock:^{
+ [self runSigninWithAdditionalDevices:2 keychainItems:0];
+ }];
+}
+
+#if 0 /* disabled because of 10min time limit in bats (for now) */
+
+- (void)testPref3Devices1 {
+ [self setupMasterDevice];
+ [self runSigninWithAdditionalDevices:2 keychainItems:1];
+ sleep(60);
+}
+
+- (void)testPref3Devices10 {
+ [self setupMasterDevice];
+ [self runSigninWithAdditionalDevices:2 keychainItems:10];
+ sleep(60);
+}
+
+- (void)testPref3Devices100 {
+ [self setupMasterDevice];
+ [self runSigninWithAdditionalDevices:2 keychainItems:100];
+ sleep(60);
+}
+
+- (void)testPref3Devices1000 {
+ [self setupMasterDevice];
+ [self runSigninWithAdditionalDevices:2 keychainItems:1000];
+ sleep(60);
+ sleep(1);
+}
+
+- (void)testPref6Devices {
+ [self setupMasterDevice];
+
+ [self measureBlock:^{
+ [self runSigninWithAdditionalDevices:5 keychainItems:0];
+ }];
+}
+
+- (void) testDevices6Retired {
+ [self setupMasterDevice];
+
+ [self measureBlock:^{
+ [self runSigninWithAdditionalDevices:5 keychainItems:0];
+ }];
+
+}
+#endif
+
+- (void)test2Device {
+
+ NSLog(@"create devices");
+ MDDevice *dev1 = [self device:@"ipad" model:@"iPad" version:@"15E143a"];
+ MDDevice *dev2 = [self device:@"mac" model:@"Mac Pro" version:@"17E121"];
+
+ /*
+ * using PCS-MasterKey for direct syncing during inital sync
+ */
+
+ NSDictionary *addItem = @{
+ (__bridge id)kSecClass :(__bridge id)kSecClassInternetPassword,
+ (__bridge id)kSecValueData : [@"foo" dataUsingEncoding:NSUTF8StringEncoding],
+ (__bridge id)kSecAttrAccessGroup: @"com.apple.cfnetwork",
+ (__bridge id)kSecAttrSyncViewHint: @"PCS-MasterKey",
+ (__bridge id)kSecAttrDescription: @"delete me if found",
+ (__bridge id)kSecAttrServer: @"server",
+ (__bridge id)kSecAttrAccount: @"account",
+ (__bridge id)kSecAttrSynchronizable: @YES,
+ (__bridge id)kSecAttrPath: @"/path",
+ (__bridge id)kSecAttrIsInvisible: @YES,
+ };
+
+ NSDictionary *findItem = @{
+ (__bridge id)kSecClass :(__bridge id)kSecClassInternetPassword,
+ (__bridge id)kSecAttrAccessGroup: @"com.apple.cfnetwork",
+ (__bridge id)kSecAttrServer: @"server",
+ (__bridge id)kSecAttrAccount: @"account",
+ (__bridge id)kSecAttrSynchronizable: @YES,
+ };
+
+ [dev1 secItemAdd:addItem complete:^void(OSStatus status, NSDictionary *result) {
+ NSLog(@"Result string was dev1: %d %@", (int)status, result);
+ XCTAssertEqual(status, 0, "Expect success");
+ }];
+ [dev1 secItemCopyMatching:findItem complete:^(OSStatus status, NSArray<NSDictionary *> *result) {
+ NSLog(@"Result string was dev1: %d %@", (int)status, result);
+ XCTAssertEqual(status, 0, "Expect success");
+ }];
+
+ /*
+ * Setup and validate device 1
+ */
+
+ XCTestExpectation *expection = [self expectationWithDescription:@"expect to create circle"];
+ [dev1 setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ [expection fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:5.0 handler:nil];
+
+ [dev1 sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+ [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCError, @"expected to be in error: %@", error);
+ }];
+
+ /*
+ * Setup and validate device 2
+ */
+
+ expection = [self expectationWithDescription:@"expect to create circle"];
+ [dev2 setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ [expection fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:5.0 handler:nil];
+
+ [dev1 sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+ [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCNotInCircle, @"expected to be NOT in circle: %@", error);
+ }];
+
+ NSLog(@"Update all views (dev1)");
+ expection = [self expectationWithDescription:@"expect circle update"];
+ expection.assertForOverFulfill = false;
+ [self.network setTestExpectation:expection forKey:@"oak"];
+
+ expection.assertForOverFulfill = false;
+ [dev1 sosEnableAllViews:^(BOOL success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ }];
+
+ [self waitForExpectationsWithTimeout:5.0 handler:nil];
+ [self.network clearTestExpectations];
+
+ __block NSString *peerID1 = NULL;
+ [dev1 sosPeerID:^(NSString *peerID) {
+ XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer1");
+ peerID1 = peerID;
+ }];
+
+ [dev2 sosPeerID:^(NSString *peerID) {
+ XCTAssertEqual(peerID, NULL, @"expected to NOT find peerID for peer2");
+ }];
+
+ [dev1 sosPeerID:^(NSString *peerID) {
+ XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer1");
+ XCTAssertEqualObjects(peerID1, peerID, "dev1 changed ?");
+ }];
+
+ /*
+ * Validate second device can request to join
+ */
+
+ expection = [self expectationWithDescription:@"expect circle update"];
+ expection.assertForOverFulfill = false;
+ [self.network setTestExpectation:expection forKey:@"oak"];
+
+ __block NSString *peerID2 = NULL;
+ [dev2 sosRequestToJoin:^(bool success, NSString *peerID, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ XCTAssertNotEqual(peerID, NULL, @"expected to find peerID for peer2");
+ peerID2 = peerID;
+ }];
+ [self waitForExpectationsWithTimeout:5.0 handler:nil];
+ [self.network clearTestExpectations];
+
+ /*
+ * Check that device 2 can't self join
+ */
+
+ expection = [self expectationWithDescription:@"expect device 2 can't self join"];
+ [dev2 sosApprovePeer:peerID2 complete:^(BOOL success, NSError *error) {
+ XCTAssert(!success, "Expect failure: %@", error);
+ [expection fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:5.0 handler:nil];
+
+ [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCRequestPending, @"expected to be pending request: %@", error);
+ }];
+
+ [dev1 sosPeerID:^(NSString *peerID) {
+ XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer1");
+ XCTAssertEqualObjects(peerID1, peerID, "dev1 changed ?");
+ }];
+
+ /*
+ * Approve device 2 and enable all views
+ */
+
+ NSLog(@"approve");
+ expection = [self expectationWithDescription:@"expect circle update"];
+ expection.assertForOverFulfill = false;
+ [self.network setTestExpectation:expection forKey:@"oak"];
+
+ [dev1 sosApprovePeer:peerID2 complete:^(BOOL success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ }];
+ [self waitForExpectationsWithTimeout:60.0 handler:nil];
+ [self.network clearTestExpectations];
+
+
+ /*
+ * Validate device 2 made it into circle and have a peerID
+ */
+
+ [dev1 sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+ [dev2 sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
+ XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
+ }];
+
+ [dev2 sosPeerID:^(NSString *peerID) {
+ XCTAssertNotEqual(peerID, NULL, @"expected to find a peerID for peer2");
+ peerID2 = peerID;
+ //XCTAssertEqualObject(peerID1, peerID2, "expect peerID to be different");
+ }];
+
+ /*
+ * Enable view for syncing
+ */
+
+ NSString *netID1toID2 = [NSString stringWithFormat:@"ak|%@:%@", peerID1, peerID2];
+ NSString *netID2toID1 = [NSString stringWithFormat:@"ak|%@:%@", peerID2, peerID1];
+
+ expection = [self expectationWithDescription:@"expect traffic from 1->2"];
+ expection.assertForOverFulfill = false;
+ [self.network setTestExpectation:expection forKey:netID1toID2];
+
+ expection = [self expectationWithDescription:@"expect traffic from 2->1"];
+ expection.assertForOverFulfill = false;
+ [self.network setTestExpectation:expection forKey:netID2toID1];
+
+ expection = [self expectationWithDescription:@"expect circle update"];
+ expection.assertForOverFulfill = false;
+ [self.network setTestExpectation:expection forKey:@"oak"];
+
+ /*
+ * Perform initial sync
+ */
+
+ NSLog(@"initial sync");
+ expection = [self expectationWithDescription:@"perform initial sync"];
+ [dev2 sosWaitForInitialSync:^(bool success, NSError *error) {
+ XCTAssert(success, "Expect success for syncing: %@", error);
+ [expection fulfill];
+ }];
+
+ /*
+ *
+ */
+
+ NSLog(@"Update all views (dev2)");
+ [dev2 sosEnableAllViews:^(BOOL success, NSError *error) {
+ XCTAssert(success, "Expect success: %@", error);
+ }];
+
+ [self waitForExpectationsWithTimeout:60.0 handler:nil];
+ [self.network clearTestExpectations];
+
+ /*
+ * check syncing did its thing
+ */
+ NSLog(@"SecItemCopyMatching");
+ [dev1 secItemCopyMatching:findItem complete:^(OSStatus status, NSArray<NSDictionary *> *result) {
+ NSLog(@"Result string was dev1: %d %@", (int)status, result);
+ XCTAssertEqual(status, 0, "Expect success");
+ }];
+
+ [dev2 secItemCopyMatching:findItem complete:^(OSStatus status, NSArray<NSDictionary *> *result) {
+ NSLog(@"Result string was dev2: %d %@", (int)status, result);
+ XCTAssertEqual(status, 0, "Expect success");
+ }];
+
+ NSLog(@"done");
+}
+
+@end
#define CFReleaseNull(CF) ({ __typeof__(CF) *const _pcf = &(CF), _cf = *_pcf; (_cf ? (*_pcf) = ((__typeof__(CF))0), (CFRelease(_cf), ((__typeof__(CF))0)) : _cf); })
-static const int kKeySize = CCAES_KEY_SIZE_128;
-static const int kSaltSize = 20;
-static const int kIterations = 5000;
-static const CFIndex tagLen = 16;
-static const CFIndex ivLen = 16;
-static const uint8_t BCversion1 = 1;
-static const uint8_t BCversion2 = 2;
-static const ssize_t paddingSize = 256;
-static const ssize_t maxSize = 1024;
+#define kBCKeySize CCAES_KEY_SIZE_128
+#define kBCSaltSize 20
+#define kBCIterations 5000
+#define BCTagLen 16
+#define BCIVLen 16
+#define BCversion1 1
+#define BCversion2 2
+#define BCPaddingSize 256
+#define BCMaxSize 1024
Boolean
SecBreadcrumbCreateFromPassword(CFStringRef inPassword,
{
const struct ccmode_ecb *ecb = ccaes_ecb_encrypt_mode();
const struct ccmode_gcm *gcm = ccaes_gcm_encrypt_mode();
- const struct ccdigest_info *di = ccsha256_di();
- uint8_t iv[ivLen];
+ uint8_t iv[BCIVLen];
CFMutableDataRef key, npw;
CFDataRef pw;
if (key == NULL)
return false;
- CFDataSetLength(key, kKeySize + kSaltSize + 4);
+ CFDataSetLength(key, kBCKeySize + kBCSaltSize + 4);
if (SecRandomCopyBytes(kSecRandomDefault, CFDataGetLength(key) - 4, CFDataGetMutableBytePtr(key)) != 0) {
CFReleaseNull(key);
return false;
}
- if (SecRandomCopyBytes(kSecRandomDefault, ivLen, iv) != 0) {
+ if (SecRandomCopyBytes(kSecRandomDefault, BCIVLen, iv) != 0) {
CFReleaseNull(key);
return false;
}
- uint32_t size = htonl(kIterations);
- memcpy(CFDataGetMutableBytePtr(key) + kKeySize + kSaltSize, &size, sizeof(size));
+ uint32_t size = htonl(kBCIterations);
+ memcpy(CFDataGetMutableBytePtr(key) + kBCKeySize + kBCSaltSize, &size, sizeof(size));
/*
* Create data for password
const CFIndex passwordLength = CFDataGetLength(pw);
- if (passwordLength > maxSize) {
+ if (passwordLength > BCMaxSize) {
CFReleaseNull(pw);
CFReleaseNull(key);
return false;
}
- CFIndex paddedSize = passwordLength + paddingSize - (passwordLength % paddingSize);
- const CFIndex outLength = 1 + ivLen + 4 + paddedSize + tagLen;
+ CFIndex paddedSize = passwordLength + BCPaddingSize - (passwordLength % BCPaddingSize);
+ const CFIndex outLength = 1 + BCIVLen + 4 + paddedSize + BCTagLen;
npw = CFDataCreateMutable(NULL, outLength);
if (npw == NULL) {
}
CFDataSetLength(npw, outLength);
- memset(CFDataGetMutableBytePtr(npw), 0, outLength);
+ cc_clear(outLength, CFDataGetMutableBytePtr(npw));
CFDataGetMutableBytePtr(npw)[0] = BCversion2;
- memcpy(CFDataGetMutableBytePtr(npw) + 1, iv, ivLen);
+ memcpy(CFDataGetMutableBytePtr(npw) + 1, iv, BCIVLen);
size = htonl(passwordLength);
- memcpy(CFDataGetMutableBytePtr(npw) + 1 + ivLen, &size, sizeof(size));
- memcpy(CFDataGetMutableBytePtr(npw) + 1 + ivLen + 4, CFDataGetBytePtr(pw), passwordLength);
+ memcpy(CFDataGetMutableBytePtr(npw) + 1 + BCIVLen, &size, sizeof(size));
+ memcpy(CFDataGetMutableBytePtr(npw) + 1 + BCIVLen + 4, CFDataGetBytePtr(pw), passwordLength);
/*
* Now create a GCM encrypted password using the random key
*/
ccgcm_ctx_decl(gcm->size, ctx);
- ccgcm_init(gcm, ctx, kKeySize, CFDataGetMutableBytePtr(key));
- ccgcm_set_iv(gcm, ctx, ivLen, iv);
+ ccgcm_init(gcm, ctx, kBCKeySize, CFDataGetMutableBytePtr(key));
+ ccgcm_set_iv(gcm, ctx, BCIVLen, iv);
ccgcm_gmac(gcm, ctx, 1, CFDataGetMutableBytePtr(npw));
- ccgcm_update(gcm, ctx, outLength - tagLen - ivLen - 1, CFDataGetMutableBytePtr(npw) + 1 + ivLen, CFDataGetMutableBytePtr(npw) + 1 + ivLen);
- ccgcm_finalize(gcm, ctx, tagLen, CFDataGetMutableBytePtr(npw) + outLength - tagLen);
+ ccgcm_update(gcm, ctx, outLength - BCTagLen - BCIVLen - 1, CFDataGetMutableBytePtr(npw) + 1 + BCIVLen, CFDataGetMutableBytePtr(npw) + 1 + BCIVLen);
+ ccgcm_finalize(gcm, ctx, BCTagLen, CFDataGetMutableBytePtr(npw) + outLength - BCTagLen);
ccgcm_ctx_clear(gcm->size, ctx);
/*
* Wrapping key is PBKDF2(sha256) over password
*/
- if (di->output_size < kKeySize) abort();
-
- uint8_t rawkey[di->output_size];
-
+ const struct ccdigest_info *di = ccsha256_di();
+ uint8_t rawkey[CCSHA256_OUTPUT_SIZE];
+ _Static_assert(sizeof(rawkey) >= kBCKeySize, "keysize changed w/o updating digest");
+ if (sizeof(rawkey) != di->output_size) abort();
+
if (ccpbkdf2_hmac(di, CFDataGetLength(pw), CFDataGetBytePtr(pw),
- kSaltSize, CFDataGetMutableBytePtr(key) + kKeySize,
- kIterations,
+ kBCSaltSize, CFDataGetMutableBytePtr(key) + kBCKeySize,
+ kBCIterations,
sizeof(rawkey), rawkey) != 0)
abort();
*/
ccecb_ctx_decl(ccecb_context_size(ecb), ecbkey);
- ccecb_init(ecb, ecbkey, kKeySize, rawkey);
+ ccecb_init(ecb, ecbkey, kBCKeySize, rawkey);
ccecb_update(ecb, ecbkey, 1, CFDataGetMutableBytePtr(key), CFDataGetMutableBytePtr(key));
ccecb_ctx_clear(ccecb_context_size(ecb), ecbkey);
*
*/
- memset(rawkey, 0, sizeof(rawkey));
+ cc_clear(sizeof(rawkey), rawkey);
CFReleaseNull(pw);
*outBreadcrumb = npw;
CFErrorRef *outError)
{
const struct ccmode_ecb *ecb = ccaes_ecb_decrypt_mode();
- const struct ccdigest_info *di = ccsha256_di();
CFMutableDataRef gcmkey, oldpw;
CFIndex outLength;
CFDataRef pw;
if (outError)
*outError = NULL;
- if (CFDataGetLength(inEncryptedKey) < kKeySize + kSaltSize + 4) {
+ if (CFDataGetLength(inEncryptedKey) < kBCKeySize + kBCSaltSize + 4) {
return false;
}
if (CFDataGetBytePtr(inBreadcrumb)[0] == BCversion1) {
- if (CFDataGetLength(inBreadcrumb) < 1 + 4 + paddingSize + tagLen)
+ if (CFDataGetLength(inBreadcrumb) < 1 + 4 + BCPaddingSize + BCTagLen)
return false;
- outLength = CFDataGetLength(inBreadcrumb) - 1 - tagLen;
+ outLength = CFDataGetLength(inBreadcrumb) - 1 - BCTagLen;
} else if (CFDataGetBytePtr(inBreadcrumb)[0] == BCversion2) {
- if (CFDataGetLength(inBreadcrumb) < 1 + ivLen + 4 + paddingSize + tagLen)
+ if (CFDataGetLength(inBreadcrumb) < 1 + BCIVLen + 4 + BCPaddingSize + BCTagLen)
return false;
- outLength = CFDataGetLength(inBreadcrumb) - 1 - ivLen - tagLen;
+ outLength = CFDataGetLength(inBreadcrumb) - 1 - BCIVLen - BCTagLen;
} else {
return false;
}
* Wrapping key is HMAC(sha256) over password
*/
- if (di->output_size < kKeySize) abort();
-
- uint8_t rawkey[di->output_size];
-
- memcpy(&size, CFDataGetMutableBytePtr(gcmkey) + kKeySize + kSaltSize, sizeof(size));
+ const struct ccdigest_info *di = ccsha256_di();
+ uint8_t rawkey[CCSHA256_OUTPUT_SIZE];
+ _Static_assert(sizeof(rawkey) >= kBCKeySize, "keysize changed w/o updating digest");
+ if (sizeof(rawkey) != di->output_size) abort();
+
+ memcpy(&size, CFDataGetMutableBytePtr(gcmkey) + kBCKeySize + kBCSaltSize, sizeof(size));
size = ntohl(size);
if (ccpbkdf2_hmac(di, CFDataGetLength(pw), CFDataGetBytePtr(pw),
- kSaltSize, CFDataGetMutableBytePtr(gcmkey) + kKeySize,
+ kBCSaltSize, CFDataGetMutableBytePtr(gcmkey) + kBCKeySize,
size,
sizeof(rawkey), rawkey) != 0)
abort();
*/
ccecb_ctx_decl(ccecb_context_size(ecb), ecbkey);
- ccecb_init(ecb, ecbkey, kKeySize, rawkey);
+ ccecb_init(ecb, ecbkey, kBCKeySize, rawkey);
ccecb_update(ecb, ecbkey, 1, CFDataGetMutableBytePtr(gcmkey), CFDataGetMutableBytePtr(gcmkey));
ccecb_ctx_clear(ccecb_context_size(ecb), ecbkey);
/*
* GCM unwrap
*/
- uint8_t tag[tagLen];
+ uint8_t tag[BCTagLen];
if (CFDataGetBytePtr(inBreadcrumb)[0] == BCversion1) {
- memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, tagLen);
+ memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, BCTagLen);
- ccgcm_one_shot_legacy(ccaes_gcm_decrypt_mode(), kKeySize, CFDataGetMutableBytePtr(gcmkey), 0, NULL, 1, CFDataGetBytePtr(inBreadcrumb),
- outLength, CFDataGetBytePtr(inBreadcrumb) + 1, CFDataGetMutableBytePtr(oldpw), tagLen, tag);
- if (memcmp(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, tagLen) != 0) {
+ ccgcm_one_shot_legacy(ccaes_gcm_decrypt_mode(), kBCKeySize, CFDataGetMutableBytePtr(gcmkey), 0, NULL, 1, CFDataGetBytePtr(inBreadcrumb),
+ outLength, CFDataGetBytePtr(inBreadcrumb) + 1, CFDataGetMutableBytePtr(oldpw), BCTagLen, tag);
+ if (memcmp(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + outLength, BCTagLen) != 0) {
CFReleaseNull(oldpw);
CFReleaseNull(gcmkey);
return false;
} else {
const uint8_t *iv = CFDataGetBytePtr(inBreadcrumb) + 1;
int res;
- memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + ivLen + outLength, tagLen);
+ memcpy(tag, CFDataGetBytePtr(inBreadcrumb) + 1 + BCIVLen + outLength, BCTagLen);
- res = ccgcm_one_shot(ccaes_gcm_decrypt_mode(), kKeySize, CFDataGetMutableBytePtr(gcmkey),
- ivLen, iv,
+ res = ccgcm_one_shot(ccaes_gcm_decrypt_mode(), kBCKeySize, CFDataGetMutableBytePtr(gcmkey),
+ BCIVLen, iv,
1, CFDataGetBytePtr(inBreadcrumb),
- outLength, CFDataGetBytePtr(inBreadcrumb) + 1 + ivLen, CFDataGetMutableBytePtr(oldpw),
- tagLen, tag);
+ outLength, CFDataGetBytePtr(inBreadcrumb) + 1 + BCIVLen, CFDataGetMutableBytePtr(oldpw),
+ BCTagLen, tag);
if (res) {
CFReleaseNull(gcmkey);
CFReleaseNull(oldpw);
const struct ccmode_ecb *enc = ccaes_ecb_encrypt_mode();
const struct ccmode_ecb *dec = ccaes_ecb_decrypt_mode();
const struct ccdigest_info *di = ccsha256_di();
- CFMutableDataRef newEncryptedKey;
+ uint8_t rawkey[CCSHA256_OUTPUT_SIZE];
CFDataRef newpw = NULL, oldpw = NULL;
- uint8_t rawkey[di->output_size];
-
- if (CFDataGetLength(encryptedKey) < kKeySize + kSaltSize + 4) {
+ CFMutableDataRef newEncryptedKey;
+
+ _Static_assert(sizeof(rawkey) >= kBCKeySize, "keysize changed w/o updating digest");
+ if (sizeof(rawkey) != di->output_size) abort();
+
+ if (CFDataGetLength(encryptedKey) < kBCKeySize + kBCSaltSize + 4) {
return NULL;
}
return false;
}
- if (di->output_size < kKeySize) abort();
-
/*
* Unwrap with new key
*/
uint32_t iter;
- memcpy(&iter, CFDataGetMutableBytePtr(newEncryptedKey) + kKeySize + kSaltSize, sizeof(iter));
+ memcpy(&iter, CFDataGetMutableBytePtr(newEncryptedKey) + kBCKeySize + kBCSaltSize, sizeof(iter));
iter = ntohl(iter);
if (ccpbkdf2_hmac(di, CFDataGetLength(oldpw), CFDataGetBytePtr(oldpw),
- kSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kKeySize,
+ kBCSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kBCKeySize,
iter,
sizeof(rawkey), rawkey) != 0)
abort();
ccecb_ctx_decl(dec->size, deckey);
- ccecb_init(dec, deckey, kKeySize, rawkey);
+ ccecb_init(dec, deckey, kBCKeySize, rawkey);
ccecb_update(dec, deckey, 1, CFDataGetMutableBytePtr(newEncryptedKey), CFDataGetMutableBytePtr(newEncryptedKey));
ccecb_ctx_clear(ccecb_context_size(dec), deckey);
- memset(rawkey, 0, sizeof(rawkey));
-
+ cc_clear(sizeof(rawkey), rawkey);
+
/*
* Re-wrap with new key
*/
if (ccpbkdf2_hmac(di, CFDataGetLength(newpw), CFDataGetBytePtr(newpw),
- kSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kKeySize,
+ kBCSaltSize, CFDataGetMutableBytePtr(newEncryptedKey) + kBCKeySize,
iter,
sizeof(rawkey), rawkey) != 0)
abort();
ccecb_ctx_decl(enc->size, enckey);
- ccecb_init(enc, enckey, kKeySize, rawkey);
+ ccecb_init(enc, enckey, kBCKeySize, rawkey);
ccecb_update(enc, enckey, 1, CFDataGetMutableBytePtr(newEncryptedKey), CFDataGetMutableBytePtr(newEncryptedKey));
ccecb_ctx_clear(ccecb_context_size(enc), enckey);
- memset(rawkey, 0, sizeof(rawkey));
+ cc_clear(sizeof(rawkey), rawkey);
return newEncryptedKey;
}
secnotice("kcn", "About to post #%d/%lu (%@): %@", postCount, noteCenter.deliveredNotifications.count, applicant.idString, note);
[appropriateNotificationCenter() deliverNotification:note];
+ [self.viewedIds addObject:applicant.idString];
postCount++;
}
-(void)setCheckbox
{
if (self.circle.isInCircle) {
- [self.enableKeychainSyncing setState:NSOnState];
+ [self.enableKeychainSyncing setState:NSControlStateValueOn];
} else if (self.circle.isOutOfCircle) {
- [self.enableKeychainSyncing setState:NSOffState];
+ [self.enableKeychainSyncing setState:NSControlStateValueOff];
} else {
- [self.enableKeychainSyncing setState:NSMixedState];
+ [self.enableKeychainSyncing setState:NSControlStateValueMixed];
}
}
{
// XXX: assert not on main_queue
CFErrorRef err = NULL;
+
+ SOSCCValidateUserPublic(NULL); // requires the account queue - makes the rest of this wait for fresh info. This used to happen in SOSCCThisDeviceIsInCircle(below) before we made it use cached info.
SOSCCStatus newRawStatus = SOSCCThisDeviceIsInCircle(&err);
NSArray *peerInfos = (__bridge NSArray *) SOSCCCopyApplicantPeerInfo(&err);
NSMutableArray *newApplicants = [[NSMutableArray alloc] initWithCapacity:peerInfos.count];
#define AUTH_STR(x) #x
#define AUTH_STRINGIFY(x) AUTH_STR(x)
-#define AUTHDB_VERSION 1
+#define AUTHDB_VERSION 2
#define AUTHDB_VERSION_STRING AUTH_STRINGIFY(AUTHDB_VERSION)
#define AUTHDB_BUSY_DELAY 1
"value TEXT NOT NULL"
");"
"CREATE INDEX b_r_id ON buttons(r_id);"
- "INSERT INTO config VALUES('version', "AUTHDB_VERSION_STRING");"
+ "INSERT INTO config VALUES('version', '1');" ,
+
+ // version 2 of the database
+ "CREATE TABLE rules_history ("
+ "timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,"
+ "rule TEXT NOT NULL,"
+ "version INTEGER NOT NULL,"
+ "source TEXT NOT NULL,"
+ "operation INTEGER NOT NULL"
+ ");"
};
static sqlite3 * _create_handle(authdb_t db);
};
static struct _db_upgrade_stages auth_upgrade_script[] = {
- { .pre = -1, .main = 0, .post = -1 } // Create version AUTHDB_VERSION databse.
+ { .pre = -1, .main = 0, .post = -1 }, // Create version AUTHDB_VERSION databse.
+ { .pre = -1, .main = 1, .post = -1}
};
static int32_t _db_run_script(authdb_connection_t dbconn, int number)
return s3e;
}
-static void _db_load_data(authdb_connection_t dbconn, auth_items_t config)
+static CFDictionaryRef _copy_plist(auth_items_t config, CFAbsoluteTime *outTs)
{
CFURLRef authURL = NULL;
CFPropertyListRef plist = NULL;
CFTypeRef value = NULL;
CFAbsoluteTime ts = 0;
CFAbsoluteTime old_ts = 0;
- Boolean ok;
-
+ Boolean ok;
authURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(AUTHDB_DATA), kCFURLPOSIXPathStyle, false);
require_action(authURL != NULL, done, os_log_error(AUTHD_LOG, "authdb: file not found %{public}s", AUTHDB_DATA));
-
- ok = CFURLCopyResourcePropertyForKey(authURL, kCFURLContentModificationDateKey, &value, &err);
+
+ ok = CFURLCopyResourcePropertyForKey(authURL, kCFURLContentModificationDateKey, &value, &err);
require_action(ok && value != NULL, done, os_log_error(AUTHD_LOG, "authdb: failed to get modification date: %{public}@", err));
if (CFGetTypeID(value) == CFDateGetTypeID()) {
ts = CFDateGetAbsoluteTime(value);
+ if (outTs) {
+ *outTs = ts;
+ }
}
- old_ts = auth_items_get_double(config, "data_ts");
-
- // <rdar://problem/17484375> SEED: BUG: Fast User Switching Not Working
- // After Mavericks => Yosemite upgrade install, the new Yosemite rule "system.login.fus" was missing.
- // Somehow (probably during install) ts < old_ts, even though that should never happen.
- // Solution: always import plist and update db when time stamps don't match.
- // After a successful import, old_ts = ts below.
- if (ts != old_ts) {
+ if (config) {
+ old_ts = auth_items_get_double(config, "data_ts");
+ }
+
+ // <rdar://problem/17484375> SEED: BUG: Fast User Switching Not Working
+ // After Mavericks => Yosemite upgrade install, the new Yosemite rule "system.login.fus" was missing.
+ // Somehow (probably during install) ts < old_ts, even though that should never happen.
+ // Solution: always import plist and update db when time stamps don't match.
+ // After a successful import, old_ts = ts below.
+ if (!config || (ts != old_ts)) {
os_log_debug(AUTHD_LOG, "authdb: %{public}s modified old=%f, new=%f", AUTHDB_DATA, old_ts, ts);
CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, authURL, &data, NULL, NULL, (SInt32*)&rc);
require_noerr_action(rc, done, os_log_error(AUTHD_LOG, "authdb: failed to load %{public}s", AUTHDB_DATA));
-
+
plist = CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, &err);
require_action(err == NULL, done, os_log_error(AUTHD_LOG, "authdb: failed to read plist: %{public}@", err));
-
- if (authdb_import_plist(dbconn, plist, true)) {
+ }
+
+done:
+ CFReleaseSafe(authURL);
+ CFReleaseSafe(value);
+ CFReleaseSafe(err);
+ CFReleaseSafe(data);
+
+ return plist;
+}
+
+static void _repair_broken_kofn_right(authdb_connection_t dbconn, const char *right, CFDictionaryRef plist)
+{
+ if (!right || !dbconn) {
+ return;
+ }
+
+ CFDictionaryRef localPlist = plist;
+ if (!localPlist) {
+ localPlist = _copy_plist(NULL, NULL);
+ }
+
+ // import the broken right
+ os_log(AUTHD_LOG, "Repairing broken right %{public}s", right);
+ authdb_import_plist(dbconn, localPlist, FALSE, right);
+
+ if (!plist && localPlist) {
+ CFRelease(localPlist);
+ }
+}
+
+static void _repair_all_kofns(authdb_connection_t dbconn, auth_items_t config)
+{
+ // we want plist to be returned always and not only when never
+ CFDictionaryRef plist = _copy_plist(NULL, NULL);
+
+ if (!plist) {
+ os_log_error(AUTHD_LOG, "authdb: unable to repair kofns");
+ return;
+ }
+
+ authdb_step(dbconn, "SELECT name FROM rules WHERE (rules.kofn > 0) AND (id NOT IN (SELECT r_id FROM delegates_map WHERE r_id = id))",
+ NULL, ^bool(auth_items_t data) {
+ const char *name = auth_items_get_string(data, "name");
+ if (name) {
+ _repair_broken_kofn_right(dbconn, name, plist);
+ }
+ return false;
+ });
+
+ CFRelease(plist);
+}
+
+static void _db_load_data(authdb_connection_t dbconn, auth_items_t config)
+{
+ CFAbsoluteTime ts = 0;
+ CFDictionaryRef plist = _copy_plist(config, &ts);
+
+ if (plist) {
+ if (authdb_import_plist(dbconn, plist, true, NULL)) {
os_log_debug(AUTHD_LOG, "authdb: updating data_ts");
auth_items_t update = auth_items_create();
auth_items_set_double(update, "data_ts", ts);
CFReleaseSafe(update);
}
}
-
-done:
- CFReleaseSafe(value);
- CFReleaseSafe(authURL);
CFReleaseSafe(plist);
- CFReleaseSafe(err);
- CFReleaseSafe(data);
}
static bool _truncate_db(authdb_connection_t dbconn)
_db_load_data(dbconn, config);
+ _repair_all_kofns(dbconn, config);
done:
CFReleaseSafe(config);
os_log_debug(AUTHD_LOG, "authdb: finished maintenance");
}
static void
-_import_rules(authdb_connection_t dbconn, CFMutableArrayRef rules, bool version_check, CFAbsoluteTime now)
+_import_rules(authdb_connection_t dbconn, CFMutableArrayRef rules, bool version_check, CFAbsoluteTime now, const char *nameFilter)
{
CFMutableArrayRef notcommited = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
CFIndex count = CFArrayGetCount(rules);
for (CFIndex i = 0; i < count; i++) {
rule_t rule = (rule_t)CFArrayGetValueAtIndex(rules, i);
+ if (nameFilter && (strcmp(nameFilter, rule_get_name(rule)) != 0)) {
+ // current rule name does not match the requested filter
+ continue;
+ }
+
bool update = false;
if (version_check) {
if (rule_get_id(rule) != 0) { // rule already exists see if we need to update
}
bool
-authdb_import_plist(authdb_connection_t dbconn, CFDictionaryRef plist, bool version_check)
+authdb_import_plist(authdb_connection_t dbconn, CFDictionaryRef plist, bool version_check, const char *name)
{
bool result = false;
if (!count)
break;
- _import_rules(dbconn, rules, version_check, now);
+ _import_rules(dbconn, rules, version_check, now, name);
}
- _import_rules(dbconn, rights, version_check, now);
+ _import_rules(dbconn, rights, version_check, now, name);
if (CFArrayGetCount(rights) == 0) {
result = true;
AUTH_NONNULL_ALL
bool authdb_transaction(authdb_connection_t, AuthDBTransactionType, bool (^t)(void));
-AUTH_NONNULL1 AUTH_NONNULL2 AUTH_NONNULL3
+AUTH_NONNULL1 AUTH_NONNULL2
bool authdb_step(authdb_connection_t, const char * sql, void (^bind_stmt)(sqlite3_stmt* stmt), authdb_iterator_t iter);
AUTH_NONNULL_ALL
AUTH_NONNULL_ALL
void authdb_checkpoint(authdb_connection_t);
-AUTH_NONNULL_ALL
-bool authdb_import_plist(authdb_connection_t,CFDictionaryRef,bool);
-
+AUTH_NONNULL1 AUTH_NONNULL2
+bool authdb_import_plist(authdb_connection_t, CFDictionaryRef, bool, const char * name);
+
#pragma mark -
#pragma mark authdb_connection_t
AuthorizationItem data;
uint32_t type;
size_t bufLen;
-
- CFStringRef cfKey;
};
static const char *
return item->data.value;
}
-static CFStringRef
-auth_item_get_cf_key(auth_item_t item)
-{
- if (!item->cfKey) {
- item->cfKey = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, item->data.name, kCFStringEncodingUTF8, kCFAllocatorNull);
- }
- return item->cfKey;
-}
-
-static AuthorizationItem *
-auth_item_get_auth_item(auth_item_t item)
-{
- return &item->data;
-}
-
static xpc_object_t
auth_item_copy_auth_item_xpc(auth_item_t item)
{
_auth_item_finalize(CFTypeRef value)
{
auth_item_t item = (auth_item_t)value;
-
- CFReleaseNull(item->cfKey);
-
+
if (item->data.name) {
free((void*)item->data.name);
/* cannot set item->data.name to NULL because item->data.name is non-nullable public API (rdar://problem/32235322)
return CFEqual(items1->dictionary, items2->dictionary);
}
+static void
+auth_items_add_item(auth_items_t items, auth_item_t item)
+{
+ CFStringRef cfName = CFStringCreateWithCString(kCFAllocatorDefault, item->data.name, kCFStringEncodingUTF8);
+ if (cfName) {
+ CFDictionarySetValue(items->dictionary, cfName, item);
+ CFRelease(cfName);
+ }
+}
+
static CFStringRef
_auth_items_copy_description(CFTypeRef value)
{
auth_item_t item = auth_item_create_with_xpc(value);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
return true;
return (size_t)CFDictionaryGetCount(items->dictionary);
}
-AuthorizationItemSet *
-auth_items_get_item_set(auth_items_t items)
-{
- uint32_t count = (uint32_t)CFDictionaryGetCount(items->dictionary);
- if (count) {
- size_t size = count * sizeof(AuthorizationItem);
- if (items->set.items == NULL) {
- items->set.items = calloc(1u, size);
- require(items->set.items != NULL, done);
- } else {
- if (count > items->set.count) {
- items->set.items = realloc(items->set.items, size);
- require_action(items->set.items != NULL, done, items->set.count = 0);
- }
- }
- items->set.count = count;
- CFTypeRef keys[count], values[count];
- CFDictionaryGetKeysAndValues(items->dictionary, keys, values);
- for (uint32_t i = 0; i < count; i++) {
- auth_item_t item = (auth_item_t)values[i];
- items->set.items[i] = *auth_item_get_auth_item(item);
- }
- } else {
- items->set.count = 0;
- }
-
-done:
- return &items->set;
-}
-
xpc_object_t
auth_items_export_xpc(auth_items_t items)
{
if (!item) {
item = auth_item_create(AI_TYPE_RIGHT, key, NULL, 0, 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
}
CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup);
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+ if (item) auth_items_add_item(items, item);
CFReleaseSafe(lookup);
return true;
});
CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup);
auth_item_t new_item = auth_item_create(item->type, item->data.name, item->data.value, item->data.valueLength, item->data.flags);
- if (new_item)
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(new_item), new_item);
+ if (new_item) auth_items_add_item(items, new_item);
CFReleaseSafe(lookup);
CFReleaseSafe(new_item);
return true;
auth_items_iterate(src, ^bool(const char *key) {
if (auth_items_check_flags(src, key, flags)) {
CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
+ if (CFDictionaryContainsKey(items->dictionary, lookup)) {
+ CFDictionaryRemoveValue(items->dictionary, lookup); // we do not want to have preserved unretained key
+ }
auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup);
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
+ if (item) auth_items_add_item(items, item);
CFReleaseSafe(lookup);
}
return true;
CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
auth_item_t item = (auth_item_t)CFDictionaryGetValue(src->dictionary, lookup);
auth_item_t new_item = auth_item_create(item->type, item->data.name, item->data.value, item->data.valueLength, item->data.flags);
- if (new_item)
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(new_item), new_item);
+ if (new_item) {
+ auth_items_add_item(items, new_item);
+ CFRelease(new_item);
+ }
CFReleaseSafe(lookup);
- CFReleaseSafe(new_item);
}
return true;
});
} else {
item = auth_item_create(AI_TYPE_STRING, key, value, valLen, 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
} else {
item = auth_item_create(AI_TYPE_DATA, key, value, len, 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
} else {
item = auth_item_create(AI_TYPE_BOOL, key, &value, sizeof(bool), 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
} else {
item = auth_item_create(AI_TYPE_INT, key, &value, sizeof(int32_t), 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
} else {
item = auth_item_create(AI_TYPE_UINT, key, &value, sizeof(uint32_t), 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
} else {
item = auth_item_create(AI_TYPE_INT64, key, &value, sizeof(int64_t), 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
} else {
item = auth_item_create(AI_TYPE_UINT64, key, &value, sizeof(uint64_t), 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
} else {
item = auth_item_create(AI_TYPE_DOUBLE, key, &value, sizeof(double), 0);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
}
{
auth_item_t item = auth_item_create(type, key, value, len, flags);
if (item) {
- CFDictionarySetValue(items->dictionary, auth_item_get_cf_key(item), item);
- CFReleaseSafe(item);
+ auth_items_add_item(items, item);
+ CFRelease(item);
}
}
_find_right_item(auth_rights_t rights, const char * key)
{
auth_item_t item = NULL;
- CFStringRef lookup = NULL;
require(key != NULL, done);
-
- lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
- require(lookup != NULL, done);
-
+
CFIndex count = CFArrayGetCount(rights->array);
for (CFIndex i = 0; i < count; i++) {
auth_item_t tmp = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i);
- if (tmp && CFEqual(auth_item_get_cf_key(tmp), lookup)) {
+ if (tmp && strcmp(tmp->data.name, key) == 0) {
item = tmp;
break;
}
}
done:
- CFReleaseSafe(lookup);
return item;
}
void auth_rights_remove(auth_rights_t rights, const char *key)
{
- CFStringRef lookup = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, key, kCFStringEncodingUTF8, kCFAllocatorNull);
CFIndex count = CFArrayGetCount(rights->array);
for (CFIndex i = 0; i < count; i++) {
auth_item_t item = (auth_item_t)CFArrayGetValueAtIndex(rights->array, i);
- if (CFEqual(auth_item_get_cf_key(item), lookup)) {
+ if (item && strcmp(item->data.name, key) == 0) {
CFArrayRemoveValueAtIndex(rights->array, i);
i--;
count--;
}
}
- CFReleaseSafe(lookup);
}
void auth_rights_clear(auth_rights_t rights)
AUTH_WARN_RESULT AUTH_NONNULL_ALL
size_t auth_items_get_count(auth_items_t);
-AUTH_WARN_RESULT AUTH_NONNULL_ALL
-AuthorizationItemSet * auth_items_get_item_set(auth_items_t);
-
AUTH_WARN_RESULT AUTH_NONNULL_ALL
xpc_object_t auth_items_export_xpc(auth_items_t);
<string>loginwindow:login</string>
<string>builtin:login-begin</string>
<string>builtin:reset-password,privileged</string>
+ <string>loginwindow:FDESupport,privileged</string>
<string>builtin:forward-login,privileged</string>
<string>builtin:auto-login,privileged</string>
<string>builtin:authenticate,privileged</string>
<string>PKINITMechanism:auth,privileged</string>
<string>builtin:login-success</string>
<string>loginwindow:success</string>
- <string>loginwindow:FDESupport,privileged</string>
<string>HomeDirMechanism:login,privileged</string>
<string>HomeDirMechanism:status</string>
<string>MCXMechanism:login</string>
<string>loginwindow:done</string>
</array>
<key>version</key>
- <integer>6</integer>
+ <integer>7</integer>
</dict>
<key>system.login.fus</key>
<dict>
<key>class</key>
<string>user</string>
<key>comment</key>
- <string>Used by AuthorizationExecuteWithPrivileges(...).
+ <string>Used by AuthorizationExecuteWithPrivileges(...).
AuthorizationExecuteWithPrivileges() is used by programs requesting
to run a tool as root (e.g., some installers).</string>
<key>group</key>
<string>rule</string>
<key>rule</key>
<string>authenticate-session-owner</string>
- </dict>
+ </dict>
<key>com.apple.security.sudo</key>
<dict>
<key>class</key>
<string>entitled</string>
<string>authenticate-session-owner</string>
</array>
- </dict>
+ </dict>
<key>system.preferences.continuity</key>
<dict>
<key>class</key>
<key>version</key>
<integer>1</integer>
</dict>
+ <key>com.apple.app-sandbox.create-symlink</key>
+ <dict>
+ <key>comment</key>
+ <string>Authorize an app-sandboxed application to install a symlink into /usr/local/bin.</string>
+ <key>class</key>
+ <string>rule</string>
+ <key>rule</key>
+ <string>authenticate-admin-nonshared</string>
+ <key>shared</key>
+ <false/>
+ <key>timeout</key>
+ <integer>60</integer>
+ </dict>
+ <key>com.apple.app-sandbox.set-attributes</key>
+ <dict>
+ <key>comment</key>
+ <string>Authorize an app-sandboxed application to change permissions on a privileged file.</string>
+ <key>class</key>
+ <string>rule</string>
+ <key>rule</key>
+ <string>authenticate-admin-nonshared</string>
+ <key>shared</key>
+ <false/>
+ <key>timeout</key>
+ <integer>60</integer>
+ </dict>
+ <key>com.apple.app-sandbox.replace-file</key>
+ <dict>
+ <key>comment</key>
+ <string>Authorize an app-sandboxed application to save (overwrite) a file in a privileged location.</string>
+ <key>class</key>
+ <string>rule</string>
+ <key>rule</key>
+ <string>authenticate-admin-nonshared</string>
+ <key>shared</key>
+ <false/>
+ <key>timeout</key>
+ <integer>60</integer>
+ </dict>
</dict>
<key>rules</key>
<dict>
</array>
<key>version</key>
<integer>1</integer>
- </dict>
+ </dict>
<key>authenticate-admin</key>
<dict>
<key>class</key>
<key>class</key>
<string>user</string>
<key>comment</key>
- <string>Like the default rule, but
- credentials remain valid for only 30 seconds after they've
+ <string>Like the default rule, but
+ credentials remain valid for only 30 seconds after they've
been obtained. An acquired credential is shared by all clients.
</string>
<key>group</key>
<key>class</key>
<string>user</string>
<key>comment</key>
- <string>Default rule.
- Credentials remain valid for 5 minutes after they've been obtained.
+ <string>Default rule.
+ Credentials remain valid for 5 minutes after they've been obtained.
An acquired credential is shared by all clients.
</string>
<key>group</key>
<true/>
<key>timeout</key>
<integer>36000</integer>
- </dict>
+ </dict>
</dict>
</dict>
</plist>
dispatch_sync(auth->dispatch_queue, ^{
CFIndex count = CFSetGetCount(auth->credentials);
+ if (count > 128) { // <rdar://problem/38179345> Variable Length Arrays; AuthD
+ // auth_token usually contains 0 or 1 credential
+ count = 128;
+ }
CFTypeRef values[count];
CFSetGetValues(auth->credentials, values);
for (CFIndex i = 0; i < count; i++) {
});
}
-bool
-auth_token_rights_iterate(auth_token_t auth, credential_iterator_t iter)
-{
- __block bool result = false;
-
- dispatch_sync(auth->dispatch_queue, ^{
- CFIndex count = CFSetGetCount(auth->authorized_rights);
- CFTypeRef values[count];
- CFSetGetValues(auth->authorized_rights, values);
- for (CFIndex i = 0; i < count; i++) {
- credential_t right = (credential_t)values[i];
- result = iter(right);
- if (!result) {
- break;
- }
- }
- });
-
- return result;
-}
-
CFTypeRef
auth_token_copy_entitlement_value(auth_token_t auth, const char * entitlement)
{
AUTH_NONNULL_ALL
void auth_token_set_right(auth_token_t,credential_t);
-AUTH_NONNULL_ALL
-bool auth_token_rights_iterate(auth_token_t, credential_iterator_t iter);
-
AUTH_NONNULL_ALL
CFTypeRef auth_token_copy_entitlement_value(auth_token_t, const char * entitlement);
(literal "/private/var/db/mds/system/mds.lock")
(subpath (param "TMP_DIR")))
+(allow network-outbound
+ (literal "/private/var/run/systemkeychaincheck.socket"))
+
(allow mach-lookup
(global-name "com.apple.CoreAuthentication.agent.libxpc")
(global-name "com.apple.CoreAuthentication.daemon.libxpc")
static bool _preevaluate_class_rule(engine_t engine, rule_t rule);
static bool _preevaluate_rule(engine_t engine, rule_t rule);
+static uint64_t global_engine_count;
+
enum {
kEngineHintsFlagTemporary = (1 << 30)
};
rule_t authenticateRule;
bool dismissed;
+
+ uint64_t engine_index;
};
static void
engine->mechanism_agents = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ engine->engine_index = global_engine_count++;
done:
return engine;
}
static void
_set_session_hints(engine_t engine, rule_t rule)
{
- os_log_debug(AUTHD_LOG, "engine: ** prepare agent hints for rule %{public}s", rule_get_name(rule));
+ os_log_debug(AUTHD_LOG, "engine %lld: ** prepare agent hints for rule %{public}s", engine->engine_index, rule_get_name(rule));
if (_evaluate_user_credential_for_rule(engine, engine->sessionCredential, rule, true, true, NULL) == errAuthorizationSuccess) {
const char * tmp = credential_get_name(engine->sessionCredential);
if (tmp != NULL) {
if (credential_is_right(cred) && credential_get_valid(cred) && _compare_string(engine->currentRightName, credential_get_name(cred))) {
if (!ignoreShared) {
if (!rule_get_shared(rule) && credential_get_shared(cred)) {
- os_log_error(AUTHD_LOG, "engine: - shared right %{public}s (does NOT satisfy rule)", credential_get_name(cred));
+ os_log_error(AUTHD_LOG, "Shared right %{public}s (does NOT satisfy rule) (engine %lld)", credential_get_name(cred), engine->engine_index);
if (reason) { *reason = unknownReason; }
return errAuthorizationDenied;
}
_evaluate_user_credential_for_rule(engine_t engine, credential_t cred, rule_t rule, bool ignoreShared, bool sessionOwner, enum Reason * reason)
{
const char * cred_label = sessionOwner ? "session owner" : "credential";
- os_log(AUTHD_LOG, "engine: - validating %{public}s%{public}s %{public}s (%i) for %{public}s", credential_get_shared(cred) ? "shared " : "",
+ os_log(AUTHD_LOG, "Validating %{public}s%{public}s %{public}s (%i) for %{public}s (engine %lld)", credential_get_shared(cred) ? "shared " : "",
cred_label,
credential_get_name(cred),
credential_get_uid(cred),
- rule_get_name(rule));
+ rule_get_name(rule),
+ engine->engine_index);
if (rule_get_class(rule) != RC_USER) {
- os_log(AUTHD_LOG, "engine: - invalid rule class %i (denied)", rule_get_class(rule));
+ os_log(AUTHD_LOG, "Invalid rule class %i (engine %lld)", rule_get_class(rule), engine->engine_index);
return errAuthorizationDenied;
}
if (credential_get_valid(cred) != true) {
- os_log(AUTHD_LOG, "engine: - %{public}s %i invalid (does NOT satisfy rule)", cred_label, credential_get_uid(cred));
+ os_log(AUTHD_LOG, "%{public}s %i invalid (does NOT satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index);
if (reason) { *reason = invalidPassphrase; }
return errAuthorizationDenied;
}
if (engine->now - credential_get_creation_time(cred) > rule_get_timeout(rule)) {
- os_log(AUTHD_LOG, "engine: - %{public}s %i expired '%f > %lli' (does NOT satisfy rule)", cred_label, credential_get_uid(cred),
- (engine->now - credential_get_creation_time(cred)), rule_get_timeout(rule));
+ os_log(AUTHD_LOG, "%{public}s %i expired '%f > %lli' (does NOT satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred),
+ (engine->now - credential_get_creation_time(cred)), rule_get_timeout(rule), engine->engine_index);
if (reason) { *reason = unknownReason; }
return errAuthorizationDenied;
}
-
if (!ignoreShared) {
if (!rule_get_shared(rule) && credential_get_shared(cred)) {
- os_log(AUTHD_LOG, "engine: - shared %{public}s %i (does NOT satisfy rule)", cred_label, credential_get_uid(cred));
+ os_log(AUTHD_LOG, "Shared %{public}s %i (does NOT satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index);
if (reason) { *reason = unknownReason; }
return errAuthorizationDenied;
}
}
if (credential_get_uid(cred) == 0) {
- os_log(AUTHD_LOG, "engine: - %{public}s %i has uid 0 (does satisfy rule)", cred_label, credential_get_uid(cred));
+ os_log(AUTHD_LOG, "%{public}s %i has uid 0 (does satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index);
return errAuthorizationSuccess;
}
if (rule_get_session_owner(rule)) {
if (credential_get_uid(cred) == session_get_uid(auth_token_get_session(engine->auth))) {
- os_log(AUTHD_LOG, "engine: - %{public}s %i is session owner (does satisfy rule)", cred_label, credential_get_uid(cred));
+ os_log(AUTHD_LOG, "%{public}s %i is session owner (does satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), engine->engine_index);
return errAuthorizationSuccess;
}
}
}
if (credential_check_membership(cred, rule_get_group(rule))) {
- os_log(AUTHD_LOG, "engine: - %{public}s %i is member of group %{public}s (does satisfy rule)", cred_label, credential_get_uid(cred), rule_get_group(rule));
+ os_log(AUTHD_LOG, "%{public}s %i is member of group %{public}s (does satisfy rule) (engine %lld)", cred_label, credential_get_uid(cred), rule_get_group(rule), engine->engine_index);
return errAuthorizationSuccess;
} else {
if (reason) { *reason = userNotInGroup; }
if (reason) { *reason = unacceptableUser; }
}
- os_log(AUTHD_LOG, "engine: - %{public}s %i (does NOT satisfy rule), reason %d", cred_label, credential_get_uid(cred), reason ? *reason : -1);
+ os_log(AUTHD_LOG, "%{public}s %i (does NOT satisfy rule), reason %d (engine %lld)", cred_label, credential_get_uid(cred), reason ? *reason : -1, engine->engine_index);
return errAuthorizationDenied;
}
CFDataRef passdata = LACopyCredential(engine->la_context, kLACredentialTypeExtractablePasscode, NULL);
if (passdata) {
if (CFDataGetBytePtr(passdata)) {
+ os_log_debug(AUTHD_LOG, "engine %lld: LA credentials retrieved", engine->engine_index);
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
+ os_log_debug(AUTHD_LOG, "engine %lld: LA credentials empty", engine->engine_index);
auth_items_set_data(engine->context, kAuthorizationEnvironmentPassword, empty_pass, 1);
}
CFRelease(passdata);
CFMutableDictionaryRef options = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(options, key, value);
la_result = LACopyResultOfPolicyEvaluation(engine->la_context, kLAPolicyDeviceOwnerAuthentication, options, NULL);
+ os_log_debug(AUTHD_LOG, "engine %lld: Retrieve LA evaluate result: %d", engine->engine_index, la_result != NULL);
CFReleaseSafe(options);
}
CFReleaseSafe(key);
mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(mechanisms, i);
if (mechanism_get_type(mech)) {
- os_log_debug(AUTHD_LOG, "engine: running builtin mechanism %{public}s (%li of %li)", mechanism_get_string(mech), i+1, count);
+ os_log_debug(AUTHD_LOG, "engine %lld: running builtin mechanism %{public}s (%li of %li)", engine->engine_index, mechanism_get_string(mech), i+1, count);
result = _evaluate_builtin_mechanism(engine, mech);
} else {
bool shoud_run_agent = true; // evaluate comes from sheet -> we may not want to run standard SecurityAgent or authhost
if (strcmp(mechanism_get_string(mech), "builtin:authenticate") == 0) {
// set the UID the same way as SecurityAgent would
if (auth_items_exist(engine->context, "sheet-uid")) {
- os_log_debug(AUTHD_LOG, "engine: setting sheet UID %d to the context", auth_items_get_uint(engine->context, "sheet-uid"));
+ os_log_debug(AUTHD_LOG, "engine %lld: setting sheet UID %d to the context", engine->engine_index, auth_items_get_uint(engine->context, "sheet-uid"));
auth_items_set_uint(engine->context, "uid", auth_items_get_uint(engine->context, "sheet-uid"));
}
// otherwise we need to check la_result
if (auth_items_exist(engine->context, AGENT_CONTEXT_AP_PAM_SERVICE_NAME) || auth_items_exist(engine->context, kAuthorizationEnvironmentPassword)) {
// do not try to get credentials as it has been already passed by sheet
- os_log(AUTHD_LOG, "engine: ignoring builtin sheet authenticate");
+ os_log_debug(AUTHD_LOG, "engine %lld: ignoring builtin sheet authenticate", engine->engine_index);
} else {
// sheet itself did the authenticate the user
- os_log(AUTHD_LOG, "engine: running builtin sheet authenticate");
+ os_log_debug(AUTHD_LOG, "engine %lld: running builtin sheet authenticate", engine->engine_index);
sheet_evaluation = true;
if (!la_result || TKGetSmartcardSetting(kTKEnforceSmartcard) != 0) {
result = kAuthorizationResultDeny; // no la_result => evaluate did not pass for sheet method. Enforced smartcard => no way to use sheet based evaluation
shoud_run_agent = false; // SecurityAgent should not be run for builtin:authenticate
} else if (strcmp(mechanism_get_string(mech), "builtin:authenticate,privileged") == 0) {
if (sheet_evaluation) {
- os_log(AUTHD_LOG, "engine: running builtin sheet privileged authenticate");
+ os_log_debug(AUTHD_LOG, "engine %lld: running builtin sheet privileged authenticate", engine->engine_index);
shoud_run_agent = false;
if (!la_result || TKGetSmartcardSetting(kTKEnforceSmartcard) != 0) { // should not get here under normal circumstances but we need to handle this case as well
result = kAuthorizationResultDeny; // no la_result => evaluate did not pass. Enforced smartcard => no way to use sheet based evaluation
}
} else {
// should_run_agent has to be set to true because we want authorizationhost to verify the credentials
- os_log(AUTHD_LOG, "engine: running sheet privileged authenticate");
+ os_log_debug(AUTHD_LOG, "engine %lld: running sheet privileged authenticate", engine->engine_index);
}
}
}
if (shoud_run_agent) {
agent_t agent = _get_agent(engine, mech, true, i == 0);
- require_action(agent != NULL, done, result = kAuthorizationResultUndefined; os_log_error(AUTHD_LOG, "engine: error creating mechanism agent"));
+ require_action(agent != NULL, done, result = kAuthorizationResultUndefined; os_log_error(AUTHD_LOG, "Error creating mechanism agent (engine %lld)", engine->engine_index));
// check if any agent has been interrupted (it necessary if interrupt will come during creation)
CFIndex j;
}
}
if (j < i) {
- os_log(AUTHD_LOG, "engine: mechanisms interrupted");
+ os_log(AUTHD_LOG, "engine %lld: mechanisms interrupted", engine->engine_index);
char * buf = NULL;
asprintf(&buf, "evaluation interrupted by %s; restarting evaluation there", mechanism_get_string(agent_get_mechanism(agent1)));
ccaudit_log_mechanism(ccaudit, engine->currentRightName, mechanism_get_string(agent_get_mechanism(agent1)), kAuthorizationResultAllow, buf);
continue;
}
- os_log(AUTHD_LOG, "engine: running mechanism %{public}s (%li of %li)", mechanism_get_string(agent_get_mechanism(agent)), i+1, count);
+ os_log(AUTHD_LOG, "engine %lld: running mechanism %{public}s (%li of %li)", engine->engine_index, mechanism_get_string(agent_get_mechanism(agent)), i+1, count);
result = agent_run(agent, hints, context, engine->immutable_hints);
}
if (interrupted) {
- os_log(AUTHD_LOG, "engine: mechanisms interrupted");
+ os_log_info(AUTHD_LOG, "Mechanisms interrupted (engine %lld)", engine->engine_index);
enum Reason reason = worldChanged;
auth_items_set_data(hints, AGENT_HINT_RETRY_REASON, &reason, sizeof(reason));
result = kAuthorizationResultAllow;
return errAuthorizationInternal;
default:
{
- os_log_error(AUTHD_LOG, "engine: unexpected error result");
+ os_log_error(AUTHD_LOG, "Evaluate - unexpected result %llu (engine %lld)", result, engine->engine_index);
return errAuthorizationInternal;
}
}
{
OSStatus status = errAuthorizationDenied;
ccaudit_t ccaudit = ccaudit_create(engine->proc, engine->auth, AUE_ssauthint);
- os_log_debug(AUTHD_LOG, "engine: evaluate authentication");
+ os_log_debug(AUTHD_LOG, "engine %lld: evaluate authentication", engine->engine_index);
_set_rule_hints(engine->hints, rule);
_set_session_hints(engine, rule);
if (!(CFArrayGetCount(mechanisms) > 0)) {
mechanisms = rule_get_mechanisms(engine->authenticateRule);
}
- require_action(CFArrayGetCount(mechanisms) > 0, done, os_log_debug(AUTHD_LOG, "engine: error no mechanisms found"));
+ require_action(CFArrayGetCount(mechanisms) > 0, done, os_log_debug(AUTHD_LOG, "engine %lld: error - no mechanisms found", engine->engine_index));
int64_t ruleTries = rule_get_tries(rule);
if (engine->la_context) {
ruleTries = 1;
- os_log_debug(AUTHD_LOG, "Sheet authentication in progress, one try is enough");
+ os_log_debug(AUTHD_LOG, "engine %lld: sheet authentication in progress, one try is enough", engine->engine_index);
}
for (engine->tries = 0; engine->tries < ruleTries; engine->tries++) {
auth_items_set_int(engine->hints, AGENT_HINT_TRIES, engine->tries);
status = _evaluate_mechanisms(engine, mechanisms);
- os_log_debug(AUTHD_LOG, "engine: evaluate mechanisms result %d", (int)status);
+ os_log_debug(AUTHD_LOG, "engine %lld: evaluate mechanisms result %d", engine->engine_index, (int)status);
// successfully ran mechanisms to obtain credential
if (status == errAuthorizationSuccess) {
if (auth_items_exist(engine->context, "uid")) {
newCred = credential_create(auth_items_get_uint(engine->context, "uid"));
} else {
- os_log_error(AUTHD_LOG, "engine: mechanism failed to return a valid uid");
+ os_log_info(AUTHD_LOG, "Mechanism failed to return a valid uid (engine %lld)", engine->engine_index);
if (engine->la_context) {
// sheet failed so remove sheet reference and next time, standard dialog will be displayed
CFReleaseNull(engine->la_context);
session_t session = auth_token_get_session(engine->auth);
if (credential_get_uid(newCred) == session_get_uid(session)) {
- os_log_debug(AUTHD_LOG, "engine: authenticated as the session owner");
+ os_log_debug(AUTHD_LOG, "engine %lld: authenticated as the session owner", engine->engine_index);
session_set_attributes(auth_token_get_session(engine->auth), AU_SESSION_FLAG_HAS_AUTHENTICATED);
}
break;
} else {
- os_log_error(AUTHD_LOG, "engine: user credential for rule failed (%d)", (int)status);
+ os_log_error(AUTHD_LOG, "User credential for rule failed (%d) (engine %lld)", (int)status, engine->engine_index);
}
CFReleaseSafe(newCred);
}
} else if (status == errAuthorizationCanceled || status == errAuthorizationInternal) {
- os_log_error(AUTHD_LOG, "engine: evaluate cancelled or failed %d", (int)status);
+ os_log_error(AUTHD_LOG, "Evaluate cancelled or failed %d (engine %lld)", (int)status, engine->engine_index);
break;
} else if (status == errAuthorizationDenied) {
- os_log_error(AUTHD_LOG, "engine: evaluate denied");
+ os_log_error(AUTHD_LOG, "Evaluate denied (engine %lld)", engine->engine_index);
engine->reason = invalidPassphrase;
}
}
if (rule_check_flags(rule, RuleFlagEntitledAndGroup)) {
if (auth_token_has_entitlement_for_right(engine->auth, engine->currentRightName)) {
if (credential_check_membership(auth_token_get_credential(engine->auth), rule_get_group(rule))) {
- os_log_debug(AUTHD_LOG, "engine: creator of authorization has entitlement for right %{public}s and is member of group '%{public}s'", engine->currentRightName, rule_get_group(rule));
+ os_log_info(AUTHD_LOG, "Creator of authorization has entitlement for right %{public}s and is member of group '%{public}s' (engine %lld)", engine->currentRightName, rule_get_group(rule), engine->engine_index);
entitled = true;
goto done;
}
value = auth_token_copy_entitlement_value(engine->auth, "com.apple.networking.vpn.configuration");
if (value) {
if (credential_check_membership(auth_token_get_credential(engine->auth), rule_get_group(rule))) {
- os_log_debug(AUTHD_LOG, "engine: creator of authorization has VPN entitlement and is member of group '%{public}s'", rule_get_group(rule));
+ os_log_info(AUTHD_LOG, "Creator of authorization has VPN entitlement and is member of group '%{public}s' (engine %lld)", rule_get_group(rule), engine->engine_index);
entitled = true;
goto done;
}
}
if (rule_get_allow_root(rule) && auth_token_get_uid(engine->auth) == 0) {
- os_log_debug(AUTHD_LOG, "engine: creator of authorization has uid == 0 granting right %{public}s", engine->currentRightName);
+ os_log_info(AUTHD_LOG, "Creator of authorization has uid == 0, granting right %{public}s (engine %lld)", engine->currentRightName, engine->engine_index);
return errAuthorizationSuccess;
}
// Finally - we didn't find a credential. Obtain a new credential if our flags let us do so.
if (!(engine->flags & kAuthorizationFlagExtendRights)) {
- os_log_error(AUTHD_LOG, "engine: authorization denied (kAuthorizationFlagExtendRights not set)");
+ os_log_error(AUTHD_LOG, "Fatal: authorization denied (kAuthorizationFlagExtendRights not set) (engine %lld)", engine->engine_index);
return errAuthorizationDenied;
}
if (!engine->preauthorizing) {
if (!(engine->flags & kAuthorizationFlagInteractionAllowed)) {
- os_log_error(AUTHD_LOG, "engine: Interaction not allowed (kAuthorizationFlagInteractionAllowed not set)");
+ os_log_error(AUTHD_LOG, "Fatal: interaction not allowed (kAuthorizationFlagInteractionAllowed not set) (engine %lld)", engine->engine_index);
return errAuthorizationInteractionNotAllowed;
}
if (!(session_get_attributes(auth_token_get_session(engine->auth)) & AU_SESSION_FLAG_HAS_GRAPHIC_ACCESS)) {
- os_log_error(AUTHD_LOG, "engine: Interaction not allowed (session has no ui access)");
+ os_log_error(AUTHD_LOG, "Fatal: interaction not allowed (session has no ui access) (engine %lld)", engine->engine_index);
return errAuthorizationInteractionNotAllowed;
}
if (server_in_dark_wake()) {
- os_log_error(AUTHD_LOG, "engine: authorization denied (DW)");
+ os_log_error(AUTHD_LOG, "Fatal: authorization denied (DW) (engine %lld)", engine->engine_index);
return errAuthorizationDenied;
}
}
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 %u delegates kofn = %lli",rule_get_name(rule), total, kofn);
+ os_log_debug(AUTHD_LOG, "engine %lld: ** rule %{public}s has %u delegates kofn = %lli", engine->engine_index, rule_get_name(rule), total, kofn);
rule_delegates_iterator(rule, ^bool(rule_t delegate) {
count++;
return false;
}
- os_log_debug(AUTHD_LOG, "engine: * evaluate rule %{public}s (%i)", rule_get_name(delegate), count);
+ os_log_debug(AUTHD_LOG, "engine %lld: * evaluate rule %{public}s (%i)", engine->engine_index, rule_get_name(delegate), count);
status = _evaluate_rule(engine, delegate, save_pwd);
// if status is cancel/internal error abort
if (kofn != 0) {
// if remaining is less than required abort
if ((total - count) < (kofn - success_count)) {
- os_log_debug(AUTHD_LOG, "engine: rule evaluation remaining: %i, required: %lli", (total - count), (kofn - success_count));
+ os_log_debug(AUTHD_LOG, "engine %lld: rule evaluation remaining: %i, required: %lli", engine->engine_index, (total - count), (kofn - success_count));
return false;
}
return true;
static bool
_preevaluate_class_rule(engine_t engine, rule_t rule)
{
- os_log_debug(AUTHD_LOG, "engine: _preevaluate_class_rule %{public}s", rule_get_name(rule));
+ os_log_debug(AUTHD_LOG, "engine %lld: _preevaluate_class_rule %{public}s", engine->engine_index, rule_get_name(rule));
__block bool password_only = false;
rule_delegates_iterator(rule, ^bool(rule_t delegate) {
OSStatus status = errAuthorizationDenied;
CFArrayRef mechanisms = NULL;
- require_action(rule_get_mechanisms_count(rule) > 0, done, status = errAuthorizationSuccess; os_log_error(AUTHD_LOG, "engine: no mechanisms specified"));
+ require_action(rule_get_mechanisms_count(rule) > 0, done, status = errAuthorizationSuccess; os_log_error(AUTHD_LOG, "Fatal: no mechanisms specified (engine %lld)", engine->engine_index));
mechanisms = rule_get_mechanisms(rule);
CFIndex count = CFArrayGetCount(mechanisms);
for (CFIndex i = 0; i < count; i++) {
if (!mechanism_is_privileged((mechanism_t)CFArrayGetValueAtIndex(mechanisms, i))) {
- os_log_error(AUTHD_LOG, "engine: authorization denied (in DW)");
+ os_log_error(AUTHD_LOG, "Fatal: authorization denied (in DW) (engine %lld)", engine->engine_index);
goto done;
}
}
auth_items_set_int(engine->hints, AGENT_HINT_TRIES, engine->tries);
status = _evaluate_mechanisms(engine, mechanisms);
- os_log_debug(AUTHD_LOG, "engine: evaluate mechanisms result %d", (int)status);
+ os_log_debug(AUTHD_LOG, "engine %lld: evaluate mechanisms result %d", engine->engine_index, (int)status);
if (status == errAuthorizationSuccess) {
credential_t newCred = NULL;
if (auth_items_exist(engine->context, "uid")) {
newCred = credential_create(auth_items_get_uint(engine->context, "uid"));
} else {
- os_log(AUTHD_LOG, "engine: mechanism did not return a uid");
+ os_log_info(AUTHD_LOG, "Mechanism did not return a uid (engine %lld)", engine->engine_index);
}
if (newCred) {
{
if (rule_check_flags(rule, RuleFlagEntitled)) {
if (auth_token_has_entitlement_for_right(engine->auth, engine->currentRightName)) {
- os_log_debug(AUTHD_LOG, "engine: rule allow, creator of authorization has entitlement for right %{public}s", engine->currentRightName);
+ os_log_debug(AUTHD_LOG, "engine %lld: rule allow, creator of authorization has entitlement for right %{public}s", engine->engine_index, engine->currentRightName);
return errAuthorizationSuccess;
}
}
if (engine->la_context || rule_check_flags(rule, RuleFlagRequireAppleSigned)) {
if (!auth_token_apple_signed(engine->auth)) {
#ifdef NDEBUG
- os_log_error(AUTHD_LOG, "engine: rule deny, creator of authorization is not signed by Apple");
+ os_log_error(AUTHD_LOG, "Rule deny, creator of authorization is not signed by Apple (engine %lld)", engine->engine_index);
return errAuthorizationDenied;
#else
- os_log_debug(AUTHD_LOG, "engine: in release mode, this rule would be denied because creator of authorization is not signed by Apple");
+ os_log_debug(AUTHD_LOG, "engine %lld: in release mode, this rule would be denied because creator of authorization is not signed by Apple", engine->engine_index);
#endif
}
}
CFTypeRef extract_password_entitlement = auth_token_copy_entitlement_value(engine->auth, "com.apple.authorization.extract-password");
if (extract_password_entitlement && (CFGetTypeID(extract_password_entitlement) == CFBooleanGetTypeID()) && extract_password_entitlement == kCFBooleanTrue) {
*save_pwd = TRUE;
- os_log_debug(AUTHD_LOG, "engine: authorization allowed to extract password");
+ os_log_debug(AUTHD_LOG, "engine %lld: authorization allowed to extract password", engine->engine_index);
} else {
- os_log_debug(AUTHD_LOG, "engine: authorization NOT allowed to extract password");
+ os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index);
}
CFReleaseSafe(extract_password_entitlement);
}
switch (rule_get_class(rule)) {
case RC_ALLOW:
- os_log(AUTHD_LOG, "engine: rule set to allow");
+ os_log(AUTHD_LOG, "Rule set to allow (engine %lld)", engine->engine_index);
return errAuthorizationSuccess;
case RC_DENY:
- os_log(AUTHD_LOG, "engine: rule set to deny");
+ os_log(AUTHD_LOG, "Rule set to deny (engine %lld)", engine->engine_index);
return errAuthorizationDenied;
case RC_USER:
return _evaluate_class_user(engine, rule);
case RC_MECHANISM:
return _evaluate_class_mechanism(engine, rule);
default:
- os_log_error(AUTHD_LOG, "engine: invalid class for rule or rule not found: %{public}s", rule_get_name(rule));
+ os_log_error(AUTHD_LOG, "Invalid class for rule or rule not found: %{public}s (engine %lld)", rule_get_name(rule), engine->engine_index);
return errAuthorizationInternal;
}
}
static bool
_preevaluate_rule(engine_t engine, rule_t rule)
{
- os_log_debug(AUTHD_LOG, "engine: _preevaluate_rule %{public}s", rule_get_name(rule));
+ os_log_debug(AUTHD_LOG, "engine %lld: _preevaluate_rule %{public}s", engine->engine_index, rule_get_name(rule));
switch (rule_get_class(rule)) {
case RC_ALLOW:
r = rule_create_with_string("", dbconn);
if (rule_get_id(r) == 0) {
CFReleaseNull(r);
- os_log_error(AUTHD_LOG, "engine: default rule lookup error (missing), using builtin defaults");
+ os_log_error(AUTHD_LOG, "Default rule lookup error (missing), using builtin defaults (engine %lld)", engine->engine_index);
r = rule_create_default();
}
}
require(environment != NULL, done);
#if DEBUG
- os_log_debug(AUTHD_LOG, "engine: Dumping Environment: %@", environment);
+ os_log_debug(AUTHD_LOG, "engine %lld: Dumping Environment: %@", engine->engine_index, environment);
#endif
// Check if a credential was passed into the environment and we were asked to extend the rights
require(password_was_used == true, done);
bool shared = auth_items_exist(environment, kAuthorizationEnvironmentShared);
- require_action(user != NULL, done, os_log_debug(AUTHD_LOG, "engine: user not used password"));
+ require_action(user != NULL, done, os_log_debug(AUTHD_LOG, "engine %lld: user not used password", engine->engine_index));
struct passwd *pw = getpwnam(user);
- require_action(pw != NULL, done, os_log_error(AUTHD_LOG, "engine: user not found %{public}s", user));
+ require_action(pw != NULL, done, os_log_error(AUTHD_LOG, "User not found %{public}s (engine %lld)", user, engine->engine_index));
int checkpw_status = checkpw_internal(pw, pass ? pass : "");
- require_action(checkpw_status == CHECKPW_SUCCESS, done, os_log_error(AUTHD_LOG, "engine: checkpw() returned %d; failed to authenticate user %{public}s (uid %u).", checkpw_status, pw->pw_name, pw->pw_uid));
+ require_action(checkpw_status == CHECKPW_SUCCESS, done, os_log_error(AUTHD_LOG, "engine %lld: checkpw() returned %d; failed to authenticate user %{public}s (uid %u).", engine->engine_index, checkpw_status, pw->pw_name, pw->pw_uid));
credential_t cred = credential_create(pw->pw_uid);
if (credential_get_valid(cred)) {
- os_log(AUTHD_LOG, "engine: checkpw() succeeded, creating credential for user %{public}s", user);
+ os_log_info(AUTHD_LOG, "checkpw() succeeded, creating credential for user %{public}s (engine %lld)", user, engine->engine_index);
_engine_set_credential(engine, cred, shared);
auth_items_set_string(engine->context, kAuthorizationEnvironmentUsername, user);
{
pid_t pid = process_get_pid(engine->proc);
if (sandbox_check(pid, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) {
- os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' by client '%{public}s' [%d]", right, process_get_code_url(engine->proc), pid);
+ os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' by client '%{public}s' [%d] (engine %lld)", right, process_get_code_url(engine->proc), pid, engine->engine_index);
return false;
}
pid = auth_token_get_pid(engine->auth);
if (auth_token_get_sandboxed(engine->auth) && sandbox_check_by_audit_token(auth_token_get_audit_info(engine->auth)->opaqueToken, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) {
- os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' for authorization created by '%{public}s' [%d]", right, auth_token_get_code_url(engine->auth), pid);
+ os_log_error(AUTHD_LOG, "Sandbox denied authorizing right '%{public}s' for authorization created by '%{public}s' [%d] (engine %lld)", right, auth_token_get_code_url(engine->auth), pid, engine->engine_index);
return false;
}
OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials)
{
- os_log(AUTHD_LOG, "engine: preauthorizing");
+ os_log(AUTHD_LOG, "engine %lld: preauthorizing", engine->engine_index);
OSStatus status = errAuthorizationDenied;
bool save_password = false;
CFTypeRef extract_password_entitlement = auth_token_copy_entitlement_value(engine->auth, "com.apple.authorization.extract-password");
if (extract_password_entitlement && (CFGetTypeID(extract_password_entitlement) == CFBooleanGetTypeID()) && extract_password_entitlement == kCFBooleanTrue) {
save_password = true;
- os_log_debug(AUTHD_LOG, "engine: authorization allowed to extract password");
+ os_log_debug(AUTHD_LOG, "engine %lld: authorization allowed to extract password", engine->engine_index);
} else {
- os_log_debug(AUTHD_LOG, "engine: authorization NOT allowed to extract password");
+ os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index);
}
CFReleaseSafe(extract_password_entitlement);
}
auth_items_t decrypted_items = auth_items_create();
- require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: unable to create items"));
+ require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index));
auth_items_content_copy(decrypted_items, auth_token_get_context(engine->auth));
auth_items_decrypt(decrypted_items, auth_token_get_encryption_key(engine->auth));
auth_items_copy(engine->context, decrypted_items);
status = _evaluate_rule(engine, rule, &save_password);
switch (status) {
case errAuthorizationSuccess:
- os_log(AUTHD_LOG, "Succeeded preauthorizing client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d)",
+ os_log(AUTHD_LOG, "Succeeded preauthorizing client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (engine %lld)",
process_get_code_url(engine->proc), process_get_pid(engine->proc),
- auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth));
+ auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), engine->engine_index);
status = errAuthorizationSuccess;
break;
case errAuthorizationDenied:
case errAuthorizationInteractionNotAllowed:
case errAuthorizationCanceled:
- os_log(AUTHD_LOG, "Failed to preauthorize client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i)",
+ os_log(AUTHD_LOG, "Failed to preauthorize client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i) (engine %lld)",
process_get_code_url(engine->proc), process_get_pid(engine->proc),
- auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status);
+ auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status, engine->engine_index);
break;
default:
- os_log_error(AUTHD_LOG, "engine: preauthorize returned %d => returning errAuthorizationInternal", (int)status);
+ os_log_error(AUTHD_LOG, "Preauthorize returned %d => returning errAuthorizationInternal (engine %lld)", (int)status, engine->engine_index);
status = errAuthorizationInternal;
break;
}
CFReleaseSafe(rule);
if (engine->dismissed) {
- os_log_error(AUTHD_LOG, "engine: engine dismissed");
+ os_log_error(AUTHD_LOG, "Engine dismissed (engine %lld)", engine->engine_index);
status = errAuthorizationDenied;
}
- os_log_debug(AUTHD_LOG, "engine: preauthorize result: %d", (int)status);
+ os_log_debug(AUTHD_LOG, "engine %lld: preauthorize result: %d", engine->engine_index, (int)status);
_cf_set_iterate(engine->credentials, ^bool(CFTypeRef value) {
credential_t cred = (credential_t)value;
session_set_credential(session, cred);
}
if (credential_is_right(cred)) {
- os_log(AUTHD_LOG, "engine: adding least privileged %{public}scredential %{public}s to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred));
+ os_log(AUTHD_LOG, "engine %lld: adding least privileged %{public}scredential %{public}s to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred));
} else {
- os_log(AUTHD_LOG, "engine: adding %{public}scredential %{public}s (%i) to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred));
+ os_log(AUTHD_LOG, "engine %lld: adding %{public}scredential %{public}s (%i) to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred));
}
return true;
});
if ((status == errAuthorizationSuccess) || (status == errAuthorizationCanceled)) {
auth_items_t encrypted_items = auth_items_create();
- require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: unable to create items"));
+ require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index));
auth_items_content_copy_with_flags(encrypted_items, engine->context, kAuthorizationContextFlagExtractable);
#if DEBUG
- os_log_debug(AUTHD_LOG, "engine: ********** Dumping preauthorized context for encryption **********");
+ os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping preauthorized context for encryption **********", engine->engine_index);
os_log_debug(AUTHD_LOG, "%@", encrypted_items);
#endif
auth_items_encrypt(encrypted_items, auth_token_get_encryption_key(engine->auth));
auth_items_copy_with_flags(auth_token_get_context(engine->auth), encrypted_items, kAuthorizationContextFlagExtractable);
- os_log_debug(AUTHD_LOG, "engine: encrypted preauthorization context data");
+ os_log_debug(AUTHD_LOG, "engine %lld: encrypted preauthorization context data", engine->engine_index);
CFReleaseSafe(encrypted_items);
}
__block OSStatus status = errAuthorizationSuccess;
__block bool save_password = false;
__block bool password_only = false;
-
+ CFIndex rights_count = auth_rights_get_count(rights);
ccaudit_t ccaudit = NULL;
require(rights != NULL, done);
if (auth_rights_get_count(rights) > 0) {
ccaudit_log(ccaudit, "begin evaluation", NULL, 0);
}
-
+
+ if (rights_count) {
+ __block CFMutableArrayRef rights_list = NULL;
+ rights_list = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+ auth_rights_iterate(rights, ^bool(const char *key) {
+ if (!key)
+ return true;
+
+ CFStringRef tmp = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8);
+ if (tmp) {
+ CFArrayAppendValue(rights_list, tmp);
+ CFRelease(tmp);
+ } else {
+ os_log_error(AUTHD_LOG, "Unable to get details for right %{public}s", key);
+ }
+ return true;
+ });
+
+ os_log_info(AUTHD_LOG, "Process %{public}s (PID %d) evaluates %ld rights (engine %lld): %{public}@", process_get_code_url(engine->proc), process_get_pid(engine->proc), (long)rights_count, engine->engine_index, rights_list);
+ CFReleaseNull(rights_list);
+ }
+
if (!auth_token_apple_signed(engine->auth)) {
#ifdef NDEBUG
- flags &= ~kAuthorizationFlagIgnorePasswordOnly;
flags &= ~kAuthorizationFlagSheet;
#else
- os_log_debug(AUTHD_LOG, "engine: in release mode, extra flags would be ommited as creator is not signed by Apple");
+ os_log_debug(AUTHD_LOG, "engine %lld: in release mode, extra flags would be ommited as creator is not signed by Apple", engine->engine_index);
#endif
}
auth_items_copy(engine->hints, environment);
}
- // First restore all context values from the AuthorizationRef
+ // Restore all context values from the AuthorizationRef
auth_items_t decrypted_items = auth_items_create();
- require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: enable to create items"));
+ require_action(decrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index));
auth_items_content_copy(decrypted_items, auth_token_get_context(engine->auth));
auth_items_decrypt(decrypted_items, auth_token_get_encryption_key(engine->auth));
auth_items_copy(engine->context, decrypted_items);
CFTypeRef extract_password_entitlement = auth_token_copy_entitlement_value(engine->auth, "com.apple.authorization.extract-password");
if (extract_password_entitlement && (CFGetTypeID(extract_password_entitlement) == CFBooleanGetTypeID()) && extract_password_entitlement == kCFBooleanTrue) {
save_password = true;
- os_log_debug(AUTHD_LOG, "engine: authorization allowed to extract password");
+ os_log_debug(AUTHD_LOG, "engine %lld: authorization allowed to extract password", engine->engine_index);
} else {
- os_log_debug(AUTHD_LOG, "engine: authorization NOT allowed to extract password");
+ os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index);
}
CFReleaseSafe(extract_password_entitlement);
}
// Try to use/update fresh context values from the environment
- require_action(environment, done, os_log_debug(AUTHD_LOG, "engine: Missing environment for sheet authorization"); status = errAuthorizationDenied);
+ require_action(environment, done, os_log_error(AUTHD_LOG, "Missing environment for sheet authorization (engine %lld)", engine->engine_index); status = errAuthorizationDenied);
const char *user = auth_items_get_string(environment, kAuthorizationEnvironmentUsername);
- require_action(user, done, os_log_debug(AUTHD_LOG, "engine: Missing username"); status = errAuthorizationDenied);
+ require_action(user, done, os_log_error(AUTHD_LOG, "Missing username (engine %lld)", engine->engine_index); status = errAuthorizationDenied);
auth_items_set_string(engine->context, kAuthorizationEnvironmentUsername, user);
struct passwd *pwd = getpwnam(user);
- require_action(pwd, done, os_log_debug(AUTHD_LOG, "engine: Invalid username %s", user); status = errAuthorizationDenied);
+ require_action(pwd, done, os_log_error(AUTHD_LOG, "Invalid username %s (engine %lld)", user, engine->engine_index); status = errAuthorizationDenied);
auth_items_set_uint(engine->context, "sheet-uid", pwd->pw_uid);
// move sheet-specific items from hints to context
auth_rights_iterate(rights, ^bool(const char *key) {
if (!key)
return true;
- os_log_debug(AUTHD_LOG, "engine: checking if rule %{public}s contains password-only item", key);
+ os_log_debug(AUTHD_LOG, "engine %lld: checking if rule %{public}s contains password-only item", engine->engine_index, key);
rule_t rule = _find_rule(engine, dbconn, key);
});
authdb_connection_release(&dbconn); // release db handle
} else {
- os_log_info(AUTHD_LOG, "engine: password-only ignored");
+ os_log_info(AUTHD_LOG, "Password-only flag ignored (engine %lld)", engine->engine_index);
}
if (password_only) {
- os_log_debug(AUTHD_LOG, "engine: password-only item found, forcing SecurityAgent to use password-only UI");
+ os_log_debug(AUTHD_LOG, "engine %lld: password-only item found, forcing SecurityAgent to use password-only UI", engine->engine_index);
auth_items_set_bool(engine->immutable_hints, AGENT_HINT_PASSWORD_ONLY, true);
}
authdb_connection_t dbconn = authdb_connection_acquire(server_get_database()); // get db handle
- os_log_debug(AUTHD_LOG, "engine: evaluate right %{public}s", key);
+ os_log_debug(AUTHD_LOG, "engine %lld: evaluate right %{public}s", engine->engine_index, key);
rule_t rule = _find_rule(engine, dbconn, key);
const char * rule_name = rule_get_name(rule);
if (rule_name && (strcasecmp(rule_name, "") == 0)) {
rule_name = "default (not defined)";
}
- os_log_debug(AUTHD_LOG, "engine: using rule %{public}s", rule_name);
+ os_log_debug(AUTHD_LOG, "engine %lld: using rule %{public}s", engine->engine_index, rule_name);
// only need the hints & mechanisms if we are going to show ui
if (engine->flags & kAuthorizationFlagInteractionAllowed) {
auth_rights_set_flags(engine->grantedRights, engine->currentRightName, kAuthorizationFlagPreAuthorize);
}
- os_log(AUTHD_LOG, "Succeeded authorizing right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d)",
+ os_log(AUTHD_LOG, "Succeeded authorizing right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (engine %lld)",
key, process_get_code_url(engine->proc), process_get_pid(engine->proc),
- auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth));
+ auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), engine->engine_index);
break;
case errAuthorizationDenied:
case errAuthorizationInteractionNotAllowed:
case errAuthorizationCanceled:
if (engine->flags & kAuthorizationFlagInteractionAllowed) {
- os_log(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i)",
+ os_log(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%i) (engine %lld)",
key, process_get_code_url(engine->proc), process_get_pid(engine->proc),
- auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status);
+ auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status,
+ engine->engine_index);
} else {
- os_log_debug(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%d)",
+ os_log_debug(AUTHD_LOG, "Failed to authorize right '%{public}s' by client '%{public}s' [%d] for authorization created by '%{public}s' [%d] (%X,%d) (%d) (engine %lld)",
key, process_get_code_url(engine->proc), process_get_pid(engine->proc),
- auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status);
+ auth_token_get_code_url(engine->auth), auth_token_get_pid(engine->auth), (unsigned int)engine->flags, auth_token_least_privileged(engine->auth), (int)status,
+ engine->engine_index);
}
break;
default:
- os_log_error(AUTHD_LOG, "engine: evaluate returned %d returning errAuthorizationInternal", (int)status);
+ os_log_error(AUTHD_LOG, "Evaluate returned %d, returning errAuthorizationInternal (engine %lld)", (int)status, engine->engine_index);
status = errAuthorizationInternal;
break;
}
});
if (password_only) {
- os_log_debug(AUTHD_LOG, "engine: removing password-only flag");
+ os_log_debug(AUTHD_LOG, "engine %lld: removing password-only flag", engine->engine_index);
auth_items_remove(engine->immutable_hints, AGENT_HINT_PASSWORD_ONLY);
}
}
if (engine->dismissed) {
- os_log_error(AUTHD_LOG, "engine: dismissed");
+ os_log_error(AUTHD_LOG, "Dismissed (engine %lld)", engine->engine_index);
status = errAuthorizationDenied;
}
- os_log_debug(AUTHD_LOG, "engine: authorize result: %d", (int)status);
+ os_log_debug(AUTHD_LOG, "engine %lld: authorize result: %d", engine->engine_index, (int)status);
if (engine->flags & kAuthorizationFlagSheet) {
engine->preauthorizing = false;
session_set_credential(session, cred);
}
if (credential_is_right(cred)) {
- os_log_debug(AUTHD_LOG, "engine: adding least privileged %{public}scredential %{public}s to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred));
+ os_log_debug(AUTHD_LOG, "engine %lld: adding least privileged %{public}scredential %{public}s to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred));
} else {
- os_log_debug(AUTHD_LOG, "engine: adding %{public}scredential %{public}s (%i) to authorization", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred));
+ os_log_debug(AUTHD_LOG, "engine %lld: adding %{public}scredential %{public}s (%i) to authorization", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred));
}
return true;
});
if ((status == errAuthorizationSuccess) || (status == errAuthorizationCanceled)) {
auth_items_t encrypted_items = auth_items_create();
- require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "engine: unable to create items"));
+ require_action(encrypted_items != NULL, done, os_log_error(AUTHD_LOG, "Unable to create items (engine %lld)", engine->engine_index));
auth_items_content_copy_with_flags(encrypted_items, engine->context, kAuthorizationContextFlagExtractable);
#if DEBUG
- os_log_debug(AUTHD_LOG,"engine: ********** Dumping context for encryption **********");
+ os_log_debug(AUTHD_LOG,"engine %lld: ********** Dumping context for encryption **********", engine->engine_index);
os_log_debug(AUTHD_LOG, "%@", encrypted_items);
#endif
auth_items_encrypt(encrypted_items, auth_token_get_encryption_key(engine->auth));
auth_items_copy_with_flags(auth_token_get_context(engine->auth), encrypted_items, kAuthorizationContextFlagExtractable);
- os_log_debug(AUTHD_LOG, "engine: encrypted authorization context data");
- CFReleaseSafe(encrypted_items);
+ os_log_debug(AUTHD_LOG, "engine %lld: encrypted authorization context data", engine->engine_index);
+ CFReleaseSafe(encrypted_items);
}
if (auth_rights_get_count(rights) > 0) {
}
#if DEBUG
- os_log_debug(AUTHD_LOG, "engine: ********** Dumping auth->credentials **********");
+ os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping auth->credentials **********", engine->engine_index);
auth_token_credentials_iterate(engine->auth, ^bool(credential_t cred) {
os_log_debug(AUTHD_LOG, "%@", cred);
return true;
});
- os_log_debug(AUTHD_LOG, "engine: ********** Dumping session->credentials **********");
+ os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping session->credentials **********", engine->engine_index);
session_credentials_iterate(auth_token_get_session(engine->auth), ^bool(credential_t cred) {
os_log_debug(AUTHD_LOG, "%@", cred);
return true;
});
- os_log_debug(AUTHD_LOG, "engine: ********** Dumping engine->context **********");
+ os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping engine->context **********", engine->engine_index);
os_log_debug(AUTHD_LOG, "%@", engine->context);
- os_log_debug(AUTHD_LOG, "engine: ********** Dumping auth->context **********");
+ os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping auth->context **********", engine->engine_index);
os_log_debug(AUTHD_LOG, "%@", engine->auth);
- os_log_debug(AUTHD_LOG, "engine: ********** Dumping granted rights **********");
+ os_log_debug(AUTHD_LOG, "engine %lld: ********** Dumping granted rights **********", engine->engine_index);
os_log_debug(AUTHD_LOG, "%@", engine->grantedRights);
#endif
size_t len = strlen(right);
require(len != 0, done);
- require_action(right[len-1] != '.', done, os_log_error(AUTHD_LOG, "engine: not allowed to set wild card rules"));
+ require_action(right[len-1] != '.', done, os_log_error(AUTHD_LOG, "Not allowed to set wild card rules (engine %lld)", engine->engine_index));
if (strncasecmp(right, kConfigRight, strlen(kConfigRight)) == 0) {
// special handling of meta right change:
status = engine_authorize(engine, checkRight, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights);
done:
- os_log_debug(AUTHD_LOG, "engine: authorizing %{public}s for db modification: %d", right, (int)status);
+ os_log_debug(AUTHD_LOG, "engine %lld: authorizing %{public}s for db modification: %d", engine->engine_index, right, (int)status);
CFReleaseSafe(checkRight);
return status;
}
void
_engine_set_credential(engine_t engine, credential_t cred, bool shared)
{
- os_log_debug(AUTHD_LOG, "engine: adding %{public}scredential %{public}s (%i) to engine shared: %i", credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred), shared);
+ os_log_debug(AUTHD_LOG, "engine %lld: adding %{public}scredential %{public}s (%i) to engine shared: %i", engine->engine_index, credential_get_shared(cred) ? "shared " : "", credential_get_name(cred), credential_get_uid(cred), shared);
CFSetSetValue(engine->credentials, cred);
if (shared) {
credential_t sharedCred = credential_create_with_credential(cred, true);
engine->dismissed = true;
_cf_dictionary_iterate(engine->mechanism_agents, ^bool(CFTypeRef key __attribute__((__unused__)), CFTypeRef value) {
- os_log_debug(AUTHD_LOG, "engine: Destroying %{public}s", mechanism_get_string((mechanism_t)key));
+ os_log_debug(AUTHD_LOG, "engine %lld: Destroying %{public}s", engine->engine_index, mechanism_get_string((mechanism_t)key));
agent_t agent = (agent_t)value;
agent_destroy(agent);
process_t proc = connection_get_process(engine->conn);
if (!proc) {
- os_log_error(AUTHD_LOG, "engine: No client process");
+ os_log_error(AUTHD_LOG, "No client process (engine %lld)", engine->engine_index);
return retval;
}
uid_t client_uid = process_get_uid(proc);
if (!client_uid) {
- os_log_error(AUTHD_LOG, "engine: No client UID");
+ os_log_error(AUTHD_LOG, "No client UID (engine %lld)", engine->engine_index);
return retval;
}
if (data) {
CFDataRef externalized = CFDataCreate(kCFAllocatorDefault, data, dataLen);
if (externalized) {
- os_log_debug(AUTHD_LOG, "engine: Going to get LA context for UID %d", client_uid);
+ os_log_debug(AUTHD_LOG, "engine %lld: going to get LA context for UID %d", engine->engine_index, client_uid);
retval = LACreateNewContextWithACMContextInSession(client_uid, externalized, NULL);
CFRelease(externalized);
}
CFReleaseSafe(engine->la_context);
engine->la_context = engine_copy_context(engine, engine->hints);
if (engine->la_context) {
- os_log_debug(AUTHD_LOG, "engine: Sheet user UID %d", uid);
+ os_log_debug(AUTHD_LOG, "engine %lld: Sheet UID %d", engine->engine_index, uid);
return true;
} else {
// this is not real failure as no LA context in authorization context is very valid scenario
- os_log_debug(AUTHD_LOG, "engine: Failed to get LA context");
+ os_log_debug(AUTHD_LOG, "engine %lld: Failed to get LA context", engine->engine_index);
}
return false;
}
#include <Security/AuthorizationDB.h>
#include <Security/AuthorizationTagsPriv.h>
#include "server.h"
+#include <libproc.h>
AUTHD_DEFINE_LOG
rule_sql_commit(rule_t rule, authdb_connection_t dbconn, CFAbsoluteTime modified, process_t proc)
{
bool result = false;
+ __block bool insert = false;
// type and class required else rule is name only?
RuleClass rule_class = rule_get_class(rule);
require(rule_get_type(rule) != 0, done);
if (rule_get_id(rule)) {
update = _sql_update(rule, dbconn);
} else {
+ insert = true;
if (proc) {
const char * ident = process_get_identifier(proc);
if (ident) {
done:
if (!result) {
os_log_debug(AUTHD_LOG, "rule: commit, failed for %{public}s (%llu)", rule_get_name(rule), rule_get_id(rule));
+ } else {
+ rule_log_manipulation(dbconn, rule, insert ? rule_insert : rule_update, proc);
}
return result;
}
bool
-rule_sql_remove(rule_t rule, authdb_connection_t dbconn)
+rule_sql_remove(rule_t rule, authdb_connection_t dbconn, process_t proc)
{
bool result = false;
int64_t id = rule_get_id(rule);
^(sqlite3_stmt *stmt) {
sqlite3_bind_int64(stmt, 1, id);
}, NULL);
-done:
+
+ if (result) {
+ rule_log_manipulation(dbconn, rule, rule_delete, proc);
+ }
+
+done:
return result;
}
return rule->requirement;
}
+
+void
+rule_log_manipulation(authdb_connection_t dbconn, rule_t rule, RuleOperation operation, process_t source)
+{
+ authdb_step(dbconn, "INSERT INTO rules_history (rule, source, operation, version) VALUES (?,?,?,?)", ^(sqlite3_stmt *stmt) {
+ char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
+ if (source) {
+ pid_t pid = process_get_pid(source);
+ if (!proc_pidpath(pid, pathbuf, sizeof(pathbuf))) {
+ os_log_error(AUTHD_LOG, "Failed to get path for pid %d", pid);
+ snprintf(pathbuf, sizeof(pathbuf), "Unknown process with PID %d", pid);
+ }
+ } else {
+ strncpy(pathbuf, "authd", sizeof(pathbuf));
+ }
+
+ sqlite3_bind_text(stmt, 1, rule_get_name(rule), -1, NULL);
+ sqlite3_bind_text(stmt, 2, pathbuf, -1, NULL);
+ sqlite3_bind_int(stmt, 3, operation);
+ sqlite3_bind_int64(stmt, 4, rule_get_version(rule));
+ }, NULL);
+}
};
typedef uint32_t RuleFlags;
+typedef enum {
+ rule_insert,
+ rule_update,
+ rule_delete,
+} RuleOperation;
+
AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED
rule_t rule_create_default(void);
bool rule_sql_commit(rule_t,authdb_connection_t,CFAbsoluteTime,process_t);
AUTH_NONNULL_ALL
-bool rule_sql_remove(rule_t,authdb_connection_t);
+bool rule_sql_remove(rule_t,authdb_connection_t,process_t);
AUTH_NONNULL_ALL
CFMutableDictionaryRef rule_copy_to_cfobject(rule_t,authdb_connection_t);
AUTH_NONNULL_ALL
SecRequirementRef rule_get_requirement(rule_t);
+AUTH_NONNULL1 AUTH_NONNULL2
+void rule_log_manipulation(authdb_connection_t dbconn, rule_t rule, RuleOperation operation, process_t source);
+
#if defined(__cplusplus)
}
#endif
}
if (rule_get_id(rule) != 0) {
- rule_sql_remove(rule, dbconn);
+ rule_sql_remove(rule, dbconn, proc);
}
done:
dispatch_sync(session->dispatch_queue, ^{
CFIndex count = CFSetGetCount(session->credentials);
+ if (count > 128) { // <rdar://problem/38179345> Variable Length Arrays; AuthD
+ // session usually contains 0 or 1 credential
+ count = 128;
+ }
+
CFTypeRef values[count];
CFSetGetValues(session->credentials, values);
for (CFIndex i = 0; i < count; i++) {
INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks
-OTHER_LDFLAGS = -laks -lCrashReporterClient -Wl,-upward_framework,Foundation
+OTHER_LDFLAGS = -laks -lCrashReporterClient -Wl,-upward_framework,Foundation -Wl,-no_inits
SECTORDER_FLAGS = -order_file_statistics
APPLY_RULES_IN_COPY_FILES = NO
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)
+
+IS_ZIPPERED = YES
"system.preferences" = "Touch ID to Modify Your System Settings.";
-"com.apple.SoftwareUpdate.modify-settings" = "Touch ID to Unlock the App Store preferences.";
+"com.apple.SoftwareUpdate.modify-settings" = "Touch ID to Unlock the Software Update preferences.";
"com.apple.uninstalld.uninstall" = "Touch ID to Delete an Application.";
"com.apple.server.admin.streaming" = "Touch ID to Modify the QuickTime Streaming Server Settings.";
-"system.preferences.softwareupdate" = "Touch ID to Unlock the App Store preferences.";
+"system.preferences.softwareupdate" = "Touch ID to Unlock the Software Update preferences.";
"system.keychain.modify" = "Touch ID to Modify the System Keychain.";
"com.apple.security.sudo" = "Touch ID to Execute a command as administrator.";
+"com.apple.configurationprofiles.userprofile.trustcert" = "Touch ID to Trust a Certificate from a User Configuration Profile.";
+
+"com.apple.app-sandbox.create-symlink" = "Touch ID to Install a Symlink into /usr/local/bin.";
+
+"com.apple.app-sandbox.set-attributes" = "Touch ID to Change the Permissions of a Privileged File.";
+
+"com.apple.app-sandbox.replace-file" = "Touch ID to Save a File in a Privileged Location.";
"system.preferences" = "__APPNAME__ is trying to modify your system settings.";
-"com.apple.SoftwareUpdate.modify-settings" = "__APPNAME__ is trying to unlock the App Store preferences.";
+"com.apple.SoftwareUpdate.modify-settings" = "__APPNAME__ is trying to unlock the Software Update preferences.";
"com.apple.uninstalld.uninstall" = "__APPNAME__ is trying to delete an application.";
"com.apple.server.admin.streaming" = "__APPNAME__ is trying to modify the QuickTime Streaming Server settings.";
-"system.preferences.softwareupdate" = "__APPNAME__ is trying to unlock the App Store preferences.";
+"system.preferences.softwareupdate" = "__APPNAME__ is trying to unlock the Software Update preferences.";
"system.keychain.modify" = "__APPNAME__ is trying to modify the system keychain.";
"com.apple.security.sudo" = "__APPNAME__ is trying to execute a command as administrator.";
"com.apple.configurationprofiles.userprofile.trustcert" = "__APPNAME__ is trying to trust a certificate from a user configuration profile.";
+
+"com.apple.app-sandbox.create-symlink" = "__APPNAME__ wants to install a symlink into /usr/local/bin.";
+
+"com.apple.app-sandbox.set-attributes" = "__APPNAME__ wants to change permissions of a privileged file.";
+
+"com.apple.app-sandbox.replace-file" = "__APPNAME__ wants to save a file in a privileged location.";
(allow mach-lookup (global-name "com.apple.CoreAuthentication.agent.libxpc"))
;; allow clients to communicate with ctkd
(allow mach-lookup (global-name "com.apple.ctkd.token-client"))
+
+;; On internal builds, allow clients to read the AMFITrustedKeys NVRAM variable
+(with-filter (system-attribute apple-internal)
+ (allow nvram-get (nvram-variable "AMFITrustedKeys")))
return CSSMERR_CSP_INTERNAL_ERROR;
}
int numBytes = BN_num_bytes(bn);
- unsigned char buf[numBytes];
+ unsigned char *buf = (unsigned char*)malloc(numBytes);
+ if (buf == NULL) {
+ dprintf("appendBigNum: Cannot allocate a temp BN buffer\n");
+ return CSSMERR_CSSM_MEMORY_ERROR;
+ }
int moved = BN_bn2bin(bn, buf);
if(moved != numBytes) {
dprintf("appendBigNum: BN_bn2bin() screwup\n");
+ free(buf);
return CSSMERR_CSP_INTERNAL_ERROR;
}
bool appendZero = false;
}
CFDataAppendBytes(cfOut, buf, numBytes);
memset(buf, 0, numBytes);
+ free(buf);
return CSSM_OK;
}
/* encrypt it */
ptextLen = CFDataGetLength(ptext);
- unsigned char ctext[ptextLen];
+ unsigned char *ctext = (unsigned char*)malloc(ptextLen);
+ if(ctext == NULL) {
+ ourRtn = CSSMERR_CSSM_MEMORY_ERROR;
+ goto errOut;
+ }
+
unsigned ctextLen;
ourRtn = ssh1DES3Crypt(cipherSpec, true,
(unsigned char *)CFDataGetBytePtr(ptext), (unsigned)ptextLen,
CFReleaseNull(cfOut);
cleanup:
/* it would be proper to zero out ptext here, but we can't do that to a CFData */
+ free(ctext);
CFRelease(ptext);
return ourRtn;
}
static const uint8 OID_PIV_AUTH_2048[] = {PIV_AUTH_2048_OID};
const CSSM_OID CSSMOID_PIV_AUTH_2048 = {PIV_AUTH_2048_OID_LEN, (uint8 *)OID_PIV_AUTH_2048};
-static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
- const CSSM_DATA *fieldOpts, // optional Common Name
- const iSignCertInfo *certInfo);
/*
* Setup a single iSignExtenInfo. Called once per known extension
* per cert.
if (!isCertInfo->basicConstraints.present)
{
- tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate");
+ tpPolicyError("tp_verifyMacAppStoreReceiptOpts: no basicConstraints in intermediate");
if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS))
return CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS;
}
return false;
}
-
-/*
- * Verify Apple ID Sharing options.
- *
- * -- Do basic cert validation (OCSP-based certs)
- * -- Validate that the cert is an Apple ID sharing cert:
- * has a custom extension: OID: Apple ID Sharing Certificate ( 1 2 840 113635 100 4 7 )
- * (CSSMOID_APPLE_EXTENSION_APPLEID_SHARING)
- * EKU should have both client and server authentication
- * chains to the "Apple Application Integration Certification Authority" intermediate
- * -- optionally has a client-specified common name, which is the Apple ID account's UUID.
-
- * -- Must have one intermediate cert ("Apple Application Integration Certification Authority")
- * -- intermediate must have basic constraints with path length 0
- * -- intermediate has CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE extension (OID 1 2 840 113635 100 6 2 3)
- OR APPLE_EXTENSION_AAI_INTERMEDIATE_2
- */
-
-static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
- const CSSM_DATA *fieldOpts, // optional Common Name
- const iSignCertInfo *certInfo) // all certs, size certGroup.numCerts()
-{
- unsigned numCerts = certGroup.numCerts();
- const iSignCertInfo *isCertInfo;
- TPCertInfo *tpCert;
- // const CE_BasicConstraints *bc; // currently unused
- CE_ExtendedKeyUsage *eku;
- CSSM_RETURN crtn = CSSM_OK;
- unsigned int serverNameLen = 0;
- const char *serverName = NULL;
-
- // The CSSM_APPLE_TP_SMIME_OPTIONS pointer is optional as is everything in it.
- if (fieldOpts && fieldOpts->Data)
- {
- CSSM_APPLE_TP_SSL_OPTIONS *sslOpts = (CSSM_APPLE_TP_SSL_OPTIONS *)fieldOpts->Data;
- switch (sslOpts->Version)
- {
- case CSSM_APPLE_TP_SSL_OPTS_VERSION:
- if (fieldOpts->Length != sizeof(CSSM_APPLE_TP_SSL_OPTIONS))
- return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
- break;
- /* handle backwards compatibility here if necessary */
- default:
- return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
- }
- serverNameLen = sslOpts->ServerNameLen;
- serverName = sslOpts->ServerName;
- }
-
- //------------------------------------------------------------------------
-
- if (numCerts != 3)
- {
- if (!certGroup.isAllowedError(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH))
- {
- tpPolicyError("tp_verifyAppleIDSharingOpts: numCerts %u", numCerts);
- return CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
- }
- else
- if (numCerts < 3)
- {
- /* this error allowed, but no intermediate...check leaf */
- goto checkLeaf;
- }
- }
-
- /* verify intermediate cert */
- isCertInfo = &certInfo[1];
- tpCert = certGroup.certAtIndex(1);
-
- if (!isCertInfo->basicConstraints.present)
- {
- tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate");
- if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS))
- return CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS;
- }
-
-checkLeaf:
-
- /* verify leaf cert */
- isCertInfo = &certInfo[0];
- tpCert = certGroup.certAtIndex(0);
-
- /* host name check is optional */
- if (serverNameLen != 0)
- {
- if (serverName == NULL)
- return CSSMERR_TP_INVALID_POINTER;
-
- /* convert caller's hostname string to lower case */
- char *hostName = (char *)certGroup.alloc().malloc(serverNameLen);
- memmove(hostName, serverName, serverNameLen);
- tpToLower(hostName, serverNameLen);
-
- /* Check common name... */
-
- bool fieldFound;
- CSSM_BOOL match = tpCompareSubjectName(*tpCert, SN_CommonName, false, hostName,
- serverNameLen, fieldFound);
-
- certGroup.alloc().free(hostName);
- if (!match && tpCert->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH))
- return CSSMERR_APPLETP_HOSTNAME_MISMATCH;
- }
-
- if (certInfo->certificatePolicies.present)
- {
- const CE_CertPolicies *certPolicies =
- &isCertInfo->certificatePolicies.extnData->certPolicies;
- if (!certificatePoliciesContainsOID(certPolicies, &CSSMOID_APPLEID_SHARING_CERT_POLICY))
- if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
- return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
- }
- else
- if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
- return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
-
- if (!isCertInfo->extendKeyUsage.present)
- {
- tpPolicyError("tp_verifyAppleIDSharingOpts: no extendedKeyUse in leaf");
- if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE))
- return crtn ? crtn : CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE;
-
- /* have to skip remainder */
- return CSSM_OK;
- }
-
- // Check that certificate can do Client and Server Authentication (EKU)
- eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
- assert(eku != NULL);
- if(eku->numPurposes != 2)
- {
- tpPolicyError("tp_verifyAppleIDSharingOpts: bad eku->numPurposes (%lu)",
- (unsigned long)eku->numPurposes);
- if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE))
- {
- if (crtn == CSSM_OK)
- crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
- }
- return crtn;
- }
- bool canDoClientAuth = false, canDoServerAuth = false, ekuError = false;
- for (int ix=0;ix<2;ix++)
- {
- if (tpCompareOids(&eku->purposes[ix], &CSSMOID_ClientAuth))
- canDoClientAuth = true;
- else
- if (tpCompareOids(&eku->purposes[ix], &CSSMOID_ServerAuth))
- canDoServerAuth = true;
- else
- {
- ekuError = true;
- break;
- }
- }
-
- if (!(canDoClientAuth && canDoServerAuth))
- ekuError = true;
- if (ekuError)
- {
- tpPolicyError("tp_verifyAppleIDSharingOpts: bad EKU in leaf");
- if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE))
- {
- if (crtn == CSSM_OK)
- crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
- }
- }
-
- return crtn;
-}
-
/*
* Verify Time Stamping (RFC3161) policy options.
*
policyError = tp_verifyMacAppStoreReceiptOpts(*certGroup, policyFieldData, certInfo);
break;
case kTP_AppleIDSharing:
- policyError = tp_verifyAppleIDSharingOpts(*certGroup, policyFieldData, certInfo);
- break;
+ /* As of macOS 10.12, this code path should be unused. Until we can remove this
+ * module entirely, ensure that no Apple ID evaluations take this path. [10119995] */
+ tpPolicyError("tp_policyVerify: unexpected attempt to use legacy kTP_AppleIDSharing");
+ policyFail = CSSM_TRUE;
+ abort();
case kTP_TimeStamping:
policyError = tp_verifyTimeStampingOpts(*certGroup, policyFieldData, certInfo);
break;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
-/* @@@ We need something that tells us which platform we are building
- for that let's us distinguish if we are doing an emulator build. */
+#if !TARGET_OS_OSX
typedef struct {
size_t Length;
extern const SecAsn1Template kSecAsn1CertExtensionTemplate[];
extern const SecAsn1Template kSecAsn1SequenceOfCertExtensionTemplate[];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
/*
* X.509 certificate object (the unsigned form)
*
extern const SecAsn1Template kSecAsn1SignedCertOrCRLTemplate[];
+#pragma clang diagnostic pop
+
#ifdef __cplusplus
}
#endif
extern "C" {
#endif
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
// MARK: ----- OCSP Request -----
/*
extern const SecAsn1Template kSecAsn1OCSPDReplyTemplate[];
extern const SecAsn1Template kSecAsn1OCSPDRepliesTemplate[];
+#pragma clang diagnostic pop
+
#ifdef __cplusplus
}
#endif
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, __IPHONE_NA);
/*
Available only on systems with callback version 2 or higher
Caller is responsible for outValue release */
OSStatus (*GetTokenIdentities)(AuthorizationEngineRef inEngine,
CFTypeRef context,
- CFArrayRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __PHONE_NA);
+ CFArrayRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_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);
+ CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_NA);
} AuthorizationCallbacks;
// make data to be encrypted
unsigned bytesInKey = encryptingKey->KeyHeader.LogicalKeySizeInBits / 8;
- u_int8_t buffer[bytesInKey];
+ u_int8_t *buffer = (u_int8_t*)malloc(bytesInKey);
+ if (buffer == NULL) {
+ CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+ }
+
unsigned i;
for (i = 0; i < bytesInKey; ++i)
CSSM_RETURN result = CSSM_CSP_CreateAsymmetricContext(moduleHandle, encryptingKey->KeyHeader.AlgorithmId, &nullCreds, encryptingKey, CSSM_PADDING_NONE, &encryptHandle);
if (result != CSSM_OK)
{
+ free(buffer);
CssmError::throwMe(result);
}
result = CSSM_QuerySize(encryptHandle, CSSM_TRUE, 1, &qsData);
if (result == CSSMERR_CSP_INVALID_ALGORITHM)
{
+ free(buffer);
return;
}
result = CSSM_EncryptData(encryptHandle, &clearBuf, 1, &cipherBuf, 1, &bytesEncrypted, &remData);
if (result != CSSM_OK)
{
+ free(buffer);
CssmError::throwMe(result);
}
if (result != CSSM_OK)
{
+ free(buffer);
CssmError::throwMe(result);
}
result = CSSM_DecryptData(decryptHandle, &cipherBuf, 1, &decryptedBuf, 1, &bytesEncrypted, &remData);
if (result != CSSM_OK)
{
+ free(buffer);
CssmError::throwMe(result);
}
{
free(remData.Data);
}
+
+ free(buffer);
}
void CSPFullPluginSession::ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
namespace Security {
-
-//
-// The null credential constant.
-//
-static const CSSM_ACCESS_CREDENTIALS null_credentials = { "" }; // and more nulls
-#if BUG_GCC
-const AccessCredentials &AccessCredentials::null =
- *static_cast<const AccessCredentials *>(&null_credentials);
-#else
-const AccessCredentials &AccessCredentials::null =
- static_cast<const AccessCredentials &>(null_credentials);
-#endif
-
-
//
// Scan a SampleGroup for samples with a given CSSM_SAMPLE_TYPE.
// Collect all matching samples into a list (which is cleared to begin with).
//
// AccessCredentials
//
+const AccessCredentials& AccessCredentials::null_credential()
+{
+ static const CSSM_ACCESS_CREDENTIALS null_credentials = { "" }; // and more nulls
+ return AccessCredentials::overlay(null_credentials);
+}
+
void AccessCredentials::tag(const char *tagString)
{
if (tagString == NULL)
bool authorizesUI() const;
public:
- static const AccessCredentials &null; // all null credential
+ static const AccessCredentials& null_credential();
// turn NULL into a null credential if needed
static const AccessCredentials *needed(const CSSM_ACCESS_CREDENTIALS *cred)
- { return cred ? overlay(cred) : &null; }
+ { return cred ? overlay(cred) : &null_credential(); }
};
// These are the kinds of ACL subjects we can deal with.
//
ModuleNexus<ObjectAcl::MakerMap> ObjectAcl::makers;
-NormalMutex ObjectAcl::makersMutex;
+ModuleNexus<NormalMutex> ObjectAcl::makersMutex;
//
AclSubject::Maker::Maker(CSSM_ACL_SUBJECT_TYPE type)
: mType(type)
{
- StLock<Mutex> _(ObjectAcl::makersMutex);
+ StLock<Mutex> _(ObjectAcl::makersMutex());
ObjectAcl::makers()[type] = this;
}
AclSubject::Maker &ObjectAcl::makerFor(CSSM_ACL_SUBJECT_TYPE type)
{
- StLock<Mutex> _(ObjectAcl::makersMutex);
+ StLock<Mutex> _(ObjectAcl::makersMutex());
AclSubject::Maker *maker = makers()[type];
if (maker == NULL)
CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED);
private:
typedef map<CSSM_ACL_SUBJECT_TYPE, AclSubject::Maker *> MakerMap;
static ModuleNexus<MakerMap> makers; // registered subject Makers
- static NormalMutex makersMutex;
+ static ModuleNexus<NormalMutex> makersMutex;
static AclSubject::Maker &makerFor(CSSM_ACL_SUBJECT_TYPE type);
};
{
secinfo("codesign", "calculating legacy hash for %s", code->canonicalPath().c_str());
UnixPlusPlus::AutoFileDesc fd(code->executablePath(), O_RDONLY);
- char buffer[legacyHashLimit];
- size_t size = fd.read(buffer, legacyHashLimit);
+ char buffer[LEGACY_HASH_LIMIT];
+ size_t size = fd.read(buffer, LEGACY_HASH_LIMIT);
SHA1 hash;
hash(buffer, size);
hash.finish(digest);
#include <string>
#include <map>
+#define LEGACY_HASH_LIMIT 16*1024
+
namespace Security {
//
class OSXVerifier {
public:
- static const size_t legacyHashLimit = 16 * 1024;
+ static const size_t legacyHashLimit = LEGACY_HASH_LIMIT;
static const uint32_t commentAlignment = 4;
public:
CSSM_CC_HANDLE ccHand;
CSSM_DATA keyLabelData;
- keyLabelData.Data = (uint8 *)keyLabel,
+ keyLabelData.Data = (uint8 *)keyLabel;
keyLabelData.Length = keyLabelLen;
memset(pubKey, 0, sizeof(CSSM_KEY));
memset(privKey, 0, sizeof(CSSM_KEY));
(SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci);
/* dig down one more layer for eContentType */
ci = SecCmsSignedDataGetContentInfo(cmsDecoder->signedData);
- cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci);
+ if (ci) {
+ cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci);
+ }
break;
default:
break;
}
return status;
}
+
+/*
+ * Obtain the expiration time of signer 'signerIndex' of a CMS message, if
+ * present. This is part of the signed attributes of the message.
+ *
+ * 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 CMSDecoderCopySignerAppleExpirationTime(
+ CMSDecoderRef cmsDecoder,
+ size_t signerIndex,
+ CFAbsoluteTime *expirationTime) /* RETURNED */
+{
+ OSStatus status = errSecParam;
+ SecCmsMessageRef cmsg = NULL;
+ int numContentInfos = 0;
+ SecCmsSignedDataRef signedData = NULL;
+
+ require(cmsDecoder && expirationTime, xit);
+ require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
+ 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 = SecCmsSignerInfoGetAppleExpirationTime(signerInfo, expirationTime);
+ break;
+ }
+ }
+ }
+ }
+xit:
+ return status;
+}
CFAbsoluteTime *signingTime) /* RETURNED */
__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA);
+#define TIMESTAMPING_SUPPORTED 1
+#if TIMESTAMPING_SUPPORTED
/*
* Obtain the timestamp of signer 'signerIndex' of a CMS message, if
* present. This timestamp is an authenticated timestamp provided by
size_t signerIndex, /* usually 0 */
CFArrayRef * __nonnull CF_RETURNS_RETAINED certificateRefs) /* RETURNED */
__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA);
+#endif // TIMESTAMPING_SUPPORTED
CF_ASSUME_NONNULL_END
CMSCertificateChainMode chainMode;
CFDataRef hashAgilityAttrValue;
CFDictionaryRef hashAgilityV2AttrValues;
+ CFAbsoluteTime expirationTime;
};
static void cmsEncoderInit(CFTypeRef enc);
// CFStringRef: OID representation is a dotted-decimal string
CFStringRef inStr = (CFStringRef)inRef;
CFIndex max = CFStringGetLength(inStr) * 3;
- char buf[max];
- if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII))
+ char *buf = (char *)malloc(max);
+ if (!buf) {
+ return errSecMemoryError;
+ }
+ if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII)) {
+ free(buf);
return errSecParam;
+ }
- if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0)
+ if (encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) {
+ free(buf);
return errSecParam;
+ }
+ free(buf);
}
else if (CFGetTypeID(inRef) == CFDataGetTypeID()) {
// CFDataRef: OID representation is in binary DER format
break;
}
}
+ if (cmsEncoder->signedAttributes & kCMSAttrAppleExpirationTime) {
+ ortn = SecCmsSignerInfoAddAppleExpirationTime(signerInfo, cmsEncoder->expirationTime);
+ if(ortn) {
+ ortn = cmsRtnToOSStatus(ortn);
+ CSSM_PERROR("SecCmsSignerInfoAddAppleExpirationTime", ortn);
+ break;
+ }
+ }
ortn = SecCmsSignedDataAddSignerInfo(signedData, signerInfo);
if(ortn) {
return errSecSuccess;
}
+/*
+ * Set the expiration time for a CMSEncoder.
+ * This is only used if the kCMSAttrAppleExpirationTime attribute is included.
+ */
+OSStatus CMSEncoderSetAppleExpirationTime(
+ CMSEncoderRef cmsEncoder,
+ CFAbsoluteTime time)
+{
+ if(cmsEncoder == NULL) {
+ return errSecParam;
+ }
+ if(cmsEncoder->encState != ES_Init) {
+ return errSecParam;
+ }
+ cmsEncoder->expirationTime = time;
+ return errSecSuccess;
+}
+
OSStatus CMSEncoderSetCertificateChainMode(
CMSEncoderRef cmsEncoder,
CMSCertificateChainMode chainMode)
#include <CoreFoundation/CoreFoundation.h>
#include <Security/cssmtype.h>
#include <stdint.h>
+#include <Availability.h>
#ifdef __cplusplus
extern "C" {
OSStatus CMSEncoderSetEncapsulatedContentType(
CMSEncoderRef cmsEncoder,
const CSSM_OID *eContentType)
- /* DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; */
- __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
+ API_DEPRECATED_WITH_REPLACEMENT("CMSEncoderSetEncapsulatedContentTypeOID", macos(10.5, 10.7)) API_UNAVAILABLE(ios);
/*
* Optionally specify an eContentType OID for the inner EncapsulatedData for
*/
kCMSAttrAppleCodesigningHashAgility = 0x0010,
kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020,
+ /*
+ * Include the expiration time.
+ */
+ kCMSAttrAppleExpirationTime = 0x0040,
};
/*
const void * content,
size_t contentLen,
CFDataRef * __nonnull CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */
- /* DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; */
- __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
+ API_DEPRECATED_WITH_REPLACEMENT("CMSEncodeContent", macos(10.5, 10.7)) API_UNAVAILABLE(ios);
/*
CMSEncoderRef cmsEncoder,
CFDictionaryRef hashAgilityV2AttrValues);
+/*
+ * Set the expiration time for a CMSEncoder.
+ * This is only used if the kCMSAttrAppleExpirationTime attribute is included.
+ */
+OSStatus CMSEncoderSetAppleExpirationTime(
+ CMSEncoderRef cmsEncoder,
+ CFAbsoluteTime time);
+
void
CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext);
CMSDecoderRef cmsDecoder,
size_t signerIndex, /* usually 0 */
CFDictionaryRef CF_RETURNS_RETAINED * hashAgilityAttrValues); /* RETURNED */
+
+/*
+ * Obtain the expiration time of signer 'signerIndex' of a CMS message, if
+ * present. This is part of the signed attributes of the message.
+ *
+ * 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 CMSDecoderCopySignerAppleExpirationTime(
+ CMSDecoderRef cmsDecoder,
+ size_t signerIndex,
+ CFAbsoluteTime *expirationTime); /* RETURNED */
#ifdef __cplusplus
}
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.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 */
/* Begin PBXFileReference section */
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 = "<group>"; };
D4C334571BE29F5200D8C1EF /* cms_regressions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cms_regressions.h; path = regressions/cms_regressions.h; sourceTree = "<group>"; };
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.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "cms-hashagility-test.m"; path = "regressions/cms-hashagility-test.m"; sourceTree = "<group>"; };
- 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 = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
D4C334571BE29F5200D8C1EF /* cms_regressions.h */,
D43B9E7C1D064F0B00B9DDDA /* cms-trust-settings-test.c */,
D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */,
- D4C334611BE2A31200D8C1EF /* cms-hashagility-test.m */,
- D4C334621BE2A31200D8C1EF /* cms-hashagility-test.h */,
);
name = regressions;
sourceTree = "<group>";
buildActionMask = 2147483647;
files = (
D43B9E7F1D064F0B00B9DDDA /* cms-trust-settings-test.h in Headers */,
- D4C334641BE2A31200D8C1EF /* cms-hashagility-test.h in Headers */,
D4C334601BE2A2B900D8C1EF /* cms_regressions.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
4CA1FEAB052A3C3800F22E42 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0810;
+ LastUpgradeCheck = 1000;
TargetAttributes = {
D4C3345B1BE2A2B100D8C1EF = {
CreatedOnToolsVersion = 7.1;
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- D4C334631BE2A31200D8C1EF /* cms-hashagility-test.m in Sources */,
D43B9E7E1D064F0B00B9DDDA /* cms-trust-settings-test.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
isa = XCBuildConfiguration;
baseConfigurationReference = 18446178146E984400B12992 /* debug.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = Debug;
isa = XCBuildConfiguration;
baseConfigurationReference = 1844617A146E984400B12992 /* release.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = Release;
baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPRESSION = lossless;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = 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;
baseConfigurationReference = 18446179146E984400B12992 /* lib.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPRESSION = "respect-asset-catalog";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = 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;
+++ /dev/null
-/*
- * 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@
- */
-
-#ifndef cms_hashagility_test_h
-#define cms_hashagility_test_h
-
-#include <stdio.h>
-#include <stdint.h>
-
-int cms_hash_agility_test(int argc, char *const *argv);
-
-/*
- * password: "password"
- * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08
- * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
- * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
- */
-unsigned char signing_identity_p12[4477] = {
- 0x30, 0x82, 0x11, 0x79, 0x02, 0x01, 0x03, 0x30, 0x82, 0x11, 0x3f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x07, 0x01, 0xa0, 0x82, 0x11, 0x30, 0x04, 0x82, 0x11, 0x2c, 0x30, 0x82, 0x11, 0x28, 0x30, 0x82, 0x07, 0x57, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x07, 0x48, 0x30, 0x82, 0x07, 0x44, 0x02, 0x01, 0x00,
- 0x30, 0x82, 0x07, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xed, 0xd8, 0x65, 0x57, 0xbb, 0xca, 0x25,
- 0x46, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x07, 0x10, 0xc0, 0x1d, 0x0d, 0x5c, 0x7f, 0x3b, 0xbe, 0x20, 0xd4, 0x9a, 0x0d,
- 0xaf, 0xb6, 0x4b, 0xc7, 0x7f, 0xa8, 0xa8, 0x3f, 0x6c, 0x96, 0x1c, 0xea, 0x90, 0xd2, 0x79, 0x9f, 0x56, 0x3a, 0x5a, 0x29,
- 0x93, 0xff, 0x72, 0x39, 0x9e, 0x41, 0xd9, 0x5a, 0xfc, 0xb5, 0x54, 0x2d, 0x89, 0x60, 0x18, 0xf2, 0xea, 0x8c, 0xeb, 0x7f,
- 0xba, 0x87, 0xc6, 0x70, 0x42, 0x25, 0x55, 0x24, 0xc5, 0x4f, 0x26, 0x66, 0x8d, 0x78, 0x44, 0x47, 0x85, 0x36, 0x53, 0x86,
- 0xc9, 0x18, 0x83, 0x33, 0x4b, 0x4b, 0x08, 0x2d, 0x7b, 0x68, 0x37, 0x29, 0x4c, 0x20, 0x74, 0xd4, 0x4f, 0xbb, 0x6e, 0x97,
- 0x7a, 0xf4, 0xbf, 0xcb, 0x40, 0x26, 0x2d, 0xac, 0x95, 0x82, 0xe0, 0x88, 0xfe, 0x54, 0x80, 0xe9, 0xf5, 0xda, 0x8e, 0x6e,
- 0x3a, 0x47, 0x2d, 0xc8, 0xd4, 0xe7, 0x2e, 0xff, 0xec, 0xfa, 0xa5, 0x70, 0xcd, 0x2e, 0x99, 0x26, 0x32, 0xc8, 0x1d, 0x53,
- 0x60, 0x1e, 0x6f, 0x68, 0xcb, 0x49, 0xd0, 0xa2, 0xf8, 0x47, 0x70, 0x1b, 0x9e, 0x85, 0xbe, 0x4e, 0x56, 0xb5, 0x8b, 0x66,
- 0x45, 0x57, 0xe3, 0xbd, 0x57, 0xed, 0x94, 0x53, 0xf6, 0x72, 0xd7, 0xb7, 0xc6, 0x9f, 0x05, 0xf5, 0x98, 0xb4, 0x13, 0x35,
- 0x69, 0x24, 0x94, 0xd9, 0x3d, 0x80, 0xbc, 0xa8, 0xea, 0x78, 0x0c, 0xe0, 0xa2, 0xfe, 0x1b, 0xd2, 0x82, 0x3d, 0x83, 0x34,
- 0x76, 0xb4, 0x45, 0xf8, 0x14, 0x09, 0x66, 0x02, 0x68, 0xc3, 0x1b, 0xcb, 0x6c, 0x91, 0x6b, 0x3e, 0xdc, 0x35, 0x68, 0xab,
- 0x49, 0x47, 0x6c, 0x60, 0xea, 0xe3, 0xd5, 0x59, 0x82, 0x9c, 0x18, 0xb0, 0x6d, 0x45, 0xc0, 0x2f, 0x58, 0xf1, 0x44, 0x79,
- 0xe3, 0xd2, 0xd6, 0x16, 0xbc, 0xde, 0x17, 0xae, 0xf7, 0xea, 0x3c, 0xe4, 0xb4, 0x7b, 0xdf, 0xba, 0x9b, 0xf1, 0xb8, 0xa8,
- 0xb0, 0x51, 0xeb, 0xe8, 0xc3, 0xe9, 0x9c, 0x1b, 0x06, 0xdd, 0x89, 0x07, 0x98, 0xf8, 0x01, 0x7f, 0xde, 0x7e, 0x05, 0xa6,
- 0x72, 0x0b, 0x3f, 0xf4, 0x7d, 0xca, 0x74, 0x7b, 0xc9, 0x87, 0x0d, 0x35, 0x8b, 0x05, 0x3a, 0x73, 0x04, 0x08, 0x7a, 0x51,
- 0x34, 0x29, 0x5b, 0xd8, 0x90, 0x0f, 0xa7, 0xf0, 0x48, 0xfc, 0x9c, 0x74, 0xca, 0xe9, 0x34, 0x75, 0x1c, 0xd1, 0xa6, 0xd1,
- 0xfb, 0x9f, 0xc7, 0x82, 0x40, 0x75, 0x87, 0xdd, 0xa2, 0x22, 0xeb, 0x91, 0xd7, 0x85, 0x1a, 0x2c, 0xa7, 0x3d, 0xd5, 0xe4,
- 0xca, 0x85, 0x00, 0x33, 0x11, 0x6d, 0x62, 0xa8, 0xb7, 0xd3, 0x45, 0x46, 0xdc, 0xb4, 0xa3, 0xeb, 0xae, 0x5e, 0x8c, 0xc2,
- 0x7a, 0x0b, 0x83, 0x98, 0x5a, 0x94, 0x0f, 0x68, 0x61, 0x36, 0x57, 0x6e, 0x94, 0xe0, 0x6d, 0x93, 0x76, 0xa0, 0x5d, 0x3f,
- 0x25, 0x8b, 0x3b, 0x46, 0x1e, 0x0c, 0x15, 0x6b, 0x9f, 0x1d, 0xc3, 0x5f, 0x61, 0x42, 0xd5, 0xf8, 0x79, 0xcd, 0xd1, 0x0a,
- 0x96, 0xce, 0x49, 0x8a, 0xff, 0x54, 0x46, 0x77, 0x65, 0x37, 0x70, 0xcd, 0x65, 0x6f, 0x3d, 0x49, 0xc1, 0x29, 0x8d, 0x16,
- 0xbd, 0x36, 0x47, 0x54, 0xa5, 0x4d, 0x06, 0xfb, 0x33, 0x00, 0x29, 0xd8, 0x31, 0x09, 0x58, 0x12, 0x4c, 0xfe, 0xef, 0x8e,
- 0xf9, 0x1e, 0x30, 0xf7, 0x05, 0xb2, 0xd8, 0xd4, 0x7d, 0xae, 0xab, 0x57, 0xb7, 0x46, 0x09, 0xff, 0xca, 0xc7, 0x7b, 0xca,
- 0x73, 0xfa, 0xf9, 0x50, 0xa0, 0xb8, 0x09, 0xc2, 0x80, 0x43, 0x0d, 0x99, 0x7f, 0x4e, 0xdf, 0xd5, 0x6c, 0xc4, 0x42, 0x1a,
- 0x05, 0xbd, 0x65, 0xf4, 0x57, 0x2a, 0xe5, 0xc4, 0xcb, 0x79, 0x3f, 0x8f, 0x74, 0x93, 0x66, 0x8d, 0x93, 0xda, 0xba, 0x23,
- 0x77, 0x3f, 0xad, 0xd3, 0x8b, 0xae, 0xf5, 0xf1, 0x5c, 0xc1, 0xd2, 0x00, 0x3a, 0x60, 0x8e, 0xc3, 0x32, 0xd6, 0x8e, 0xce,
- 0x95, 0x24, 0x03, 0x79, 0x03, 0xf2, 0xb8, 0x2a, 0x94, 0xeb, 0x15, 0x97, 0xdc, 0x18, 0x8d, 0xc7, 0xd9, 0xc2, 0x63, 0x69,
- 0xfb, 0xf9, 0x8f, 0x05, 0xd3, 0x7c, 0x60, 0x5a, 0x57, 0xe4, 0xa5, 0xc1, 0xdf, 0x1d, 0x11, 0x84, 0x69, 0xba, 0x20, 0xd8,
- 0x79, 0xc3, 0x34, 0x3a, 0xb1, 0x63, 0x4c, 0xd2, 0x91, 0x2d, 0x87, 0x1e, 0xec, 0x06, 0xea, 0x35, 0x97, 0x0e, 0x59, 0x54,
- 0x83, 0x50, 0x3e, 0xac, 0xf2, 0xea, 0x6c, 0x0c, 0xa0, 0x57, 0xfb, 0xe8, 0x6b, 0xf9, 0xd1, 0x25, 0xc0, 0xa2, 0xb0, 0xa2,
- 0xcd, 0xde, 0x2b, 0xa7, 0xb3, 0x40, 0x75, 0x36, 0xf7, 0x20, 0xbe, 0xd7, 0xd1, 0x2e, 0x66, 0xc5, 0x3c, 0xf8, 0x6e, 0xce,
- 0xcb, 0x76, 0x7f, 0x1d, 0x32, 0x3b, 0x14, 0x27, 0x9c, 0x9e, 0xa3, 0xeb, 0x0c, 0x2f, 0x71, 0xba, 0x0d, 0xca, 0x27, 0x90,
- 0x42, 0xfd, 0xd4, 0x34, 0xb9, 0x96, 0xae, 0xcb, 0xd8, 0xfe, 0x31, 0x62, 0xe8, 0x4c, 0x07, 0x71, 0xb9, 0x0c, 0x9f, 0xe2,
- 0x8e, 0x66, 0xc2, 0x39, 0xc5, 0xc3, 0x1c, 0xfd, 0x5e, 0x18, 0x0b, 0xd4, 0x93, 0x3d, 0x98, 0x33, 0xaf, 0x6d, 0xb4, 0x6f,
- 0xe6, 0x75, 0x67, 0x62, 0xe7, 0x42, 0xee, 0xc6, 0xf2, 0x2e, 0x21, 0xa9, 0x75, 0xde, 0x0a, 0x8c, 0x39, 0xb7, 0x4b, 0x54,
- 0x01, 0xa7, 0xeb, 0x5a, 0x88, 0x79, 0xa8, 0xb3, 0x3f, 0x31, 0x8c, 0x47, 0x08, 0x94, 0x47, 0x52, 0xcf, 0x3c, 0xac, 0xd9,
- 0x32, 0x57, 0x4a, 0x18, 0x55, 0x5b, 0x66, 0xdc, 0x89, 0xd2, 0xc6, 0xa1, 0x11, 0x40, 0x19, 0x9c, 0x46, 0x88, 0x21, 0x77,
- 0xc1, 0x7f, 0x09, 0xc7, 0xfb, 0x52, 0x92, 0xec, 0x1a, 0xe0, 0xdd, 0x76, 0xb9, 0xfd, 0xa7, 0x8f, 0x61, 0xe3, 0xf0, 0x1b,
- 0x4e, 0xdb, 0xa0, 0xde, 0x90, 0xd6, 0x49, 0xea, 0xe9, 0x86, 0xc6, 0x5d, 0xac, 0xd0, 0xc2, 0xc5, 0x01, 0xcb, 0x3f, 0xcb,
- 0xf0, 0x62, 0x90, 0xa1, 0x17, 0x4b, 0x72, 0x5c, 0xc8, 0xe9, 0x24, 0x93, 0xda, 0x5c, 0x75, 0x24, 0x96, 0x35, 0x54, 0xf4,
- 0xfa, 0xc8, 0x27, 0xe1, 0xdd, 0x32, 0xda, 0x2f, 0x2b, 0x7d, 0xf6, 0xd8, 0x0b, 0xf2, 0xca, 0xb5, 0xee, 0x8a, 0xcf, 0xb6,
- 0x26, 0x71, 0x65, 0x85, 0xfe, 0x8c, 0x37, 0xf1, 0x17, 0x6b, 0x5e, 0x8a, 0xee, 0xb4, 0xc7, 0x0a, 0xff, 0xb2, 0x9a, 0x72,
- 0xe5, 0x85, 0xf3, 0xc0, 0xf9, 0x84, 0xbc, 0xe0, 0x18, 0x3c, 0x12, 0x0c, 0xa1, 0xe9, 0x10, 0xd4, 0x3b, 0x1a, 0x21, 0x35,
- 0xc6, 0x06, 0x93, 0xa0, 0xdf, 0x0d, 0x68, 0xa3, 0xf1, 0x06, 0xd9, 0xed, 0xb7, 0xa7, 0xba, 0xb0, 0x22, 0xc2, 0x0b, 0x6b,
- 0x70, 0x50, 0xf5, 0x49, 0x9a, 0x4f, 0x99, 0xaa, 0x1e, 0x9c, 0xa6, 0xf3, 0x99, 0x3a, 0xfd, 0x3b, 0xd2, 0xeb, 0xce, 0x1e,
- 0x72, 0x62, 0x99, 0xc0, 0x1e, 0x2b, 0x09, 0x75, 0x4a, 0xfb, 0xc8, 0x26, 0xcf, 0x76, 0xa2, 0x0e, 0xef, 0xf4, 0xa8, 0x70,
- 0x31, 0xd8, 0xa1, 0x22, 0x62, 0xcc, 0x9f, 0xd5, 0xa3, 0x55, 0xc2, 0x78, 0xd7, 0x27, 0xfc, 0x3c, 0x53, 0xe8, 0xeb, 0x7e,
- 0x7a, 0x27, 0xcf, 0x6d, 0x52, 0xb5, 0x9a, 0x2b, 0x49, 0x8d, 0x3f, 0x89, 0x80, 0x1a, 0x5c, 0x39, 0xe7, 0x53, 0xb3, 0xf3,
- 0x33, 0x97, 0xcf, 0x7d, 0xfb, 0x8e, 0x19, 0xf4, 0x72, 0xeb, 0xe7, 0xdf, 0xb1, 0xe3, 0xc1, 0x6c, 0x7f, 0x17, 0x89, 0x34,
- 0x4f, 0x45, 0x0f, 0xc5, 0xfc, 0x15, 0xb3, 0x3f, 0xc6, 0xdc, 0x25, 0xa6, 0xda, 0x28, 0x85, 0x5d, 0x25, 0x02, 0x78, 0x74,
- 0xd9, 0x74, 0xb8, 0x65, 0x48, 0x3a, 0x8a, 0x2a, 0xd5, 0xa9, 0xb8, 0x7f, 0xaa, 0x9d, 0xe7, 0xaf, 0xbd, 0xdf, 0xfd, 0x00,
- 0x67, 0xab, 0x39, 0xe1, 0x2c, 0x3d, 0xd1, 0x5c, 0x9b, 0x61, 0x2b, 0x51, 0xdc, 0x87, 0x19, 0x6c, 0xa0, 0x12, 0xd4, 0x60,
- 0xed, 0x94, 0xe9, 0xeb, 0x4e, 0x51, 0xd8, 0x50, 0xcb, 0x97, 0x8a, 0x20, 0x21, 0xdf, 0xe9, 0x2c, 0xd2, 0xe2, 0x04, 0x14,
- 0xaf, 0x7b, 0x7e, 0xd6, 0xeb, 0x1d, 0x25, 0x09, 0x98, 0x8e, 0x9e, 0x56, 0xf8, 0x7d, 0xfc, 0x0f, 0xbf, 0xd2, 0x6b, 0xbc,
- 0xab, 0xed, 0xca, 0x43, 0x6d, 0x28, 0xbe, 0xd5, 0x20, 0x44, 0xcb, 0x6b, 0xbc, 0x80, 0x5a, 0x82, 0x13, 0x50, 0xbd, 0xda,
- 0x18, 0x10, 0xac, 0xae, 0x56, 0xb9, 0x46, 0xc5, 0xa2, 0xca, 0xb2, 0x03, 0xf0, 0x57, 0xfe, 0xcd, 0x9a, 0x1b, 0x81, 0x6a,
- 0x10, 0x51, 0x2e, 0x88, 0x30, 0x57, 0x3c, 0xfe, 0x7c, 0x56, 0x0c, 0x00, 0x89, 0x5c, 0x21, 0x57, 0x19, 0x96, 0x85, 0x98,
- 0xeb, 0x43, 0x71, 0x0d, 0x8a, 0x35, 0xc3, 0xae, 0x36, 0x59, 0x72, 0x97, 0x12, 0x6d, 0xcd, 0x28, 0x64, 0x17, 0x9e, 0xe7,
- 0x2c, 0x28, 0xfd, 0x32, 0xa8, 0x10, 0x67, 0x4e, 0xc0, 0x14, 0x21, 0x7c, 0x36, 0x20, 0xe9, 0x46, 0x68, 0x62, 0xc1, 0xff,
- 0xb0, 0xdf, 0xaa, 0x87, 0xff, 0x94, 0xa4, 0xf3, 0xb3, 0xc8, 0x53, 0x57, 0x18, 0x92, 0x15, 0xc7, 0x78, 0x2d, 0x91, 0xba,
- 0xb3, 0x1f, 0x06, 0x13, 0x79, 0x21, 0x86, 0x1d, 0xa2, 0x38, 0x2c, 0xda, 0x35, 0x31, 0xbb, 0x04, 0x65, 0xa3, 0x01, 0xa6,
- 0x63, 0xa4, 0x4a, 0xa2, 0xc1, 0xad, 0x04, 0xc1, 0xfa, 0x78, 0xe1, 0xb6, 0x50, 0x46, 0xab, 0xad, 0x1c, 0xcf, 0xf4, 0xe5,
- 0xba, 0xa5, 0xe2, 0x91, 0x29, 0x4b, 0xa1, 0xc6, 0x4b, 0x30, 0xa5, 0x31, 0x02, 0xe9, 0xd0, 0x50, 0x72, 0x2c, 0x8e, 0xbd,
- 0xb2, 0x12, 0xd9, 0x4f, 0x7c, 0x87, 0x4b, 0xa0, 0x45, 0x71, 0x0c, 0x23, 0x37, 0x6b, 0x60, 0xd7, 0x9f, 0x19, 0xe8, 0x0b,
- 0x85, 0x57, 0x72, 0xb6, 0xbb, 0x20, 0x23, 0xd3, 0x7d, 0x9a, 0x9b, 0x9a, 0x05, 0x46, 0x5c, 0xf5, 0x02, 0xf1, 0x56, 0x00,
- 0xc2, 0x05, 0x85, 0x48, 0xd3, 0x8d, 0x8e, 0xe1, 0xcb, 0xc5, 0x83, 0x1f, 0x78, 0xd0, 0xc5, 0xb1, 0xdf, 0x80, 0x9d, 0x04,
- 0xe7, 0xac, 0xd1, 0x68, 0x1a, 0x19, 0x18, 0x16, 0xfa, 0x3a, 0xe2, 0xd2, 0x30, 0x08, 0x17, 0x4d, 0x50, 0x2b, 0xd4, 0xa3,
- 0xbe, 0x98, 0x5f, 0xe0, 0xcf, 0xed, 0x7d, 0x74, 0x94, 0xd1, 0xb2, 0x77, 0xbc, 0x72, 0xbc, 0xf5, 0xc7, 0x82, 0x26, 0x53,
- 0x14, 0xcc, 0xf9, 0xf7, 0x71, 0xea, 0x97, 0xaa, 0xbf, 0x21, 0x46, 0x59, 0x2c, 0x9a, 0xc4, 0xeb, 0xa3, 0x4a, 0x97, 0x91,
- 0x11, 0xf1, 0x01, 0x19, 0x7e, 0xb1, 0xb2, 0x63, 0x0d, 0xf0, 0x5d, 0xaf, 0x53, 0xdf, 0x4d, 0xa1, 0x90, 0xe5, 0x12, 0x82,
- 0x33, 0x6f, 0x1d, 0x73, 0xdf, 0xdb, 0x1f, 0x18, 0xa0, 0x72, 0xc1, 0xd6, 0xa7, 0x4d, 0xb2, 0x3e, 0x24, 0xb7, 0xa7, 0x76,
- 0x15, 0x46, 0x22, 0x48, 0x49, 0x55, 0xd1, 0xfb, 0x66, 0x32, 0x02, 0xa9, 0xfc, 0xbe, 0x7e, 0x16, 0xcf, 0xac, 0x32, 0xbc,
- 0xdb, 0xd5, 0xd8, 0xa3, 0x23, 0x6a, 0x10, 0xa6, 0x37, 0x03, 0xf6, 0x2a, 0xde, 0xba, 0xde, 0x2d, 0x7d, 0xef, 0x1d, 0xb9,
- 0xf3, 0x93, 0xd4, 0xf2, 0x13, 0xf4, 0x9c, 0x5a, 0x32, 0xba, 0x5f, 0xef, 0x7b, 0xd0, 0x6b, 0xd7, 0x91, 0x6d, 0x7b, 0xe1,
- 0x4d, 0xf2, 0x8c, 0xe7, 0xf1, 0x66, 0xb9, 0xad, 0xc6, 0x30, 0x08, 0x9e, 0x51, 0xd4, 0x39, 0x87, 0x09, 0xfa, 0x6b, 0x7a,
- 0xa7, 0x5f, 0x1a, 0x9c, 0x98, 0xc5, 0x76, 0xb0, 0x71, 0x76, 0xf5, 0xfc, 0x56, 0x88, 0x1c, 0xca, 0xee, 0x76, 0xd4, 0x2c,
- 0xa6, 0x64, 0x80, 0x59, 0x12, 0x8c, 0x08, 0xce, 0x83, 0xb3, 0xd9, 0x68, 0x59, 0xc1, 0x26, 0x86, 0xa7, 0x80, 0x10, 0xbc,
- 0x41, 0x28, 0x6c, 0x45, 0xd4, 0x6d, 0x15, 0xd0, 0x76, 0x44, 0x0e, 0xcf, 0xc1, 0xde, 0xef, 0x7a, 0x97, 0x36, 0x8f, 0x0d,
- 0x8a, 0xf5, 0x45, 0xde, 0xae, 0x61, 0xd0, 0x55, 0xe9, 0x8d, 0x62, 0xfd, 0xa3, 0x0d, 0x44, 0x0f, 0x49, 0xb6, 0x5a, 0xa4,
- 0xaa, 0x03, 0x4e, 0x60, 0x35, 0x53, 0x86, 0x9e, 0xec, 0x75, 0xd9, 0x0a, 0xca, 0x14, 0xe3, 0x1b, 0x06, 0x05, 0xd6, 0x8f,
- 0x4f, 0x11, 0xb3, 0x13, 0xdd, 0x26, 0x35, 0xbd, 0x56, 0x55, 0xf1, 0x43, 0x89, 0x5e, 0x5b, 0x25, 0x4d, 0xa8, 0x09, 0xdd,
- 0xf2, 0x6d, 0x9e, 0x8c, 0xcd, 0xa2, 0xde, 0x84, 0x00, 0x6a, 0x0a, 0xc6, 0x92, 0x30, 0x82, 0xcf, 0xa4, 0x31, 0x67, 0xbd,
- 0xd4, 0x36, 0x6a, 0x8b, 0xc6, 0x33, 0xdf, 0x8b, 0xde, 0x33, 0x01, 0x7b, 0x9d, 0xbf, 0xe9, 0x12, 0x35, 0x8a, 0x97, 0x07,
- 0x72, 0x0b, 0x6b, 0x60, 0xe6, 0x1e, 0x7d, 0x78, 0x22, 0x9f, 0xbf, 0x66, 0x8e, 0x02, 0xf4, 0xdc, 0xa1, 0xb0, 0x42, 0x73,
- 0x86, 0xca, 0x34, 0xf0, 0xa7, 0x2e, 0x15, 0x84, 0xa4, 0x60, 0xa8, 0x47, 0x05, 0x80, 0x03, 0x27, 0xa8, 0x04, 0x03, 0xfe,
- 0x47, 0xd4, 0xeb, 0x33, 0x27, 0xbf, 0x89, 0xff, 0x4c, 0xd9, 0x27, 0x0e, 0xd0, 0xa9, 0x41, 0x8b, 0xd5, 0x7c, 0xc4, 0x14,
- 0x7a, 0x9c, 0xb3, 0xaa, 0x13, 0x32, 0xa4, 0x67, 0xd5, 0x95, 0xdc, 0x4a, 0x3d, 0xf2, 0x54, 0xd7, 0x02, 0xf8, 0x06, 0x7b,
- 0x1d, 0x9a, 0xa4, 0x53, 0xa0, 0x9c, 0x76, 0x7d, 0xf4, 0x01, 0xa3, 0x4b, 0xb2, 0x8b, 0x44, 0x85, 0xf6, 0x80, 0x99, 0x2f,
- 0x77, 0x08, 0x20, 0xea, 0x08, 0xf8, 0x14, 0x76, 0xfe, 0xa0, 0x5a, 0xf9, 0x1f, 0x87, 0x03, 0xff, 0x8d, 0x1f, 0x5d, 0x02,
- 0x64, 0x8a, 0xf4, 0xa5, 0x8c, 0xb7, 0x0a, 0x34, 0x68, 0xaa, 0xca, 0xc8, 0xe1, 0x78, 0x9b, 0xd3, 0x6c, 0x5c, 0x07, 0x99,
- 0xc1, 0x10, 0x3f, 0x77, 0x0c, 0x45, 0xa2, 0xda, 0xda, 0xab, 0x7c, 0xf0, 0x90, 0x12, 0xa2, 0x7c, 0x84, 0x30, 0x82, 0x09,
- 0xc9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0xba, 0x04, 0x82, 0x09, 0xb6,
- 0x30, 0x82, 0x09, 0xb2, 0x30, 0x82, 0x09, 0xae, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
- 0x02, 0xa0, 0x82, 0x09, 0x76, 0x30, 0x82, 0x09, 0x72, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd3, 0x5d, 0xa8, 0x14, 0xbc, 0x7a, 0xaa, 0x5f, 0x02, 0x02, 0x08, 0x00, 0x04,
- 0x82, 0x09, 0x50, 0xaf, 0xe9, 0x63, 0xb6, 0x05, 0x8b, 0x48, 0xe1, 0x11, 0xd0, 0x37, 0x1d, 0x48, 0x71, 0x22, 0x70, 0xdc,
- 0xbd, 0xca, 0x98, 0x5d, 0x72, 0xca, 0x38, 0xdc, 0x2e, 0x4f, 0xd4, 0x71, 0xd3, 0xac, 0xf3, 0x0c, 0xcf, 0x78, 0x4e, 0x5c,
- 0x63, 0x35, 0xaa, 0xac, 0x5a, 0xf0, 0xef, 0x6c, 0xc0, 0x89, 0x28, 0xc4, 0x64, 0xec, 0x5c, 0x92, 0x72, 0xbc, 0xe5, 0x30,
- 0xe9, 0x5c, 0x35, 0xff, 0xe0, 0xb1, 0x1f, 0xc6, 0x37, 0x50, 0xb7, 0x3d, 0x94, 0x28, 0xbd, 0x3b, 0xf0, 0xd9, 0x5c, 0xb1,
- 0x45, 0x93, 0xde, 0x41, 0x5b, 0x12, 0xba, 0xfa, 0x27, 0x49, 0x6b, 0xb7, 0x9a, 0xa6, 0x46, 0x8e, 0xe3, 0x15, 0x1b, 0x7f,
- 0x2c, 0x91, 0x2e, 0x33, 0xf3, 0xef, 0x7a, 0x9b, 0x9d, 0xa8, 0x82, 0x95, 0xa0, 0x7e, 0x43, 0xd6, 0x9d, 0xe2, 0xfb, 0xb1,
- 0xb0, 0xcf, 0xbd, 0xb6, 0x9b, 0x55, 0x4c, 0xc8, 0x4a, 0xc7, 0x82, 0xeb, 0x3d, 0x09, 0x8d, 0x85, 0x6f, 0x8c, 0x42, 0x6d,
- 0x10, 0x7d, 0x77, 0x57, 0x29, 0x00, 0xe2, 0xd8, 0x2f, 0xed, 0x7c, 0x10, 0x5b, 0x03, 0xfa, 0x60, 0x34, 0xc9, 0x63, 0x25,
- 0x4d, 0x02, 0x77, 0x8f, 0x7f, 0x4b, 0x53, 0xe4, 0x8d, 0x1e, 0x4e, 0x2c, 0x0c, 0x7f, 0x0e, 0x48, 0x4b, 0xcd, 0xc8, 0x6a,
- 0xfa, 0xd3, 0x9f, 0x6f, 0x20, 0x4e, 0x2c, 0x77, 0x2a, 0x84, 0x5e, 0x6c, 0xc3, 0x57, 0xba, 0x97, 0xa7, 0xa8, 0xcb, 0x6f,
- 0x22, 0xc1, 0xa7, 0x61, 0xf7, 0x7e, 0x7a, 0xae, 0xda, 0xbd, 0x3a, 0xea, 0xb3, 0x46, 0x54, 0x8d, 0x46, 0x48, 0x1f, 0xf3,
- 0x5c, 0xaa, 0x2e, 0x44, 0xe1, 0x83, 0x69, 0x45, 0x30, 0x02, 0x49, 0x63, 0xa6, 0xdd, 0xf0, 0x25, 0xce, 0x81, 0xab, 0x66,
- 0x20, 0x04, 0x12, 0x2f, 0x94, 0x2f, 0x8f, 0xf9, 0x88, 0xea, 0x5b, 0xba, 0x87, 0xd7, 0xbe, 0x63, 0x2e, 0xb4, 0xa4, 0x15,
- 0xe8, 0x56, 0x9e, 0xb5, 0x7b, 0x27, 0xf8, 0x06, 0xfd, 0xf5, 0x21, 0x93, 0x2b, 0x64, 0xb0, 0xe2, 0x31, 0xb3, 0x19, 0xe0,
- 0x6b, 0x10, 0x8c, 0xa5, 0xa5, 0x38, 0x27, 0x78, 0xc9, 0x9c, 0x01, 0xa7, 0x42, 0x22, 0x3d, 0xf8, 0x8c, 0x23, 0x46, 0xc5,
- 0x4e, 0x47, 0xa5, 0x9e, 0xd7, 0xa5, 0x50, 0x24, 0x02, 0x30, 0xe9, 0x15, 0x3e, 0x17, 0xba, 0x2c, 0xf2, 0x5e, 0xc7, 0x01,
- 0x25, 0x9a, 0x74, 0x73, 0x5c, 0x5e, 0xca, 0x01, 0xe2, 0x58, 0x96, 0x47, 0x3e, 0x4c, 0xb9, 0x0f, 0x95, 0xbf, 0xf3, 0xc4,
- 0x24, 0x98, 0x6c, 0xc5, 0x40, 0xd2, 0xf3, 0x88, 0x62, 0xb0, 0x25, 0x54, 0xb5, 0xf6, 0x2b, 0xfd, 0xf5, 0x6a, 0x6d, 0x15,
- 0xb2, 0x18, 0x7d, 0xef, 0x3e, 0x66, 0x7d, 0x38, 0x4c, 0xda, 0xc9, 0x1a, 0xcd, 0x40, 0x2a, 0xc6, 0x7b, 0x2e, 0x8a, 0x15,
- 0xa7, 0xae, 0x99, 0xf5, 0x93, 0x39, 0x20, 0xd2, 0xd8, 0xfd, 0x1f, 0x87, 0x2e, 0xa0, 0xcd, 0x95, 0xa2, 0xd7, 0xd0, 0x48,
- 0xf7, 0x6e, 0x81, 0x91, 0x1c, 0x37, 0x8a, 0x28, 0x6f, 0x22, 0x7b, 0x37, 0x69, 0x30, 0x3a, 0x64, 0x6e, 0x4a, 0x5f, 0x0a,
- 0xa6, 0xd7, 0x53, 0xce, 0x1d, 0x60, 0x88, 0xa5, 0x0b, 0xde, 0xf5, 0x01, 0x3a, 0x20, 0xfa, 0xd6, 0x08, 0xdf, 0x83, 0x39,
- 0x2e, 0xb8, 0x3a, 0x91, 0xec, 0x39, 0x47, 0xaa, 0x66, 0x8a, 0xb4, 0x35, 0x70, 0xaf, 0x88, 0x24, 0xb2, 0xc3, 0xdc, 0x7c,
- 0xd0, 0x8f, 0x93, 0x0d, 0xa4, 0x53, 0xf1, 0x55, 0x92, 0xae, 0xd9, 0xeb, 0x31, 0xa0, 0x68, 0x29, 0xf5, 0xdb, 0x2f, 0xd1,
- 0xa3, 0xfe, 0x34, 0x2f, 0xcd, 0x64, 0x0c, 0x11, 0x13, 0x14, 0x50, 0xeb, 0x27, 0x56, 0xda, 0xc0, 0x30, 0x3a, 0x8c, 0x92,
- 0xb3, 0xb8, 0xc8, 0xb7, 0x19, 0xea, 0x4c, 0x74, 0xb9, 0x95, 0x46, 0x9f, 0xc0, 0x63, 0xfd, 0x72, 0x35, 0x0b, 0xb9, 0x1d,
- 0x1e, 0x85, 0xf8, 0xf9, 0x23, 0xf7, 0x42, 0xe2, 0xf4, 0x67, 0xbf, 0x3d, 0x30, 0x4b, 0x6a, 0xf2, 0x44, 0x2f, 0xcb, 0x6f,
- 0xe9, 0x73, 0x4b, 0x8f, 0x09, 0x29, 0x69, 0xcd, 0x8d, 0xcd, 0xc7, 0xd4, 0xa2, 0x0c, 0x6a, 0xc4, 0x9a, 0x33, 0xe2, 0x64,
- 0x5f, 0x07, 0xf2, 0xb6, 0xf8, 0x86, 0x7f, 0x05, 0x04, 0xf1, 0x1d, 0x9d, 0xd1, 0xc8, 0x3c, 0x16, 0x6e, 0x18, 0x96, 0x15,
- 0x33, 0xda, 0x84, 0xb6, 0xfd, 0x13, 0x29, 0x2f, 0x5e, 0xa0, 0x0e, 0xaa, 0xf6, 0x24, 0xb4, 0xa5, 0x48, 0x01, 0x02, 0x07,
- 0x31, 0x98, 0x0d, 0x9c, 0x65, 0x59, 0x68, 0x61, 0x22, 0xdb, 0x64, 0x16, 0x05, 0xae, 0xd8, 0x64, 0x5f, 0xba, 0x51, 0xab,
- 0x5e, 0xe0, 0xbe, 0x3d, 0x29, 0x67, 0x20, 0x94, 0x63, 0xfe, 0xc7, 0x90, 0x30, 0xc9, 0x43, 0xf1, 0xce, 0x9c, 0x53, 0x01,
- 0x2c, 0x64, 0x56, 0x85, 0xb7, 0x3b, 0xa4, 0x05, 0x5d, 0x88, 0xdf, 0x44, 0xda, 0x18, 0xf3, 0x8c, 0xdb, 0xae, 0xd2, 0x9f,
- 0xee, 0x4e, 0x08, 0x17, 0xf9, 0xd8, 0xe0, 0xc9, 0x7d, 0xa5, 0xad, 0x79, 0x06, 0x1b, 0x8c, 0x92, 0xe7, 0x53, 0xdf, 0xde,
- 0xa3, 0xa5, 0x84, 0x1d, 0xd8, 0x75, 0x35, 0x78, 0x32, 0x55, 0x6f, 0x4f, 0x29, 0x34, 0x4e, 0x6f, 0x32, 0x16, 0xe4, 0xfd,
- 0xbc, 0xf5, 0x76, 0x99, 0xf3, 0x48, 0x5b, 0xa0, 0x65, 0xb2, 0xef, 0xeb, 0x58, 0x6c, 0xf4, 0x1e, 0x97, 0x34, 0xee, 0xf9,
- 0x74, 0xe2, 0x94, 0xc0, 0xf2, 0xf5, 0x0b, 0x97, 0x40, 0xce, 0x25, 0xd6, 0xe5, 0xdf, 0x0b, 0x3b, 0x6b, 0xf3, 0x38, 0x28,
- 0xc3, 0xa6, 0x30, 0xa5, 0x22, 0x3c, 0xb0, 0xbd, 0x4d, 0xd5, 0x79, 0x25, 0xb9, 0xb2, 0xb4, 0xc4, 0x31, 0x62, 0x0b, 0xe7,
- 0x73, 0x4e, 0xf9, 0xa7, 0x57, 0xdf, 0x33, 0x0e, 0xf0, 0xb9, 0x3b, 0x6d, 0xff, 0x6b, 0x11, 0xb0, 0x90, 0x10, 0x2a, 0x7b,
- 0xb5, 0x0b, 0x41, 0x17, 0x0b, 0x12, 0xc7, 0x61, 0xef, 0xb1, 0x9b, 0x57, 0x3a, 0x01, 0x55, 0x91, 0xe3, 0xd5, 0xc8, 0xd5,
- 0xeb, 0x26, 0x90, 0x2b, 0x67, 0x5b, 0xc2, 0x0b, 0xad, 0x6f, 0x26, 0x3a, 0xf5, 0x45, 0xb2, 0xd7, 0x6a, 0x78, 0xaa, 0x43,
- 0xd0, 0xdb, 0x53, 0x6f, 0x1a, 0x7a, 0x5c, 0x92, 0xe1, 0xb7, 0xe5, 0xad, 0xda, 0xac, 0x3b, 0x5a, 0x20, 0x06, 0xe1, 0x56,
- 0xf0, 0x55, 0x66, 0x64, 0x42, 0xd4, 0xe4, 0x77, 0x3b, 0xa5, 0x60, 0x8d, 0x5b, 0x24, 0x7a, 0x2a, 0xb9, 0xe2, 0x2f, 0xc6,
- 0x02, 0xd1, 0x21, 0xf3, 0x08, 0xbd, 0x7b, 0xf4, 0x44, 0x47, 0x00, 0xd2, 0xca, 0x3c, 0x80, 0x37, 0xb0, 0xf2, 0x3d, 0x07,
- 0x87, 0xbd, 0xe8, 0x59, 0x01, 0x17, 0x7b, 0xb3, 0x1b, 0xc3, 0xce, 0x45, 0x77, 0x3c, 0x0e, 0xdd, 0xac, 0x38, 0xf1, 0x5e,
- 0xde, 0x5e, 0xdd, 0xad, 0xf2, 0xc9, 0x0f, 0xed, 0xec, 0xe5, 0x00, 0x8b, 0x61, 0xf4, 0x62, 0xd5, 0x58, 0x37, 0xec, 0xbf,
- 0x36, 0xcf, 0x7a, 0x6a, 0x55, 0x1f, 0x25, 0x53, 0xba, 0xcd, 0x76, 0xc3, 0x07, 0x5e, 0x12, 0xf0, 0xc3, 0x82, 0x52, 0x5f,
- 0xc6, 0x24, 0x54, 0x76, 0x49, 0xa3, 0xf1, 0xdd, 0x67, 0x29, 0x81, 0x19, 0x5f, 0x7b, 0xcd, 0xc6, 0x60, 0x3e, 0x80, 0x02,
- 0xb3, 0xd9, 0xb6, 0x9d, 0x29, 0x59, 0xdc, 0x79, 0x90, 0xab, 0x53, 0xf4, 0xe6, 0x23, 0xb4, 0x77, 0x0f, 0xc8, 0xf2, 0x88,
- 0xb3, 0x1c, 0x70, 0xb4, 0xeb, 0xa8, 0xdf, 0x25, 0x5b, 0x94, 0xa6, 0xce, 0x80, 0xbd, 0x46, 0xe6, 0x26, 0x8c, 0x4f, 0xee,
- 0x37, 0x81, 0x84, 0xc6, 0xff, 0x0a, 0x37, 0x2e, 0xa4, 0xcb, 0xdf, 0x62, 0x81, 0x79, 0x3b, 0xa2, 0xdb, 0x07, 0x14, 0x0c,
- 0xf7, 0x44, 0x1e, 0xda, 0xe0, 0x6c, 0x1a, 0xb6, 0x52, 0x7f, 0xd8, 0xce, 0xe7, 0x29, 0x98, 0xc1, 0x69, 0x40, 0xb9, 0x2a,
- 0xe7, 0xb4, 0xee, 0x04, 0x67, 0xf7, 0x54, 0xac, 0x94, 0x12, 0x5c, 0x67, 0xb4, 0x51, 0x9c, 0xf6, 0xfa, 0x9b, 0x10, 0xd3,
- 0x7e, 0xce, 0x78, 0xd5, 0x88, 0x80, 0xd7, 0x88, 0xea, 0x16, 0x51, 0x0c, 0xc9, 0xf2, 0x55, 0xda, 0xbd, 0x22, 0x34, 0x1a,
- 0x65, 0x8f, 0xd7, 0x52, 0x00, 0x98, 0xc3, 0x76, 0xff, 0x3e, 0xfc, 0x44, 0x4b, 0x7e, 0xc2, 0x40, 0x00, 0x94, 0xf3, 0xc6,
- 0xd5, 0xa3, 0x0f, 0x95, 0x9a, 0x96, 0xbb, 0x50, 0xcd, 0xd0, 0x6f, 0x75, 0xd7, 0xcc, 0x89, 0xb4, 0xc2, 0x85, 0x7f, 0x5f,
- 0x06, 0xc1, 0xdf, 0x3c, 0xdd, 0x32, 0xdb, 0x44, 0xae, 0x1e, 0xd8, 0x56, 0xde, 0x93, 0xb0, 0xbd, 0xed, 0x8c, 0xb6, 0xcc,
- 0x15, 0xe7, 0x81, 0x98, 0x36, 0x36, 0xd6, 0x91, 0x61, 0xd8, 0x65, 0x57, 0x5d, 0xcd, 0xbf, 0xf1, 0x3b, 0x31, 0xb6, 0xdd,
- 0x6e, 0xc6, 0xd3, 0x1b, 0xc9, 0x47, 0x8c, 0x09, 0x03, 0x81, 0x7d, 0xbd, 0x64, 0xa9, 0x09, 0x66, 0x81, 0x2d, 0x56, 0x43,
- 0xe8, 0x3c, 0x3e, 0xaa, 0xf8, 0x28, 0x92, 0x13, 0xea, 0x1f, 0xc1, 0x81, 0x4f, 0xb1, 0x1e, 0x88, 0xd2, 0x47, 0xdb, 0xb4,
- 0x7e, 0xcb, 0xac, 0xc4, 0xbc, 0x07, 0x68, 0x83, 0x7d, 0xd2, 0x90, 0x90, 0x01, 0xa7, 0x0b, 0xac, 0x60, 0x67, 0x0f, 0xf4,
- 0x1b, 0x2c, 0x1e, 0x93, 0x93, 0x6a, 0x16, 0x63, 0x78, 0x36, 0x7d, 0xc5, 0xa5, 0x04, 0xf4, 0x96, 0x1d, 0xae, 0x1a, 0xdf,
- 0x1d, 0xba, 0xfc, 0x00, 0x21, 0x07, 0x8c, 0xa7, 0x9d, 0x00, 0x60, 0xb7, 0xa4, 0x05, 0xdd, 0xcd, 0x05, 0xee, 0x70, 0x5e,
- 0xc5, 0x79, 0x6c, 0xc1, 0x22, 0x57, 0xfb, 0x5a, 0x25, 0x3e, 0xb9, 0x37, 0x76, 0x61, 0xc2, 0x7d, 0x14, 0x3c, 0xd3, 0x3a,
- 0x13, 0xb9, 0x33, 0x07, 0xf6, 0x53, 0xc9, 0x5b, 0xb9, 0x97, 0x03, 0xd0, 0x76, 0xb8, 0xd1, 0xf1, 0x43, 0x9d, 0x7f, 0x37,
- 0x46, 0x1a, 0xda, 0xdf, 0xd7, 0x4a, 0xb7, 0x79, 0x84, 0x9e, 0x47, 0x73, 0xac, 0x26, 0xf7, 0xd7, 0x54, 0x16, 0xad, 0x49,
- 0x5e, 0x5d, 0x77, 0x61, 0x79, 0xdd, 0x52, 0x13, 0x2f, 0x20, 0xce, 0x26, 0x35, 0xa3, 0x60, 0x28, 0x3f, 0xc5, 0x67, 0xce,
- 0x43, 0xa0, 0x86, 0x28, 0xf7, 0xa6, 0xf9, 0x6a, 0xbf, 0x25, 0x41, 0xb7, 0x7d, 0xbc, 0x04, 0x02, 0xd1, 0xe5, 0xed, 0x74,
- 0xf5, 0xf5, 0x39, 0xf5, 0x18, 0x42, 0x9f, 0xdc, 0xaf, 0x46, 0xb6, 0x55, 0x48, 0x72, 0xa6, 0x66, 0x94, 0xef, 0x4a, 0x45,
- 0x92, 0xf8, 0x31, 0x7a, 0x19, 0x69, 0xcb, 0xcf, 0xf3, 0x10, 0x4a, 0x65, 0x53, 0x18, 0xf4, 0x7f, 0x47, 0xe8, 0xe5, 0x07,
- 0xb1, 0x8b, 0x3c, 0x3b, 0xb1, 0x1f, 0xdb, 0xb8, 0x5d, 0x53, 0xcb, 0xad, 0xf7, 0x38, 0x91, 0x8a, 0x1e, 0xa6, 0x76, 0x05,
- 0x48, 0x89, 0xcc, 0xff, 0x51, 0x59, 0x53, 0xe9, 0xd7, 0x6e, 0x1a, 0x6e, 0xad, 0xf2, 0xcb, 0xf5, 0xfd, 0x48, 0xbe, 0xa8,
- 0x70, 0xae, 0x5e, 0xc1, 0x7e, 0x1e, 0x07, 0x8e, 0x64, 0x0d, 0x70, 0xb7, 0x92, 0xda, 0x6f, 0x45, 0xb0, 0xe3, 0x8a, 0x30,
- 0xbc, 0x45, 0xd1, 0x65, 0xf2, 0xb7, 0xab, 0x4e, 0x16, 0x5c, 0xa2, 0xb2, 0x9a, 0x4d, 0x2f, 0x76, 0x26, 0x62, 0x92, 0x7a,
- 0x3c, 0x47, 0xf6, 0x87, 0x04, 0x0f, 0x7b, 0xda, 0x4b, 0x02, 0x6b, 0xd6, 0x16, 0x79, 0xbd, 0x16, 0x24, 0x42, 0x7a, 0xf4,
- 0x44, 0x58, 0xb4, 0x68, 0x71, 0xce, 0xb3, 0x28, 0xba, 0x84, 0x6c, 0x26, 0x82, 0x1e, 0xba, 0x19, 0x83, 0xb7, 0x75, 0x1b,
- 0xde, 0x09, 0xf6, 0x1b, 0x4f, 0x31, 0x65, 0xae, 0xb6, 0x45, 0xc2, 0xa7, 0x35, 0x2d, 0x9f, 0x14, 0x10, 0xe0, 0x3e, 0x43,
- 0xa7, 0x82, 0x01, 0x06, 0x95, 0x2c, 0x19, 0x43, 0x8c, 0x94, 0xd4, 0x8c, 0x85, 0x6d, 0x88, 0x33, 0xff, 0x19, 0x51, 0xd3,
- 0x7c, 0xf2, 0xa7, 0x5b, 0x05, 0xd1, 0x2b, 0x56, 0x18, 0x5e, 0xa6, 0xb9, 0x66, 0x3c, 0xf7, 0x4d, 0xbd, 0xa9, 0x95, 0x75,
- 0xa9, 0xa1, 0x87, 0x24, 0x87, 0xf0, 0x60, 0xbb, 0x39, 0xec, 0xd1, 0xe5, 0x67, 0x51, 0x76, 0x99, 0xbc, 0x64, 0x7b, 0x5a,
- 0xd5, 0xa6, 0x54, 0x4f, 0x16, 0x10, 0xb2, 0xe9, 0x43, 0x1c, 0x3a, 0x4c, 0x88, 0x51, 0xf4, 0xc2, 0x95, 0x16, 0x8e, 0xbf,
- 0x79, 0x19, 0x22, 0x95, 0xd1, 0x76, 0x99, 0xb8, 0x68, 0xf3, 0x6a, 0x1a, 0x4e, 0x43, 0xf8, 0x9c, 0x6b, 0x75, 0x8c, 0xa5,
- 0xbd, 0x65, 0x3a, 0x83, 0x0b, 0x47, 0xcf, 0x08, 0xf7, 0x22, 0x86, 0xad, 0xd5, 0x89, 0xd0, 0x6f, 0x4e, 0xbe, 0x2a, 0x81,
- 0x1d, 0x1c, 0xf1, 0xc8, 0xf3, 0x18, 0x44, 0x40, 0xf3, 0x99, 0xfd, 0x18, 0xe3, 0x1a, 0xc9, 0x7f, 0x3b, 0x93, 0x68, 0x84,
- 0xe2, 0x49, 0xb9, 0xcf, 0x00, 0x5c, 0x76, 0xc4, 0xcc, 0x4b, 0x7e, 0x86, 0x7e, 0x3f, 0x4b, 0x23, 0x61, 0x92, 0x7c, 0xcb,
- 0x0c, 0x0c, 0x3e, 0x97, 0x34, 0xcc, 0xfd, 0x34, 0xa9, 0xcc, 0xf0, 0x83, 0xb1, 0xbc, 0x50, 0x4c, 0x84, 0x6f, 0xba, 0x68,
- 0x01, 0x4f, 0x71, 0x57, 0x05, 0x7f, 0x01, 0xe2, 0x18, 0x23, 0xe9, 0x44, 0xa8, 0x4d, 0x93, 0x11, 0xee, 0xc0, 0x79, 0x5a,
- 0x94, 0x13, 0x81, 0xf4, 0x67, 0xa0, 0x50, 0x79, 0x83, 0xa1, 0x13, 0x5f, 0x0e, 0x82, 0x9a, 0x72, 0x90, 0xba, 0x43, 0x21,
- 0x28, 0xa9, 0x65, 0x1c, 0x16, 0x97, 0x6f, 0xdb, 0xc3, 0x1e, 0x23, 0xc5, 0x4a, 0xdb, 0x3b, 0x3c, 0x42, 0x4a, 0xc4, 0xb5,
- 0x7f, 0x6b, 0x5d, 0xfc, 0x09, 0x08, 0x43, 0x2f, 0xf8, 0x11, 0x27, 0x6f, 0x1d, 0xc0, 0x12, 0x59, 0x04, 0xa4, 0x5b, 0xe9,
- 0x9f, 0x25, 0xd1, 0x58, 0x3a, 0x1f, 0xac, 0x05, 0x15, 0x18, 0xea, 0xbd, 0x4b, 0xd2, 0xba, 0x67, 0xf3, 0x1d, 0x89, 0x09,
- 0x52, 0xe5, 0x0e, 0x15, 0xd6, 0x5b, 0x87, 0xf5, 0xc3, 0x3c, 0x98, 0xbc, 0x46, 0x4e, 0x19, 0x8d, 0xbb, 0x3e, 0xe0, 0xde,
- 0x19, 0x59, 0x53, 0x32, 0x62, 0x31, 0x16, 0xd4, 0xea, 0x63, 0xda, 0xf4, 0xcc, 0x94, 0xd0, 0x18, 0x98, 0xbc, 0x00, 0xd3,
- 0x6c, 0xe2, 0xa5, 0xac, 0x30, 0x08, 0x9d, 0x68, 0x82, 0x8e, 0xbb, 0xdf, 0x9a, 0xa1, 0x13, 0xa5, 0x98, 0x18, 0xa9, 0x11,
- 0xde, 0x49, 0x18, 0x88, 0xab, 0xff, 0xc6, 0x2c, 0xa8, 0xe1, 0xf7, 0x49, 0xba, 0x17, 0x93, 0x1c, 0x6c, 0x7f, 0x2c, 0xa9,
- 0x3a, 0xee, 0x77, 0x9d, 0x46, 0x0c, 0xf9, 0x1c, 0x24, 0x33, 0x6f, 0x9b, 0xf8, 0x47, 0x9d, 0xc9, 0x7f, 0x9c, 0x80, 0xa0,
- 0x2c, 0x96, 0x63, 0xe1, 0x97, 0x75, 0x75, 0x1f, 0xb3, 0xc6, 0x0d, 0xa9, 0x49, 0x82, 0x66, 0x86, 0x13, 0xa4, 0x62, 0x4c,
- 0x56, 0x89, 0x73, 0x03, 0x1b, 0x61, 0xff, 0xfa, 0x0f, 0xf4, 0x84, 0xe3, 0xad, 0x89, 0xc0, 0x8e, 0x03, 0x91, 0x1c, 0x99,
- 0x9f, 0x99, 0x92, 0x7e, 0xb5, 0xd8, 0xe3, 0xee, 0x6c, 0x21, 0x27, 0x5d, 0xa2, 0xa5, 0x90, 0xf2, 0x67, 0xed, 0xf3, 0xca,
- 0x51, 0x56, 0x28, 0x7d, 0xa9, 0xd0, 0x4a, 0x4b, 0x76, 0x2b, 0xa8, 0x95, 0x8a, 0x37, 0xb4, 0x72, 0x96, 0xb2, 0xa0, 0xbe,
- 0x90, 0x4f, 0x4e, 0x37, 0xbb, 0x14, 0xf8, 0xd2, 0x76, 0x7c, 0x79, 0xf3, 0xd2, 0xbf, 0x35, 0xad, 0x64, 0xbc, 0x98, 0x73,
- 0xe5, 0xb9, 0xb3, 0xa2, 0x9b, 0x54, 0x17, 0x9b, 0x99, 0xa1, 0xeb, 0xfd, 0xc2, 0x8b, 0xbd, 0xac, 0x6d, 0x14, 0x35, 0xc2,
- 0x3b, 0xc9, 0x88, 0x57, 0x64, 0xaa, 0x52, 0x3d, 0xf1, 0x80, 0x9c, 0xb2, 0xfc, 0xe9, 0x53, 0x7c, 0x12, 0x81, 0xe6, 0x07,
- 0xa1, 0x0b, 0x2b, 0xb3, 0x88, 0xa6, 0x07, 0xb8, 0x10, 0x7e, 0xc4, 0x55, 0x14, 0xa2, 0x66, 0xf1, 0xcc, 0xff, 0x49, 0x84,
- 0xbc, 0x54, 0x15, 0x41, 0x26, 0x15, 0x44, 0xf1, 0xe4, 0x4e, 0x8a, 0xf4, 0x02, 0xb1, 0x87, 0x51, 0xa7, 0xa4, 0xe6, 0x4f,
- 0xbb, 0xff, 0xfe, 0x94, 0x51, 0x54, 0x20, 0x7e, 0x16, 0x60, 0x23, 0xfe, 0x05, 0x8c, 0x1a, 0xe1, 0x12, 0x7c, 0xd4, 0xc0,
- 0xae, 0x3a, 0x96, 0x13, 0x5d, 0x83, 0x89, 0x49, 0x99, 0x2c, 0x3e, 0x19, 0x8b, 0xa8, 0xf0, 0x0d, 0x65, 0x5d, 0x35, 0x37,
- 0xa1, 0x2d, 0xdd, 0xe2, 0x6b, 0x0d, 0xa9, 0x47, 0x9e, 0xf0, 0x22, 0xb5, 0x8e, 0xab, 0xc1, 0x34, 0x93, 0x4c, 0xff, 0x89,
- 0x9b, 0x24, 0xd4, 0x01, 0x24, 0xbc, 0xf5, 0x42, 0xd8, 0xee, 0xc2, 0xbc, 0x78, 0x03, 0xc1, 0x24, 0xa8, 0x88, 0xba, 0x3f,
- 0x71, 0x58, 0x3d, 0xdd, 0xef, 0xa8, 0xf8, 0x15, 0x4c, 0xb0, 0x68, 0x7c, 0xbc, 0x41, 0x66, 0x72, 0xc4, 0x4d, 0x9f, 0xd0,
- 0xdb, 0x9a, 0xd0, 0x65, 0xde, 0xf1, 0x25, 0x02, 0x35, 0xff, 0x49, 0x4a, 0xd8, 0xa4, 0x19, 0x49, 0xb4, 0x51, 0xda, 0x4b,
- 0x75, 0x81, 0x17, 0xa7, 0x84, 0x80, 0x70, 0x3f, 0xc7, 0x0d, 0xb2, 0x79, 0x24, 0x25, 0x7c, 0xe2, 0x30, 0x67, 0x15, 0x00,
- 0x80, 0x68, 0x1e, 0xde, 0xf0, 0x3e, 0xda, 0xc6, 0x31, 0x4d, 0xa7, 0xf0, 0x53, 0x0d, 0x88, 0x08, 0xe1, 0xd8, 0xe2, 0x8b,
- 0x01, 0xdb, 0x9f, 0x5b, 0x7c, 0xd4, 0x68, 0x89, 0xb1, 0xeb, 0xdb, 0x4e, 0x6f, 0xac, 0x21, 0xad, 0xf2, 0xed, 0x6f, 0x61,
- 0x4d, 0x1f, 0x2f, 0x64, 0x0b, 0xdb, 0x07, 0x54, 0x65, 0xd7, 0xf0, 0xf8, 0x40, 0xdb, 0xd9, 0x5e, 0x2d, 0xaf, 0x4f, 0x14,
- 0x9f, 0x5b, 0x0b, 0x74, 0x4e, 0xad, 0x07, 0x60, 0xac, 0x24, 0x04, 0x5b, 0xc8, 0xf4, 0xc9, 0x6f, 0x28, 0xb0, 0x2b, 0xb3,
- 0xd9, 0x43, 0xf1, 0x55, 0xc9, 0x25, 0x01, 0xb7, 0xab, 0x8f, 0xd8, 0x0f, 0x78, 0x6a, 0xbf, 0xa0, 0x4e, 0x80, 0x22, 0xc6,
- 0x8a, 0x42, 0x37, 0x6d, 0x3a, 0xbd, 0xf3, 0x66, 0xbe, 0x84, 0x87, 0xf6, 0xa1, 0xa0, 0x99, 0x7f, 0x13, 0x66, 0x40, 0x39,
- 0xce, 0x43, 0x8f, 0xe5, 0x83, 0x48, 0x94, 0xc6, 0x59, 0xc2, 0xce, 0x55, 0x35, 0x44, 0x74, 0xa6, 0x37, 0x0c, 0x3c, 0x69,
- 0xdc, 0xdb, 0x2b, 0x3a, 0xd8, 0x32, 0x4d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x01, 0xae, 0x1a, 0x61, 0x75, 0xae, 0x23, 0xd9, 0x11, 0x5c, 0x28, 0x93, 0xa9, 0xe2,
- 0x49, 0x5e, 0x74, 0x28, 0x4c, 0x08, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
- 0x00, 0x04, 0x14, 0x3d, 0xc6, 0xb0, 0x07, 0xf5, 0xd4, 0xa7, 0x42, 0x90, 0xa1, 0x2f, 0x4d, 0x1e, 0x43, 0x09, 0x7d, 0xd5,
- 0xfe, 0x15, 0xb1, 0x04, 0x08, 0xdd, 0xee, 0x2c, 0x8a, 0x3d, 0x65, 0x41, 0x94, 0x02, 0x02, 0x08, 0x00
-};
-
-/* Random data for content */
-uint8_t content[1024] = {
- 0x2a, 0xb1, 0x8c, 0xf1, 0x66, 0x52, 0xd5, 0x3c, 0xdd, 0x53, 0xc0, 0x07, 0x6a, 0x13, 0xda, 0x25, 0x9c, 0x04, 0x64, 0x5c,
- 0x97, 0xb8, 0xb3, 0xb5, 0xcf, 0xf8, 0xe1, 0x8f, 0xdd, 0x49, 0x64, 0x55, 0x97, 0xad, 0xbc, 0xad, 0xff, 0xd1, 0xd9, 0xdf,
- 0x0f, 0x26, 0x96, 0x27, 0x78, 0x1b, 0x13, 0xf6, 0x2e, 0x75, 0xb2, 0x6a, 0xf1, 0x04, 0x71, 0xa3, 0x51, 0x8d, 0x9c, 0xe8,
- 0xab, 0xee, 0xf4, 0xf4, 0xfa, 0x75, 0x16, 0xbe, 0x08, 0xaf, 0xdf, 0x23, 0xc2, 0x17, 0x75, 0x80, 0xad, 0x0e, 0x68, 0xc1,
- 0x37, 0xd9, 0x49, 0x0b, 0xea, 0x8a, 0x29, 0x3a, 0x2d, 0xff, 0x45, 0xe9, 0x13, 0x93, 0xac, 0x2e, 0x25, 0x3d, 0x5f, 0xd1,
- 0x36, 0x66, 0x61, 0x14, 0xa9, 0xf1, 0xae, 0x83, 0x3a, 0x96, 0xe3, 0xcd, 0xe1, 0xdd, 0xb8, 0x8b, 0x85, 0xe7, 0xd9, 0x1b,
- 0x76, 0xf9, 0x55, 0xf7, 0xd8, 0xb6, 0xca, 0x5b, 0x0f, 0xb8, 0x40, 0x1b, 0x69, 0x54, 0x07, 0xde, 0xd5, 0x26, 0x85, 0x9b,
- 0xd1, 0x4a, 0xce, 0x2b, 0xe1, 0xd8, 0xe7, 0x6a, 0x06, 0x28, 0x4b, 0x05, 0xa9, 0x0b, 0x65, 0x07, 0x3d, 0xf5, 0xca, 0x31,
- 0xd0, 0xfb, 0x5b, 0xf8, 0x1e, 0x19, 0x5f, 0x69, 0x64, 0x1b, 0xe1, 0x6d, 0x15, 0x88, 0x9c, 0xd1, 0x25, 0x4d, 0xf2, 0xa5,
- 0x74, 0x82, 0xa4, 0xd3, 0x21, 0xc2, 0x4f, 0x78, 0xcf, 0x37, 0xdd, 0x3c, 0xe5, 0x69, 0x27, 0x82, 0xf1, 0xc8, 0xe9, 0x2f,
- 0x7a, 0x7d, 0xd4, 0x65, 0x78, 0xad, 0x4c, 0xfc, 0xa5, 0x29, 0x51, 0xe2, 0x67, 0xac, 0x29, 0xa4, 0x23, 0x46, 0xe0, 0x10,
- 0x55, 0x2a, 0x7e, 0xef, 0x04, 0xd4, 0x9f, 0xe3, 0x65, 0x09, 0x2d, 0x33, 0x07, 0xa5, 0x6c, 0x3d, 0x6e, 0xf5, 0x3e, 0xda,
- 0x92, 0xb3, 0x47, 0x89, 0xa8, 0xda, 0x04, 0xe0, 0xa6, 0xcd, 0xd5, 0x84, 0xd6, 0xd5, 0x6f, 0xa5, 0x30, 0x3f, 0xcc, 0x9e,
- 0xfe, 0xd5, 0xd6, 0xb8, 0x61, 0xf6, 0xb0, 0x10, 0x9d, 0x4d, 0x5c, 0x90, 0xc8, 0x05, 0x4d, 0xba, 0x99, 0x8e, 0xa7, 0xc8,
- 0x53, 0xe7, 0x5d, 0xd7, 0x37, 0xf3, 0x0b, 0xc9, 0x0f, 0x97, 0x2d, 0x3e, 0x22, 0xed, 0xdc, 0x28, 0x22, 0x32, 0x04, 0xc0,
- 0x6a, 0x38, 0xd8, 0xc8, 0x85, 0xef, 0x57, 0x9c, 0xa1, 0xe0, 0x0b, 0x7e, 0x6a, 0xb4, 0x5a, 0x76, 0x7c, 0xaf, 0x6f, 0x5d,
- 0xcc, 0x56, 0xef, 0x60, 0x3c, 0xce, 0x0f, 0x0a, 0x5e, 0xfa, 0xbb, 0xb6, 0xd8, 0xba, 0xda, 0x9d, 0xf5, 0x86, 0x55, 0xc2,
- 0x84, 0x9b, 0x3d, 0xc2, 0x54, 0x5b, 0xa9, 0x23, 0x57, 0xe1, 0x0a, 0x84, 0x7e, 0x3c, 0x52, 0x9c, 0x3d, 0x02, 0x9b, 0xb5,
- 0x9c, 0x50, 0xfb, 0xfc, 0x43, 0xf9, 0x07, 0x34, 0xd9, 0xad, 0x3f, 0x59, 0x44, 0x6b, 0x47, 0xa0, 0xb9, 0x29, 0x63, 0xfb,
- 0xd9, 0xd7, 0xfc, 0x62, 0xda, 0x23, 0x7e, 0x2b, 0xb6, 0x09, 0xfc, 0x52, 0x70, 0x77, 0xb9, 0x4d, 0x92, 0xdd, 0xf2, 0x82,
- 0x8c, 0xa3, 0xf5, 0x79, 0xf9, 0x21, 0xe8, 0x36, 0xea, 0xf5, 0xa7, 0x8c, 0x3c, 0x46, 0xab, 0x29, 0xdc, 0x91, 0xa8, 0x8e,
- 0xc5, 0xe7, 0xe5, 0x95, 0xd5, 0xca, 0xed, 0xad, 0x54, 0x24, 0xf2, 0xee, 0x40, 0x9c, 0x06, 0x08, 0x03, 0x36, 0x0a, 0x73,
- 0xa4, 0xcb, 0xbb, 0x28, 0x83, 0x28, 0x66, 0xc3, 0x79, 0xba, 0x7a, 0x76, 0x90, 0x10, 0x88, 0x04, 0x3f, 0x0f, 0x67, 0xd2,
- 0x53, 0xab, 0x63, 0xc7, 0x83, 0xc9, 0x2b, 0xdd, 0x9c, 0x61, 0x99, 0xe4, 0x12, 0x18, 0xc6, 0x9a, 0x9d, 0x3c, 0xea, 0x13,
- 0x87, 0x32, 0x57, 0x8d, 0x01, 0x11, 0x39, 0x56, 0x94, 0xb2, 0x4d, 0x73, 0xc0, 0xdc, 0x2d, 0x4c, 0xb3, 0xd1, 0x90, 0x36,
- 0xd8, 0xae, 0xd3, 0x06, 0xd7, 0x70, 0xa5, 0xd6, 0x0e, 0x64, 0xf8, 0x80, 0xb6, 0x36, 0x0c, 0x31, 0xd3, 0xcc, 0x46, 0xba,
- 0xb4, 0x14, 0xb4, 0xcb, 0x43, 0x68, 0x0f, 0x8d, 0xf7, 0x2c, 0x61, 0xf4, 0xfb, 0xce, 0xf1, 0xaf, 0xe9, 0x2e, 0x52, 0x02,
- 0x29, 0x5e, 0xd7, 0xc6, 0xed, 0xf6, 0x22, 0xb9, 0x7b, 0xe8, 0x1a, 0xe6, 0x59, 0xdb, 0x43, 0xdd, 0x58, 0xe2, 0x50, 0xab,
- 0x57, 0x01, 0xf0, 0x61, 0xb0, 0x83, 0xa9, 0x40, 0x0c, 0x24, 0x08, 0x6e, 0x95, 0x45, 0xba, 0xb3, 0x02, 0xa9, 0x41, 0xde,
- 0xaf, 0xc2, 0x4c, 0xc2, 0x71, 0x1e, 0x86, 0xe4, 0xe9, 0x81, 0x9e, 0xdf, 0xea, 0x11, 0x66, 0x91, 0x02, 0x8c, 0xf5, 0xa3,
- 0x05, 0xe3, 0xe9, 0x6e, 0x7f, 0x34, 0xb5, 0x0a, 0x3f, 0xc3, 0x70, 0x18, 0x33, 0x33, 0x7e, 0x85, 0x81, 0x04, 0x1f, 0xaa,
- 0x14, 0x0c, 0x57, 0xca, 0x41, 0x97, 0x79, 0x62, 0x2e, 0x99, 0xbc, 0x6f, 0xce, 0x21, 0xad, 0xde, 0x7d, 0x74, 0x73, 0x3f,
- 0x75, 0x00, 0x65, 0xc2, 0x40, 0x5e, 0xda, 0xce, 0x41, 0x4e, 0x8b, 0xd0, 0x32, 0x4f, 0x7f, 0xee, 0xbe, 0xc9, 0x41, 0xb2,
- 0x42, 0xe9, 0x5a, 0xe5, 0xee, 0x18, 0x0c, 0x70, 0x93, 0xec, 0xb2, 0x46, 0xcd, 0x11, 0x16, 0x31, 0x81, 0x33, 0x5e, 0x82,
- 0x20, 0x85, 0x1b, 0x02, 0x76, 0xeb, 0x13, 0xb9, 0xd4, 0xbd, 0xf9, 0xe7, 0xb5, 0x5e, 0x5e, 0x05, 0x48, 0x74, 0x27, 0xf2,
- 0xdc, 0x3e, 0x87, 0x8b, 0x33, 0x3f, 0x50, 0xb6, 0xc6, 0x52, 0xf8, 0x61, 0x69, 0x7e, 0x6b, 0x30, 0xef, 0x2c, 0x6c, 0x5e,
- 0x69, 0xc8, 0xba, 0x1e, 0x3d, 0x2a, 0x0c, 0x74, 0xbd, 0x93, 0xc9, 0x36, 0xcc, 0x72, 0x15, 0xe6, 0xbb, 0xd0, 0xc0, 0xe3,
- 0xaf, 0x60, 0xcd, 0x83, 0x54, 0x50, 0x67, 0xbb, 0x70, 0x2a, 0xa1, 0x51, 0x87, 0x9b, 0xc5, 0xe0, 0xbb, 0xa3, 0xb1, 0x6f,
- 0x3a, 0x1a, 0x62, 0x72, 0x6f, 0x89, 0x8a, 0x1d, 0xc4, 0x09, 0x55, 0xac, 0x67, 0x7b, 0xa3, 0xe6, 0xed, 0x4e, 0xbb, 0xf2,
- 0x5f, 0x42, 0x95, 0x7b, 0x95, 0x7a, 0xbe, 0x3e, 0xf5, 0x2f, 0xee, 0x5f, 0x30, 0x57, 0x51, 0x94, 0x7d, 0x45, 0xd5, 0xd7,
- 0x6e, 0xcc, 0xf6, 0x4d, 0xac, 0x7b, 0x51, 0x70, 0x32, 0x07, 0x1c, 0xaf, 0x97, 0xdd, 0x92, 0x0d, 0x9d, 0xba, 0x53, 0xf5,
- 0x49, 0xc7, 0xa5, 0x6a, 0x7a, 0x3b, 0xb0, 0x3f, 0x0c, 0x01, 0xa5, 0x00, 0x4a, 0x33, 0x90, 0xf7, 0xee, 0x0a, 0x12, 0x5d,
- 0xc0, 0x5d, 0xb1, 0x85, 0x63, 0xed, 0xcf, 0xb8, 0x84, 0xde, 0x51, 0x8f, 0xd9, 0xf4, 0x15, 0x76, 0x43, 0xc4, 0xfe, 0x89,
- 0x16, 0xfe, 0x13, 0x92, 0xbd, 0x25, 0x66, 0xb9, 0x56, 0x60, 0x1f, 0x85, 0x3d, 0xc6, 0x9a, 0x02, 0xc4, 0x2a, 0xbf, 0x8b,
- 0x1b, 0xf1, 0x41, 0xbb, 0x37, 0x77, 0xe1, 0x18, 0xa7, 0x5f, 0x2a, 0x30, 0x37, 0xf6, 0xf4, 0x2a, 0x4b, 0x77, 0xf8, 0x15,
- 0xc5, 0xb9, 0xb5, 0xdd, 0x93, 0x4f, 0x59, 0x97, 0x6b, 0xf2, 0xe8, 0x6e, 0xf5, 0x7e, 0x21, 0x20, 0x64, 0xac, 0xe8, 0x8d,
- 0x60, 0xcb, 0xd2, 0xdc, 0xa7, 0xc8, 0x16, 0xb2, 0x7c, 0xf3, 0xbe, 0x88, 0x5b, 0x75, 0xcb, 0xf7, 0x38, 0x79, 0xa5, 0x32,
- 0x5f, 0xa7, 0xf2, 0xfd, 0x6a, 0x21, 0x71, 0x16, 0x1b, 0xe9, 0xde, 0xd9, 0x88, 0xf2, 0x89, 0xef, 0x4f, 0x9a, 0xc4, 0x9b,
- 0x04, 0xa0, 0x16, 0xab, 0x39, 0x62, 0x3f, 0x1f, 0x06, 0x2a, 0x88, 0x04, 0x68, 0x63, 0xb1, 0x21, 0x87, 0x25, 0xfb, 0xc3,
- 0xb5, 0xe0, 0xc8, 0x48, 0x42, 0x4e, 0x3a, 0xc9, 0x90, 0x4c, 0xc1, 0xa5, 0x69, 0x62, 0xd6, 0x25, 0xdc, 0xc9, 0x51, 0xeb,
- 0x6f, 0x00, 0x70, 0x91, 0x86, 0x57, 0x36, 0x23, 0x1f, 0x29, 0x8b, 0x52, 0xb2, 0x31, 0xd5, 0x8d, 0xc5, 0xa3, 0x5f, 0xd3,
- 0x7a, 0xe4, 0x2e, 0x3a
-};
-
-/* Random data for hash agility attribute */
-uint8_t attribute[32] = {
- 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab, 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3,
- 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,
- 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, 0x6d,
- 0x30, 0x82, 0x03, 0x69, 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, 0x9a,
- 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, 0x35, 0x31, 0x31, 0x30,
- 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab,
- 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0,
- 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00,
- 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d,
- 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb,
- 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d,
- 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b,
- 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab,
- 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a,
- 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88,
- 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57,
- 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac,
- 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5,
- 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55,
- 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d,
- 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1,
- 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35,
- 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab,
- 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6,
- 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83,
- 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36,
- 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78,
- 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad,
- 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88,
- 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93,
- 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d,
- 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59,
- 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0,
- 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d,
- 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c,
- 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4,
- 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05,
- 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c,
- 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69,
- 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
-};
-
-/*
- * Invalid CMS message on content with hash agility attribute.
- * Only the hash agility attribute value has been changed from the valid message.
- */
-uint8_t invalid_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, 0x6d,
- 0x30, 0x82, 0x03, 0x69, 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, 0x9a,
- 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, 0x35, 0x31, 0x31, 0x30,
- 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd0, 0x8f, 0xfd, 0xab,
- 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0,
- 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00,
- 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d,
- 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb,
- 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d,
- 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b,
- 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab,
- 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a,
- 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88,
- 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57,
- 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac,
- 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5,
- 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55,
- 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d,
- 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1,
- 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35,
- 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab,
- 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6,
- 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83,
- 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36,
- 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78,
- 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad,
- 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88,
- 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93,
- 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d,
- 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59,
- 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0,
- 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d,
- 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c,
- 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4,
- 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05,
- 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c,
- 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69,
- 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
-};
-
-/* Valid CMS message with no hash agility attribute */
-unsigned char valid_no_attr[] = {
- 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, 0x3b,
- 0x30, 0x82, 0x03, 0x37, 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, 0x69, 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, 0x35, 0x31, 0x31, 0x30, 0x34,
- 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xbc, 0x5a, 0x74, 0xac, 0x24,
- 0x13, 0xa5, 0xa3, 0xfb, 0x61, 0xfb, 0x19, 0x7a, 0x3f, 0x7b, 0x46, 0x5a, 0xcd, 0x8a, 0x92, 0x23,
- 0xeb, 0xd0, 0xdf, 0xf2, 0x05, 0xbe, 0x02, 0xf9, 0xd5, 0x81, 0xca, 0x16, 0xf9, 0xd9, 0x63, 0x9e,
- 0x19, 0xb8, 0xea, 0x1d, 0x51, 0x2c, 0xfc, 0x65, 0x0c, 0x67, 0x31, 0x5d, 0xa2, 0x87, 0x40, 0xa2,
- 0x58, 0x57, 0x35, 0xe1, 0xa2, 0xc8, 0x25, 0xe4, 0x79, 0xd1, 0xc2, 0x76, 0x26, 0x20, 0x11, 0x76,
- 0x38, 0xc8, 0xa1, 0x08, 0x98, 0x7c, 0x28, 0x8a, 0x14, 0x23, 0x89, 0xfa, 0xe6, 0x55, 0xaf, 0x47,
- 0x1f, 0xe8, 0x5c, 0xc4, 0x0b, 0x88, 0x27, 0x75, 0xf5, 0x2d, 0x2c, 0x63, 0x63, 0x7b, 0xd3, 0x2b,
- 0xd2, 0xb1, 0x4d, 0xf5, 0xd3, 0xa9, 0xdc, 0xc1, 0x34, 0x9d, 0xb8, 0x44, 0xae, 0xa3, 0x41, 0xd7,
- 0x1e, 0x02, 0xff, 0x06, 0x3d, 0x8b, 0x3b, 0x01, 0xc6, 0xa9, 0x0f, 0x7a, 0x59, 0x03, 0x05, 0x2a,
- 0xcf, 0x19, 0xc1, 0xd2, 0xea, 0x30, 0x3f, 0xbd, 0x83, 0x80, 0x26, 0xd7, 0x73, 0x32, 0x00, 0x8d,
- 0x4f, 0x69, 0xaa, 0xf0, 0x39, 0x3f, 0xae, 0x46, 0xfc, 0x19, 0x7e, 0x62, 0xd2, 0xc8, 0x59, 0xa2,
- 0xd1, 0x23, 0xa2, 0xab, 0xdd, 0x5b, 0xbc, 0xa9, 0x4d, 0x8c, 0x3a, 0xa4, 0x9d, 0x8e, 0x80, 0x0c,
- 0x2b, 0x2d, 0x26, 0x27, 0xb7, 0xf2, 0xb9, 0x19, 0xc5, 0x8e, 0x17, 0x44, 0xb2, 0x19, 0x29, 0x3b,
- 0x25, 0x7e, 0x76, 0xf8, 0x97, 0x85, 0xbc, 0x78, 0xa4, 0x41, 0xcb, 0x10, 0xed, 0xd7, 0x8c, 0x4c,
- 0x56, 0x44, 0xfc, 0x7c, 0xa8, 0x98, 0xff, 0xa5, 0xef, 0x21, 0xe4, 0xc2, 0x2b, 0xaf, 0xfb, 0xb2,
- 0xcb, 0x4c, 0x63, 0x19, 0x53, 0xae, 0xc4, 0xbc, 0x44, 0x31, 0xcb, 0x06, 0x2f, 0x01, 0x2b, 0x6b,
- 0x7e, 0xd8, 0x24, 0x76, 0x16, 0x74, 0xa5, 0xb2, 0x46, 0xff, 0x14, 0xde, 0xc8, 0xe5, 0xfc, 0xeb,
- 0xfa, 0xb8, 0xc2, 0x39, 0x9d, 0xf6, 0xdd, 0xbb, 0xba, 0x7d, 0x2d, 0x49, 0x4c, 0x7d, 0x87, 0xe2,
- 0x0a, 0xb7, 0x52, 0xb5, 0x3d, 0x9d, 0x02, 0xf2, 0x04, 0x3d, 0x9b, 0x8b, 0x04, 0xe8, 0x84, 0x50,
- 0x19, 0xb7, 0xfa, 0x4f, 0x9f, 0xa6, 0x00, 0x06, 0x2a, 0x44, 0xb2, 0x58, 0x91, 0x2f, 0xde, 0xd6,
- 0x25, 0xcc, 0xd5, 0x68, 0x04, 0x51, 0xb1, 0x0f, 0x08, 0x41, 0xdd, 0xea, 0x16, 0x70, 0xbd, 0x5a,
- 0xbc, 0x05, 0x60, 0xbc, 0xd4, 0x67, 0x62, 0xe2, 0xc3, 0xc0, 0x79, 0xdf, 0x49, 0xd7, 0x52, 0x62,
- 0xde, 0xce, 0x68, 0x5c, 0x32, 0x9b, 0xd3, 0xb8, 0xef, 0x62, 0x7b, 0x4b, 0x0e, 0x15, 0xae, 0x92,
- 0xfb, 0x06, 0x36, 0xb9, 0x05, 0x72, 0x2f, 0x01, 0x55, 0x70, 0x2b, 0x09, 0x54, 0xe1, 0x70, 0x15,
- 0xab, 0x24, 0xcb, 0x07, 0x4c, 0x7e, 0xde, 0x38, 0xb2, 0x03, 0x56, 0xdb, 0x2f, 0x8c, 0x3b, 0xe5,
- 0x5e, 0x1a, 0xbb, 0x90, 0x08, 0x55, 0xb2, 0x3d, 0xd9, 0x6f, 0xe8, 0x81, 0x08, 0x04, 0x5e, 0x82,
- 0x84, 0x7e, 0x9c, 0x3f, 0x5a, 0x66, 0x6f, 0x6c, 0xc6, 0x98, 0x82, 0x27, 0xb6, 0x49, 0x7b, 0x14,
- 0x07, 0x9d, 0x20, 0x61, 0x9d, 0xd9, 0x3d, 0xd0, 0x71, 0x0c, 0x72, 0x82, 0x50, 0xac, 0x61, 0xcd,
- 0xc5, 0xc6, 0xc9, 0x90, 0xe2, 0x92, 0x5b, 0x02, 0x73, 0xda, 0x98, 0x2e, 0x21, 0x1e, 0x66, 0x79,
- 0x83, 0x2e, 0x1d, 0x66, 0x0e, 0x2b, 0x6d, 0x42, 0x7d, 0xf4, 0x0a, 0xd3, 0xa1, 0x9b, 0x7f, 0x61,
- 0xa7, 0x13, 0x3a, 0xa4, 0x6e, 0x0d, 0x0b, 0xbf, 0x42, 0x32, 0xf7, 0xca, 0x0e, 0x96, 0x0a, 0xcb,
- 0x9a, 0x0a, 0x6a, 0x24, 0x8c, 0x43, 0x76, 0x0e, 0xa8, 0x71, 0xcd, 0x3f, 0xc4, 0x85, 0x46, 0x50,
- 0xb9, 0x65, 0x43, 0x49, 0xae, 0x31, 0x25, 0x76, 0x4b, 0xfb, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
- 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 */
+++ /dev/null
-/*
- * 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 <AssertMacros.h>
-#include <Foundation/Foundation.h>
-
-#include <regressions/test/testmore.h>
-#include <Security/SecBase.h>
-#include <utilities/SecCFRelease.h>
-#include <Security/CMSEncoder.h>
-#include <Security/SecImportExport.h>
-#include <Security/CMSPrivate.h>
-#include <Security/SecCertificatePriv.h>
-#include <Security/SecTrust.h>
-#include <Security/SecPolicy.h>
-#include <Security/SecKeychain.h>
-#include <Security/SecIdentity.h>
-
-#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;
-}
#include <regressions/test/testmore.h>
-ONE_TEST(cms_hash_agility_test)
ONE_TEST(cms_trust_settings_test)
errSecCSBadDiskImageFormat = -67001, /* disk image format unrecognized, invalid, or unsuitable */
errSecCSUnsupportedDigestAlgorithm = -67000, /* a requested signature digest algorithm is not supported */
errSecCSInvalidAssociatedFileData = -66999, /* resource fork, Finder information, or similar detritus not allowed */
- errSecCSInvalidTeamIdentifier = -66998, /* a Team Identifier string is invalid */
- errSecCSBadTeamIdentifier = -66997, /* a Team Identifier is wrong or inappropriate */
- errSecCSSignatureUntrusted = -66996, /* signature is valid but signer is not trusted */
+ errSecCSInvalidTeamIdentifier = -66998, /* a Team Identifier string is invalid */
+ errSecCSBadTeamIdentifier = -66997, /* a Team Identifier is wrong or inappropriate */
+ errSecCSSignatureUntrusted = -66996, /* signature is valid but signer is not trusted */
errSecMultipleExecSegments = -66995, /* the image contains multiple executable segments */
errSecCSInvalidEntitlements = -66994, /* invalid entitlement plist */
- errSecCSInvalidRuntimeVersion = -66993, /* an invalid runtime version was explicitly set */
+ errSecCSInvalidRuntimeVersion = -66993, /* an invalid runtime version was explicitly set */
+ errSecCSRevokedNotarization = -66992, /* notarization indicates this code has been revoked */
};
/*
This bit can only be set. Code that has the kill flag set will never be dynamically invalid
(and live). Note however that a change in static validity does not necessarily trigger instant
death.
+
+ @constant kSecCodeStatusDebugged
+ Indicated that code has been debugged by another process that was allowed to do so. The debugger
+ causes this to be set when it attachs.
+
+ @constant kSecCodeStatusPlatform
+ Indicates the code is platform code, shipping with the operating system and signed by Apple.
*/
typedef CF_OPTIONS(uint32_t, SecCodeStatus) {
- kSecCodeStatusValid = 0x0001,
- kSecCodeStatusHard = 0x0100,
- kSecCodeStatusKill = 0x0200,
+ kSecCodeStatusValid = 0x00000001,
+ kSecCodeStatusHard = 0x00000100,
+ kSecCodeStatusKill = 0x00000200,
+ kSecCodeStatusDebugged = 0x10000000,
+ kSecCodeStatusPlatform = 0x04000000,
};
kSecCodeSignatureHashSHA256 = 2, /* SHA-256 */
kSecCodeSignatureHashSHA256Truncated = 3, /* SHA-256 truncated to first 20 bytes */
kSecCodeSignatureHashSHA384 = 4, /* SHA-384 */
+ kSecCodeSignatureHashSHA512 = 5, /* SHA-512 */
};
CF_ASSUME_NONNULL_END
#include "cskernel.h"
#include <security_utilities/cfmunge.h>
#include <security_utilities/debugging.h>
+#include "SecInternalReleasePriv.h"
namespace Security {
namespace CodeSigning {
myDisk->diskRep()->strictValidate(myDisk->codeDirectory(), DiskRep::ToleratedErrors(), flags);
// check my own dynamic state
- if (!(this->host()->getGuestStatus(this) & kSecCodeStatusValid))
- MacOSError::throwMe(errSecCSGuestInvalid);
-
+ SecCodeStatus dynamic_status = this->host()->getGuestStatus(this);
+ bool isValid = (dynamic_status & kSecCodeStatusValid) != 0;
+ if (!isValid) {
+ bool isDebugged = (dynamic_status & kSecCodeStatusDebugged) != 0;
+ bool isPlatform = (dynamic_status & kSecCodeStatusPlatform) != 0;
+ bool isInternal = SecIsInternalRelease();
+
+ if (!isDebugged || (isPlatform && !isInternal)) {
+ // fatal if the code is invalid and not being debugged, but
+ // never let platform code be debugged except on internal systems.
+ MacOSError::throwMe(errSecCSGuestInvalid);
+ }
+ }
+
// check that static and dynamic views are consistent
if (this->cdHash() && !CFEqual(this->cdHash(), myDisk->cdHash()))
MacOSError::throwMe(errSecCSStaticCodeChanged);
}
state.mRuntimeVersionOverride = parseRuntimeVersion(runtime);
}
+ state.mPreserveAFSC = getBool(kSecCodeSignerPreserveAFSC);
}
bool mNoTimeStampCerts; // don't request certificates with timestamping request
LimitedAsync *mLimitedAsync; // limited async workers for verification
uint32_t mRuntimeVersionOverride; // runtime Version Override
+ bool mPreserveAFSC; // preserve AFSC compression
};
"identifier",
"cdhash",
"platform",
+ "notarized",
"anchor",
"apple",
"generic",
void RequirementLexer::initLiterals()
{
- literals["certificate"] = 25;
+ literals["certificate"] = 26;
literals["always"] = 15;
literals["host"] = 6;
literals["guest"] = 5;
literals["cdhash"] = 20;
- literals["entitlement"] = 29;
+ literals["entitlement"] = 30;
literals["library"] = 8;
literals["never"] = 17;
- literals["cert"] = 26;
+ literals["cert"] = 27;
literals["plugin"] = 9;
literals["or"] = 10;
- literals["leaf"] = 42;
- literals["info"] = 28;
+ literals["leaf"] = 43;
+ literals["info"] = 29;
literals["designated"] = 7;
- literals["apple"] = 23;
- literals["trusted"] = 27;
+ literals["apple"] = 24;
+ literals["trusted"] = 28;
literals["true"] = 16;
+ literals["notarized"] = 22;
literals["and"] = 11;
- literals["root"] = 43;
+ literals["root"] = 44;
literals["platform"] = 21;
- literals["anchor"] = 22;
+ literals["anchor"] = 23;
literals["false"] = 18;
- literals["generic"] = 24;
+ literals["generic"] = 25;
literals["identifier"] = 19;
- literals["exists"] = 30;
+ literals["exists"] = 31;
}
antlr::RefToken RequirementLexer::nextToken()
const unsigned long RequirementLexer::_tokenSet_2_data_[] = { 4294967295UL, 4294967291UL, 4026531839UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
// 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10
// 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e
-// 0x1f ! # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9
+// 0x1f ! # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 :
const antlr::BitSet RequirementLexer::_tokenSet_2(_tokenSet_2_data_,8);
const unsigned long RequirementLexer::_tokenSet_3_data_[] = { 4294966271UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
// 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xd 0xe 0xf 0x10 0x11
// 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f
-// ! \" # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9
+// ! \" # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 :
const antlr::BitSet RequirementLexer::_tokenSet_3(_tokenSet_3_data_,8);
const unsigned long RequirementLexer::_tokenSet_4_data_[] = { 4294967295UL, 4294934527UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
// 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10
// 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e
-// 0x1f ! \" # $ % & \' ( ) * + , - . 0 1 2 3 4 5 6 7 8 9
+// 0x1f ! \" # $ % & \' ( ) * + , - . 0 1 2 3 4 5 6 7 8 9 :
const antlr::BitSet RequirementLexer::_tokenSet_4(_tokenSet_4_data_,8);
const unsigned long RequirementLexer::_tokenSet_5_data_[] = { 4294967295UL, 4294966271UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
// 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10
// 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e
-// 0x1f ! \" # $ % & \' ( ) + , - . / 0 1 2 3 4 5 6 7 8 9
+// 0x1f ! \" # $ % & \' ( ) + , - . / 0 1 2 3 4 5 6 7 8 9 :
const antlr::BitSet RequirementLexer::_tokenSet_5(_tokenSet_5_data_,8);
ANTLR_END_NAMESPACE
case LITERAL_identifier:
case LITERAL_cdhash:
case LITERAL_platform:
+ case LITERAL_notarized:
case LITERAL_anchor:
case LITERAL_certificate:
case LITERAL_cert:
maker.platform(ident);
break;
}
+ case LITERAL_notarized:
+ {
+ match(LITERAL_notarized);
+ maker.put(opNotarized);
+ break;
+ }
default:
if ((LA(1) == LPAREN) && (_tokenSet_8.member(LA(2)))) {
match(LPAREN);
"\"identifier\"",
"\"cdhash\"",
"\"platform\"",
+ "\"notarized\"",
"\"anchor\"",
"\"apple\"",
"\"generic\"",
const unsigned long RequirementParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL };
// EOF
const antlr::BitSet RequirementParser::_tokenSet_0(_tokenSet_0_data_,4);
-const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 131072UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 262144UL, 0UL, 0UL };
// "guest" "host" "designated" "library" "plugin" INTEGER
const antlr::BitSet RequirementParser::_tokenSet_1(_tokenSet_1_data_,4);
const unsigned long RequirementParser::_tokenSet_2_data_[] = { 16UL, 0UL, 0UL, 0UL };
// ARROW
const antlr::BitSet RequirementParser::_tokenSet_2(_tokenSet_2_data_,4);
-const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 131072UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 262144UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" INTEGER
const antlr::BitSet RequirementParser::_tokenSet_3(_tokenSet_3_data_,4);
-const unsigned long RequirementParser::_tokenSet_4_data_[] = { 2281713650UL, 512129UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_4_data_[] = { 268447730UL, 1024259UL, 0UL, 0UL };
// EOF ARROW "guest" "host" "designated" "library" "plugin" "or" "and"
// RPAREN "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
// INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_4(_tokenSet_4_data_,4);
-const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 393216UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 786432UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" RPAREN INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_5(_tokenSet_5_data_,4);
-const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 393216UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 786432UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_6(_tokenSet_6_data_,4);
-const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 393216UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 786432UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" "or" RPAREN INTEGER
// SEMI
const antlr::BitSet RequirementParser::_tokenSet_7(_tokenSet_7_data_,4);
-const unsigned long RequirementParser::_tokenSet_8_data_[] = { 914345984UL, 0UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_8_data_[] = { 1828704256UL, 0UL, 0UL, 0UL };
// LPAREN NOT "always" "true" "never" "false" "identifier" "cdhash" "platform"
-// "anchor" "certificate" "cert" "info" "entitlement"
+// "notarized" "anchor" "certificate" "cert" "info" "entitlement"
const antlr::BitSet RequirementParser::_tokenSet_8(_tokenSet_8_data_,4);
-const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 393216UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 786432UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
// INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_9(_tokenSet_9_data_,4);
-const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 134656UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 269312UL, 0UL, 0UL };
// NEG "leaf" "root" INTEGER
const antlr::BitSet RequirementParser::_tokenSet_10(_tokenSet_10_data_,4);
-const unsigned long RequirementParser::_tokenSet_11_data_[] = { 2147483648UL, 118913UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_11_data_[] = { 0UL, 237827UL, 0UL, 0UL };
// EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
const antlr::BitSet RequirementParser::_tokenSet_11(_tokenSet_11_data_,4);
-const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 249856UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 499712UL, 0UL, 0UL };
// HASHCONSTANT DOTKEY STRING PATHNAME INTEGER
const antlr::BitSet RequirementParser::_tokenSet_12(_tokenSet_12_data_,4);
-const unsigned long RequirementParser::_tokenSet_13_data_[] = { 2281701376UL, 118913UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_13_data_[] = { 268435456UL, 237827UL, 0UL, 0UL };
// "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
const antlr::BitSet RequirementParser::_tokenSet_13(_tokenSet_13_data_,4);
-const unsigned long RequirementParser::_tokenSet_14_data_[] = { 1073754082UL, 512000UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_14_data_[] = { 2147495906UL, 1024000UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
// "exists" HASHCONSTANT DOTKEY STRING PATHNAME INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_14(_tokenSet_14_data_,4);
-const unsigned long RequirementParser::_tokenSet_15_data_[] = { 3221237730UL, 393341UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_15_data_[] = { 2147495906UL, 786683UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
// "exists" EQL EQQL SUBS LESS GT LE GE INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_15(_tokenSet_15_data_,4);
-const unsigned long RequirementParser::_tokenSet_16_data_[] = { 12258UL, 393218UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_16_data_[] = { 12258UL, 786436UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
// STAR INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_16(_tokenSet_16_data_,4);
-const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 393474UL, 0UL, 0UL };
+const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 786948UL, 0UL, 0UL };
// EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
// STAR RBRACK INTEGER SEMI
const antlr::BitSet RequirementParser::_tokenSet_17(_tokenSet_17_data_,4);
private:
static const char* tokenNames[];
#ifndef NO_STATIC_CONSTS
- static const int NUM_TOKENS = 58;
+ static const int NUM_TOKENS = 59;
#else
enum {
- NUM_TOKENS = 58
+ NUM_TOKENS = 59
};
#endif
LITERAL_identifier = 19,
LITERAL_cdhash = 20,
LITERAL_platform = 21,
- LITERAL_anchor = 22,
- LITERAL_apple = 23,
- LITERAL_generic = 24,
- LITERAL_certificate = 25,
- LITERAL_cert = 26,
- LITERAL_trusted = 27,
- LITERAL_info = 28,
- LITERAL_entitlement = 29,
- LITERAL_exists = 30,
- EQL = 31,
- EQQL = 32,
- STAR = 33,
- SUBS = 34,
- LESS = 35,
- GT = 36,
- LE = 37,
- GE = 38,
- LBRACK = 39,
- RBRACK = 40,
- NEG = 41,
- LITERAL_leaf = 42,
- LITERAL_root = 43,
- HASHCONSTANT = 44,
- HEXCONSTANT = 45,
- DOTKEY = 46,
- STRING = 47,
- PATHNAME = 48,
- INTEGER = 49,
- SEMI = 50,
- IDENT = 51,
- HEX = 52,
- COMMA = 53,
- WS = 54,
- SHELLCOMMENT = 55,
- C_COMMENT = 56,
- CPP_COMMENT = 57,
+ LITERAL_notarized = 22,
+ LITERAL_anchor = 23,
+ LITERAL_apple = 24,
+ LITERAL_generic = 25,
+ LITERAL_certificate = 26,
+ LITERAL_cert = 27,
+ LITERAL_trusted = 28,
+ LITERAL_info = 29,
+ LITERAL_entitlement = 30,
+ LITERAL_exists = 31,
+ EQL = 32,
+ EQQL = 33,
+ STAR = 34,
+ SUBS = 35,
+ LESS = 36,
+ GT = 37,
+ LE = 38,
+ GE = 39,
+ LBRACK = 40,
+ RBRACK = 41,
+ NEG = 42,
+ LITERAL_leaf = 43,
+ LITERAL_root = 44,
+ HASHCONSTANT = 45,
+ HEXCONSTANT = 46,
+ DOTKEY = 47,
+ STRING = 48,
+ PATHNAME = 49,
+ INTEGER = 50,
+ SEMI = 51,
+ IDENT = 52,
+ HEX = 53,
+ COMMA = 54,
+ WS = 55,
+ SHELLCOMMENT = 56,
+ C_COMMENT = 57,
+ CPP_COMMENT = 58,
NULL_TREE_LOOKAHEAD = 3
};
#ifdef __cplusplus
LITERAL_identifier="identifier"=19
LITERAL_cdhash="cdhash"=20
LITERAL_platform="platform"=21
-LITERAL_anchor="anchor"=22
-LITERAL_apple="apple"=23
-LITERAL_generic="generic"=24
-LITERAL_certificate="certificate"=25
-LITERAL_cert="cert"=26
-LITERAL_trusted="trusted"=27
-LITERAL_info="info"=28
-LITERAL_entitlement="entitlement"=29
-LITERAL_exists="exists"=30
-EQL=31
-EQQL=32
-STAR=33
-SUBS=34
-LESS=35
-GT=36
-LE=37
-GE=38
-LBRACK=39
-RBRACK=40
-NEG=41
-LITERAL_leaf="leaf"=42
-LITERAL_root="root"=43
-HASHCONSTANT=44
-HEXCONSTANT=45
-DOTKEY=46
-STRING=47
-PATHNAME=48
-INTEGER=49
-SEMI=50
-IDENT=51
-HEX=52
-COMMA=53
-WS=54
-SHELLCOMMENT=55
-C_COMMENT=56
-CPP_COMMENT=57
+LITERAL_notarized="notarized"=22
+LITERAL_anchor="anchor"=23
+LITERAL_apple="apple"=24
+LITERAL_generic="generic"=25
+LITERAL_certificate="certificate"=26
+LITERAL_cert="cert"=27
+LITERAL_trusted="trusted"=28
+LITERAL_info="info"=29
+LITERAL_entitlement="entitlement"=30
+LITERAL_exists="exists"=31
+EQL=32
+EQQL=33
+STAR=34
+SUBS=35
+LESS=36
+GT=37
+LE=38
+GE=39
+LBRACK=40
+RBRACK=41
+NEG=42
+LITERAL_leaf="leaf"=43
+LITERAL_root="root"=44
+HASHCONSTANT=45
+HEXCONSTANT=46
+DOTKEY=47
+STRING=48
+PATHNAME=49
+INTEGER=50
+SEMI=51
+IDENT=52
+HEX=53
+COMMA=54
+WS=55
+SHELLCOMMENT=56
+C_COMMENT=57
+CPP_COMMENT=58
CFStringRef kSecAssessmentAssessmentFromCache = CFSTR("assessment:authority:cached");
CFStringRef kSecAssessmentAssessmentWeakSignature = CFSTR("assessment:authority:weak");
CFStringRef kSecAssessmentAssessmentCodeSigningError = CFSTR("assessment:cserror");
+CFStringRef kSecAssessmentAssessmentNotarizationDate = CFSTR("assessment:notarization-date");
CFStringRef kDisabledOverride = CFSTR("security disabled");
END_CSAPI_ERRORS1(NULL)
}
+static void
+updateAuthority(const char *authority, bool enable, CFErrorRef *errors)
+{
+ CFStringRef updateValue = enable ? kSecAssessmentUpdateOperationEnable : kSecAssessmentUpdateOperationDisable;
+ CFTemp<CFDictionaryRef> ctx("{%O=%s, %O=%O}", kSecAssessmentUpdateKeyLabel, authority, kSecAssessmentContextKeyUpdate, updateValue);
+ SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors);
+}
+
//
// The fcntl of System Policies.
result = kCFBooleanTrue;
return true;
} else if (CFEqual(control, CFSTR("ui-enable-devid"))) {
- CFTemp<CFDictionaryRef> ctx("{%O=%s, %O=%O}", kSecAssessmentUpdateKeyLabel, "Developer ID", kSecAssessmentContextKeyUpdate, kSecAssessmentUpdateOperationEnable);
- SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors);
+ updateAuthority("Developer ID", true, errors);
+ updateAuthority("Notarized Developer ID", true, errors);
MessageTrace trace("com.apple.security.assessment.state", "enable-devid");
trace.send("enable Developer ID approval");
return true;
} else if (CFEqual(control, CFSTR("ui-disable-devid"))) {
- CFTemp<CFDictionaryRef> ctx("{%O=%s, %O=%O}", kSecAssessmentUpdateKeyLabel, "Developer ID", kSecAssessmentContextKeyUpdate, kSecAssessmentUpdateOperationDisable);
- SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors);
+ updateAuthority("Developer ID", false, errors);
MessageTrace trace("com.apple.security.assessment.state", "disable-devid");
trace.send("disable Developer ID approval");
return true;
else
result = kCFBooleanTrue;
return true;
+ } else if (CFEqual(control, CFSTR("ui-enable-notarized"))) {
+ updateAuthority("Notarized Developer ID", true, errors);
+ MessageTrace trace("com.apple.security.assessment.state", "enable-notarized");
+ trace.send("enable Notarized Developer ID approval");
+ return true;
+ } else if (CFEqual(control, CFSTR("ui-disable-notarized"))) {
+ updateAuthority("Notarized Developer ID", false, errors);
+ MessageTrace trace("com.apple.security.assessment.state", "disable-notarized");
+ trace.send("disable Notarized Developer ID approval");
+ return true;
+ } else if (CFEqual(control, CFSTR("ui-get-notarized"))) {
+ xpcEngineCheckNotarized((CFBooleanRef*)(arguments));
+ return true;
+ } else if (CFEqual(control, CFSTR("ui-get-notarized-local"))) {
+ CFBooleanRef &result = *(CFBooleanRef*)(arguments);
+ if (gEngine().value<int>("SELECT disabled FROM authority WHERE label = 'Notarized Developer ID';", true))
+ result = kCFBooleanFalse;
+ else
+ result = kCFBooleanTrue;
+ return true;
} else if (CFEqual(control, CFSTR("ui-record-reject"))) {
// send this through syspolicyd for update validation
xpcEngineRecord(CFDictionaryRef(arguments));
END_CSAPI_ERRORS1(false)
}
+
+Boolean SecAssessmentTicketRegister(CFDataRef ticketData, CFErrorRef *errors)
+{
+ BEGIN_CSAPI
+
+ xpcEngineTicketRegister(ticketData);
+ return true;
+
+ END_CSAPI_ERRORS1(false)
+}
+
+Boolean SecAssessmentTicketLookup(CFDataRef hash, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date, CFErrorRef *errors)
+{
+ BEGIN_CSAPI
+
+ xpcEngineTicketLookup(hash, hashType, flags, date);
+ return true;
+
+ END_CSAPI_ERRORS1(false)
+}
+
#define _H_SECASSESSMENT
#include <CoreFoundation/CoreFoundation.h>
+#include <Security/CSCommon.h>
#ifdef __cplusplus
extern "C" {
extern CFStringRef kSecAssessmentAssessmentAuthorityOverride; // (internal)
extern CFStringRef kSecAssessmentAssessmentAuthorityOriginalVerdict; // (internal)
extern CFStringRef kSecAssessmentAssessmentAuthorityFlags; // (internal)
+extern CFStringRef kSecAssessmentAssessmentNotarizationDate; // (internal)
extern CFStringRef kDisabledOverride; // AuthorityOverride value for "Gatekeeper is disabled"
*/
Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *errors);
+/*
+ * SecAssessmentTicket SPI
+ */
+typedef uint64_t SecAssessmentTicketFlags;
+enum {
+ kSecAssessmentTicketFlagDefault = 0, // default behavior, offline check
+ kSecAssessmentTicketFlagForceOnlineCheck = 1 << 0, // force an online check
+};
+Boolean SecAssessmentTicketRegister(CFDataRef ticketData, CFErrorRef *errors);
+Boolean SecAssessmentTicketLookup(CFDataRef hash, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date, CFErrorRef *errors);
#ifdef __cplusplus
}
const CFStringRef kSecCodeInfoCodeOffset = CFSTR("CodeOffset");
const CFStringRef kSecCodeInfoDiskRepInfo = CFSTR("DiskRepInfo");
const CFStringRef kSecCodeInfoResourceDirectory = CFSTR("ResourceDirectory");
+const CFStringRef kSecCodeInfoNotarizationDate = CFSTR("NotarizationDate");
/* DiskInfoRepInfo types */
const CFStringRef kSecCodeInfoDiskRepVersionPlatform = CFSTR("VersionPlatform");
extern const CFStringRef kSecCodeInfoCodeOffset; /* Internal */
extern const CFStringRef kSecCodeInfoDiskRepInfo; /* Internal */
extern const CFStringRef kSecCodeInfoResourceDirectory; /* Internal */
+extern const CFStringRef kSecCodeInfoNotarizationDate; /* Internal */
extern const CFStringRef kSecCodeInfoDiskRepVersionPlatform; /* Number */
extern const CFStringRef kSecCodeInfoDiskRepVersionMin; /* Number */
const CFStringRef kSecCodeSignerTeamIdentifier = CFSTR("teamidentifier");
const CFStringRef kSecCodeSignerPlatformIdentifier = CFSTR("platform-identifier");
const CFStringRef kSecCodeSignerRuntimeVersion = CFSTR("runtime-version");
+const CFStringRef kSecCodeSignerPreserveAFSC = CFSTR("preserve-afsc");
extern const CFStringRef kSecCodeSignerTeamIdentifier;
extern const CFStringRef kSecCodeSignerPlatformIdentifier;
extern const CFStringRef kSecCodeSignerRuntimeVersion;
+extern const CFStringRef kSecCodeSignerPreserveAFSC;
enum {
kSecCodeSignerPreserveIdentifier = 1 << 0, // preserve signing identifier
CFStringRef kSecRequirementKeyInfoPlist = CFSTR("requirement:eval:info");
CFStringRef kSecRequirementKeyEntitlements = CFSTR("requirement:eval:entitlements");
CFStringRef kSecRequirementKeyIdentifier = CFSTR("requirement:eval:identifier");
+CFStringRef kSecRequirementKeyPackageChecksum = CFSTR("requirement:eval:package_checksum");
+CFStringRef kSecRequirementKeyChecksumAlgorithm = CFSTR("requirement:eval:package_checksum_algorithm");
OSStatus SecRequirementEvaluate(SecRequirementRef requirementRef,
CFArrayRef certificateChain, CFDictionaryRef context,
const Requirement *req = SecRequirement::required(requirementRef)->requirement();
checkFlags(flags);
CodeSigning::Required(certificateChain);
-
+
+ SecCSDigestAlgorithm checksumAlgorithm = kSecCodeSignatureNoHash;
+ if (context) {
+ CFRef<CFNumberRef> num = (CFNumberRef)CFDictionaryGetValue(context, kSecRequirementKeyChecksumAlgorithm);
+ if (num) {
+ checksumAlgorithm = (SecCSDigestAlgorithm)cfNumber<uint32_t>(num);
+ }
+ }
+
Requirement::Context ctx(certificateChain, // mandatory
context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyInfoPlist)) : NULL,
context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyEntitlements)) : NULL,
(context && CFDictionaryGetValue(context, kSecRequirementKeyIdentifier)) ?
cfString(CFStringRef(CFDictionaryGetValue(context, kSecRequirementKeyIdentifier))) : "",
- NULL // can't specify a CodeDirectory here
+ NULL, // can't specify a CodeDirectory here
+ context ? CFDataRef(CFDictionaryGetValue(context, kSecRequirementKeyPackageChecksum)) : NULL,
+ checksumAlgorithm,
+ false // can't get forced platform this way
);
req->validate(ctx);
extern CFStringRef kSecRequirementKeyInfoPlist;
extern CFStringRef kSecRequirementKeyEntitlements;
extern CFStringRef kSecRequirementKeyIdentifier;
+extern CFStringRef kSecRequirementKeyPackageChecksum;
+extern CFStringRef kSecRequirementKeyChecksumAlgorithm;
/*!
@function SecRequirementEvaluate
Explicitly evaluate a SecRequirementRef against context provided in the call.
{
BEGIN_CSAPI
- checkFlags(flags);
- CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str())))->handle();
+ checkFlags(flags, kSecCSForceOnlineNotarizationCheck);
+ CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str()), flags))->handle();
END_CSAPI
}
{
BEGIN_CSAPI
- checkFlags(flags);
+ checkFlags(flags, kSecCSForceOnlineNotarizationCheck);
DiskRep::Context ctx;
std::string version; // holds memory placed into ctx
if (attributes) {
ctx.version = version.c_str();
}
- CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str(), &ctx)))->handle();
+ CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str(), &ctx), flags))->handle();
END_CSAPI
}
checkFlags(flags);
SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
if (const CodeDirectory *cd = code->codeDirectory(false)) {
- fsignatures args = { static_cast<off_t>(code->diskRep()->signingBase()), (void *)cd, cd->length() };
- UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args));
- } else
+ if (code->isDetached()) {
+ // Detached signatures need to attach their code directory from memory.
+ fsignatures args = { static_cast<off_t>(code->diskRep()->signingBase()), (void *)cd, cd->length() };
+ UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args));
+ } else {
+ // All other signatures can simply point to the signature in the main executable.
+ Universal *execImage = code->diskRep()->mainExecutableImage();
+ if (execImage == NULL) {
+ MacOSError::throwMe(errSecCSNoMainExecutable);
+ }
+
+ auto_ptr<MachO> arch(execImage->architecture());
+ if (arch.get() == NULL) {
+ MacOSError::throwMe(errSecCSNoMainExecutable);
+ }
+
+ size_t signatureOffset = arch->signingOffset();
+ size_t signatureLength = arch->signingLength();
+ if (signatureOffset == 0) {
+ MacOSError::throwMe(errSecCSUnsigned);
+ }
+
+ fsignatures args = {
+ static_cast<off_t>(code->diskRep()->signingBase()),
+ (void *)signatureOffset,
+ signatureLength,
+ };
+ UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDFILESIGS, &args));
+ }
+ } else {
MacOSError::throwMe(errSecCSUnsigned);
+ }
END_CSAPI
}
extern "C" {
#endif
+/*
+ Private SecStaticCodeCreate* SecCS flags.
+ */
+CF_ENUM(uint32_t) {
+ kSecCSForceOnlineNotarizationCheck = 1 << 0,
+};
+
/*
@function SecCodeSetCallback
#include "reqmaker.h"
#if TARGET_OS_OSX
#include "drmaker.h"
+#include "notarization.h"
#endif
#include "reqdumper.h"
#include "reqparser.h"
//
// Construct a SecStaticCode object given a disk representation object
//
-SecStaticCode::SecStaticCode(DiskRep *rep)
+SecStaticCode::SecStaticCode(DiskRep *rep, uint32_t flags)
: mCheckfix30814861builder1(NULL),
mRep(rep),
mValidated(false), mExecutableValidated(false), mResourcesValidated(false), mResourcesValidContext(NULL),
mProgressQueue("com.apple.security.validation-progress", false, QOS_CLASS_UNSPECIFIED),
mOuterScope(NULL), mResourceScope(NULL),
- mDesignatedReq(NULL), mGotResourceBase(false), mMonitor(NULL), mLimitedAsync(NULL)
+ mDesignatedReq(NULL), mGotResourceBase(false), mMonitor(NULL), mLimitedAsync(NULL),
+ mFlags(flags), mNotarizationChecked(false), mStaplingChecked(false), mNotarizationDate(NAN)
#if TARGET_OS_OSX
, mEvalDetails(NULL)
#else
return mSigningTimestamp;
}
+#if TARGET_OS_OSX
+#define kSecSHA256HashSize 32
+// subject:/C=US/ST=California/L=San Jose/O=Adobe Systems Incorporated/OU=Information Systems/OU=Digital ID Class 3 - Microsoft Software Validation v2/CN=Adobe Systems Incorporated
+// issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Code Signing 2010 CA
+// Not Before: Dec 15 00:00:00 2010 GMT
+// Not After : Dec 14 23:59:59 2012 GMT
+static const unsigned char ASI_CS_12[] = {
+ 0x77,0x82,0x9C,0x64,0x33,0x45,0x2E,0x4A,0xD3,0xA8,0xE4,0x6F,0x00,0x6C,0x27,0xEA,
+ 0xFB,0xD3,0xF2,0x6D,0x50,0xF3,0x6F,0xE0,0xE9,0x6D,0x06,0x59,0x19,0xB5,0x46,0xFF
+};
+
+bool SecStaticCode::checkfix41082220(OSStatus cssmTrustResult)
+{
+ // only applicable to revoked results
+ if (cssmTrustResult != CSSMERR_TP_CERT_REVOKED) {
+ return false;
+ }
+
+ // only this leaf certificate
+ if (CFArrayGetCount(mCertChain) == 0) {
+ return false;
+ }
+ CFRef<CFDataRef> leafHash(SecCertificateCopySHA256Digest((SecCertificateRef)CFArrayGetValueAtIndex(mCertChain, 0)));
+ if (memcmp(ASI_CS_12, CFDataGetBytePtr(leafHash), kSecSHA256HashSize) != 0) {
+ return false;
+ }
+
+ // detached dmg signature
+ if (!isDetached() || format() != std::string("disk image")) {
+ return false;
+ }
+
+ // sha-1 signed
+ if (hashAlgorithms().size() != 1 || hashAlgorithm() != kSecCodeSignatureHashSHA1) {
+ return false;
+ }
+
+ // not a privileged binary - no TeamID and no entitlements
+ if (component(cdEntitlementSlot) || teamID()) {
+ return false;
+ }
+
+ // no flags and old version
+ if (codeDirectory()->version != 0x20100 || codeDirectory()->flags != 0) {
+ return false;
+ }
+
+ Security::Syslog::warning("CodeSigning: Check-fix enabled for dmg '%s' with identifier '%s' signed with revoked certificates",
+ mainExecutablePath().c_str(), identifier().c_str());
+ return true;
+}
+#endif // TARGET_OS_OSX
//
// Verify the CMS signature.
continue; // retry validation while tolerating expiration
}
}
+ if (checkfix41082220(result)) {
+ break; // success
+ }
Security::Syslog::error("SecStaticCode: verification failed (trust result %d, error %d)", trustResult, (int)result);
MacOSError::throwMe(result);
}
this->infoDictionary(),
this->entitlements(),
this->identifier(),
- this->codeDirectory()
+ this->codeDirectory(),
+ NULL,
+ kSecCodeSignatureNoHash,
+ false
);
return DRMaker(context).make();
#else
bool result = false;
assert(req);
validateDirectory();
- result = req->validates(Requirement::Context(mCertChain, infoDictionary(), entitlements(), codeDirectory()->identifier(), codeDirectory()), failure);
+ result = req->validates(Requirement::Context(mCertChain, infoDictionary(), entitlements(), codeDirectory()->identifier(), codeDirectory(), NULL, kSecCodeSignatureNoHash, mRep->appleInternalForcePlatform()), failure);
return result;
}
if (CFRef<CFDictionaryRef> ddict = diskRepInformation())
CFDictionaryAddValue(dict, kSecCodeInfoDiskRepInfo, ddict);
} catch (...) { }
+ if (mNotarizationChecked && !isnan(mNotarizationDate)) {
+ CFRef<CFDateRef> date = CFDateCreate(NULL, mNotarizationDate);
+ if (date) {
+ CFDictionaryAddValue(dict, kSecCodeInfoNotarizationDate, date.get());
+ } else {
+ secerror("Error creating date from timestamp: %f", mNotarizationDate);
+ }
+ }
}
{
setValidationFlags(flags);
+#if TARGET_OS_OSX
+ if (!mStaplingChecked) {
+ mRep->registerStapledTicket();
+ mStaplingChecked = true;
+ }
+
+ if (mFlags & kSecCSForceOnlineNotarizationCheck) {
+ if (!mNotarizationChecked) {
+ if (this->cdHash()) {
+ bool is_revoked = checkNotarizationServiceForRevocation(this->cdHash(), (SecCSDigestAlgorithm)this->hashAlgorithm(), &mNotarizationDate);
+ if (is_revoked) {
+ MacOSError::throwMe(errSecCSRevokedNotarization);
+ }
+ }
+ mNotarizationChecked = true;
+ }
+ }
+#endif // TARGET_OS_OSX
+
// initialize progress/cancellation state
if (flags & kSecCSReportProgress)
prepareProgress(estimateResourceWorkload() + 2); // +1 head, +1 tail
{
static const std::string appleDeveloperRequirement = "(" + std::string(WWDRRequirement) + ") or (" + MACWWDRRequirement + ") or (" + developerID + ") or (" + distributionCertificate + ") or (" + iPhoneDistributionCert + ")";
SecPointer<SecRequirement> req = new SecRequirement(parseRequirement(appleDeveloperRequirement), true);
- Requirement::Context ctx(certs, NULL, NULL, "", NULL);
+ Requirement::Context ctx(certs, NULL, NULL, "", NULL, NULL, kSecCodeSignatureNoHash, false);
return req->requirement()->validates(ctx);
}
static SecStaticCode *requiredStatic(SecStaticCodeRef ref); // convert SecCodeRef
static SecCode *optionalDynamic(SecStaticCodeRef ref); // extract SecCodeRef or NULL if static
- SecStaticCode(DiskRep *rep);
+ SecStaticCode(DiskRep *rep, uint32_t flags = 0);
virtual ~SecStaticCode() throw();
void initializeFromParent(const SecStaticCode& parent);
private:
void validateOtherVersions(CFURLRef path, SecCSFlags flags, SecRequirementRef req, SecStaticCode *code);
bool checkfix30814861(string path, bool addition);
+ bool checkfix41082220(OSStatus result);
ResourceBuilder *mCheckfix30814861builder1;
dispatch_once_t mCheckfix30814861builder1_once;
LimitedAsync *mLimitedAsync; // limited async workers for verification
+ uint32_t mFlags; // flags from creation
+ bool mNotarizationChecked; // ensure notarization check only performed once
+ bool mStaplingChecked; // ensure stapling check only performed once
+ double mNotarizationDate; // the notarization ticket's date, if online check failed
+
// signature verification outcome (mTrust == NULL => not done yet)
CFRef<SecTrustRef> mTrust; // outcome of crypto validation (valid or not)
CFRef<CFArrayRef> mCertChain;
#include "bundlediskrep.h"
#include "filediskrep.h"
#include "dirscanner.h"
+#include "notarization.h"
#include <CoreFoundation/CFBundlePriv.h>
#include <CoreFoundation/CFURLAccess.h>
#include <CoreFoundation/CFBundlePriv.h>
// We make a CFBundleRef immediately, but everything else is lazy
//
BundleDiskRep::BundleDiskRep(const char *path, const Context *ctx)
- : mBundle(_CFBundleCreateUnique(NULL, CFTempURL(path)))
+ : mBundle(_CFBundleCreateUnique(NULL, CFTempURL(path))), forcePlatform(false)
{
if (!mBundle)
MacOSError::throwMe(errSecCSBadBundleFormat);
setup(ctx);
+ forcePlatform = mExecRep->appleInternalForcePlatform();
CODESIGN_DISKREP_CREATE_BUNDLE_PATH(this, (char*)path, (void*)ctx, mExecRep);
}
{
mBundle = ref; // retains
setup(ctx);
+ forcePlatform = mExecRep->appleInternalForcePlatform();
CODESIGN_DISKREP_CREATE_BUNDLE_REF(this, ref, (void*)ctx, mExecRep);
}
mInstallerPackage = false; // default
mAppLike = false; // pessimism first
bool appDisqualified = false; // found reason to disqualify as app
-
+
// capture the path of the main executable before descending into a specific version
CFRef<CFURLRef> mainExecBefore = CFBundleCopyExecutableURL(mBundle);
CFRef<CFURLRef> infoPlistBefore = _CFBundleCopyInfoPlistURL(mBundle);
"'^.*' = #T" // everything is a resource
"'^Info\\.plist$' = {omit=#T,weight=10}" // explicitly exclude this for backward compatibility
"}}");
-
- // new (V2) executable bundle rules
- return cfmake<CFDictionaryRef>("{" // *** the new (V2) world ***
- "rules={" // old (V1; legacy) version
- "'^version.plist$' = #T" // include version.plist
- "%s = #T" // include Resources
- "%s = {optional=#T, weight=1000}" // make localizations optional
- "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all
- "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files
- "},rules2={"
- "'^.*' = #T" // include everything as a resource, with the following exceptions
- "'^[^/]+$' = {nested=#T, weight=10}" // files directly in Contents
- "'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=10}" // dynamic repositories
- "'.*\\.dSYM($|/)' = {weight=11}" // but allow dSYM directories in code locations (parallel to their code)
- "'^(.*/)?\\.DS_Store$' = {omit=#T,weight=2000}" // ignore .DS_Store files
- "'^Info\\.plist$' = {omit=#T, weight=20}" // excluded automatically now, but old systems need to be told
- "'^version\\.plist$' = {weight=20}" // include version.plist as resource
- "'^embedded\\.provisionprofile$' = {weight=20}" // include embedded.provisionprofile as resource
- "'^PkgInfo$' = {omit=#T, weight=20}" // traditionally not included
- "%s = {weight=20}" // Resources override default nested (widgets)
- "%s = {optional=#T, weight=1000}" // make localizations optional
- "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all
- "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files
- "}}",
-
- (string("^") + resources).c_str(),
- (string("^") + resources + ".*\\.lproj/").c_str(),
- (string("^") + resources + "Base\\.lproj/").c_str(),
- (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str(),
-
- (string("^") + resources).c_str(),
- (string("^") + resources + ".*\\.lproj/").c_str(),
- (string("^") + resources + "Base\\.lproj/").c_str(),
- (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str()
- );
+
+ // new (V2) executable bundle rules
+ if (!resources.empty()) {
+ return cfmake<CFDictionaryRef>("{" // *** the new (V2) world ***
+ "rules={" // old (V1; legacy) version
+ "'^version.plist$' = #T" // include version.plist
+ "%s = #T" // include Resources
+ "%s = {optional=#T, weight=1000}" // make localizations optional
+ "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all
+ "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files
+ "},rules2={"
+ "'^.*' = #T" // include everything as a resource, with the following exceptions
+ "'^[^/]+$' = {nested=#T, weight=10}" // files directly in Contents
+ "'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=10}" // dynamic repositories
+ "'.*\\.dSYM($|/)' = {weight=11}" // but allow dSYM directories in code locations (parallel to their code)
+ "'^(.*/)?\\.DS_Store$' = {omit=#T,weight=2000}" // ignore .DS_Store files
+ "'^Info\\.plist$' = {omit=#T, weight=20}" // excluded automatically now, but old systems need to be told
+ "'^version\\.plist$' = {weight=20}" // include version.plist as resource
+ "'^embedded\\.provisionprofile$' = {weight=20}" // include embedded.provisionprofile as resource
+ "'^PkgInfo$' = {omit=#T, weight=20}" // traditionally not included
+ "%s = {weight=20}" // Resources override default nested (widgets)
+ "%s = {optional=#T, weight=1000}" // make localizations optional
+ "%s = {weight=1010}" // ... except for Base.lproj which really isn't optional at all
+ "%s = {omit=#T, weight=1100}" // exclude all locversion.plist files
+ "}}",
+
+ (string("^") + resources).c_str(),
+ (string("^") + resources + ".*\\.lproj/").c_str(),
+ (string("^") + resources + "Base\\.lproj/").c_str(),
+ (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str(),
+
+ (string("^") + resources).c_str(),
+ (string("^") + resources + ".*\\.lproj/").c_str(),
+ (string("^") + resources + "Base\\.lproj/").c_str(),
+ (string("^") + resources + ".*\\.lproj/locversion.plist$").c_str()
+ );
+ } else {
+ /* This is a bundle format without a Resources directory, which means we need to omit
+ * Resources-directory specific rules that would create conflicts. */
+
+ /* We also declare that flat bundles do not use any nested code rules.
+ * Embedded, where flat bundles are used, currently does not support them,
+ * and we have no plans for allowing the replacement of nested code there.
+ * Should anyone actually intend to use nested code rules in a flat
+ * bundle, they are free to create their own rules. */
+
+ return cfmake<CFDictionaryRef>("{" // *** the new (V2) world ***
+ "rules={" // old (V1; legacy) version
+ "'^version.plist$' = #T" // include version.plist
+ "'^.*' = #T" // include Resources
+ "'^.*\\.lproj/' = {optional=#T, weight=1000}" // make localizations optional
+ "'^Base\\.lproj/' = {weight=1010}" // ... except for Base.lproj which really isn't optional at all
+ "'^.*\\.lproj/locversion.plist$' = {omit=#T, weight=1100}" // exclude all locversion.plist files
+ "},rules2={"
+ "'^.*' = #T" // include everything as a resource, with the following exceptions
+ "'.*\\.dSYM($|/)' = {weight=11}" // but allow dSYM directories in code locations (parallel to their code)
+ "'^(.*/)?\\.DS_Store$' = {omit=#T,weight=2000}" // ignore .DS_Store files
+ "'^Info\\.plist$' = {omit=#T, weight=20}" // excluded automatically now, but old systems need to be told
+ "'^version\\.plist$' = {weight=20}" // include version.plist as resource
+ "'^embedded\\.provisionprofile$' = {weight=20}" // include embedded.provisionprofile as resource
+ "'^PkgInfo$' = {omit=#T, weight=20}" // traditionally not included
+ "'^.*\\.lproj/' = {optional=#T, weight=1000}" // make localizations optional
+ "'^Base\\.lproj/' = {weight=1010}" // ... except for Base.lproj which really isn't optional at all
+ "'^.*\\.lproj/locversion.plist$' = {omit=#T, weight=1100}" // exclude all locversion.plist files
+ "}}"
+ );
+ }
}
if (const char *name = CodeDirectory::canonicalSlotName(slot)) {
rep->createMeta();
string path = rep->metaPath(name);
+
+#if TARGET_OS_OSX
+ // determine AFSC status if we are told to preserve compression
+ bool conductCompression = false;
+ cmpInfo cInfo;
+ if (this->getPreserveAFSC()) {
+ struct stat statBuffer;
+ if (stat(path.c_str(), &statBuffer) == 0) {
+ if (queryCompressionInfo(path.c_str(), &cInfo) == 0) {
+ if (cInfo.compressionType != 0 && cInfo.compressedSize > 0) {
+ conductCompression = true;
+ }
+ }
+ }
+ }
+#endif
+
AutoFileDesc fd(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
fd.writeAll(CFDataGetBytePtr(data), CFDataGetLength(data));
+ fd.close();
+
+#if TARGET_OS_OSX
+ // if the original file was compressed, compress the new file after move
+ if (conductCompression) {
+ CFMutableDictionaryRef options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFStringRef val = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), cInfo.compressionType);
+ CFDictionarySetValue(options, kAFSCCompressionTypes, val);
+ CFRelease(val);
+
+ CompressionQueueContext compressionQueue = CreateCompressionQueue(NULL, NULL, NULL, NULL, options);
+
+ if (!CompressFile(compressionQueue, path.c_str(), NULL)) {
+ secinfo("bundlediskrep", "%p Failed to queue compression of file %s", this, path.c_str());
+ MacOSError::throwMe(errSecCSInternalError);
+ }
+
+ FinishCompressionAndCleanUp(compressionQueue);
+ compressionQueue = NULL;
+ CFRelease(options);
+ }
+#endif
+
mWrittenFiles.insert(name);
} else
MacOSError::throwMe(errSecCSBadBundleFormat);
execWriter->flush();
purgeMetaDirectory();
}
-
-
+
// purge _CodeSignature of all left-over files from any previous signature
void BundleDiskRep::Writer::purgeMetaDirectory()
{
}
+void BundleDiskRep::registerStapledTicket()
+{
+ string root = cfStringRelease(copyCanonicalPath());
+ registerStapledTicketInBundle(root);
+}
} // end namespace CodeSigning
} // end namespace Security
#include "diskrep.h"
#include "machorep.h"
+#include <sys/cdefs.h>
+
+#if TARGET_OS_OSX
+__BEGIN_DECLS
+#include <AppleFSCompression/AppleFSCompression.h>
+__END_DECLS
+#endif
+
namespace Security {
namespace CodeSigning {
void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags);
CFArrayRef allowedResourceOmissions();
+ void registerStapledTicket();
+
+ bool appleInternalForcePlatform() const {return forcePlatform;};
+
CFBundleRef bundle() const { return mBundle; }
public:
bool mComponentsFromExecValid; // mComponentsFromExec is valid (tri-state)
std::set<CodeDirectory::SpecialSlot> mUsedComponents; // remember what components we've retrieved
std::set<OSStatus> mStrictErrors; // strict validation errors encountered
+ bool forcePlatform; // treat as anchor apple on apple internal
};
return cdComponentIsBlob; // global
case cdIdentificationSlot:
return cdComponentPerArchitecture; // raw
+ case cdTicketSlot:
+ return 0; // global, raw
default:
return 0; // global, raw
}
cdAlternateCodeDirectoryLimit = 0x1005, // 5+1 hashes should be enough for everyone...
cdSignatureSlot = 0x10000, // CMS signature
cdIdentificationSlot, // identification blob (detached signatures only)
+ cdTicketSlot, // ticket embedded in signature (DMG only)
// (add further virtual slot numbers here)
};
{
if (mGuest->pidBased()->supportInfoPlist())
return SecStaticCode::infoDictionary();
- return makeCFDictionary(0);
+ if (!mEmptyInfoDict) {
+ mEmptyInfoDict.take(makeCFDictionary(0));
+ }
+ return mEmptyInfoDict;
}
void ProcessDynamicCode::validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail /* = errSecCSSignatureFailed */)
void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
private:
ProcessCode *mGuest;
-
+ CFRef<CFDictionaryRef> mEmptyInfoDict;
};
} // end namespace CodeSigning
// diskimagerep - DiskRep representing a single read-only compressed disk image file
//
#include "diskimagerep.h"
+#include "notarization.h"
#include "sigblob.h"
#include "CodeSigner.h"
#include <security_utilities/endian.h>
{
}
+void DiskImageRep::registerStapledTicket()
+{
+ CFRef<CFDataRef> data = NULL;
+ if (mSigningData) {
+ data.take(mSigningData->component(cdTicketSlot));
+ registerStapledTicketInDMG(data);
+ }
+}
+
} // end namespace CodeSigning
} // end namespace Security
void prepareForSigning(SigningContext& state);
static bool candidate(UnixPlusPlus::FileDesc &fd);
-
+ void registerStapledTicket();
+
public:
static CFDataRef identificationFor(MachO *macho);
// do nothing
}
-
//
// Given a file system path, come up with the most likely correct
// disk representation for what's there.
return s.substr(0, p);
}
+void DiskRep::registerStapledTicket()
+{ /* do nothing */ }
+
//
// Writers
virtual void flush(); // flush caches (refetch as needed)
virtual CFDictionaryRef diskRepInformation(); // information from diskrep
+ virtual void registerStapledTicket();
+
// default values for signing operations
virtual std::string recommendedIdentifier(const SigningContext &ctx) = 0; // default identifier
virtual CFDictionaryRef defaultResourceRules(const SigningContext &ctx); // default resource rules [none]
virtual void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); // perform strict validation
virtual CFArrayRef allowedResourceOmissions(); // allowed (default) resource omission rules
+ virtual bool appleInternalForcePlatform() const {return false;};
+
bool mainExecutableIsMachO() { return mainExecutableImage() != NULL; }
// shorthands
void signature(CFDataRef data) { component(cdSignatureSlot, data); }
void codeDirectory(const CodeDirectory *cd, CodeDirectory::SpecialSlot slot)
{ component(slot, CFTempData(cd->data(), cd->length())); }
-
+
+#if TARGET_OS_OSX
+ bool getPreserveAFSC() { return mPreserveAFSC; }
+ void setPreserveAFSC(bool flag) { mPreserveAFSC = flag; }
+#endif
+
private:
Architecture mArch;
uint32_t mAttributes;
+#if TARGET_OS_OSX
+ bool mPreserveAFSC = false; // preserve AFSC compression
+#endif
};
//
void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags);
void flush(); // flush cache
-
+
static bool candidate(UnixPlusPlus::FileDesc &fd);
public:
--- /dev/null
+/*
+ * 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@
+ */
+#include "SecAssessment.h"
+#include "notarization.h"
+#include "unix++.h"
+
+typedef struct __attribute__((packed)) _package_trailer {
+ uint8_t magic[4];
+ uint16_t version;
+ uint16_t type;
+ uint32_t length;
+ uint8_t reserved[4];
+} package_trailer_t;
+
+enum TrailerType {
+ TrailerTypeInvalid = 0,
+ TrailerTypeTerminator,
+ TrailerTypeTicket,
+};
+
+static const char *TrailerMagic = "t8lr";
+
+namespace Security {
+namespace CodeSigning {
+
+static void
+registerStapledTicketWithSystem(CFDataRef data)
+{
+ secinfo("notarization", "Registering stapled ticket with system");
+
+#if TARGET_OS_OSX
+ CFErrorRef error = NULL;
+ if (!SecAssessmentTicketRegister(data, &error)) {
+ secerror("Error registering stapled ticket: %@", data);
+ }
+#endif // TARGET_OS_OSX
+}
+
+bool
+checkNotarizationServiceForRevocation(CFDataRef hash, SecCSDigestAlgorithm hashType, double *date)
+{
+ bool is_revoked = false;
+
+ secinfo("notarization", "checking with online notarization service for hash: %@", hash);
+
+#if TARGET_OS_OSX
+ CFRef<CFErrorRef> error;
+ if (!SecAssessmentTicketLookup(hash, hashType, kSecAssessmentTicketFlagForceOnlineCheck, date, &error.aref())) {
+ CFIndex err = CFErrorGetCode(error);
+ if (err == EACCES) {
+ secerror("Notarization daemon found revoked hash: %@", hash);
+ is_revoked = true;
+ } else {
+ secerror("Error checking with notarization daemon: %ld", err);
+ }
+ }
+#endif
+
+ return is_revoked;
+}
+
+bool
+isNotarized(const Requirement::Context *context)
+{
+ CFRef<CFDataRef> cd;
+ CFRef<CFErrorRef> error;
+ bool is_notarized = false;
+ SecCSDigestAlgorithm hashType = kSecCodeSignatureNoHash;
+
+ if (context == NULL) {
+ is_notarized = false;
+ goto lb_exit;
+ }
+
+ if (context->directory) {
+ cd.take(context->directory->cdhash());
+ hashType = (SecCSDigestAlgorithm)context->directory->hashType;
+ } else if (context->packageChecksum) {
+ cd = context->packageChecksum;
+ hashType = context->packageAlgorithm;
+ }
+
+ if (cd.get() == NULL) {
+ // No cdhash means we can't check notarization.
+ is_notarized = false;
+ goto lb_exit;
+ }
+
+ secinfo("notarization", "checking notarization on %d, %@", hashType, cd.get());
+
+#if TARGET_OS_OSX
+ if (SecAssessmentTicketLookup(cd, hashType, kSecAssessmentTicketFlagDefault, NULL, &error.aref())) {
+ is_notarized = true;
+ } else {
+ is_notarized = false;
+ if (error.get() != NULL) {
+ secerror("Error checking with notarization daemon: %ld", CFErrorGetCode(error));
+ }
+ }
+#endif
+
+lb_exit:
+ secinfo("notarization", "isNotarized = %d", is_notarized);
+ return is_notarized;
+}
+
+void
+registerStapledTicketInPackage(const std::string& path)
+{
+ int fd = 0;
+ package_trailer_t trailer;
+ off_t readOffset = 0;
+ size_t bytesRead = 0;
+ off_t backSeek = 0;
+ uint8_t *ticketData = NULL;
+ boolean_t ticketTrailerFound = false;
+ CFRef<CFDataRef> data;
+
+ secinfo("notarization", "Extracting ticket from package: %s", path.c_str());
+
+ fd = open(path.c_str(), O_RDONLY);
+ if (fd <= 0) {
+ secerror("cannot open package for reading");
+ goto lb_exit;
+ }
+
+ bzero(&trailer, sizeof(trailer));
+ readOffset = lseek(fd, -sizeof(trailer), SEEK_END);
+ if (readOffset <= 0) {
+ secerror("could not scan for first trailer on package (error - %d)", errno);
+ goto lb_exit;
+ }
+
+ while (!ticketTrailerFound) {
+ bytesRead = read(fd, &trailer, sizeof(trailer));
+ if (bytesRead != sizeof(trailer)) {
+ secerror("could not read next trailer from package (error - %d)", errno);
+ goto lb_exit;
+ }
+
+ if (memcmp(trailer.magic, TrailerMagic, strlen(TrailerMagic)) != 0) {
+ // Most packages will not be stapled, so this isn't really an error.
+ secdebug("notarization", "package did not end in a trailer");
+ goto lb_exit;
+ }
+
+ switch (trailer.type) {
+ case TrailerTypeTicket:
+ ticketTrailerFound = true;
+ break;
+ case TrailerTypeTerminator:
+ // Found a terminator before a trailer, so just exit.
+ secinfo("notarization", "package had a trailer, but no ticket trailers");
+ goto lb_exit;
+ case TrailerTypeInvalid:
+ secinfo("notarization", "package had an invalid trailer");
+ goto lb_exit;
+ default:
+ // it's an unsupported trailer type, so skip it.
+ break;
+ }
+
+ // If we're here, it's either a ticket or an unknown trailer. In both cases we can definitely seek back to the
+ // beginning of the data pointed to by this trailer, which is the length of its data and the size of the trailer itself.
+ backSeek = -1 * (sizeof(trailer) + trailer.length);
+ if (!ticketTrailerFound) {
+ // If we didn't find a ticket, we're about to iterate again and want to read the next trailer so seek back an additional
+ // trailer blob to prepare for reading it.
+ backSeek -= sizeof(trailer);
+ }
+ readOffset = lseek(fd, backSeek, SEEK_CUR);
+ if (readOffset <= 0) {
+ secerror("could not scan backwards (%lld) for next trailer on package (error - %d)", backSeek, errno);
+ goto lb_exit;
+ }
+ }
+
+ // If we got here, we have a valid ticket trailer and already seeked back to the beginning of its data.
+ ticketData = (uint8_t*)malloc(trailer.length);
+ if (ticketData == NULL) {
+ secerror("could not allocate memory for ticket");
+ goto lb_exit;
+ }
+
+ bytesRead = read(fd, ticketData, trailer.length);
+ if (bytesRead != trailer.length) {
+ secerror("unable to read entire ticket (error - %d)", errno);
+ goto lb_exit;
+ }
+
+ data = CFDataCreateWithBytesNoCopy(NULL, ticketData, trailer.length, NULL);
+ if (data.get() == NULL) {
+ secerror("unable to create cfdata for notarization");
+ goto lb_exit;
+ }
+
+ secinfo("notarization", "successfully found stapled ticket for: %s", path.c_str());
+ registerStapledTicketWithSystem(data);
+
+lb_exit:
+ if (fd) {
+ close(fd);
+ }
+ if (ticketData) {
+ free(ticketData);
+ }
+}
+
+void
+registerStapledTicketInBundle(const std::string& path)
+{
+ int fd = 0;
+ struct stat st;
+ uint8_t *ticketData = NULL;
+ size_t ticketLength = 0;
+ size_t bytesRead = 0;
+ CFRef<CFDataRef> data;
+ std::string ticketLocation = path + "/Contents/CodeResources";
+
+ secinfo("notarization", "Extracting ticket from bundle: %s", path.c_str());
+
+ fd = open(ticketLocation.c_str(), O_RDONLY);
+ if (fd <= 0) {
+ // Only print an error if the file exists, otherwise its an expected early exit case.
+ if (errno != ENOENT) {
+ secerror("cannot open stapled file for reading: %d", errno);
+ }
+ goto lb_exit;
+ }
+
+ if (fstat(fd, &st)) {
+ secerror("unable to stat stapling file: %d", errno);
+ goto lb_exit;
+ }
+
+ if ((st.st_mode & S_IFREG) != S_IFREG) {
+ secerror("stapling is not a regular file");
+ goto lb_exit;
+ }
+
+ if (st.st_size <= INT_MAX) {
+ ticketLength = (size_t)st.st_size;
+ } else {
+ secerror("ticket size was too large: %lld", st.st_size);
+ goto lb_exit;
+ }
+
+ ticketData = (uint8_t*)malloc(ticketLength);
+ if (ticketData == NULL) {
+ secerror("unable to allocate data for ticket");
+ goto lb_exit;
+ }
+
+ bytesRead = read(fd, ticketData, ticketLength);
+ if (bytesRead != ticketLength) {
+ secerror("unable to read entire ticket from bundle");
+ goto lb_exit;
+ }
+
+ data = CFDataCreateWithBytesNoCopy(NULL, ticketData, ticketLength, NULL);
+ if (data.get() == NULL) {
+ secerror("unable to create cfdata for notarization");
+ goto lb_exit;
+ }
+
+ secinfo("notarization", "successfully found stapled ticket for: %s", path.c_str());
+ registerStapledTicketWithSystem(data);
+
+lb_exit:
+ if (fd) {
+ close(fd);
+ }
+ if (ticketData) {
+ free(ticketData);
+ }
+}
+
+void
+registerStapledTicketInDMG(CFDataRef ticketData)
+{
+ if (ticketData == NULL) {
+ return;
+ }
+ secinfo("notarization", "successfully found stapled ticket in DMG");
+ registerStapledTicketWithSystem(ticketData);
+}
+
+}
+}
--- /dev/null
+/*
+ * 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 _H_NOTARIZATION
+#define _H_NOTARIZATION
+
+#include <Security/Security.h>
+#include <security_utilities/dispatch.h>
+#include <security_utilities/hashing.h>
+#include <security_utilities/unix++.h>
+#include "requirement.h"
+
+namespace Security {
+namespace CodeSigning {
+
+// Performs an online check for a ticket, and returns true if a revocation ticket is found.
+bool checkNotarizationServiceForRevocation(CFDataRef hash, SecCSDigestAlgorithm hashType, double *date);
+
+// Performs an offline notarization check for the hash represented in the requirement context
+// and returns whether the hash has a valid, unrevoked notarization ticket.
+bool isNotarized(const Requirement::Context *context);
+
+// Representation-specific methods for extracting a stapled ticket and registering
+// it with the notarization daemon.
+void registerStapledTicketInPackage(const std::string& path);
+void registerStapledTicketInBundle(const std::string& path);
+void registerStapledTicketInDMG(CFDataRef ticketData);
+
+} // end namespace CodeSigning
+} // end namespace Security
+
+#endif /* _H_NOTARIZATION */
return path;
}
-
+
+bool PidDiskRep::appleInternalForcePlatform() const
+{
+ uint32_t flags = 0;
+ int rcent = ::csops(mPid, CS_OPS_STATUS, &flags, sizeof(flags));
+
+ if (rcent != 0) {
+ MacOSError::throwMe(errSecCSNoSuchCode);
+ }
+
+ return (flags & CS_PLATFORM_BINARY) == CS_PLATFORM_BINARY;
+}
} // end namespace CodeSigning
} // end namespace Security
void setCredentials(const CodeDirectory* cd);
+ bool appleInternalForcePlatform() const;
+
private:
const BlobCore *blob() { return (const BlobCore *)mBuffer; }
void fetchData(void);
simpleFeature("root_only", ^{
UnixError::check(::chmod(dbPath(), S_IRUSR | S_IWUSR));
});
+
+ simpleFeature("notarized_apps", ^{
+
+ // Insert a set of notarization requirements for notarized applications and installers, with a priority that will be higher than developer id priorities
+ // so they are guaranteed to match first.
+ SQLite::Statement addNotarizedExecutables(*this,
+ "INSERT INTO authority (type, allow, flags, priority, label, requirement) VALUES (1, 1, 2, 5.0, 'Notarized Developer ID', 'anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and notarized')");
+ addNotarizedExecutables.execute();
+
+ SQLite::Statement addNotarizedInstallers(*this,
+ "INSERT INTO authority (type, allow, flags, priority, label, requirement) VALUES (2, 1, 2, 5.0, 'Notarized Developer ID', 'anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and (certificate leaf[field.1.2.840.113635.100.6.1.14] or certificate leaf[field.1.2.840.113635.100.6.1.13]) and notarized')");
+ addNotarizedInstallers.execute();
+
+ // Bump the priority on apple system, apple installer, and mac app store entries so they are evaluated before Developer ID variants.
+ // This is important because notarized variants meet the requirement of the Developer ID variant and would could match that too.
+ SQLite::Statement bumpAppleSystemPriority(*this,
+ "UPDATE authority SET priority = 20.0 WHERE label = 'Apple System'");
+ bumpAppleSystemPriority.execute();
+
+ SQLite::Statement bumpAppleInstallerPriority(*this,
+ "UPDATE authority SET priority = 20.0 WHERE label = 'Apple Installer'");
+ bumpAppleInstallerPriority.execute();
+
+ SQLite::Statement bumpMacAppStorePriority(*this,
+ "UPDATE authority SET priority = 10.0 WHERE label = 'Mac App Store'");
+ bumpMacAppStorePriority.execute();
+ });
}
#include "diskrep.h"
#include "codedirectory.h"
#include "csutilities.h"
+#include "notarization.h"
#include "StaticCode.h"
#include <CoreServices/CoreServicesPriv.h>
SQLite3::int64 disabled = query[6];
// const char *filter = query[7];
// const char *remarks = query[8];
-
- secdebug("gk", "considering rule %d(%s) requirement %s", int(id), label ? label : "UNLABELED", reqString);
+
+ secdebug("gk", "considering rule %d(%s) requirement %s", int(id), label ? label : "UNLABELED", reqString);
CFRef<SecRequirementRef> requirement;
MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref()));
switch (OSStatus rc = SecStaticCodeCheckValidity(code, kSecCSBasicValidateOnly | kSecCSCheckGatekeeperArchitectures, requirement)) {
MacOSError::throwMe(rc); // general error; pass to caller
}
- // if this rule is disabled, skip it but record the first matching one for posterity
- if (disabled && latentID == 0) {
- latentID = id;
- latentLabel = label ? label : "";
+ // If this rule is disabled, do not continue any further and just continue iterating
+ // until we find one that is enabled.
+ if (disabled) {
+ // ...but always record the first matching rule for informational purposes.
+ if (latentID == 0) {
+ latentID = id;
+ latentLabel = label ? label : "";
+ }
continue;
}
-
+
// current rule is first rule (in priority order) that matched. Apply it
secnotice("gk", "rule %d applies - allow=%d", int(id), allow);
if (nested && allow) // success, nothing to record
}
CFCopyRef<SecStaticCodeRef> code;
- MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref()));
+ MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags | kSecCSForceOnlineNotarizationCheck, &code.aref()));
SecCSFlags validationFlags = kSecCSEnforceRevocationChecks | kSecCSCheckAllArchitectures;
if (!(flags & kSecAssessmentFlagAllowWeak))
}
return NULL;
}));
-
+
// go for it!
SecCSFlags topFlags = validationFlags | kSecCSCheckNestedCode | kSecCSRestrictSymlinks | kSecCSReportProgress;
if (type == kAuthorityExecute && !appOk)
default:
MacOSError::throwMe(rc);
}
+
+ // Copy notarization date, if present, from code signing information
+ CFRef<CFDictionaryRef> info;
+ OSStatus status = SecCodeCopySigningInformation(code, kSecCSInternalInformation, &info.aref());
+ if (status == 0 && info) {
+ CFDateRef date = (CFDateRef)CFDictionaryGetValue(info, kSecCodeInfoNotarizationDate);
+ if (date) {
+ cfadd(result, "{%O=%O}", kSecAssessmentAssessmentNotarizationDate, date);
+ }
+ } else {
+ secerror("Unable to copy signing information: %d", (int)status);
+ }
if (nestedFailure && CFEqual(CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict), kCFBooleanTrue)) {
// structure intact, top level approved, nested code failed policy
if (CFRef<CFArrayRef> certs = xar.copyCertChain()) {
CFRef<CFTypeRef> policy = installerPolicy();
CFRef<SecTrustRef> trust;
+ CFRef<CFDataRef> checksum;
+ CFRef<CFMutableDictionaryRef> requirementContext = makeCFMutableDictionary();
MacOSError::check(SecTrustCreateWithCertificates(certs, policy, &trust.aref()));
// MacOSError::check(SecTrustSetAnchorCertificates(trust, cfEmptyArray())); // no anchors
MacOSError::check(SecTrustSetOptions(trust, kSecTrustOptionAllowExpired | kSecTrustOptionImplicitAnchors));
}
}
+ xar.registerStapledNotarization();
+ checksum.take(xar.createPackageChecksum());
+ if (checksum) {
+ double notarizationDate = NAN;
+
+ // Force a single online check for the checksum, which is always SHA1.
+ bool is_revoked = checkNotarizationServiceForRevocation(checksum, kSecCodeSignatureHashSHA1, ¬arizationDate);
+ if (is_revoked) {
+ MacOSError::throwMe(errSecCSRevokedNotarization);
+ }
+
+ // Create the appropriate requirement context entry to allow notarized requirement check.
+ CFRef<CFNumberRef> algorithm = makeCFNumber((uint32_t)xar.checksumDigestAlgorithm());
+ cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyPackageChecksum, checksum.get());
+ cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyChecksumAlgorithm, algorithm.get());
+
+ if (!isnan(notarizationDate)) {
+ CFRef<CFDateRef> date = CFDateCreate(NULL, notarizationDate);
+ if (date) {
+ cfadd(result, "{%O=%O}", kSecAssessmentAssessmentNotarizationDate, date.get());
+ }
+ }
+ }
+
SQLite::Statement query(*this,
"SELECT allow, requirement, id, label, flags, disabled FROM scan_authority"
" WHERE type = :type"
const char *label = query[3];
//sqlite_uint64 ruleFlags = query[4];
SQLite3::int64 disabled = query[5];
-
+
CFRef<SecRequirementRef> requirement;
MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref()));
- switch (OSStatus rc = SecRequirementEvaluate(requirement, chain, NULL, kSecCSDefaultFlags)) {
+ switch (OSStatus rc = SecRequirementEvaluate(requirement, chain, requirementContext.get(), kSecCSDefaultFlags)) {
case errSecSuccess: // success
break;
case errSecCSReqFailed: // requirement missed, but otherwise okay
case opPlatform:
print("platform = %d", get<int32_t>());
break;
+ case opNotarized:
+ print("notarized");
+ break;
default:
if (op & opGenericFalse) {
print(" false /* opcode %d */", op & ~opFlagMask);
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFUnserialize.h>
#include "csutilities.h"
+#include "notarization.h"
namespace Security {
namespace CodeSigning {
int32_t targetPlatform = get<int32_t>();
return mContext->directory && mContext->directory->platform == targetPlatform;
}
+ case opNotarized:
+ {
+ return isNotarized(mContext);
+ }
default:
// opcode not recognized - handle generically if possible, fail otherwise
if (op & (opGenericFalse | opGenericSkip)) {
if (csr_check(CSR_ALLOW_APPLE_INTERNAL))
return false;
+ if (mContext->forcePlatform) {
+ return true;
+ }
+
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
additionalTrustedCertificates = getAdditionalTrustedAnchors();
return true;
} else if (appleLocalAnchored()) {
return true;
- }
+ }
return false;
}
void cdhash(SHA1::Digest digest);
void cdhash(CFDataRef digest);
void platform(int platformIdentifier);
-
+
void copy(const void *data, size_t length)
{ memcpy(this->alloc(length), data, length); }
void copy(const Requirement *req); // inline expand
class Requirement::Context {
protected:
Context()
- : certs(NULL), info(NULL), entitlements(NULL), identifier(""), directory(NULL) { }
+ : certs(NULL), info(NULL), entitlements(NULL), identifier(""), directory(NULL), packageChecksum(NULL), packageAlgorithm(kSecCodeSignatureNoHash), forcePlatform(false) { }
public:
- Context(CFArrayRef certChain, CFDictionaryRef infoDict, CFDictionaryRef entitlementDict,
- const std::string &ident, const CodeDirectory *dir)
- : certs(certChain), info(infoDict), entitlements(entitlementDict), identifier(ident), directory(dir) { }
+ Context(CFArrayRef certChain, CFDictionaryRef infoDict, CFDictionaryRef entitlementDict, const std::string &ident,
+ const CodeDirectory *dir, CFDataRef packageChecksum, SecCSDigestAlgorithm packageAlgorithm, bool force_platform)
+ : certs(certChain), info(infoDict), entitlements(entitlementDict), identifier(ident), directory(dir),
+ packageChecksum(packageChecksum), packageAlgorithm(packageAlgorithm), forcePlatform(force_platform) { }
CFArrayRef certs; // certificate chain
CFDictionaryRef info; // Info.plist
CFDictionaryRef entitlements; // entitlement plist
std::string identifier; // signing identifier
const CodeDirectory *directory; // CodeDirectory
+ CFDataRef packageChecksum; // package checksum
+ SecCSDigestAlgorithm packageAlgorithm; // package checksum algorithm
+ bool forcePlatform;
SecCertificateRef cert(int ix) const; // get a cert from the cert chain (NULL if not found)
unsigned int certCount() const; // length of cert chain (including root)
opNamedAnchor, // named anchor type
opNamedCode, // named subroutine
opPlatform, // platform constraint [integer]
+ opNotarized, // has a developer id+ ticket
exprOpCount // (total opcode count in use)
};
MacOSError::throwMe(errSecCSNotSupported);
rep = code->diskRep();
+
+ if (state.mPreserveAFSC)
+ rep->writer()->setPreserveAFSC(state.mPreserveAFSC);
+
if (Universal *fat = state.mNoMachO ? NULL : rep->mainExecutableImage()) {
// architecture-sensitive removal
MachOEditor editor(rep->writer(), *fat, digestAlgorithms(), rep->mainExecutablePath());
if (!(signingFlags() & kSecCSSignV1)) {
CFCopyRef<CFDictionaryRef> rules2 = cfget<CFDictionaryRef>(rulesDict, "rules2");
if (!rules2) {
- // Clone V1 rules and add default nesting rules at weight 0 (overridden by anything in rules).
+ // Clone V1 rules and add default nesting rules at weight 0 (overridden by anything in rules,
+ // because the default weight, according to ResourceBuilder::addRule(), is 1).
// V1 rules typically do not cover these places so we'll prevail, but if they do, we defer to them.
rules2 = cfmake<CFDictionaryRef>("{+%O"
"'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=0}" // exclude dynamic repositories
{
// Mach-O executable at the core - perform multi-architecture signing
RefPointer<DiskRep::Writer> writer = rep->writer();
+
+ if (state.mPreserveAFSC)
+ writer->setPreserveAFSC(state.mPreserveAFSC);
+
auto_ptr<ArchEditor> editor(state.mDetached
? static_cast<ArchEditor *>(new BlobEditor(*fat, *this))
: new MachOEditor(writer, *fat, this->digestAlgorithms(), rep->mainExecutablePath()));
// non-Mach-O executable - single-instance signing
RefPointer<DiskRep::Writer> writer = state.mDetached ?
(new DetachedBlobWriter(*this)) : rep->writer();
-
+
+ if(state.mPreserveAFSC)
+ writer->setPreserveAFSC(state.mPreserveAFSC);
+
CodeDirectorySet cdSet;
for (auto type = digestAlgorithms().begin(); type != digestAlgorithms().end(); ++type) {
ArchEditor::Arch::Arch(const Architecture &arch, CodeDirectory::HashAlgorithms hashTypes)
: architecture(arch)
{
+ blobSize = 0;
for (auto type = hashTypes.begin(); type != hashTypes.end(); ++type)
cdBuilders.insert(make_pair(*type, new CodeDirectory::Builder(*type)));
}
delete mNewCode;
if (mTempMayExist)
::remove(tempPath.c_str()); // ignore error (can't do anything about it)
+
this->kill();
}
// copy metadata from original file...
copy(sourcePath.c_str(), NULL, COPYFILE_SECURITY | COPYFILE_METADATA);
-
+
+#if TARGET_OS_OSX
+ // determine AFSC status if we are told to preserve compression
+ bool conductCompression = false;
+ cmpInfo cInfo;
+ if (writer->getPreserveAFSC()) {
+ if (queryCompressionInfo(sourcePath.c_str(), &cInfo) == 0) {
+ if (cInfo.compressionType != 0 && cInfo.compressedSize > 0)
+ conductCompression = true;
+ }
+ }
+#endif
+
// ... but explicitly update the timestamps since we did change the file
char buf;
mFd.read(&buf, sizeof(buf), 0);
// move the new file into place
UnixError::check(::rename(tempPath.c_str(), sourcePath.c_str()));
mTempMayExist = false; // we renamed it away
+
+#if TARGET_OS_OSX
+ // if the original file was compressed, compress the new file after move
+ if (conductCompression) {
+ CFMutableDictionaryRef options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFStringRef val = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), cInfo.compressionType);
+ CFDictionarySetValue(options, kAFSCCompressionTypes, val);
+ CFRelease(val);
+
+ CompressionQueueContext compressionQueue = CreateCompressionQueue(NULL, NULL, NULL, NULL, options);
+
+ if (!CompressFile(compressionQueue, sourcePath.c_str(), NULL)) {
+ secinfo("signer", "%p Failed to queue compression of file %s", this, sourcePath.c_str());
+ MacOSError::throwMe(errSecCSInternalError);
+ }
+ FinishCompressionAndCleanUp(compressionQueue);
+
+ compressionQueue = NULL;
+ CFRelease(options);
+ }
+#endif
+
}
this->writer->flush();
}
#include <security_utilities/unix++.h>
#include <security_utilities/unixchild.h>
+#include <sys/cdefs.h>
+
+#if TARGET_OS_OSX
+__BEGIN_DECLS
+#include <AppleFSCompression/AppleFSCompression.h>
+__END_DECLS
+#endif
+
namespace Security {
namespace CodeSigning {
mFd.close();
}
+//Check the magic darwinup xattr
+bool SingleDiskRep::appleInternalForcePlatform() const
+{
+ return mFd.hasExtendedAttribute("com.apple.root.installed");
+}
+
//
// The recommended identifier of a SingleDiskRep is, absent any better clue,
// the basename of its path.
size_t execSegLimit(const Architecture *arch); // size of executable segment
UnixPlusPlus::FileDesc &fd(); // readable fd for this file
void flush(); // close cached fd
-
+
+ bool appleInternalForcePlatform() const;
+
std::string recommendedIdentifier(const SigningContext &ctx); // basename(path)
void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags);
// xar++ - interface to XAR-format archive files
//
#include "xar++.h"
+#include "notarization.h"
#include <security_utilities/cfutilities.h>
#include <Security/Security.h>
{
if ((mXar = ::xar_open(path, READ)) == NULL)
return;
+
+ mPath = std::string(path);
xar_signature_t sig = ::xar_signature_first(mXar);
// read signatures until we find a CMS signature
return NULL;
}
+void Xar::registerStapledNotarization()
+{
+ registerStapledTicketInPackage(mPath);
+}
+
+CFDataRef Xar::createPackageChecksum()
+{
+ xar_signature_t sig = NULL;
+
+ // Always prefer a CMS signature to a class signature and return early
+ // if no appropriate signature has been found.
+ if (mSigCMS) {
+ sig = mSigCMS;
+ } else if (mSigClassic) {
+ sig = mSigClassic;
+ } else {
+ return NULL;
+ }
+
+ // Extract the signed data from the xar, which is actually just the checksum
+ // we use as an identifying hash.
+ uint8_t *data = NULL;
+ uint32_t length;
+ if (xar_signature_copy_signed_data(sig, &data, &length, NULL, NULL, NULL) != 0) {
+ secerror("Unable to extract package hash for package: %s", mPath.c_str());
+ return NULL;
+ }
+
+ return makeCFData(data, length);
+}
+
+SecCSDigestAlgorithm Xar::checksumDigestAlgorithm()
+{
+ int32_t error = 0;
+ const char* value = NULL;
+ unsigned long size = 0;
+
+ if (mXar == NULL) {
+ secerror("Evaluating checksum digest on bad xar: %s", mPath.c_str());
+ return kSecCodeSignatureNoHash;
+ }
+
+ error = xar_prop_get((xar_file_t)mXar, "checksum/size", &value);
+ if (error == -1) {
+ secerror("Unable to extract package checksum size: %s", mPath.c_str());
+ return kSecCodeSignatureNoHash;
+ }
+
+ size = strtoul(value, NULL, 10);
+ switch (size) {
+ case CC_SHA1_DIGEST_LENGTH:
+ return kSecCodeSignatureHashSHA1;
+ case CC_SHA256_DIGEST_LENGTH:
+ return kSecCodeSignatureHashSHA256;
+ case CC_SHA512_DIGEST_LENGTH:
+ return kSecCodeSignatureHashSHA512;
+ case CC_MD5_DIGEST_LENGTH:
+ default:
+ return kSecCodeSignatureNoHash;
+ }
+}
} // end namespace CodeSigning
} // end namespace Security
#include <security_utilities/utilities.h>
#include <CoreFoundation/CoreFoundation.h>
+#include "CSCommon.h"
extern "C" {
#include <xar/xar.h>
operator bool() const { return mXar != 0; }
bool isSigned() const { return mSigClassic != 0 || mSigCMS != 0; }
-
+
+ void registerStapledNotarization();
+ CFDataRef createPackageChecksum();
CFArrayRef copyCertChain();
+ SecCSDigestAlgorithm checksumDigestAlgorithm();
private:
xar_t mXar;
xar_signature_t mSigClassic;
xar_signature_t mSigCMS;
+ std::string mPath;
};
precheckAccess(path, context);
Message msg("assess");
xpc_dictionary_set_string(msg, "path", cfString(path).c_str());
- xpc_dictionary_set_int64(msg, "flags", flags);
+ xpc_dictionary_set_uint64(msg, "flags", flags);
CFRef<CFMutableDictionaryRef> ctx = makeCFMutableDictionary();
if (context)
CFDictionaryApplyFunction(context, copyCFDictionary, ctx);
} else
MacOSError::throwMe(errSecCSInvalidObjectRef);
}
- xpc_dictionary_set_int64(msg, "flags", flags);
+ xpc_dictionary_set_uint64(msg, "flags", flags);
CFRef<CFMutableDictionaryRef> ctx = makeCFMutableDictionary();
if (context)
CFDictionaryApplyFunction(context, copyCFDictionary, ctx);
*result = xpc_dictionary_get_bool(msg,"result") ? kCFBooleanTrue : kCFBooleanFalse;
}
+void xpcEngineCheckNotarized(CFBooleanRef* result)
+{
+ Message msg("check-notarized");
+
+ msg.send();
+
+ if (int64_t error = xpc_dictionary_get_int64(msg, "error")) {
+ MacOSError::throwMe((int)error);
+ }
+
+ *result = xpc_dictionary_get_bool(msg,"result") ? kCFBooleanTrue : kCFBooleanFalse;
+}
+
+void xpcEngineTicketRegister(CFDataRef ticketData)
+{
+ Message msg("ticket-register");
+ xpc_dictionary_set_data(msg, "ticketData", CFDataGetBytePtr(ticketData), CFDataGetLength(ticketData));
+
+ msg.send();
+
+ if (int64_t error = xpc_dictionary_get_int64(msg, "error")) {
+ MacOSError::throwMe((int)error);
+ }
+}
+
+void xpcEngineTicketLookup(CFDataRef hashData, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date)
+{
+ Message msg("ticket-lookup");
+ xpc_dictionary_set_data(msg, "hashData", CFDataGetBytePtr(hashData), CFDataGetLength(hashData));
+ xpc_dictionary_set_uint64(msg, "hashType", hashType);
+ xpc_dictionary_set_uint64(msg, "flags", flags);
+
+ msg.send();
+
+ if (int64_t error = xpc_dictionary_get_int64(msg, "error")) {
+ MacOSError::throwMe((int)error);
+ }
+
+ double local_date = xpc_dictionary_get_double(msg, "date");
+ if (date && !isnan(local_date)) {
+ *date = local_date;
+ }
+}
+
} // end namespace CodeSigning
} // end namespace Security
bool xpcEngineControl(const char *name);
void xpcEngineRecord(CFDictionaryRef info);
void xpcEngineCheckDevID(CFBooleanRef* result);
+void xpcEngineCheckNotarized(CFBooleanRef* result);
+void xpcEngineTicketRegister(CFDataRef ticketData);
+void xpcEngineTicketLookup(CFDataRef hashData, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date);
} // end namespace CodeSigning
} // end namespace Security
{ maker.cdhash(digest); }
| "platform" { int32_t ident; } eql ident=integer
{ maker.platform(ident); }
+ | "notarized"
+ { maker.put(opNotarized); }
| LPAREN { string name; } name=identifierString RPAREN
{ maker.put(opNamedCode); maker.put(name); }
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-typedef struct cssm_spi_ac_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_ac_funcs {
CSSM_RETURN (CSSMACI *AuthCompute)
(CSSM_AC_HANDLE ACHandle,
const CSSM_TUPLEGROUP *BaseAuthorizations,
#ifndef _CSSMAPPLE_PRIV_H_
#define _CSSMAPPLE_PRIV_H_ 1
+#include <TargetConditionals.h>
+
+#if TARGET_OS_OSX
+
#include <Security/cssmtype.h>
#include <Security/cssmapple.h>
};
/* AppleCSPDL passthrough parameters */
-typedef struct cssm_applecspdl_db_recode_parameters
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_recode_parameters
{
CSSM_DATA dbBlob;
CSSM_DATA extraData;
-} CSSM_APPLECSPDL_RECODE_PARAMETERS, *CSSM_APPLECSPDL_RECODE_PARAMETERS_PTR;
+} CSSM_APPLECSPDL_RECODE_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_APPLECSPDL_RECODE_PARAMETERS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_applecspdl_db_copy_blob_parameters
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_copy_blob_parameters
{
CSSM_DATA blob;
-} CSSM_APPLECSPDL_DB_COPY_BLOB_PARAMETERS;
+} CSSM_APPLECSPDL_DB_COPY_BLOB_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_applecspdl_db_insert_without_encryption_parameters
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_insert_without_encryption_parameters
{
CSSM_DB_RECORDTYPE recordType;
CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes;
CSSM_DATA data;
-} CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS;
+} CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_applecspdl_db_modify_without_encryption_parameters
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_modify_without_encryption_parameters
{
CSSM_DB_RECORDTYPE recordType;
CSSM_DB_UNIQUE_RECORD_PTR uniqueID;
CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes;
CSSM_DATA *data;
CSSM_DB_MODIFY_MODE modifyMode;
-} CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS;
+} CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_applecspdl_db_get_without_encryption_parameters
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_get_without_encryption_parameters
{
CSSM_DB_UNIQUE_RECORD_PTR uniqueID;
CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes;
-} CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS;
+} CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_applecspdl_db_create_with_blob_parameters
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_applecspdl_db_create_with_blob_parameters
{
const char *dbName;
const CSSM_NET_ADDRESS *dbLocation;
const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry;
const void *openParameters;
const CSSM_DATA *blob;
-} CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS;
+} CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
#ifdef __cplusplus
}
#endif
+#endif /* TARGET_OS_OSX */
+
#endif /* _CSSMAPPLE_PRIV_H_ */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-typedef struct cssm_spi_cl_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_cl_funcs {
CSSM_RETURN (CSSMCLI *CertCreateTemplate)
(CSSM_CL_HANDLE CLHandle,
uint32 NumberOfFields,
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-typedef struct cssm_spi_csp_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_csp_funcs {
CSSM_RETURN (CSSMCSPI *EventNotify)
(CSSM_CSP_HANDLE CSPHandle,
CSSM_CONTEXT_EVENT Event,
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-typedef struct cssm_spi_dl_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_dl_funcs {
CSSM_RETURN (CSSMDLI *DbOpen)
(CSSM_DL_HANDLE DLHandle,
const char *DbName,
char *Name; /* name string */
} CSSM_KR_NAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_kr_profile {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_profile {
CSSM_KR_NAME UserName; /* name of the user */
CSSM_CERTGROUP_PTR UserCertificate; /* public key certificate of the user */
CSSM_CERTGROUP_PTR KRSCertChain; /* cert chain for the KRSP coordinator */
CSSM_DATA_PTR KRSPExtensions; /* reserved for extensions specific to KRSPs */
} CSSM_KR_PROFILE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KR_PROFILE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_kr_wrappedproductinfo {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_wrappedproductinfo {
CSSM_VERSION StandardVersion;
CSSM_STRING StandardDescription;
CSSM_VERSION ProductVersion;
uint32 ProductFlags;
} CSSM_KR_WRAPPEDPRODUCT_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KR_WRAPPEDPRODUCT_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_krsubservice {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_krsubservice {
uint32 SubServiceId;
char *Description; /* Description of this sub service */
CSSM_KR_WRAPPEDPRODUCT_INFO WrappedProduct;
-} CSSM_KRSUBSERVICE, *CSSM_KRSUBSERVICE_PTR;
+} CSSM_KRSUBSERVICE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KRSUBSERVICE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef uint32 CSSM_KR_POLICY_TYPE;
#define CSSM_KR_INDIV_POLICY (0x00000001)
#define CSSM_KR_OPTIMIZE (0x00000010)
#define CSSM_KR_DROP_WORKFACTOR (0x00000020)
-typedef struct cssm_kr_policy_list_item {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_policy_list_item {
struct kr_policy_list_item *next;
CSSM_ALGORITHMS AlgorithmId;
CSSM_ENCRYPT_MODE Mode;
CSSM_CONTEXT_TYPE AlgClass;
} CSSM_KR_POLICY_LIST_ITEM DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KR_POLICY_LIST_ITEM_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_kr_policy_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kr_policy_info {
CSSM_BOOL krbNotAllowed;
uint32 numberOfEntries;
CSSM_KR_POLICY_LIST_ITEM *policyEntry;
/* Data types for Key Recovery SPI */
-typedef struct cssm_spi_kr_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_kr_funcs {
CSSM_RETURN (CSSMKRI *RegistrationRequest)
(CSSM_KRSP_HANDLE KRSPHandle,
CSSM_CC_HANDLE KRRegistrationContextHandle,
void *CssmNotifyCallbackCtx,
uint32 SubserviceId,
CSSM_SERVICE_TYPE ServiceType,
- CSSM_MODULE_EVENT EventType);
+ CSSM_MODULE_EVENT EventType) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef uint32 CSSM_CONTEXT_EVENT;
enum {
CSSM_CONTEXT_EVENT_UPDATE = 3
};
-typedef struct cssm_module_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_module_funcs {
CSSM_SERVICE_TYPE ServiceType;
uint32 NumberOfServiceFuncs;
const CSSM_PROC_ADDR *ServiceFuncs;
size_t num,
size_t size) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_upcalls {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_upcalls {
CSSM_UPCALLS_MALLOC malloc_func;
CSSM_UPCALLS_FREE free_func;
CSSM_UPCALLS_REALLOC realloc_func;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-typedef struct cssm_spi_tp_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_spi_tp_funcs {
CSSM_RETURN (CSSMTPI *SubmitCredRequest)
(CSSM_TP_HANDLE TPHandle,
const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
typedef CSSM_SERVICE_MASK CSSM_SERVICE_TYPE;
-typedef struct cssm_subservice_uid {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_subservice_uid {
CSSM_GUID Guid;
CSSM_VERSION Version;
uint32 SubserviceId;
void* AppNotifyCallbackCtx,
uint32 SubserviceId,
CSSM_SERVICE_TYPE ServiceType,
- CSSM_MODULE_EVENT EventType);
+ CSSM_MODULE_EVENT EventType) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef uint32 CSSM_ATTACH_FLAGS;
enum {
CSSM_ADDR_NAME = 4 /* char* - qualified by access method */
};
-typedef struct cssm_net_address {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_net_address {
CSSM_NET_ADDRESS_TYPE AddressType;
CSSM_DATA Address;
} CSSM_NET_ADDRESS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_NET_ADDRESS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
};
typedef CSSM_RETURN (CSSMAPI *CSSM_CALLBACK)
- (CSSM_DATA_PTR OutData, void *CallerCtx);
+ (CSSM_DATA_PTR OutData, void *CallerCtx) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_crypto_data {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_crypto_data {
CSSM_DATA Param;
CSSM_CALLBACK Callback;
void *CallerCtx;
CSSM_LIST_ELEMENT_PTR Tail; /* tail of the list */
} CSSM_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_LIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_list_element {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_list_element {
struct cssm_list_element *NextElement; /* next list element */
CSSM_WORDID_TYPE WordID; /* integer identifier associated */
/* with a Word value */
CSSM_LIST Sublist; /* sublist */
CSSM_DATA Word; /* a byte-string */
} Element;
-} CSSM_LIST_ELEMENT;
+} CSSM_LIST_ELEMENT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct { /* 5-tuple definition */
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { /* 5-tuple definition */
CSSM_LIST Issuer; /* issuer, or empty if ACL */
CSSM_LIST Subject; /* subject */
CSSM_BOOL Delegate; /* permission to delegate */
CSSM_LIST ValidityPeriod; /* validity information (dates) */
} CSSM_TUPLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TUPLE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tuplegroup {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tuplegroup {
uint32 NumberOfTuples;
CSSM_TUPLE_PTR Tuples;
} CSSM_TUPLEGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TUPLEGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_SAMPLE_TYPE_THRESHOLD = CSSM_WORDID_THRESHOLD
};
-typedef struct cssm_sample {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_sample {
CSSM_LIST TypedSample;
const CSSM_SUBSERVICE_UID *Verifier;
} CSSM_SAMPLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_SAMPLE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_samplegroup {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_samplegroup {
uint32 NumberOfSamples;
const CSSM_SAMPLE *Samples;
} CSSM_SAMPLEGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_SAMPLEGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
void *AllocRef;
} CSSM_MEMORY_FUNCS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_MEMORY_FUNCS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef CSSM_MEMORY_FUNCS CSSM_API_MEMORY_FUNCS;
-typedef CSSM_API_MEMORY_FUNCS *CSSM_API_MEMORY_FUNCS_PTR;
+typedef CSSM_MEMORY_FUNCS CSSM_API_MEMORY_FUNCS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
+typedef CSSM_API_MEMORY_FUNCS *CSSM_API_MEMORY_FUNCS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef CSSM_RETURN (CSSMAPI * CSSM_CHALLENGE_CALLBACK)
(const CSSM_LIST *Challenge,
CSSM_SAMPLEGROUP_PTR Response,
void *CallerCtx,
- const CSSM_MEMORY_FUNCS *MemFuncs);
+ const CSSM_MEMORY_FUNCS *MemFuncs) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef uint32 CSSM_CERT_TYPE, *CSSM_CERT_TYPE_PTR;
enum {
CSSM_CL_CUSTOM_CERT_ENCODING = 0x8000
};
-typedef struct cssm_encoded_cert {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_encoded_cert {
CSSM_CERT_TYPE CertType; /* type of certificate */
CSSM_CERT_ENCODING CertEncoding; /* encoding for this packed cert */
CSSM_DATA CertBlob; /* packed cert */
void *ParsedCert; /* parsed cert (to be typecast) */
} CSSM_PARSED_CERT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PARSED_CERT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_cert_pair {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_cert_pair {
CSSM_ENCODED_CERT EncodedCert; /* an encoded certificate blob */
CSSM_PARSED_CERT ParsedCert; /* equivalent parsed certificate */
} CSSM_CERT_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERT_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_CERTGROUP_CERT_PAIR = 0x03
};
-typedef struct cssm_certgroup {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_certgroup {
CSSM_CERT_TYPE CertType;
CSSM_CERT_ENCODING CertEncoding;
uint32 NumCerts; /* # of certificates in this list */
CSSM_CERTGROUP_TYPE CertGroupType;
/* type of structure in the GroupList */
void *Reserved; /* reserved for implementation dependent use */
-} CSSM_CERTGROUP, *CSSM_CERTGROUP_PTR;
+} CSSM_CERTGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERTGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_base_certs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_base_certs {
CSSM_TP_HANDLE TPHandle;
CSSM_CL_HANDLE CLHandle;
CSSM_CERTGROUP Certs;
} CSSM_BASE_CERTS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_BASE_CERTS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_access_credentials {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_access_credentials {
CSSM_STRING EntryTag;
CSSM_BASE_CERTS BaseCerts;
CSSM_SAMPLEGROUP Samples;
CSSM_ACL_AUTHORIZATION_TAG *AuthTags;
} CSSM_AUTHORIZATIONGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_AUTHORIZATIONGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_acl_validity_period {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_validity_period {
CSSM_DATA StartDate;
CSSM_DATA EndDate;
} CSSM_ACL_VALIDITY_PERIOD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_VALIDITY_PERIOD_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_acl_entry_prototype {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_entry_prototype {
CSSM_LIST TypedSubject;
CSSM_BOOL Delegate;
CSSM_AUTHORIZATIONGROUP Authorization;
CSSM_STRING EntryTag;
} CSSM_ACL_ENTRY_PROTOTYPE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_ENTRY_PROTOTYPE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_acl_owner_prototype {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_owner_prototype {
CSSM_LIST TypedSubject;
CSSM_BOOL Delegate;
} CSSM_ACL_OWNER_PROTOTYPE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_OWNER_PROTOTYPE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
(const CSSM_LIST *SubjectRequest,
CSSM_LIST_PTR SubjectResponse,
void *CallerContext,
- const CSSM_MEMORY_FUNCS *MemFuncs);
+ const CSSM_MEMORY_FUNCS *MemFuncs) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_acl_entry_input {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_entry_input {
CSSM_ACL_ENTRY_PROTOTYPE Prototype;
CSSM_ACL_SUBJECT_CALLBACK Callback;
void *CallerContext;
} CSSM_ACL_ENTRY_INPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_ENTRY_INPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_resource_control_context {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_resource_control_context {
CSSM_ACCESS_CREDENTIALS_PTR AccessCred;
CSSM_ACL_ENTRY_INPUT InitialAclEntry;
} CSSM_RESOURCE_CONTROL_CONTEXT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_RESOURCE_CONTROL_CONTEXT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef CSSM_HANDLE CSSM_ACL_HANDLE;
-typedef struct cssm_acl_entry_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_entry_info {
CSSM_ACL_ENTRY_PROTOTYPE EntryPublicInfo;
CSSM_ACL_HANDLE EntryHandle;
} CSSM_ACL_ENTRY_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_ACL_ENTRY_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_ACL_EDIT_MODE_REPLACE = 3
};
-typedef struct cssm_acl_edit {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_acl_edit {
CSSM_ACL_EDIT_MODE EditMode;
CSSM_ACL_HANDLE OldEntryHandle;
const CSSM_ACL_ENTRY_INPUT *NewEntry;
CSSM_ALGMODE_VENDOR_DEFINED = CSSM_ALGMODE_NONE + 0x80000000
};
-typedef struct cssm_keyheader {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_keyheader {
CSSM_HEADERVERSION HeaderVersion; /* Key header version */
CSSM_GUID CspId; /* GUID of CSP generating the key */
CSSM_KEYBLOB_TYPE BlobType; /* See BlobType enum */
uint32 Reserved;
} CSSM_KEYHEADER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KEYHEADER_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_key {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_key {
CSSM_KEYHEADER KeyHeader; /* Fixed length key header */
CSSM_DATA KeyData; /* Variable length key data */
} CSSM_KEY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KEY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef CSSM_KEY CSSM_WRAP_KEY, *CSSM_WRAP_KEY_PTR;
+typedef CSSM_KEY CSSM_WRAP_KEY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_WRAP_KEY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef uint32 CSSM_CSPTYPE;
enum {
typedef CSSM_ALGORITHMS CSSM_KEY_TYPE;
-typedef struct cssm_context_attribute {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_context_attribute {
CSSM_ATTRIBUTE_TYPE AttributeType;
uint32 AttributeLength;
- union cssm_context_attribute_value {
+ union DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_context_attribute_value {
char *String;
uint32 Uint32;
CSSM_ACCESS_CREDENTIALS_PTR AccessCredentials;
CSSM_DL_DB_HANDLE_PTR DLDBHandle;
struct cssm_kr_profile *KRProfile;
} Attribute;
-} CSSM_CONTEXT_ATTRIBUTE, *CSSM_CONTEXT_ATTRIBUTE_PTR;
+} CSSM_CONTEXT_ATTRIBUTE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CONTEXT_ATTRIBUTE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_context {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_context {
CSSM_CONTEXT_TYPE ContextType;
CSSM_ALGORITHMS AlgorithmType;
uint32 NumberOfAttributes;
CSSM_PKCS_OAEP_PSOURCE_Pspecified = CSSM_PKCS_OAEP_PSOURCE_NONE + 1
};
-typedef struct cssm_pkcs1_oaep_params {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_pkcs1_oaep_params {
uint32 HashAlgorithm;
CSSM_DATA HashParams;
CSSM_PKCS_OAEP_MGF MGF;
CSSM_VALUE_NOT_AVAILABLE = -1
};
-typedef struct cssm_pkcs5_pbkdf1_params {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_pkcs5_pbkdf1_params {
CSSM_DATA Passphrase;
CSSM_DATA InitVector;
} CSSM_PKCS5_PBKDF1_PARAMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PKCS5_PBKDF1_PARAMS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1 = 0
};
-typedef struct cssm_pkcs5_pbkdf2_params {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_pkcs5_pbkdf2_params {
CSSM_DATA Passphrase;
CSSM_PKCS5_PBKDF2_PRF PseudoRandomFunction;
} CSSM_PKCS5_PBKDF2_PARAMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PKCS5_PBKDF2_PARAMS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_kea_derive_params {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_kea_derive_params {
CSSM_DATA Rb;
CSSM_DATA Yb;
} CSSM_KEA_DERIVE_PARAMS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KEA_DERIVE_PARAMS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* Data Types for Trust Policy Services */
-typedef struct cssm_tp_authority_id {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_authority_id {
CSSM_DATA *AuthorityCert;
CSSM_NET_ADDRESS_PTR AuthorityLocation;
} CSSM_TP_AUTHORITY_ID DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_AUTHORITY_ID_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
typedef CSSM_RETURN (CSSMAPI * CSSM_TP_VERIFICATION_RESULTS_CALLBACK)
(CSSM_MODULE_HANDLE ModuleHandle,
void *CallerCtx,
- CSSM_DATA_PTR VerifiedCert);
+ CSSM_DATA_PTR VerifiedCert) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* From CL */
-typedef CSSM_DATA CSSM_OID, *CSSM_OID_PTR;
+typedef CSSM_DATA CSSM_OID DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_OID_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_field {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_field {
CSSM_OID FieldOid;
CSSM_DATA FieldValue;
} CSSM_FIELD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_FIELD_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* TP Again. */
-typedef struct cssm_tp_policyinfo {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_policyinfo {
uint32 NumberOfPolicyIds;
CSSM_FIELD_PTR PolicyIds;
void *PolicyControl;
typedef char *CSSM_TIMESTRING;
/* From DL. */
-typedef struct cssm_dl_db_list {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_dl_db_list {
uint32 NumHandles;
CSSM_DL_DB_HANDLE_PTR DLDBHandle;
} CSSM_DL_DB_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DL_DB_LIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* TP Again. */
-typedef struct cssm_tp_callerauth_context {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_callerauth_context {
CSSM_TP_POLICYINFO Policy;
CSSM_TIMESTRING VerifyTime;
CSSM_TP_STOP_ON VerificationAbortOn;
CSSM_CRL_ENCODING_MULTIPLE = 0x7FFE
};
-typedef struct cssm_encoded_crl {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_encoded_crl {
CSSM_CRL_TYPE CrlType; /* type of CRL */
CSSM_CRL_ENCODING CrlEncoding; /* encoding for this packed CRL */
CSSM_DATA CrlBlob; /* packed CRL */
void *ParsedCrl; /* parsed CRL (to be typecast) */
} CSSM_PARSED_CRL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_PARSED_CRL_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_crl_pair {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_crl_pair {
CSSM_ENCODED_CRL EncodedCrl; /* an encoded CRL blob */
CSSM_PARSED_CRL ParsedCrl; /* equivalent parsed CRL */
} CSSM_CRL_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CRL_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_CRLGROUP_CRL_PAIR = 0x03
};
-typedef struct cssm_crlgroup {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_crlgroup {
CSSM_CRL_TYPE CrlType;
CSSM_CRL_ENCODING CrlEncoding;
uint32 NumberOfCrls;
CSSM_CRL_PAIR_PTR PairCrlList;
} GroupCrlList;
CSSM_CRLGROUP_TYPE CrlGroupType;
-} CSSM_CRLGROUP, *CSSM_CRLGROUP_PTR;
+} CSSM_CRLGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CRLGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_fieldgroup {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_fieldgroup {
int NumberOfFields; /* number of fields in the array */
CSSM_FIELD_PTR Fields; /* array of fields */
} CSSM_FIELDGROUP DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_FIELDGROUP_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_EVIDENCE_FORM_TUPLEGROUP = 0x9
};
-typedef struct cssm_evidence {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_evidence {
CSSM_EVIDENCE_FORM EvidenceForm;
void *Evidence; /* Evidence content */
} CSSM_EVIDENCE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_EVIDENCE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tp_verify_context {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_verify_context {
CSSM_TP_ACTION Action;
CSSM_DATA ActionData;
CSSM_CRLGROUP Crls;
CSSM_TP_CALLERAUTH_CONTEXT_PTR Cred;
} CSSM_TP_VERIFY_CONTEXT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_VERIFY_CONTEXT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tp_verify_context_result {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_verify_context_result {
uint32 NumberOfEvidences;
CSSM_EVIDENCE_PTR Evidence;
} CSSM_TP_VERIFY_CONTEXT_RESULT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_VERIFY_CONTEXT_RESULT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tp_request_set {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_request_set {
uint32 NumberOfRequests;
void *Requests;
} CSSM_TP_REQUEST_SET DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_REQUEST_SET_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
submit-retrieve function pair */
};
-typedef struct cssm_tp_confirm_response {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_confirm_response {
uint32 NumberOfResponses;
CSSM_TP_CONFIRM_STATUS_PTR Responses;
} CSSM_TP_CONFIRM_RESPONSE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CONFIRM_RESPONSE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_ELAPSED_TIME_COMPLETE = -2
};
-typedef struct cssm_tp_certissue_input {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certissue_input {
CSSM_SUBSERVICE_UID CSPSubserviceUid;
CSSM_CL_HANDLE CLHandle;
uint32 NumberOfTemplateFields;
a revocation of the certificate */
};
-typedef struct cssm_tp_certissue_output {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certissue_output {
CSSM_TP_CERTISSUE_STATUS IssueStatus;
CSSM_CERTGROUP_PTR CertGroup;
CSSM_TP_SERVICES PerformedServiceRequests;
jurisdiction of this certificate */
};
-typedef struct cssm_tp_certchange_input {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certchange_input {
CSSM_TP_CERTCHANGE_ACTION Action;
CSSM_TP_CERTCHANGE_REASON Reason;
CSSM_CL_HANDLE CLHandle;
the cert state */
};
-typedef struct cssm_tp_certchange_output {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certchange_output {
CSSM_TP_CERTCHANGE_STATUS ActionStatus;
CSSM_FIELD RevokeInfo;
} CSSM_TP_CERTCHANGE_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTCHANGE_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tp_certverify_input {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certverify_input {
CSSM_CL_HANDLE CLHandle;
CSSM_DATA_PTR Cert;
CSSM_TP_VERIFY_CONTEXT_PTR VerifyContext;
CSSM_TP_CERTVERIFY_UNKNOWN_CRITICAL_EXT = 0x10
};
-typedef struct cssm_tp_certverify_output {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certverify_output {
CSSM_TP_CERTVERIFY_STATUS VerifyStatus;
uint32 NumberOfEvidence;
CSSM_EVIDENCE_PTR Evidence;
} CSSM_TP_CERTVERIFY_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTVERIFY_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tp_certnotarize_input {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certnotarize_input {
CSSM_CL_HANDLE CLHandle;
uint32 NumberOfFields;
CSSM_FIELD_PTR MoreFields;
not authorized */
};
-typedef struct cssm_tp_certnotarize_output {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certnotarize_output {
CSSM_TP_CERTNOTARIZE_STATUS NotarizeStatus;
CSSM_CERTGROUP_PTR NotarizedCertGroup;
CSSM_TP_SERVICES PerformedServiceRequests;
} CSSM_TP_CERTNOTARIZE_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTNOTARIZE_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tp_certreclaim_input {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certreclaim_input {
CSSM_CL_HANDLE CLHandle;
uint32 NumberOfSelectionFields;
CSSM_FIELD_PTR SelectionFields;
authorized */
};
-typedef struct cssm_tp_certreclaim_output {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_certreclaim_output {
CSSM_TP_CERTRECLAIM_STATUS ReclaimStatus;
CSSM_CERTGROUP_PTR ReclaimedCertGroup;
CSSM_LONG_HANDLE KeyCacheHandle;
} CSSM_TP_CERTRECLAIM_OUTPUT DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_TP_CERTRECLAIM_OUTPUT_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_tp_crlissue_input {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_crlissue_input {
CSSM_CL_HANDLE CLHandle;
uint32 CrlIdentifier;
CSSM_TIMESTRING CrlThisTime;
next CRL has been returned. */
};
-typedef struct cssm_tp_crlissue_output {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_tp_crlissue_output {
CSSM_TP_CRLISSUE_STATUS IssueStatus;
CSSM_ENCODED_CRL_PTR Crl;
CSSM_TIMESTRING CrlNextTime;
CSSM_CERT_BUNDLE_ENCODING_PGP = 0x05
};
-typedef struct cssm_cert_bundle_header {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_cert_bundle_header {
CSSM_CERT_BUNDLE_TYPE BundleType;
CSSM_CERT_BUNDLE_ENCODING BundleEncoding;
} CSSM_CERT_BUNDLE_HEADER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERT_BUNDLE_HEADER_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_cert_bundle {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_cert_bundle {
CSSM_CERT_BUNDLE_HEADER BundleHeader;
CSSM_DATA Bundle;
} CSSM_CERT_BUNDLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_CERT_BUNDLE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX = 8
};
-typedef struct cssm_db_attribute_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_attribute_info {
CSSM_DB_ATTRIBUTE_NAME_FORMAT AttributeNameFormat;
- union cssm_db_attribute_label {
+ union DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_attribute_label {
char *AttributeName; /* e.g., "record label" */
CSSM_OID AttributeOID; /* e.g., CSSMOID_RECORDLABEL */
uint32 AttributeID; /* e.g., FOUR_CHAR_CODE('recl') */
} Label;
CSSM_DB_ATTRIBUTE_FORMAT AttributeFormat;
-} CSSM_DB_ATTRIBUTE_INFO, *CSSM_DB_ATTRIBUTE_INFO_PTR;
+} CSSM_DB_ATTRIBUTE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_ATTRIBUTE_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_db_attribute_data {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_attribute_data {
CSSM_DB_ATTRIBUTE_INFO Info;
uint32 NumberOfValues;
CSSM_DATA_PTR Value;
CSSM_DB_CERT_USE_PRIVACY = 0x00000020 /* use cert for confidentiality only */
};
-typedef struct cssm_db_record_attribute_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_record_attribute_info {
CSSM_DB_RECORDTYPE DataRecordType;
uint32 NumberOfAttributes;
CSSM_DB_ATTRIBUTE_INFO_PTR AttributeInfo;
} CSSM_DB_RECORD_ATTRIBUTE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_RECORD_ATTRIBUTE_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_db_record_attribute_data {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_record_attribute_data {
CSSM_DB_RECORDTYPE DataRecordType;
uint32 SemanticInformation;
uint32 NumberOfAttributes;
CSSM_DB_ATTRIBUTE_DATA_PTR AttributeData;
} CSSM_DB_RECORD_ATTRIBUTE_DATA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_db_parsing_module_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_parsing_module_info {
CSSM_DB_RECORDTYPE RecordType;
CSSM_SUBSERVICE_UID ModuleSubserviceUid;
} CSSM_DB_PARSING_MODULE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_PARSING_MODULE_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_DB_INDEX_ON_RECORD = 2
};
-typedef struct cssm_db_index_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_index_info {
CSSM_DB_INDEX_TYPE IndexType;
CSSM_DB_INDEXED_DATA_LOCATION IndexedDataLocation;
CSSM_DB_ATTRIBUTE_INFO Info;
} CSSM_DB_INDEX_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_INDEX_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_db_unique_record {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_unique_record {
CSSM_DB_INDEX_INFO RecordLocator;
CSSM_DATA RecordIdentifier;
} CSSM_DB_UNIQUE_RECORD DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DB_UNIQUE_RECORD_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_db_record_index_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_record_index_info {
CSSM_DB_RECORDTYPE DataRecordType;
uint32 NumberOfIndexes;
CSSM_DB_INDEX_INFO_PTR IndexInfo;
CSSM_DB_MODIFY_ATTRIBUTE_REPLACE = CSSM_DB_MODIFY_ATTRIBUTE_NONE + 3
};
-typedef struct cssm_dbinfo {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_dbinfo {
/* meta information about each record type stored in this
data store including meta information about record
attributes and indexes */
CSSM_DB_OR = 2
};
-typedef struct cssm_selection_predicate {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_selection_predicate {
CSSM_DB_OPERATOR DbOperator;
CSSM_DB_ATTRIBUTE_DATA Attribute;
} CSSM_SELECTION_PREDICATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_SELECTION_PREDICATE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_QUERY_SIZELIMIT_NONE = 0
};
-typedef struct cssm_query_limits {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_query_limits {
uint32 TimeLimit; /* in seconds */
uint32 SizeLimit; /* max. number of records to return */
} CSSM_QUERY_LIMITS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_QUERY_LIMITS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CSSM_QUERY_RETURN_DATA = 0x01
};
-typedef struct cssm_query {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_query {
CSSM_DB_RECORDTYPE RecordType;
CSSM_DB_CONJUNCTIVE Conjunctive;
uint32 NumSelectionPredicates;
CSSM_DB_FILESYSTEMSCAN_MODE = 1
};
-typedef struct cssm_db_schema_attribute_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_db_schema_attribute_info {
uint32 AttributeId;
char *AttributeName;
CSSM_OID AttributeNameID;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-typedef struct cssm_state_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_state_funcs {
CSSM_RETURN (CSSMAPI *cssm_GetAttachFunctions)
(CSSM_MODULE_HANDLE hAddIn,
CSSM_SERVICE_MASK AddinType,
(const CSSM_MANAGER_EVENT_NOTIFICATION *EventDescription);
} CSSM_STATE_FUNCS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_STATE_FUNCS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_manager_registration_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_manager_registration_info {
/* loading, unloading, dispatch table, and event notification */
CSSM_RETURN (CSSMAPI *Initialize)
(uint32 VerMajor,
#define CSSM_MANAGER_SERVICE_REQUEST 1
#define CSSM_MANAGER_REPLY 2
-typedef struct cssm_manager_event_notification {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_manager_event_notification {
CSSM_SERVICE_MASK DestinationModuleManagerType;
CSSM_SERVICE_MASK SourceModuleManagerType;
CSSM_MANAGER_EVENT_TYPES Event;
";
while (($name, $_) = each %spi) {
print "extern const char *const ${name}NameTable[] = {";
- s/^.*struct cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s
+ s/^.*struct(?: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER)? cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s
or die "bad format in $SPI_H{$name}";
s/CSSM_RETURN \(CSSM[A-Z]*I \*([A-Za-z_]+)\)\s+\([^)]+\)[^;]*;/\t"$1",/g;
print;
/* Data Structures for X.509 Certificates */
-typedef struct cssm_x509_algorithm_identifier {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_algorithm_identifier {
CSSM_OID algorithm;
CSSM_DATA parameters;
} CSSM_X509_ALGORITHM_IDENTIFIER DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_ALGORITHM_IDENTIFIER_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* X509 Distinguished name structure */
-typedef struct cssm_x509_type_value_pair {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_type_value_pair {
CSSM_OID type;
CSSM_BER_TAG valueType; /* The Tag to be used when */
/*this value is BER encoded */
CSSM_DATA value;
} CSSM_X509_TYPE_VALUE_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TYPE_VALUE_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509_rdn {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_rdn {
uint32 numberOfPairs;
CSSM_X509_TYPE_VALUE_PAIR_PTR AttributeTypeAndValue;
} CSSM_X509_RDN DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_RDN_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509_name {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_name {
uint32 numberOfRDNs;
CSSM_X509_RDN_PTR RelativeDistinguishedName;
} CSSM_X509_NAME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_NAME_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* Public key info struct */
-typedef struct cssm_x509_subject_public_key_info {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_subject_public_key_info {
CSSM_X509_ALGORITHM_IDENTIFIER algorithm;
CSSM_DATA subjectPublicKey;
} CSSM_X509_SUBJECT_PUBLIC_KEY_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SUBJECT_PUBLIC_KEY_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509_time {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_time {
CSSM_BER_TAG timeType;
CSSM_DATA time;
} CSSM_X509_TIME DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TIME_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* Validity struct */
-typedef struct x509_validity {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER x509_validity {
CSSM_X509_TIME notBefore;
CSSM_X509_TIME notAfter;
} CSSM_X509_VALIDITY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_VALIDITY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
#define CSSM_X509_OPTION_NOT_PRESENT CSSM_FALSE
typedef CSSM_BOOL CSSM_X509_OPTION;
-typedef struct cssm_x509ext_basicConstraints {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_basicConstraints {
CSSM_BOOL cA;
CSSM_X509_OPTION pathLenConstraintPresent;
uint32 pathLenConstraint;
CSSM_X509_DATAFORMAT_PAIR
} CSSM_X509EXT_DATA_FORMAT;
-typedef struct cssm_x509_extensionTagAndValue {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_extensionTagAndValue {
CSSM_BER_TAG type;
CSSM_DATA value;
} CSSM_X509EXT_TAGandVALUE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_TAGandVALUE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509ext_pair {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_pair {
CSSM_X509EXT_TAGandVALUE tagAndValue;
void *parsedValue;
} CSSM_X509EXT_PAIR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_PAIR_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* Extension structure */
-typedef struct cssm_x509_extension {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_extension {
CSSM_OID extnId;
CSSM_BOOL critical;
CSSM_X509EXT_DATA_FORMAT format;
- union cssm_x509ext_value {
+ union DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_value {
CSSM_X509EXT_TAGandVALUE *tagAndValue;
void *parsedValue;
CSSM_X509EXT_PAIR *valuePair;
CSSM_DATA BERvalue;
} CSSM_X509_EXTENSION DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_EXTENSION_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509_extensions {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_extensions {
uint32 numberOfExtensions;
CSSM_X509_EXTENSION_PTR extensions;
} CSSM_X509_EXTENSIONS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_EXTENSIONS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* X509V3 certificate structure */
-typedef struct cssm_x509_tbs_certificate {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_tbs_certificate {
CSSM_DATA version;
CSSM_DATA serialNumber;
CSSM_X509_ALGORITHM_IDENTIFIER signature;
} CSSM_X509_TBS_CERTIFICATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TBS_CERTIFICATE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* Signature structure */
-typedef struct cssm_x509_signature {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_signature {
CSSM_X509_ALGORITHM_IDENTIFIER algorithmIdentifier;
CSSM_DATA encrypted;
} CSSM_X509_SIGNATURE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SIGNATURE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* Signed certificate structure */
-typedef struct cssm_x509_signed_certificate {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_signed_certificate {
CSSM_X509_TBS_CERTIFICATE certificate;
CSSM_X509_SIGNATURE signature;
} CSSM_X509_SIGNED_CERTIFICATE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SIGNED_CERTIFICATE_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509ext_policyQualifierInfo {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_policyQualifierInfo {
CSSM_OID policyQualifierId;
CSSM_DATA value;
} CSSM_X509EXT_POLICYQUALIFIERINFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_POLICYQUALIFIERINFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509ext_policyQualifiers {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_policyQualifiers {
uint32 numberOfPolicyQualifiers;
CSSM_X509EXT_POLICYQUALIFIERINFO *policyQualifier;
} CSSM_X509EXT_POLICYQUALIFIERS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_POLICYQUALIFIERS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509ext_policyInfo {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509ext_policyInfo {
CSSM_OID policyIdentifier;
CSSM_X509EXT_POLICYQUALIFIERS policyQualifiers;
} CSSM_X509EXT_POLICYINFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509EXT_POLICYINFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* Data Structures for X.509 Certificate Revocations Lists */
/* x509V2 entry in the CRL revokedCertificates sequence */
-typedef struct cssm_x509_revoked_cert_entry {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_revoked_cert_entry {
CSSM_DATA certificateSerialNumber;
CSSM_X509_TIME revocationDate;
CSSM_X509_EXTENSIONS extensions;
} CSSM_X509_REVOKED_CERT_ENTRY DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_REVOKED_CERT_ENTRY_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509_revoked_cert_list {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_revoked_cert_list {
uint32 numberOfRevokedCertEntries;
CSSM_X509_REVOKED_CERT_ENTRY_PTR revokedCertEntry;
} CSSM_X509_REVOKED_CERT_LIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_REVOKED_CERT_LIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/* x509v2 Certificate Revocation List (CRL) (unsigned) structure */
-typedef struct cssm_x509_tbs_certlist {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_tbs_certlist {
CSSM_DATA version;
CSSM_X509_ALGORITHM_IDENTIFIER signature;
CSSM_X509_NAME issuer;
CSSM_X509_EXTENSIONS extensions;
} CSSM_X509_TBS_CERTLIST DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_TBS_CERTLIST_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct cssm_x509_signed_crl {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_signed_crl {
CSSM_X509_TBS_CERTLIST tbsCertList;
CSSM_X509_SIGNATURE signature;
} CSSM_X509_SIGNED_CRL DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_X509_SIGNED_CRL_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
Keychain thisKeychain;
Item thisItem;
- list<CallbackInfo> eventCallbacks;
+ list<CallbackInfo> eventCallbacks = CCallbackMgr::Instance().mEventCallbacks;
+
+ // First, does this process care about this notification? If not, just exit early.
+ bool careAboutEventType = thisEvent == kSecDeleteEvent || thisEvent == kSecKeychainListChangedEvent;
+ bool registeredCallbacksForEventType = false;
+ for (ConstCallbackInfoListIterator ix = eventCallbacks.begin(); ix != eventCallbacks.end(); ++ix)
+ {
+ if ((ix->mEventMask & (1U << thisEvent))) {
+ registeredCallbacksForEventType = true;
+ break;
+ }
+ }
+ if(!careAboutEventType && !registeredCallbacksForEventType) {
+ secinfo("kcnotify", "not processing uninteresting event (%d)", (unsigned int)thisEvent);
+ return;
+ }
+
{
// Lock the global API lock before doing stuff with StorageManager.
// make sure we have a database identifier
else if (thisEvent == kSecKeychainListChangedEvent)
globals().storageManager.forceUserSearchListReread();
- eventCallbacks = CCallbackMgr::Instance().mEventCallbacks;
// We can safely release the global API lock now since thisKeychain and thisItem
// are CFRetained and will be until they go out of scope.
}
if (mWeakSecKeyRef != NULL) {
if (_CFTryRetain(mWeakSecKeyRef) == NULL) {
+ StMaybeLock<Mutex> secKeyCDSAMutex(mWeakSecKeyRef->cdsaKeyMutex);
// mWeakSecKeyRef is not really valid, pointing to SecKeyRef which going to die - it is somewhere between last CFRelease and entering into mutex-protected section of SecCDSAKeyDestroy. Avoid using it, pretend that no enveloping SecKeyRef exists. But make sure that this KeyImpl is disconnected from this about-to-die SecKeyRef, because we do not want KeyImpl connected to it to be really destroyed, it will be connected to newly created SecKeyRef (see below).
mWeakSecKeyRef->key = NULL;
mWeakSecKeyRef = NULL;
SecKeyRef cdsaKey;
Security::KeychainCore::KeyItem *key;
SecCredentialType credentialType;
+ Mutex *cdsaKeyMutex;
};
#endif // !_SECURITY_KEYITEM_H_
};
static ModuleNexus<TheOneTP> theOneTP;
-static const CssmOid *theOidList[] = {
- static_cast<const CssmOid *>(&CSSMOID_APPLE_ISIGN),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_X509_BASIC),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SSL),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SMIME),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_EAP),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_IP_SEC),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_ICHAT),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_RESOURCE_SIGN),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_CLIENT),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_SERVER),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_CODE_SIGNING),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
- static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
- NULL // sentinel
+static const CssmOid** theOidList() {
+ static const CssmOid* list[] = {
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_ISIGN),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_X509_BASIC),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SSL),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SMIME),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_EAP),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_IP_SEC),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_ICHAT),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_RESOURCE_SIGN),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_CLIENT),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_SERVER),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_CODE_SIGNING),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
+ static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
+ NULL // sentinel
+ };
+ return list;
};
{
StLock<Mutex>_(mMutex);
- while (theOidList[mSearchPos]) {
- if (mOidGiven && mOid != *theOidList[mSearchPos]) {
+ while (theOidList()[mSearchPos]) {
+ if (mOidGiven && mOid != *(theOidList()[mSearchPos])) {
mSearchPos++;
continue; // no oid match
}
// ignoring mValue - not used by current TP
- policy = new Policy(theOneTP(), *theOidList[mSearchPos]);
+ policy = new Policy(theOneTP(), *(theOidList()[mSearchPos]));
mSearchPos++; // advance cursor
return true; // return next match
}
@param accessRef On return, a pointer to the new access reference.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef __nullable trustedlist, SecAccessRef * __nonnull CF_RETURNS_RETAINED accessRef);
+OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef __nullable trustedlist, SecAccessRef * __nonnull CF_RETURNS_RETAINED accessRef) API_UNAVAILABLE(ios);
/*!
@function SecAccessCreateFromOwnerAndACL
@param aclList On return, a pointer to a new created CFArray of SecACL instances. The caller is responsible for calling CFRelease on this array.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecAccessCopyACLList(SecAccessRef accessRef, CFArrayRef * __nonnull CF_RETURNS_RETAINED aclList);
+OSStatus SecAccessCopyACLList(SecAccessRef accessRef, CFArrayRef * __nonnull CF_RETURNS_RETAINED aclList) API_UNAVAILABLE(ios);
/*!
@function SecAccessCopySelectedACLList
#endif
OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNameLength, const char *accountName,
- UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) __deprecated_msg("iTools is no longer supported");
+ UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) __deprecated_msg("iTools is no longer supported") API_UNAVAILABLE(ios);
/*!
@function SecAccessCreateWithTrustedApplications
@discussion The SecAccessCreateWithPList creates a SecAccess with the provided list of trusted applications.
*/
-OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess);
+OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess) API_UNAVAILABLE(ios);
#if defined(__cplusplus)
#include <security_utilities/threading.h>
#include <utilities/SecCFRelease.h>
#include "SecBridge.h"
+#include "SecFramework.h"
static CFStringRef copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName);
OSStatus SecCertificateGetCLHandle_legacy(SecCertificateRef certificate, CSSM_CL_HANDLE *clHandle);
extern CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage);
-#define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
-SEC_CONST_DECL (kSecCertificateProductionEscrowKey, "ProductionEscrowKey");
-SEC_CONST_DECL (kSecCertificateProductionPCSEscrowKey, "ProductionPCSEscrowKey");
-SEC_CONST_DECL (kSecCertificateEscrowFileName, "AppleESCertificates");
using namespace CssmClient;
const char *templateStr = "%s [key usage 0x%X]";
const int keyUsageMaxStrLen = 8;
accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
- char accountUTF8[accountUTF8Len];
+ char *accountUTF8 = (char *)malloc(accountUTF8Len);
+ if (!accountUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
accountUTF8[0] = (char)'\0';
if (keyUsage)
snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
- CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ free(accountUTF8);
CFRelease(labelStr);
// service attribute (name provided by the caller)
CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8) + 1;;
- char serviceUTF8[serviceUTF8Len];
+ char *serviceUTF8 = (char *)malloc(serviceUTF8Len);
+ if (!serviceUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(name, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
serviceUTF8[0] = (char)'\0';
- CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ CssmDataContainer service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ free(serviceUTF8);
// look for existing preference item, in case this is an update
StorageManager::KeychainList keychains;
const CSSM_CERT_BUNDLE* bundle,
CSSM_CERT_BUNDLE_TYPE type,
CSSM_CERT_BUNDLE_ENCODING encodingType,
- CFArrayRef keychainListToSkipDuplicates);
+ CFArrayRef keychainListToSkipDuplicates) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function SecCertificateBundleExport
CFArrayRef certificates,
CSSM_CERT_BUNDLE_TYPE type,
CSSM_CERT_BUNDLE_ENCODING encodingType,
- CSSM_DATA* data);
+ CSSM_DATA* data) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
#if defined(__cplusplus)
}
const char *templateStr = "%s [key usage 0x%X]";
const int keyUsageMaxStrLen = 8;
accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
- char accountUTF8[accountUTF8Len];
+ char *accountUTF8 = (char *)malloc(accountUTF8Len);
+ if (!accountUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
accountUTF8[0] = (char)'\0';
if (keyUsage)
snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8);
- CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ free(accountUTF8);
CFRelease(labelStr);
// service attribute (name provided by the caller)
CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8) + 1;;
- char serviceUTF8[serviceUTF8Len];
+ char *serviceUTF8 = (char *)malloc(serviceUTF8Len);
+ if (!serviceUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(name, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
serviceUTF8[0] = (char)'\0';
- CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ CssmDataContainer service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ free(serviceUTF8);
// look for existing identity preference item, in case this is an update
StorageManager::KeychainList keychains;
const char *templateStr = "%s [key usage 0x%X]";
const int keyUsageMaxStrLen = 8;
accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
- char accountUTF8[accountUTF8Len];
+ char *accountUTF8 = (char *)malloc(accountUTF8Len);
+ if (!accountUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
accountUTF8[0] = (char)'\0';
if (keyUsage)
snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8);
- CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ free(accountUTF8);
CFRelease(labelStr);
// service attribute (name provided by the caller)
CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(idString), kCFStringEncodingUTF8) + 1;;
- char serviceUTF8[serviceUTF8Len];
+ char *serviceUTF8 = (char *)malloc(serviceUTF8Len);
+ if (!serviceUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(idString, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
serviceUTF8[0] = (char)'\0';
- CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ CssmDataContainer service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ free(serviceUTF8);
// set item attribute values
item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service);
const char *templateStr = "%s [key usage 0x%X]";
const int keyUsageMaxStrLen = 8;
accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
- char accountUTF8[accountUTF8Len];
- if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
+ char *accountUTF8 = (char *)malloc(accountUTF8Len);
+ if (!accountUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
+ if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
accountUTF8[0] = (char)'\0';
if (keyUsage)
snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8);
- CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
prefItem->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
- CFRelease(labelStr);
+ free(accountUTF8);
+ CFRelease(labelStr);
// generic attribute (store persistent certificate reference)
CFDataRef pItemRef = nil;
#include <Security/SecBase.h>
#include <Security/SecBasePriv.h>
#include <Security/SecItem.h>
-//#include <Security/SecRSAKey.h>
#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
#include <Security/SecIdentity.h>
#include <Security/SecIdentityPriv.h>
#include <Security/SecPolicy.h>
// key ID
if (!status) {
- SecKeyRef itemKey = NULL;
- status = SecCertificateCopyPublicKey(itemCert, &itemKey);
- if (!status) {
- const CSSM_KEY *cssmKey;
- status = SecKeyGetCSSMKey(itemKey, &cssmKey);
- if (!status) {
- unsigned char hash[CC_SHA1_DIGEST_LENGTH];
- CC_SHA1(cssmKey->KeyData.Data, (CC_LONG)cssmKey->KeyData.Length, &hash[0]);
- CFDataRef digest = CFDataCreate(NULL, (const UInt8 *)hash, CC_SHA1_DIGEST_LENGTH);
- if (digest) {
- CFDictionaryAddValue(itemDict, kSecImportItemKeyID, digest);
- CFRelease(digest);
- }
- }
- CFRelease(itemKey);
+ CFDataRef digest = SecCertificateCopyPublicKeySHA1Digest(itemCert);
+ if (digest) {
+ CFDictionaryAddValue(itemDict, kSecImportItemKeyID, digest);
+ CFRelease(digest);
}
}
&ccHand);
if(crtn) {
SecImpExpDbg("impExpCreatePassKey: CSSM_CSP_CreateKeyGenContext error");
+ free(ourKey);
return crtn;
}
/* subsequent errors to errOut: */
#include <login/SessionAgentCom.h>
#include <login/SessionAgentStatusCom.h>
#include <os/activity.h>
+#include <CoreFoundation/CFPriv.h>
const uint8_t kUUIDStringLength = 36;
}
static Boolean SecItemSynchronizable(CFDictionaryRef query);
+static CFArrayRef _CopyMatchingIssuers(CFArrayRef issuers);
static void secitemlog(int priority, const char *format, ...)
{
require_action(!(itemParams->itemClass == 0 && !itemParams->useItems), error_exit, status = errSecItemClassMissing);
}
- // kSecMatchIssuers is only permitted with identities.
+ // kSecMatchIssuers is only permitted with identities or certificates.
// Convert the input issuers to normalized form.
require_noerr(status = _ValidateDictionaryEntry(dict, kSecMatchIssuers, (const void **)&itemParams->matchIssuers, CFArrayGetTypeID(), NULL), error_exit);
if (itemParams->matchIssuers) {
- require_action(itemParams->returnIdentity, error_exit, status = errSecParam);
+ CFTypeRef allowCerts = CFDictionaryGetValue(itemParams->query, kSecUseCertificatesWithMatchIssuers);
+ require_action(itemParams->returnIdentity || (allowCerts && CFEqual(allowCerts, kCFBooleanTrue)), error_exit, status = errSecParam);
CFMutableArrayRef canonical_issuers = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
CFArrayRef issuers = (CFArrayRef)itemParams->matchIssuers;
if (canonical_issuers) {
can_target_osx = can_target_ios = true;
// Check no-legacy flag.
- CFTypeRef value = CFDictionaryGetValue(query, kSecAttrNoLegacy);
- if (value != NULL) {
- can_target_ios = readNumber(value) != 0;
+ // it's iOS or bust if we're on MZ!
+ CFTypeRef noLegacy = NULL;
+ if (_CFMZEnabled()) {
+ noLegacy = kCFBooleanTrue;
+ }
+ else {
+ noLegacy = CFDictionaryGetValue(query, kSecAttrNoLegacy);
+ }
+
+ if (noLegacy != NULL) {
+ can_target_ios = readNumber(noLegacy) != 0;
can_target_osx = !can_target_ios;
return errSecSuccess;
}
// Check whether the query contains kSecValueRef and modify can_ flags according to the kind and type of the value.
- value = CFDictionaryGetValue(query, kSecValueRef);
+ CFTypeRef value = CFDictionaryGetValue(query, kSecValueRef);
if (value != NULL) {
CFTypeID typeID = CFGetTypeID(value);
if (typeID == SecKeyGetTypeID()) {
can_target_ios = can_target_ios && !CFDictionaryContainsKey(query, *osx_only_items[i]);
}
+ // Absence of all of kSecItemClass, kSecValuePersistentRef, and kSecValueRef means that the query can't target iOS
+ if(CFDictionaryGetValue(query, kSecClass) == NULL &&
+ CFDictionaryGetValue(query, kSecValuePersistentRef) == NULL &&
+ CFDictionaryGetValue(query, kSecValueRef) == NULL) {
+ can_target_ios = false;
+ }
+
return (can_target_ios || can_target_osx) ? errSecSuccess : errSecParam;
}
return status;
}
-static Mutex gParentCertCacheLock;
+static Mutex& gParentCertCacheLock() {
+ static Mutex fParentCertCacheLock;
+ return fParentCertCacheLock;
+}
static CFMutableDictionaryRef gParentCertCache;
static CFMutableArrayRef gParentCertCacheList;
#define PARENT_CACHE_SIZE 100
void SecItemParentCachePurge() {
- StLock<Mutex> _(gParentCertCacheLock);
+ StLock<Mutex> _(gParentCertCacheLock());
CFReleaseNull(gParentCertCache);
CFReleaseNull(gParentCertCacheList);
}
CFDataRef digest = SecCertificateGetSHA1Digest(certificate);
if (!digest) return NULL;
- StLock<Mutex> _(gParentCertCacheLock);
+ StLock<Mutex> _(gParentCertCacheLock());
if (gParentCertCache && gParentCertCacheList) {
if (0 <= (ix = CFArrayGetFirstIndexOfValue(gParentCertCacheList,
CFRangeMake(0, CFArrayGetCount(gParentCertCacheList)),
CFDataRef digest = SecCertificateGetSHA1Digest(certificate);
if (!digest) return;
- StLock<Mutex> _(gParentCertCacheLock);
+ StLock<Mutex> _(gParentCertCacheLock());
if (!gParentCertCache || !gParentCertCacheList) {
CFReleaseNull(gParentCertCache);
gParentCertCache = makeCFMutableDictionary();
CFDictionaryAddValue(gParentCertCache, digest, parents);
if (PARENT_CACHE_SIZE <= CFArrayGetCount(gParentCertCacheList)) {
// Remove least recently used cache entry.
+ CFDictionaryRemoveValue(gParentCertCache, CFArrayGetValueAtIndex(gParentCertCacheList, 0));
CFArrayRemoveValueAtIndex(gParentCertCacheList, 0);
}
CFArrayAppendValue(gParentCertCacheList, digest);
#pragma unused (context) /* for now; in future this can reference a container object */
/* Certificates are unique by issuer and serial number. */
+ CFDataRef serialNumber = SecCertificateCopySerialNumberData(certificate, NULL);
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
- CFDataRef serialNumber = SecCertificateCopySerialNumber(certificate, NULL);
CFDataRef normalizedIssuer = SecCertificateCopyNormalizedIssuerContent(certificate, NULL);
#else
- CFDataRef serialNumber = SecCertificateCopySerialNumber(certificate);
CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate);
CFRetainSafe(normalizedIssuer);
#endif
* which won't work once the item is updated.
*/
CFDictionaryRemoveValue(result, kSecAttrModificationDate);
+
+ /* Find all intermediate certificates in OSX keychain and append them in to the kSecMatchIssuers.
+ * This is required because secd cannot do query in to the OSX keychain
+ */
+ CFTypeRef matchIssuers = CFDictionaryGetValue(result, kSecMatchIssuers);
+ if (matchIssuers && CFGetTypeID(matchIssuers) == CFArrayGetTypeID()) {
+ CFArrayRef newMatchIssuers = _CopyMatchingIssuers((CFArrayRef)matchIssuers);
+ if (newMatchIssuers) {
+ CFDictionarySetValue(result, kSecMatchIssuers, newMatchIssuers);
+ CFRelease(newMatchIssuers);
+ }
+ }
}
else {
/* iOS doesn't add the class attribute, so we must do it here. */
} /* extern "C" */
+static CFArrayRef
+_CopyMatchingIssuers(CFArrayRef matchIssuers) {
+ CFMutableArrayRef result = NULL;
+ CFMutableDictionaryRef query = NULL;
+ CFMutableDictionaryRef policyProperties = NULL;
+ SecPolicyRef policy = NULL;
+ CFTypeRef matchedCertificates = NULL;
+
+ require_quiet(policyProperties = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), out);
+ CFDictionarySetValue(policyProperties, kSecPolicyKU_KeyCertSign, kCFBooleanTrue);
+ require_quiet(policy = SecPolicyCreateWithProperties(kSecPolicyAppleX509Basic, policyProperties), out);
+
+ require_quiet(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), out);
+ CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
+ CFDictionarySetValue(query, kSecMatchIssuers, matchIssuers);
+ CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
+ CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
+ CFDictionarySetValue(query, kSecUseCertificatesWithMatchIssuers, kCFBooleanTrue);
+ CFDictionarySetValue(query, kSecMatchPolicy, policy);
+
+ if (SecItemCopyMatching_osx(query, &matchedCertificates) == errSecSuccess && CFGetTypeID(matchedCertificates) == CFArrayGetTypeID()) {
+ require_quiet(result = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, (CFArrayRef)matchedCertificates), out);
+ for(CFIndex i = 0; i < CFArrayGetCount((CFArrayRef)matchedCertificates); ++i) {
+ CFDictionaryRef attributes = (CFDictionaryRef)CFArrayGetValueAtIndex((CFArrayRef)matchedCertificates, i);
+ CFTypeRef subject = CFDictionaryGetValue(attributes, kSecAttrSubject);
+ if (!CFArrayContainsValue(result, CFRangeMake(0, CFArrayGetCount(result)), subject)) {
+ CFArrayAppendValue(result, subject);
+ }
+ }
+ }
+
+out:
+ CFReleaseSafe(query);
+ CFReleaseSafe(policyProperties);
+ CFReleaseSafe(policy);
+ CFReleaseSafe(matchedCertificates);
+
+ return result;
+}
+
static OSStatus
SecItemMergeResults(bool can_target_ios, OSStatus status_ios, CFTypeRef result_ios,
bool can_target_osx, OSStatus status_osx, CFTypeRef result_osx,
#define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
+// See the other SecItemContants.c for actual definitions
+
/* Class Key Constant */
-SEC_CONST_DECL (kSecClass, "class");
+//SEC_CONST_DECL (kSecClass, "class");
/* Class Value Constants */
-SEC_CONST_DECL (kSecClassGenericPassword, "genp");
-SEC_CONST_DECL (kSecClassInternetPassword, "inet");
-SEC_CONST_DECL (kSecClassAppleSharePassword, "apls");
-SEC_CONST_DECL (kSecClassCertificate, "cert");
-SEC_CONST_DECL (kSecClassKey, "keys");
-SEC_CONST_DECL (kSecClassIdentity, "idnt");
+//SEC_CONST_DECL (kSecClassGenericPassword, "genp");
+//SEC_CONST_DECL (kSecClassInternetPassword, "inet");
+//SEC_CONST_DECL (kSecClassAppleSharePassword, "apls");
+//SEC_CONST_DECL (kSecClassCertificate, "cert");
+//SEC_CONST_DECL (kSecClassKey, "keys");
+//SEC_CONST_DECL (kSecClassIdentity, "idnt");
/* Attribute Key Constants */
-SEC_CONST_DECL (kSecAttrAccessible, "pdmn");
-SEC_CONST_DECL (kSecAttrAccessGroup, "agrp");
+//SEC_CONST_DECL (kSecAttrAccessible, "pdmn");
+//SEC_CONST_DECL (kSecAttrAccessGroup, "agrp");
SEC_CONST_DECL (kSecAttrAccess, "acls");
-SEC_CONST_DECL (kSecAttrCreationDate, "cdat");
-SEC_CONST_DECL (kSecAttrModificationDate, "mdat");
-SEC_CONST_DECL (kSecAttrDescription, "desc");
-SEC_CONST_DECL (kSecAttrComment, "icmt");
-SEC_CONST_DECL (kSecAttrCreator, "crtr");
-SEC_CONST_DECL (kSecAttrType, "type");
-SEC_CONST_DECL (kSecAttrLabel, "labl");
-SEC_CONST_DECL (kSecAttrIsInvisible, "invi");
-SEC_CONST_DECL (kSecAttrIsNegative, "nega");
-SEC_CONST_DECL (kSecAttrAccount, "acct");
-SEC_CONST_DECL (kSecAttrService, "svce");
-SEC_CONST_DECL (kSecAttrGeneric, "gena");
-SEC_CONST_DECL (kSecAttrSecurityDomain, "sdmn");
-SEC_CONST_DECL (kSecAttrServer, "srvr");
-SEC_CONST_DECL (kSecAttrProtocol, "ptcl");
-SEC_CONST_DECL (kSecAttrAuthenticationType, "atyp");
-SEC_CONST_DECL (kSecAttrPort, "port");
-SEC_CONST_DECL (kSecAttrPath, "path");
-SEC_CONST_DECL (kSecAttrVolume, "volm");
-SEC_CONST_DECL (kSecAttrAddress, "addr");
-SEC_CONST_DECL (kSecAttrAFPServerSignature, "afps");
-SEC_CONST_DECL (kSecAttrAlias, "alis");
-SEC_CONST_DECL (kSecAttrSubject, "subj");
-SEC_CONST_DECL (kSecAttrIssuer, "issr");
-SEC_CONST_DECL (kSecAttrSerialNumber, "slnr");
-SEC_CONST_DECL (kSecAttrSubjectKeyID, "skid");
-SEC_CONST_DECL (kSecAttrPublicKeyHash, "pkhh");
-SEC_CONST_DECL (kSecAttrCertificateType, "ctyp");
-SEC_CONST_DECL (kSecAttrCertificateEncoding, "cenc");
-SEC_CONST_DECL (kSecAttrKeyClass, "kcls");
-SEC_CONST_DECL (kSecAttrApplicationLabel, "klbl");
-SEC_CONST_DECL (kSecAttrIsPermanent, "perm");
-SEC_CONST_DECL (kSecAttrIsModifiable, "modi");
-SEC_CONST_DECL (kSecAttrIsPrivate, "priv");
-SEC_CONST_DECL (kSecAttrApplicationTag, "atag");
-SEC_CONST_DECL (kSecAttrKeyCreator, "crtr");
-SEC_CONST_DECL (kSecAttrKeyType, "type");
+//SEC_CONST_DECL (kSecAttrCreationDate, "cdat");
+//SEC_CONST_DECL (kSecAttrModificationDate, "mdat");
+//SEC_CONST_DECL (kSecAttrDescription, "desc");
+//SEC_CONST_DECL (kSecAttrComment, "icmt");
+//SEC_CONST_DECL (kSecAttrCreator, "crtr");
+//SEC_CONST_DECL (kSecAttrType, "type");
+//SEC_CONST_DECL (kSecAttrLabel, "labl");
+//SEC_CONST_DECL (kSecAttrIsInvisible, "invi");
+//SEC_CONST_DECL (kSecAttrIsNegative, "nega");
+//SEC_CONST_DECL (kSecAttrAccount, "acct");
+//SEC_CONST_DECL (kSecAttrService, "svce");
+//SEC_CONST_DECL (kSecAttrGeneric, "gena");
+//SEC_CONST_DECL (kSecAttrSecurityDomain, "sdmn");
+//SEC_CONST_DECL (kSecAttrServer, "srvr");
+//SEC_CONST_DECL (kSecAttrProtocol, "ptcl");
+//SEC_CONST_DECL (kSecAttrAuthenticationType, "atyp");
+//SEC_CONST_DECL (kSecAttrPort, "port");
+//SEC_CONST_DECL (kSecAttrPath, "path");
+//SEC_CONST_DECL (kSecAttrVolume, "volm");
+//SEC_CONST_DECL (kSecAttrAddress, "addr");
+//SEC_CONST_DECL (kSecAttrAFPServerSignature, "afps");
+//SEC_CONST_DECL (kSecAttrAlias, "alis");
+//SEC_CONST_DECL (kSecAttrSubject, "subj");
+//SEC_CONST_DECL (kSecAttrIssuer, "issr");
+//SEC_CONST_DECL (kSecAttrSerialNumber, "slnr");
+//SEC_CONST_DECL (kSecAttrSubjectKeyID, "skid");
+//SEC_CONST_DECL (kSecAttrPublicKeyHash, "pkhh");
+//SEC_CONST_DECL (kSecAttrCertificateType, "ctyp");
+//SEC_CONST_DECL (kSecAttrCertificateEncoding, "cenc");
+//SEC_CONST_DECL (kSecAttrKeyClass, "kcls");
+//SEC_CONST_DECL (kSecAttrApplicationLabel, "klbl");
+//SEC_CONST_DECL (kSecAttrIsPermanent, "perm");
+//SEC_CONST_DECL (kSecAttrIsModifiable, "modi");
+//SEC_CONST_DECL (kSecAttrIsPrivate, "priv");
+//SEC_CONST_DECL (kSecAttrApplicationTag, "atag");
+//SEC_CONST_DECL (kSecAttrKeyCreator, "crtr");
+//SEC_CONST_DECL (kSecAttrKeyType, "type");
SEC_CONST_DECL (kSecAttrPRF, "prf");
SEC_CONST_DECL (kSecAttrSalt, "salt");
SEC_CONST_DECL (kSecAttrRounds, "rounds");
-SEC_CONST_DECL (kSecAttrKeySizeInBits, "bsiz");
-SEC_CONST_DECL (kSecAttrEffectiveKeySize, "esiz");
-SEC_CONST_DECL (kSecAttrStartDate, "sdat");
-SEC_CONST_DECL (kSecAttrEndDate, "edat");
-SEC_CONST_DECL (kSecAttrIsSensitive, "sens");
-SEC_CONST_DECL (kSecAttrWasAlwaysSensitive, "asen");
-SEC_CONST_DECL (kSecAttrIsExtractable, "extr");
-SEC_CONST_DECL (kSecAttrWasNeverExtractable, "next");
-SEC_CONST_DECL (kSecAttrCanEncrypt, "encr");
-SEC_CONST_DECL (kSecAttrCanDecrypt, "decr");
-SEC_CONST_DECL (kSecAttrCanDerive, "drve");
-SEC_CONST_DECL (kSecAttrCanSign, "sign");
-SEC_CONST_DECL (kSecAttrCanVerify, "vrfy");
-SEC_CONST_DECL (kSecAttrCanSignRecover, "snrc");
-SEC_CONST_DECL (kSecAttrCanVerifyRecover, "vyrc");
-SEC_CONST_DECL (kSecAttrCanWrap, "wrap");
-SEC_CONST_DECL (kSecAttrCanUnwrap, "unwp");
-SEC_CONST_DECL (kSecAttrSyncViewHint, "vwht");
-SEC_CONST_DECL (kSecAttrTokenID, "tkid");
+//SEC_CONST_DECL (kSecAttrKeySizeInBits, "bsiz");
+//SEC_CONST_DECL (kSecAttrEffectiveKeySize, "esiz");
+//SEC_CONST_DECL (kSecAttrStartDate, "sdat");
+//SEC_CONST_DECL (kSecAttrEndDate, "edat");
+//SEC_CONST_DECL (kSecAttrIsSensitive, "sens");
+//SEC_CONST_DECL (kSecAttrWasAlwaysSensitive, "asen");
+//SEC_CONST_DECL (kSecAttrIsExtractable, "extr");
+//SEC_CONST_DECL (kSecAttrWasNeverExtractable, "next");
+//SEC_CONST_DECL (kSecAttrCanEncrypt, "encr");
+//SEC_CONST_DECL (kSecAttrCanDecrypt, "decr");
+//SEC_CONST_DECL (kSecAttrCanDerive, "drve");
+//SEC_CONST_DECL (kSecAttrCanSign, "sign");
+//SEC_CONST_DECL (kSecAttrCanVerify, "vrfy");
+//SEC_CONST_DECL (kSecAttrCanSignRecover, "snrc");
+//SEC_CONST_DECL (kSecAttrCanVerifyRecover, "vyrc");
+//SEC_CONST_DECL (kSecAttrCanWrap, "wrap");
+//SEC_CONST_DECL (kSecAttrCanUnwrap, "unwp");
+//SEC_CONST_DECL (kSecAttrSyncViewHint, "vwht");
+//SEC_CONST_DECL (kSecAttrTokenID, "tkid");
/* Attribute Constants (Private) */
-SEC_CONST_DECL (kSecAttrScriptCode, "scrp");
-SEC_CONST_DECL (kSecAttrHasCustomIcon, "cusi");
-SEC_CONST_DECL (kSecAttrCRLType, "crlt");
-SEC_CONST_DECL (kSecAttrCRLEncoding, "crle");
-SEC_CONST_DECL (kSecAttrSynchronizable, "sync");
-SEC_CONST_DECL (kSecAttrSynchronizableAny, "syna");
-SEC_CONST_DECL (kSecAttrTombstone, "tomb");
-SEC_CONST_DECL (kSecAttrNoLegacy, "nleg");
-SEC_CONST_DECL (kSecAttrMultiUser, "musr");
-SEC_CONST_DECL (kSecAttrTokenOID, "toid");
-SEC_CONST_DECL (kSecAttrUUID, "UUID");
-SEC_CONST_DECL (kSecAttrPersistantReference, "persistref");
-SEC_CONST_DECL (kSecAttrPersistentReference, "persistref");
-SEC_CONST_DECL (kSecAttrSysBound, "sysb");
-SEC_CONST_DECL (kSecAttrSHA1, "sha1");
-
-SEC_CONST_DECL (kSecAttrDeriveSyncIDFromItemAttributes, "dspk");
-SEC_CONST_DECL (kSecAttrPCSPlaintextServiceIdentifier, "pcss");
-SEC_CONST_DECL (kSecAttrPCSPlaintextPublicKey, "pcsk");
-SEC_CONST_DECL (kSecAttrPCSPlaintextPublicIdentity, "pcsi");
+//SEC_CONST_DECL (kSecAttrScriptCode, "scrp");
+//SEC_CONST_DECL (kSecAttrHasCustomIcon, "cusi");
+//SEC_CONST_DECL (kSecAttrCRLType, "crlt");
+//SEC_CONST_DECL (kSecAttrCRLEncoding, "crle");
+//SEC_CONST_DECL (kSecAttrSynchronizable, "sync");
+//SEC_CONST_DECL (kSecAttrSynchronizableAny, "syna");
+//SEC_CONST_DECL (kSecAttrTombstone, "tomb");
+//SEC_CONST_DECL (kSecAttrNoLegacy, "nleg");
+//SEC_CONST_DECL (kSecAttrMultiUser, "musr");
+//SEC_CONST_DECL (kSecAttrTokenOID, "toid");
+//SEC_CONST_DECL (kSecAttrUUID, "UUID");
+//SEC_CONST_DECL (kSecAttrPersistantReference, "persistref");
+//SEC_CONST_DECL (kSecAttrPersistentReference, "persistref");
+//SEC_CONST_DECL (kSecAttrSysBound, "sysb");
+//SEC_CONST_DECL (kSecAttrSHA1, "sha1");
+//
+//SEC_CONST_DECL (kSecAttrDeriveSyncIDFromItemAttributes, "dspk");
+//SEC_CONST_DECL (kSecAttrPCSPlaintextServiceIdentifier, "pcss");
+//SEC_CONST_DECL (kSecAttrPCSPlaintextPublicKey, "pcsk");
+//SEC_CONST_DECL (kSecAttrPCSPlaintextPublicIdentity, "pcsi");
/* Predefined access groups constants */
-SEC_CONST_DECL (kSecAttrAccessGroupToken, "com.apple.token");
+//SEC_CONST_DECL (kSecAttrAccessGroupToken, "com.apple.token");
/* Search Constants */
-SEC_CONST_DECL (kSecMatchPolicy, "m_Policy");
-SEC_CONST_DECL (kSecMatchItemList, "m_ItemList");
-SEC_CONST_DECL (kSecMatchSearchList, "m_SearchList");
-SEC_CONST_DECL (kSecMatchIssuers, "m_Issuers");
-SEC_CONST_DECL (kSecMatchEmailAddressIfPresent, "m_EmailAddressIfPresent");
-SEC_CONST_DECL (kSecMatchSubjectContains, "m_SubjectContains");
+//SEC_CONST_DECL (kSecMatchPolicy, "m_Policy");
+//SEC_CONST_DECL (kSecMatchItemList, "m_ItemList");
+//SEC_CONST_DECL (kSecMatchSearchList, "m_SearchList");
+//SEC_CONST_DECL (kSecMatchIssuers, "m_Issuers");
+//SEC_CONST_DECL (kSecMatchEmailAddressIfPresent, "m_EmailAddressIfPresent");
+//SEC_CONST_DECL (kSecMatchSubjectContains, "m_SubjectContains");
SEC_CONST_DECL (kSecMatchSubjectStartsWith, "m_SubjectStartsWith");
SEC_CONST_DECL (kSecMatchSubjectEndsWith, "m_SubjectEndsWith");
SEC_CONST_DECL (kSecMatchSubjectWholeString, "m_SubjectWholeString");
-SEC_CONST_DECL (kSecMatchCaseInsensitive, "m_CaseInsensitive");
+//SEC_CONST_DECL (kSecMatchCaseInsensitive, "m_CaseInsensitive");
SEC_CONST_DECL (kSecMatchDiacriticInsensitive, "m_DiacriticInsensitive");
SEC_CONST_DECL (kSecMatchWidthInsensitive, "m_WidthInsensitive");
-SEC_CONST_DECL (kSecMatchTrustedOnly, "m_TrustedOnly");
-SEC_CONST_DECL (kSecMatchValidOnDate, "m_ValidOnDate");
-SEC_CONST_DECL (kSecMatchLimit, "m_Limit");
+//SEC_CONST_DECL (kSecMatchTrustedOnly, "m_TrustedOnly");
+//SEC_CONST_DECL (kSecMatchValidOnDate, "m_ValidOnDate");
+//SEC_CONST_DECL (kSecMatchLimit, "m_Limit");
/* Could just use kCFBooleanTrue and kCFBooleanFalse for these 2. */
-SEC_CONST_DECL (kSecMatchLimitOne, "m_LimitOne");
-SEC_CONST_DECL (kSecMatchLimitAll, "m_LimitAll");
+//SEC_CONST_DECL (kSecMatchLimitOne, "m_LimitOne");
+//SEC_CONST_DECL (kSecMatchLimitAll, "m_LimitAll");
/* Return Type Key Constants */
-SEC_CONST_DECL (kSecReturnData, "r_Data");
-SEC_CONST_DECL (kSecReturnAttributes, "r_Attributes");
-SEC_CONST_DECL (kSecReturnRef, "r_Ref");
-SEC_CONST_DECL (kSecReturnPersistentRef, "r_PersistentRef");
+//SEC_CONST_DECL (kSecReturnData, "r_Data");
+//SEC_CONST_DECL (kSecReturnAttributes, "r_Attributes");
+//SEC_CONST_DECL (kSecReturnRef, "r_Ref");
+//SEC_CONST_DECL (kSecReturnPersistentRef, "r_PersistentRef");
/* Value Type Key Constants */
-SEC_CONST_DECL (kSecValueData, "v_Data");
-SEC_CONST_DECL (kSecValueRef, "v_Ref");
-SEC_CONST_DECL (kSecValuePersistentRef, "v_PersistentRef");
+//SEC_CONST_DECL (kSecValueData, "v_Data");
+//SEC_CONST_DECL (kSecValueRef, "v_Ref");
+//SEC_CONST_DECL (kSecValuePersistentRef, "v_PersistentRef");
/* Other Constants */
-SEC_CONST_DECL (kSecUseItemList, "u_ItemList");
+//SEC_CONST_DECL (kSecUseItemList, "u_ItemList");
SEC_CONST_DECL (kSecUseKeychain, "u_Keychain");
-SEC_CONST_DECL (kSecUseSystemKeychain, "u_SystemKeychain");
-SEC_CONST_DECL (kSecUseSyncBubbleKeychain, "u_SyncBubbleKeychain");
+//SEC_CONST_DECL (kSecUseSystemKeychain, "u_SystemKeychain");
+//SEC_CONST_DECL (kSecUseSyncBubbleKeychain, "u_SyncBubbleKeychain");
/* kSecAttrAccessible Value Constants. */
-SEC_CONST_DECL (kSecAttrAccessibleWhenUnlocked, "ak");
-SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlock, "ck");
-SEC_CONST_DECL (kSecAttrAccessibleAlways, "dk");
-SEC_CONST_DECL (kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "aku");
-SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, "cku");
-SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnly, "dku");
-SEC_CONST_DECL (kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, "akpu");
+//SEC_CONST_DECL (kSecAttrAccessibleWhenUnlocked, "ak");
+//SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlock, "ck");
+//SEC_CONST_DECL (kSecAttrAccessibleAlways, "dk");
+//SEC_CONST_DECL (kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "aku");
+//SEC_CONST_DECL (kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, "cku");
+//SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnly, "dku");
+//SEC_CONST_DECL (kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, "akpu");
/* kSecAttrAccessible Value Constants (Private). */
-SEC_CONST_DECL (kSecAttrAccessibleAlwaysPrivate, "dk");
-SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate, "dku");
+//SEC_CONST_DECL (kSecAttrAccessibleAlwaysPrivate, "dk");
+//SEC_CONST_DECL (kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate, "dku");
/* kSecAttrProtocol Value Constants. */
-SEC_CONST_DECL (kSecAttrProtocolFTP, "ftp ");
-SEC_CONST_DECL (kSecAttrProtocolFTPAccount, "ftpa");
-SEC_CONST_DECL (kSecAttrProtocolHTTP, "http");
-SEC_CONST_DECL (kSecAttrProtocolIRC, "irc ");
-SEC_CONST_DECL (kSecAttrProtocolNNTP, "nntp");
-SEC_CONST_DECL (kSecAttrProtocolPOP3, "pop3");
-SEC_CONST_DECL (kSecAttrProtocolSMTP, "smtp");
-SEC_CONST_DECL (kSecAttrProtocolSOCKS, "sox ");
-SEC_CONST_DECL (kSecAttrProtocolIMAP, "imap");
-SEC_CONST_DECL (kSecAttrProtocolLDAP, "ldap");
-SEC_CONST_DECL (kSecAttrProtocolAppleTalk, "atlk");
-SEC_CONST_DECL (kSecAttrProtocolAFP, "afp ");
-SEC_CONST_DECL (kSecAttrProtocolTelnet, "teln");
-SEC_CONST_DECL (kSecAttrProtocolSSH, "ssh ");
-SEC_CONST_DECL (kSecAttrProtocolFTPS, "ftps");
-SEC_CONST_DECL (kSecAttrProtocolHTTPS, "htps");
-SEC_CONST_DECL (kSecAttrProtocolHTTPProxy, "htpx");
-SEC_CONST_DECL (kSecAttrProtocolHTTPSProxy, "htsx");
-SEC_CONST_DECL (kSecAttrProtocolFTPProxy, "ftpx");
-SEC_CONST_DECL (kSecAttrProtocolSMB, "smb ");
-SEC_CONST_DECL (kSecAttrProtocolRTSP, "rtsp");
-SEC_CONST_DECL (kSecAttrProtocolRTSPProxy, "rtsx");
-SEC_CONST_DECL (kSecAttrProtocolDAAP, "daap");
-SEC_CONST_DECL (kSecAttrProtocolEPPC, "eppc");
-SEC_CONST_DECL (kSecAttrProtocolIPP, "ipp ");
-SEC_CONST_DECL (kSecAttrProtocolNNTPS, "ntps");
-SEC_CONST_DECL (kSecAttrProtocolLDAPS, "ldps");
-SEC_CONST_DECL (kSecAttrProtocolTelnetS, "tels");
-SEC_CONST_DECL (kSecAttrProtocolIMAPS, "imps");
-SEC_CONST_DECL (kSecAttrProtocolIRCS, "ircs");
-SEC_CONST_DECL (kSecAttrProtocolPOP3S, "pops");
+//SEC_CONST_DECL (kSecAttrProtocolFTP, "ftp ");
+//SEC_CONST_DECL (kSecAttrProtocolFTPAccount, "ftpa");
+//SEC_CONST_DECL (kSecAttrProtocolHTTP, "http");
+//SEC_CONST_DECL (kSecAttrProtocolIRC, "irc ");
+//SEC_CONST_DECL (kSecAttrProtocolNNTP, "nntp");
+//SEC_CONST_DECL (kSecAttrProtocolPOP3, "pop3");
+//SEC_CONST_DECL (kSecAttrProtocolSMTP, "smtp");
+//SEC_CONST_DECL (kSecAttrProtocolSOCKS, "sox ");
+//SEC_CONST_DECL (kSecAttrProtocolIMAP, "imap");
+//SEC_CONST_DECL (kSecAttrProtocolLDAP, "ldap");
+//SEC_CONST_DECL (kSecAttrProtocolAppleTalk, "atlk");
+//SEC_CONST_DECL (kSecAttrProtocolAFP, "afp ");
+//SEC_CONST_DECL (kSecAttrProtocolTelnet, "teln");
+//SEC_CONST_DECL (kSecAttrProtocolSSH, "ssh ");
+//SEC_CONST_DECL (kSecAttrProtocolFTPS, "ftps");
+//SEC_CONST_DECL (kSecAttrProtocolHTTPS, "htps");
+//SEC_CONST_DECL (kSecAttrProtocolHTTPProxy, "htpx");
+//SEC_CONST_DECL (kSecAttrProtocolHTTPSProxy, "htsx");
+//SEC_CONST_DECL (kSecAttrProtocolFTPProxy, "ftpx");
+//SEC_CONST_DECL (kSecAttrProtocolSMB, "smb ");
+//SEC_CONST_DECL (kSecAttrProtocolRTSP, "rtsp");
+//SEC_CONST_DECL (kSecAttrProtocolRTSPProxy, "rtsx");
+//SEC_CONST_DECL (kSecAttrProtocolDAAP, "daap");
+//SEC_CONST_DECL (kSecAttrProtocolEPPC, "eppc");
+//SEC_CONST_DECL (kSecAttrProtocolIPP, "ipp ");
+//SEC_CONST_DECL (kSecAttrProtocolNNTPS, "ntps");
+//SEC_CONST_DECL (kSecAttrProtocolLDAPS, "ldps");
+//SEC_CONST_DECL (kSecAttrProtocolTelnetS, "tels");
+//SEC_CONST_DECL (kSecAttrProtocolIMAPS, "imps");
+//SEC_CONST_DECL (kSecAttrProtocolIRCS, "ircs");
+//SEC_CONST_DECL (kSecAttrProtocolPOP3S, "pops");
/* kSecAttrAuthenticationType Value Constants. */
-SEC_CONST_DECL (kSecAttrAuthenticationTypeNTLM, "ntlm");
-SEC_CONST_DECL (kSecAttrAuthenticationTypeMSN, "msna");
-SEC_CONST_DECL (kSecAttrAuthenticationTypeDPA, "dpaa");
-SEC_CONST_DECL (kSecAttrAuthenticationTypeRPA, "rpaa");
-SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPBasic, "http");
-SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPDigest, "httd");
-SEC_CONST_DECL (kSecAttrAuthenticationTypeHTMLForm, "form");
-SEC_CONST_DECL (kSecAttrAuthenticationTypeDefault, "dflt");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeNTLM, "ntlm");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeMSN, "msna");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeDPA, "dpaa");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeRPA, "rpaa");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPBasic, "http");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeHTTPDigest, "httd");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeHTMLForm, "form");
+//SEC_CONST_DECL (kSecAttrAuthenticationTypeDefault, "dflt");
/* kSecAttrKeyClass Value Constants. Based on <Security/cssmtype.h>
CSSM_KEYCLASS_PUBLIC_KEY = 0,
CSSM_KEYCLASS_PRIVATE_KEY = 1,
CSSM_KEYCLASS_SESSION_KEY = 2,
*/
-SEC_CONST_DECL (kSecAttrKeyClassPublic, "0");
-SEC_CONST_DECL (kSecAttrKeyClassPrivate, "1");
-SEC_CONST_DECL (kSecAttrKeyClassSymmetric, "2");
+//SEC_CONST_DECL (kSecAttrKeyClassPublic, "0");
+//SEC_CONST_DECL (kSecAttrKeyClassPrivate, "1");
+//SEC_CONST_DECL (kSecAttrKeyClassSymmetric, "2");
/* kSecAttrKeyType Value Constants. Based on CSSM_ALGORITHMS. */
SEC_CONST_DECL (kSecAttrKeyTypeDES, "14");
SEC_CONST_DECL (kSecAttrKeyType3DES, "17");
SEC_CONST_DECL (kSecAttrKeyTypeRC2, "23");
SEC_CONST_DECL (kSecAttrKeyTypeRC4, "25");
-SEC_CONST_DECL (kSecAttrKeyTypeRSA, "42");
+
+//SEC_CONST_DECL (kSecAttrKeyTypeRSA, "42");
SEC_CONST_DECL (kSecAttrKeyTypeDSA, "43");
SEC_CONST_DECL (kSecAttrKeyTypeCAST, "56");
-SEC_CONST_DECL (kSecAttrKeyTypeECDSA, "73");
-SEC_CONST_DECL (kSecAttrKeyTypeEC, "73"); /* rdar://13326326 */
-SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandom, "73");
+SEC_CONST_DECL (kSecAttrKeyTypeECDSA, "73"); /**/
+//SEC_CONST_DECL (kSecAttrKeyTypeEC, "73"); /* rdar://13326326 */
+//SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandom, "73");
SEC_CONST_DECL (kSecAttrKeyTypeAES, "2147483649"); /* <Security/cssmapple.h> */
-SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandomPKA, "2147483678"); /* <Security/cssmapple.h> CSSM_ALGID__FIRST_UNUSED */
-SEC_CONST_DECL (kSecAttrKeyTypeSecureEnclaveAttestation, "2147483679"); /* <Security/cssmapple.h> CSSM_ALGID__FIRST_UNUSED + 1 */
+//SEC_CONST_DECL (kSecAttrKeyTypeECSECPrimeRandomPKA, "2147483678"); /* <Security/cssmapple.h> CSSM_ALGID__FIRST_UNUSED */
+//SEC_CONST_DECL (kSecAttrKeyTypeSecureEnclaveAttestation, "2147483679"); /* <Security/cssmapple.h> CSSM_ALGID__FIRST_UNUSED + 1 */
SEC_CONST_DECL (kSecAttrPRFHmacAlgSHA1, "hsha1");
SEC_CONST_DECL (kSecAttrPRFHmacAlgSHA224, "hsha224");
/* Constants used by SecKeyGeneratePair() - in SecKey.h. Never used in
any SecItem apis directly. */
-SEC_CONST_DECL (kSecPrivateKeyAttrs, "private");
-SEC_CONST_DECL (kSecPublicKeyAttrs, "public");
+//SEC_CONST_DECL (kSecPrivateKeyAttrs, "private");
+//SEC_CONST_DECL (kSecPublicKeyAttrs, "public");
/* Used for SecKeyGenerateSymmetric */
SEC_CONST_DECL (kSecSymmetricKeyAttrs, "symmetric");
#include <security_utilities/casts.h>
#include <CommonCrypto/CommonKeyDerivation.h>
+#include <CoreFoundation/CFPriv.h>
+// 'verify' macro is somehow dragged in from CFPriv.h and breaks compilation of signclient.h, so undef it, we don't need it.
+#undef verify
+
#include "SecBridge.h"
#include <security_keychain/Access.h>
key->key = const_cast<KeyItem *>(reinterpret_cast<const KeyItem *>(keyData));
key->key->initializeWithSecKeyRef(key);
key->credentialType = kSecCredentialTypeDefault;
+ key->cdsaKeyMutex = new Mutex();
return errSecSuccess;
}
// If we hold the keychain's mutex (the key's 'mutexForObject') during this destruction, pthread gets upset.
// Hold a reference to the keychain (if it exists) until after we release the keychain's mutex.
+ StMaybeLock<Mutex> cdsaMutex(keyRef->cdsaKeyMutex);
+
KeyItem *keyItem = keyRef->key;
+
if (keyItem == NULL) {
// KeyImpl::attachSecKeyRef disconnected us from KeyItem instance, there is nothing to do for us.
+ cdsaMutex.unlock();
+ delete keyRef->cdsaKeyMutex;
return;
}
Keychain kc = keyItem->keychain();
+ // We have a +1 reference to the KeyItem now; no need to protect our storage any more
+ cdsaMutex.unlock();
+
{
StMaybeLock<Mutex> _(keyItem->getMutexForObject());
keyItem = keyRef->key;
delete keyItem;
}
+ delete keyRef->cdsaKeyMutex;
+
(void) kc; // Tell the compiler we're actually using this variable. At destruction time, it'll release the keychain.
}
#pragma clang diagnostic pop
static SecKeyRef SecCDSAKeyCopyPublicKey(SecKeyRef privateKey) {
- CFErrorRef *error;
+ CFErrorRef *error = NULL;
BEGIN_SECKEYAPI(SecKeyRef, NULL)
result = NULL;
}
static Boolean SecCDSAKeyIsEqual(SecKeyRef key1, SecKeyRef key2) {
- CFErrorRef *error;
+ CFErrorRef *error = NULL;
BEGIN_SECKEYAPI(Boolean, false)
result = key1->key->equal(*key2->key);
.copyOperationResult = SecCDSAKeyCopyOperationResult,
.isEqual = SecCDSAKeyIsEqual,
.setParameter = SecCDSAKeySetParameter,
+
+ .extraBytes = (sizeof(struct OpaqueSecKeyRef) > sizeof(struct __SecKey) ? (sizeof(struct OpaqueSecKeyRef) - sizeof(struct __SecKey)) : 0),
};
namespace Security {
//
static ModuleNexus<Mutex> gSecReturnedKeyCSPsMutex;
-static std::set<CssmClient::CSP> gSecReturnedKeyCSPs;
+static ModuleNexus<std::set<CssmClient::CSP>> gSecReturnedKeyCSPs;
OSStatus
SecKeyGetCSPHandle(SecKeyRef keyRef, CSSM_CSP_HANDLE *cspHandle)
CssmClient::CSP returnedKeyCSP = keyItem->csp();
{
StLock<Mutex> _(gSecReturnedKeyCSPsMutex());
- gSecReturnedKeyCSPs.insert(returnedKeyCSP);
+ gSecReturnedKeyCSPs().insert(returnedKeyCSP);
}
Required(cspHandle) = returnedKeyCSP->handle();
Required(publicKey);
Required(privateKey);
- CFTypeRef tokenID = GetAttributeFromParams(parameters, kSecAttrTokenID, NULL);
- CFTypeRef noLegacy = GetAttributeFromParams(parameters, kSecAttrNoLegacy, NULL);
- CFTypeRef sync = GetAttributeFromParams(parameters, kSecAttrSynchronizable, kSecPrivateKeyAttrs);
- CFTypeRef accessControl = GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPrivateKeyAttrs) ?:
- GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPublicKeyAttrs);
- CFTypeRef accessGroup = GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPrivateKeyAttrs) ?:
- GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPublicKeyAttrs);
-
- // If any of these attributes are present, forward the call to iOS implementation (and create keys in iOS keychain).
- if (tokenID != NULL ||
- (noLegacy != NULL && CFBooleanGetValue((CFBooleanRef)noLegacy)) ||
- (sync != NULL && CFBooleanGetValue((CFBooleanRef)sync)) ||
- accessControl != NULL || (accessGroup != NULL && CFEqual(accessGroup, kSecAttrAccessGroupToken))) {
+ bool forceIOSKey = false;
+ if (_CFMZEnabled()) {
+ // On Marzipan, always go iOS SecItem/SecKey route, do not drag CSSM keys in.
+ forceIOSKey = true;
+ } else {
+ CFTypeRef tokenID = GetAttributeFromParams(parameters, kSecAttrTokenID, NULL);
+ CFTypeRef noLegacy = GetAttributeFromParams(parameters, kSecAttrNoLegacy, NULL);
+ CFTypeRef sync = GetAttributeFromParams(parameters, kSecAttrSynchronizable, kSecPrivateKeyAttrs);
+ CFTypeRef accessControl = GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPrivateKeyAttrs) ?:
+ GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPublicKeyAttrs);
+ CFTypeRef accessGroup = GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPrivateKeyAttrs) ?:
+ GetAttributeFromParams(parameters, kSecAttrAccessGroup, kSecPublicKeyAttrs);
+ // If any of these attributes are present, forward the call to iOS implementation (and create keys in iOS keychain).
+ forceIOSKey = (tokenID != NULL ||
+ (noLegacy != NULL && CFBooleanGetValue((CFBooleanRef)noLegacy)) ||
+ (sync != NULL && CFBooleanGetValue((CFBooleanRef)sync)) ||
+ accessControl != NULL || (accessGroup != NULL && CFEqual(accessGroup, kSecAttrAccessGroupToken)));
+ }
+
+ if (forceIOSKey) {
// Generate keys in iOS keychain.
return SecKeyGeneratePair_ios(parameters, publicKey, privateKey);
}
END_SECAPI
}
-static ModuleNexus<Mutex> gSecReturnedKeyCSPsMutex;
-static std::set<CssmClient::CSP> gSecReturnedKeychainCSPs;
+static ModuleNexus<Mutex> gSecReturnedKeychainCSPsMutex;
+static ModuleNexus<std::set<CssmClient::CSP>> gSecReturnedKeychainCSPs;
OSStatus
SecKeychainGetCSPHandle(SecKeychainRef keychainRef, CSSM_CSP_HANDLE *cspHandle)
// Keep a global pointer to it to force the CSP to stay live forever.
CssmClient::CSP returnedKeychainCSP = keychain->csp();
{
- StLock<Mutex> _(gSecReturnedKeyCSPsMutex());
- gSecReturnedKeychainCSPs.insert(returnedKeychainCSP);
+ StLock<Mutex> _(gSecReturnedKeychainCSPsMutex());
+ gSecReturnedKeychainCSPs().insert(returnedKeychainCSP);
}
*cspHandle = returnedKeychainCSP->handle();
@field pid The id of the process that generated this event.
@discussion The SecKeychainCallbackInfo type represents a structure that contains information about the keychain event for which your application is being notified. For information on how to write a keychain event callback function, see SecKeychainCallback.
*/
-struct SecKeychainCallbackInfo
+struct API_UNAVAILABLE(ios) SecKeychainCallbackInfo
{
UInt32 version;
SecKeychainItemRef __nonnull item;
SecKeychainRef __nonnull keychain;
pid_t pid;
};
-typedef struct SecKeychainCallbackInfo SecKeychainCallbackInfo;
+typedef struct SecKeychainCallbackInfo SecKeychainCallbackInfo API_UNAVAILABLE(ios);
/*!
@function SecKeychainGetTypeID
@param keychain On return, a pointer to a keychain reference. The memory that keychain occupies must be released by calling CFRelease when finished with it.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain parameter is invalid (NULL).
*/
-OSStatus SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void * __nullable password, Boolean promptUser, SecAccessRef __nullable initialAccess, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain);
+OSStatus SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void * __nullable password, Boolean promptUser, SecAccessRef __nullable initialAccess, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain) API_UNAVAILABLE(ios);
/*!
@function SecKeychainDelete
@param keychainOrArray A single keychain reference or a reference to an array of keychains to delete. IMPORTANT: SecKeychainDelete does not dispose the memory occupied by keychain references; use the CFRelease function when you are completely finished with a keychain.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecInvalidKeychain (-25295) may be returned if the keychain parameter is invalid (NULL).
*/
-OSStatus SecKeychainDelete(SecKeychainRef __nullable keychainOrArray);
+OSStatus SecKeychainDelete(SecKeychainRef __nullable keychainOrArray) API_UNAVAILABLE(ios);
/*!
@function SecKeychainSetSettings
@param newSettings A pointer to the new keychain settings.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainSetSettings(SecKeychainRef __nullable keychain, const SecKeychainSettings *newSettings);
+OSStatus SecKeychainSetSettings(SecKeychainRef __nullable keychain, const SecKeychainSettings *newSettings) API_UNAVAILABLE(ios);
/*!
@function SecKeychainCopySettings
@param outSettings A pointer to a keychain settings structure. Since this structure is versioned, you must preallocate it and fill in the version of the structure.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainCopySettings(SecKeychainRef __nullable keychain, SecKeychainSettings *outSettings);
+OSStatus SecKeychainCopySettings(SecKeychainRef __nullable keychain, SecKeychainSettings *outSettings) API_UNAVAILABLE(ios);
/*!
@function SecKeychainUnlock
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion In most cases, your application does not need to call the SecKeychainUnlock function directly, since most Keychain Manager functions that require an unlocked keychain call SecKeychainUnlock automatically. If your application needs to verify that a keychain is unlocked, call the function SecKeychainGetStatus.
*/
-OSStatus SecKeychainUnlock(SecKeychainRef __nullable keychain, UInt32 passwordLength, const void * __nullable password, Boolean usePassword);
+OSStatus SecKeychainUnlock(SecKeychainRef __nullable keychain, UInt32 passwordLength, const void * __nullable password, Boolean usePassword) API_UNAVAILABLE(ios);
/*!
@function SecKeychainLock
@param keychain A reference to the keychain to lock.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainLock(SecKeychainRef __nullable keychain);
+OSStatus SecKeychainLock(SecKeychainRef __nullable keychain) API_UNAVAILABLE(ios);
/*!
@function SecKeychainLockAll
@abstract Locks all keychains belonging to the current user.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainLockAll(void);
+OSStatus SecKeychainLockAll(void) API_UNAVAILABLE(ios);
/*!
@function SecKeychainCopyDefault
@param keychain On return, a pointer to the default keychain reference.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainCopyDefault(SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain);
+OSStatus SecKeychainCopyDefault(SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain) API_UNAVAILABLE(ios);
/*!
@function SecKeychainSetDefault
@param keychain A reference to the keychain to set as default.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain parameter is invalid (NULL).
*/
-OSStatus SecKeychainSetDefault(SecKeychainRef __nullable keychain);
+OSStatus SecKeychainSetDefault(SecKeychainRef __nullable keychain) API_UNAVAILABLE(ios);
/*!
@function SecKeychainCopySearchList
@param searchList The returned list of keychains to search. When finished with the array, you must call CFRelease() to release the memory.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain list is not specified (NULL).
*/
-OSStatus SecKeychainCopySearchList(CFArrayRef * __nonnull CF_RETURNS_RETAINED searchList);
+OSStatus SecKeychainCopySearchList(CFArrayRef * __nonnull CF_RETURNS_RETAINED searchList) API_UNAVAILABLE(ios);
/*!
@function SecKeychainSetSearchList
@param searchList The list of keychains to use in a search list when the SecKeychainCopySearchList function is called. An empty array clears the search list.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if the keychain list is not specified (NULL).
*/
-OSStatus SecKeychainSetSearchList(CFArrayRef searchList);
+OSStatus SecKeychainSetSearchList(CFArrayRef searchList) API_UNAVAILABLE(ios);
/*
@param keychainStatus On return, a pointer to the status of the specified keychain. See KeychainStatus for valid status constants.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainGetStatus(SecKeychainRef __nullable keychain, SecKeychainStatus *keychainStatus);
+OSStatus SecKeychainGetStatus(SecKeychainRef __nullable keychain, SecKeychainStatus *keychainStatus) API_UNAVAILABLE(ios);
/*!
@function SecKeychainGetPath
@param pathName On return, the POSIX path to the keychain.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainGetPath(SecKeychainRef __nullable keychain, UInt32 *ioPathLength, char *pathName);
+OSStatus SecKeychainGetPath(SecKeychainRef __nullable keychain, UInt32 *ioPathLength, char *pathName) API_UNAVAILABLE(ios);
#pragma mark ---- Keychain Item Attribute Information ----
/*!
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters were supplied (NULL).
@discussion Warning, this call returns more attributes than are support by the old style Keychain API and passing them into older calls will yield an invalid attribute error. The recommended call to retrieve the attribute values is the SecKeychainItemCopyAttributesAndData function.
*/
-OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef __nullable keychain, UInt32 itemID, SecKeychainAttributeInfo * __nullable * __nonnull info);
+OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef __nullable keychain, UInt32 itemID, SecKeychainAttributeInfo * __nullable * __nonnull info) API_UNAVAILABLE(ios);
/*!
@function SecKeychainFreeAttributeInfo
@param info A pointer to the keychain attribute information to release.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters were supplied (NULL).
*/
-OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info);
+OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info) API_UNAVAILABLE(ios);
#pragma mark ---- Keychain Manager Callbacks ----
To add your callback function, use the SecKeychainAddCallback function. To remove your callback function, use the SecKeychainRemoveCallback function.
*/
-typedef OSStatus (*SecKeychainCallback)(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void * __nullable context);
+typedef OSStatus (*SecKeychainCallback)(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void * __nullable context) API_UNAVAILABLE(ios);
/*!
@function SecKeychainAddCallback
@param userContext A pointer to application-defined storage that will be passed to your callback function. Your application can use this to associate any particular call of SecKeychainAddCallback with any particular call of your keychain event callback function.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void * __nullable userContext);
+OSStatus SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void * __nullable userContext) API_UNAVAILABLE(ios);
/*!
@function SecKeychainRemoveCallback
@param callbackFunction The callback function pointer to remove
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction);
+OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction) API_UNAVAILABLE(ios);
#pragma mark ---- High Level Keychain Manager Calls ----
/*!
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion The SecKeychainAddInternetPassword function adds a new Internet server password to the specified keychain. Required parameters to identify the password are serverName and accountName (you cannot pass NULL for both parameters). In addition, some protocols may require an optional securityDomain when authentication is requested. SecKeychainAddInternetPassword optionally returns a reference to the newly added item.
*/
-OSStatus SecKeychainAddInternetPassword(SecKeychainRef __nullable keychain, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef);
+OSStatus SecKeychainAddInternetPassword(SecKeychainRef __nullable keychain, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios);
/*!
@function SecKeychainFindInternetPassword
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion The SecKeychainFindInternetPassword function finds the first Internet password item which matches the attributes you provide. Most attributes are optional; you should pass only as many as you need to narrow the search sufficiently for your application's intended use. SecKeychainFindInternetPassword optionally returns a reference to the found item.
*/
-OSStatus SecKeychainFindInternetPassword(CFTypeRef __nullable keychainOrArray, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef);
+OSStatus SecKeychainFindInternetPassword(CFTypeRef __nullable keychainOrArray, UInt32 serverNameLength, const char * __nullable serverName, UInt32 securityDomainLength, const char * __nullable securityDomain, UInt32 accountNameLength, const char * __nullable accountName, UInt32 pathLength, const char * __nullable path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios);
/*!
@function SecKeychainAddGenericPassword
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion The SecKeychainAddGenericPassword function adds a new generic password to the default keychain. Required parameters to identify the password are serviceName and accountName, which are application-defined strings. SecKeychainAddGenericPassword optionally returns a reference to the newly added item.
*/
-OSStatus SecKeychainAddGenericPassword(SecKeychainRef __nullable keychain, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef);
+OSStatus SecKeychainAddGenericPassword(SecKeychainRef __nullable keychain, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios);
/*!
@function SecKeychainFindGenericPassword
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion The SecKeychainFindGenericPassword function finds the first generic password item which matches the attributes you provide. Most attributes are optional; you should pass only as many as you need to narrow the search sufficiently for your application's intended use. SecKeychainFindGenericPassword optionally returns a reference to the found item.
*/
-OSStatus SecKeychainFindGenericPassword(CFTypeRef __nullable keychainOrArray, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef);
+OSStatus SecKeychainFindGenericPassword(CFTypeRef __nullable keychainOrArray, UInt32 serviceNameLength, const char * __nullable serviceName, UInt32 accountNameLength, const char * __nullable accountName, UInt32 * __nullable passwordLength, void * __nullable * __nullable passwordData, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios);
#pragma mark ---- Managing User Interaction ----
/*!
@param state A boolean representing the state of user interaction. You should pass TRUE to allow user interaction, and FALSE to disallow user interaction
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainSetUserInteractionAllowed(Boolean state);
+OSStatus SecKeychainSetUserInteractionAllowed(Boolean state) API_UNAVAILABLE(ios);
/*!
@function SecKeychainGetUserInteractionAllowed
@param state On return, a pointer to the current state of user interaction. If this is TRUE then user interaction is allowed, if it is FALSE, then user interaction is not allowed.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state);
+OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state) API_UNAVAILABLE(ios);
#pragma mark ---- CSSM Bridge Functions ----
/*!
}
CFErrorRef errorRef = NULL;
- CFDataRef serialData = SecCertificateCopySerialNumber(certItem, &errorRef);
+ CFDataRef serialData = SecCertificateCopySerialNumberData(certItem, &errorRef);
if (errorRef) {
CFIndex err = CFErrorGetCode(errorRef);
CFRelease(errorRef);
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns errSecSuccess.
*/
-OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data);
+OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCreateFromContent
*/
OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList,
UInt32 length, const void * __nullable data, SecKeychainRef __nullable keychainRef,
- SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef);
+ SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemModifyContent
@param data A pointer to a buffer containing the data to store. Pass NULL if you don't need to modify the data.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data);
+OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCopyContent
@param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeContent when you no longer need the data.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied.
*/
-OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData);
+OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemFreeContent
@param attrList A pointer to the attribute list to release. Pass NULL to ignore this parameter.
@param data A pointer to the data buffer to release. Pass NULL to ignore this parameter.
*/
-OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList * __nullable attrList, void * __nullable data);
+OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList * __nullable attrList, void * __nullable data) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCopyAttributesAndData
@param outData On return, a pointer to a buffer containing the data in this item. Pass NULL if you don't need to retrieve the data. You must call SecKeychainItemFreeAttributesAndData when you no longer need the data.
@result A result code. See "Security Error Codes" (SecBase.h). In addition, errSecParam (-50) may be returned if not enough valid parameters are supplied.
*/
-OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo * __nullable info, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData);
+OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo * __nullable info, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemFreeAttributesAndData
@param data A pointer to the data buffer to release. Pass NULL to ignore this parameter.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList * __nullable attrList, void * __nullable data);
+OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList * __nullable attrList, void * __nullable data) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemDelete
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion If itemRef has not previously been added to the keychain, SecKeychainItemDelete does nothing and returns errSecSuccess. IMPORTANT: SecKeychainItemDelete does not dispose the memory occupied by the item reference itself; use the CFRelease function when you are completely finished with an item.
*/
-OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef);
+OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCopyKeychain
@param keychainRef On return, the keychain reference for the specified item. Release this reference by calling the CFRelease function.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychainRef);
+OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychainRef) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCreateCopy
@result A result code. See "Security Error Codes" (SecBase.h).
*/
OSStatus SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainRef __nullable destKeychainRef,
- SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemCopy);
+ SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemCopy) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCreatePersistentReference
@param persistentItemRef On return, a CFDataRef containing a persistent reference. You must release this data reference by calling the CFRelease function.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CFDataRef * __nonnull CF_RETURNS_RETAINED persistentItemRef);
+OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CFDataRef * __nonnull CF_RETURNS_RETAINED persistentItemRef) API_UNAVAILABLE(ios);
/*!
@param itemRef On return, a SecKeychainItemRef for the keychain item described by the persistent reference. You must release this item reference by calling the CFRelease function.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemRef);
+OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios);
#pragma mark ---- CSSM Bridge Functions ----
@param access On return, a reference to the keychain item's access.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef * __nonnull CF_RETURNS_RETAINED access);
+OSStatus SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef * __nonnull CF_RETURNS_RETAINED access) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemSetAccess
@param access A reference to an access to replace the keychain item's current access.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef access);
+OSStatus SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef access) API_UNAVAILABLE(ios);
CF_ASSUME_NONNULL_END
OSStatus SecKeychainItemSetExtendedAttribute(
SecKeychainItemRef itemRef,
CFStringRef attrName, /* identifies the attribute */
- CFDataRef attrValue); /* value to set; NULL means delete the
+ CFDataRef attrValue) /* value to set; NULL means delete the
* attribute */
+ API_UNAVAILABLE(ios);
/*
* SecKeychainItemCopyExtendedAttribute() - Obtain the value of an an extended attribute.
OSStatus SecKeychainItemCopyExtendedAttribute(
SecKeychainItemRef itemRef,
CFStringRef attrName,
- CFDataRef *attrValue); /* RETURNED */
+ CFDataRef *attrValue) API_UNAVAILABLE(ios); /* RETURNED */
/*
* SecKeychainItemCopyAllExtendedAttributes() - obtain all of an item's extended attributes.
OSStatus SecKeychainItemCopyAllExtendedAttributes(
SecKeychainItemRef itemRef,
CFArrayRef *attrNames, /* RETURNED, each element is a CFStringRef */
- CFArrayRef *attrValues); /* optional, RETURNED, each element is a
+ CFArrayRef *attrValues) /* optional, RETURNED, each element is a
* CFDataRef */
+ API_UNAVAILABLE(ios);
#if defined(__cplusplus)
}
#endif
/* also kSecModDateItemAttr from SecKeychainItem.h */
};
-OSStatus SecKeychainItemCreateNew(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, SecKeychainItemRef* itemRef);
+OSStatus SecKeychainItemCreateNew(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, SecKeychainItemRef* itemRef) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, void* data, UInt32* actualLength);
+OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, void* data, UInt32* actualLength) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemGetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute, UInt32* actualLength);
+OSStatus SecKeychainItemGetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute, UInt32* actualLength) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute);
+OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemAdd(SecKeychainItemRef itemRef);
+OSStatus SecKeychainItemAdd(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemAddNoUI(SecKeychainRef keychainRef, SecKeychainItemRef itemRef);
+OSStatus SecKeychainItemAddNoUI(SecKeychainRef keychainRef, SecKeychainItemRef itemRef) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemUpdate(SecKeychainItemRef itemRef);
+OSStatus SecKeychainItemUpdate(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data);
+OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data) API_UNAVAILABLE(ios);
-OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef, SecKeychainItemRef *itemRef);
+OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef, SecKeychainItemRef *itemRef) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCopyRecordIdentifier
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeychainItemCopyRecordIdentifier(SecKeychainItemRef itemRef, CFDataRef *recordIdentifier);
+OSStatus SecKeychainItemCopyRecordIdentifier(SecKeychainItemRef itemRef, CFDataRef *recordIdentifier) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCopyFromRecordIdentifier
OSStatus SecKeychainItemCopyFromRecordIdentifier(SecKeychainRef keychain,
SecKeychainItemRef *itemRef,
- CFDataRef recordIdentifier);
+ CFDataRef recordIdentifier) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCopyAttributesAndEncryptedData
*/
OSStatus SecKeychainItemCopyAttributesAndEncryptedData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info,
SecItemClass *itemClass, SecKeychainAttributeList **attrList,
- UInt32 *length, void **outData);
+ UInt32 *length, void **outData) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemModifyEncryptedData
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion The keychain item is written to the keychain's permanent data store. If the keychain item has not previously been added to a keychain, a call to the SecKeychainItemModifyContent function does nothing and returns errSecSuccess.
*/
-OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 length, const void *data);
+OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 length, const void *data) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemCreateFromEncryptedContent
*/
OSStatus SecKeychainItemCreateFromEncryptedContent(SecItemClass itemClass, UInt32 length, const void *data,
SecKeychainRef keychainRef, SecAccessRef initialAccess,
- SecKeychainItemRef *itemRef, CFDataRef *itemLocalID);
+ SecKeychainItemRef *itemRef, CFDataRef *itemLocalID) API_UNAVAILABLE(ios);
/*!
@function SecKeychainItemSetAccessWithPassword
@param password A buffer containing the password for the keychain. if this password is incorrect, this call might fail---it will not prompt the user.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
- OSStatus SecKeychainItemSetAccessWithPassword(SecKeychainItemRef itemRef, SecAccessRef accessRef, UInt32 passwordLength, const void * password);
+ OSStatus SecKeychainItemSetAccessWithPassword(SecKeychainItemRef itemRef, SecAccessRef accessRef, UInt32 passwordLength, const void * password) API_UNAVAILABLE(ios);
#if defined(__cplusplus)
}
#endif
#include <Security/Security.h>
#include <Security/SecBasePriv.h>
+#include <Security/SecKeychain.h>
#include <CoreFoundation/CoreFoundation.h>
#if defined(__cplusplus)
OSStatus SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword)
__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
OSStatus SecKeychainOpenWithGuid(const CSSM_GUID *guid, uint32 subserviceId, uint32 subserviceType, const char* dbName, const CSSM_NET_ADDRESS *dbLocation, SecKeychainRef *keychain)
- __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
+ API_DEPRECATED("CSSM_GUID/CSSM_NET_ADDRESS is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios);
OSStatus SecKeychainSetBatchMode (SecKeychainRef kcRef, Boolean mode, Boolean rollback)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
/* Login keychain support */
OSStatus SecKeychainLogin(UInt32 nameLength, const void* name, UInt32 passwordLength, const void* password)
__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
-OSStatus SecKeychainStash()
+OSStatus SecKeychainStash(void)
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
-OSStatus SecKeychainLogout()
+OSStatus SecKeychainLogout(void)
__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef)
__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA);
OSStatus SecKeychainVerifyKeyStorePassphrase(uint32_t retries)
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
-OSStatus SecKeychainChangeKeyStorePassphrase()
+OSStatus SecKeychainChangeKeyStorePassphrase(void)
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
/* Keychain synchronization */
/* Keychain list manipulation */
OSStatus SecKeychainAddDBToKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType)
- __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
+ API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios);
OSStatus SecKeychainDBIsInKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType)
- __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
+ API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios);
OSStatus SecKeychainRemoveDBFromKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType)
- __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
+ API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios);
/* server operation (keychain inhibit) */
-void SecKeychainSetServerMode()
+void SecKeychainSetServerMode(void)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
/* special calls */
-OSStatus SecKeychainCleanupHandles()
+OSStatus SecKeychainCleanupHandles(void)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
-OSStatus SecKeychainSystemKeychainCheckWouldDeadlock()
+OSStatus SecKeychainSystemKeychainCheckWouldDeadlock(void)
__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);
@function SecKeychainMDSInstall
Set up MDS.
*/
-OSStatus SecKeychainMDSInstall();
+OSStatus SecKeychainMDSInstall(void);
#if defined(__cplusplus)
}
@param itemAttrList (in/opt) A list of attributes which will be used for item creation.
@param itemRef (out) On return, a pointer to a password reference. Release this by calling the CFRelease function.
*/
-OSStatus SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList, SecPasswordRef *itemRef);
+OSStatus SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList, SecPasswordRef *itemRef) API_UNAVAILABLE(ios);
/*!
@function SecPasswordAction
@param data A pointer to a buffer containing the data to store.
*/
-OSStatus SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt32 *length, const void **data);
+OSStatus SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt32 *length, const void **data) API_UNAVAILABLE(ios);
/*!
@function SecPasswordSetInitialAccess
@abstract Set the initial access ref. Only used when a password is first added to the keychain.
*/
-OSStatus SecPasswordSetInitialAccess(SecPasswordRef itemRef, SecAccessRef accessRef);
+OSStatus SecPasswordSetInitialAccess(SecPasswordRef itemRef, SecAccessRef accessRef) API_UNAVAILABLE(ios);
#if defined(__cplusplus)
}
static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
*/
-const oidmap_entry_t oidmap[] = {
- { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC },
- { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL },
- { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME },
- { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP },
- { kSecPolicyAppleSWUpdateSigning, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
- { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC },
- { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT },
- { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT },
- { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER },
- { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING },
- { kSecPolicyApplePackageSigning, &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
- { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING },
- { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
- { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING },
- { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION },
- { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_OCSP },
- { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_CRL },
- { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
- { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE },
- { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE },
- { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING },
- { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
- { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
- { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
- { kSecPolicyAppleOSXProvisioningProfileSigning, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING },
-};
-const oidmap_entry_t oidmap_priv[] = {
- { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC },
- { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL },
- { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL },
- { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME },
- { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP },
- { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP },
- { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
- { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC },
- { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC },
- { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING },
- { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
- { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING },
- { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
- { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING },
- { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION },
- { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
- { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE },
- { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE },
- { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING },
- { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
- { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
- { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
- { CFSTR("AppleOSXProvisioningProfileSigning"), &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING },
+static const size_t OIDMAP_LENGTH = 25;
+static const oidmap_entry_t* oidmap_f() {
+ static const oidmap_entry_t oidmap_array[] = {
+ { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC },
+ { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL },
+ { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME },
+ { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP },
+ { kSecPolicyAppleSWUpdateSigning, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
+ { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC },
+ { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT },
+ { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT },
+ { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER },
+ { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING },
+ { kSecPolicyApplePackageSigning, &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
+ { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING },
+ { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
+ { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING },
+ { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION },
+ { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_OCSP },
+ { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_CRL },
+ { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
+ { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE },
+ { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE },
+ { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING },
+ { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
+ { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
+ { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
+ { kSecPolicyAppleOSXProvisioningProfileSigning, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING },
+ };
+ static_assert(OIDMAP_LENGTH == (sizeof(oidmap_array)/sizeof(oidmap_entry_t)), "OIDMAP_LENGTH is incorrect; must match oidmap_array");
+
+ return oidmap_array;
};
+static const size_t OIDMAP_PRIV_LENGTH = 23;
+static const oidmap_entry_t* oidmap_priv_f() {
+ static const oidmap_entry_t oidmap_priv_array[] = {
+ { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC },
+ { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL },
+ { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL },
+ { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME },
+ { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP },
+ { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP },
+ { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
+ { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC },
+ { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC },
+ { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING },
+ { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
+ { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING },
+ { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
+ { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING },
+ { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION },
+ { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
+ { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE },
+ { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE },
+ { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING },
+ { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
+ { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
+ { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
+ { CFSTR("AppleOSXProvisioningProfileSigning"), &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING },
+ };
+ static_assert(OIDMAP_PRIV_LENGTH == (sizeof(oidmap_priv_array)/sizeof(oidmap_entry_t)), "OIDMAP_PRIV_LENGTH is incorrect; must match oidmap_priv_array");
+
+ return oidmap_priv_array;
+}
+
//
// Sec API bridge functions
//
return errSecParam; // bad policy ref?
}
CSSM_OID *oidptr = NULL;
- unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
- for (i=0; i<oidmaplen; i++) {
- CFStringRef str = (CFStringRef) oidmap[i].oidstr;
+ unsigned int i;
+ for (i=0; i<OIDMAP_LENGTH; i++) {
+ CFStringRef str = (CFStringRef) oidmap_f()[i].oidstr;
if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
- oidptr = (CSSM_OID*)oidmap[i].oidptr;
+ oidptr = (CSSM_OID*)oidmap_f()[i].oidptr;
break;
}
}
if (!oidptr) {
// Check private iOS policy names.
- oidmaplen = sizeof(oidmap_priv) / sizeof(oidmap_entry_t);
- for (i=0; i<oidmaplen; i++) {
- CFStringRef str = (CFStringRef) oidmap_priv[i].oidstr;
+
+ for (i=0; i<OIDMAP_PRIV_LENGTH; i++) {
+ CFStringRef str = (CFStringRef) oidmap_priv_f()[i].oidstr;
if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
- oidptr = (CSSM_OID*)oidmap_priv[i].oidptr;
+ oidptr = (CSSM_OID*)oidmap_priv_f()[i].oidptr;
break;
}
}
return NULL;
}
// given a CSSM_OID pointer, return corresponding string in oidmap
- unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
- for (i=0; i<oidmaplen; i++) {
- CSSM_OID* oidptr = (CSSM_OID*)oidmap[i].oidptr;
+ unsigned int i;
+ for (i=0; i<OIDMAP_LENGTH; i++) {
+ CSSM_OID* oidptr = (CSSM_OID*)oidmap_f()[i].oidptr;
if (compareOids(oid, oidptr)) {
- return (CFStringRef) oidmap[i].oidstr;
+ return (CFStringRef) oidmap_f()[i].oidstr;
}
}
return NULL;
if (!oidStr) {
return policy;
}
- unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
- for (i=0; i<oidmaplen; i++) {
- CFStringRef str = (CFStringRef) oidmap[i].oidstr;
+ unsigned int i;
+ for (i=0; i<OIDMAP_LENGTH; i++) {
+ CFStringRef str = (CFStringRef) oidmap_f()[i].oidstr;
if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
- oidPtr = (CSSM_OID*)oidmap[i].oidptr;
+ oidPtr = (CSSM_OID*)oidmap_f()[i].oidptr;
break;
}
}
const SecRandomRef kSecRandomDefault = NULL;
-int SecRandomCopyBytes(SecRandomRef rnd, size_t count, void *bytes) {
- if (rnd != kSecRandomDefault)
- return errSecParam;
+int SecRandomCopyBytes(__unused SecRandomRef rnd, size_t count, void *bytes) {
return CCRandomCopyBytes(kCCRandomDefault, bytes, count);
}
bool exceptionNotFound;
} SecTrustCheckExceptionContext;
-// public trust result constants
-const CFStringRef kSecTrustEvaluationDate = CFSTR("TrustEvaluationDate");
-const CFStringRef kSecTrustExtendedValidation = CFSTR("TrustExtendedValidation");
-const CFStringRef kSecTrustOrganizationName = CFSTR("Organization");
-const CFStringRef kSecTrustResultValue = CFSTR("TrustResultValue");
-const CFStringRef kSecTrustRevocationChecked = CFSTR("TrustRevocationChecked");
-const CFStringRef kSecTrustRevocationReason = CFSTR("TrustRevocationReason");
-const CFStringRef kSecTrustRevocationValidUntilDate = CFSTR("TrustExpirationDate");
-const CFStringRef kSecTrustResultDetails = CFSTR("TrustResultDetails");
-
//
// Sec* API bridge functions
//
/* Go through outArray and do a SecTrustEvaluate */
CFIndex i;
SecPolicyRef policy = SecPolicyCreateBasicX509();
+ SecTrustRef trust = NULL;
CFMutableArrayRef trustedCertArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
for (i = 0; i < count ; i++) {
- SecTrustRef trust;
SecTrustResultType result;
SecCertificateRef certificate = (SecCertificateRef) CFArrayGetValueAtIndex(outArray, i);
status = SecTrustCreateWithCertificates(certificate, policy, &trust);
if (result != kSecTrustResultFatalTrustFailure) {
CFArrayAppendValue(trustedCertArray, certificate);
}
+ CFReleaseNull(trust);
}
if (CFArrayGetCount(trustedCertArray) == 0) {
status = errSecNoTrustSettings;
out:
CFReleaseSafe(outArray);
CFReleaseSafe(policy);
+ CFReleaseSafe(trust);
return status;
END_SECAPI
}
{
SecKeyRef pubKey = NULL;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, 0);
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
(void) SecCertificateCopyPublicKey(certificate, &pubKey);
+#pragma clang diagnostic pop
return pubKey;
}
/* serialNumber is a CSSM_DATA with the value from the TBS Certificate. */
CSSM_DATA serialNumber = { 0, NULL };
- serialData = SecCertificateCopySerialNumber(cert, NULL);
+ serialData = SecCertificateCopySerialNumberData(cert, NULL);
if (serialData) {
serialNumber.Data = (uint8_t *)CFDataGetBytePtr(serialData);
serialNumber.Length = CFDataGetLength(serialData);
OSStatus status;
TrustSettings* ts;
CFMutableArrayRef trustedCertArray = NULL;
+ SecTrustRef trust = NULL;
status = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
if (status != errSecSuccess) {
SecPolicyRef policy = SecPolicyCreateBasicX509();
trustedCertArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
for (i = 0; i < count ; i++) {
- SecTrustRef trust;
SecTrustResultType result;
SecCertificateRef certificate = (SecCertificateRef) CFArrayGetValueAtIndex(outArray, i);
status = SecTrustCreateWithCertificates(certificate, policy, &trust);
if (result != kSecTrustResultFatalTrustFailure) {
CFArrayAppendValue(trustedCertArray, certificate);
}
+ CFReleaseNull(trust);
}
tsAddConditionalCerts(trustedCertArray);
if (CFArrayGetCount(trustedCertArray) == 0) {
CFReleaseSafe(outArray);
CFReleaseSafe(trustedCertArray);
}
+ CFReleaseNull(trust);
return status;
END_RCSAPI
}
static CFArrayRef gUserAdminCerts = NULL;
static bool gUserAdminCertsCacheBuilt = false;
-static ReadWriteLock gUserAdminCertsLock;
+static ModuleNexus<ReadWriteLock> gUserAdminCertsLock;
void SecTrustSettingsPurgeUserAdminCertsCache(void) {
- StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Write);
+ StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Write);
CFReleaseNull(gUserAdminCerts);
gUserAdminCertsCacheBuilt = false;
}
OSStatus result = errSecSuccess;
{ /* Hold the read lock for the check */
- StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Read);
+ StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Read);
if (gUserAdminCertsCacheBuilt) {
if (gUserAdminCerts) {
*certArray = (CFArrayRef)CFRetain(gUserAdminCerts);
/* For valid results, update the global cache */
if (result == errSecSuccess || result == errSecNoTrustSettings) {
- StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Write);
+ StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Write);
CFReleaseNull(gUserAdminCerts);
gUserAdminCerts = (CFArrayRef)CFRetainSafe(outArray);
gUserAdminCertsCacheBuilt = true;
@param app On return, a pointer to the trusted application reference.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecTrustedApplicationCreateFromPath(const char * __nullable path, SecTrustedApplicationRef * __nonnull CF_RETURNS_RETAINED app);
+OSStatus SecTrustedApplicationCreateFromPath(const char * __nullable path, SecTrustedApplicationRef * __nonnull CF_RETURNS_RETAINED app) API_UNAVAILABLE(ios);
/*!
@function SecTrustedApplicationCopyData
@param data On return, a pointer to a data reference of the trusted application.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef, CFDataRef * __nonnull CF_RETURNS_RETAINED data);
+OSStatus SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef, CFDataRef * __nonnull CF_RETURNS_RETAINED data) API_UNAVAILABLE(ios);
/*!
@function SecTrustedApplicationSetData
@param data A reference to the data to set in the trusted application.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecTrustedApplicationSetData(SecTrustedApplicationRef appRef, CFDataRef data);
+OSStatus SecTrustedApplicationSetData(SecTrustedApplicationRef appRef, CFDataRef data) API_UNAVAILABLE(ios);
CF_ASSUME_NONNULL_END
* Determine whether the application at path satisfies the trust expressed in appRef.
*/
OSStatus
-SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const char *path);
+SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const char *path) API_UNAVAILABLE(ios);
/*!
@function SecTrustedApplicationCreateFromRequirement
@result A result code. See SecBase.h and CSCommon.h.
*/
OSStatus SecTrustedApplicationCreateFromRequirement(const char *description,
- SecRequirementRef requirement, SecTrustedApplicationRef *app);
+ SecRequirementRef requirement, SecTrustedApplicationRef *app) API_UNAVAILABLE(ios);
/*!
@function SecTrustedApplicationCopyRequirement
no SecRequirementRef could be obtained.
*/
OSStatus SecTrustedApplicationCopyRequirement(SecTrustedApplicationRef appRef,
- SecRequirementRef *requirement);
+ SecRequirementRef *requirement) API_UNAVAILABLE(ios);
/*!
@result A result code. See SecBase.h and CSCommon.h.
*/
OSStatus SecTrustedApplicationCreateApplicationGroup(const char *groupName,
- SecCertificateRef anchor, SecTrustedApplicationRef *app);
+ SecCertificateRef anchor, SecTrustedApplicationRef *app) API_UNAVAILABLE(ios);
/*!
*/
OSStatus SecTrustedApplicationCopyExternalRepresentation(
SecTrustedApplicationRef appRef,
- CFDataRef *externalRef);
+ CFDataRef *externalRef) API_UNAVAILABLE(ios);
/*!
@function SecTrustedApplicationCreateWithExternalRepresentation
*/
OSStatus SecTrustedApplicationCreateWithExternalRepresentation(
CFDataRef externalRef,
- SecTrustedApplicationRef *appRef);
+ SecTrustedApplicationRef *appRef) API_UNAVAILABLE(ios);
/*
OSStatus
SecTrustedApplicationMakeEquivalent(SecTrustedApplicationRef oldRef,
- SecTrustedApplicationRef newRef, UInt32 flags);
+ SecTrustedApplicationRef newRef, UInt32 flags) API_UNAVAILABLE(ios);
OSStatus
-SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 flags);
+SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 flags) API_UNAVAILABLE(ios);
/*
* pre-emptive code equivalency establishment
*/
OSStatus
-SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path);
+SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path) API_UNAVAILABLE(ios);
/*
* This is for system update installers (only)!
*/
OSStatus
-SecTrustedApplicationUseAlternateSystem(const char *systemRoot);
+SecTrustedApplicationUseAlternateSystem(const char *systemRoot) API_UNAVAILABLE(ios);
#if defined(__cplusplus)
__block CFTypeRef kcHandle = kcImpl->handle(); // calls retain; this keychain object will stay around until our dispatch block fires.
- dispatch_async(release_queue, ^() {
+ // You _must not_ call CFRelease while on this queue, due to the locking order mishmash. CFRelease takes a lock, so remember to do it later.
+ __block bool releaseImmediately = false;
+
+ dispatch_sync(release_queue, ^() {
if(kcImpl->mCacheTimer) {
// Update the cache timer to be seconds from now
dispatch_source_set_timer(kcImpl->mCacheTimer, dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, NSEC_PER_SEC/2);
secdebug("keychain", "updating cache on %p %s", kcImpl, kcImpl->name());
- // We've added an extra retain to this keychain right before invoking this block. Release it.
- CFRelease(kcHandle);
-
+ // We've added an extra retain to this keychain right before invoking this block. Remember to release it.
+ releaseImmediately = true;
} else {
// No cache timer; make one.
kcImpl->mCacheTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, release_queue);
dispatch_source_cancel(kcImpl->mCacheTimer);
dispatch_release(kcImpl->mCacheTimer);
kcImpl->mCacheTimer = NULL;
- CFRelease(kcHandle);
+
+ // Since we're on the timer queue, we can't call CFRelease on the kcHandle (since that takes a lock). Dispatch_async it over to some other queue...
+ // This is better than using dispatch_async on the timer queue initially, since it's less dispatch_asyncs overall, even though it's more confusing.
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{
+ CFRelease(kcHandle);
+ });
});
dispatch_resume(kcImpl->mCacheTimer);
}
});
+
+ if(releaseImmediately) {
+ CFRelease(kcHandle);
+ }
}
// Create keychain if it doesn't exist, and optionally add it to the search list.
#include <coreauthd_spi.h>
}
+static os_log_t TOKEN_LOG_DEFAULT() {
+ static dispatch_once_t once;
+ static os_log_t log;
+ dispatch_once(&once, ^{ log = os_log_create("com.apple.security", "tokenlogin"); });
+ return log;
+};
+#define TL_LOG TOKEN_LOG_DEFAULT()
+
#define kSecTokenLoginDomain CFSTR("com.apple.security.tokenlogin")
static CFStringRef CF_RETURNS_RETAINED cfDataToHex(CFDataRef bin)
CFStringRef tokenId = (CFStringRef)CFDictionaryGetValue(context, kSecAttrTokenID);
if (!tokenId || CFGetTypeID(tokenId) != CFStringGetTypeID()) {
- secinfo("TokenLogin", "Invalid tokenId");
+ os_log_debug(TL_LOG, "Invalid tokenId");
return NULL;
}
return tokenId;
CFDataRef pubKeyHash = (CFDataRef)CFDictionaryGetValue(context, kSecAttrPublicKeyHash);
if (!pubKeyHash || CFGetTypeID(pubKeyHash) != CFDataGetTypeID()) {
- secinfo("TokenLogin", "Invalid pubkeyhash");
+ os_log_debug(TL_LOG, "Invalid pubkeyhash");
return NULL;
}
return pubKeyHash;
CFDataRef pubKeyHashWrap = (CFDataRef)CFDictionaryGetValue(context, kSecAttrAccount);
if (!pubKeyHashWrap || CFGetTypeID(pubKeyHashWrap) != CFDataGetTypeID()) {
- secinfo("TokenLogin", "Invalid pubkeyhashwrap");
+ os_log_debug(TL_LOG, "Invalid pubkeyhashwrap");
return NULL;
}
return pubKeyHashWrap;
static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey, CFTypeRef *laCtx)
{
- if (!context) {
- return errSecParam;
- }
+ if (!context) {
+ os_log_error(TL_LOG, "private key for pubkeyhash wrong params");
+ return errSecParam;
+ }
CFRef<CFMutableDictionaryRef> tokenAttributes = makeCFMutableDictionary(1, kSecAttrTokenID, getTokenId(context));
CFRef<CFErrorRef> error;
if (pin) {
CFRef<CFTypeRef> LAContext = LACreateNewContextWithACMContext(NULL, error.take());
if (!LAContext) {
- secinfo("TokenLogin", "Failed to LA Context: %@", error.get());
+ os_log_error(TL_LOG, "Failed to LA Context: %@", error.get());
return errSecParam;
}
if (laCtx)
*laCtx = (CFTypeRef)CFRetain(LAContext);
CFRef<CFDataRef> externalizedContext = LACopyACMContext(LAContext, error.take());
if (!externalizedContext) {
- secinfo("TokenLogin", "Failed to get externalized context: %@", error.get());
+ os_log_error(TL_LOG, "Failed to get externalized context: %@", error.get());
return errSecParam;
}
CFDictionarySetValue(tokenAttributes, kSecUseCredentialReference, externalizedContext.get());
CFRef<TKTokenRef> token = TKTokenCreate(tokenAttributes, error.take());
if (!token) {
- secinfo("TokenLogin", "Failed to create token: %@", error.get());
+ os_log_error(TL_LOG, "Failed to create token: %@", error.get());
return errSecParam;
}
CFRef<CFArrayRef> identities = TKTokenCopyIdentities(token, TKTokenKeyUsageAny, error.take());
if (!identities || !CFArrayGetCount(identities)) {
- secinfo("TokenLogin", "No identities found for token: %@", error.get());
+ os_log_error(TL_LOG, "No identities found for token: %@", error.get());
return errSecParam;
}
CFRef<SecCertificateRef> certificate;
OSStatus result = SecIdentityCopyCertificate(identity, certificate.take());
if (result != errSecSuccess) {
- secinfo("TokenLogin", "Failed to get certificate for identity: %d", (int) result);
+ os_log_error(TL_LOG, "Failed to get certificate for identity: %d", (int) result);
continue;
}
if (identityHash && CFEqual(desiredHash, identityHash)) {
result = SecIdentityCopyPrivateKey(identity, privKey);
if (result != errSecSuccess) {
- secinfo("TokenLogin", "Failed to get identity private key: %d", (int) result);
+ os_log_error(TL_LOG, "Failed to get identity private key: %d", (int) result);
}
return result;
}
OSStatus TokenLoginGetContext(const void *base64TokenLoginData, UInt32 base64TokenLoginDataLength, CFDictionaryRef *context)
{
- if (!base64TokenLoginData || !context) {
- return errSecParam;
- }
+ if (!base64TokenLoginData || !context) {
+ os_log_error(TL_LOG, "Get login context - wrong params");
+ return errSecParam;
+ }
// Token data are base64 encoded in password.
size_t dataLen = SecBase64Decode((const char *)base64TokenLoginData, base64TokenLoginDataLength, NULL, 0);
if (!dataLen) {
- secinfo("TokenLogin", "Invalid base64 encoded token data");
+ os_log_debug(TL_LOG, "Invalid base64 encoded token data");
return errSecParam;
}
CFRef<CFMutableDataRef> data = CFDataCreateMutable(kCFAllocatorDefault, dataLen);
dataLen = SecBase64Decode((const char *)base64TokenLoginData, base64TokenLoginDataLength, CFDataGetMutableBytePtr(data), dataLen);
if (!dataLen) {
- secinfo("TokenLogin", "Invalid base64 encoded token data");
+ os_log_error(TL_LOG, "Invalid base64 encoded token data");
return errSecParam;
}
CFDataSetLength(data, dataLen);
NULL,
error.take());
if (!*context || CFGetTypeID(*context) != CFDictionaryGetTypeID()) {
- secinfo("TokenLogin", "Invalid token login data property list, %@", error.get());
+ os_log_error(TL_LOG, "Invalid token login data property list, %@", error.get());
return errSecParam;
}
if (!getPin(*context) || !getTokenId(*context) || !getPubKeyHash(*context) || !getPubKeyHashWrap(*context)) {
- secinfo("TokenLogin", "Invalid token login data context, %@", error.get());
+ os_log_error(TL_LOG, "Invalid token login data context, %@", error.get());
return errSecParam;
}
OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey)
{
- if (!context || !unlockKey) {
- return errSecParam;
- }
+ if (!context || !unlockKey) {
+ os_log_error(TL_LOG, "Get unlock key - wrong params");
+ return errSecParam;
+ }
CFRef<CFDictionaryRef> loginData;
OSStatus result = TokenLoginGetLoginData(context, loginData.take());
if (result != errSecSuccess) {
- secinfo("TokenLogin", "Failed to get login data: %d", (int)result);
+ os_log_error(TL_LOG, "Failed to get login data: %d", (int)result);
return result;
}
CFDataRef wrappedUnlockKey = (CFDataRef)CFDictionaryGetValue(loginData, kSecValueData);
if (!wrappedUnlockKey) {
- secinfo("TokenLogin", "Wrapped unlock key not found in unlock key data");
+ os_log_error(TL_LOG, "Wrapped unlock key not found in unlock key data");
return errSecParam;
}
SecKeyAlgorithm algorithm = (SecKeyAlgorithm)CFDictionaryGetValue(loginData, kSecAttrService);
if (!algorithm) {
- secinfo("TokenLogin", "Algorithm not found in unlock key data");
+ os_log_error(TL_LOG, "Algorithm not found in unlock key data");
return errSecParam;
}
CFRef<CFTypeRef> LAContext;
result = privKeyForPubKeyHash(context, privKey.take(), LAContext.take());
if (result != errSecSuccess) {
- secinfo("TokenLogin", "Failed to get private key for public key hash: %d", (int)result);
+ os_log_error(TL_LOG, "Failed to get private key for public key hash: %d", (int)result);
return result;
}
CFRef<SecKeyRef> pubKey = SecKeyCopyPublicKey(privKey);
if (!pubKey) {
- secinfo("TokenLogin", "Failed to get public key from private key");
+ os_log_error(TL_LOG, "Failed to get public key from private key");
return errSecParam;
}
CFRef<CFErrorRef> error;
wrappedUnlockKey,
error.take());
if (!*unlockKey) {
- secinfo("TokenLogin", "Failed to unwrap unlock key: %@", error.get());
+ os_log_error(TL_LOG, "Failed to unwrap unlock key: %@", error.get());
return errSecDecode;
}
// we need to re-wrap already unwrapped data to avoid capturing and reusing communication with the smartcard
CFRef<CFDataRef> reWrappedUnlockKey = SecKeyCreateEncryptedData(pubKey, algorithm, *unlockKey, error.take());
if (!reWrappedUnlockKey) {
- secinfo("TokenLogin", "Failed to rewrap unlock key: %@", error.get());
+ os_log_error(TL_LOG, "Failed to rewrap unlock key: %@", error.get());
TokenLoginDeleteUnlockData(getPubKeyHash(context));
return errSecParam;
}
OSStatus TokenLoginGetLoginData(CFDictionaryRef context, CFDictionaryRef *loginData)
{
- if (!loginData || !context) {
- return errSecParam;
- }
+ os_log(TL_LOG, "secinfo TokenLoginGetLoginData");
+ secinfo("TokenLogin", "secinfo TokenLoginGetLoginData");
+
+ os_log(TL_LOG, "secerror");
+ secerror("secerror");
+
+ os_log(TL_LOG, "secwarning");
+ secwarning("secwarning");
+
+ if (!loginData || !context) {
+ os_log_error(TL_LOG, "Get login data - wrong params");
+ return errSecParam;
+ }
CFRef<CFStringRef> pubKeyHashHex = cfDataToHex(getPubKeyHash(context));
+ os_log(TL_LOG, "pubkeyhash %@", pubKeyHashHex.get());
+
CFPreferencesSynchronize(kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
CFRef<CFDataRef> storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
- if (!storedData) {
- secinfo("TokenLogin", "Failed to read token login plist");
+ os_log(TL_LOG, "stored data %@", storedData.get());
+
+ if (!storedData) {
+ os_log_debug(TL_LOG, "Failed to read token login plist");
+ os_log(TL_LOG, "Failed to read token login plist");
return errSecIO;
}
NULL,
error.take());
if (!*loginData || CFGetTypeID(*loginData) != CFDictionaryGetTypeID()) {
- secinfo("TokenLogin", "Failed to deserialize unlock key data: %@", error.get());
+ os_log_error(TL_LOG, "Failed to deserialize unlock key data: %@", error.get());
return errSecParam;
}
OSStatus TokenLoginUpdateUnlockData(CFDictionaryRef context, CFStringRef password)
{
- if (!context) {
- return errSecParam;
- }
+ if (!context) {
+ os_log_error(TL_LOG, "Updating unlock data - wrong params");
+ return errSecParam;
+ }
CFRef<SecKeychainRef> loginKeychain;
OSStatus result = SecKeychainCopyLogin(loginKeychain.take());
if (result != errSecSuccess) {
- secinfo("TokenLogin", "Failed to get user keychain: %d", (int) result);
+ os_log_error(TL_LOG, "Failed to get user keychain: %d", (int) result);
return result;
}
OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CFDataRef pubKeyHashWrap, CFDataRef unlockKey, CFDataRef scBlob)
{
- if (!tokenId || !pubKeyHash || !pubKeyHashWrap || !unlockKey || !scBlob)
- return errSecParam;
+ if (!tokenId || !pubKeyHash || !pubKeyHashWrap || !unlockKey || !scBlob) {
+ os_log_error(TL_LOG, "Create login data - wrong params");
+ return errSecParam;
+ }
CFRef<CFDictionaryRef> ctx = makeCFDictionary(3,
kSecAttrTokenID, tokenId,
CFRef<SecKeyRef> privKey;
OSStatus result = privKeyForPubKeyHash(ctx, privKey.take(), NULL);
if (result != errSecSuccess) {
- secinfo("TokenLogin", "Failed to get private key for public key hash: %d", (int) result);
+ os_log_error(TL_LOG, "Failed to get private key for public key hash: %d", (int) result);
return result;
}
CFRef<SecKeyRef> pubKey = SecKeyCopyPublicKey(privKey);
if (!pubKey) {
- secinfo("TokenLogin", "Failed to get public key from private key");
+ os_log_error(TL_LOG, "Failed to get public key from private key");
return errSecParam;
}
}
}
if (algorithm == NULL) {
- secinfo("SecKeychain", "Failed to find supported wrap algorithm");
+ os_log_error(TL_LOG, "Failed to find supported wrap algorithm");
return errSecParam;
}
CFRef<CFErrorRef> error;
CFRef<CFDataRef> wrappedUnlockKey = SecKeyCreateEncryptedData(pubKey, algorithm, unlockKey, error.take());
if (!wrappedUnlockKey) {
- secinfo("TokenLogin", "Failed to wrap unlock key: %@", error.get());
+ os_log_error(TL_LOG, "Failed to wrap unlock key: %@", error.get());
return errSecParam;
}
OSStatus TokenLoginStoreUnlockData(CFDictionaryRef context, CFDictionaryRef loginData)
{
+ os_log(TL_LOG, "Storing unlock data");
CFRef<CFErrorRef> error;
CFRef<CFDataRef> data = CFPropertyListCreateData(kCFAllocatorDefault,
0,
error.take());
if (!data) {
- secdebug("TokenLogin", "Failed to create unlock data: %@", error.get());
+ os_log_error(TL_LOG, "Failed to create unlock data: %@", error.get());
return errSecInternal;
}
CFRef<CFStringRef> pubKeyHashHex = cfDataToHex(getPubKeyHash(context));
- CFPreferencesSetValue(pubKeyHashHex, data, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+ os_log(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get());
+
+ CFPreferencesSetValue(pubKeyHashHex, data, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+ os_log(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get());
+
CFPreferencesSynchronize(kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
CFRef<CFDataRef> storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+ os_log(TL_LOG, "Stored data %@", storedData.get());
if (!storedData || !CFEqual(storedData, data)) {
- secinfo("TokenLogin", "Failed to write token login plist");
+ os_log_error(TL_LOG, "Failed to write token login plist");
return errSecIO;
}
+ os_log(TL_LOG, "Original data %@. Everything is OK", data.get());
return errSecSuccess;
}
CFRef<CFDataRef> storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
if (storedData) {
- secinfo("TokenLogin", "Failed to remove unlock data");
+ os_log_error(TL_LOG, "Failed to remove unlock data");
return errSecIO;
}
OSStatus TokenLoginGetScBlob(CFDataRef pubKeyHashWrap, CFStringRef tokenId, CFStringRef password, CFDataRef *scBlob)
{
if (scBlob == NULL || password == NULL || pubKeyHashWrap == NULL || tokenId == NULL) {
- secinfo("TokenLogin", "TokenLoginGetScBlob wrong params");
+ os_log_error(TL_LOG, "TokenLoginGetScBlob wrong params");
return errSecParam;
}
CFRef<SecKeyRef> privKey;
OSStatus retval = privKeyForPubKeyHash(ctx, privKey.take(), NULL);
if (retval != errSecSuccess) {
- secinfo("TokenLogin", "TokenLoginGetScBlob failed to get private key for public key hash: %d", (int) retval);
+ os_log_error(TL_LOG, "TokenLoginGetScBlob failed to get private key for public key hash: %d", (int) retval);
return retval;
}
CFRef<SecKeyRef> pubKey = SecKeyCopyPublicKey(privKey);
if (!pubKey) {
- secinfo("TokenLogin", "TokenLoginGetScBlob no pubkey");
+ os_log_error(TL_LOG, "TokenLoginGetScBlob no pubkey");
return errSecInternal;
}
CFRef<CFDictionaryRef> attributes = SecKeyCopyAttributes(pubKey);
if (!attributes) {
- secinfo("TokenLogin", "TokenLoginGetScBlob no attributes");
+ os_log_error(TL_LOG, "TokenLoginGetScBlob no attributes");
return errSecInternal;
}
else if (CFEqual(type, kSecAttrKeyTypeEC))
mode = AKS_SMARTCARD_MODE_ECDH;
else {
- secinfo("TokenLogin", "TokenLoginGetScBlob bad type");
+ os_log_error(TL_LOG, "TokenLoginGetScBlob bad type");
return errSecNotAvailable;
}
CFRef<CFDataRef> publicBytes = SecKeyCopyExternalRepresentation(pubKey, NULL);
if (!publicBytes) {
- secinfo("TokenLogin", "TokenLoginGetScBlob cannot get public bytes");
+ os_log_error(TL_LOG, "TokenLoginGetScBlob cannot get public bytes");
return retval;
}
CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(password), kCFStringEncodingUTF8) + 1;
char* buf = (char*)malloc(maxLength);
if (buf == NULL) {
- secinfo("TokenLogin", "TokenLoginGetScBlob no mem for buffer");
+ os_log_error(TL_LOG, "TokenLoginGetScBlob no mem for buffer");
return retval;
}
if (CFStringGetCString(password, buf, maxLength, kCFStringEncodingUTF8) == FALSE) {
- secinfo("TokenLogin", "TokenLoginGetScBlob no pwd cstr");
+ os_log_error(TL_LOG, "TokenLoginGetScBlob no pwd cstr");
free(buf);
return retval;
}
aks_smartcard_unregister(session_keybag_handle); // just to be sure no previous registration exist
kern_return_t aks_retval = aks_smartcard_register(session_keybag_handle, (uint8_t *)buf, strlen(buf), mode, (uint8_t *)CFDataGetBytePtr(publicBytes), (size_t)CFDataGetLength(publicBytes), &sc_blob, &sc_len);
free(buf);
- secinfo("TokenLogin", "TokenLoginGetScBlob register result %d", aks_retval);
+ os_log_debug(TL_LOG, "TokenLoginGetScBlob register result %d", aks_retval);
if (sc_blob) {
*scBlob = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)sc_blob, (CFIndex)sc_len);
CFDataRef scBlob = (CFDataRef)CFDictionaryGetValue(loginData, kSecClassKey);
if (scBlob == NULL) {
- secinfo("TokenLogin", "Failed to get scblob");
+ os_log_error(TL_LOG, "Failed to get scblob");
return errSecInternal;
}
CFRef<CFTypeRef> LAContext;
OSStatus retval = privKeyForPubKeyHash(context, privKey.take(), LAContext.take());
if (retval != errSecSuccess) {
- secinfo("TokenLogin", "Failed to get private key for public key hash: %d", (int) retval);
+ os_log_error(TL_LOG, "Failed to get private key for public key hash: %d", (int) retval);
return retval;
}
CFRef<SecKeyRef> pubKey = SecKeyCopyPublicKey(privKey);
if (!pubKey) {
- secinfo("TokenLogin", "Failed to get pubkey");
+ os_log_error(TL_LOG, "Failed to get pubkey");
return retval;
}
CFRef<CFDictionaryRef> attributes = SecKeyCopyAttributes(pubKey);
if (!attributes) {
- secinfo("TokenLogin", "TokenLoginUnlockKeybag no attributes");
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag no attributes");
return errSecInternal;
}
else if (CFEqual(type, kSecAttrKeyTypeEC))
mode = AKS_SMARTCARD_MODE_ECDH;
else {
- secinfo("TokenLogin", "TokenLoginUnlockKeybag bad type");
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag bad type");
return errSecNotAvailable;
}
size_t scChallengeLen = 0;
int res = aks_smartcard_request_unlock(session_keybag_handle, (uint8_t *)CFDataGetBytePtr(scBlob), (size_t)CFDataGetLength(scBlob), &scChallenge, &scChallengeLen);
if (res != 0) {
- secinfo("TokenLogin", "TokenLoginUnlockKeybag cannot request unlock: %x", res);
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag cannot request unlock: %x", res);
return errSecInternal;
}
const void *scUsk = NULL;
if (res != 0 || scUsk == NULL) {
free(scChallenge);
- secinfo("TokenLogin", "TokenLoginUnlockKeybag cannot get usk: %x", res);
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag cannot get usk: %x", res);
return errSecInternal;
}
res = aks_smartcard_get_ec_pub(scChallenge, scChallengeLen, &ecPub, &ecPubLen);
if (res != 0 || ecPub == NULL) {
free(scChallenge);
- secinfo("TokenLogin", "TokenLoginUnlockKeybag cannot get ecpub: %x", res);
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag cannot get ecpub: %x", res);
return errSecInternal;
}
wrappedUsk = CFDataCreateMutable(kCFAllocatorDefault, ecPubLen + scUskLen);
if (!wrappedUsk) {
free(scChallenge);
- secinfo("TokenLogin", "TokenLoginUnlockKeybag no mem for ecpubusk");
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag no mem for ecpubusk");
return errSecInternal;
}
CFDataAppendBytes((CFMutableDataRef)wrappedUsk.get(), (const UInt8 *)ecPub, (CFIndex)ecPubLen);
(CFDataRef)wrappedUsk.get(),
error.take());
if (!unwrappedUsk) {
- secinfo("TokenLogin", "TokenLoginUnlockKeybag failed to unwrap blob: %@", error.get());
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag failed to unwrap blob: %@", error.get());
return errSecInternal;
}
CFDictionarySetValue(newDict, kSecClassKey, newBlobData.get());
TokenLoginStoreUnlockData(context, newDict);
}
- }
+ } else {
+ os_log_error(TL_LOG, "TokenLoginUnlockKeybag no new scblob received: %d", res);
+ }
return res;
}
{
if (GetServerMode()) // in server mode? Don't go through StorageManager to make a keychain
{
- mRootStoreDL = new DL(gGuidAppleFileDL),
- mRootStoreDb = new Db(*mRootStoreDL, SYSTEM_ROOT_STORE_PATH),
+ mRootStoreDL = new DL(gGuidAppleFileDL);
+ mRootStoreDb = new Db(*mRootStoreDL, SYSTEM_ROOT_STORE_PATH);
mRootStore = new Keychain(*mRootStoreDb);
}
else
SecKeyRef keyRef = NULL;
SecCertificateRef resultCert = NULL;
// note: Sec* APIs are not re-entrant due to the API lock
- // status = SecCertificateCopyPublicKey(certificate, &keyRef);
BEGIN_SECAPI_INTERNAL_CALL
keyRef = Certificate::required(certificate)->publicKey()->handle();
END_SECAPI_INTERNAL_CALL
}
}
-const CFStringRef gPrefix = CFSTR("Test Key");
-const CFStringRef gLabel = CFSTR("Test AES Encryption Key");
-const CFStringRef gUUID = CFSTR("550e8400-e29b-41d4-a716-446655441234");
+const CFStringRef g15Prefix = CFSTR("Test Key");
+const CFStringRef g15Label = CFSTR("Test AES Encryption Key");
+const CFStringRef g15UUID = CFSTR("550e8400-e29b-41d4-a716-446655441234");
// CreateSymmetricKey will create a new AES-128 symmetric encryption key
// with the provided label, application label, and application tag.
// note: the access descriptor should be the same string as will be used for the item's label,
// since it's the string that is displayed by the access confirmation dialog to describe the item.
SecAccessRef access = NULL;
- status = SecAccessCreate(gLabel, NULL, &access);
+ status = SecAccessCreate(g15Label, NULL, &access);
// create a dictionary of parameters describing the key we want to create
CFMutableDictionaryRef params = CFDictionaryCreateMutable(NULL, 0,
// first, create a symmetric key
CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL);
CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"),
- gPrefix, (int) (curGDate.year), (int) (curGDate.month), (int) (curGDate.day));
+ g15Prefix, (int) (curGDate.year), (int) (curGDate.month), (int) (curGDate.day));
CFStringRef curAppTag = CFSTR("SecItemUpdate");
- status = CreateSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, noErr);
+ status = CreateSymmetricKey(keychain, curDateLabel, g15UUID, curAppTag, noErr);
CFReleaseNull(curDateLabel);
if (status && status != errSecDuplicateItem)
++result;
-const CFStringRef gPrefix = CFSTR("Test Key");
-const CFStringRef gLabel = CFSTR("Test AES Encryption Key");
-const CFStringRef gUUID = CFSTR("550e8400-e29b-41d4-a716-446655441234");
+const CFStringRef g18Prefix = CFSTR("Test Key");
+const CFStringRef g18Label = CFSTR("Test AES Encryption Key");
+const CFStringRef g18UUID = CFSTR("550e8400-e29b-41d4-a716-446655441234");
// CreateSymmetricKey will create a new AES-128 symmetric encryption key
// with the provided label, application label, and application tag.
// note: the access descriptor should be the same string as will be used for the item's label,
// since it's the string that is displayed by the access confirmation dialog to describe the item.
SecAccessRef access = NULL;
- status = SecAccessCreate(gLabel, NULL, &access);
+ status = SecAccessCreate(g18Label, NULL, &access);
// create a dictionary of parameters describing the key we want to create
CFMutableDictionaryRef params = CFDictionaryCreateMutable(NULL, 0,
int result = 0;
// look up our symmetric key by label and UUID (it might not exist yet)
- if (FindSymmetricKey(keychain, gLabel, gUUID, NULL, errSecItemNotFound) != errSecSuccess) {
+ if (FindSymmetricKey(keychain, g18Label, g18UUID, NULL, errSecItemNotFound) != errSecSuccess) {
// create test key (unique by UUID only)
- if (CreateSymmetricKey(keychain, gLabel, gUUID, NULL, errSecSuccess) != errSecSuccess)
+ if (CreateSymmetricKey(keychain, g18Label, g18UUID, NULL, errSecSuccess) != errSecSuccess)
++result;
// look it up again (it should exist now!)
- if (FindSymmetricKey(keychain, gLabel, gUUID, NULL, errSecSuccess) != errSecSuccess)
+ if (FindSymmetricKey(keychain, g18Label, g18UUID, NULL, errSecSuccess) != errSecSuccess)
++result;
}
// (so we can make sure on a daily basis that SecKeyGenerateSymmetric is still working)
CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL);
CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"),
- gPrefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day);
+ g18Prefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day);
//
//%%% FIXME Creating a symmetric key with attributes that would duplicate an existing
CFStringRef curAppTag = CFSTR("SecItemFind");
// look up our date-based symmetric key by label, UUID, and tag (it might not exist yet)
- if (FindSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecItemNotFound) != errSecSuccess) {
+ if (FindSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecItemNotFound) != errSecSuccess) {
// create test key (unique by combination of UUID and application tag)
- if (CreateSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecSuccess) != errSecSuccess)
+ if (CreateSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecSuccess) != errSecSuccess)
++result;
// look it up again (it should exist now!)
- if (FindSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecSuccess) != errSecSuccess)
+ if (FindSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecSuccess) != errSecSuccess)
++result;
}
// test handling of duplicate symmetric key items (<rdar://8289559>)
- if (CreateSymmetricKey(keychain, curDateLabel, gUUID, curAppTag, errSecDuplicateItem) != errSecDuplicateItem)
+ if (CreateSymmetricKey(keychain, curDateLabel, g18UUID, curAppTag, errSecDuplicateItem) != errSecDuplicateItem)
++result;
CFRelease(curDateLabel);
++result;
// delete our test symmetric keys (no partial string matching for key items! need an ER Radar...)
- if (FindAndDeleteItemsByName(keychain, gLabel, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr))
+ if (FindAndDeleteItemsByName(keychain, g18Label, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr))
++result;
CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL);
CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"),
- gPrefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day);
+ g18Prefix, (int32_t) curGDate.year, (int8_t) curGDate.month, (int8_t) curGDate.day);
if (FindAndDeleteItemsByName(keychain, curDateLabel, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr))
++result;
CFRelease(curDateLabel);
CFMutableDictionaryRef query = createQueryCustomItemDictionaryWithService(kc, kSecClassInternetPassword, CFSTR("test_service"), CFSTR("test_service"));
CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
- ok_status(SecItemCopyMatching(query, (CFTypeRef*) &blockItem), "%s: SecItemCopyMatching (%d)", testName, iteration);
+ ok_status(SecItemCopyMatching(query, (CFTypeRef*) &blockItem), "%s: SecItemCopyMatching", testName);
CFReleaseNull(query);
CFReleaseNull(blockItem);
// Turn off deprecated API warnings
//#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+unsigned char test_import_p12[] = {
+ 0x30, 0x82, 0x09, 0xbf, 0x02, 0x01, 0x03, 0x30, 0x82, 0x09, 0x86, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x07, 0x01, 0xa0, 0x82, 0x09, 0x77, 0x04, 0x82, 0x09, 0x73, 0x30, 0x82, 0x09, 0x6f, 0x30, 0x82, 0x03, 0xff, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x03, 0xec, 0x02, 0x01, 0x00,
+ 0x30, 0x82, 0x03, 0xe5, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xcb, 0xa2, 0x8c, 0x60, 0xc2, 0x36, 0x55,
+ 0x05, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03, 0xb8, 0x57, 0x1d, 0x4c, 0x1f, 0xc7, 0x4c, 0x00, 0x82, 0xa3, 0xc9, 0x6f,
+ 0x2e, 0x00, 0x03, 0x1b, 0x55, 0xaa, 0xe5, 0x89, 0x58, 0x18, 0x71, 0xb8, 0xff, 0x40, 0x13, 0xd5, 0xac, 0x7f, 0xf1, 0x48,
+ 0xb2, 0x7e, 0x6e, 0xeb, 0x6e, 0xde, 0xe8, 0x35, 0x22, 0xa5, 0x45, 0x5a, 0xa6, 0x2e, 0xed, 0x0d, 0xe0, 0x8f, 0x2f, 0x60,
+ 0x5c, 0xd8, 0x49, 0x89, 0x26, 0x42, 0xd6, 0xe0, 0x24, 0x1c, 0x59, 0x9c, 0xe0, 0xbf, 0x98, 0x0c, 0xc3, 0x81, 0x20, 0x47,
+ 0x03, 0x03, 0xe2, 0x73, 0x90, 0x13, 0x6e, 0x96, 0x31, 0x68, 0xb7, 0x8f, 0xaa, 0x25, 0x4b, 0x27, 0x95, 0x3f, 0xef, 0xa3,
+ 0x2b, 0x96, 0x10, 0x85, 0xf3, 0x49, 0x3c, 0x6f, 0x9a, 0x20, 0x02, 0x17, 0x42, 0xe9, 0x9c, 0x5e, 0x5d, 0x4b, 0x3c, 0x88,
+ 0x65, 0xf5, 0x67, 0x61, 0x3e, 0xa6, 0x1a, 0x0f, 0x5b, 0x1e, 0x35, 0x18, 0x4e, 0xf3, 0x98, 0x93, 0x7e, 0x76, 0x77, 0x31,
+ 0x3b, 0x00, 0x78, 0x8c, 0x50, 0x28, 0x76, 0xca, 0xc8, 0x39, 0xc5, 0xf5, 0x79, 0x23, 0x4a, 0xea, 0x9a, 0xf0, 0xb5, 0xb6,
+ 0x50, 0x8d, 0x16, 0xd9, 0x39, 0x74, 0x36, 0x1d, 0x26, 0xcb, 0xbf, 0xb7, 0x72, 0x5e, 0x77, 0xf5, 0xb8, 0x35, 0xfc, 0x66,
+ 0x4d, 0xdc, 0xd6, 0x20, 0x50, 0x70, 0xc6, 0xf7, 0x13, 0x55, 0xb1, 0x97, 0x7e, 0x1d, 0x6a, 0x7d, 0x73, 0xc2, 0x71, 0x49,
+ 0xd1, 0x15, 0xe7, 0x30, 0xa7, 0x52, 0x1f, 0x24, 0xe8, 0x7b, 0xd7, 0x81, 0x53, 0x27, 0x94, 0xd0, 0x31, 0xe5, 0x11, 0xe4,
+ 0x90, 0x8a, 0x02, 0x46, 0x70, 0x82, 0xe7, 0xc4, 0xfe, 0xb5, 0xed, 0xb0, 0x1b, 0xcb, 0xa2, 0x23, 0x5c, 0xd2, 0x95, 0xe6,
+ 0x2c, 0x5f, 0x2d, 0x07, 0xb1, 0xd8, 0xe8, 0xa0, 0x39, 0xe7, 0xdd, 0x2e, 0x36, 0xac, 0x38, 0xfc, 0x65, 0x99, 0x2c, 0xda,
+ 0x3d, 0x26, 0x5d, 0x1e, 0x2f, 0xbc, 0x31, 0x36, 0x3e, 0x87, 0x55, 0x5f, 0x40, 0xf1, 0x77, 0x7a, 0x15, 0xa2, 0xc3, 0xe4,
+ 0x21, 0xc0, 0xe1, 0x11, 0x15, 0x31, 0xf4, 0x7a, 0x51, 0xc3, 0x78, 0x70, 0xfc, 0x3b, 0xed, 0x04, 0x7f, 0x5c, 0xaf, 0x22,
+ 0x37, 0x1c, 0x80, 0xb6, 0x7b, 0xdf, 0x11, 0x90, 0x52, 0xc1, 0x0d, 0xfb, 0xaa, 0xd0, 0x43, 0x47, 0xe9, 0xdb, 0x31, 0xb7,
+ 0xfc, 0x35, 0xbf, 0xce, 0x00, 0x15, 0x0d, 0x51, 0xb1, 0x78, 0x99, 0x55, 0x91, 0x1f, 0xf1, 0x4c, 0x36, 0xfa, 0xc1, 0xa0,
+ 0xce, 0x86, 0xc9, 0x79, 0x60, 0x07, 0x58, 0xa7, 0xe5, 0x28, 0x28, 0x84, 0x92, 0x03, 0x2c, 0x43, 0xda, 0x69, 0xce, 0x75,
+ 0x25, 0x01, 0x51, 0x37, 0xd4, 0xfd, 0xa2, 0xc4, 0x09, 0xfb, 0xa0, 0xf5, 0x1f, 0x23, 0x7b, 0xd6, 0x63, 0xd1, 0xb5, 0x5b,
+ 0xc5, 0xd9, 0xbc, 0xe7, 0xd4, 0x5e, 0x8b, 0x62, 0xee, 0xdb, 0xb7, 0x1e, 0xd2, 0x8b, 0x6e, 0xe4, 0x8c, 0xfd, 0x11, 0x25,
+ 0xda, 0xac, 0x2a, 0x7a, 0x9a, 0xad, 0x6c, 0x29, 0xe1, 0x1c, 0x68, 0x4f, 0xb3, 0x99, 0x06, 0xb4, 0x72, 0x2a, 0x5a, 0x70,
+ 0xd6, 0xf6, 0x7c, 0x22, 0x0f, 0x85, 0xf1, 0xc4, 0x30, 0x9f, 0x32, 0x53, 0xa1, 0xb2, 0x1a, 0x41, 0x01, 0xa2, 0x92, 0x58,
+ 0xa2, 0x27, 0xe8, 0x09, 0xed, 0x75, 0x84, 0x41, 0xcd, 0x19, 0x46, 0x47, 0x86, 0x7d, 0xa0, 0x49, 0xc4, 0x72, 0x94, 0x9f,
+ 0x43, 0xf2, 0x09, 0x3a, 0x59, 0x56, 0x7c, 0x3b, 0x34, 0x79, 0x1b, 0x58, 0x82, 0xc7, 0x64, 0x19, 0x7c, 0x32, 0x7b, 0x42,
+ 0x66, 0x9f, 0x32, 0xef, 0x48, 0xb4, 0xf7, 0xd0, 0x74, 0x1f, 0x1c, 0xbe, 0xd4, 0x7a, 0x2a, 0x02, 0xb2, 0x3d, 0x47, 0x15,
+ 0x40, 0xa8, 0xd5, 0x57, 0xc8, 0xe7, 0x7d, 0x8d, 0xa6, 0xea, 0xe5, 0x21, 0x6a, 0xbe, 0x39, 0x8c, 0xfd, 0x78, 0x26, 0xaf,
+ 0x31, 0x93, 0x0f, 0x94, 0x07, 0x87, 0x6c, 0xa8, 0x56, 0xd8, 0xc6, 0x79, 0xcf, 0x1d, 0x36, 0xee, 0xab, 0x33, 0x5b, 0x63,
+ 0xe8, 0x34, 0x00, 0x0c, 0x95, 0x48, 0x34, 0xac, 0xe2, 0xda, 0x61, 0x7a, 0x97, 0x3e, 0x41, 0xe4, 0xb7, 0x30, 0xb0, 0xb3,
+ 0x96, 0xed, 0x91, 0xb8, 0x5b, 0x20, 0x30, 0xfa, 0xf0, 0xfa, 0xc7, 0xc2, 0x97, 0x14, 0x9b, 0x81, 0xa9, 0x70, 0x8a, 0x10,
+ 0xf1, 0x75, 0xe4, 0xec, 0x54, 0x3e, 0xd9, 0xa8, 0x94, 0xcd, 0x3a, 0x82, 0xf7, 0xe3, 0xb8, 0x75, 0xd7, 0x49, 0x6c, 0x80,
+ 0x97, 0xd8, 0xdf, 0x56, 0x66, 0x93, 0xe6, 0xef, 0xa3, 0xc3, 0xd6, 0x34, 0xb7, 0x6f, 0x9b, 0x51, 0xaa, 0x7c, 0x1e, 0x16,
+ 0x8f, 0x21, 0x8a, 0x0a, 0x9f, 0x0e, 0xbe, 0x6b, 0x96, 0x8b, 0x95, 0x95, 0x5d, 0x11, 0x39, 0x15, 0x8c, 0xca, 0x9d, 0xec,
+ 0x26, 0x39, 0x49, 0x1e, 0xf6, 0x16, 0x09, 0x36, 0x95, 0xae, 0xa0, 0x55, 0xbf, 0x94, 0xf2, 0x6f, 0x1b, 0x74, 0x93, 0x97,
+ 0x6d, 0xd8, 0x00, 0x0c, 0xf0, 0x9e, 0x24, 0xb9, 0xfe, 0x04, 0xfa, 0x30, 0x63, 0x90, 0x28, 0xcb, 0x0d, 0x8e, 0xe8, 0xf0,
+ 0x7f, 0x9a, 0x69, 0x54, 0xf2, 0xbc, 0x9f, 0x24, 0x0b, 0xd1, 0xda, 0x2f, 0x22, 0x81, 0x22, 0x31, 0x03, 0xc2, 0x60, 0x41,
+ 0x2e, 0xe0, 0xc6, 0x52, 0x7b, 0x5a, 0x35, 0xbc, 0x00, 0xfd, 0x71, 0x00, 0x19, 0xd3, 0xa4, 0xa8, 0x5b, 0xbc, 0xfc, 0xae,
+ 0x24, 0x10, 0xb4, 0x21, 0x8c, 0x3c, 0x15, 0xad, 0x2d, 0x1e, 0x33, 0x09, 0x58, 0x93, 0xb4, 0x29, 0x3a, 0xbc, 0x6f, 0x7d,
+ 0x51, 0x3b, 0x5b, 0x97, 0xfe, 0x67, 0xe1, 0x9e, 0xff, 0x6b, 0xdc, 0xf2, 0xb0, 0x6f, 0xa1, 0x4e, 0x4b, 0xf2, 0xdf, 0xd6,
+ 0xa4, 0xec, 0x8d, 0x19, 0x6d, 0x30, 0x67, 0xde, 0x04, 0x5e, 0xaf, 0xd7, 0xd4, 0x42, 0xf8, 0xbc, 0xca, 0xfc, 0x49, 0xc0,
+ 0xe7, 0xcd, 0xfc, 0xab, 0xca, 0x3f, 0x67, 0xff, 0xfb, 0x41, 0xc0, 0xe4, 0xe8, 0x0c, 0xe8, 0x2e, 0xca, 0x43, 0xfb, 0xec,
+ 0xe0, 0xeb, 0xea, 0x30, 0x14, 0xca, 0x30, 0x8d, 0x49, 0xaa, 0x99, 0x71, 0xcb, 0x85, 0xa4, 0x68, 0xda, 0xd1, 0xbe, 0xa9,
+ 0xc6, 0xee, 0x26, 0xdf, 0x3f, 0xde, 0x39, 0x29, 0x6c, 0x45, 0x9e, 0x41, 0x88, 0x63, 0xd8, 0x31, 0x47, 0x8e, 0xdc, 0xc8,
+ 0xe4, 0x28, 0x25, 0x75, 0x11, 0x99, 0xdd, 0x28, 0x25, 0xa7, 0x5e, 0xac, 0x7f, 0x0c, 0xb5, 0x2b, 0x62, 0x9d, 0xe0, 0xda,
+ 0xe3, 0xc2, 0xd8, 0x8d, 0xc6, 0x25, 0x5f, 0x08, 0x6e, 0xfc, 0xcd, 0xae, 0x4c, 0x99, 0x41, 0xc4, 0x75, 0x3e, 0x5e, 0x51,
+ 0xa1, 0x76, 0x47, 0x93, 0x4a, 0x83, 0x51, 0x91, 0xf3, 0x92, 0xd0, 0x29, 0xa6, 0x44, 0x3c, 0x2a, 0x91, 0x3f, 0x01, 0x75,
+ 0xeb, 0x6f, 0xf3, 0x3c, 0x04, 0xd3, 0x74, 0x7a, 0xfc, 0x7a, 0x39, 0x70, 0xc8, 0x3a, 0x89, 0x93, 0xbd, 0xfd, 0xd7, 0x41,
+ 0x2c, 0xb0, 0xd3, 0xef, 0xd0, 0xd5, 0x75, 0x24, 0xb1, 0x0e, 0x3d, 0x89, 0x8e, 0xde, 0xa7, 0x40, 0x80, 0xd2, 0x05, 0xe5,
+ 0x18, 0xa2, 0xf3, 0x30, 0x22, 0x56, 0x0b, 0xbc, 0x05, 0xb0, 0x48, 0x9a, 0x42, 0xb7, 0xe1, 0x32, 0xba, 0x52, 0x99, 0x22,
+ 0xf6, 0x30, 0x82, 0x05, 0x68, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x59,
+ 0x04, 0x82, 0x05, 0x55, 0x30, 0x82, 0x05, 0x51, 0x30, 0x82, 0x05, 0x4d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x8e, 0x7e, 0x90, 0x94, 0xaf, 0x09, 0xc5, 0xbc, 0x02,
+ 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0x0c, 0x7c, 0x7f, 0x58, 0x8b, 0x41, 0x9a, 0xb8, 0x70, 0xbf, 0x6c, 0x4c, 0xb8,
+ 0x7d, 0x72, 0xa5, 0x50, 0xe6, 0xc4, 0xaf, 0x74, 0x0e, 0x88, 0xbf, 0x83, 0x51, 0xbc, 0xe1, 0x66, 0x8a, 0x9f, 0x42, 0x11,
+ 0x2b, 0x3d, 0x8c, 0x10, 0xa3, 0xc2, 0xdf, 0xb9, 0x36, 0x74, 0xc1, 0x18, 0x23, 0x1e, 0x9a, 0xbf, 0x8d, 0x0a, 0x4b, 0x63,
+ 0xd5, 0x20, 0x1b, 0xae, 0xb0, 0x64, 0xfc, 0xe1, 0x5c, 0xe7, 0xde, 0xa3, 0x6f, 0x8e, 0xe3, 0xc9, 0x8d, 0x18, 0x63, 0x7f,
+ 0x26, 0x4a, 0x3d, 0x41, 0x76, 0xa6, 0xaa, 0x3f, 0x27, 0x75, 0xec, 0x2f, 0x78, 0xd2, 0x40, 0x28, 0xe7, 0xf5, 0xee, 0x61,
+ 0x6d, 0x49, 0xe0, 0x64, 0x33, 0xc9, 0x9e, 0xf6, 0xda, 0x86, 0x3a, 0xad, 0x47, 0x13, 0xe2, 0x8a, 0x0b, 0x98, 0xe7, 0x73,
+ 0xea, 0x08, 0x59, 0xfe, 0x74, 0x6f, 0x10, 0x7d, 0xbc, 0x0b, 0xb9, 0xcf, 0xe7, 0xe7, 0x28, 0xe8, 0xfe, 0x20, 0x8a, 0x98,
+ 0x40, 0x00, 0x52, 0xa0, 0x0c, 0x5c, 0xfa, 0x48, 0x5b, 0xf4, 0x3c, 0x76, 0x5d, 0xf4, 0x33, 0x53, 0xd4, 0x51, 0x43, 0x47,
+ 0x29, 0xda, 0xff, 0xbd, 0xfe, 0x71, 0x5b, 0x50, 0xa1, 0xa5, 0x25, 0xe9, 0xcc, 0x68, 0x74, 0x9f, 0x7f, 0x39, 0x65, 0x5e,
+ 0xb9, 0x71, 0x8f, 0x25, 0x68, 0xe6, 0x71, 0x06, 0x10, 0xa2, 0xfb, 0x08, 0x54, 0x21, 0xca, 0x28, 0xfc, 0xf1, 0x89, 0xb9,
+ 0x29, 0x11, 0x67, 0x00, 0x19, 0xdd, 0x00, 0xd8, 0x48, 0x89, 0x46, 0x0d, 0x39, 0x0c, 0x7e, 0x94, 0x02, 0x80, 0x37, 0xa0,
+ 0x01, 0x45, 0x25, 0xbd, 0x8b, 0x44, 0xcc, 0xdf, 0x43, 0xa1, 0x1d, 0xf5, 0x59, 0x4b, 0x07, 0xe6, 0xab, 0x15, 0x93, 0x3d,
+ 0xea, 0x7d, 0xd6, 0xaa, 0xb0, 0x97, 0xed, 0x1d, 0x5e, 0xc2, 0xf0, 0xea, 0x1b, 0xc2, 0xcc, 0x88, 0x47, 0x3e, 0xe4, 0x54,
+ 0xc3, 0x02, 0xac, 0x5e, 0x88, 0xb9, 0x2f, 0x82, 0xd4, 0xd0, 0x5d, 0xb2, 0x2a, 0xee, 0x94, 0x3d, 0xdb, 0x82, 0x93, 0xc6,
+ 0x69, 0x5f, 0x40, 0x83, 0xf0, 0x07, 0x8d, 0x9f, 0x7f, 0x29, 0x3f, 0x4d, 0x3b, 0x08, 0xd9, 0x29, 0xf5, 0x1c, 0x0f, 0x18,
+ 0x42, 0x4b, 0xd9, 0x01, 0xda, 0x71, 0x92, 0xa8, 0x32, 0xa7, 0x53, 0x6f, 0xd0, 0x74, 0x4a, 0xee, 0x39, 0x04, 0xf1, 0x2d,
+ 0xee, 0x50, 0xbe, 0x48, 0xb1, 0x90, 0x21, 0x24, 0x28, 0x40, 0xa9, 0x85, 0xe1, 0x81, 0x77, 0x37, 0xa8, 0x86, 0x15, 0x7d,
+ 0x16, 0xb2, 0xe7, 0xcc, 0xe0, 0xa2, 0x7e, 0x58, 0xb3, 0xdc, 0xf9, 0x41, 0xae, 0x36, 0xba, 0x55, 0x87, 0x64, 0x01, 0xfd,
+ 0xc9, 0x0e, 0xa1, 0xfe, 0x55, 0xc3, 0x2a, 0x66, 0xd5, 0x83, 0x39, 0x7e, 0x5a, 0xe8, 0x28, 0x76, 0x36, 0xbb, 0x39, 0xa9,
+ 0xb7, 0xc6, 0xcf, 0x99, 0x56, 0xe5, 0xbf, 0x4d, 0xb2, 0xa0, 0xac, 0x64, 0x00, 0xc9, 0x42, 0x79, 0x47, 0x46, 0xd7, 0x9c,
+ 0x4a, 0x33, 0x03, 0x55, 0x07, 0x7f, 0x05, 0x23, 0xe3, 0x51, 0x35, 0xa9, 0x32, 0xe9, 0xa6, 0xf2, 0xe2, 0x42, 0x4d, 0x00,
+ 0xbb, 0xdb, 0xc3, 0x85, 0x05, 0xcb, 0xe4, 0xb1, 0x0a, 0x03, 0xf4, 0xe5, 0x27, 0x28, 0x12, 0xec, 0x1e, 0xd4, 0xd7, 0x43,
+ 0xe3, 0x05, 0xc7, 0x92, 0xd2, 0x8e, 0xf7, 0xae, 0x55, 0x1a, 0x50, 0x88, 0x2f, 0x91, 0x05, 0x65, 0x4b, 0xe3, 0xba, 0xc0,
+ 0x42, 0x86, 0x19, 0x2b, 0x64, 0xfc, 0x46, 0x31, 0x9b, 0xd2, 0x88, 0x32, 0xf8, 0x4d, 0x91, 0xd4, 0xc6, 0x77, 0xcb, 0x29,
+ 0x00, 0x5e, 0xd2, 0x48, 0x99, 0x0e, 0x3f, 0x2d, 0x4f, 0xdb, 0x9b, 0x05, 0xea, 0xa1, 0x3d, 0x9f, 0x21, 0x83, 0x6f, 0xcf,
+ 0xe9, 0x1c, 0x65, 0x40, 0x3c, 0x8b, 0x2a, 0x38, 0x8f, 0x1b, 0x5a, 0x3c, 0x73, 0x7a, 0xfc, 0x81, 0x69, 0xb3, 0xff, 0xb6,
+ 0x25, 0x12, 0x3f, 0xda, 0x50, 0xe7, 0xde, 0xfe, 0xd3, 0x31, 0x2f, 0xb4, 0x99, 0x87, 0xae, 0x17, 0xaf, 0xe4, 0xb8, 0x35,
+ 0xf7, 0x3c, 0xc0, 0x99, 0x0e, 0x75, 0x72, 0xb6, 0x46, 0xa1, 0x55, 0xef, 0xff, 0x48, 0x3b, 0x5c, 0x85, 0xf7, 0xc3, 0x03,
+ 0x0a, 0x49, 0x0f, 0x11, 0x48, 0x13, 0x8b, 0x90, 0x73, 0x33, 0xb6, 0x22, 0x35, 0x45, 0x07, 0x80, 0x1a, 0xf9, 0x91, 0x80,
+ 0x9d, 0x8b, 0xc7, 0x8e, 0xcc, 0x3a, 0x52, 0x93, 0x8f, 0xf6, 0x59, 0x3c, 0x69, 0xf7, 0x52, 0x9a, 0x8d, 0x8e, 0xfe, 0x8a,
+ 0x41, 0xb0, 0x43, 0x74, 0x04, 0xe8, 0x0e, 0xf5, 0xc1, 0x4c, 0xa3, 0x8d, 0xe3, 0x98, 0x25, 0xf6, 0xd5, 0x0d, 0xa9, 0x2d,
+ 0xb7, 0x6f, 0x52, 0x22, 0x43, 0x59, 0x30, 0x6d, 0x54, 0xb6, 0xad, 0x73, 0xa1, 0xe8, 0xee, 0x10, 0xbd, 0x55, 0xa4, 0x7f,
+ 0xc3, 0x1d, 0xad, 0x8e, 0x72, 0xf1, 0x26, 0x6d, 0xa1, 0xaf, 0xda, 0x82, 0x37, 0xa1, 0x6d, 0xfe, 0x78, 0xd1, 0x88, 0x65,
+ 0x6a, 0xb2, 0x33, 0x23, 0xcd, 0xba, 0xbe, 0x09, 0x66, 0x61, 0x33, 0xdc, 0x69, 0xed, 0x4f, 0xe6, 0xfb, 0x2f, 0x7d, 0xd0,
+ 0xfd, 0x7a, 0x21, 0x69, 0x2d, 0x1f, 0xd4, 0xc4, 0x93, 0x7c, 0x34, 0x7d, 0x67, 0x2c, 0xe9, 0x2a, 0x9a, 0x53, 0xc2, 0xbf,
+ 0xf9, 0x06, 0x10, 0xa6, 0xa8, 0x60, 0xe3, 0x01, 0xcb, 0x2b, 0x03, 0xdb, 0xb7, 0x27, 0xe9, 0x86, 0xe8, 0x7d, 0x75, 0xce,
+ 0x80, 0xdb, 0xaf, 0xe9, 0x7e, 0x75, 0xad, 0xe3, 0xd4, 0xc4, 0xf3, 0x10, 0x89, 0x16, 0xcb, 0xc6, 0x23, 0x5a, 0x58, 0x66,
+ 0xb6, 0x2a, 0xd7, 0xc9, 0x69, 0xd3, 0x7f, 0xa2, 0x9a, 0x5c, 0x1c, 0xd4, 0xf8, 0xe3, 0xe0, 0x63, 0x01, 0x88, 0x14, 0xb3,
+ 0x20, 0xe3, 0x22, 0x45, 0x3d, 0xae, 0xaf, 0x0b, 0x55, 0xa1, 0x65, 0xec, 0x16, 0x0b, 0x35, 0x37, 0x6f, 0x12, 0x5f, 0x29,
+ 0x47, 0xee, 0xdd, 0xbb, 0xcf, 0x9f, 0x87, 0xaf, 0x7d, 0xaa, 0xf4, 0x01, 0x45, 0xea, 0x5f, 0x00, 0x87, 0x1e, 0xeb, 0x2f,
+ 0x77, 0x2b, 0x92, 0x42, 0x04, 0x45, 0x33, 0xf2, 0xfb, 0x6b, 0xac, 0xca, 0x98, 0x79, 0x56, 0x6f, 0xe7, 0x5b, 0xbd, 0x63,
+ 0xc7, 0x3a, 0x8c, 0xfd, 0x93, 0xb1, 0x13, 0x4e, 0xc2, 0x05, 0x7f, 0xde, 0x44, 0xa8, 0xb7, 0xc4, 0x9c, 0xba, 0x57, 0x58,
+ 0x3b, 0xba, 0xb5, 0x74, 0x73, 0x97, 0x20, 0x53, 0x70, 0x70, 0x65, 0xf1, 0x81, 0xea, 0x07, 0xc2, 0xbe, 0x57, 0x71, 0x62,
+ 0x3b, 0xc0, 0x3c, 0x07, 0x65, 0xf4, 0x22, 0xfb, 0xd3, 0xf9, 0x2d, 0xb3, 0x20, 0xdd, 0x66, 0x51, 0x89, 0x54, 0x57, 0xcd,
+ 0xd7, 0xc7, 0x1a, 0xd9, 0xfe, 0xe0, 0x13, 0x9d, 0x7d, 0xe7, 0xe3, 0x2f, 0x65, 0x3e, 0xf0, 0xb2, 0xd9, 0x0c, 0x1a, 0xa9,
+ 0xaa, 0xba, 0x3b, 0x79, 0x86, 0xed, 0x6c, 0xbf, 0x9e, 0x9b, 0xb5, 0x78, 0xd8, 0x9e, 0x2f, 0x95, 0xcc, 0x31, 0xb4, 0x5f,
+ 0xd3, 0x63, 0xff, 0xb9, 0x62, 0x34, 0xfd, 0x78, 0x1f, 0xac, 0xe7, 0xbd, 0x29, 0x09, 0x2a, 0x1c, 0x94, 0xc5, 0x28, 0x6c,
+ 0x04, 0x59, 0xeb, 0xd6, 0x7c, 0x0d, 0x45, 0x07, 0xd9, 0xde, 0x89, 0xa1, 0xd8, 0x38, 0x8a, 0x2b, 0x9f, 0xc3, 0xdb, 0x55,
+ 0x89, 0x90, 0xc6, 0x75, 0xd0, 0x2f, 0x85, 0x9b, 0x0a, 0x5e, 0x04, 0xa1, 0xf9, 0xf7, 0x16, 0x35, 0x9d, 0x97, 0xfe, 0x7c,
+ 0x4b, 0x27, 0x4c, 0xc3, 0x8a, 0x2a, 0x56, 0x6a, 0x41, 0xe5, 0xd3, 0x82, 0xeb, 0xd2, 0x62, 0x4e, 0x11, 0x1e, 0x4e, 0xae,
+ 0xa4, 0x79, 0x89, 0x20, 0x82, 0x6e, 0x39, 0x7d, 0x70, 0xf8, 0x17, 0xd6, 0xe3, 0x67, 0x9a, 0x14, 0xd7, 0xc8, 0x80, 0xbe,
+ 0x62, 0x52, 0xe7, 0x69, 0xab, 0x98, 0xa9, 0x14, 0x98, 0xbd, 0x30, 0xf4, 0xab, 0x2c, 0x22, 0x6b, 0x5f, 0xee, 0x58, 0xf3,
+ 0x6f, 0x15, 0xea, 0xce, 0xd3, 0x1b, 0x07, 0xfa, 0xe6, 0x4c, 0xeb, 0xeb, 0x30, 0xa6, 0xff, 0x03, 0xc9, 0x75, 0x94, 0xa5,
+ 0x5b, 0x68, 0xd3, 0x42, 0x85, 0x3f, 0xa4, 0x87, 0xee, 0x3f, 0x14, 0x63, 0x16, 0x52, 0x26, 0x3b, 0x1a, 0xee, 0x48, 0x77,
+ 0x6e, 0x4a, 0x56, 0x01, 0x53, 0x54, 0x1b, 0xa6, 0xd7, 0x72, 0x98, 0x89, 0xd5, 0xf7, 0x11, 0x3a, 0x86, 0xac, 0x64, 0xe6,
+ 0x59, 0xba, 0x07, 0xea, 0x23, 0x21, 0x05, 0xd6, 0x14, 0xed, 0x88, 0x2e, 0x96, 0xb3, 0x90, 0xc3, 0xb7, 0xc4, 0x5b, 0x8f,
+ 0x0e, 0xcd, 0x56, 0xba, 0xb8, 0x4b, 0x7b, 0xfd, 0xd4, 0x7d, 0x0c, 0xcb, 0xe1, 0xff, 0xaf, 0x3e, 0x2a, 0x7c, 0x1a, 0xe5,
+ 0x66, 0x65, 0x59, 0x42, 0xd7, 0x3b, 0xd2, 0x2e, 0x89, 0x1d, 0x64, 0xc0, 0xbd, 0xec, 0x8c, 0xaa, 0x06, 0xb8, 0x5a, 0x7c,
+ 0xb8, 0xd0, 0xa5, 0xef, 0x5a, 0xf3, 0x92, 0x4c, 0x2f, 0x60, 0x98, 0x34, 0x73, 0x49, 0x92, 0x7a, 0x5d, 0x7c, 0x2c, 0xcd,
+ 0x0b, 0xfb, 0x28, 0xd9, 0x3e, 0xfa, 0xbd, 0x76, 0x0f, 0xaa, 0x71, 0xfa, 0x98, 0x36, 0x94, 0x97, 0xaa, 0x97, 0x1f, 0x34,
+ 0x21, 0x72, 0xc6, 0x19, 0xb4, 0xe3, 0xaa, 0x05, 0x16, 0xda, 0xaa, 0x92, 0x04, 0x49, 0xc7, 0x97, 0x42, 0x58, 0xd0, 0x80,
+ 0xdc, 0x9e, 0xcf, 0xfa, 0x5f, 0x4b, 0xbc, 0x78, 0xff, 0x95, 0x39, 0x31, 0x4c, 0x30, 0x25, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31, 0x18, 0x1e, 0x16, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5f,
+ 0x00, 0x69, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x74, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xf6, 0x4d, 0x65, 0x40, 0x9d, 0xff, 0x26, 0x84, 0x3f, 0x6e, 0x6b,
+ 0x99, 0x75, 0xb0, 0xae, 0x60, 0x01, 0x8c, 0xf0, 0xf9, 0x30, 0x30, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x3d, 0xbb, 0x58, 0x44, 0x6c, 0xa3, 0x3c, 0x48, 0xaa, 0x52, 0x76, 0xd1, 0xef, 0x3a,
+ 0xe2, 0xa4, 0x23, 0xcc, 0x4d, 0x38, 0x04, 0x08, 0x11, 0xa4, 0xda, 0x79, 0x3e, 0xdd, 0xba, 0xfa, 0x02, 0x01, 0x01
+};
+unsigned int test_import_p12_len = 2499;
+
+// test_import_p12's password: "password"
+
static void
verifyPrivateKeyExtractability(BOOL extractable, NSArray *items)
{
options:NSDataBase64DecodingIgnoreUnknownCharacters];
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData);
SecKeyRef pubKey = NULL;
- ok_status(SecCertificateCopyPublicKey(cert, &pubKey), "export public key from certificate");
+ ok(pubKey = SecCertificateCopyKey(cert), "export public key from certificate");
NSData *pubKeyData = (__bridge_transfer NSData *)SecKeyCopyExternalRepresentation(pubKey, NULL);
eq_cf( (__bridge CFTypeRef) pubKeyData, (__bridge CFTypeRef) pubKData, "public key exports itself into expected data");
CFReleaseNull(pubKey);
}
#endif
-
-#if !TARGET_OS_IPHONE
-/* This is part of Security.framework on iOS */
-
-enum {
- // kSecKeyKeySizeInBits = 0, // already exists on osx
- kSecKeySignatureSize = 101,
- kSecKeyEncryptedDataSize = 102,
- // More might belong here, but we aren't settled on how
- // to take into account padding and/or digest types.
-};
-
-static
-size_t SecKeyGetSize(SecKeyRef key, int whichSize)
-{
- /* SecKeyGetBlockSize return the signature size on OS X -- smh */
- size_t result = SecKeyGetBlockSize(key);
-
- result = (result - 2)/2 - 3;
-
- /* in this test, this is always an ECDSA key */
- switch (whichSize) {
- case kSecKeyEncryptedDataSize:
- result = 0;
- break;
- case kSecKeySignatureSize:
- result = (result >= 66 ? 9 : 8) + 2 * result;
- break;
- case kSecKeyKeySizeInBits:
- if (result >= 66)
- return 521;
- }
-
- if (whichSize == kSecKeyKeySizeInBits)
- result *= 8;
-
- return result;
-
-}
-#endif
-
-
static void testkeygen(size_t keySizeInBits) {
SecKeyRef pubKey = NULL, privKey = NULL;
size_t keySizeInBytes = (keySizeInBits + 7) / 8;
skip("keygen failed", 8, status == errSecSuccess);
ok(pubKey, "pubKey returned");
ok(privKey, "privKey returned");
- is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
- is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
/* Sign something. */
uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
skip("keygen failed", 8, status == errSecSuccess);
ok(pubKey, "pubKey returned");
ok(privKey, "privKey returned");
- is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
- is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
SecKeyRef pubKey2, privKey2;
CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
/* Sign something. */
uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
- size_t sigLen = SecKeyGetSize(privKey2, kSecKeySignatureSize);
+ size_t sigLen = (((keySizeInBits + 7) / 8) + 3) * 2 + 3;
uint8_t sig[sigLen];
ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
something, sizeof(something), sig, &sigLen), "sign something");
int kc_41_sececkey(int argc, char *const *argv)
{
- plan_tests(288);
+ plan_tests(272);
tests();
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData);
ok(cert != NULL, "create certificate from data");
+ // Clean up any pre-existing data, but don't fail if nothing is deleted.
+ SecItemDelete((CFDictionaryRef)@{
+ (id)kSecClass: (id)kSecClassCertificate,
+ (id)kSecAttrLabel: @"sectests:store_cert_to_ios",
+ (id)kSecAttrNoLegacy: @YES,
+ });
+
// Store certificate to modern keychain.
NSDictionary *attrs = @{
(id)kSecValueRef: (__bridge id)cert,
#include "kc-keychain-file-helpers.h"
+extern char keychainFile[1000];
+extern char keychainDbFile[1000];
+extern char keychainTempFile[1000];
+extern char keychainName[1000];
+extern char testName[1000];
+
/* redefine this since the headers are mixed up */
static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right)
{
return CFEqual(left, right);
}
-static char keychainFile[1000];
-static char keychainDbFile[1000];
-static char keychainTempFile[1000];
-static char keychainName[1000];
-static char testName[1000];
-static uint32_t promptAttempts;
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-variable"
-#pragma clang diagnostic ignored "-Wunused-function"
-
-static void startTest(const char* thisTestName) {
- strlcpy(testName, thisTestName, sizeof(testName));
-}
+void startTest(const char* thisTestName);
-static void initializeKeychainTests(const char* thisTestName) {
- const char *home_dir = getenv("HOME");
- snprintf(keychainName, sizeof(keychainName), "test-%s.asdf", thisTestName);
- snprintf(keychainFile, sizeof(keychainFile), "%s/Library/Keychains/%s", home_dir, keychainName);
- snprintf(keychainDbFile, sizeof(keychainDbFile), "%s/Library/Keychains/%s-db", home_dir, keychainName);
- snprintf(keychainTempFile, sizeof(keychainTempFile), "%s/Library/Keychains/test_temp", home_dir);
-
- deleteKeychainFiles(keychainFile);
-
- startTest(thisTestName);
-
- SecKeychainGetUserPromptAttempts(&promptAttempts);
- SecKeychainSetUserInteractionAllowed(FALSE);
-}
+void initializeKeychainTests(const char* thisTestName);
// Use this at the bottom of every test to make sure everything is gone
-static void deleteTestFiles() {
- deleteKeychainFiles(keychainFile);
-}
-
-static SecKeychainRef CF_RETURNS_RETAINED getPopulatedTestKeychain() {
- deleteKeychainFiles(keychainFile);
-
- writeFile(keychainFile, test_keychain, sizeof(test_keychain));
-
- SecKeychainRef kc = NULL;
- ok_status(SecKeychainOpen(keychainFile, &kc), "%s: getPopulatedTestKeychain: SecKeychainOpen", testName);
- ok_status(SecKeychainUnlock(kc, (UInt32) strlen(test_keychain_password), test_keychain_password, true), "%s: getPopulatedTestKeychain: SecKeychainUnlock", testName);
- return kc;
-}
-#define getPopulatedTestKeychainTests 2
-
-static SecKeychainRef CF_RETURNS_RETAINED getEmptyTestKeychain() {
- deleteKeychainFiles(keychainFile);
-
- SecKeychainRef kc = NULL;
- ok_status(SecKeychainCreate(keychainFile, (UInt32) strlen(test_keychain_password), test_keychain_password, false, NULL, &kc), "%s: getPopulatedTestKeychain: SecKeychainCreate", testName);
- return kc;
-}
-#define getEmptyTestKeychainTests 1
-
-
-static void addToSearchList(SecKeychainRef keychain) {
- CFArrayRef searchList = NULL;
- SecKeychainCopySearchList(&searchList);
- CFMutableArrayRef mutableSearchList = CFArrayCreateMutableCopy(NULL, CFArrayGetCount(searchList) + 1, searchList);
- CFArrayAppendValue(mutableSearchList, keychain);
- SecKeychainSetSearchList(mutableSearchList);
- CFRelease(searchList);
- CFRelease(mutableSearchList);
-}
+void deleteTestFiles(void);
+void addToSearchList(SecKeychainRef keychain);
/* Checks to be sure there are N elements in this search, and returns the first
* if it exists. */
-static SecKeychainItemRef checkNCopyFirst(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) {
- CFArrayRef results = NULL;
- if(n > 0) {
- ok_status(SecItemCopyMatching(query, (CFTypeRef*) &results), "%s: SecItemCopyMatching", testName);
- } else {
- is(SecItemCopyMatching(query, (CFTypeRef*) &results), errSecItemNotFound, "%s: SecItemCopyMatching (for no items)", testName);
- }
-
- SecKeychainItemRef item = NULL;
- if(results) {
- is(CFArrayGetCount(results), n, "%s: Wrong number of results", testName);
- if(n >= 1) {
- ok(item = (SecKeychainItemRef) CFArrayGetValueAtIndex(results, 0), "%s: Couldn't get item", testName);
- } else {
- pass("make test numbers match");
- }
- } else if((!results) && n == 0) {
- pass("%s: no results found (and none expected)", testName);
- pass("make test numbers match");
- } else {
- fail("%s: no results found (and %d expected)", testName, n);
- fflush(stdout); CFShow(query); fflush(stdout);
- pass("make test numbers match");
- }
-
- CFRetainSafe(item);
- CFReleaseNull(results);
-
- CFRelease(query);
- return item;
-}
-
-static void checkN(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) {
- SecKeychainItemRef item = checkNCopyFirst(testName, query, n);
- CFReleaseSafe(item);
-}
+SecKeychainItemRef checkNCopyFirst(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n);
+void checkN(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n);
#define checkNTests 3
-
-static void readPasswordContentsWithResult(SecKeychainItemRef item, OSStatus expectedResult, CFStringRef expectedContents) {
- if(!item) {
- fail("no item passed to readPasswordContentsWithResult");
- fail("Match test numbers");
- fail("Match test numbers");
- return;
- }
-
- CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
- CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
- CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
-
- CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
- CFArrayAppendValue((CFMutableArrayRef)itemList, item);
- CFDictionarySetValue(query, kSecUseItemList, itemList);
-
- CFTypeRef results = NULL;
- if(expectedContents) {
- is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: SecItemCopyMatching", testName);
- CFReleaseNull(query);
-
- if(results) {
- ok(CFGetTypeID(results) == CFDataGetTypeID(), "%s: result is not a data", testName);
-
- CFDataRef data = (CFDataRef) results;
- CFStringRef str = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, false);
- eq_cf(str, expectedContents, "%s: contents do not match", testName);
- CFReleaseNull(str);
- CFReleaseNull(results);
- } else {
- fail("Didn't get any results");
- fail("Match test numbers");
- }
- } else {
- is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: expecting error %d", testName, (int) expectedResult);
- pass("Match test numbers");
- pass("Match test numbers");
- }
-}
+void readPasswordContentsWithResult(SecKeychainItemRef item, OSStatus expectedResult, CFStringRef expectedContents);
#define readPasswordContentsWithResultTests 3
-static void readPasswordContents(SecKeychainItemRef item, CFStringRef expectedContents) {
- return readPasswordContentsWithResult(item, errSecSuccess, expectedContents);
-}
+void readPasswordContents(SecKeychainItemRef item, CFStringRef expectedContents);
#define readPasswordContentsTests readPasswordContentsWithResultTests
-static void changePasswordContents(SecKeychainItemRef item, CFStringRef newPassword) {
- if(!item) {
- fail("no item passed to changePasswordContents");
- return;
- }
-
- CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
- CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
-
- CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
- CFArrayAppendValue((CFMutableArrayRef)itemList, item);
- CFDictionarySetValue(query, kSecUseItemList, itemList);
-
- CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDataRef data = CFDataCreate(NULL, (const UInt8*) CFStringGetCStringPtr(newPassword, kCFStringEncodingUTF8), CFStringGetLength(newPassword));
- CFDictionarySetValue(attrs, kSecValueData, data);
- CFReleaseNull(data);
-
- ok_status(SecItemUpdate(query, attrs), "%s: SecItemUpdate", testName);
-}
+void changePasswordContents(SecKeychainItemRef item, CFStringRef newPassword);
#define changePasswordContentsTests 1
-static void deleteItem(SecKeychainItemRef item) {
- CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
- CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
- CFArrayAppendValue((CFMutableArrayRef)itemList, item);
- CFDictionarySetValue(query, kSecUseItemList, itemList);
-
- ok_status(SecItemDelete(query), "%s: SecItemDelete single item", testName);
- CFReleaseNull(query);
-}
+void deleteItem(SecKeychainItemRef item);
#define deleteItemTests 1
-static void deleteItems(CFArrayRef items) {
- if(!items) {
- fail("no items passed to deleteItems");
- return;
- }
-
- CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(query, kSecUseItemList, items);
-
- size_t count = (size_t) CFArrayGetCount(items);
- if(count > 0) {
- ok_status(SecItemDelete(query), "%s: SecItemDelete %ld items", testName, count);
- } else {
- is(SecItemDelete(query), errSecItemNotFound, "%s: SecItemDelete no items", testName);
- }
- CFReleaseNull(query);
-}
+void deleteItems(CFArrayRef items);
#define deleteItemsTests 1
/* Checks in with securityd to see how many prompts were generated since the last call to this function, and tests against the number expected.
Returns the number generated since the last call. */
-static uint32_t checkPrompts(uint32_t expectedSinceLastCall, char* explanation) {
- uint32_t currentPrompts = UINT_MAX;
- uint32_t newPrompts = UINT_MAX;
- ok_status(SecKeychainGetUserPromptAttempts(¤tPrompts), "%s: SecKeychainGetUserPromptAttempts", testName);
-
- newPrompts = currentPrompts - promptAttempts;
-
- is(newPrompts, expectedSinceLastCall, "%s: wrong number of prompts: %s", testName, explanation);
- promptAttempts = currentPrompts;
-
- return newPrompts;
-}
+uint32_t checkPrompts(uint32_t expectedSinceLastCall, char* explanation);
#define checkPromptsTests 2
-#pragma clang diagnostic pop
-
#endif /* kc_helpers_h */
}
#define findIdentityTests 2
-unsigned char test_import_p12[] = {
- 0x30, 0x82, 0x09, 0xbf, 0x02, 0x01, 0x03, 0x30, 0x82, 0x09, 0x86, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x07, 0x01, 0xa0, 0x82, 0x09, 0x77, 0x04, 0x82, 0x09, 0x73, 0x30, 0x82, 0x09, 0x6f, 0x30, 0x82, 0x03, 0xff, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x03, 0xec, 0x02, 0x01, 0x00,
- 0x30, 0x82, 0x03, 0xe5, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xcb, 0xa2, 0x8c, 0x60, 0xc2, 0x36, 0x55,
- 0x05, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03, 0xb8, 0x57, 0x1d, 0x4c, 0x1f, 0xc7, 0x4c, 0x00, 0x82, 0xa3, 0xc9, 0x6f,
- 0x2e, 0x00, 0x03, 0x1b, 0x55, 0xaa, 0xe5, 0x89, 0x58, 0x18, 0x71, 0xb8, 0xff, 0x40, 0x13, 0xd5, 0xac, 0x7f, 0xf1, 0x48,
- 0xb2, 0x7e, 0x6e, 0xeb, 0x6e, 0xde, 0xe8, 0x35, 0x22, 0xa5, 0x45, 0x5a, 0xa6, 0x2e, 0xed, 0x0d, 0xe0, 0x8f, 0x2f, 0x60,
- 0x5c, 0xd8, 0x49, 0x89, 0x26, 0x42, 0xd6, 0xe0, 0x24, 0x1c, 0x59, 0x9c, 0xe0, 0xbf, 0x98, 0x0c, 0xc3, 0x81, 0x20, 0x47,
- 0x03, 0x03, 0xe2, 0x73, 0x90, 0x13, 0x6e, 0x96, 0x31, 0x68, 0xb7, 0x8f, 0xaa, 0x25, 0x4b, 0x27, 0x95, 0x3f, 0xef, 0xa3,
- 0x2b, 0x96, 0x10, 0x85, 0xf3, 0x49, 0x3c, 0x6f, 0x9a, 0x20, 0x02, 0x17, 0x42, 0xe9, 0x9c, 0x5e, 0x5d, 0x4b, 0x3c, 0x88,
- 0x65, 0xf5, 0x67, 0x61, 0x3e, 0xa6, 0x1a, 0x0f, 0x5b, 0x1e, 0x35, 0x18, 0x4e, 0xf3, 0x98, 0x93, 0x7e, 0x76, 0x77, 0x31,
- 0x3b, 0x00, 0x78, 0x8c, 0x50, 0x28, 0x76, 0xca, 0xc8, 0x39, 0xc5, 0xf5, 0x79, 0x23, 0x4a, 0xea, 0x9a, 0xf0, 0xb5, 0xb6,
- 0x50, 0x8d, 0x16, 0xd9, 0x39, 0x74, 0x36, 0x1d, 0x26, 0xcb, 0xbf, 0xb7, 0x72, 0x5e, 0x77, 0xf5, 0xb8, 0x35, 0xfc, 0x66,
- 0x4d, 0xdc, 0xd6, 0x20, 0x50, 0x70, 0xc6, 0xf7, 0x13, 0x55, 0xb1, 0x97, 0x7e, 0x1d, 0x6a, 0x7d, 0x73, 0xc2, 0x71, 0x49,
- 0xd1, 0x15, 0xe7, 0x30, 0xa7, 0x52, 0x1f, 0x24, 0xe8, 0x7b, 0xd7, 0x81, 0x53, 0x27, 0x94, 0xd0, 0x31, 0xe5, 0x11, 0xe4,
- 0x90, 0x8a, 0x02, 0x46, 0x70, 0x82, 0xe7, 0xc4, 0xfe, 0xb5, 0xed, 0xb0, 0x1b, 0xcb, 0xa2, 0x23, 0x5c, 0xd2, 0x95, 0xe6,
- 0x2c, 0x5f, 0x2d, 0x07, 0xb1, 0xd8, 0xe8, 0xa0, 0x39, 0xe7, 0xdd, 0x2e, 0x36, 0xac, 0x38, 0xfc, 0x65, 0x99, 0x2c, 0xda,
- 0x3d, 0x26, 0x5d, 0x1e, 0x2f, 0xbc, 0x31, 0x36, 0x3e, 0x87, 0x55, 0x5f, 0x40, 0xf1, 0x77, 0x7a, 0x15, 0xa2, 0xc3, 0xe4,
- 0x21, 0xc0, 0xe1, 0x11, 0x15, 0x31, 0xf4, 0x7a, 0x51, 0xc3, 0x78, 0x70, 0xfc, 0x3b, 0xed, 0x04, 0x7f, 0x5c, 0xaf, 0x22,
- 0x37, 0x1c, 0x80, 0xb6, 0x7b, 0xdf, 0x11, 0x90, 0x52, 0xc1, 0x0d, 0xfb, 0xaa, 0xd0, 0x43, 0x47, 0xe9, 0xdb, 0x31, 0xb7,
- 0xfc, 0x35, 0xbf, 0xce, 0x00, 0x15, 0x0d, 0x51, 0xb1, 0x78, 0x99, 0x55, 0x91, 0x1f, 0xf1, 0x4c, 0x36, 0xfa, 0xc1, 0xa0,
- 0xce, 0x86, 0xc9, 0x79, 0x60, 0x07, 0x58, 0xa7, 0xe5, 0x28, 0x28, 0x84, 0x92, 0x03, 0x2c, 0x43, 0xda, 0x69, 0xce, 0x75,
- 0x25, 0x01, 0x51, 0x37, 0xd4, 0xfd, 0xa2, 0xc4, 0x09, 0xfb, 0xa0, 0xf5, 0x1f, 0x23, 0x7b, 0xd6, 0x63, 0xd1, 0xb5, 0x5b,
- 0xc5, 0xd9, 0xbc, 0xe7, 0xd4, 0x5e, 0x8b, 0x62, 0xee, 0xdb, 0xb7, 0x1e, 0xd2, 0x8b, 0x6e, 0xe4, 0x8c, 0xfd, 0x11, 0x25,
- 0xda, 0xac, 0x2a, 0x7a, 0x9a, 0xad, 0x6c, 0x29, 0xe1, 0x1c, 0x68, 0x4f, 0xb3, 0x99, 0x06, 0xb4, 0x72, 0x2a, 0x5a, 0x70,
- 0xd6, 0xf6, 0x7c, 0x22, 0x0f, 0x85, 0xf1, 0xc4, 0x30, 0x9f, 0x32, 0x53, 0xa1, 0xb2, 0x1a, 0x41, 0x01, 0xa2, 0x92, 0x58,
- 0xa2, 0x27, 0xe8, 0x09, 0xed, 0x75, 0x84, 0x41, 0xcd, 0x19, 0x46, 0x47, 0x86, 0x7d, 0xa0, 0x49, 0xc4, 0x72, 0x94, 0x9f,
- 0x43, 0xf2, 0x09, 0x3a, 0x59, 0x56, 0x7c, 0x3b, 0x34, 0x79, 0x1b, 0x58, 0x82, 0xc7, 0x64, 0x19, 0x7c, 0x32, 0x7b, 0x42,
- 0x66, 0x9f, 0x32, 0xef, 0x48, 0xb4, 0xf7, 0xd0, 0x74, 0x1f, 0x1c, 0xbe, 0xd4, 0x7a, 0x2a, 0x02, 0xb2, 0x3d, 0x47, 0x15,
- 0x40, 0xa8, 0xd5, 0x57, 0xc8, 0xe7, 0x7d, 0x8d, 0xa6, 0xea, 0xe5, 0x21, 0x6a, 0xbe, 0x39, 0x8c, 0xfd, 0x78, 0x26, 0xaf,
- 0x31, 0x93, 0x0f, 0x94, 0x07, 0x87, 0x6c, 0xa8, 0x56, 0xd8, 0xc6, 0x79, 0xcf, 0x1d, 0x36, 0xee, 0xab, 0x33, 0x5b, 0x63,
- 0xe8, 0x34, 0x00, 0x0c, 0x95, 0x48, 0x34, 0xac, 0xe2, 0xda, 0x61, 0x7a, 0x97, 0x3e, 0x41, 0xe4, 0xb7, 0x30, 0xb0, 0xb3,
- 0x96, 0xed, 0x91, 0xb8, 0x5b, 0x20, 0x30, 0xfa, 0xf0, 0xfa, 0xc7, 0xc2, 0x97, 0x14, 0x9b, 0x81, 0xa9, 0x70, 0x8a, 0x10,
- 0xf1, 0x75, 0xe4, 0xec, 0x54, 0x3e, 0xd9, 0xa8, 0x94, 0xcd, 0x3a, 0x82, 0xf7, 0xe3, 0xb8, 0x75, 0xd7, 0x49, 0x6c, 0x80,
- 0x97, 0xd8, 0xdf, 0x56, 0x66, 0x93, 0xe6, 0xef, 0xa3, 0xc3, 0xd6, 0x34, 0xb7, 0x6f, 0x9b, 0x51, 0xaa, 0x7c, 0x1e, 0x16,
- 0x8f, 0x21, 0x8a, 0x0a, 0x9f, 0x0e, 0xbe, 0x6b, 0x96, 0x8b, 0x95, 0x95, 0x5d, 0x11, 0x39, 0x15, 0x8c, 0xca, 0x9d, 0xec,
- 0x26, 0x39, 0x49, 0x1e, 0xf6, 0x16, 0x09, 0x36, 0x95, 0xae, 0xa0, 0x55, 0xbf, 0x94, 0xf2, 0x6f, 0x1b, 0x74, 0x93, 0x97,
- 0x6d, 0xd8, 0x00, 0x0c, 0xf0, 0x9e, 0x24, 0xb9, 0xfe, 0x04, 0xfa, 0x30, 0x63, 0x90, 0x28, 0xcb, 0x0d, 0x8e, 0xe8, 0xf0,
- 0x7f, 0x9a, 0x69, 0x54, 0xf2, 0xbc, 0x9f, 0x24, 0x0b, 0xd1, 0xda, 0x2f, 0x22, 0x81, 0x22, 0x31, 0x03, 0xc2, 0x60, 0x41,
- 0x2e, 0xe0, 0xc6, 0x52, 0x7b, 0x5a, 0x35, 0xbc, 0x00, 0xfd, 0x71, 0x00, 0x19, 0xd3, 0xa4, 0xa8, 0x5b, 0xbc, 0xfc, 0xae,
- 0x24, 0x10, 0xb4, 0x21, 0x8c, 0x3c, 0x15, 0xad, 0x2d, 0x1e, 0x33, 0x09, 0x58, 0x93, 0xb4, 0x29, 0x3a, 0xbc, 0x6f, 0x7d,
- 0x51, 0x3b, 0x5b, 0x97, 0xfe, 0x67, 0xe1, 0x9e, 0xff, 0x6b, 0xdc, 0xf2, 0xb0, 0x6f, 0xa1, 0x4e, 0x4b, 0xf2, 0xdf, 0xd6,
- 0xa4, 0xec, 0x8d, 0x19, 0x6d, 0x30, 0x67, 0xde, 0x04, 0x5e, 0xaf, 0xd7, 0xd4, 0x42, 0xf8, 0xbc, 0xca, 0xfc, 0x49, 0xc0,
- 0xe7, 0xcd, 0xfc, 0xab, 0xca, 0x3f, 0x67, 0xff, 0xfb, 0x41, 0xc0, 0xe4, 0xe8, 0x0c, 0xe8, 0x2e, 0xca, 0x43, 0xfb, 0xec,
- 0xe0, 0xeb, 0xea, 0x30, 0x14, 0xca, 0x30, 0x8d, 0x49, 0xaa, 0x99, 0x71, 0xcb, 0x85, 0xa4, 0x68, 0xda, 0xd1, 0xbe, 0xa9,
- 0xc6, 0xee, 0x26, 0xdf, 0x3f, 0xde, 0x39, 0x29, 0x6c, 0x45, 0x9e, 0x41, 0x88, 0x63, 0xd8, 0x31, 0x47, 0x8e, 0xdc, 0xc8,
- 0xe4, 0x28, 0x25, 0x75, 0x11, 0x99, 0xdd, 0x28, 0x25, 0xa7, 0x5e, 0xac, 0x7f, 0x0c, 0xb5, 0x2b, 0x62, 0x9d, 0xe0, 0xda,
- 0xe3, 0xc2, 0xd8, 0x8d, 0xc6, 0x25, 0x5f, 0x08, 0x6e, 0xfc, 0xcd, 0xae, 0x4c, 0x99, 0x41, 0xc4, 0x75, 0x3e, 0x5e, 0x51,
- 0xa1, 0x76, 0x47, 0x93, 0x4a, 0x83, 0x51, 0x91, 0xf3, 0x92, 0xd0, 0x29, 0xa6, 0x44, 0x3c, 0x2a, 0x91, 0x3f, 0x01, 0x75,
- 0xeb, 0x6f, 0xf3, 0x3c, 0x04, 0xd3, 0x74, 0x7a, 0xfc, 0x7a, 0x39, 0x70, 0xc8, 0x3a, 0x89, 0x93, 0xbd, 0xfd, 0xd7, 0x41,
- 0x2c, 0xb0, 0xd3, 0xef, 0xd0, 0xd5, 0x75, 0x24, 0xb1, 0x0e, 0x3d, 0x89, 0x8e, 0xde, 0xa7, 0x40, 0x80, 0xd2, 0x05, 0xe5,
- 0x18, 0xa2, 0xf3, 0x30, 0x22, 0x56, 0x0b, 0xbc, 0x05, 0xb0, 0x48, 0x9a, 0x42, 0xb7, 0xe1, 0x32, 0xba, 0x52, 0x99, 0x22,
- 0xf6, 0x30, 0x82, 0x05, 0x68, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x59,
- 0x04, 0x82, 0x05, 0x55, 0x30, 0x82, 0x05, 0x51, 0x30, 0x82, 0x05, 0x4d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x8e, 0x7e, 0x90, 0x94, 0xaf, 0x09, 0xc5, 0xbc, 0x02,
- 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0x0c, 0x7c, 0x7f, 0x58, 0x8b, 0x41, 0x9a, 0xb8, 0x70, 0xbf, 0x6c, 0x4c, 0xb8,
- 0x7d, 0x72, 0xa5, 0x50, 0xe6, 0xc4, 0xaf, 0x74, 0x0e, 0x88, 0xbf, 0x83, 0x51, 0xbc, 0xe1, 0x66, 0x8a, 0x9f, 0x42, 0x11,
- 0x2b, 0x3d, 0x8c, 0x10, 0xa3, 0xc2, 0xdf, 0xb9, 0x36, 0x74, 0xc1, 0x18, 0x23, 0x1e, 0x9a, 0xbf, 0x8d, 0x0a, 0x4b, 0x63,
- 0xd5, 0x20, 0x1b, 0xae, 0xb0, 0x64, 0xfc, 0xe1, 0x5c, 0xe7, 0xde, 0xa3, 0x6f, 0x8e, 0xe3, 0xc9, 0x8d, 0x18, 0x63, 0x7f,
- 0x26, 0x4a, 0x3d, 0x41, 0x76, 0xa6, 0xaa, 0x3f, 0x27, 0x75, 0xec, 0x2f, 0x78, 0xd2, 0x40, 0x28, 0xe7, 0xf5, 0xee, 0x61,
- 0x6d, 0x49, 0xe0, 0x64, 0x33, 0xc9, 0x9e, 0xf6, 0xda, 0x86, 0x3a, 0xad, 0x47, 0x13, 0xe2, 0x8a, 0x0b, 0x98, 0xe7, 0x73,
- 0xea, 0x08, 0x59, 0xfe, 0x74, 0x6f, 0x10, 0x7d, 0xbc, 0x0b, 0xb9, 0xcf, 0xe7, 0xe7, 0x28, 0xe8, 0xfe, 0x20, 0x8a, 0x98,
- 0x40, 0x00, 0x52, 0xa0, 0x0c, 0x5c, 0xfa, 0x48, 0x5b, 0xf4, 0x3c, 0x76, 0x5d, 0xf4, 0x33, 0x53, 0xd4, 0x51, 0x43, 0x47,
- 0x29, 0xda, 0xff, 0xbd, 0xfe, 0x71, 0x5b, 0x50, 0xa1, 0xa5, 0x25, 0xe9, 0xcc, 0x68, 0x74, 0x9f, 0x7f, 0x39, 0x65, 0x5e,
- 0xb9, 0x71, 0x8f, 0x25, 0x68, 0xe6, 0x71, 0x06, 0x10, 0xa2, 0xfb, 0x08, 0x54, 0x21, 0xca, 0x28, 0xfc, 0xf1, 0x89, 0xb9,
- 0x29, 0x11, 0x67, 0x00, 0x19, 0xdd, 0x00, 0xd8, 0x48, 0x89, 0x46, 0x0d, 0x39, 0x0c, 0x7e, 0x94, 0x02, 0x80, 0x37, 0xa0,
- 0x01, 0x45, 0x25, 0xbd, 0x8b, 0x44, 0xcc, 0xdf, 0x43, 0xa1, 0x1d, 0xf5, 0x59, 0x4b, 0x07, 0xe6, 0xab, 0x15, 0x93, 0x3d,
- 0xea, 0x7d, 0xd6, 0xaa, 0xb0, 0x97, 0xed, 0x1d, 0x5e, 0xc2, 0xf0, 0xea, 0x1b, 0xc2, 0xcc, 0x88, 0x47, 0x3e, 0xe4, 0x54,
- 0xc3, 0x02, 0xac, 0x5e, 0x88, 0xb9, 0x2f, 0x82, 0xd4, 0xd0, 0x5d, 0xb2, 0x2a, 0xee, 0x94, 0x3d, 0xdb, 0x82, 0x93, 0xc6,
- 0x69, 0x5f, 0x40, 0x83, 0xf0, 0x07, 0x8d, 0x9f, 0x7f, 0x29, 0x3f, 0x4d, 0x3b, 0x08, 0xd9, 0x29, 0xf5, 0x1c, 0x0f, 0x18,
- 0x42, 0x4b, 0xd9, 0x01, 0xda, 0x71, 0x92, 0xa8, 0x32, 0xa7, 0x53, 0x6f, 0xd0, 0x74, 0x4a, 0xee, 0x39, 0x04, 0xf1, 0x2d,
- 0xee, 0x50, 0xbe, 0x48, 0xb1, 0x90, 0x21, 0x24, 0x28, 0x40, 0xa9, 0x85, 0xe1, 0x81, 0x77, 0x37, 0xa8, 0x86, 0x15, 0x7d,
- 0x16, 0xb2, 0xe7, 0xcc, 0xe0, 0xa2, 0x7e, 0x58, 0xb3, 0xdc, 0xf9, 0x41, 0xae, 0x36, 0xba, 0x55, 0x87, 0x64, 0x01, 0xfd,
- 0xc9, 0x0e, 0xa1, 0xfe, 0x55, 0xc3, 0x2a, 0x66, 0xd5, 0x83, 0x39, 0x7e, 0x5a, 0xe8, 0x28, 0x76, 0x36, 0xbb, 0x39, 0xa9,
- 0xb7, 0xc6, 0xcf, 0x99, 0x56, 0xe5, 0xbf, 0x4d, 0xb2, 0xa0, 0xac, 0x64, 0x00, 0xc9, 0x42, 0x79, 0x47, 0x46, 0xd7, 0x9c,
- 0x4a, 0x33, 0x03, 0x55, 0x07, 0x7f, 0x05, 0x23, 0xe3, 0x51, 0x35, 0xa9, 0x32, 0xe9, 0xa6, 0xf2, 0xe2, 0x42, 0x4d, 0x00,
- 0xbb, 0xdb, 0xc3, 0x85, 0x05, 0xcb, 0xe4, 0xb1, 0x0a, 0x03, 0xf4, 0xe5, 0x27, 0x28, 0x12, 0xec, 0x1e, 0xd4, 0xd7, 0x43,
- 0xe3, 0x05, 0xc7, 0x92, 0xd2, 0x8e, 0xf7, 0xae, 0x55, 0x1a, 0x50, 0x88, 0x2f, 0x91, 0x05, 0x65, 0x4b, 0xe3, 0xba, 0xc0,
- 0x42, 0x86, 0x19, 0x2b, 0x64, 0xfc, 0x46, 0x31, 0x9b, 0xd2, 0x88, 0x32, 0xf8, 0x4d, 0x91, 0xd4, 0xc6, 0x77, 0xcb, 0x29,
- 0x00, 0x5e, 0xd2, 0x48, 0x99, 0x0e, 0x3f, 0x2d, 0x4f, 0xdb, 0x9b, 0x05, 0xea, 0xa1, 0x3d, 0x9f, 0x21, 0x83, 0x6f, 0xcf,
- 0xe9, 0x1c, 0x65, 0x40, 0x3c, 0x8b, 0x2a, 0x38, 0x8f, 0x1b, 0x5a, 0x3c, 0x73, 0x7a, 0xfc, 0x81, 0x69, 0xb3, 0xff, 0xb6,
- 0x25, 0x12, 0x3f, 0xda, 0x50, 0xe7, 0xde, 0xfe, 0xd3, 0x31, 0x2f, 0xb4, 0x99, 0x87, 0xae, 0x17, 0xaf, 0xe4, 0xb8, 0x35,
- 0xf7, 0x3c, 0xc0, 0x99, 0x0e, 0x75, 0x72, 0xb6, 0x46, 0xa1, 0x55, 0xef, 0xff, 0x48, 0x3b, 0x5c, 0x85, 0xf7, 0xc3, 0x03,
- 0x0a, 0x49, 0x0f, 0x11, 0x48, 0x13, 0x8b, 0x90, 0x73, 0x33, 0xb6, 0x22, 0x35, 0x45, 0x07, 0x80, 0x1a, 0xf9, 0x91, 0x80,
- 0x9d, 0x8b, 0xc7, 0x8e, 0xcc, 0x3a, 0x52, 0x93, 0x8f, 0xf6, 0x59, 0x3c, 0x69, 0xf7, 0x52, 0x9a, 0x8d, 0x8e, 0xfe, 0x8a,
- 0x41, 0xb0, 0x43, 0x74, 0x04, 0xe8, 0x0e, 0xf5, 0xc1, 0x4c, 0xa3, 0x8d, 0xe3, 0x98, 0x25, 0xf6, 0xd5, 0x0d, 0xa9, 0x2d,
- 0xb7, 0x6f, 0x52, 0x22, 0x43, 0x59, 0x30, 0x6d, 0x54, 0xb6, 0xad, 0x73, 0xa1, 0xe8, 0xee, 0x10, 0xbd, 0x55, 0xa4, 0x7f,
- 0xc3, 0x1d, 0xad, 0x8e, 0x72, 0xf1, 0x26, 0x6d, 0xa1, 0xaf, 0xda, 0x82, 0x37, 0xa1, 0x6d, 0xfe, 0x78, 0xd1, 0x88, 0x65,
- 0x6a, 0xb2, 0x33, 0x23, 0xcd, 0xba, 0xbe, 0x09, 0x66, 0x61, 0x33, 0xdc, 0x69, 0xed, 0x4f, 0xe6, 0xfb, 0x2f, 0x7d, 0xd0,
- 0xfd, 0x7a, 0x21, 0x69, 0x2d, 0x1f, 0xd4, 0xc4, 0x93, 0x7c, 0x34, 0x7d, 0x67, 0x2c, 0xe9, 0x2a, 0x9a, 0x53, 0xc2, 0xbf,
- 0xf9, 0x06, 0x10, 0xa6, 0xa8, 0x60, 0xe3, 0x01, 0xcb, 0x2b, 0x03, 0xdb, 0xb7, 0x27, 0xe9, 0x86, 0xe8, 0x7d, 0x75, 0xce,
- 0x80, 0xdb, 0xaf, 0xe9, 0x7e, 0x75, 0xad, 0xe3, 0xd4, 0xc4, 0xf3, 0x10, 0x89, 0x16, 0xcb, 0xc6, 0x23, 0x5a, 0x58, 0x66,
- 0xb6, 0x2a, 0xd7, 0xc9, 0x69, 0xd3, 0x7f, 0xa2, 0x9a, 0x5c, 0x1c, 0xd4, 0xf8, 0xe3, 0xe0, 0x63, 0x01, 0x88, 0x14, 0xb3,
- 0x20, 0xe3, 0x22, 0x45, 0x3d, 0xae, 0xaf, 0x0b, 0x55, 0xa1, 0x65, 0xec, 0x16, 0x0b, 0x35, 0x37, 0x6f, 0x12, 0x5f, 0x29,
- 0x47, 0xee, 0xdd, 0xbb, 0xcf, 0x9f, 0x87, 0xaf, 0x7d, 0xaa, 0xf4, 0x01, 0x45, 0xea, 0x5f, 0x00, 0x87, 0x1e, 0xeb, 0x2f,
- 0x77, 0x2b, 0x92, 0x42, 0x04, 0x45, 0x33, 0xf2, 0xfb, 0x6b, 0xac, 0xca, 0x98, 0x79, 0x56, 0x6f, 0xe7, 0x5b, 0xbd, 0x63,
- 0xc7, 0x3a, 0x8c, 0xfd, 0x93, 0xb1, 0x13, 0x4e, 0xc2, 0x05, 0x7f, 0xde, 0x44, 0xa8, 0xb7, 0xc4, 0x9c, 0xba, 0x57, 0x58,
- 0x3b, 0xba, 0xb5, 0x74, 0x73, 0x97, 0x20, 0x53, 0x70, 0x70, 0x65, 0xf1, 0x81, 0xea, 0x07, 0xc2, 0xbe, 0x57, 0x71, 0x62,
- 0x3b, 0xc0, 0x3c, 0x07, 0x65, 0xf4, 0x22, 0xfb, 0xd3, 0xf9, 0x2d, 0xb3, 0x20, 0xdd, 0x66, 0x51, 0x89, 0x54, 0x57, 0xcd,
- 0xd7, 0xc7, 0x1a, 0xd9, 0xfe, 0xe0, 0x13, 0x9d, 0x7d, 0xe7, 0xe3, 0x2f, 0x65, 0x3e, 0xf0, 0xb2, 0xd9, 0x0c, 0x1a, 0xa9,
- 0xaa, 0xba, 0x3b, 0x79, 0x86, 0xed, 0x6c, 0xbf, 0x9e, 0x9b, 0xb5, 0x78, 0xd8, 0x9e, 0x2f, 0x95, 0xcc, 0x31, 0xb4, 0x5f,
- 0xd3, 0x63, 0xff, 0xb9, 0x62, 0x34, 0xfd, 0x78, 0x1f, 0xac, 0xe7, 0xbd, 0x29, 0x09, 0x2a, 0x1c, 0x94, 0xc5, 0x28, 0x6c,
- 0x04, 0x59, 0xeb, 0xd6, 0x7c, 0x0d, 0x45, 0x07, 0xd9, 0xde, 0x89, 0xa1, 0xd8, 0x38, 0x8a, 0x2b, 0x9f, 0xc3, 0xdb, 0x55,
- 0x89, 0x90, 0xc6, 0x75, 0xd0, 0x2f, 0x85, 0x9b, 0x0a, 0x5e, 0x04, 0xa1, 0xf9, 0xf7, 0x16, 0x35, 0x9d, 0x97, 0xfe, 0x7c,
- 0x4b, 0x27, 0x4c, 0xc3, 0x8a, 0x2a, 0x56, 0x6a, 0x41, 0xe5, 0xd3, 0x82, 0xeb, 0xd2, 0x62, 0x4e, 0x11, 0x1e, 0x4e, 0xae,
- 0xa4, 0x79, 0x89, 0x20, 0x82, 0x6e, 0x39, 0x7d, 0x70, 0xf8, 0x17, 0xd6, 0xe3, 0x67, 0x9a, 0x14, 0xd7, 0xc8, 0x80, 0xbe,
- 0x62, 0x52, 0xe7, 0x69, 0xab, 0x98, 0xa9, 0x14, 0x98, 0xbd, 0x30, 0xf4, 0xab, 0x2c, 0x22, 0x6b, 0x5f, 0xee, 0x58, 0xf3,
- 0x6f, 0x15, 0xea, 0xce, 0xd3, 0x1b, 0x07, 0xfa, 0xe6, 0x4c, 0xeb, 0xeb, 0x30, 0xa6, 0xff, 0x03, 0xc9, 0x75, 0x94, 0xa5,
- 0x5b, 0x68, 0xd3, 0x42, 0x85, 0x3f, 0xa4, 0x87, 0xee, 0x3f, 0x14, 0x63, 0x16, 0x52, 0x26, 0x3b, 0x1a, 0xee, 0x48, 0x77,
- 0x6e, 0x4a, 0x56, 0x01, 0x53, 0x54, 0x1b, 0xa6, 0xd7, 0x72, 0x98, 0x89, 0xd5, 0xf7, 0x11, 0x3a, 0x86, 0xac, 0x64, 0xe6,
- 0x59, 0xba, 0x07, 0xea, 0x23, 0x21, 0x05, 0xd6, 0x14, 0xed, 0x88, 0x2e, 0x96, 0xb3, 0x90, 0xc3, 0xb7, 0xc4, 0x5b, 0x8f,
- 0x0e, 0xcd, 0x56, 0xba, 0xb8, 0x4b, 0x7b, 0xfd, 0xd4, 0x7d, 0x0c, 0xcb, 0xe1, 0xff, 0xaf, 0x3e, 0x2a, 0x7c, 0x1a, 0xe5,
- 0x66, 0x65, 0x59, 0x42, 0xd7, 0x3b, 0xd2, 0x2e, 0x89, 0x1d, 0x64, 0xc0, 0xbd, 0xec, 0x8c, 0xaa, 0x06, 0xb8, 0x5a, 0x7c,
- 0xb8, 0xd0, 0xa5, 0xef, 0x5a, 0xf3, 0x92, 0x4c, 0x2f, 0x60, 0x98, 0x34, 0x73, 0x49, 0x92, 0x7a, 0x5d, 0x7c, 0x2c, 0xcd,
- 0x0b, 0xfb, 0x28, 0xd9, 0x3e, 0xfa, 0xbd, 0x76, 0x0f, 0xaa, 0x71, 0xfa, 0x98, 0x36, 0x94, 0x97, 0xaa, 0x97, 0x1f, 0x34,
- 0x21, 0x72, 0xc6, 0x19, 0xb4, 0xe3, 0xaa, 0x05, 0x16, 0xda, 0xaa, 0x92, 0x04, 0x49, 0xc7, 0x97, 0x42, 0x58, 0xd0, 0x80,
- 0xdc, 0x9e, 0xcf, 0xfa, 0x5f, 0x4b, 0xbc, 0x78, 0xff, 0x95, 0x39, 0x31, 0x4c, 0x30, 0x25, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31, 0x18, 0x1e, 0x16, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5f,
- 0x00, 0x69, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x74, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xf6, 0x4d, 0x65, 0x40, 0x9d, 0xff, 0x26, 0x84, 0x3f, 0x6e, 0x6b,
- 0x99, 0x75, 0xb0, 0xae, 0x60, 0x01, 0x8c, 0xf0, 0xf9, 0x30, 0x30, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
- 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x3d, 0xbb, 0x58, 0x44, 0x6c, 0xa3, 0x3c, 0x48, 0xaa, 0x52, 0x76, 0xd1, 0xef, 0x3a,
- 0xe2, 0xa4, 0x23, 0xcc, 0x4d, 0x38, 0x04, 0x08, 0x11, 0xa4, 0xda, 0x79, 0x3e, 0xdd, 0xba, 0xfa, 0x02, 0x01, 0x01
-};
-unsigned int test_import_p12_len = 2499;
-
-// test_import_p12's password: "password"
-
#pragma clang diagnostic pop
#endif /* kc_identity_helpers_h */
--- /dev/null
+
+#include "kc-keychain-file-helpers.h"
+#include "kc-helpers.h"
+
+char keychainFile[1000];
+char keychainDbFile[1000];
+char keychainTempFile[1000];
+char keychainName[1000];
+char testName[1000];
+uint32_t promptAttempts;
+
+const char * test_keychain_password = "password";
+
+unsigned char test_keychain[] = {
+ 0x6b, 0x79, 0x63, 0x68, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xb3, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x1b, 0x70,
+ 0x00, 0x00, 0x4d, 0xe8, 0x00, 0x00, 0x4e, 0x10, 0x00, 0x00, 0x57, 0xe0, 0x00, 0x00, 0x6c, 0x88, 0x00, 0x00, 0x8b, 0x44,
+ 0x00, 0x00, 0x91, 0x20, 0x00, 0x00, 0x96, 0x4c, 0x00, 0x00, 0x97, 0x0c, 0x00, 0x00, 0xb2, 0x28, 0x00, 0x00, 0x03, 0x2c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x03, 0x24, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x01, 0x14,
+ 0x00, 0x00, 0x01, 0x5c, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x02, 0x04,
+ 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0xd8, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
+ 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
+ 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d,
+ 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42,
+ 0x55, 0x54, 0x45, 0x53, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x19, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d,
+ 0x41, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
+ 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
+ 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x50, 0x41, 0x52, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f,
+ 0x44, 0x55, 0x4c, 0x45, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x44, 0x42, 0x42, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
+ 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
+ 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59,
+ 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d,
+ 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x52,
+ 0x49, 0x56, 0x41, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
+ 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1f, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
+ 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x53, 0x59, 0x4d, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f,
+ 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x22, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52,
+ 0x44, 0x5f, 0x58, 0x35, 0x30, 0x39, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a,
+ 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x01, 0x84,
+ 0x00, 0x00, 0x01, 0xc4, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x02, 0xc4,
+ 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x03, 0x44, 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x03, 0xc4, 0x00, 0x00, 0x04, 0x04,
+ 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x84, 0x00, 0x00, 0x04, 0xc4, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x05, 0x44,
+ 0x00, 0x00, 0x05, 0x84, 0x00, 0x00, 0x05, 0xc4, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x44, 0x00, 0x00, 0x06, 0x84,
+ 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x84, 0x00, 0x00, 0x07, 0xc4,
+ 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x44, 0x00, 0x00, 0x08, 0x84, 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x09, 0x04,
+ 0x00, 0x00, 0x09, 0x44, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x09, 0xc4, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x44,
+ 0x00, 0x00, 0x0a, 0x84, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x0b, 0x44, 0x00, 0x00, 0x0b, 0x84,
+ 0x00, 0x00, 0x0b, 0xc4, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x0c, 0x44, 0x00, 0x00, 0x0c, 0x84, 0x00, 0x00, 0x0c, 0xc4,
+ 0x00, 0x00, 0x0d, 0x04, 0x00, 0x00, 0x0d, 0x44, 0x00, 0x00, 0x0d, 0x84, 0x00, 0x00, 0x0d, 0xc4, 0x00, 0x00, 0x0e, 0x04,
+ 0x00, 0x00, 0x0e, 0x44, 0x00, 0x00, 0x0e, 0x84, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x0f, 0x44,
+ 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0x0f, 0xc4, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x10, 0x84,
+ 0x00, 0x00, 0x10, 0xc4, 0x00, 0x00, 0x11, 0x04, 0x00, 0x00, 0x11, 0x44, 0x00, 0x00, 0x11, 0x84, 0x00, 0x00, 0x11, 0xc4,
+ 0x00, 0x00, 0x12, 0x04, 0x00, 0x00, 0x12, 0x44, 0x00, 0x00, 0x12, 0x84, 0x00, 0x00, 0x12, 0xc4, 0x00, 0x00, 0x13, 0x04,
+ 0x00, 0x00, 0x13, 0x44, 0x00, 0x00, 0x13, 0x84, 0x00, 0x00, 0x13, 0xc4, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x14, 0x44,
+ 0x00, 0x00, 0x14, 0x84, 0x00, 0x00, 0x14, 0xc4, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x15, 0x44, 0x00, 0x00, 0x15, 0x84,
+ 0x00, 0x00, 0x15, 0xc4, 0x00, 0x00, 0x16, 0x04, 0x00, 0x00, 0x16, 0x44, 0x00, 0x00, 0x16, 0x84, 0x00, 0x00, 0x16, 0xc4,
+ 0x00, 0x00, 0x17, 0x04, 0x00, 0x00, 0x17, 0x44, 0x00, 0x00, 0x17, 0x84, 0x00, 0x00, 0x17, 0xc4, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x61, 0x63, 0x63, 0x74,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, 0x69, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
+ 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x72, 0x74,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x08, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x70, 0x74, 0x63, 0x6c,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c,
+ 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x0d, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4a,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4f,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x6e, 0x62, 0x72,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x73, 0x6e, 0x62, 0x72,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x59,
+ 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x78, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac,
+ 0x00, 0x00, 0x32, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x02, 0xfc,
+ 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x03, 0x9c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x98,
+ 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x05, 0x90, 0x00, 0x00, 0x05, 0xdc, 0x00, 0x00, 0x06, 0x2c,
+ 0x00, 0x00, 0x06, 0x7c, 0x00, 0x00, 0x06, 0xd4, 0x00, 0x00, 0x07, 0x24, 0x00, 0x00, 0x07, 0x74, 0x00, 0x00, 0x07, 0xc0,
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x58, 0x00, 0x00, 0x08, 0xac, 0x00, 0x00, 0x08, 0xec, 0x00, 0x00, 0x09, 0x2c,
+ 0x00, 0x00, 0x09, 0x6c, 0x00, 0x00, 0x09, 0xac, 0x00, 0x00, 0x09, 0xec, 0x00, 0x00, 0x0a, 0x2c, 0x00, 0x00, 0x0a, 0x6c,
+ 0x00, 0x00, 0x0a, 0xbc, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x0b, 0x48, 0x00, 0x00, 0x0b, 0x88, 0x00, 0x00, 0x0b, 0xc8,
+ 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x0c, 0x88, 0x00, 0x00, 0x0c, 0xc8, 0x00, 0x00, 0x0d, 0x08,
+ 0x00, 0x00, 0x0d, 0x48, 0x00, 0x00, 0x0d, 0x88, 0x00, 0x00, 0x0d, 0xc8, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x00, 0x0e, 0x48,
+ 0x00, 0x00, 0x0e, 0x88, 0x00, 0x00, 0x0e, 0xd8, 0x00, 0x00, 0x0f, 0x24, 0x00, 0x00, 0x0f, 0x64, 0x00, 0x00, 0x0f, 0xa4,
+ 0x00, 0x00, 0x0f, 0xe4, 0x00, 0x00, 0x10, 0x24, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x10, 0xa4, 0x00, 0x00, 0x10, 0xe4,
+ 0x00, 0x00, 0x11, 0x24, 0x00, 0x00, 0x11, 0x64, 0x00, 0x00, 0x11, 0xa4, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00, 0x12, 0x24,
+ 0x00, 0x00, 0x12, 0x64, 0x00, 0x00, 0x12, 0xa4, 0x00, 0x00, 0x12, 0xe4, 0x00, 0x00, 0x13, 0x24, 0x00, 0x00, 0x13, 0x64,
+ 0x00, 0x00, 0x13, 0xb4, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x14, 0xc0,
+ 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x40, 0x00, 0x00, 0x15, 0x80, 0x00, 0x00, 0x15, 0xc0, 0x00, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x16, 0x40, 0x00, 0x00, 0x16, 0x80, 0x00, 0x00, 0x16, 0xc0, 0x00, 0x00, 0x17, 0x0c, 0x00, 0x00, 0x17, 0x5c,
+ 0x00, 0x00, 0x17, 0xa8, 0x00, 0x00, 0x17, 0xf8, 0x00, 0x00, 0x18, 0x44, 0x00, 0x00, 0x18, 0x94, 0x00, 0x00, 0x18, 0xe0,
+ 0x00, 0x00, 0x19, 0x34, 0x00, 0x00, 0x19, 0x84, 0x00, 0x00, 0x19, 0xd0, 0x00, 0x00, 0x1a, 0x24, 0x00, 0x00, 0x1a, 0x78,
+ 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1b, 0x14, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0xb8, 0x00, 0x00, 0x1c, 0x08,
+ 0x00, 0x00, 0x1c, 0x5c, 0x00, 0x00, 0x1c, 0xa8, 0x00, 0x00, 0x1c, 0xf4, 0x00, 0x00, 0x1d, 0x40, 0x00, 0x00, 0x1d, 0x88,
+ 0x00, 0x00, 0x1d, 0xd4, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x78, 0x00, 0x00, 0x1e, 0xc0, 0x00, 0x00, 0x1f, 0x0c,
+ 0x00, 0x00, 0x1f, 0x58, 0x00, 0x00, 0x1f, 0xa8, 0x00, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x20, 0x44, 0x00, 0x00, 0x20, 0x90,
+ 0x00, 0x00, 0x20, 0xe0, 0x00, 0x00, 0x21, 0x2c, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x21, 0xd0, 0x00, 0x00, 0x22, 0x1c,
+ 0x00, 0x00, 0x22, 0x70, 0x00, 0x00, 0x22, 0xc4, 0x00, 0x00, 0x23, 0x14, 0x00, 0x00, 0x23, 0x60, 0x00, 0x00, 0x23, 0xb0,
+ 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x24, 0x54, 0x00, 0x00, 0x24, 0xa8, 0x00, 0x00, 0x24, 0xf4, 0x00, 0x00, 0x25, 0x40,
+ 0x00, 0x00, 0x25, 0x8c, 0x00, 0x00, 0x25, 0xd4, 0x00, 0x00, 0x26, 0x20, 0x00, 0x00, 0x26, 0x70, 0x00, 0x00, 0x26, 0xc4,
+ 0x00, 0x00, 0x27, 0x0c, 0x00, 0x00, 0x27, 0x58, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x27, 0xf4, 0x00, 0x00, 0x28, 0x40,
+ 0x00, 0x00, 0x28, 0x90, 0x00, 0x00, 0x28, 0xdc, 0x00, 0x00, 0x29, 0x2c, 0x00, 0x00, 0x29, 0x78, 0x00, 0x00, 0x29, 0xcc,
+ 0x00, 0x00, 0x2a, 0x1c, 0x00, 0x00, 0x2a, 0x68, 0x00, 0x00, 0x2a, 0xbc, 0x00, 0x00, 0x2b, 0x10, 0x00, 0x00, 0x2b, 0x60,
+ 0x00, 0x00, 0x2b, 0xac, 0x00, 0x00, 0x2b, 0xfc, 0x00, 0x00, 0x2c, 0x50, 0x00, 0x00, 0x2c, 0xa0, 0x00, 0x00, 0x2c, 0xf4,
+ 0x00, 0x00, 0x2d, 0x40, 0x00, 0x00, 0x2d, 0x8c, 0x00, 0x00, 0x2d, 0xd8, 0x00, 0x00, 0x2e, 0x20, 0x00, 0x00, 0x2e, 0x6c,
+ 0x00, 0x00, 0x2e, 0xbc, 0x00, 0x00, 0x2f, 0x10, 0x00, 0x00, 0x2f, 0x58, 0x00, 0x00, 0x2f, 0xa4, 0x00, 0x00, 0x2f, 0xf0,
+ 0x00, 0x00, 0x30, 0x40, 0x00, 0x00, 0x30, 0x90, 0x00, 0x00, 0x30, 0xdc, 0x00, 0x00, 0x31, 0x28, 0x00, 0x00, 0x31, 0x74,
+ 0x00, 0x00, 0x31, 0xc4, 0x00, 0x00, 0x32, 0x1c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+ 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+ 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x44, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x6f, 0x72,
+ 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x44, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x4c,
+ 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72,
+ 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4d, 0x6f, 0x64, 0x75,
+ 0x6c, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x41, 0x64, 0x64, 0x69, 0x6e, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x53, 0x53, 0x49, 0x44, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x64, 0x61, 0x74,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
+ 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
+ 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x1a,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e,
+ 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1b,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
+ 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x00, 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
+ 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x00, 0x67, 0x65, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x64, 0x65, 0x73, 0x63,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
+ 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x02, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6e, 0x65, 0x67, 0x61,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
+ 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x02, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x72, 0x76, 0x72,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
+ 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x02, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x6d, 0x64, 0x61, 0x74,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
+ 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x01, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x63, 0x72, 0x70,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d,
+ 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x69, 0x6e, 0x76, 0x69,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
+ 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x41,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x01, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
+ 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x46,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x80, 0x00, 0x00, 0x01, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a,
+ 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
+ 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x51,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c,
+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a,
+ 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c,
+ 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07,
+ 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53,
+ 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10,
+ 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
+ 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f,
+ 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
+ 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
+ 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x5f,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x19,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
+ 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
+ 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x65,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43,
+ 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d,
+ 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e,
+ 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d,
+ 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74,
+ 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
+ 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65,
+ 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08,
+ 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x81,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e,
+ 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x82,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e,
+ 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79,
+ 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74,
+ 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74,
+ 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61,
+ 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74,
+ 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72,
+ 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x96,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69,
+ 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f,
+ 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65,
+ 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x99,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1a,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x08, 0x43, 0x65, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x63, 0x65, 0x6e, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c,
+ 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x6c, 0x61, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
+ 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c,
+ 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
+ 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9f,
+ 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x80, 0x00, 0x10, 0x00, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x53, 0x75, 0x62, 0x6a,
+ 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00,
+ 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6e, 0x62, 0x72,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6b, 0x69, 0x64,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x64,
+ 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0xa3,
+ 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
+ 0x80, 0x00, 0x10, 0x00, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x50, 0x75, 0x62, 0x6c,
+ 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x03, 0x20,
+ 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51,
+ 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79,
+ 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd,
+ 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
+ 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed,
+ 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78, 0x74, 0x20, 0x70, 0x75,
+ 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e, 0x50, 0x10,
+ 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b, 0x07, 0x8c,
+ 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a, 0x6d, 0x4d,
+ 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83, 0xfb, 0x8d,
+ 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92, 0x6f, 0xda,
+ 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2, 0x58, 0x5b,
+ 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f, 0xcd, 0x4b,
+ 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8, 0x36, 0x7c,
+ 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6, 0x04, 0xe1,
+ 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2, 0x10, 0x2b,
+ 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31, 0xb0, 0x99,
+ 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6, 0x7c, 0x24,
+ 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42, 0x70, 0xf1,
+ 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d,
+ 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
+ 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
+ 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x51,
+ 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x79,
+ 0x00, 0x00, 0x02, 0x7d, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5,
+ 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
+ 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed,
+ 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0xfa, 0xde, 0x07, 0x11,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78,
+ 0x74, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, 0x39, 0x92, 0x01, 0x00, 0x00, 0x00,
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0, 0xb7, 0x97, 0x0d, 0x43,
+ 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8, 0xc9, 0xdd, 0x21, 0xb4,
+ 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48, 0x64, 0x41, 0x91, 0xf7,
+ 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7, 0xde, 0x62, 0x9f, 0x82,
+ 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f, 0xa8, 0x06, 0xc3, 0xe9,
+ 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25, 0xa5, 0x1a, 0xd0, 0x2a,
+ 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82, 0x3f, 0xa7, 0x6b, 0x64,
+ 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71, 0x30, 0x60, 0x21, 0x12,
+ 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d, 0x4b, 0x8a, 0xcd, 0x1d,
+ 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f, 0x1e, 0x3c, 0x63, 0x7a,
+ 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf, 0xa8, 0x1b, 0xf7, 0xbd,
+ 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0, 0x7e, 0x95, 0xd4, 0x0b,
+ 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80, 0xd2, 0x5f, 0x0c, 0x0b,
+ 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc,
+ 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31,
+ 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32,
+ 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x06, 0x54, 0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x07, 0xd8, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x48,
+ 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0xb8, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x09, 0x28, 0x00, 0x00, 0x09, 0x60,
+ 0x00, 0x00, 0x09, 0x98, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x98,
+ 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14,
+ 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
+ 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
+ 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee,
+ 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
+ 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d,
+ 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x07, 0xbc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97,
+ 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee,
+ 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x08, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xa8, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xe0, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x18,
+ 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x50, 0x00, 0x00, 0x09, 0x58,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x88, 0x00, 0x00, 0x09, 0x90, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0xc0, 0x00, 0x00, 0x09, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14, 0xa8,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x10, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01,
+ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x06, 0x15, 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x06, 0x1d, 0x00, 0x00, 0x06, 0x21,
+ 0x00, 0x00, 0x06, 0x25, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x06, 0x41, 0x00, 0x00, 0x06, 0x6d, 0x00, 0x00, 0x06, 0x71,
+ 0x00, 0x00, 0x06, 0x75, 0x00, 0x00, 0x06, 0x79, 0x00, 0x00, 0x06, 0x85, 0x00, 0x00, 0x06, 0x91, 0x00, 0x00, 0x06, 0x95,
+ 0x00, 0x00, 0x06, 0x99, 0x00, 0x00, 0x06, 0x9d, 0x00, 0x00, 0x06, 0xa1, 0x00, 0x00, 0x06, 0xa5, 0x00, 0x00, 0x06, 0xa9,
+ 0x00, 0x00, 0x06, 0xad, 0x00, 0x00, 0x06, 0xb1, 0x00, 0x00, 0x06, 0xb5, 0x00, 0x00, 0x06, 0xb9, 0x00, 0x00, 0x06, 0xbd,
+ 0x00, 0x00, 0x06, 0xc1, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x05, 0x7c,
+ 0xce, 0x5e, 0x64, 0x56, 0xc9, 0x2c, 0x8c, 0xbb, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4,
+ 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06,
+ 0x39, 0xf9, 0x47, 0x1e, 0xec, 0x0d, 0xb8, 0x07, 0x55, 0xbc, 0xbf, 0x6e, 0xd7, 0xa7, 0xc4, 0x53, 0x73, 0x06, 0xa9, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0xc0, 0x79, 0x0d, 0x4e, 0xd3, 0x15, 0x14, 0x9a, 0x46, 0xeb, 0x6d,
+ 0x81, 0xe0, 0xa8, 0x43, 0x02, 0x74, 0x53, 0x4b, 0x3a, 0x23, 0xf7, 0x6d, 0x16, 0x6f, 0x5d, 0x5a, 0xa9, 0x97, 0x54, 0x37,
+ 0xd0, 0x44, 0xd1, 0x9c, 0x15, 0x33, 0x05, 0xdb, 0x6b, 0xcb, 0x5c, 0xcd, 0x23, 0xc9, 0x65, 0x07, 0x79, 0x1b, 0x60, 0x2d,
+ 0xd6, 0x17, 0x2b, 0x45, 0x20, 0x8f, 0xb6, 0x31, 0x91, 0xc0, 0x59, 0x53, 0x87, 0xa0, 0x3c, 0xd1, 0x77, 0x97, 0x91, 0xd8,
+ 0x9c, 0xfc, 0x51, 0x4f, 0xfd, 0x21, 0x6a, 0x71, 0x12, 0x5a, 0x6e, 0x10, 0xd1, 0x5c, 0xe9, 0x7e, 0x24, 0xb8, 0xf3, 0x5d,
+ 0xab, 0x51, 0x2f, 0x67, 0xa7, 0x65, 0x5c, 0x27, 0xb8, 0xe2, 0x06, 0x98, 0xd2, 0x57, 0xb8, 0xc7, 0x4e, 0xea, 0x28, 0x23,
+ 0x6e, 0x90, 0x25, 0x2e, 0xb6, 0xf3, 0x5c, 0x18, 0xe8, 0x94, 0xa5, 0x7c, 0x55, 0xbf, 0x22, 0x94, 0xfc, 0x0e, 0xe7, 0x15,
+ 0xde, 0xe3, 0x72, 0x80, 0xe7, 0xf1, 0xfd, 0xd4, 0x0e, 0x2a, 0xda, 0x53, 0x56, 0xcb, 0xdb, 0xe3, 0x71, 0xc7, 0xc5, 0xd7,
+ 0x35, 0x95, 0x39, 0xf8, 0xee, 0x16, 0x22, 0x3c, 0x19, 0x3e, 0xd4, 0x03, 0x49, 0xe7, 0xf6, 0xb9, 0x50, 0x9f, 0x18, 0xee,
+ 0xdf, 0x7b, 0x79, 0xc4, 0x3f, 0xd4, 0x41, 0x45, 0xf2, 0xea, 0xdd, 0x5f, 0xda, 0x17, 0xd3, 0xb0, 0x50, 0xfc, 0x2c, 0xe9,
+ 0x6a, 0xb6, 0x35, 0xf3, 0xd7, 0xfd, 0xe6, 0x62, 0x51, 0x16, 0x5c, 0x8d, 0x26, 0xc3, 0x18, 0x9c, 0xf0, 0xb9, 0xe5, 0xa9,
+ 0x46, 0xd9, 0xe3, 0x80, 0x6c, 0xe3, 0x66, 0x70, 0xed, 0x4e, 0xfd, 0xf9, 0x8b, 0xdb, 0x06, 0x56, 0x3f, 0x2d, 0xfe, 0x74,
+ 0xee, 0x66, 0x75, 0x2a, 0xad, 0x1e, 0x41, 0x6c, 0x1b, 0x6a, 0xe4, 0x90, 0x76, 0x48, 0x27, 0x73, 0x4b, 0x13, 0xda, 0x72,
+ 0xa6, 0x7f, 0xc2, 0x7c, 0xb5, 0xca, 0x4c, 0x15, 0x64, 0x27, 0x9e, 0xc4, 0x9e, 0x3a, 0xb4, 0x13, 0x9d, 0xb8, 0x02, 0x3f,
+ 0x92, 0x6c, 0xe5, 0x73, 0x3e, 0x61, 0xbb, 0x01, 0xec, 0x81, 0x9b, 0x64, 0x59, 0x11, 0x4e, 0x42, 0x8b, 0x31, 0x97, 0x16,
+ 0x18, 0x53, 0x98, 0x82, 0x6e, 0xa5, 0x44, 0x7f, 0xcf, 0x05, 0x9c, 0x2c, 0x9d, 0x8f, 0xe3, 0x45, 0x57, 0xb2, 0xb5, 0x7a,
+ 0x71, 0x62, 0x25, 0x41, 0x8b, 0xed, 0xe9, 0x08, 0x46, 0x44, 0xda, 0xe3, 0xa3, 0xdf, 0x4b, 0x66, 0x77, 0x19, 0xc2, 0x4f,
+ 0xbb, 0xa7, 0xde, 0x4b, 0xa0, 0xbd, 0x95, 0x0f, 0xe1, 0x10, 0x49, 0x13, 0xa3, 0xec, 0x80, 0x27, 0xbb, 0x8b, 0xc8, 0xed,
+ 0x7a, 0x3a, 0x70, 0x5d, 0xea, 0x93, 0x6c, 0x0c, 0xc7, 0x2f, 0x41, 0x15, 0x64, 0x3d, 0x3a, 0x65, 0x02, 0x72, 0x78, 0xc9,
+ 0x35, 0x61, 0xe8, 0xd9, 0x63, 0x3f, 0x45, 0x7f, 0x04, 0xaf, 0x0b, 0x37, 0x7a, 0x66, 0x4e, 0x49, 0x3d, 0x6c, 0x3d, 0x2a,
+ 0xda, 0x0b, 0x81, 0x6d, 0x9f, 0x51, 0xea, 0xf6, 0x23, 0x6d, 0x7f, 0xcb, 0x75, 0x02, 0x49, 0x5e, 0x69, 0x57, 0x5b, 0x14,
+ 0xcb, 0xc2, 0xc8, 0xd4, 0xe4, 0x68, 0xab, 0xec, 0x51, 0x19, 0x80, 0xe4, 0xc1, 0xc7, 0x9b, 0x99, 0x15, 0xe1, 0x25, 0xf9,
+ 0x58, 0x18, 0x45, 0x0c, 0xde, 0xa7, 0x14, 0xe6, 0x96, 0xd5, 0xb8, 0x36, 0x83, 0x35, 0xfe, 0x77, 0x51, 0x4a, 0x57, 0x2e,
+ 0xaa, 0x26, 0x13, 0x23, 0x5d, 0x7d, 0xcf, 0x93, 0xce, 0x4a, 0x9a, 0xff, 0x03, 0x48, 0xf7, 0x10, 0x09, 0xe2, 0x01, 0xbb,
+ 0x17, 0xb6, 0x9d, 0xc7, 0x27, 0xe2, 0xd1, 0x26, 0xf1, 0x7c, 0xd0, 0x53, 0xf6, 0x53, 0x76, 0xfd, 0x39, 0x58, 0xd2, 0xc8,
+ 0xa8, 0x90, 0xa9, 0x75, 0x16, 0xaf, 0xe2, 0x91, 0x40, 0x53, 0x2e, 0x08, 0xdd, 0xb9, 0xfb, 0x17, 0x51, 0x51, 0x1b, 0xb9,
+ 0x12, 0xf0, 0x31, 0xd8, 0x48, 0x8f, 0x7d, 0x08, 0x9d, 0x1d, 0x2a, 0xb5, 0xcd, 0x46, 0x23, 0x2c, 0xf3, 0xb5, 0x11, 0x91,
+ 0x7f, 0x3c, 0x7a, 0x5e, 0x75, 0x90, 0x0e, 0xc0, 0xc0, 0x4f, 0x5e, 0xcb, 0xbc, 0x33, 0x09, 0x88, 0x4e, 0x68, 0xac, 0xba,
+ 0x46, 0x31, 0x41, 0x98, 0xf5, 0x75, 0x87, 0xf6, 0x0c, 0x0c, 0xaa, 0x84, 0x75, 0xe4, 0xfa, 0xa3, 0x1e, 0xe1, 0xe2, 0x88,
+ 0x09, 0xf0, 0x57, 0x8b, 0xdc, 0x47, 0x7b, 0xff, 0x39, 0xac, 0x51, 0x8b, 0x00, 0x08, 0xc0, 0x9f, 0xd4, 0xa4, 0xbe, 0xe5,
+ 0x41, 0x8b, 0xc5, 0x66, 0xdb, 0xed, 0x08, 0x0b, 0xdf, 0xa4, 0x2b, 0x5a, 0x59, 0xde, 0x0e, 0x9c, 0x8b, 0x7f, 0xd1, 0x80,
+ 0x4d, 0xf9, 0x22, 0x60, 0x2c, 0xd4, 0xf9, 0x1c, 0xd7, 0xf5, 0xbd, 0x64, 0x7f, 0x4f, 0xeb, 0xf8, 0xa5, 0xb2, 0x34, 0x3d,
+ 0xfa, 0x07, 0xef, 0x44, 0x3c, 0x00, 0x2c, 0xec, 0x36, 0x36, 0xdd, 0xd5, 0x5c, 0xbd, 0x6b, 0x27, 0xba, 0x13, 0x91, 0x90,
+ 0x58, 0xe7, 0x75, 0x89, 0x00, 0x6b, 0x5a, 0x0c, 0x35, 0x9c, 0xe3, 0x8a, 0xd8, 0x46, 0xd2, 0x15, 0x14, 0x8b, 0x8b, 0xff,
+ 0x6a, 0x35, 0xf9, 0xd7, 0x65, 0x67, 0x56, 0x6d, 0xd5, 0x2d, 0x9c, 0xd6, 0xb1, 0xe2, 0x9a, 0xb0, 0xfa, 0x0e, 0xa2, 0xd5,
+ 0x5d, 0x30, 0x15, 0x8e, 0x48, 0x59, 0xd0, 0x13, 0xa7, 0x2b, 0x40, 0x97, 0x8c, 0xe4, 0x02, 0x38, 0x28, 0x54, 0x53, 0x6c,
+ 0x1c, 0xc7, 0x38, 0x06, 0xe9, 0xfc, 0x2d, 0xd5, 0x59, 0x74, 0x77, 0x62, 0x14, 0xf2, 0xa7, 0x7e, 0xfe, 0x59, 0xbf, 0xdf,
+ 0x8b, 0x6e, 0xd7, 0x66, 0xd1, 0x6a, 0xb9, 0xe6, 0x35, 0x98, 0xc6, 0x76, 0x44, 0x38, 0xb4, 0xe8, 0x3c, 0xf5, 0x3c, 0x27,
+ 0xb9, 0xa1, 0x21, 0x7d, 0x17, 0xf9, 0xb3, 0x1e, 0x30, 0xe7, 0xab, 0xd5, 0x2d, 0x8c, 0x02, 0xc3, 0xa4, 0x3c, 0xf4, 0x09,
+ 0x9f, 0x17, 0xc1, 0xce, 0xc9, 0xf5, 0xdf, 0xdb, 0x8b, 0xf5, 0x05, 0x14, 0x6d, 0x74, 0xdf, 0xa9, 0x0b, 0x87, 0x98, 0x17,
+ 0xf3, 0x68, 0x8d, 0xb3, 0xbc, 0x86, 0x3a, 0x47, 0x1d, 0x29, 0x80, 0x40, 0xba, 0xb0, 0x3d, 0x65, 0x0d, 0xd7, 0x95, 0x4a,
+ 0x79, 0x0d, 0x34, 0x20, 0x72, 0x25, 0xaa, 0x71, 0x43, 0x5c, 0x52, 0x0b, 0x69, 0xde, 0xf7, 0xc5, 0xfd, 0xdb, 0x41, 0x05,
+ 0xb1, 0xde, 0x94, 0xdb, 0xc4, 0xe4, 0x85, 0xf2, 0x6c, 0xc5, 0xd1, 0x04, 0xcd, 0xd7, 0x84, 0x0b, 0xd8, 0xa8, 0x2c, 0x68,
+ 0xfd, 0xe7, 0x30, 0xaf, 0x6e, 0xae, 0x02, 0x3f, 0xea, 0x13, 0x68, 0xb0, 0xd1, 0xef, 0x6d, 0x78, 0xf8, 0x77, 0x3e, 0xe8,
+ 0x03, 0x05, 0x6e, 0x00, 0x59, 0xf1, 0xde, 0x57, 0xbe, 0xfa, 0x6b, 0xde, 0x47, 0x86, 0x21, 0xa0, 0x8e, 0xcc, 0x0b, 0x15,
+ 0x7e, 0x7d, 0xd2, 0x59, 0x37, 0x7f, 0x74, 0xc5, 0x79, 0x8e, 0xf0, 0x37, 0x9b, 0xb3, 0x0e, 0x7f, 0x14, 0x91, 0x0e, 0xe5,
+ 0xe8, 0xdf, 0xf7, 0xdf, 0x6b, 0x59, 0x79, 0x37, 0x90, 0x99, 0xc8, 0xff, 0xb2, 0xe9, 0xe4, 0x35, 0x8c, 0x20, 0xde, 0x8c,
+ 0x6c, 0xb8, 0x87, 0x16, 0xdd, 0xc4, 0x4b, 0x5e, 0x93, 0x38, 0x06, 0x0f, 0x4a, 0xb0, 0xba, 0xe1, 0xc5, 0xb1, 0x5d, 0x5f,
+ 0x3a, 0x2e, 0x84, 0x56, 0x72, 0x13, 0xb2, 0xb4, 0xdf, 0xc0, 0x36, 0xe6, 0xf2, 0xee, 0x77, 0x93, 0xc1, 0xc7, 0xc5, 0xe5,
+ 0x58, 0x66, 0x3e, 0x8c, 0x5d, 0xe3, 0x5d, 0xbd, 0x43, 0xf6, 0x72, 0x51, 0xe7, 0x4c, 0xd4, 0x2f, 0x46, 0x12, 0x66, 0xc2,
+ 0x7a, 0xd4, 0xd9, 0x75, 0x25, 0xa5, 0x63, 0x60, 0x9c, 0xc4, 0xff, 0x0a, 0xec, 0x8d, 0x13, 0x22, 0x3e, 0x95, 0xe8, 0xd9,
+ 0xd4, 0xa4, 0x12, 0xba, 0x46, 0x93, 0x1f, 0x6b, 0x9f, 0xb2, 0xba, 0xca, 0x39, 0xda, 0x32, 0xe5, 0x5c, 0xb3, 0x86, 0xc9,
+ 0x86, 0xb9, 0x9c, 0x92, 0x72, 0xe4, 0xa7, 0x53, 0xe4, 0x39, 0x07, 0x96, 0xc6, 0x18, 0xbc, 0xfc, 0x2e, 0x5f, 0xd6, 0x15,
+ 0x2c, 0x73, 0x01, 0x05, 0x74, 0xd7, 0x9a, 0x34, 0x35, 0x56, 0x32, 0xb7, 0x50, 0x22, 0x76, 0x66, 0x4d, 0x6f, 0xd1, 0x19,
+ 0x6a, 0x79, 0xc1, 0x3f, 0x15, 0x21, 0x04, 0x14, 0x34, 0xc9, 0x9a, 0xdb, 0x25, 0x0d, 0xfb, 0xa9, 0x53, 0xc0, 0x5f, 0xac,
+ 0xb7, 0xec, 0x67, 0xac, 0x8e, 0x46, 0x4c, 0xd7, 0x1b, 0x9b, 0x25, 0x87, 0x97, 0x73, 0xd9, 0xc8, 0xb3, 0x65, 0x22, 0x3b,
+ 0x35, 0xc0, 0x2f, 0xf5, 0x7d, 0xa4, 0x9b, 0x79, 0x92, 0xfb, 0xb6, 0x0b, 0xc9, 0xf9, 0x88, 0xc5, 0x5b, 0x88, 0x21, 0x0d,
+ 0xcf, 0xd9, 0x83, 0x6d, 0xae, 0x58, 0x3f, 0xac, 0x88, 0x16, 0xae, 0x3f, 0xb5, 0xdb, 0x78, 0x1c, 0x03, 0x3a, 0x19, 0xf1,
+ 0xbe, 0xc6, 0x46, 0x12, 0x6b, 0x18, 0x0b, 0x70, 0x83, 0x2d, 0x2f, 0x16, 0xac, 0xa9, 0x31, 0x2d, 0xf3, 0xe5, 0xd7, 0xe1,
+ 0x0e, 0x0e, 0x23, 0xb3, 0x9e, 0xc5, 0x6e, 0x35, 0xb7, 0xc4, 0x7f, 0xac, 0x60, 0x92, 0xde, 0x73, 0x3b, 0x02, 0xb6, 0xf5,
+ 0x97, 0xe6, 0xe1, 0x55, 0x50, 0x72, 0xd2, 0xb4, 0xbd, 0xcd, 0x7e, 0x11, 0xe4, 0x7b, 0x4b, 0xa5, 0x6b, 0x7e, 0xbf, 0xb8,
+ 0x4a, 0x1f, 0xf6, 0x34, 0x29, 0xee, 0x28, 0xb0, 0x45, 0x7d, 0x48, 0xc2, 0x18, 0xb2, 0x15, 0x0c, 0xe5, 0x5a, 0x3e, 0xee,
+ 0xdd, 0x1f, 0x20, 0x7b, 0xe6, 0x79, 0x60, 0xee, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d,
+ 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
+ 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
+ 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x00, 0x00, 0x09, 0x4d, 0x00, 0x00, 0x09, 0x61,
+ 0x00, 0x00, 0x09, 0x65, 0x00, 0x00, 0x09, 0x69, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x00, 0x09, 0x71, 0x00, 0x00, 0x09, 0x89,
+ 0x00, 0x00, 0x09, 0x8d, 0x00, 0x00, 0x09, 0xb9, 0x00, 0x00, 0x09, 0xbd, 0x00, 0x00, 0x09, 0xc1, 0x00, 0x00, 0x09, 0xc5,
+ 0x00, 0x00, 0x09, 0xd1, 0x00, 0x00, 0x09, 0xdd, 0x00, 0x00, 0x09, 0xe1, 0x00, 0x00, 0x09, 0xe5, 0x00, 0x00, 0x09, 0xe9,
+ 0x00, 0x00, 0x09, 0xed, 0x00, 0x00, 0x09, 0xf1, 0x00, 0x00, 0x09, 0xf5, 0x00, 0x00, 0x09, 0xf9, 0x00, 0x00, 0x09, 0xfd,
+ 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x09, 0x00, 0x00, 0x0a, 0x0d, 0xfa, 0xde, 0x07, 0x11,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x08, 0xc4, 0x7a, 0x50, 0x55, 0x75, 0xed, 0x3d, 0xfc, 0x68,
+ 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xb4, 0x4e, 0xa3, 0xa8, 0x86, 0x4f, 0x76, 0xe9,
+ 0x0f, 0x06, 0x2d, 0xca, 0x91, 0x26, 0x8e, 0x86, 0x1a, 0x1f, 0xb9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67,
+ 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae,
+ 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba, 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73,
+ 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76,
+ 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73,
+ 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e,
+ 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73,
+ 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae, 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba,
+ 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72,
+ 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61,
+ 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x10, 0x49, 0xe1, 0x42,
+ 0x39, 0xee, 0xe2, 0xbd, 0x76, 0x61, 0x00, 0x6f, 0xe5, 0xf4, 0xbe, 0xdb, 0xbc, 0x89, 0xbe, 0x56, 0x00, 0x00, 0x00, 0x44,
+ 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x4d, 0x61, 0x69, 0x6c, 0x2e, 0x61,
+ 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x61,
+ 0x69, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14,
+ 0x55, 0x29, 0x46, 0xa2, 0xfb, 0x92, 0xda, 0xe4, 0xf8, 0x4c, 0x7d, 0xdd, 0xc3, 0x4e, 0x52, 0x62, 0xff, 0x0f, 0xd2, 0x04,
+ 0x00, 0x00, 0x00, 0x40, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x2f, 0x72, 0x61, 0x63, 0x6f, 0x6f, 0x6e,
+ 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x72, 0x61,
+ 0x63, 0x6f, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+ 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00,
+ 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1d,
+ 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x61, 0x6e, 0x61,
+ 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00,
+ 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67,
+ 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x84, 0x5f, 0xda, 0x57, 0x4e, 0xc0, 0xb5, 0x32, 0xdf, 0xc4, 0x87, 0x7f, 0x8c, 0x04, 0x1f, 0x65, 0xa2, 0x23, 0x20, 0x8c,
+ 0xab, 0x49, 0x2f, 0xff, 0x12, 0xfa, 0x57, 0x33, 0xf8, 0xcb, 0x7a, 0xcd, 0xc4, 0x7b, 0xc0, 0xf6, 0xf7, 0xe7, 0x2f, 0x7d,
+ 0x3f, 0xec, 0xf5, 0x8a, 0xee, 0x1e, 0x26, 0xe9, 0x12, 0x96, 0xdb, 0xa2, 0x2a, 0xf6, 0xb9, 0x3c, 0x68, 0x14, 0x49, 0x86,
+ 0x00, 0xc0, 0xaa, 0x29, 0xd3, 0xad, 0x4b, 0x48, 0xca, 0x48, 0x3f, 0xdb, 0x36, 0xdd, 0x3d, 0x3b, 0x18, 0x59, 0x26, 0x2a,
+ 0x9e, 0x5f, 0x86, 0xe9, 0x4b, 0xaa, 0x83, 0x60, 0x20, 0x36, 0x1e, 0x59, 0x17, 0x33, 0x5b, 0x20, 0x42, 0x7a, 0x59, 0xfd,
+ 0xb3, 0xa2, 0x5f, 0x2b, 0xdb, 0x63, 0x7e, 0x66, 0xee, 0x5e, 0xf5, 0x22, 0x0c, 0x10, 0x61, 0xd3, 0x9e, 0x3d, 0xce, 0x62,
+ 0x6b, 0xc3, 0x97, 0x86, 0x68, 0x61, 0x2a, 0x31, 0xaa, 0x7d, 0x5d, 0x18, 0x1f, 0xe9, 0xc3, 0x12, 0xb7, 0x0d, 0x14, 0x84,
+ 0x5c, 0xa0, 0x84, 0x0c, 0x07, 0xef, 0x01, 0xf4, 0xd3, 0xa1, 0x14, 0xa8, 0x5a, 0xb8, 0x15, 0xb7, 0x1b, 0x7a, 0x4a, 0x12,
+ 0x2f, 0x9d, 0x8f, 0x79, 0xb1, 0x74, 0x3e, 0x50, 0xd5, 0x99, 0x9c, 0x26, 0x7d, 0x37, 0xaf, 0xc7, 0x7b, 0x15, 0x8c, 0x07,
+ 0xae, 0x74, 0xef, 0xc3, 0xb1, 0x6a, 0xa2, 0x76, 0xf9, 0x6d, 0x6e, 0xc2, 0x6a, 0x01, 0x9a, 0x5f, 0x23, 0xf4, 0xd5, 0xe3,
+ 0x6a, 0x34, 0x86, 0x1e, 0x9d, 0xed, 0x5c, 0x09, 0xd3, 0xba, 0xff, 0x2d, 0xbe, 0x4b, 0xbb, 0x6c, 0x6a, 0x20, 0xc9, 0x8b,
+ 0x51, 0xcd, 0x4c, 0x91, 0x51, 0x6d, 0xf5, 0x80, 0x42, 0x31, 0xc1, 0x3a, 0x10, 0xdc, 0xb4, 0x92, 0x97, 0x18, 0xcc, 0x26,
+ 0xf1, 0xe6, 0x18, 0xe1, 0x97, 0x21, 0x94, 0x3d, 0xca, 0xa7, 0xb5, 0xcd, 0xce, 0x53, 0x7b, 0x16, 0x0b, 0x80, 0x8d, 0x4c,
+ 0xc8, 0x28, 0xc8, 0x55, 0xcf, 0xc7, 0xba, 0xd1, 0x05, 0x6a, 0x66, 0x72, 0x51, 0xb2, 0xd4, 0x3d, 0x81, 0x8d, 0xc5, 0xb3,
+ 0x86, 0xa6, 0x02, 0x53, 0x16, 0x2a, 0x2a, 0x40, 0xf1, 0x8d, 0xff, 0x42, 0x9a, 0x12, 0xd2, 0x46, 0x1d, 0x42, 0x98, 0x1f,
+ 0x1c, 0x52, 0x3f, 0x11, 0xa7, 0x12, 0xa7, 0xba, 0xb7, 0x84, 0xba, 0x80, 0xdf, 0x3e, 0x89, 0xcd, 0x81, 0x05, 0x98, 0x0a,
+ 0x92, 0x3e, 0x4b, 0x61, 0x44, 0x2f, 0xb8, 0xfe, 0x86, 0x56, 0x6b, 0xe1, 0xc0, 0xb4, 0x09, 0x52, 0x6c, 0xb2, 0xff, 0x1f,
+ 0xe7, 0x74, 0x98, 0xb6, 0x65, 0x47, 0x31, 0x5a, 0x33, 0x3a, 0x8c, 0x05, 0x18, 0xa5, 0x25, 0xc6, 0xb7, 0x18, 0x29, 0xf9,
+ 0x87, 0x7c, 0x3c, 0x3d, 0x70, 0x56, 0x60, 0xfe, 0x0c, 0xb9, 0x17, 0x89, 0xa0, 0x72, 0xe6, 0xa5, 0x2f, 0xa6, 0xa9, 0xc4,
+ 0x34, 0x5a, 0xbe, 0x0d, 0xa5, 0xf3, 0xac, 0xe8, 0x69, 0xa8, 0x2e, 0x50, 0xa2, 0xc1, 0x99, 0x7e, 0x7c, 0xd2, 0xd7, 0x60,
+ 0x1b, 0x41, 0xe4, 0x1f, 0x76, 0x5c, 0xeb, 0x1b, 0x28, 0x53, 0xd3, 0xab, 0x48, 0xd0, 0x7f, 0xb8, 0x9d, 0x70, 0x39, 0x8a,
+ 0xcd, 0x3c, 0x0f, 0x03, 0x5e, 0xe8, 0xa9, 0x95, 0x60, 0x54, 0x93, 0xfa, 0xd1, 0x9b, 0x49, 0xdb, 0x34, 0x32, 0x36, 0x38,
+ 0x56, 0xbb, 0xbf, 0xcf, 0x54, 0xe6, 0x5c, 0xa2, 0x8a, 0x9e, 0x73, 0x83, 0xa0, 0x53, 0x71, 0xfd, 0xef, 0x49, 0x1a, 0xa7,
+ 0x06, 0xca, 0x90, 0xd5, 0x2f, 0x31, 0xb4, 0x52, 0x0f, 0xaf, 0xfe, 0x6c, 0x19, 0x6d, 0xca, 0x11, 0xaa, 0xaf, 0x24, 0x21,
+ 0x47, 0x7f, 0x15, 0x47, 0x51, 0x96, 0x59, 0x3b, 0x27, 0x13, 0xc6, 0x50, 0x7b, 0x1c, 0x84, 0x0d, 0x61, 0x3d, 0x51, 0x58,
+ 0x9c, 0xe4, 0x65, 0x06, 0x1f, 0x7b, 0x91, 0x98, 0x7d, 0x35, 0x8c, 0x9f, 0xba, 0x38, 0x90, 0x89, 0xa2, 0xae, 0x68, 0x68,
+ 0x4b, 0x11, 0x2f, 0xea, 0x4d, 0xcb, 0x01, 0x59, 0x94, 0x26, 0x52, 0x37, 0x01, 0x6e, 0xfb, 0x01, 0x8b, 0x61, 0x59, 0x5b,
+ 0x49, 0xdf, 0xf2, 0x1c, 0x48, 0xbc, 0xed, 0x98, 0x8f, 0x09, 0x38, 0xa2, 0xf8, 0x27, 0xbb, 0x1a, 0x04, 0xcf, 0xd0, 0x4a,
+ 0x93, 0x32, 0xb8, 0x9d, 0x2f, 0x9c, 0xf3, 0xb2, 0xa8, 0x56, 0x47, 0xff, 0xa1, 0x28, 0x60, 0x6b, 0xc2, 0x3c, 0x1b, 0x48,
+ 0x5d, 0xc9, 0x05, 0x39, 0x98, 0xe5, 0x98, 0xfb, 0x17, 0x3f, 0x6d, 0x41, 0x8d, 0xc5, 0xa1, 0xee, 0x31, 0x19, 0x00, 0x2d,
+ 0xfb, 0x1e, 0x8f, 0x5f, 0x72, 0x6a, 0x92, 0x64, 0x01, 0xad, 0xcc, 0x90, 0x14, 0x48, 0x83, 0x88, 0x2e, 0xc1, 0x58, 0xe5,
+ 0x33, 0xa4, 0x19, 0xc3, 0x1d, 0xee, 0x06, 0xb6, 0x96, 0xb7, 0x57, 0x04, 0xa5, 0x4a, 0xa0, 0xa5, 0x1b, 0xa5, 0xda, 0x91,
+ 0xb7, 0x2c, 0xcd, 0x6d, 0x81, 0xff, 0x9f, 0xac, 0xc9, 0x05, 0x26, 0x8f, 0xb2, 0x37, 0x3c, 0xb8, 0x53, 0xab, 0x2b, 0xaf,
+ 0x9e, 0x22, 0xd2, 0xcd, 0xf4, 0x65, 0xf3, 0x84, 0x68, 0x83, 0xc2, 0xf8, 0xb7, 0x05, 0x25, 0xfe, 0x08, 0x2c, 0xb2, 0xb4,
+ 0xf3, 0x95, 0x63, 0x9a, 0xcc, 0x9d, 0xb1, 0xee, 0x5c, 0x53, 0x3b, 0x6b, 0xab, 0x0e, 0x95, 0x50, 0xcc, 0x8e, 0xc3, 0x97,
+ 0x43, 0x67, 0xe5, 0x49, 0xd0, 0x20, 0xbd, 0xda, 0x45, 0x6c, 0xef, 0x9a, 0xc7, 0x47, 0xdc, 0x7f, 0xda, 0xab, 0xf2, 0x8a,
+ 0xc5, 0x4f, 0xc5, 0xdb, 0xba, 0x87, 0x5f, 0xc1, 0xe0, 0x12, 0xc0, 0xb1, 0x3e, 0x1b, 0x72, 0x34, 0x00, 0x9f, 0x0a, 0xb4,
+ 0x99, 0xf8, 0x33, 0xe7, 0xb7, 0xc6, 0xc0, 0xed, 0xe6, 0x2c, 0x1b, 0x29, 0x9c, 0xfd, 0xeb, 0x6f, 0x9b, 0x0a, 0x55, 0xd2,
+ 0x09, 0xa2, 0x64, 0x49, 0x39, 0x30, 0x33, 0xb2, 0x77, 0x31, 0x32, 0x81, 0x25, 0x58, 0x66, 0x4d, 0xd2, 0xc2, 0xa6, 0x18,
+ 0xdc, 0xfc, 0x0a, 0x73, 0x5f, 0xbc, 0xcc, 0xef, 0xfe, 0xee, 0x1d, 0x3d, 0xb8, 0x21, 0xfb, 0x52, 0x25, 0x6f, 0xc3, 0x99,
+ 0x67, 0xa1, 0x69, 0x20, 0xb3, 0x01, 0xb4, 0x75, 0xbe, 0x08, 0x49, 0x2e, 0xe3, 0x6f, 0x1a, 0xd0, 0xe9, 0x7c, 0xec, 0xbf,
+ 0x98, 0x45, 0x82, 0xf8, 0xc4, 0x77, 0x74, 0x20, 0xc9, 0x5f, 0xa1, 0x8b, 0xf4, 0xa8, 0x4d, 0x12, 0xd5, 0x92, 0xd1, 0xe1,
+ 0x42, 0x4b, 0xa2, 0x45, 0x18, 0x60, 0xaf, 0x9a, 0xf2, 0xe4, 0xcf, 0x3e, 0x66, 0x87, 0x12, 0x0e, 0xa7, 0x55, 0x53, 0x96,
+ 0xcb, 0xcf, 0xd3, 0x34, 0xab, 0xdd, 0x20, 0x0f, 0x62, 0x9a, 0xb4, 0x86, 0x2f, 0x9f, 0x01, 0xda, 0xd6, 0xe6, 0x2b, 0xe2,
+ 0x5b, 0xb9, 0x74, 0xd8, 0x28, 0xad, 0x94, 0x89, 0x3e, 0x3a, 0x2a, 0x82, 0xa2, 0x0a, 0x7b, 0x4b, 0x4f, 0x3f, 0xed, 0x7f,
+ 0x2a, 0x3a, 0x06, 0xc8, 0xd4, 0x65, 0xcd, 0x60, 0x19, 0x79, 0x36, 0x31, 0x4c, 0xc1, 0x1e, 0x55, 0x22, 0x4f, 0x6e, 0xe0,
+ 0x1b, 0xab, 0x0b, 0x49, 0xa8, 0x9f, 0xf9, 0xc9, 0x6c, 0xd4, 0xd6, 0xfa, 0x07, 0xcd, 0xf5, 0xe7, 0x94, 0x51, 0x1b, 0x3d,
+ 0xc5, 0x00, 0x79, 0x38, 0xaf, 0xc0, 0x23, 0x60, 0x2b, 0x92, 0xda, 0x76, 0x69, 0xf7, 0xda, 0x23, 0xf9, 0xa6, 0x21, 0x34,
+ 0xc6, 0xf3, 0xc3, 0x69, 0xa6, 0x25, 0x87, 0x70, 0x5c, 0x0c, 0xc1, 0xfc, 0x9c, 0x30, 0xbc, 0xdf, 0x26, 0xbe, 0x4b, 0x49,
+ 0x44, 0xdd, 0x2f, 0x21, 0xc1, 0xa8, 0xcd, 0x54, 0x7a, 0xa4, 0x1b, 0xae, 0x82, 0xce, 0x05, 0x50, 0x9c, 0xb6, 0x85, 0x5d,
+ 0xf9, 0xbd, 0xdd, 0x4a, 0x56, 0x51, 0x32, 0x50, 0xdd, 0xaa, 0x55, 0xfe, 0x26, 0x3c, 0xee, 0x36, 0xa4, 0xa8, 0x53, 0x66,
+ 0x72, 0x89, 0xf6, 0xa3, 0x25, 0x7a, 0x23, 0x53, 0x29, 0x4d, 0x34, 0x29, 0x62, 0x94, 0x4f, 0x4f, 0x1b, 0x53, 0xcb, 0xc1,
+ 0x7c, 0xd1, 0x50, 0x8e, 0xa3, 0x19, 0x89, 0xfa, 0x90, 0x42, 0x69, 0x16, 0xd0, 0x6f, 0xf8, 0x7a, 0xc2, 0x9e, 0x67, 0xe8,
+ 0xe8, 0xff, 0xf1, 0x61, 0x7b, 0x31, 0x19, 0xcf, 0xf1, 0x27, 0xee, 0xab, 0x63, 0xe8, 0xdb, 0xf7, 0x4c, 0xbf, 0xcf, 0x2f,
+ 0xe7, 0x83, 0x92, 0xf8, 0x6d, 0x15, 0x9e, 0x1d, 0x77, 0xef, 0x40, 0x79, 0x58, 0xe4, 0xf9, 0xa7, 0x3d, 0xb6, 0x2d, 0xd0,
+ 0xfc, 0x01, 0x66, 0x20, 0x2c, 0xd1, 0x29, 0x86, 0x9b, 0x88, 0xcd, 0x98, 0xb4, 0x66, 0x61, 0x94, 0x58, 0x56, 0xf4, 0xff,
+ 0x60, 0x90, 0xf2, 0x8c, 0x07, 0x1c, 0x0b, 0x13, 0xfe, 0xb6, 0x58, 0x15, 0x6a, 0x8a, 0xd7, 0x98, 0xb2, 0x3e, 0xee, 0x49,
+ 0xdb, 0x3a, 0x0f, 0x98, 0x27, 0xc6, 0x88, 0xc5, 0x15, 0xe5, 0x67, 0x08, 0x09, 0xfc, 0x63, 0x6c, 0x8f, 0x30, 0xf4, 0x95,
+ 0xb7, 0x69, 0xd4, 0x47, 0x93, 0xe5, 0xa6, 0xf9, 0x73, 0xdd, 0x98, 0xb4, 0x66, 0x02, 0x1f, 0x3b, 0xe7, 0x53, 0x9f, 0x54,
+ 0x44, 0x0b, 0x9b, 0xdb, 0xe8, 0xaa, 0x77, 0xc3, 0x89, 0x65, 0x12, 0xb2, 0xc5, 0x2f, 0x5e, 0xaa, 0xff, 0xab, 0x72, 0x1f,
+ 0xf1, 0xd3, 0xdc, 0x8f, 0xaf, 0x13, 0x31, 0xaa, 0x5d, 0x48, 0x5a, 0x1b, 0x31, 0x61, 0x0b, 0x48, 0x9b, 0xe6, 0x75, 0x2e,
+ 0xd5, 0xdb, 0xd3, 0x22, 0xb5, 0x77, 0x9b, 0x45, 0xc2, 0x9d, 0x1b, 0xe2, 0x2b, 0x8c, 0x14, 0x99, 0x10, 0x7c, 0x24, 0x18,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67,
+ 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97,
+ 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61,
+ 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30,
+ 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x11, 0x2c, 0x00, 0x00, 0x12, 0x50, 0x00, 0x00, 0x12, 0xb0,
+ 0x00, 0x00, 0x12, 0xe8, 0x00, 0x00, 0x13, 0x20, 0x00, 0x00, 0x13, 0x58, 0x00, 0x00, 0x13, 0x90, 0x00, 0x00, 0x13, 0xc8,
+ 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x38, 0x00, 0x00, 0x14, 0x70, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x70, 0x00, 0x00, 0x11, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5,
+ 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
+ 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
+ 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14,
+ 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
+ 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
+ 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0x78, 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8,
+ 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14,
+ 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65,
+ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0xd8, 0x00, 0x00, 0x12, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x13, 0x10, 0x00, 0x00, 0x13, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x48,
+ 0x00, 0x00, 0x13, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x80, 0x00, 0x00, 0x13, 0x88,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xb8, 0x00, 0x00, 0x13, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xf0, 0x00, 0x00, 0x13, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x14, 0x28, 0x00, 0x00, 0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x60,
+ 0x00, 0x00, 0x14, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x98, 0x00, 0x00, 0x14, 0xa0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1e, 0xbc, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x15, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x02, 0xf8,
+ 0x00, 0x00, 0x05, 0xe4, 0x00, 0x00, 0x08, 0xa4, 0x00, 0x00, 0x0e, 0xfc, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x11, 0xe4,
+ 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5, 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15,
+ 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d,
+ 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d, 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81,
+ 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d,
+ 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1,
+ 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70, 0xea, 0x6d, 0x4d, 0x2b, 0x42, 0xd6, 0x1d, 0xa7, 0x00, 0x00, 0x00, 0x02,
+ 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x59, 0x1b, 0x38, 0x6f, 0x83, 0xff, 0xcf, 0x13, 0x00, 0xc5, 0x58, 0x14,
+ 0x81, 0x60, 0xd5, 0xf2, 0x76, 0x2d, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25,
+ 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe5, 0x1f, 0x40, 0x4b, 0xde, 0x16, 0xe0, 0x41,
+ 0xc5, 0xdc, 0x68, 0x83, 0xfb, 0x0f, 0x7b, 0xad, 0x62, 0x9d, 0xa3, 0xee, 0xea, 0xa9, 0x6b, 0x27, 0x69, 0x1e, 0xea, 0xc7,
+ 0x1c, 0xf7, 0x06, 0xa5, 0x76, 0xcd, 0x9d, 0x65, 0x3c, 0xb1, 0x30, 0x6a, 0x30, 0xd1, 0x31, 0xbd, 0x8a, 0x19, 0x90, 0x89,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0,
+ 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0,
+ 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
+ 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
+ 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x25, 0x00, 0x00, 0x02, 0x3d,
+ 0x00, 0x00, 0x02, 0x41, 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x65,
+ 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1,
+ 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5,
+ 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
+ 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0xfa, 0xde, 0x07, 0x11,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x6c, 0x00, 0x00, 0x01, 0x9c, 0x8b, 0x41, 0x4a, 0x57, 0xa6, 0xf2, 0x36, 0xc2,
+ 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x9a, 0xfe, 0xce, 0x76, 0xf7, 0x40, 0x3a, 0x9f,
+ 0xd2, 0xc5, 0x69, 0x65, 0x60, 0xea, 0x1a, 0x98, 0xc7, 0xed, 0x28, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65,
+ 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63,
+ 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c,
+ 0x00, 0x00, 0x0c, 0x00, 0x00, 0x5a, 0x4c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73,
+ 0x83, 0x67, 0xc1, 0x00, 0xdf, 0x03, 0x66, 0xb0, 0xbb, 0x20, 0xb3, 0x39, 0x84, 0xf0, 0x07, 0xc3, 0x17, 0x75, 0x8a, 0x1b,
+ 0xce, 0x2a, 0xb7, 0xc3, 0x31, 0xd7, 0xea, 0xba, 0xa4, 0x38, 0xf5, 0x78, 0x94, 0xa5, 0xff, 0x08, 0x6d, 0x36, 0x41, 0xa5,
+ 0x8d, 0x6e, 0xf7, 0x55, 0x1f, 0x6f, 0xe9, 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
+ 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
+ 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31,
+ 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32,
+ 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5,
+ 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15, 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d,
+ 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d,
+ 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91,
+ 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5,
+ 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9,
+ 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70,
+ 0x44, 0x1d, 0x55, 0x6f, 0xda, 0x1b, 0x4a, 0x43, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4,
+ 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06,
+ 0x23, 0x07, 0xb7, 0x3f, 0xb3, 0x23, 0xad, 0xb2, 0xa9, 0x7f, 0x10, 0x8b, 0x76, 0x89, 0x68, 0x1b, 0x42, 0xb4, 0x45, 0x98,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b,
+ 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xc5, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x23, 0xe5, 0x14, 0x64, 0x77, 0x35, 0x5f, 0x79, 0x3e, 0x4c, 0x4d, 0x5e, 0xee, 0xa7, 0x26, 0x39, 0x7d,
+ 0x28, 0x18, 0xd5, 0xf5, 0x08, 0x07, 0x99, 0x37, 0xb1, 0xea, 0x83, 0x7c, 0xbc, 0xeb, 0x64, 0x47, 0xc6, 0xe1, 0x82, 0xfe,
+ 0x1f, 0x20, 0x67, 0x1e, 0x37, 0x92, 0x57, 0xaa, 0xbe, 0x4f, 0xac, 0x5f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14,
+ 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
+ 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
+ 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5c,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5,
+ 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x03, 0x05,
+ 0x00, 0x00, 0x03, 0x09, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x29,
+ 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39, 0x00, 0x00, 0x03, 0x3d,
+ 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0x00, 0x00, 0x03, 0x4d, 0x00, 0x00, 0x03, 0x51,
+ 0x00, 0x00, 0x03, 0x55, 0x00, 0x00, 0x03, 0x59, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xdc,
+ 0x00, 0x00, 0x02, 0x0c, 0x52, 0x60, 0x55, 0x9c, 0x4a, 0x26, 0x30, 0x1b, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2,
+ 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x06, 0x93, 0x56, 0x67, 0xd4, 0x00, 0x07, 0x17, 0xac, 0xc1, 0xbd, 0xea, 0x93, 0x3b, 0xd3, 0x28, 0xa0,
+ 0x57, 0xe5, 0x77, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c,
+ 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x74,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x9d, 0x01, 0xd2, 0x67, 0xcc, 0xce, 0x6d, 0x38, 0xee, 0x87, 0xc1, 0xcc,
+ 0x32, 0xbb, 0xee, 0x47, 0xfa, 0x77, 0x9b, 0xdf, 0x00, 0x00, 0x00, 0x44, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x62, 0x69, 0x6e,
+ 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x63, 0x6f, 0x6d, 0x2e,
+ 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69, 0x63,
+ 0x74, 0x69, 0x76, 0x65, 0xad, 0xa7, 0xd1, 0x01, 0x67, 0x9c, 0xc4, 0xea, 0xc3, 0xdf, 0x8e, 0xc4, 0x08, 0x5b, 0x35, 0x71,
+ 0x96, 0xc4, 0xb0, 0x57, 0x19, 0x46, 0xb5, 0x63, 0xce, 0xbb, 0x8e, 0xe7, 0x35, 0x53, 0x02, 0xe2, 0xb2, 0x8d, 0xfa, 0xf4,
+ 0x08, 0xdd, 0x5f, 0xda, 0x2e, 0x3e, 0xf4, 0x8c, 0x14, 0x02, 0xe2, 0x53, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14,
+ 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
+ 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
+ 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfc,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x29, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51,
+ 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79, 0x00, 0x00, 0x02, 0xa5,
+ 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc9,
+ 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x02, 0xdd,
+ 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, 0x00, 0x00, 0x02, 0xf1,
+ 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x7c,
+ 0x00, 0x00, 0x01, 0xa4, 0x3b, 0xaf, 0x30, 0xf6, 0xce, 0x08, 0x47, 0xad, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2,
+ 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xcf,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x06, 0xeb, 0x22, 0x2e, 0xd0, 0xa1, 0x2a, 0x8b, 0xd2, 0x11, 0xac, 0x9f, 0x5b, 0x27, 0x35, 0x5d, 0xd8,
+ 0x58, 0x6d, 0x84, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0x8c, 0xbf,
+ 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a,
+ 0x76, 0x25, 0x8c, 0xbf, 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x01, 0x01, 0x00, 0x00, 0xc2, 0xa8, 0x12, 0x5f, 0x3d, 0xc2, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0xc2, 0x8c, 0xc2, 0xbf,
+ 0x1f, 0x58, 0xc3, 0x8b, 0x76, 0xc3, 0x96, 0xc2, 0xbb, 0xc3, 0xbf, 0xc2, 0xb1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3,
+ 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26,
+ 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe6, 0x50, 0x17, 0x0a, 0x9f, 0xb9, 0xab, 0x61, 0x5d, 0x77, 0x39, 0x8b,
+ 0x76, 0x2d, 0x3f, 0x20, 0xb2, 0xec, 0x7c, 0xbc, 0xa1, 0x54, 0xac, 0x1b, 0x1c, 0x6d, 0x6b, 0x88, 0x3b, 0xd2, 0x7b, 0x6b,
+ 0x24, 0x84, 0x7c, 0xca, 0xc7, 0xe8, 0x66, 0x8e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x18, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+ 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61,
+ 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30,
+ 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x41,
+ 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x65,
+ 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa9,
+ 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5,
+ 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
+ 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0xa8, 0xf4, 0x8e, 0xca, 0x78, 0x14, 0xb8, 0x41, 0x73, 0x00, 0x00, 0x00, 0x02,
+ 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21,
+ 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x72, 0x3a, 0x27, 0x07, 0x00, 0xae, 0x19, 0xfc, 0x71, 0x1c, 0x6f, 0x2f,
+ 0xe2, 0x2b, 0x78, 0x9a, 0xdc, 0x88, 0xc1, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e, 0x94, 0x1b, 0x4d, 0x42,
+ 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e,
+ 0x94, 0x1b, 0x4d, 0x42, 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff,
+ 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc3, 0x89, 0x22, 0xc3, 0x9f, 0x1e, 0xc2, 0x94,
+ 0x1b, 0x4d, 0x42, 0x21, 0x42, 0xc2, 0x85, 0xc3, 0x8d, 0x32, 0xc3, 0xac, 0xc3, 0xa5, 0xc3, 0x97, 0xc3, 0xb9, 0x61, 0x38,
+ 0xc3, 0xa1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0x4d,
+ 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x7b, 0x74, 0x34, 0xf2,
+ 0x79, 0x55, 0x24, 0x13, 0xc5, 0x6c, 0xdd, 0xe2, 0xe7, 0xd5, 0xbf, 0x4e, 0xaa, 0xc8, 0x50, 0xa3, 0xc6, 0x46, 0x67, 0x62,
+ 0x08, 0x04, 0x0d, 0xe7, 0x54, 0xe1, 0xb5, 0x0a, 0x53, 0x0d, 0x90, 0xbc, 0xd7, 0x2e, 0x5f, 0x6d, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x08, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
+ 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
+ 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x85, 0x00, 0x00, 0x02, 0x9d,
+ 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xc5,
+ 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0x00, 0x00, 0x03, 0x01,
+ 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x19, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x21, 0x00, 0x00, 0x03, 0x25,
+ 0x00, 0x00, 0x03, 0x29, 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39,
+ 0x00, 0x00, 0x03, 0x3d, 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0xfa, 0xde, 0x07, 0x11,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x01, 0xfc, 0x1a, 0xe7, 0x86, 0xc7, 0x8e, 0x0c, 0x7b, 0xed,
+ 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xbb, 0x34, 0xae, 0xf4, 0x96, 0x00, 0x3a, 0xa9,
+ 0x6c, 0x3b, 0x6c, 0xa6, 0x1b, 0xa0, 0xfd, 0x0d, 0x0b, 0x7b, 0xc1, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f,
+ 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x50, 0x81, 0xee, 0xbe, 0x1f, 0x36, 0xff, 0x64,
+ 0xa1, 0x66, 0x43, 0xd7, 0xdc, 0x0e, 0x61, 0xf0, 0x17, 0xaf, 0x60, 0x35, 0x00, 0x00, 0x00, 0x60, 0x2f, 0x41, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f,
+ 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x00,
+ 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61,
+ 0x69, 0x6e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xb8, 0x58, 0xf2, 0xef,
+ 0xb1, 0x4e, 0x1e, 0x2e, 0x15, 0xe0, 0x0f, 0xb5, 0xea, 0xd4, 0xf5, 0x1e, 0x45, 0x79, 0x80, 0x58, 0xe2, 0xb2, 0x93, 0xf6,
+ 0x1c, 0xbf, 0x8c, 0x2b, 0x1d, 0xdb, 0xed, 0x58, 0xd3, 0x90, 0x91, 0xfd, 0x86, 0xbe, 0x01, 0xdd, 0x76, 0x36, 0x01, 0xf0,
+ 0x1a, 0x4f, 0xd8, 0x7d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56,
+ 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56,
+ 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
+ 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d,
+ 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x8c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x15, 0x64,
+ 0x00, 0x00, 0x18, 0xe0, 0x00, 0x00, 0x19, 0xf4, 0x00, 0x00, 0x1a, 0x7c, 0x00, 0x00, 0x1b, 0x04, 0x00, 0x00, 0x1b, 0x8c,
+ 0x00, 0x00, 0x1c, 0x14, 0x00, 0x00, 0x1c, 0x9c, 0x00, 0x00, 0x1d, 0x24, 0x00, 0x00, 0x1d, 0xac, 0x00, 0x00, 0x1e, 0x34,
+ 0x00, 0x00, 0x03, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x15, 0xd0, 0x00, 0x00, 0x16, 0x44,
+ 0x00, 0x00, 0x16, 0xb4, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x17, 0x94, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x18, 0x74,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x17, 0x72, 0x65, 0x73, 0x74,
+ 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
+ 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
+ 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76,
+ 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
+ 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d,
+ 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
+ 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f,
+ 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61,
+ 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30,
+ 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
+ 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31,
+ 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32,
+ 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0,
+ 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
+ 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
+ 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14,
+ 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
+ 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
+ 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
+ 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
+ 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x19, 0x30,
+ 0x00, 0x00, 0x19, 0x50, 0x00, 0x00, 0x19, 0x6c, 0x00, 0x00, 0x19, 0x88, 0x00, 0x00, 0x19, 0xa4, 0x00, 0x00, 0x19, 0xc0,
+ 0x00, 0x00, 0x19, 0xdc, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x17,
+ 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76,
+ 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14,
+ 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9,
+ 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
+ 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6,
+ 0xdf, 0x25, 0xe4, 0x2d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0x44, 0x00, 0x00, 0x1a, 0x4c,
+ 0x00, 0x00, 0x1a, 0x54, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x64, 0x00, 0x00, 0x1a, 0x6c, 0x00, 0x00, 0x1a, 0x74,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0xcc, 0x00, 0x00, 0x1a, 0xd4, 0x00, 0x00, 0x1a, 0xdc,
+ 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1a, 0xec, 0x00, 0x00, 0x1a, 0xf4, 0x00, 0x00, 0x1a, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1b, 0x54, 0x00, 0x00, 0x1b, 0x5c, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0x6c,
+ 0x00, 0x00, 0x1b, 0x74, 0x00, 0x00, 0x1b, 0x7c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x1b, 0xdc, 0x00, 0x00, 0x1b, 0xe4, 0x00, 0x00, 0x1b, 0xec, 0x00, 0x00, 0x1b, 0xf4, 0x00, 0x00, 0x1b, 0xfc,
+ 0x00, 0x00, 0x1c, 0x04, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0x64,
+ 0x00, 0x00, 0x1c, 0x6c, 0x00, 0x00, 0x1c, 0x74, 0x00, 0x00, 0x1c, 0x7c, 0x00, 0x00, 0x1c, 0x84, 0x00, 0x00, 0x1c, 0x8c,
+ 0x00, 0x00, 0x1c, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0xec, 0x00, 0x00, 0x1c, 0xf4,
+ 0x00, 0x00, 0x1c, 0xfc, 0x00, 0x00, 0x1d, 0x04, 0x00, 0x00, 0x1d, 0x0c, 0x00, 0x00, 0x1d, 0x14, 0x00, 0x00, 0x1d, 0x1c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0x74, 0x00, 0x00, 0x1d, 0x7c, 0x00, 0x00, 0x1d, 0x84,
+ 0x00, 0x00, 0x1d, 0x8c, 0x00, 0x00, 0x1d, 0x94, 0x00, 0x00, 0x1d, 0x9c, 0x00, 0x00, 0x1d, 0xa4, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0xfc, 0x00, 0x00, 0x1e, 0x04, 0x00, 0x00, 0x1e, 0x0c, 0x00, 0x00, 0x1e, 0x14,
+ 0x00, 0x00, 0x1e, 0x1c, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88,
+ 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x1e, 0x84, 0x00, 0x00, 0x1e, 0x8c, 0x00, 0x00, 0x1e, 0x94, 0x00, 0x00, 0x1e, 0x9c, 0x00, 0x00, 0x1e, 0xa4,
+ 0x00, 0x00, 0x1e, 0xac, 0x00, 0x00, 0x1e, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xdc, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
+ 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xf5,
+ 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
+ 0x4a, 0x16, 0x48, 0x81, 0x4a, 0xfb, 0x22, 0x80, 0x56, 0xd0, 0x65, 0x2b, 0x3e, 0x11, 0x11, 0xe2, 0x12, 0x2b, 0xc6, 0x87,
+ 0xa1, 0xd0, 0x14, 0x1e, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00,
+ 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63,
+ 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+ 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5,
+ 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x01, 0x15, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60,
+ 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0xfd, 0xc0, 0xab, 0x3b, 0xfc, 0x61, 0xe6, 0xd5, 0xdd, 0xcf, 0x26, 0x91,
+ 0xe5, 0xe9, 0xfb, 0x2c, 0xc0, 0x8d, 0xfe, 0x4c, 0x96, 0xf5, 0x08, 0x64, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38,
+ 0x31, 0x38, 0x35, 0x31, 0x31, 0x37, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31,
+ 0x31, 0x37, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20,
+ 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63,
+ 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5,
+ 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0xd9, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9,
+ 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0xdc, 0xaf, 0x18, 0xfa, 0xad, 0xad, 0x06, 0xf6, 0x32, 0x30, 0x31, 0x36,
+ 0x30, 0x34, 0x31, 0x31, 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31,
+ 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x61, 0x61, 0x70, 0x6c, 0x69, 0x70, 0x72, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x11,
+ 0x73, 0x73, 0x75, 0x69, 0x00, 0x00, 0x00, 0x20, 0x87, 0x19, 0x1c, 0xa3, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05,
+ 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x64, 0x62, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x21, 0x7e, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x4b, 0x65,
+ 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x73, 0x64, 0x66, 0x2d, 0x64, 0x62,
+ 0x00, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74,
+ 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b,
+ 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53,
+ 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c,
+ 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb4,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x05, 0x5c, 0x00, 0x00, 0x00, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x73, 0x76, 0x63, 0x65,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x04, 0x94, 0x00, 0x00, 0x04, 0xc8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x6c,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x05, 0x34, 0x00, 0x00, 0x05, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69,
+ 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x8c, 0x00, 0x00, 0x05, 0xa4, 0x00, 0x00, 0x05, 0xb8,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73,
+ 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x05, 0x2c, 0x80, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5,
+ 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x21,
+ 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x2d, 0x00, 0x00, 0x01, 0x31, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51,
+ 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0xce, 0x58, 0x3c, 0x63, 0xf0, 0xe1, 0x4b, 0xfc,
+ 0xee, 0x88, 0x20, 0xa4, 0xc4, 0x20, 0xc4, 0x8c, 0xaf, 0x9d, 0xe6, 0x89, 0x39, 0xe3, 0xcc, 0x27, 0x32, 0x30, 0x31, 0x36,
+ 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38,
+ 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73,
+ 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65,
+ 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73,
+ 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xed,
+ 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x01, 0x11,
+ 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39,
+ 0x60, 0x88, 0xd4, 0xf3, 0x53, 0x7d, 0x89, 0x6e, 0xc1, 0x4f, 0xfd, 0x7b, 0x4b, 0x9d, 0x0d, 0xe0, 0xe9, 0xd6, 0x84, 0xdf,
+ 0x0f, 0x23, 0x90, 0x0b, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00,
+ 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74,
+ 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04,
+ 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x03, 0x5c, 0x00, 0x00, 0x03, 0xac, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x04, 0x44,
+ 0x00, 0x00, 0x04, 0x7c, 0x00, 0x00, 0x04, 0xbc, 0x00, 0x00, 0x04, 0xf4, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x61, 0x63, 0x63, 0x74, 0x73, 0x64, 0x6d, 0x6e, 0x73, 0x72, 0x76, 0x72,
+ 0x70, 0x74, 0x63, 0x6c, 0x61, 0x74, 0x79, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73,
+ 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73,
+ 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04,
+ 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x84,
+ 0x00, 0x00, 0x03, 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c,
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xd4,
+ 0x00, 0x00, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x04, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65,
+ 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x04, 0x74, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xa4, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04,
+ 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x1c, 0x00, 0x00, 0x05, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x61, 0x63, 0x63, 0x74, 0x76, 0x6c, 0x6d, 0x65,
+ 0x61, 0x64, 0x64, 0x72, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x64, 0x64, 0x72,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28,
+ 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x45, 0x00, 0x00, 0x04, 0x49,
+ 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x5d, 0x00, 0x00, 0x04, 0x71, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x05, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x04, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74,
+ 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
+ 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46,
+ 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f,
+ 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09,
+ 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x17,
+ 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30,
+ 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14,
+ 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c,
+ 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e,
+ 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f,
+ 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 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, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e,
+ 0x50, 0x10, 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b,
+ 0x07, 0x8c, 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a,
+ 0x6d, 0x4d, 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83,
+ 0xfb, 0x8d, 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92,
+ 0x6f, 0xda, 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2,
+ 0x58, 0x5b, 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f,
+ 0xcd, 0x4b, 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8,
+ 0x36, 0x7c, 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6,
+ 0x04, 0xe1, 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2,
+ 0x10, 0x2b, 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31,
+ 0xb0, 0x99, 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6,
+ 0x7c, 0x24, 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42,
+ 0x70, 0xf1, 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x47, 0x30, 0x45, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c,
+ 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
+ 0x14, 0x30, 0x12, 0x81, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+ 0x00, 0x00, 0xa3, 0x3e, 0x5c, 0x33, 0x06, 0x0b, 0x74, 0xf7, 0x59, 0x56, 0x2e, 0x26, 0x18, 0xe0, 0x59, 0xc9, 0x20, 0x9d,
+ 0xaa, 0xf2, 0xfb, 0xa0, 0xf8, 0x11, 0x00, 0x71, 0x53, 0x3d, 0xfa, 0xdc, 0xe9, 0x12, 0x4c, 0x8a, 0xa1, 0x1c, 0x7c, 0xb3,
+ 0x4b, 0xa5, 0xa0, 0xfa, 0x03, 0xc5, 0x82, 0x1c, 0xab, 0x44, 0xf6, 0xcb, 0x59, 0x4b, 0x80, 0xeb, 0xc0, 0xa8, 0x0e, 0xc6,
+ 0x93, 0xea, 0xbf, 0x67, 0x41, 0xa9, 0x64, 0xcb, 0xb4, 0x3e, 0xf7, 0x64, 0xcf, 0x4c, 0xef, 0x24, 0x62, 0x73, 0x2d, 0xed,
+ 0xb4, 0xec, 0x30, 0x97, 0x91, 0x9f, 0x18, 0xe9, 0x12, 0x93, 0x18, 0x83, 0x70, 0xb0, 0xc4, 0x35, 0x33, 0x67, 0x17, 0xb0,
+ 0x8b, 0xbe, 0x45, 0xde, 0x98, 0x23, 0xf2, 0x02, 0x77, 0x79, 0x55, 0x53, 0xc4, 0xd7, 0x67, 0x81, 0xde, 0xa1, 0x3f, 0x63,
+ 0xb5, 0x87, 0xb6, 0x20, 0x8d, 0x4f, 0x5e, 0x7e, 0x27, 0x30, 0x99, 0xe0, 0xff, 0x91, 0x8b, 0x00, 0x8d, 0x7d, 0xe5, 0x57,
+ 0x57, 0xd8, 0xd9, 0x7d, 0x6f, 0xc6, 0xb8, 0x6f, 0x84, 0xed, 0x84, 0x9d, 0xd9, 0xac, 0x13, 0xd8, 0x4a, 0x96, 0x55, 0x2d,
+ 0x8e, 0x21, 0x11, 0xc9, 0xa4, 0x81, 0x10, 0x7a, 0x0a, 0x15, 0xce, 0x99, 0x98, 0x09, 0xdd, 0xec, 0x8d, 0x1b, 0xfb, 0x17,
+ 0x55, 0x03, 0xa6, 0x44, 0xb5, 0xc9, 0xa9, 0x1f, 0x52, 0xd7, 0x35, 0x06, 0x8d, 0x0a, 0x5a, 0x01, 0x2a, 0xb0, 0xd2, 0x0c,
+ 0xfa, 0xd9, 0x66, 0xfa, 0x35, 0x6e, 0xa0, 0xbc, 0x21, 0xe4, 0xe1, 0xe0, 0x3c, 0x3b, 0x7a, 0xef, 0x7d, 0xe1, 0x34, 0x2e,
+ 0xe3, 0x9c, 0xc0, 0xa9, 0x4c, 0x16, 0xab, 0x00, 0x60, 0xe0, 0x44, 0xeb, 0x62, 0xcc, 0x1d, 0x27, 0x84, 0x0f, 0x33, 0x37,
+ 0x9d, 0xc5, 0xc4, 0xa1, 0xd3, 0xe8, 0x38, 0xff, 0xf2, 0xdf, 0xcd, 0x7c, 0xbb, 0xc3, 0xa1, 0xae, 0x4d, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69,
+ 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
+ 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54,
+ 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02,
+ 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06,
+ 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21,
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50,
+ 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31,
+ 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f,
+ 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1,
+ 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4,
+ 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x31, 0x00, 0x00, 0x04, 0x35, 0x00, 0x00, 0x04, 0x39,
+ 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x61, 0x00, 0x00, 0x05, 0x0d, 0x00, 0x00, 0x05, 0xb9, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x03, 0xee, 0x30, 0x82, 0x02, 0xd6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x06,
+ 0xe0, 0x2a, 0x1d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64,
+ 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41,
+ 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+ 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20,
+ 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c,
+ 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a,
+ 0x17, 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a, 0x30, 0x81, 0xa2, 0x31, 0x19,
+ 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69,
+ 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c,
+ 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f,
+ 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c,
+ 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75,
+ 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 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, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0,
+ 0xb7, 0x97, 0x0d, 0x43, 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8,
+ 0xc9, 0xdd, 0x21, 0xb4, 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48,
+ 0x64, 0x41, 0x91, 0xf7, 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7,
+ 0xde, 0x62, 0x9f, 0x82, 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f,
+ 0xa8, 0x06, 0xc3, 0xe9, 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25,
+ 0xa5, 0x1a, 0xd0, 0x2a, 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82,
+ 0x3f, 0xa7, 0x6b, 0x64, 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71,
+ 0x30, 0x60, 0x21, 0x12, 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d,
+ 0x4b, 0x8a, 0xcd, 0x1d, 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f,
+ 0x1e, 0x3c, 0x63, 0x7a, 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf,
+ 0xa8, 0x1b, 0xf7, 0xbd, 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0,
+ 0x7e, 0x95, 0xd4, 0x0b, 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80,
+ 0xd2, 0x5f, 0x0c, 0x0b, 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x2a, 0x30, 0x28, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d,
+ 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaf, 0xe3,
+ 0x41, 0xaa, 0x63, 0xdc, 0x3e, 0xd1, 0x46, 0x1e, 0x7a, 0x09, 0x04, 0x4a, 0xfd, 0x54, 0xc7, 0xd9, 0x25, 0x2f, 0xce, 0x8e,
+ 0x5d, 0x34, 0x96, 0x04, 0x67, 0xbc, 0x6f, 0xb6, 0x99, 0x35, 0xc2, 0x16, 0x1c, 0x2a, 0xc3, 0x5f, 0xdf, 0x6e, 0xe2, 0xe4,
+ 0x2e, 0xbb, 0x64, 0x1c, 0x0a, 0xff, 0x62, 0x79, 0x70, 0x7c, 0xc6, 0x8e, 0xd9, 0x95, 0xb6, 0x8a, 0x3d, 0xf6, 0xdd, 0x79,
+ 0x1c, 0xeb, 0x73, 0x05, 0x2f, 0x7e, 0x38, 0xb8, 0x9c, 0xfc, 0x06, 0x8f, 0x5f, 0xd7, 0xec, 0xd3, 0x23, 0xae, 0x75, 0x0f,
+ 0x8e, 0x70, 0xb2, 0xd8, 0x88, 0xa0, 0x4f, 0x53, 0x0a, 0xcc, 0xee, 0x18, 0xf2, 0x5b, 0xf8, 0xe1, 0x22, 0x6b, 0xeb, 0x4d,
+ 0x9d, 0x2a, 0xa1, 0x46, 0xf4, 0xc7, 0x99, 0x26, 0x5b, 0xaf, 0x92, 0x54, 0x72, 0xe7, 0xea, 0x49, 0x34, 0x98, 0x8d, 0x93,
+ 0x18, 0xc5, 0x6e, 0x79, 0x79, 0xb3, 0x63, 0x76, 0xf7, 0x84, 0x49, 0x06, 0x58, 0x14, 0x1a, 0x86, 0xbd, 0xe5, 0x5a, 0xf8,
+ 0x81, 0x06, 0x15, 0x0c, 0xf7, 0x57, 0x4e, 0xeb, 0xbe, 0xc9, 0xe6, 0x09, 0xa3, 0x1d, 0xcc, 0xc6, 0x08, 0xbc, 0x71, 0x4b,
+ 0x62, 0x1a, 0xec, 0xdd, 0xad, 0xe3, 0x00, 0xd9, 0xf3, 0x98, 0x94, 0x75, 0xb5, 0xc2, 0x64, 0xec, 0xec, 0xe1, 0x88, 0x5b,
+ 0x24, 0xd6, 0xa2, 0x27, 0x86, 0x10, 0xc4, 0xfc, 0xf7, 0x8d, 0x79, 0x95, 0x20, 0x3e, 0xc5, 0x7a, 0xdc, 0x57, 0xc8, 0x2e,
+ 0x78, 0x63, 0xd5, 0x09, 0xc3, 0xa9, 0xa4, 0xd9, 0x83, 0x99, 0xbe, 0x17, 0xdc, 0x22, 0x85, 0x98, 0x0b, 0xe1, 0xf6, 0x67,
+ 0x47, 0xf7, 0x1d, 0xed, 0x40, 0xe4, 0x5c, 0x5e, 0x58, 0xf1, 0x27, 0x5b, 0xe2, 0x7b, 0xb0, 0xf5, 0xbf, 0x37, 0xc3, 0xe2,
+ 0x73, 0xa8, 0xd6, 0xf1, 0x42, 0xb2, 0x56, 0x90, 0x00, 0xa4, 0x35, 0x4a, 0x5a, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67,
+ 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14,
+ 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c,
+ 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62,
+ 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
+ 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63,
+ 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
+ 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53,
+ 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c,
+ 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0x14,
+ 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c,
+ 0x00, 0x00, 0x06, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x00, 0x00, 0x04, 0x85, 0x00, 0x00, 0x04, 0x89, 0x00, 0x00, 0x04, 0xa5,
+ 0x00, 0x00, 0x04, 0xc5, 0x00, 0x00, 0x05, 0x81, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x45,
+ 0x30, 0x82, 0x04, 0x3d, 0x30, 0x82, 0x03, 0x25, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30,
+ 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63,
+ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
+ 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55,
+ 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e,
+ 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30,
+ 0x34, 0x30, 0x39, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
+ 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46,
+ 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f,
+ 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09,
+ 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 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, 0xc3, 0xe8, 0xe0, 0x34, 0xff, 0x63, 0x08, 0xce, 0x36, 0x82, 0x02, 0xe7, 0x91,
+ 0x0b, 0x73, 0x84, 0xb9, 0xad, 0xd8, 0x79, 0x92, 0x34, 0x20, 0x96, 0xd1, 0x3a, 0xc7, 0x7f, 0x19, 0xd7, 0xcf, 0x9f, 0xab,
+ 0x2b, 0xc0, 0x0c, 0xe1, 0xf6, 0x0e, 0x9e, 0x9f, 0x73, 0x42, 0x95, 0xf1, 0x2c, 0x63, 0xff, 0x3f, 0x31, 0xb1, 0xe3, 0x24,
+ 0x1a, 0x75, 0x7d, 0x50, 0x2c, 0x23, 0x59, 0x53, 0x2c, 0xab, 0xaf, 0xd7, 0x5c, 0xf1, 0x27, 0xd2, 0xe9, 0xf5, 0x8f, 0x76,
+ 0xc4, 0x96, 0x74, 0x3c, 0xda, 0x65, 0xd4, 0x9e, 0xde, 0x33, 0x25, 0x5d, 0xed, 0x04, 0x94, 0x2c, 0xb5, 0x18, 0xeb, 0x64,
+ 0x8e, 0xf4, 0xd4, 0xe0, 0xb6, 0xfc, 0xcc, 0xd7, 0xfb, 0x90, 0x9c, 0xc1, 0xe6, 0x09, 0xb9, 0x8c, 0xc9, 0xba, 0x91, 0x4d,
+ 0x63, 0x5f, 0xa1, 0x75, 0x13, 0x11, 0x7d, 0x13, 0xa9, 0x2c, 0x07, 0xbd, 0xcb, 0x5d, 0xc5, 0xb0, 0x4f, 0xed, 0x95, 0xc6,
+ 0x8c, 0xe9, 0x78, 0xa2, 0xa5, 0x42, 0x15, 0x5a, 0xd0, 0x9c, 0x9c, 0x85, 0x85, 0x6e, 0x50, 0xae, 0x19, 0xd5, 0x91, 0x13,
+ 0x62, 0x96, 0xd9, 0x4a, 0x47, 0xe3, 0xfe, 0x8f, 0x7d, 0x47, 0xbd, 0xbe, 0xaa, 0x37, 0x64, 0xe3, 0xf0, 0xa3, 0xa4, 0xd0,
+ 0xef, 0xef, 0x2a, 0xa7, 0x45, 0xbf, 0x21, 0x79, 0xb8, 0x5c, 0x04, 0x8a, 0x2f, 0x7b, 0xe0, 0xe2, 0x32, 0x58, 0x75, 0xec,
+ 0xec, 0x2f, 0x78, 0xa5, 0x9a, 0x7b, 0xa3, 0x3c, 0xf6, 0x67, 0x00, 0x83, 0xe5, 0x77, 0x1d, 0x2b, 0xdd, 0x74, 0xd0, 0x45,
+ 0xcf, 0xa4, 0x0c, 0xf2, 0xe2, 0x60, 0xa8, 0x70, 0x87, 0x05, 0x0b, 0x7c, 0xef, 0x88, 0x09, 0x23, 0x15, 0xdf, 0xdb, 0x9f,
+ 0xc2, 0x80, 0x1f, 0x0a, 0x12, 0xcb, 0x00, 0xa4, 0x8a, 0x77, 0xa7, 0x54, 0x8f, 0xcb, 0x91, 0xbb, 0x55, 0x52, 0x51, 0x8f,
+ 0xca, 0xf6, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c,
+ 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
+ 0x20, 0x30, 0x1e, 0x81, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8c, 0x44, 0x70, 0xda, 0xd9, 0x65, 0x52,
+ 0xfd, 0x46, 0x0e, 0xab, 0xbb, 0xb5, 0x1c, 0x46, 0x0a, 0xcb, 0x3d, 0xc3, 0x71, 0x79, 0xa8, 0x5f, 0x3b, 0x45, 0x49, 0x29,
+ 0x0c, 0xf5, 0x69, 0xb4, 0x27, 0x4d, 0x79, 0xad, 0xa9, 0x93, 0x11, 0x7b, 0xad, 0x45, 0xc6, 0x49, 0x54, 0x8b, 0x5d, 0x5f,
+ 0xcc, 0x9d, 0xd9, 0xe4, 0x8f, 0xff, 0x21, 0x0f, 0x7a, 0x40, 0xf2, 0xd6, 0xce, 0xe1, 0x97, 0x5f, 0x7d, 0x9c, 0x76, 0x22,
+ 0x73, 0x30, 0x3b, 0xb4, 0x5b, 0xa0, 0x07, 0x70, 0x96, 0x97, 0x84, 0xe1, 0x47, 0x5b, 0x3e, 0xd2, 0xed, 0x3f, 0xca, 0x97,
+ 0x3a, 0x33, 0x52, 0xb8, 0x22, 0x89, 0xe2, 0x2e, 0x61, 0x5e, 0x20, 0x1a, 0xf9, 0x4f, 0x9a, 0x18, 0xde, 0xf3, 0x8e, 0x11,
+ 0x3b, 0x19, 0x09, 0xce, 0x8e, 0xb9, 0x28, 0x5f, 0x64, 0x54, 0xc1, 0x33, 0x19, 0x68, 0x96, 0x54, 0x53, 0x84, 0xb6, 0xf2,
+ 0xdb, 0xb3, 0x6b, 0xca, 0x36, 0x08, 0xb1, 0xa3, 0x0d, 0x19, 0x4e, 0xac, 0x17, 0x25, 0x96, 0x0d, 0x4c, 0x9e, 0xc5, 0xa0,
+ 0xcc, 0xe4, 0x52, 0x98, 0x1c, 0xcf, 0x0a, 0x77, 0x91, 0xf2, 0xc8, 0xae, 0x8c, 0x1c, 0x1d, 0xae, 0x79, 0xf6, 0x0c, 0x65,
+ 0xf0, 0xb4, 0xdd, 0x0c, 0x6f, 0x35, 0x12, 0x93, 0xb7, 0x20, 0xd1, 0x29, 0xa3, 0x40, 0xb5, 0x66, 0x67, 0x69, 0xdd, 0x97,
+ 0xcf, 0x48, 0x9f, 0xe9, 0x00, 0x33, 0x0e, 0x8e, 0xae, 0xc6, 0x40, 0xe3, 0x40, 0xdb, 0xab, 0x8b, 0x1e, 0x34, 0xbb, 0x0b,
+ 0xb7, 0x42, 0xd4, 0x0d, 0x9e, 0x86, 0x99, 0x3c, 0xbd, 0x34, 0xc5, 0xba, 0xac, 0x03, 0x8b, 0xcd, 0xa3, 0xee, 0x36, 0x52,
+ 0x28, 0x59, 0x7a, 0x29, 0xd7, 0x1f, 0xa1, 0x18, 0xc5, 0xba, 0x7a, 0xc4, 0xf0, 0x67, 0x4a, 0x61, 0x5c, 0x83, 0xad, 0x6c,
+ 0x89, 0x0b, 0xdd, 0x40, 0xf8, 0xfd, 0x8c, 0xce, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63,
+ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65,
+ 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+ 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
+ 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
+ 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41,
+ 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+ 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45,
+ 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07,
+ 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01,
+ 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x12, 0x5c,
+ 0x00, 0x00, 0x14, 0xd0, 0x00, 0x00, 0x15, 0x18, 0x00, 0x00, 0x15, 0x9c, 0x00, 0x00, 0x17, 0xe4, 0x00, 0x00, 0x1a, 0x2c,
+ 0x00, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x1a, 0x98, 0x00, 0x00, 0x02, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x03, 0x63, 0x74, 0x79, 0x70, 0x69, 0x73, 0x73, 0x75, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x13, 0x48, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31,
+ 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65,
+ 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
+ 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
+ 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04,
+ 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31,
+ 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73,
+ 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
+ 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46,
+ 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e,
+ 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43,
+ 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65,
+ 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+ 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
+ 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
+ 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x00, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0x48, 0x00, 0x00, 0x15, 0x60,
+ 0x00, 0x00, 0x15, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63,
+ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x75, 0x62, 0x6a,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0xcc, 0x00, 0x00, 0x16, 0x74, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31,
+ 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65,
+ 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
+ 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
+ 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xac,
+ 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65,
+ 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
+ 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e,
+ 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e,
+ 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
+ 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10,
+ 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40,
+ 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xb8,
+ 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73,
+ 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21,
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50,
+ 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31,
+ 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f,
+ 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x18, 0x14, 0x00, 0x00, 0x18, 0xbc, 0x00, 0x00, 0x19, 0x6c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0,
+ 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73,
+ 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65,
+ 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52,
+ 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c,
+ 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75,
+ 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14,
+ 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c,
+ 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62,
+ 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
+ 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65,
+ 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+ 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
+ 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
+ 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c,
+ 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x68,
+ 0x00, 0x00, 0x1a, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8,
+ 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14,
+ 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01,
+ 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x00, 0xe8, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8,
+ 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xa8,
+ 0x52, 0xba, 0xd6, 0xe8, 0x80, 0xd9, 0x0e, 0xbb, 0x2e, 0x64, 0x65, 0xce, 0xcd, 0xe6, 0xa9, 0x71, 0x00, 0x00, 0x00, 0x00,
+ 0x7f, 0xff, 0xff, 0xff, 0x00, 0x7f, 0x00, 0x00, 0x58, 0xcc, 0x46, 0xd5, 0x94, 0x46, 0x74, 0xb1, 0x30, 0x40, 0x9b, 0x78,
+ 0xb0, 0x30, 0x4b, 0x1a, 0xa1, 0x93, 0x58, 0x1f, 0x48, 0xd4, 0x81, 0x1e, 0x1e, 0x1e, 0xe2, 0xaf, 0xda, 0x6a, 0x3e, 0x6e,
+ 0x08, 0x90, 0x5e, 0xd5, 0xf1, 0xce, 0x8b, 0x78, 0x8a, 0x5e, 0xe2, 0x36, 0x45, 0x92, 0xee, 0xeb, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xe6, 0xb4, 0xf8, 0xd6, 0xa3, 0x68, 0x66, 0xde, 0x70, 0xd4, 0xe0, 0xd6, 0x9a, 0x46, 0x5d, 0xbd,
+ 0x60, 0x41, 0x2b, 0x19, 0x2b, 0x4b, 0x55, 0x64, 0x60, 0xe4, 0x91, 0x17, 0x5e, 0xa2, 0x08, 0xe0, 0x1c, 0x6e, 0xbd, 0xf1,
+ 0x08, 0xfd, 0x2d, 0x7b, 0x42, 0x6a, 0x7c, 0xa3, 0x73, 0x6d, 0xb0, 0xfd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48
+};
+unsigned int test_keychain_len = 45864;
+
+
+SecKeychainRef CF_RETURNS_RETAINED getPopulatedTestKeychain() {
+ deleteKeychainFiles(keychainFile);
+
+ writeFile(keychainFile, test_keychain, test_keychain_len);
+
+ SecKeychainRef kc = NULL;
+ ok_status(SecKeychainOpen(keychainFile, &kc), "%s: getPopulatedTestKeychain: SecKeychainOpen", testName);
+ ok_status(SecKeychainUnlock(kc, (UInt32) strlen(test_keychain_password), test_keychain_password, true), "%s: getPopulatedTestKeychain: SecKeychainUnlock", testName);
+ return kc;
+}
+#define getPopulatedTestKeychainTests 2
+
+SecKeychainRef CF_RETURNS_RETAINED getEmptyTestKeychain() {
+ deleteKeychainFiles(keychainFile);
+
+ SecKeychainRef kc = NULL;
+ ok_status(SecKeychainCreate(keychainFile, (UInt32) strlen(test_keychain_password), test_keychain_password, false, NULL, &kc), "%s: getPopulatedTestKeychain: SecKeychainCreate", testName);
+ return kc;
+}
+#define getEmptyTestKeychainTests 1
+
+
+void startTest(const char* thisTestName) {
+ strlcpy(testName, thisTestName, sizeof(testName));
+}
+
+void initializeKeychainTests(const char* thisTestName) {
+ const char *home_dir = getenv("HOME");
+ snprintf(keychainName, sizeof(keychainName), "test-%s.asdf", thisTestName);
+ snprintf(keychainFile, sizeof(keychainFile), "%s/Library/Keychains/%s", home_dir, keychainName);
+ snprintf(keychainDbFile, sizeof(keychainDbFile), "%s/Library/Keychains/%s-db", home_dir, keychainName);
+ snprintf(keychainTempFile, sizeof(keychainTempFile), "%s/Library/Keychains/test_temp", home_dir);
+
+ deleteKeychainFiles(keychainFile);
+
+ startTest(thisTestName);
+
+ SecKeychainGetUserPromptAttempts(&promptAttempts);
+ SecKeychainSetUserInteractionAllowed(FALSE);
+}
+
+// Use this at the bottom of every test to make sure everything is gone
+void deleteTestFiles() {
+ deleteKeychainFiles(keychainFile);
+}
+
+void addToSearchList(SecKeychainRef keychain) {
+ CFArrayRef searchList = NULL;
+ SecKeychainCopySearchList(&searchList);
+ CFMutableArrayRef mutableSearchList = CFArrayCreateMutableCopy(NULL, CFArrayGetCount(searchList) + 1, searchList);
+ CFArrayAppendValue(mutableSearchList, keychain);
+ SecKeychainSetSearchList(mutableSearchList);
+ CFRelease(searchList);
+ CFRelease(mutableSearchList);
+}
+
+
+/* Checks to be sure there are N elements in this search, and returns the first
+ * if it exists. */
+SecKeychainItemRef checkNCopyFirst(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) {
+ CFArrayRef results = NULL;
+ if(n > 0) {
+ ok_status(SecItemCopyMatching(query, (CFTypeRef*) &results), "%s: SecItemCopyMatching", testName);
+ } else {
+ is(SecItemCopyMatching(query, (CFTypeRef*) &results), errSecItemNotFound, "%s: SecItemCopyMatching (for no items)", testName);
+ }
+
+ SecKeychainItemRef item = NULL;
+ if(results) {
+ is(CFArrayGetCount(results), n, "%s: Wrong number of results", testName);
+ if(n >= 1) {
+ ok(item = (SecKeychainItemRef) CFArrayGetValueAtIndex(results, 0), "%s: Couldn't get item", testName);
+ } else {
+ pass("make test numbers match");
+ }
+ } else if((!results) && n == 0) {
+ pass("%s: no results found (and none expected)", testName);
+ pass("make test numbers match");
+ } else {
+ fail("%s: no results found (and %d expected)", testName, n);
+ fflush(stdout); CFShow(query); fflush(stdout);
+ pass("make test numbers match");
+ }
+
+ CFRetainSafe(item);
+ CFReleaseNull(results);
+
+ CFRelease(query);
+ return item;
+}
+
+void checkN(char* testName, const CFDictionaryRef CF_CONSUMED query, uint32_t n) {
+ SecKeychainItemRef item = checkNCopyFirst(testName, query, n);
+ CFReleaseSafe(item);
+}
+
+#define checkNTests 3
+
+
+void readPasswordContentsWithResult(SecKeychainItemRef item, OSStatus expectedResult, CFStringRef expectedContents) {
+ if(!item) {
+ fail("no item passed to readPasswordContentsWithResult");
+ fail("Match test numbers");
+ fail("Match test numbers");
+ return;
+ }
+
+ CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
+ CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
+
+ CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue((CFMutableArrayRef)itemList, item);
+ CFDictionarySetValue(query, kSecUseItemList, itemList);
+
+ CFTypeRef results = NULL;
+ if(expectedContents) {
+ is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: SecItemCopyMatching", testName);
+ CFReleaseNull(query);
+
+ if(results) {
+ ok(CFGetTypeID(results) == CFDataGetTypeID(), "%s: result is not a data", testName);
+
+ CFDataRef data = (CFDataRef) results;
+ CFStringRef str = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, false);
+ eq_cf(str, expectedContents, "%s: contents do not match", testName);
+ CFReleaseNull(str);
+ CFReleaseNull(results);
+ } else {
+ fail("Didn't get any results");
+ fail("Match test numbers");
+ }
+ } else {
+ is(SecItemCopyMatching(query, (CFTypeRef*) &results), expectedResult, "%s: readPasswordContents: expecting error %d", testName, (int) expectedResult);
+ pass("Match test numbers");
+ pass("Match test numbers");
+ }
+}
+#define readPasswordContentsWithResultTests 3
+
+void readPasswordContents(SecKeychainItemRef item, CFStringRef expectedContents) {
+ return readPasswordContentsWithResult(item, errSecSuccess, expectedContents);
+}
+#define readPasswordContentsTests readPasswordContentsWithResultTests
+
+void changePasswordContents(SecKeychainItemRef item, CFStringRef newPassword) {
+ if(!item) {
+ fail("no item passed to changePasswordContents");
+ return;
+ }
+
+ CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
+
+ CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue((CFMutableArrayRef)itemList, item);
+ CFDictionarySetValue(query, kSecUseItemList, itemList);
+
+ CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDataRef data = CFDataCreate(NULL, (const UInt8*) CFStringGetCStringPtr(newPassword, kCFStringEncodingUTF8), CFStringGetLength(newPassword));
+ CFDictionarySetValue(attrs, kSecValueData, data);
+ CFReleaseNull(data);
+
+ ok_status(SecItemUpdate(query, attrs), "%s: SecItemUpdate", testName);
+}
+#define changePasswordContentsTests 1
+
+void deleteItem(SecKeychainItemRef item) {
+ CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue((CFMutableArrayRef)itemList, item);
+ CFDictionarySetValue(query, kSecUseItemList, itemList);
+
+ ok_status(SecItemDelete(query), "%s: SecItemDelete single item", testName);
+ CFReleaseNull(query);
+}
+#define deleteItemTests 1
+
+void deleteItems(CFArrayRef items) {
+ if(!items) {
+ fail("no items passed to deleteItems");
+ return;
+ }
+
+ CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(query, kSecUseItemList, items);
+
+ size_t count = (size_t) CFArrayGetCount(items);
+ if(count > 0) {
+ ok_status(SecItemDelete(query), "%s: SecItemDelete %ld items", testName, count);
+ } else {
+ is(SecItemDelete(query), errSecItemNotFound, "%s: SecItemDelete no items", testName);
+ }
+ CFReleaseNull(query);
+}
+#define deleteItemsTests 1
+
+/* Checks in with securityd to see how many prompts were generated since the last call to this function, and tests against the number expected.
+ Returns the number generated since the last call. */
+uint32_t checkPrompts(uint32_t expectedSinceLastCall, char* explanation) {
+ uint32_t currentPrompts = UINT_MAX;
+ uint32_t newPrompts = UINT_MAX;
+ ok_status(SecKeychainGetUserPromptAttempts(¤tPrompts), "%s: SecKeychainGetUserPromptAttempts", testName);
+
+ newPrompts = currentPrompts - promptAttempts;
+
+ is(newPrompts, expectedSinceLastCall, "%s: wrong number of prompts: %s", testName, explanation);
+ promptAttempts = currentPrompts;
+
+ return newPrompts;
+}
+#define checkPromptsTests 2
#ifndef kc_file_helpers_h
#define kc_file_helpers_h
+#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <Security/SecItem.h>
+#include <Security/SecKeychain.h>
+#include "keychain_regressions.h"
#pragma clang diagnostic push
sync();
}
+SecKeychainRef CF_RETURNS_RETAINED getPopulatedTestKeychain(void);
+#define getPopulatedTestKeychainTests 2
+
+SecKeychainRef CF_RETURNS_RETAINED getEmptyTestKeychain(void);
+#define getEmptyTestKeychainTests 1
+
// The following keychain includes:
//
// security add-internet-password -s test_service_restrictive_acl -a test_account -j "a useful comment" -r "htps" -t dflt -w test_password test.keychain
// Code Signing identity
// S/MIME identity
-const char * test_keychain_password = "password";
+extern const char * test_keychain_password;
+
+extern unsigned char test_keychain[];
-unsigned char test_keychain[] = {
- 0x6b, 0x79, 0x63, 0x68, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xb3, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x1b, 0x70,
- 0x00, 0x00, 0x4d, 0xe8, 0x00, 0x00, 0x4e, 0x10, 0x00, 0x00, 0x57, 0xe0, 0x00, 0x00, 0x6c, 0x88, 0x00, 0x00, 0x8b, 0x44,
- 0x00, 0x00, 0x91, 0x20, 0x00, 0x00, 0x96, 0x4c, 0x00, 0x00, 0x97, 0x0c, 0x00, 0x00, 0xb2, 0x28, 0x00, 0x00, 0x03, 0x2c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x03, 0x24, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x01, 0x14,
- 0x00, 0x00, 0x01, 0x5c, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x02, 0x04,
- 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0xd8, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
- 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d,
- 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42,
- 0x55, 0x54, 0x45, 0x53, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x19, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d,
- 0x41, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
- 0x44, 0x42, 0x5f, 0x53, 0x43, 0x48, 0x45, 0x4d, 0x41, 0x5f, 0x50, 0x41, 0x52, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f,
- 0x44, 0x55, 0x4c, 0x45, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x44, 0x42, 0x42, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1c, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
- 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59,
- 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d,
- 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x50, 0x52,
- 0x49, 0x56, 0x41, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x0a,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1f, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f,
- 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x53, 0x59, 0x4d, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f,
- 0x4b, 0x45, 0x59, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, 0x80, 0x00, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x22, 0x43, 0x53, 0x53, 0x4d, 0x5f, 0x44, 0x4c, 0x5f, 0x44, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52,
- 0x44, 0x5f, 0x58, 0x35, 0x30, 0x39, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a,
- 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x01, 0x84,
- 0x00, 0x00, 0x01, 0xc4, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x02, 0xc4,
- 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x03, 0x44, 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x03, 0xc4, 0x00, 0x00, 0x04, 0x04,
- 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x84, 0x00, 0x00, 0x04, 0xc4, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x05, 0x44,
- 0x00, 0x00, 0x05, 0x84, 0x00, 0x00, 0x05, 0xc4, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x44, 0x00, 0x00, 0x06, 0x84,
- 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x84, 0x00, 0x00, 0x07, 0xc4,
- 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x44, 0x00, 0x00, 0x08, 0x84, 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x09, 0x04,
- 0x00, 0x00, 0x09, 0x44, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x09, 0xc4, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x44,
- 0x00, 0x00, 0x0a, 0x84, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x0b, 0x44, 0x00, 0x00, 0x0b, 0x84,
- 0x00, 0x00, 0x0b, 0xc4, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x0c, 0x44, 0x00, 0x00, 0x0c, 0x84, 0x00, 0x00, 0x0c, 0xc4,
- 0x00, 0x00, 0x0d, 0x04, 0x00, 0x00, 0x0d, 0x44, 0x00, 0x00, 0x0d, 0x84, 0x00, 0x00, 0x0d, 0xc4, 0x00, 0x00, 0x0e, 0x04,
- 0x00, 0x00, 0x0e, 0x44, 0x00, 0x00, 0x0e, 0x84, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x0f, 0x44,
- 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0x0f, 0xc4, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x10, 0x84,
- 0x00, 0x00, 0x10, 0xc4, 0x00, 0x00, 0x11, 0x04, 0x00, 0x00, 0x11, 0x44, 0x00, 0x00, 0x11, 0x84, 0x00, 0x00, 0x11, 0xc4,
- 0x00, 0x00, 0x12, 0x04, 0x00, 0x00, 0x12, 0x44, 0x00, 0x00, 0x12, 0x84, 0x00, 0x00, 0x12, 0xc4, 0x00, 0x00, 0x13, 0x04,
- 0x00, 0x00, 0x13, 0x44, 0x00, 0x00, 0x13, 0x84, 0x00, 0x00, 0x13, 0xc4, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x14, 0x44,
- 0x00, 0x00, 0x14, 0x84, 0x00, 0x00, 0x14, 0xc4, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x15, 0x44, 0x00, 0x00, 0x15, 0x84,
- 0x00, 0x00, 0x15, 0xc4, 0x00, 0x00, 0x16, 0x04, 0x00, 0x00, 0x16, 0x44, 0x00, 0x00, 0x16, 0x84, 0x00, 0x00, 0x16, 0xc4,
- 0x00, 0x00, 0x17, 0x04, 0x00, 0x00, 0x17, 0x44, 0x00, 0x00, 0x17, 0x84, 0x00, 0x00, 0x17, 0xc4, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x61, 0x63, 0x63, 0x74,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, 0x69, 0x67,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
- 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x06, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0e,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x72, 0x74,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x08, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x70, 0x74, 0x63, 0x6c,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c,
- 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x0d, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a,
- 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4a,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4f,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x6e, 0x62, 0x72,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x54,
- 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x73, 0x6e, 0x62, 0x72,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x59,
- 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x78, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac,
- 0x00, 0x00, 0x32, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x02, 0xfc,
- 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x03, 0x9c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x04, 0x98,
- 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x05, 0x90, 0x00, 0x00, 0x05, 0xdc, 0x00, 0x00, 0x06, 0x2c,
- 0x00, 0x00, 0x06, 0x7c, 0x00, 0x00, 0x06, 0xd4, 0x00, 0x00, 0x07, 0x24, 0x00, 0x00, 0x07, 0x74, 0x00, 0x00, 0x07, 0xc0,
- 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x58, 0x00, 0x00, 0x08, 0xac, 0x00, 0x00, 0x08, 0xec, 0x00, 0x00, 0x09, 0x2c,
- 0x00, 0x00, 0x09, 0x6c, 0x00, 0x00, 0x09, 0xac, 0x00, 0x00, 0x09, 0xec, 0x00, 0x00, 0x0a, 0x2c, 0x00, 0x00, 0x0a, 0x6c,
- 0x00, 0x00, 0x0a, 0xbc, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x0b, 0x48, 0x00, 0x00, 0x0b, 0x88, 0x00, 0x00, 0x0b, 0xc8,
- 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x0c, 0x88, 0x00, 0x00, 0x0c, 0xc8, 0x00, 0x00, 0x0d, 0x08,
- 0x00, 0x00, 0x0d, 0x48, 0x00, 0x00, 0x0d, 0x88, 0x00, 0x00, 0x0d, 0xc8, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x00, 0x0e, 0x48,
- 0x00, 0x00, 0x0e, 0x88, 0x00, 0x00, 0x0e, 0xd8, 0x00, 0x00, 0x0f, 0x24, 0x00, 0x00, 0x0f, 0x64, 0x00, 0x00, 0x0f, 0xa4,
- 0x00, 0x00, 0x0f, 0xe4, 0x00, 0x00, 0x10, 0x24, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x10, 0xa4, 0x00, 0x00, 0x10, 0xe4,
- 0x00, 0x00, 0x11, 0x24, 0x00, 0x00, 0x11, 0x64, 0x00, 0x00, 0x11, 0xa4, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00, 0x12, 0x24,
- 0x00, 0x00, 0x12, 0x64, 0x00, 0x00, 0x12, 0xa4, 0x00, 0x00, 0x12, 0xe4, 0x00, 0x00, 0x13, 0x24, 0x00, 0x00, 0x13, 0x64,
- 0x00, 0x00, 0x13, 0xb4, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x14, 0xc0,
- 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x40, 0x00, 0x00, 0x15, 0x80, 0x00, 0x00, 0x15, 0xc0, 0x00, 0x00, 0x16, 0x00,
- 0x00, 0x00, 0x16, 0x40, 0x00, 0x00, 0x16, 0x80, 0x00, 0x00, 0x16, 0xc0, 0x00, 0x00, 0x17, 0x0c, 0x00, 0x00, 0x17, 0x5c,
- 0x00, 0x00, 0x17, 0xa8, 0x00, 0x00, 0x17, 0xf8, 0x00, 0x00, 0x18, 0x44, 0x00, 0x00, 0x18, 0x94, 0x00, 0x00, 0x18, 0xe0,
- 0x00, 0x00, 0x19, 0x34, 0x00, 0x00, 0x19, 0x84, 0x00, 0x00, 0x19, 0xd0, 0x00, 0x00, 0x1a, 0x24, 0x00, 0x00, 0x1a, 0x78,
- 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1b, 0x14, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0xb8, 0x00, 0x00, 0x1c, 0x08,
- 0x00, 0x00, 0x1c, 0x5c, 0x00, 0x00, 0x1c, 0xa8, 0x00, 0x00, 0x1c, 0xf4, 0x00, 0x00, 0x1d, 0x40, 0x00, 0x00, 0x1d, 0x88,
- 0x00, 0x00, 0x1d, 0xd4, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x78, 0x00, 0x00, 0x1e, 0xc0, 0x00, 0x00, 0x1f, 0x0c,
- 0x00, 0x00, 0x1f, 0x58, 0x00, 0x00, 0x1f, 0xa8, 0x00, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x20, 0x44, 0x00, 0x00, 0x20, 0x90,
- 0x00, 0x00, 0x20, 0xe0, 0x00, 0x00, 0x21, 0x2c, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x21, 0xd0, 0x00, 0x00, 0x22, 0x1c,
- 0x00, 0x00, 0x22, 0x70, 0x00, 0x00, 0x22, 0xc4, 0x00, 0x00, 0x23, 0x14, 0x00, 0x00, 0x23, 0x60, 0x00, 0x00, 0x23, 0xb0,
- 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x24, 0x54, 0x00, 0x00, 0x24, 0xa8, 0x00, 0x00, 0x24, 0xf4, 0x00, 0x00, 0x25, 0x40,
- 0x00, 0x00, 0x25, 0x8c, 0x00, 0x00, 0x25, 0xd4, 0x00, 0x00, 0x26, 0x20, 0x00, 0x00, 0x26, 0x70, 0x00, 0x00, 0x26, 0xc4,
- 0x00, 0x00, 0x27, 0x0c, 0x00, 0x00, 0x27, 0x58, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x27, 0xf4, 0x00, 0x00, 0x28, 0x40,
- 0x00, 0x00, 0x28, 0x90, 0x00, 0x00, 0x28, 0xdc, 0x00, 0x00, 0x29, 0x2c, 0x00, 0x00, 0x29, 0x78, 0x00, 0x00, 0x29, 0xcc,
- 0x00, 0x00, 0x2a, 0x1c, 0x00, 0x00, 0x2a, 0x68, 0x00, 0x00, 0x2a, 0xbc, 0x00, 0x00, 0x2b, 0x10, 0x00, 0x00, 0x2b, 0x60,
- 0x00, 0x00, 0x2b, 0xac, 0x00, 0x00, 0x2b, 0xfc, 0x00, 0x00, 0x2c, 0x50, 0x00, 0x00, 0x2c, 0xa0, 0x00, 0x00, 0x2c, 0xf4,
- 0x00, 0x00, 0x2d, 0x40, 0x00, 0x00, 0x2d, 0x8c, 0x00, 0x00, 0x2d, 0xd8, 0x00, 0x00, 0x2e, 0x20, 0x00, 0x00, 0x2e, 0x6c,
- 0x00, 0x00, 0x2e, 0xbc, 0x00, 0x00, 0x2f, 0x10, 0x00, 0x00, 0x2f, 0x58, 0x00, 0x00, 0x2f, 0xa4, 0x00, 0x00, 0x2f, 0xf0,
- 0x00, 0x00, 0x30, 0x40, 0x00, 0x00, 0x30, 0x90, 0x00, 0x00, 0x30, 0xdc, 0x00, 0x00, 0x31, 0x28, 0x00, 0x00, 0x31, 0x74,
- 0x00, 0x00, 0x31, 0xc4, 0x00, 0x00, 0x32, 0x1c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
- 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
- 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x44, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x6f, 0x72,
- 0x6d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x44, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x4c,
- 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x65, 0x6c, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0e,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x74, 0x74, 0x72,
- 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4d, 0x6f, 0x64, 0x75,
- 0x6c, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x41, 0x64, 0x64, 0x69, 0x6e, 0x56, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x53, 0x53, 0x49, 0x44, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x64, 0x61, 0x74,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
- 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x15,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
- 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x1a,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e,
- 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1b,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61,
- 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
- 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1d,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x00, 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x61, 0x63, 0x63, 0x74,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00,
- 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x00, 0x67, 0x65, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x64, 0x65, 0x73, 0x63,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
- 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x27,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x02, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x63, 0x72, 0x70, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x69, 0x6e, 0x76, 0x69, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x6e, 0x65, 0x67, 0x61,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
- 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2f,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x02, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x72, 0x76, 0x72,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02,
- 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x02, 0x61, 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x02, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x6d, 0x64, 0x61, 0x74,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
- 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x01, 0x69, 0x63, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x63, 0x72, 0x74, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x63, 0x72, 0x70,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d,
- 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x69, 0x6e, 0x76, 0x69,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
- 0x6e, 0x65, 0x67, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x41,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x01, 0x63, 0x75, 0x73, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x72, 0x6f, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01,
- 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x46,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
- 0x80, 0x00, 0x00, 0x01, 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a,
- 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
- 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x51,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a,
- 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c,
- 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07,
- 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x54,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53,
- 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
- 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10,
- 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
- 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
- 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f,
- 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x12,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
- 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
- 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x5f,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x19,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06,
- 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x65,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x65, 0x79, 0x43,
- 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d,
- 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54,
- 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e,
- 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54,
- 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d,
- 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74,
- 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48,
- 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
- 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65,
- 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08,
- 0x4b, 0x65, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x81,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x72, 0x69, 0x6e,
- 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x82,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x41, 0x6c, 0x69, 0x61,
- 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e,
- 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x65, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79,
- 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74,
- 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0e,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74,
- 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x61,
- 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74,
- 0x72, 0x61, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x45, 0x6e, 0x63, 0x72,
- 0x79, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x96,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x56, 0x65, 0x72, 0x69,
- 0x66, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x63, 0x6f,
- 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65,
- 0x63, 0x6f, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x99,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x57, 0x72, 0x61, 0x70,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1a,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x08, 0x43, 0x65, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x63, 0x65, 0x6e, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c,
- 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x6c, 0x61, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
- 0x50, 0x72, 0x69, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c,
- 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
- 0x41, 0x6c, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x9f,
- 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x80, 0x00, 0x10, 0x00, 0x73, 0x75, 0x62, 0x6a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x53, 0x75, 0x62, 0x6a,
- 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35,
- 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x80, 0x00, 0x10, 0x00,
- 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6e, 0x62, 0x72,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x80, 0x00, 0x10, 0x00, 0x73, 0x6b, 0x69, 0x64,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x64,
- 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0xa3,
- 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
- 0x80, 0x00, 0x10, 0x00, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x50, 0x75, 0x62, 0x6c,
- 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24,
- 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x03, 0x20,
- 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51,
- 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79,
- 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd,
- 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
- 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed,
- 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78, 0x74, 0x20, 0x70, 0x75,
- 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x82, 0x01, 0x0a,
- 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e, 0x50, 0x10,
- 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b, 0x07, 0x8c,
- 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a, 0x6d, 0x4d,
- 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83, 0xfb, 0x8d,
- 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92, 0x6f, 0xda,
- 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2, 0x58, 0x5b,
- 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f, 0xcd, 0x4b,
- 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8, 0x36, 0x7c,
- 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6, 0x04, 0xe1,
- 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2, 0x10, 0x2b,
- 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31, 0xb0, 0x99,
- 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6, 0x7c, 0x24,
- 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42, 0x70, 0xf1,
- 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d,
- 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
- 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
- 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
- 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x51,
- 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x5d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x79,
- 0x00, 0x00, 0x02, 0x7d, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5,
- 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
- 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed,
- 0x00, 0x00, 0x02, 0xf1, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0xfa, 0xde, 0x07, 0x11,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x74, 0x65, 0x78,
- 0x74, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, 0x39, 0x92, 0x01, 0x00, 0x00, 0x00,
- 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0, 0xb7, 0x97, 0x0d, 0x43,
- 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8, 0xc9, 0xdd, 0x21, 0xb4,
- 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48, 0x64, 0x41, 0x91, 0xf7,
- 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7, 0xde, 0x62, 0x9f, 0x82,
- 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f, 0xa8, 0x06, 0xc3, 0xe9,
- 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25, 0xa5, 0x1a, 0xd0, 0x2a,
- 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82, 0x3f, 0xa7, 0x6b, 0x64,
- 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71, 0x30, 0x60, 0x21, 0x12,
- 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d, 0x4b, 0x8a, 0xcd, 0x1d,
- 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f, 0x1e, 0x3c, 0x63, 0x7a,
- 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf, 0xa8, 0x1b, 0xf7, 0xbd,
- 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0, 0x7e, 0x95, 0xd4, 0x0b,
- 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80, 0xd2, 0x5f, 0x0c, 0x0b,
- 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc,
- 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31,
- 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32,
- 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0x06, 0x54, 0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x07, 0xd8, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x48,
- 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0xb8, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x09, 0x28, 0x00, 0x00, 0x09, 0x60,
- 0x00, 0x00, 0x09, 0x98, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a,
- 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x98,
- 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14,
- 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
- 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
- 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee,
- 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
- 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d,
- 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x07, 0xbc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97,
- 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee,
- 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x08, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xa8, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x08, 0xe0, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x18,
- 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x50, 0x00, 0x00, 0x09, 0x58,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x88, 0x00, 0x00, 0x09, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0xc0, 0x00, 0x00, 0x09, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14, 0xa8,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x10, 0xf8, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x06, 0xc4, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01,
- 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x06, 0x15, 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x06, 0x1d, 0x00, 0x00, 0x06, 0x21,
- 0x00, 0x00, 0x06, 0x25, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x06, 0x41, 0x00, 0x00, 0x06, 0x6d, 0x00, 0x00, 0x06, 0x71,
- 0x00, 0x00, 0x06, 0x75, 0x00, 0x00, 0x06, 0x79, 0x00, 0x00, 0x06, 0x85, 0x00, 0x00, 0x06, 0x91, 0x00, 0x00, 0x06, 0x95,
- 0x00, 0x00, 0x06, 0x99, 0x00, 0x00, 0x06, 0x9d, 0x00, 0x00, 0x06, 0xa1, 0x00, 0x00, 0x06, 0xa5, 0x00, 0x00, 0x06, 0xa9,
- 0x00, 0x00, 0x06, 0xad, 0x00, 0x00, 0x06, 0xb1, 0x00, 0x00, 0x06, 0xb5, 0x00, 0x00, 0x06, 0xb9, 0x00, 0x00, 0x06, 0xbd,
- 0x00, 0x00, 0x06, 0xc1, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x05, 0x7c,
- 0xce, 0x5e, 0x64, 0x56, 0xc9, 0x2c, 0x8c, 0xbb, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4,
- 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06,
- 0x39, 0xf9, 0x47, 0x1e, 0xec, 0x0d, 0xb8, 0x07, 0x55, 0xbc, 0xbf, 0x6e, 0xd7, 0xa7, 0xc4, 0x53, 0x73, 0x06, 0xa9, 0x05,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0xc0, 0x79, 0x0d, 0x4e, 0xd3, 0x15, 0x14, 0x9a, 0x46, 0xeb, 0x6d,
- 0x81, 0xe0, 0xa8, 0x43, 0x02, 0x74, 0x53, 0x4b, 0x3a, 0x23, 0xf7, 0x6d, 0x16, 0x6f, 0x5d, 0x5a, 0xa9, 0x97, 0x54, 0x37,
- 0xd0, 0x44, 0xd1, 0x9c, 0x15, 0x33, 0x05, 0xdb, 0x6b, 0xcb, 0x5c, 0xcd, 0x23, 0xc9, 0x65, 0x07, 0x79, 0x1b, 0x60, 0x2d,
- 0xd6, 0x17, 0x2b, 0x45, 0x20, 0x8f, 0xb6, 0x31, 0x91, 0xc0, 0x59, 0x53, 0x87, 0xa0, 0x3c, 0xd1, 0x77, 0x97, 0x91, 0xd8,
- 0x9c, 0xfc, 0x51, 0x4f, 0xfd, 0x21, 0x6a, 0x71, 0x12, 0x5a, 0x6e, 0x10, 0xd1, 0x5c, 0xe9, 0x7e, 0x24, 0xb8, 0xf3, 0x5d,
- 0xab, 0x51, 0x2f, 0x67, 0xa7, 0x65, 0x5c, 0x27, 0xb8, 0xe2, 0x06, 0x98, 0xd2, 0x57, 0xb8, 0xc7, 0x4e, 0xea, 0x28, 0x23,
- 0x6e, 0x90, 0x25, 0x2e, 0xb6, 0xf3, 0x5c, 0x18, 0xe8, 0x94, 0xa5, 0x7c, 0x55, 0xbf, 0x22, 0x94, 0xfc, 0x0e, 0xe7, 0x15,
- 0xde, 0xe3, 0x72, 0x80, 0xe7, 0xf1, 0xfd, 0xd4, 0x0e, 0x2a, 0xda, 0x53, 0x56, 0xcb, 0xdb, 0xe3, 0x71, 0xc7, 0xc5, 0xd7,
- 0x35, 0x95, 0x39, 0xf8, 0xee, 0x16, 0x22, 0x3c, 0x19, 0x3e, 0xd4, 0x03, 0x49, 0xe7, 0xf6, 0xb9, 0x50, 0x9f, 0x18, 0xee,
- 0xdf, 0x7b, 0x79, 0xc4, 0x3f, 0xd4, 0x41, 0x45, 0xf2, 0xea, 0xdd, 0x5f, 0xda, 0x17, 0xd3, 0xb0, 0x50, 0xfc, 0x2c, 0xe9,
- 0x6a, 0xb6, 0x35, 0xf3, 0xd7, 0xfd, 0xe6, 0x62, 0x51, 0x16, 0x5c, 0x8d, 0x26, 0xc3, 0x18, 0x9c, 0xf0, 0xb9, 0xe5, 0xa9,
- 0x46, 0xd9, 0xe3, 0x80, 0x6c, 0xe3, 0x66, 0x70, 0xed, 0x4e, 0xfd, 0xf9, 0x8b, 0xdb, 0x06, 0x56, 0x3f, 0x2d, 0xfe, 0x74,
- 0xee, 0x66, 0x75, 0x2a, 0xad, 0x1e, 0x41, 0x6c, 0x1b, 0x6a, 0xe4, 0x90, 0x76, 0x48, 0x27, 0x73, 0x4b, 0x13, 0xda, 0x72,
- 0xa6, 0x7f, 0xc2, 0x7c, 0xb5, 0xca, 0x4c, 0x15, 0x64, 0x27, 0x9e, 0xc4, 0x9e, 0x3a, 0xb4, 0x13, 0x9d, 0xb8, 0x02, 0x3f,
- 0x92, 0x6c, 0xe5, 0x73, 0x3e, 0x61, 0xbb, 0x01, 0xec, 0x81, 0x9b, 0x64, 0x59, 0x11, 0x4e, 0x42, 0x8b, 0x31, 0x97, 0x16,
- 0x18, 0x53, 0x98, 0x82, 0x6e, 0xa5, 0x44, 0x7f, 0xcf, 0x05, 0x9c, 0x2c, 0x9d, 0x8f, 0xe3, 0x45, 0x57, 0xb2, 0xb5, 0x7a,
- 0x71, 0x62, 0x25, 0x41, 0x8b, 0xed, 0xe9, 0x08, 0x46, 0x44, 0xda, 0xe3, 0xa3, 0xdf, 0x4b, 0x66, 0x77, 0x19, 0xc2, 0x4f,
- 0xbb, 0xa7, 0xde, 0x4b, 0xa0, 0xbd, 0x95, 0x0f, 0xe1, 0x10, 0x49, 0x13, 0xa3, 0xec, 0x80, 0x27, 0xbb, 0x8b, 0xc8, 0xed,
- 0x7a, 0x3a, 0x70, 0x5d, 0xea, 0x93, 0x6c, 0x0c, 0xc7, 0x2f, 0x41, 0x15, 0x64, 0x3d, 0x3a, 0x65, 0x02, 0x72, 0x78, 0xc9,
- 0x35, 0x61, 0xe8, 0xd9, 0x63, 0x3f, 0x45, 0x7f, 0x04, 0xaf, 0x0b, 0x37, 0x7a, 0x66, 0x4e, 0x49, 0x3d, 0x6c, 0x3d, 0x2a,
- 0xda, 0x0b, 0x81, 0x6d, 0x9f, 0x51, 0xea, 0xf6, 0x23, 0x6d, 0x7f, 0xcb, 0x75, 0x02, 0x49, 0x5e, 0x69, 0x57, 0x5b, 0x14,
- 0xcb, 0xc2, 0xc8, 0xd4, 0xe4, 0x68, 0xab, 0xec, 0x51, 0x19, 0x80, 0xe4, 0xc1, 0xc7, 0x9b, 0x99, 0x15, 0xe1, 0x25, 0xf9,
- 0x58, 0x18, 0x45, 0x0c, 0xde, 0xa7, 0x14, 0xe6, 0x96, 0xd5, 0xb8, 0x36, 0x83, 0x35, 0xfe, 0x77, 0x51, 0x4a, 0x57, 0x2e,
- 0xaa, 0x26, 0x13, 0x23, 0x5d, 0x7d, 0xcf, 0x93, 0xce, 0x4a, 0x9a, 0xff, 0x03, 0x48, 0xf7, 0x10, 0x09, 0xe2, 0x01, 0xbb,
- 0x17, 0xb6, 0x9d, 0xc7, 0x27, 0xe2, 0xd1, 0x26, 0xf1, 0x7c, 0xd0, 0x53, 0xf6, 0x53, 0x76, 0xfd, 0x39, 0x58, 0xd2, 0xc8,
- 0xa8, 0x90, 0xa9, 0x75, 0x16, 0xaf, 0xe2, 0x91, 0x40, 0x53, 0x2e, 0x08, 0xdd, 0xb9, 0xfb, 0x17, 0x51, 0x51, 0x1b, 0xb9,
- 0x12, 0xf0, 0x31, 0xd8, 0x48, 0x8f, 0x7d, 0x08, 0x9d, 0x1d, 0x2a, 0xb5, 0xcd, 0x46, 0x23, 0x2c, 0xf3, 0xb5, 0x11, 0x91,
- 0x7f, 0x3c, 0x7a, 0x5e, 0x75, 0x90, 0x0e, 0xc0, 0xc0, 0x4f, 0x5e, 0xcb, 0xbc, 0x33, 0x09, 0x88, 0x4e, 0x68, 0xac, 0xba,
- 0x46, 0x31, 0x41, 0x98, 0xf5, 0x75, 0x87, 0xf6, 0x0c, 0x0c, 0xaa, 0x84, 0x75, 0xe4, 0xfa, 0xa3, 0x1e, 0xe1, 0xe2, 0x88,
- 0x09, 0xf0, 0x57, 0x8b, 0xdc, 0x47, 0x7b, 0xff, 0x39, 0xac, 0x51, 0x8b, 0x00, 0x08, 0xc0, 0x9f, 0xd4, 0xa4, 0xbe, 0xe5,
- 0x41, 0x8b, 0xc5, 0x66, 0xdb, 0xed, 0x08, 0x0b, 0xdf, 0xa4, 0x2b, 0x5a, 0x59, 0xde, 0x0e, 0x9c, 0x8b, 0x7f, 0xd1, 0x80,
- 0x4d, 0xf9, 0x22, 0x60, 0x2c, 0xd4, 0xf9, 0x1c, 0xd7, 0xf5, 0xbd, 0x64, 0x7f, 0x4f, 0xeb, 0xf8, 0xa5, 0xb2, 0x34, 0x3d,
- 0xfa, 0x07, 0xef, 0x44, 0x3c, 0x00, 0x2c, 0xec, 0x36, 0x36, 0xdd, 0xd5, 0x5c, 0xbd, 0x6b, 0x27, 0xba, 0x13, 0x91, 0x90,
- 0x58, 0xe7, 0x75, 0x89, 0x00, 0x6b, 0x5a, 0x0c, 0x35, 0x9c, 0xe3, 0x8a, 0xd8, 0x46, 0xd2, 0x15, 0x14, 0x8b, 0x8b, 0xff,
- 0x6a, 0x35, 0xf9, 0xd7, 0x65, 0x67, 0x56, 0x6d, 0xd5, 0x2d, 0x9c, 0xd6, 0xb1, 0xe2, 0x9a, 0xb0, 0xfa, 0x0e, 0xa2, 0xd5,
- 0x5d, 0x30, 0x15, 0x8e, 0x48, 0x59, 0xd0, 0x13, 0xa7, 0x2b, 0x40, 0x97, 0x8c, 0xe4, 0x02, 0x38, 0x28, 0x54, 0x53, 0x6c,
- 0x1c, 0xc7, 0x38, 0x06, 0xe9, 0xfc, 0x2d, 0xd5, 0x59, 0x74, 0x77, 0x62, 0x14, 0xf2, 0xa7, 0x7e, 0xfe, 0x59, 0xbf, 0xdf,
- 0x8b, 0x6e, 0xd7, 0x66, 0xd1, 0x6a, 0xb9, 0xe6, 0x35, 0x98, 0xc6, 0x76, 0x44, 0x38, 0xb4, 0xe8, 0x3c, 0xf5, 0x3c, 0x27,
- 0xb9, 0xa1, 0x21, 0x7d, 0x17, 0xf9, 0xb3, 0x1e, 0x30, 0xe7, 0xab, 0xd5, 0x2d, 0x8c, 0x02, 0xc3, 0xa4, 0x3c, 0xf4, 0x09,
- 0x9f, 0x17, 0xc1, 0xce, 0xc9, 0xf5, 0xdf, 0xdb, 0x8b, 0xf5, 0x05, 0x14, 0x6d, 0x74, 0xdf, 0xa9, 0x0b, 0x87, 0x98, 0x17,
- 0xf3, 0x68, 0x8d, 0xb3, 0xbc, 0x86, 0x3a, 0x47, 0x1d, 0x29, 0x80, 0x40, 0xba, 0xb0, 0x3d, 0x65, 0x0d, 0xd7, 0x95, 0x4a,
- 0x79, 0x0d, 0x34, 0x20, 0x72, 0x25, 0xaa, 0x71, 0x43, 0x5c, 0x52, 0x0b, 0x69, 0xde, 0xf7, 0xc5, 0xfd, 0xdb, 0x41, 0x05,
- 0xb1, 0xde, 0x94, 0xdb, 0xc4, 0xe4, 0x85, 0xf2, 0x6c, 0xc5, 0xd1, 0x04, 0xcd, 0xd7, 0x84, 0x0b, 0xd8, 0xa8, 0x2c, 0x68,
- 0xfd, 0xe7, 0x30, 0xaf, 0x6e, 0xae, 0x02, 0x3f, 0xea, 0x13, 0x68, 0xb0, 0xd1, 0xef, 0x6d, 0x78, 0xf8, 0x77, 0x3e, 0xe8,
- 0x03, 0x05, 0x6e, 0x00, 0x59, 0xf1, 0xde, 0x57, 0xbe, 0xfa, 0x6b, 0xde, 0x47, 0x86, 0x21, 0xa0, 0x8e, 0xcc, 0x0b, 0x15,
- 0x7e, 0x7d, 0xd2, 0x59, 0x37, 0x7f, 0x74, 0xc5, 0x79, 0x8e, 0xf0, 0x37, 0x9b, 0xb3, 0x0e, 0x7f, 0x14, 0x91, 0x0e, 0xe5,
- 0xe8, 0xdf, 0xf7, 0xdf, 0x6b, 0x59, 0x79, 0x37, 0x90, 0x99, 0xc8, 0xff, 0xb2, 0xe9, 0xe4, 0x35, 0x8c, 0x20, 0xde, 0x8c,
- 0x6c, 0xb8, 0x87, 0x16, 0xdd, 0xc4, 0x4b, 0x5e, 0x93, 0x38, 0x06, 0x0f, 0x4a, 0xb0, 0xba, 0xe1, 0xc5, 0xb1, 0x5d, 0x5f,
- 0x3a, 0x2e, 0x84, 0x56, 0x72, 0x13, 0xb2, 0xb4, 0xdf, 0xc0, 0x36, 0xe6, 0xf2, 0xee, 0x77, 0x93, 0xc1, 0xc7, 0xc5, 0xe5,
- 0x58, 0x66, 0x3e, 0x8c, 0x5d, 0xe3, 0x5d, 0xbd, 0x43, 0xf6, 0x72, 0x51, 0xe7, 0x4c, 0xd4, 0x2f, 0x46, 0x12, 0x66, 0xc2,
- 0x7a, 0xd4, 0xd9, 0x75, 0x25, 0xa5, 0x63, 0x60, 0x9c, 0xc4, 0xff, 0x0a, 0xec, 0x8d, 0x13, 0x22, 0x3e, 0x95, 0xe8, 0xd9,
- 0xd4, 0xa4, 0x12, 0xba, 0x46, 0x93, 0x1f, 0x6b, 0x9f, 0xb2, 0xba, 0xca, 0x39, 0xda, 0x32, 0xe5, 0x5c, 0xb3, 0x86, 0xc9,
- 0x86, 0xb9, 0x9c, 0x92, 0x72, 0xe4, 0xa7, 0x53, 0xe4, 0x39, 0x07, 0x96, 0xc6, 0x18, 0xbc, 0xfc, 0x2e, 0x5f, 0xd6, 0x15,
- 0x2c, 0x73, 0x01, 0x05, 0x74, 0xd7, 0x9a, 0x34, 0x35, 0x56, 0x32, 0xb7, 0x50, 0x22, 0x76, 0x66, 0x4d, 0x6f, 0xd1, 0x19,
- 0x6a, 0x79, 0xc1, 0x3f, 0x15, 0x21, 0x04, 0x14, 0x34, 0xc9, 0x9a, 0xdb, 0x25, 0x0d, 0xfb, 0xa9, 0x53, 0xc0, 0x5f, 0xac,
- 0xb7, 0xec, 0x67, 0xac, 0x8e, 0x46, 0x4c, 0xd7, 0x1b, 0x9b, 0x25, 0x87, 0x97, 0x73, 0xd9, 0xc8, 0xb3, 0x65, 0x22, 0x3b,
- 0x35, 0xc0, 0x2f, 0xf5, 0x7d, 0xa4, 0x9b, 0x79, 0x92, 0xfb, 0xb6, 0x0b, 0xc9, 0xf9, 0x88, 0xc5, 0x5b, 0x88, 0x21, 0x0d,
- 0xcf, 0xd9, 0x83, 0x6d, 0xae, 0x58, 0x3f, 0xac, 0x88, 0x16, 0xae, 0x3f, 0xb5, 0xdb, 0x78, 0x1c, 0x03, 0x3a, 0x19, 0xf1,
- 0xbe, 0xc6, 0x46, 0x12, 0x6b, 0x18, 0x0b, 0x70, 0x83, 0x2d, 0x2f, 0x16, 0xac, 0xa9, 0x31, 0x2d, 0xf3, 0xe5, 0xd7, 0xe1,
- 0x0e, 0x0e, 0x23, 0xb3, 0x9e, 0xc5, 0x6e, 0x35, 0xb7, 0xc4, 0x7f, 0xac, 0x60, 0x92, 0xde, 0x73, 0x3b, 0x02, 0xb6, 0xf5,
- 0x97, 0xe6, 0xe1, 0x55, 0x50, 0x72, 0xd2, 0xb4, 0xbd, 0xcd, 0x7e, 0x11, 0xe4, 0x7b, 0x4b, 0xa5, 0x6b, 0x7e, 0xbf, 0xb8,
- 0x4a, 0x1f, 0xf6, 0x34, 0x29, 0xee, 0x28, 0xb0, 0x45, 0x7d, 0x48, 0xc2, 0x18, 0xb2, 0x15, 0x0c, 0xe5, 0x5a, 0x3e, 0xee,
- 0xdd, 0x1f, 0x20, 0x7b, 0xe6, 0x79, 0x60, 0xee, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d,
- 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
- 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
- 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
- 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x08, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x49, 0x00, 0x00, 0x09, 0x4d, 0x00, 0x00, 0x09, 0x61,
- 0x00, 0x00, 0x09, 0x65, 0x00, 0x00, 0x09, 0x69, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x00, 0x09, 0x71, 0x00, 0x00, 0x09, 0x89,
- 0x00, 0x00, 0x09, 0x8d, 0x00, 0x00, 0x09, 0xb9, 0x00, 0x00, 0x09, 0xbd, 0x00, 0x00, 0x09, 0xc1, 0x00, 0x00, 0x09, 0xc5,
- 0x00, 0x00, 0x09, 0xd1, 0x00, 0x00, 0x09, 0xdd, 0x00, 0x00, 0x09, 0xe1, 0x00, 0x00, 0x09, 0xe5, 0x00, 0x00, 0x09, 0xe9,
- 0x00, 0x00, 0x09, 0xed, 0x00, 0x00, 0x09, 0xf1, 0x00, 0x00, 0x09, 0xf5, 0x00, 0x00, 0x09, 0xf9, 0x00, 0x00, 0x09, 0xfd,
- 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x09, 0x00, 0x00, 0x0a, 0x0d, 0xfa, 0xde, 0x07, 0x11,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x08, 0xc4, 0x7a, 0x50, 0x55, 0x75, 0xed, 0x3d, 0xfc, 0x68,
- 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xb4, 0x4e, 0xa3, 0xa8, 0x86, 0x4f, 0x76, 0xe9,
- 0x0f, 0x06, 0x2d, 0xca, 0x91, 0x26, 0x8e, 0x86, 0x1a, 0x1f, 0xb9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67,
- 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae,
- 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba, 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73,
- 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73,
- 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e,
- 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73,
- 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x14, 0xf7, 0xc4, 0x67, 0x03, 0x4c, 0xab, 0x35, 0xae, 0x20, 0x64, 0x45, 0xf0, 0xe3, 0x48, 0xbc, 0xba,
- 0x5f, 0xac, 0x81, 0xda, 0x00, 0x00, 0x00, 0x74, 0x2f, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x4c, 0x69, 0x62, 0x72,
- 0x61, 0x72, 0x79, 0x2f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x43, 0x65, 0x72,
- 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2e, 0x61,
- 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x43, 0x65,
- 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x10, 0x49, 0xe1, 0x42,
- 0x39, 0xee, 0xe2, 0xbd, 0x76, 0x61, 0x00, 0x6f, 0xe5, 0xf4, 0xbe, 0xdb, 0xbc, 0x89, 0xbe, 0x56, 0x00, 0x00, 0x00, 0x44,
- 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x4d, 0x61, 0x69, 0x6c, 0x2e, 0x61,
- 0x70, 0x70, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x61,
- 0x69, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14,
- 0x55, 0x29, 0x46, 0xa2, 0xfb, 0x92, 0xda, 0xe4, 0xf8, 0x4c, 0x7d, 0xdd, 0xc3, 0x4e, 0x52, 0x62, 0xff, 0x0f, 0xd2, 0x04,
- 0x00, 0x00, 0x00, 0x40, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x2f, 0x72, 0x61, 0x63, 0x6f, 0x6f, 0x6e,
- 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x72, 0x61,
- 0x63, 0x6f, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
- 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1d,
- 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x61, 0x6e, 0x61,
- 0x67, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00,
- 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67,
- 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x84, 0x5f, 0xda, 0x57, 0x4e, 0xc0, 0xb5, 0x32, 0xdf, 0xc4, 0x87, 0x7f, 0x8c, 0x04, 0x1f, 0x65, 0xa2, 0x23, 0x20, 0x8c,
- 0xab, 0x49, 0x2f, 0xff, 0x12, 0xfa, 0x57, 0x33, 0xf8, 0xcb, 0x7a, 0xcd, 0xc4, 0x7b, 0xc0, 0xf6, 0xf7, 0xe7, 0x2f, 0x7d,
- 0x3f, 0xec, 0xf5, 0x8a, 0xee, 0x1e, 0x26, 0xe9, 0x12, 0x96, 0xdb, 0xa2, 0x2a, 0xf6, 0xb9, 0x3c, 0x68, 0x14, 0x49, 0x86,
- 0x00, 0xc0, 0xaa, 0x29, 0xd3, 0xad, 0x4b, 0x48, 0xca, 0x48, 0x3f, 0xdb, 0x36, 0xdd, 0x3d, 0x3b, 0x18, 0x59, 0x26, 0x2a,
- 0x9e, 0x5f, 0x86, 0xe9, 0x4b, 0xaa, 0x83, 0x60, 0x20, 0x36, 0x1e, 0x59, 0x17, 0x33, 0x5b, 0x20, 0x42, 0x7a, 0x59, 0xfd,
- 0xb3, 0xa2, 0x5f, 0x2b, 0xdb, 0x63, 0x7e, 0x66, 0xee, 0x5e, 0xf5, 0x22, 0x0c, 0x10, 0x61, 0xd3, 0x9e, 0x3d, 0xce, 0x62,
- 0x6b, 0xc3, 0x97, 0x86, 0x68, 0x61, 0x2a, 0x31, 0xaa, 0x7d, 0x5d, 0x18, 0x1f, 0xe9, 0xc3, 0x12, 0xb7, 0x0d, 0x14, 0x84,
- 0x5c, 0xa0, 0x84, 0x0c, 0x07, 0xef, 0x01, 0xf4, 0xd3, 0xa1, 0x14, 0xa8, 0x5a, 0xb8, 0x15, 0xb7, 0x1b, 0x7a, 0x4a, 0x12,
- 0x2f, 0x9d, 0x8f, 0x79, 0xb1, 0x74, 0x3e, 0x50, 0xd5, 0x99, 0x9c, 0x26, 0x7d, 0x37, 0xaf, 0xc7, 0x7b, 0x15, 0x8c, 0x07,
- 0xae, 0x74, 0xef, 0xc3, 0xb1, 0x6a, 0xa2, 0x76, 0xf9, 0x6d, 0x6e, 0xc2, 0x6a, 0x01, 0x9a, 0x5f, 0x23, 0xf4, 0xd5, 0xe3,
- 0x6a, 0x34, 0x86, 0x1e, 0x9d, 0xed, 0x5c, 0x09, 0xd3, 0xba, 0xff, 0x2d, 0xbe, 0x4b, 0xbb, 0x6c, 0x6a, 0x20, 0xc9, 0x8b,
- 0x51, 0xcd, 0x4c, 0x91, 0x51, 0x6d, 0xf5, 0x80, 0x42, 0x31, 0xc1, 0x3a, 0x10, 0xdc, 0xb4, 0x92, 0x97, 0x18, 0xcc, 0x26,
- 0xf1, 0xe6, 0x18, 0xe1, 0x97, 0x21, 0x94, 0x3d, 0xca, 0xa7, 0xb5, 0xcd, 0xce, 0x53, 0x7b, 0x16, 0x0b, 0x80, 0x8d, 0x4c,
- 0xc8, 0x28, 0xc8, 0x55, 0xcf, 0xc7, 0xba, 0xd1, 0x05, 0x6a, 0x66, 0x72, 0x51, 0xb2, 0xd4, 0x3d, 0x81, 0x8d, 0xc5, 0xb3,
- 0x86, 0xa6, 0x02, 0x53, 0x16, 0x2a, 0x2a, 0x40, 0xf1, 0x8d, 0xff, 0x42, 0x9a, 0x12, 0xd2, 0x46, 0x1d, 0x42, 0x98, 0x1f,
- 0x1c, 0x52, 0x3f, 0x11, 0xa7, 0x12, 0xa7, 0xba, 0xb7, 0x84, 0xba, 0x80, 0xdf, 0x3e, 0x89, 0xcd, 0x81, 0x05, 0x98, 0x0a,
- 0x92, 0x3e, 0x4b, 0x61, 0x44, 0x2f, 0xb8, 0xfe, 0x86, 0x56, 0x6b, 0xe1, 0xc0, 0xb4, 0x09, 0x52, 0x6c, 0xb2, 0xff, 0x1f,
- 0xe7, 0x74, 0x98, 0xb6, 0x65, 0x47, 0x31, 0x5a, 0x33, 0x3a, 0x8c, 0x05, 0x18, 0xa5, 0x25, 0xc6, 0xb7, 0x18, 0x29, 0xf9,
- 0x87, 0x7c, 0x3c, 0x3d, 0x70, 0x56, 0x60, 0xfe, 0x0c, 0xb9, 0x17, 0x89, 0xa0, 0x72, 0xe6, 0xa5, 0x2f, 0xa6, 0xa9, 0xc4,
- 0x34, 0x5a, 0xbe, 0x0d, 0xa5, 0xf3, 0xac, 0xe8, 0x69, 0xa8, 0x2e, 0x50, 0xa2, 0xc1, 0x99, 0x7e, 0x7c, 0xd2, 0xd7, 0x60,
- 0x1b, 0x41, 0xe4, 0x1f, 0x76, 0x5c, 0xeb, 0x1b, 0x28, 0x53, 0xd3, 0xab, 0x48, 0xd0, 0x7f, 0xb8, 0x9d, 0x70, 0x39, 0x8a,
- 0xcd, 0x3c, 0x0f, 0x03, 0x5e, 0xe8, 0xa9, 0x95, 0x60, 0x54, 0x93, 0xfa, 0xd1, 0x9b, 0x49, 0xdb, 0x34, 0x32, 0x36, 0x38,
- 0x56, 0xbb, 0xbf, 0xcf, 0x54, 0xe6, 0x5c, 0xa2, 0x8a, 0x9e, 0x73, 0x83, 0xa0, 0x53, 0x71, 0xfd, 0xef, 0x49, 0x1a, 0xa7,
- 0x06, 0xca, 0x90, 0xd5, 0x2f, 0x31, 0xb4, 0x52, 0x0f, 0xaf, 0xfe, 0x6c, 0x19, 0x6d, 0xca, 0x11, 0xaa, 0xaf, 0x24, 0x21,
- 0x47, 0x7f, 0x15, 0x47, 0x51, 0x96, 0x59, 0x3b, 0x27, 0x13, 0xc6, 0x50, 0x7b, 0x1c, 0x84, 0x0d, 0x61, 0x3d, 0x51, 0x58,
- 0x9c, 0xe4, 0x65, 0x06, 0x1f, 0x7b, 0x91, 0x98, 0x7d, 0x35, 0x8c, 0x9f, 0xba, 0x38, 0x90, 0x89, 0xa2, 0xae, 0x68, 0x68,
- 0x4b, 0x11, 0x2f, 0xea, 0x4d, 0xcb, 0x01, 0x59, 0x94, 0x26, 0x52, 0x37, 0x01, 0x6e, 0xfb, 0x01, 0x8b, 0x61, 0x59, 0x5b,
- 0x49, 0xdf, 0xf2, 0x1c, 0x48, 0xbc, 0xed, 0x98, 0x8f, 0x09, 0x38, 0xa2, 0xf8, 0x27, 0xbb, 0x1a, 0x04, 0xcf, 0xd0, 0x4a,
- 0x93, 0x32, 0xb8, 0x9d, 0x2f, 0x9c, 0xf3, 0xb2, 0xa8, 0x56, 0x47, 0xff, 0xa1, 0x28, 0x60, 0x6b, 0xc2, 0x3c, 0x1b, 0x48,
- 0x5d, 0xc9, 0x05, 0x39, 0x98, 0xe5, 0x98, 0xfb, 0x17, 0x3f, 0x6d, 0x41, 0x8d, 0xc5, 0xa1, 0xee, 0x31, 0x19, 0x00, 0x2d,
- 0xfb, 0x1e, 0x8f, 0x5f, 0x72, 0x6a, 0x92, 0x64, 0x01, 0xad, 0xcc, 0x90, 0x14, 0x48, 0x83, 0x88, 0x2e, 0xc1, 0x58, 0xe5,
- 0x33, 0xa4, 0x19, 0xc3, 0x1d, 0xee, 0x06, 0xb6, 0x96, 0xb7, 0x57, 0x04, 0xa5, 0x4a, 0xa0, 0xa5, 0x1b, 0xa5, 0xda, 0x91,
- 0xb7, 0x2c, 0xcd, 0x6d, 0x81, 0xff, 0x9f, 0xac, 0xc9, 0x05, 0x26, 0x8f, 0xb2, 0x37, 0x3c, 0xb8, 0x53, 0xab, 0x2b, 0xaf,
- 0x9e, 0x22, 0xd2, 0xcd, 0xf4, 0x65, 0xf3, 0x84, 0x68, 0x83, 0xc2, 0xf8, 0xb7, 0x05, 0x25, 0xfe, 0x08, 0x2c, 0xb2, 0xb4,
- 0xf3, 0x95, 0x63, 0x9a, 0xcc, 0x9d, 0xb1, 0xee, 0x5c, 0x53, 0x3b, 0x6b, 0xab, 0x0e, 0x95, 0x50, 0xcc, 0x8e, 0xc3, 0x97,
- 0x43, 0x67, 0xe5, 0x49, 0xd0, 0x20, 0xbd, 0xda, 0x45, 0x6c, 0xef, 0x9a, 0xc7, 0x47, 0xdc, 0x7f, 0xda, 0xab, 0xf2, 0x8a,
- 0xc5, 0x4f, 0xc5, 0xdb, 0xba, 0x87, 0x5f, 0xc1, 0xe0, 0x12, 0xc0, 0xb1, 0x3e, 0x1b, 0x72, 0x34, 0x00, 0x9f, 0x0a, 0xb4,
- 0x99, 0xf8, 0x33, 0xe7, 0xb7, 0xc6, 0xc0, 0xed, 0xe6, 0x2c, 0x1b, 0x29, 0x9c, 0xfd, 0xeb, 0x6f, 0x9b, 0x0a, 0x55, 0xd2,
- 0x09, 0xa2, 0x64, 0x49, 0x39, 0x30, 0x33, 0xb2, 0x77, 0x31, 0x32, 0x81, 0x25, 0x58, 0x66, 0x4d, 0xd2, 0xc2, 0xa6, 0x18,
- 0xdc, 0xfc, 0x0a, 0x73, 0x5f, 0xbc, 0xcc, 0xef, 0xfe, 0xee, 0x1d, 0x3d, 0xb8, 0x21, 0xfb, 0x52, 0x25, 0x6f, 0xc3, 0x99,
- 0x67, 0xa1, 0x69, 0x20, 0xb3, 0x01, 0xb4, 0x75, 0xbe, 0x08, 0x49, 0x2e, 0xe3, 0x6f, 0x1a, 0xd0, 0xe9, 0x7c, 0xec, 0xbf,
- 0x98, 0x45, 0x82, 0xf8, 0xc4, 0x77, 0x74, 0x20, 0xc9, 0x5f, 0xa1, 0x8b, 0xf4, 0xa8, 0x4d, 0x12, 0xd5, 0x92, 0xd1, 0xe1,
- 0x42, 0x4b, 0xa2, 0x45, 0x18, 0x60, 0xaf, 0x9a, 0xf2, 0xe4, 0xcf, 0x3e, 0x66, 0x87, 0x12, 0x0e, 0xa7, 0x55, 0x53, 0x96,
- 0xcb, 0xcf, 0xd3, 0x34, 0xab, 0xdd, 0x20, 0x0f, 0x62, 0x9a, 0xb4, 0x86, 0x2f, 0x9f, 0x01, 0xda, 0xd6, 0xe6, 0x2b, 0xe2,
- 0x5b, 0xb9, 0x74, 0xd8, 0x28, 0xad, 0x94, 0x89, 0x3e, 0x3a, 0x2a, 0x82, 0xa2, 0x0a, 0x7b, 0x4b, 0x4f, 0x3f, 0xed, 0x7f,
- 0x2a, 0x3a, 0x06, 0xc8, 0xd4, 0x65, 0xcd, 0x60, 0x19, 0x79, 0x36, 0x31, 0x4c, 0xc1, 0x1e, 0x55, 0x22, 0x4f, 0x6e, 0xe0,
- 0x1b, 0xab, 0x0b, 0x49, 0xa8, 0x9f, 0xf9, 0xc9, 0x6c, 0xd4, 0xd6, 0xfa, 0x07, 0xcd, 0xf5, 0xe7, 0x94, 0x51, 0x1b, 0x3d,
- 0xc5, 0x00, 0x79, 0x38, 0xaf, 0xc0, 0x23, 0x60, 0x2b, 0x92, 0xda, 0x76, 0x69, 0xf7, 0xda, 0x23, 0xf9, 0xa6, 0x21, 0x34,
- 0xc6, 0xf3, 0xc3, 0x69, 0xa6, 0x25, 0x87, 0x70, 0x5c, 0x0c, 0xc1, 0xfc, 0x9c, 0x30, 0xbc, 0xdf, 0x26, 0xbe, 0x4b, 0x49,
- 0x44, 0xdd, 0x2f, 0x21, 0xc1, 0xa8, 0xcd, 0x54, 0x7a, 0xa4, 0x1b, 0xae, 0x82, 0xce, 0x05, 0x50, 0x9c, 0xb6, 0x85, 0x5d,
- 0xf9, 0xbd, 0xdd, 0x4a, 0x56, 0x51, 0x32, 0x50, 0xdd, 0xaa, 0x55, 0xfe, 0x26, 0x3c, 0xee, 0x36, 0xa4, 0xa8, 0x53, 0x66,
- 0x72, 0x89, 0xf6, 0xa3, 0x25, 0x7a, 0x23, 0x53, 0x29, 0x4d, 0x34, 0x29, 0x62, 0x94, 0x4f, 0x4f, 0x1b, 0x53, 0xcb, 0xc1,
- 0x7c, 0xd1, 0x50, 0x8e, 0xa3, 0x19, 0x89, 0xfa, 0x90, 0x42, 0x69, 0x16, 0xd0, 0x6f, 0xf8, 0x7a, 0xc2, 0x9e, 0x67, 0xe8,
- 0xe8, 0xff, 0xf1, 0x61, 0x7b, 0x31, 0x19, 0xcf, 0xf1, 0x27, 0xee, 0xab, 0x63, 0xe8, 0xdb, 0xf7, 0x4c, 0xbf, 0xcf, 0x2f,
- 0xe7, 0x83, 0x92, 0xf8, 0x6d, 0x15, 0x9e, 0x1d, 0x77, 0xef, 0x40, 0x79, 0x58, 0xe4, 0xf9, 0xa7, 0x3d, 0xb6, 0x2d, 0xd0,
- 0xfc, 0x01, 0x66, 0x20, 0x2c, 0xd1, 0x29, 0x86, 0x9b, 0x88, 0xcd, 0x98, 0xb4, 0x66, 0x61, 0x94, 0x58, 0x56, 0xf4, 0xff,
- 0x60, 0x90, 0xf2, 0x8c, 0x07, 0x1c, 0x0b, 0x13, 0xfe, 0xb6, 0x58, 0x15, 0x6a, 0x8a, 0xd7, 0x98, 0xb2, 0x3e, 0xee, 0x49,
- 0xdb, 0x3a, 0x0f, 0x98, 0x27, 0xc6, 0x88, 0xc5, 0x15, 0xe5, 0x67, 0x08, 0x09, 0xfc, 0x63, 0x6c, 0x8f, 0x30, 0xf4, 0x95,
- 0xb7, 0x69, 0xd4, 0x47, 0x93, 0xe5, 0xa6, 0xf9, 0x73, 0xdd, 0x98, 0xb4, 0x66, 0x02, 0x1f, 0x3b, 0xe7, 0x53, 0x9f, 0x54,
- 0x44, 0x0b, 0x9b, 0xdb, 0xe8, 0xaa, 0x77, 0xc3, 0x89, 0x65, 0x12, 0xb2, 0xc5, 0x2f, 0x5e, 0xaa, 0xff, 0xab, 0x72, 0x1f,
- 0xf1, 0xd3, 0xdc, 0x8f, 0xaf, 0x13, 0x31, 0xaa, 0x5d, 0x48, 0x5a, 0x1b, 0x31, 0x61, 0x0b, 0x48, 0x9b, 0xe6, 0x75, 0x2e,
- 0xd5, 0xdb, 0xd3, 0x22, 0xb5, 0x77, 0x9b, 0x45, 0xc2, 0x9d, 0x1b, 0xe2, 0x2b, 0x8c, 0x14, 0x99, 0x10, 0x7c, 0x24, 0x18,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67,
- 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97,
- 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61,
- 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30,
- 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x11, 0x2c, 0x00, 0x00, 0x12, 0x50, 0x00, 0x00, 0x12, 0xb0,
- 0x00, 0x00, 0x12, 0xe8, 0x00, 0x00, 0x13, 0x20, 0x00, 0x00, 0x13, 0x58, 0x00, 0x00, 0x13, 0x90, 0x00, 0x00, 0x13, 0xc8,
- 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x38, 0x00, 0x00, 0x14, 0x70, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x70, 0x00, 0x00, 0x11, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5,
- 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
- 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
- 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
- 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14,
- 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
- 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
- 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0x78, 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8,
- 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14,
- 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65,
- 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x12, 0xd8, 0x00, 0x00, 0x12, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x13, 0x10, 0x00, 0x00, 0x13, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x48,
- 0x00, 0x00, 0x13, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x80, 0x00, 0x00, 0x13, 0x88,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xb8, 0x00, 0x00, 0x13, 0xc0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0xf0, 0x00, 0x00, 0x13, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x14, 0x28, 0x00, 0x00, 0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x60,
- 0x00, 0x00, 0x14, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x98, 0x00, 0x00, 0x14, 0xa0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1e, 0xbc, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x15, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x02, 0xf8,
- 0x00, 0x00, 0x05, 0xe4, 0x00, 0x00, 0x08, 0xa4, 0x00, 0x00, 0x0e, 0xfc, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x11, 0xe4,
- 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5, 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15,
- 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d,
- 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d, 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81,
- 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d,
- 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1,
- 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70, 0xea, 0x6d, 0x4d, 0x2b, 0x42, 0xd6, 0x1d, 0xa7, 0x00, 0x00, 0x00, 0x02,
- 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x59, 0x1b, 0x38, 0x6f, 0x83, 0xff, 0xcf, 0x13, 0x00, 0xc5, 0x58, 0x14,
- 0x81, 0x60, 0xd5, 0xf2, 0x76, 0x2d, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25,
- 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe5, 0x1f, 0x40, 0x4b, 0xde, 0x16, 0xe0, 0x41,
- 0xc5, 0xdc, 0x68, 0x83, 0xfb, 0x0f, 0x7b, 0xad, 0x62, 0x9d, 0xa3, 0xee, 0xea, 0xa9, 0x6b, 0x27, 0x69, 0x1e, 0xea, 0xc7,
- 0x1c, 0xf7, 0x06, 0xa5, 0x76, 0xcd, 0x9d, 0x65, 0x3c, 0xb1, 0x30, 0x6a, 0x30, 0xd1, 0x31, 0xbd, 0x8a, 0x19, 0x90, 0x89,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0,
- 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0,
- 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
- 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
- 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x25, 0x00, 0x00, 0x02, 0x3d,
- 0x00, 0x00, 0x02, 0x41, 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x65,
- 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1,
- 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5,
- 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
- 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0xfa, 0xde, 0x07, 0x11,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x6c, 0x00, 0x00, 0x01, 0x9c, 0x8b, 0x41, 0x4a, 0x57, 0xa6, 0xf2, 0x36, 0xc2,
- 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0,
- 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x9a, 0xfe, 0xce, 0x76, 0xf7, 0x40, 0x3a, 0x9f,
- 0xd2, 0xc5, 0x69, 0x65, 0x60, 0xea, 0x1a, 0x98, 0xc7, 0xed, 0x28, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65,
- 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63,
- 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c,
- 0x00, 0x00, 0x0c, 0x00, 0x00, 0x5a, 0x4c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73,
- 0x83, 0x67, 0xc1, 0x00, 0xdf, 0x03, 0x66, 0xb0, 0xbb, 0x20, 0xb3, 0x39, 0x84, 0xf0, 0x07, 0xc3, 0x17, 0x75, 0x8a, 0x1b,
- 0xce, 0x2a, 0xb7, 0xc3, 0x31, 0xd7, 0xea, 0xba, 0xa4, 0x38, 0xf5, 0x78, 0x94, 0xa5, 0xff, 0x08, 0x6d, 0x36, 0x41, 0xa5,
- 0x8d, 0x6e, 0xf7, 0x55, 0x1f, 0x6f, 0xe9, 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
- 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
- 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31,
- 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32,
- 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf5,
- 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x15, 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x02, 0x1d,
- 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x69, 0x00, 0x00, 0x02, 0x6d,
- 0x00, 0x00, 0x02, 0x71, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x02, 0x91,
- 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5,
- 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9,
- 0x00, 0x00, 0x02, 0xbd, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x70,
- 0x44, 0x1d, 0x55, 0x6f, 0xda, 0x1b, 0x4a, 0x43, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4,
- 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06,
- 0x23, 0x07, 0xb7, 0x3f, 0xb3, 0x23, 0xad, 0xb2, 0xa9, 0x7f, 0x10, 0x8b, 0x76, 0x89, 0x68, 0x1b, 0x42, 0xb4, 0x45, 0x98,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
- 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b,
- 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xc5, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x23, 0xe5, 0x14, 0x64, 0x77, 0x35, 0x5f, 0x79, 0x3e, 0x4c, 0x4d, 0x5e, 0xee, 0xa7, 0x26, 0x39, 0x7d,
- 0x28, 0x18, 0xd5, 0xf5, 0x08, 0x07, 0x99, 0x37, 0xb1, 0xea, 0x83, 0x7c, 0xbc, 0xeb, 0x64, 0x47, 0xc6, 0xe1, 0x82, 0xfe,
- 0x1f, 0x20, 0x67, 0x1e, 0x37, 0x92, 0x57, 0xaa, 0xbe, 0x4f, 0xac, 0x5f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14,
- 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
- 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
- 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5c,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xb5,
- 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x03, 0x05,
- 0x00, 0x00, 0x03, 0x09, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x29,
- 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39, 0x00, 0x00, 0x03, 0x3d,
- 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0x00, 0x00, 0x03, 0x4d, 0x00, 0x00, 0x03, 0x51,
- 0x00, 0x00, 0x03, 0x55, 0x00, 0x00, 0x03, 0x59, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xdc,
- 0x00, 0x00, 0x02, 0x0c, 0x52, 0x60, 0x55, 0x9c, 0x4a, 0x26, 0x30, 0x1b, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2,
- 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x06, 0x93, 0x56, 0x67, 0xd4, 0x00, 0x07, 0x17, 0xac, 0xc1, 0xbd, 0xea, 0x93, 0x3b, 0xd3, 0x28, 0xa0,
- 0x57, 0xe5, 0x77, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c,
- 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x74,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x9d, 0x01, 0xd2, 0x67, 0xcc, 0xce, 0x6d, 0x38, 0xee, 0x87, 0xc1, 0xcc,
- 0x32, 0xbb, 0xee, 0x47, 0xfa, 0x77, 0x9b, 0xdf, 0x00, 0x00, 0x00, 0x44, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x62, 0x69, 0x6e,
- 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x63, 0x6f, 0x6d, 0x2e,
- 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69, 0x63,
- 0x74, 0x69, 0x76, 0x65, 0xad, 0xa7, 0xd1, 0x01, 0x67, 0x9c, 0xc4, 0xea, 0xc3, 0xdf, 0x8e, 0xc4, 0x08, 0x5b, 0x35, 0x71,
- 0x96, 0xc4, 0xb0, 0x57, 0x19, 0x46, 0xb5, 0x63, 0xce, 0xbb, 0x8e, 0xe7, 0x35, 0x53, 0x02, 0xe2, 0xb2, 0x8d, 0xfa, 0xf4,
- 0x08, 0xdd, 0x5f, 0xda, 0x2e, 0x3e, 0xf4, 0x8c, 0x14, 0x02, 0xe2, 0x53, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14,
- 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
- 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
- 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfc,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x29, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x51,
- 0x00, 0x00, 0x02, 0x55, 0x00, 0x00, 0x02, 0x59, 0x00, 0x00, 0x02, 0x75, 0x00, 0x00, 0x02, 0x79, 0x00, 0x00, 0x02, 0xa5,
- 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xb1, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc9,
- 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x02, 0xdd,
- 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0xed, 0x00, 0x00, 0x02, 0xf1,
- 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x7c,
- 0x00, 0x00, 0x01, 0xa4, 0x3b, 0xaf, 0x30, 0xf6, 0xce, 0x08, 0x47, 0xad, 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2,
- 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xcf,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x06, 0xeb, 0x22, 0x2e, 0xd0, 0xa1, 0x2a, 0x8b, 0xd2, 0x11, 0xac, 0x9f, 0x5b, 0x27, 0x35, 0x5d, 0xd8,
- 0x58, 0x6d, 0x84, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0x8c, 0xbf,
- 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xa8, 0x12, 0x5f, 0x3d, 0x91, 0x36, 0x30, 0x1a,
- 0x76, 0x25, 0x8c, 0xbf, 0x1f, 0x58, 0xcb, 0x76, 0xd6, 0xbb, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
- 0x01, 0x01, 0x00, 0x00, 0xc2, 0xa8, 0x12, 0x5f, 0x3d, 0xc2, 0x91, 0x36, 0x30, 0x1a, 0x76, 0x25, 0xc2, 0x8c, 0xc2, 0xbf,
- 0x1f, 0x58, 0xc3, 0x8b, 0x76, 0xc3, 0x96, 0xc2, 0xbb, 0xc3, 0xbf, 0xc2, 0xb1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3,
- 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26,
- 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xe6, 0x50, 0x17, 0x0a, 0x9f, 0xb9, 0xab, 0x61, 0x5d, 0x77, 0x39, 0x8b,
- 0x76, 0x2d, 0x3f, 0x20, 0xb2, 0xec, 0x7c, 0xbc, 0xa1, 0x54, 0xac, 0x1b, 0x1c, 0x6d, 0x6b, 0x88, 0x3b, 0xd2, 0x7b, 0x6b,
- 0x24, 0x84, 0x7c, 0xca, 0xc7, 0xe8, 0x66, 0x8e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x18, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
- 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61,
- 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30,
- 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xa8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x02, 0x41,
- 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x02, 0x49, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x02, 0x61, 0x00, 0x00, 0x02, 0x65,
- 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9d, 0x00, 0x00, 0x02, 0xa9,
- 0x00, 0x00, 0x02, 0xb5, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x02, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc5,
- 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xcd, 0x00, 0x00, 0x02, 0xd1, 0x00, 0x00, 0x02, 0xd5, 0x00, 0x00, 0x02, 0xd9,
- 0x00, 0x00, 0x02, 0xdd, 0x00, 0x00, 0x02, 0xe1, 0x00, 0x00, 0x02, 0xe5, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0xa8, 0xf4, 0x8e, 0xca, 0x78, 0x14, 0xb8, 0x41, 0x73, 0x00, 0x00, 0x00, 0x02,
- 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21,
- 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x72, 0x3a, 0x27, 0x07, 0x00, 0xae, 0x19, 0xfc, 0x71, 0x1c, 0x6f, 0x2f,
- 0xe2, 0x2b, 0x78, 0x9a, 0xdc, 0x88, 0xc1, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e, 0x94, 0x1b, 0x4d, 0x42,
- 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x98, 0xb9, 0x89, 0x06,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc9, 0x22, 0xdf, 0x1e,
- 0x94, 0x1b, 0x4d, 0x42, 0x21, 0x42, 0x85, 0xcd, 0x32, 0xec, 0xe5, 0xd7, 0xf9, 0x61, 0x38, 0xe1, 0xff, 0xff, 0xff, 0xff,
- 0x98, 0xb9, 0x89, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc3, 0x89, 0x22, 0xc3, 0x9f, 0x1e, 0xc2, 0x94,
- 0x1b, 0x4d, 0x42, 0x21, 0x42, 0xc2, 0x85, 0xc3, 0x8d, 0x32, 0xc3, 0xac, 0xc3, 0xa5, 0xc3, 0x97, 0xc3, 0xb9, 0x61, 0x38,
- 0xc3, 0xa1, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf, 0xc2, 0x98, 0xc2, 0xb9, 0xc2, 0x89, 0x06, 0x01, 0x00, 0x4d,
- 0x00, 0x54, 0x55, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0x7b, 0x74, 0x34, 0xf2,
- 0x79, 0x55, 0x24, 0x13, 0xc5, 0x6c, 0xdd, 0xe2, 0xe7, 0xd5, 0xbf, 0x4e, 0xaa, 0xc8, 0x50, 0xa3, 0xc6, 0x46, 0x67, 0x62,
- 0x08, 0x04, 0x0d, 0xe7, 0x54, 0xe1, 0xb5, 0x0a, 0x53, 0x0d, 0x90, 0xbc, 0xd7, 0x2e, 0x5f, 0x6d, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x08, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70,
- 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
- 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
- 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x02, 0x85, 0x00, 0x00, 0x02, 0x9d,
- 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x02, 0xa5, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x02, 0xc5,
- 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x02, 0xf9, 0x00, 0x00, 0x02, 0xfd, 0x00, 0x00, 0x03, 0x01,
- 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x03, 0x19, 0x00, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x21, 0x00, 0x00, 0x03, 0x25,
- 0x00, 0x00, 0x03, 0x29, 0x00, 0x00, 0x03, 0x2d, 0x00, 0x00, 0x03, 0x31, 0x00, 0x00, 0x03, 0x35, 0x00, 0x00, 0x03, 0x39,
- 0x00, 0x00, 0x03, 0x3d, 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x03, 0x45, 0x00, 0x00, 0x03, 0x49, 0xfa, 0xde, 0x07, 0x11,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x01, 0xfc, 0x1a, 0xe7, 0x86, 0xc7, 0x8e, 0x0c, 0x7b, 0xed,
- 0x00, 0x00, 0x00, 0x02, 0x87, 0x19, 0x1c, 0xa2, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0,
- 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0xbb, 0x34, 0xae, 0xf4, 0x96, 0x00, 0x3a, 0xa9,
- 0x6c, 0x3b, 0x6c, 0xa6, 0x1b, 0xa0, 0xfd, 0x0d, 0x0b, 0x7b, 0xc1, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f,
- 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x50, 0x81, 0xee, 0xbe, 0x1f, 0x36, 0xff, 0x64,
- 0xa1, 0x66, 0x43, 0xd7, 0xdc, 0x0e, 0x61, 0xf0, 0x17, 0xaf, 0x60, 0x35, 0x00, 0x00, 0x00, 0x60, 0x2f, 0x41, 0x70, 0x70,
- 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f,
- 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x00,
- 0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61,
- 0x69, 0x6e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x73, 0xb8, 0x58, 0xf2, 0xef,
- 0xb1, 0x4e, 0x1e, 0x2e, 0x15, 0xe0, 0x0f, 0xb5, 0xea, 0xd4, 0xf5, 0x1e, 0x45, 0x79, 0x80, 0x58, 0xe2, 0xb2, 0x93, 0xf6,
- 0x1c, 0xbf, 0x8c, 0x2b, 0x1d, 0xdb, 0xed, 0x58, 0xd3, 0x90, 0x91, 0xfd, 0x86, 0xbe, 0x01, 0xdd, 0x76, 0x36, 0x01, 0xf0,
- 0x1a, 0x4f, 0xd8, 0x7d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56,
- 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56,
- 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
- 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d,
- 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x8c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x15, 0x64,
- 0x00, 0x00, 0x18, 0xe0, 0x00, 0x00, 0x19, 0xf4, 0x00, 0x00, 0x1a, 0x7c, 0x00, 0x00, 0x1b, 0x04, 0x00, 0x00, 0x1b, 0x8c,
- 0x00, 0x00, 0x1c, 0x14, 0x00, 0x00, 0x1c, 0x9c, 0x00, 0x00, 0x1d, 0x24, 0x00, 0x00, 0x1d, 0xac, 0x00, 0x00, 0x1e, 0x34,
- 0x00, 0x00, 0x03, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x15, 0xd0, 0x00, 0x00, 0x16, 0x44,
- 0x00, 0x00, 0x16, 0xb4, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x17, 0x94, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x18, 0x74,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x17, 0x72, 0x65, 0x73, 0x74,
- 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
- 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
- 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76,
- 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
- 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d,
- 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
- 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f,
- 0x22, 0x80, 0x18, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61,
- 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30,
- 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0,
- 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
- 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9, 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31,
- 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32,
- 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0,
- 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
- 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
- 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14,
- 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31, 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66,
- 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61, 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62,
- 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70,
- 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x7b, 0x38, 0x37, 0x31,
- 0x39, 0x31, 0x63, 0x61, 0x32, 0x2d, 0x30, 0x66, 0x63, 0x39, 0x2d, 0x31, 0x31, 0x64, 0x34, 0x2d, 0x38, 0x34, 0x39, 0x61,
- 0x2d, 0x30, 0x30, 0x30, 0x35, 0x30, 0x32, 0x62, 0x35, 0x32, 0x31, 0x32, 0x32, 0x7d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x19, 0x30,
- 0x00, 0x00, 0x19, 0x50, 0x00, 0x00, 0x19, 0x6c, 0x00, 0x00, 0x19, 0x88, 0x00, 0x00, 0x19, 0xa4, 0x00, 0x00, 0x19, 0xc0,
- 0x00, 0x00, 0x19, 0xdc, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x17,
- 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76,
- 0xa3, 0xc3, 0x9d, 0x60, 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14,
- 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51, 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9,
- 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70,
- 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x14, 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6,
- 0xdf, 0x25, 0xe4, 0x2d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x70,
- 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0x44, 0x00, 0x00, 0x1a, 0x4c,
- 0x00, 0x00, 0x1a, 0x54, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x64, 0x00, 0x00, 0x1a, 0x6c, 0x00, 0x00, 0x1a, 0x74,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1a, 0xcc, 0x00, 0x00, 0x1a, 0xd4, 0x00, 0x00, 0x1a, 0xdc,
- 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1a, 0xec, 0x00, 0x00, 0x1a, 0xf4, 0x00, 0x00, 0x1a, 0xfc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1b, 0x54, 0x00, 0x00, 0x1b, 0x5c, 0x00, 0x00, 0x1b, 0x64, 0x00, 0x00, 0x1b, 0x6c,
- 0x00, 0x00, 0x1b, 0x74, 0x00, 0x00, 0x1b, 0x7c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x1b, 0xdc, 0x00, 0x00, 0x1b, 0xe4, 0x00, 0x00, 0x1b, 0xec, 0x00, 0x00, 0x1b, 0xf4, 0x00, 0x00, 0x1b, 0xfc,
- 0x00, 0x00, 0x1c, 0x04, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0x64,
- 0x00, 0x00, 0x1c, 0x6c, 0x00, 0x00, 0x1c, 0x74, 0x00, 0x00, 0x1c, 0x7c, 0x00, 0x00, 0x1c, 0x84, 0x00, 0x00, 0x1c, 0x8c,
- 0x00, 0x00, 0x1c, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1c, 0xec, 0x00, 0x00, 0x1c, 0xf4,
- 0x00, 0x00, 0x1c, 0xfc, 0x00, 0x00, 0x1d, 0x04, 0x00, 0x00, 0x1d, 0x0c, 0x00, 0x00, 0x1d, 0x14, 0x00, 0x00, 0x1d, 0x1c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0x74, 0x00, 0x00, 0x1d, 0x7c, 0x00, 0x00, 0x1d, 0x84,
- 0x00, 0x00, 0x1d, 0x8c, 0x00, 0x00, 0x1d, 0x94, 0x00, 0x00, 0x1d, 0x9c, 0x00, 0x00, 0x1d, 0xa4, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19,
- 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1d, 0xfc, 0x00, 0x00, 0x1e, 0x04, 0x00, 0x00, 0x1e, 0x0c, 0x00, 0x00, 0x1e, 0x14,
- 0x00, 0x00, 0x1e, 0x1c, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1e, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88,
- 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x1e, 0x84, 0x00, 0x00, 0x1e, 0x8c, 0x00, 0x00, 0x1e, 0x94, 0x00, 0x00, 0x1e, 0x9c, 0x00, 0x00, 0x1e, 0xa4,
- 0x00, 0x00, 0x1e, 0xac, 0x00, 0x00, 0x1e, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xdc, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
- 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xf5,
- 0x73, 0x73, 0x67, 0x70, 0xea, 0xa1, 0xad, 0x3e, 0x49, 0xa8, 0x35, 0x7b, 0xce, 0x5d, 0x8c, 0xd6, 0xdf, 0x25, 0xe4, 0x2d,
- 0x4a, 0x16, 0x48, 0x81, 0x4a, 0xfb, 0x22, 0x80, 0x56, 0xd0, 0x65, 0x2b, 0x3e, 0x11, 0x11, 0xe2, 0x12, 0x2b, 0xc6, 0x87,
- 0xa1, 0xd0, 0x14, 0x1e, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00,
- 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31, 0x30, 0x36, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63,
- 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
- 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5,
- 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x01, 0x15, 0x73, 0x73, 0x67, 0x70, 0x10, 0x34, 0x14, 0x76, 0xa3, 0xc3, 0x9d, 0x60,
- 0x91, 0x3d, 0xda, 0x7c, 0x59, 0x37, 0xec, 0x91, 0xfd, 0xc0, 0xab, 0x3b, 0xfc, 0x61, 0xe6, 0xd5, 0xdd, 0xcf, 0x26, 0x91,
- 0xe5, 0xe9, 0xfb, 0x2c, 0xc0, 0x8d, 0xfe, 0x4c, 0x96, 0xf5, 0x08, 0x64, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38,
- 0x31, 0x38, 0x35, 0x31, 0x31, 0x37, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x31,
- 0x31, 0x37, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20,
- 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63,
- 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5,
- 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0xd9, 0x73, 0x73, 0x67, 0x70, 0x88, 0x63, 0xaf, 0x56, 0xf7, 0x5a, 0x1f, 0xa9,
- 0xf0, 0x1f, 0x26, 0xc0, 0x6c, 0x8d, 0x8a, 0xb4, 0xdc, 0xaf, 0x18, 0xfa, 0xad, 0xad, 0x06, 0xf6, 0x32, 0x30, 0x31, 0x36,
- 0x30, 0x34, 0x31, 0x31, 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31,
- 0x32, 0x31, 0x35, 0x31, 0x31, 0x35, 0x5a, 0x00, 0x61, 0x61, 0x70, 0x6c, 0x69, 0x70, 0x72, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
- 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x11,
- 0x73, 0x73, 0x75, 0x69, 0x00, 0x00, 0x00, 0x20, 0x87, 0x19, 0x1c, 0xa3, 0x0f, 0xc9, 0x11, 0xd4, 0x84, 0x9a, 0x00, 0x05,
- 0x02, 0xb5, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x64, 0x62, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x21, 0x7e, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x4b, 0x65,
- 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x73, 0x64, 0x66, 0x2d, 0x64, 0x62,
- 0x00, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74,
- 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b,
- 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53,
- 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
- 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c,
- 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb4,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x05, 0x5c, 0x00, 0x00, 0x00, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x61, 0x63, 0x63, 0x74, 0x73, 0x76, 0x63, 0x65,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x04, 0x94, 0x00, 0x00, 0x04, 0xc8, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x24,
- 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x6c,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x05, 0x34, 0x00, 0x00, 0x05, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69,
- 0x6d, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x73, 0x76, 0x63, 0x65, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x8c, 0x00, 0x00, 0x05, 0xa4, 0x00, 0x00, 0x05, 0xb8,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20,
- 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73,
- 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x05, 0x2c, 0x80, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5,
- 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x21,
- 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x2d, 0x00, 0x00, 0x01, 0x31, 0x73, 0x73, 0x67, 0x70, 0x66, 0x4e, 0xf9, 0x51,
- 0xc5, 0xeb, 0x28, 0x0b, 0xca, 0x0c, 0x15, 0x2f, 0x22, 0x80, 0x18, 0x7b, 0xce, 0x58, 0x3c, 0x63, 0xf0, 0xe1, 0x4b, 0xfc,
- 0xee, 0x88, 0x20, 0xa4, 0xc4, 0x20, 0xc4, 0x8c, 0xaf, 0x9d, 0xe6, 0x89, 0x39, 0xe3, 0xcc, 0x27, 0x32, 0x30, 0x31, 0x36,
- 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38,
- 0x31, 0x38, 0x34, 0x39, 0x33, 0x34, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73,
- 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65,
- 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73,
- 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xed,
- 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x01, 0x11,
- 0x73, 0x73, 0x67, 0x70, 0xce, 0x31, 0x50, 0xc1, 0x8c, 0xde, 0x4b, 0xa0, 0xca, 0xfd, 0x36, 0x98, 0x33, 0x59, 0x99, 0x39,
- 0x60, 0x88, 0xd4, 0xf3, 0x53, 0x7d, 0x89, 0x6e, 0xc1, 0x4f, 0xfd, 0x7b, 0x4b, 0x9d, 0x0d, 0xe0, 0xe9, 0xd6, 0x84, 0xdf,
- 0x0f, 0x23, 0x90, 0x0b, 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00,
- 0x32, 0x30, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x34, 0x39, 0x34, 0x33, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x61, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74,
- 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0c,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04,
- 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x03, 0x5c, 0x00, 0x00, 0x03, 0xac, 0x00, 0x00, 0x03, 0xe4, 0x00, 0x00, 0x04, 0x44,
- 0x00, 0x00, 0x04, 0x7c, 0x00, 0x00, 0x04, 0xbc, 0x00, 0x00, 0x04, 0xf4, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x61, 0x63, 0x63, 0x74, 0x73, 0x64, 0x6d, 0x6e, 0x73, 0x72, 0x76, 0x72,
- 0x70, 0x74, 0x63, 0x6c, 0x61, 0x74, 0x79, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x68, 0x74, 0x70, 0x73,
- 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73,
- 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04,
- 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x84,
- 0x00, 0x00, 0x03, 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c,
- 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x64, 0x6d, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xd4,
- 0x00, 0x00, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x73, 0x72, 0x76, 0x72, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x04, 0x20,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x76, 0x65,
- 0x5f, 0x61, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x70, 0x74, 0x63, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x6c, 0x00, 0x00, 0x04, 0x74, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, 0x74, 0x70, 0x73,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x74, 0x79, 0x70,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xa4, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04,
- 0x64, 0x66, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x70, 0x61, 0x74, 0x68,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x1c, 0x00, 0x00, 0x05, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
- 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c,
- 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x24,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x61, 0x63, 0x63, 0x74, 0x76, 0x6c, 0x6d, 0x65,
- 0x61, 0x64, 0x64, 0x72, 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x63, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x6c, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x64, 0x64, 0x72,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x73, 0x73, 0x69, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28,
- 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x45, 0x00, 0x00, 0x04, 0x49,
- 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x5d, 0x00, 0x00, 0x04, 0x71, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x05, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x04, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
- 0x05, 0x00, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74,
- 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
- 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46,
- 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f,
- 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09,
- 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
- 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x17,
- 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x35, 0x33, 0x32, 0x5a, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c,
- 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e,
- 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f,
- 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 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, 0xb3, 0xaa, 0xa8, 0x77, 0xe7, 0x3e, 0x2d, 0x0c, 0xf4, 0x83, 0x55, 0xc2, 0x9e,
- 0x50, 0x10, 0xc9, 0xef, 0xc8, 0x48, 0x38, 0xe4, 0x43, 0x96, 0xfa, 0x93, 0x32, 0xbf, 0x66, 0xad, 0x84, 0xa2, 0x8b, 0x6b,
- 0x07, 0x8c, 0xc6, 0x93, 0x8c, 0x4d, 0x65, 0x0f, 0xad, 0x76, 0x73, 0x0c, 0x4d, 0x43, 0xee, 0x35, 0xd4, 0x68, 0x4a, 0x9a,
- 0x6d, 0x4d, 0xa5, 0xae, 0x66, 0xcf, 0xfb, 0xbb, 0x93, 0xd3, 0x6a, 0xe3, 0xfc, 0x41, 0x97, 0xae, 0x90, 0xc3, 0xd8, 0x83,
- 0xfb, 0x8d, 0x67, 0x84, 0xc1, 0xd5, 0x7d, 0x1d, 0x12, 0xca, 0x0c, 0xb5, 0xae, 0xf0, 0xe3, 0x36, 0x39, 0xf1, 0x68, 0x92,
- 0x6f, 0xda, 0x2d, 0x48, 0x87, 0xf0, 0x4b, 0x15, 0x4e, 0x4f, 0x7a, 0x3a, 0x16, 0xb9, 0x02, 0x89, 0x95, 0x98, 0xab, 0xb2,
- 0x58, 0x5b, 0x31, 0x7f, 0x49, 0x90, 0x48, 0xfd, 0x8d, 0x8a, 0x37, 0x3a, 0x4e, 0xd8, 0x00, 0x4a, 0xdc, 0xd4, 0x02, 0x9f,
- 0xcd, 0x4b, 0xde, 0x75, 0x4a, 0xb2, 0x27, 0x8e, 0xe6, 0x2d, 0xea, 0x35, 0x89, 0x85, 0x8a, 0x37, 0x59, 0xd6, 0xd1, 0xf8,
- 0x36, 0x7c, 0x93, 0x9e, 0xd6, 0xd1, 0xc3, 0xd9, 0x75, 0xa4, 0x4f, 0x40, 0x24, 0xe9, 0xc0, 0xde, 0xeb, 0xc0, 0x5e, 0xd6,
- 0x04, 0xe1, 0xd0, 0x07, 0x29, 0xc1, 0x9d, 0x6f, 0x78, 0x2d, 0x5a, 0xef, 0xe6, 0xff, 0x25, 0x16, 0xcf, 0x60, 0x77, 0xa2,
- 0x10, 0x2b, 0xa4, 0x2a, 0xff, 0x74, 0x3b, 0xe6, 0x4d, 0xc1, 0x13, 0xba, 0x8b, 0xe8, 0x15, 0x8e, 0xc7, 0xc3, 0xd4, 0x31,
- 0xb0, 0x99, 0x51, 0x32, 0x30, 0x03, 0x0b, 0x1c, 0xa0, 0x0a, 0x17, 0x15, 0x34, 0x57, 0x38, 0xd3, 0x08, 0x13, 0xc4, 0xd6,
- 0x7c, 0x24, 0x16, 0xd0, 0x2f, 0x00, 0x88, 0xd7, 0xd9, 0xca, 0x1e, 0x6b, 0x50, 0x3b, 0x5f, 0xb6, 0x08, 0xb1, 0x29, 0x42,
- 0x70, 0xf1, 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x47, 0x30, 0x45, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c,
- 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
- 0x14, 0x30, 0x12, 0x81, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
- 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
- 0x00, 0x00, 0xa3, 0x3e, 0x5c, 0x33, 0x06, 0x0b, 0x74, 0xf7, 0x59, 0x56, 0x2e, 0x26, 0x18, 0xe0, 0x59, 0xc9, 0x20, 0x9d,
- 0xaa, 0xf2, 0xfb, 0xa0, 0xf8, 0x11, 0x00, 0x71, 0x53, 0x3d, 0xfa, 0xdc, 0xe9, 0x12, 0x4c, 0x8a, 0xa1, 0x1c, 0x7c, 0xb3,
- 0x4b, 0xa5, 0xa0, 0xfa, 0x03, 0xc5, 0x82, 0x1c, 0xab, 0x44, 0xf6, 0xcb, 0x59, 0x4b, 0x80, 0xeb, 0xc0, 0xa8, 0x0e, 0xc6,
- 0x93, 0xea, 0xbf, 0x67, 0x41, 0xa9, 0x64, 0xcb, 0xb4, 0x3e, 0xf7, 0x64, 0xcf, 0x4c, 0xef, 0x24, 0x62, 0x73, 0x2d, 0xed,
- 0xb4, 0xec, 0x30, 0x97, 0x91, 0x9f, 0x18, 0xe9, 0x12, 0x93, 0x18, 0x83, 0x70, 0xb0, 0xc4, 0x35, 0x33, 0x67, 0x17, 0xb0,
- 0x8b, 0xbe, 0x45, 0xde, 0x98, 0x23, 0xf2, 0x02, 0x77, 0x79, 0x55, 0x53, 0xc4, 0xd7, 0x67, 0x81, 0xde, 0xa1, 0x3f, 0x63,
- 0xb5, 0x87, 0xb6, 0x20, 0x8d, 0x4f, 0x5e, 0x7e, 0x27, 0x30, 0x99, 0xe0, 0xff, 0x91, 0x8b, 0x00, 0x8d, 0x7d, 0xe5, 0x57,
- 0x57, 0xd8, 0xd9, 0x7d, 0x6f, 0xc6, 0xb8, 0x6f, 0x84, 0xed, 0x84, 0x9d, 0xd9, 0xac, 0x13, 0xd8, 0x4a, 0x96, 0x55, 0x2d,
- 0x8e, 0x21, 0x11, 0xc9, 0xa4, 0x81, 0x10, 0x7a, 0x0a, 0x15, 0xce, 0x99, 0x98, 0x09, 0xdd, 0xec, 0x8d, 0x1b, 0xfb, 0x17,
- 0x55, 0x03, 0xa6, 0x44, 0xb5, 0xc9, 0xa9, 0x1f, 0x52, 0xd7, 0x35, 0x06, 0x8d, 0x0a, 0x5a, 0x01, 0x2a, 0xb0, 0xd2, 0x0c,
- 0xfa, 0xd9, 0x66, 0xfa, 0x35, 0x6e, 0xa0, 0xbc, 0x21, 0xe4, 0xe1, 0xe0, 0x3c, 0x3b, 0x7a, 0xef, 0x7d, 0xe1, 0x34, 0x2e,
- 0xe3, 0x9c, 0xc0, 0xa9, 0x4c, 0x16, 0xab, 0x00, 0x60, 0xe0, 0x44, 0xeb, 0x62, 0xcc, 0x1d, 0x27, 0x84, 0x0f, 0x33, 0x37,
- 0x9d, 0xc5, 0xc4, 0xa1, 0xd3, 0xe8, 0x38, 0xff, 0xf2, 0xdf, 0xcd, 0x7c, 0xbb, 0xc3, 0xa1, 0xae, 0x4d, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69,
- 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54,
- 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02,
- 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06,
- 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61,
- 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21,
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50,
- 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31,
- 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f,
- 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1,
- 0x00, 0x00, 0x00, 0x14, 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4,
- 0x3e, 0xfd, 0x6a, 0x65, 0x00, 0x00, 0x05, 0xd8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x31, 0x00, 0x00, 0x04, 0x35, 0x00, 0x00, 0x04, 0x39,
- 0x00, 0x00, 0x04, 0x4d, 0x00, 0x00, 0x04, 0x61, 0x00, 0x00, 0x05, 0x0d, 0x00, 0x00, 0x05, 0xb9, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x05, 0xc1, 0x30, 0x82, 0x03, 0xee, 0x30, 0x82, 0x02, 0xd6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x06,
- 0xe0, 0x2a, 0x1d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
- 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64,
- 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41,
- 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
- 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20,
- 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c,
- 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e,
- 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x30, 0x38, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a,
- 0x17, 0x0d, 0x32, 0x36, 0x30, 0x34, 0x30, 0x36, 0x31, 0x38, 0x35, 0x36, 0x34, 0x36, 0x5a, 0x30, 0x81, 0xa2, 0x31, 0x19,
- 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69,
- 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c,
- 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f,
- 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c,
- 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75,
- 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 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, 0xb6, 0x07, 0xac, 0x5c, 0xc6, 0xcb, 0xf0,
- 0xb7, 0x97, 0x0d, 0x43, 0x1a, 0xe9, 0x61, 0xe7, 0x34, 0x63, 0x6a, 0x26, 0x0d, 0x77, 0xba, 0x25, 0xaa, 0xc8, 0x46, 0xf8,
- 0xc9, 0xdd, 0x21, 0xb4, 0x3e, 0x2e, 0x11, 0x8e, 0xb6, 0x72, 0xf2, 0x01, 0x16, 0x07, 0xcf, 0x88, 0x91, 0xc4, 0xc0, 0x48,
- 0x64, 0x41, 0x91, 0xf7, 0x63, 0x72, 0xd5, 0x37, 0xef, 0x37, 0x62, 0xed, 0x33, 0xb3, 0xf9, 0x6e, 0x31, 0xd1, 0x68, 0xe7,
- 0xde, 0x62, 0x9f, 0x82, 0xb8, 0x9e, 0x11, 0xe7, 0x66, 0x91, 0xc1, 0xbe, 0xe5, 0x5c, 0xd6, 0x71, 0x83, 0x91, 0xbc, 0x0f,
- 0xa8, 0x06, 0xc3, 0xe9, 0xb6, 0x76, 0x16, 0xae, 0x69, 0x0a, 0x47, 0xe4, 0x65, 0xaa, 0x13, 0x71, 0x48, 0xb3, 0x5c, 0x25,
- 0xa5, 0x1a, 0xd0, 0x2a, 0x57, 0x57, 0xf9, 0xb7, 0x13, 0xbd, 0xf4, 0x13, 0x5a, 0x11, 0x1b, 0xcc, 0xd8, 0x9a, 0x5f, 0x82,
- 0x3f, 0xa7, 0x6b, 0x64, 0x47, 0x54, 0xb6, 0x81, 0xaf, 0xcb, 0x4b, 0x94, 0x39, 0x65, 0x15, 0xba, 0x6a, 0x02, 0x7c, 0x71,
- 0x30, 0x60, 0x21, 0x12, 0x63, 0x28, 0xe0, 0x85, 0xca, 0xcc, 0x07, 0xb1, 0x13, 0x40, 0x19, 0x72, 0x02, 0x35, 0x0e, 0x2d,
- 0x4b, 0x8a, 0xcd, 0x1d, 0x09, 0x65, 0xb0, 0x81, 0x49, 0xea, 0x70, 0x15, 0x92, 0x19, 0x7b, 0xfe, 0x15, 0xf7, 0x4a, 0x3f,
- 0x1e, 0x3c, 0x63, 0x7a, 0x0f, 0x17, 0x32, 0x1a, 0xb7, 0x26, 0xa1, 0xa0, 0x9b, 0x3f, 0x4e, 0x7c, 0x38, 0xe6, 0x27, 0xbf,
- 0xa8, 0x1b, 0xf7, 0xbd, 0x2d, 0xfd, 0x9b, 0x05, 0x0c, 0xaa, 0x81, 0xb8, 0x09, 0xd4, 0xe2, 0xe3, 0xbd, 0x6c, 0x70, 0xc0,
- 0x7e, 0x95, 0xd4, 0x0b, 0x13, 0xab, 0xb8, 0xdd, 0x3d, 0x4c, 0x59, 0xf0, 0xc7, 0x8e, 0x47, 0xb5, 0xd8, 0x31, 0x78, 0x80,
- 0xd2, 0x5f, 0x0c, 0x0b, 0xae, 0x22, 0xe7, 0x9e, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x2a, 0x30, 0x28, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d,
- 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaf, 0xe3,
- 0x41, 0xaa, 0x63, 0xdc, 0x3e, 0xd1, 0x46, 0x1e, 0x7a, 0x09, 0x04, 0x4a, 0xfd, 0x54, 0xc7, 0xd9, 0x25, 0x2f, 0xce, 0x8e,
- 0x5d, 0x34, 0x96, 0x04, 0x67, 0xbc, 0x6f, 0xb6, 0x99, 0x35, 0xc2, 0x16, 0x1c, 0x2a, 0xc3, 0x5f, 0xdf, 0x6e, 0xe2, 0xe4,
- 0x2e, 0xbb, 0x64, 0x1c, 0x0a, 0xff, 0x62, 0x79, 0x70, 0x7c, 0xc6, 0x8e, 0xd9, 0x95, 0xb6, 0x8a, 0x3d, 0xf6, 0xdd, 0x79,
- 0x1c, 0xeb, 0x73, 0x05, 0x2f, 0x7e, 0x38, 0xb8, 0x9c, 0xfc, 0x06, 0x8f, 0x5f, 0xd7, 0xec, 0xd3, 0x23, 0xae, 0x75, 0x0f,
- 0x8e, 0x70, 0xb2, 0xd8, 0x88, 0xa0, 0x4f, 0x53, 0x0a, 0xcc, 0xee, 0x18, 0xf2, 0x5b, 0xf8, 0xe1, 0x22, 0x6b, 0xeb, 0x4d,
- 0x9d, 0x2a, 0xa1, 0x46, 0xf4, 0xc7, 0x99, 0x26, 0x5b, 0xaf, 0x92, 0x54, 0x72, 0xe7, 0xea, 0x49, 0x34, 0x98, 0x8d, 0x93,
- 0x18, 0xc5, 0x6e, 0x79, 0x79, 0xb3, 0x63, 0x76, 0xf7, 0x84, 0x49, 0x06, 0x58, 0x14, 0x1a, 0x86, 0xbd, 0xe5, 0x5a, 0xf8,
- 0x81, 0x06, 0x15, 0x0c, 0xf7, 0x57, 0x4e, 0xeb, 0xbe, 0xc9, 0xe6, 0x09, 0xa3, 0x1d, 0xcc, 0xc6, 0x08, 0xbc, 0x71, 0x4b,
- 0x62, 0x1a, 0xec, 0xdd, 0xad, 0xe3, 0x00, 0xd9, 0xf3, 0x98, 0x94, 0x75, 0xb5, 0xc2, 0x64, 0xec, 0xec, 0xe1, 0x88, 0x5b,
- 0x24, 0xd6, 0xa2, 0x27, 0x86, 0x10, 0xc4, 0xfc, 0xf7, 0x8d, 0x79, 0x95, 0x20, 0x3e, 0xc5, 0x7a, 0xdc, 0x57, 0xc8, 0x2e,
- 0x78, 0x63, 0xd5, 0x09, 0xc3, 0xa9, 0xa4, 0xd9, 0x83, 0x99, 0xbe, 0x17, 0xdc, 0x22, 0x85, 0x98, 0x0b, 0xe1, 0xf6, 0x67,
- 0x47, 0xf7, 0x1d, 0xed, 0x40, 0xe4, 0x5c, 0x5e, 0x58, 0xf1, 0x27, 0x5b, 0xe2, 0x7b, 0xb0, 0xf5, 0xbf, 0x37, 0xc3, 0xe2,
- 0x73, 0xa8, 0xd6, 0xf1, 0x42, 0xb2, 0x56, 0x90, 0x00, 0xa4, 0x35, 0x4a, 0x5a, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67,
- 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c,
- 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62,
- 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
- 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63,
- 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
- 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53,
- 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
- 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c,
- 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0x14,
- 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8, 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c,
- 0x00, 0x00, 0x06, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x00, 0x00, 0x04, 0x85, 0x00, 0x00, 0x04, 0x89, 0x00, 0x00, 0x04, 0xa5,
- 0x00, 0x00, 0x04, 0xc5, 0x00, 0x00, 0x05, 0x81, 0x00, 0x00, 0x06, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x45,
- 0x30, 0x82, 0x04, 0x3d, 0x30, 0x82, 0x03, 0x25, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30,
- 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63,
- 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
- 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55,
- 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
- 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72,
- 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e,
- 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x31, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30,
- 0x34, 0x30, 0x39, 0x32, 0x32, 0x34, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
- 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46,
- 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f,
- 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09,
- 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 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, 0xc3, 0xe8, 0xe0, 0x34, 0xff, 0x63, 0x08, 0xce, 0x36, 0x82, 0x02, 0xe7, 0x91,
- 0x0b, 0x73, 0x84, 0xb9, 0xad, 0xd8, 0x79, 0x92, 0x34, 0x20, 0x96, 0xd1, 0x3a, 0xc7, 0x7f, 0x19, 0xd7, 0xcf, 0x9f, 0xab,
- 0x2b, 0xc0, 0x0c, 0xe1, 0xf6, 0x0e, 0x9e, 0x9f, 0x73, 0x42, 0x95, 0xf1, 0x2c, 0x63, 0xff, 0x3f, 0x31, 0xb1, 0xe3, 0x24,
- 0x1a, 0x75, 0x7d, 0x50, 0x2c, 0x23, 0x59, 0x53, 0x2c, 0xab, 0xaf, 0xd7, 0x5c, 0xf1, 0x27, 0xd2, 0xe9, 0xf5, 0x8f, 0x76,
- 0xc4, 0x96, 0x74, 0x3c, 0xda, 0x65, 0xd4, 0x9e, 0xde, 0x33, 0x25, 0x5d, 0xed, 0x04, 0x94, 0x2c, 0xb5, 0x18, 0xeb, 0x64,
- 0x8e, 0xf4, 0xd4, 0xe0, 0xb6, 0xfc, 0xcc, 0xd7, 0xfb, 0x90, 0x9c, 0xc1, 0xe6, 0x09, 0xb9, 0x8c, 0xc9, 0xba, 0x91, 0x4d,
- 0x63, 0x5f, 0xa1, 0x75, 0x13, 0x11, 0x7d, 0x13, 0xa9, 0x2c, 0x07, 0xbd, 0xcb, 0x5d, 0xc5, 0xb0, 0x4f, 0xed, 0x95, 0xc6,
- 0x8c, 0xe9, 0x78, 0xa2, 0xa5, 0x42, 0x15, 0x5a, 0xd0, 0x9c, 0x9c, 0x85, 0x85, 0x6e, 0x50, 0xae, 0x19, 0xd5, 0x91, 0x13,
- 0x62, 0x96, 0xd9, 0x4a, 0x47, 0xe3, 0xfe, 0x8f, 0x7d, 0x47, 0xbd, 0xbe, 0xaa, 0x37, 0x64, 0xe3, 0xf0, 0xa3, 0xa4, 0xd0,
- 0xef, 0xef, 0x2a, 0xa7, 0x45, 0xbf, 0x21, 0x79, 0xb8, 0x5c, 0x04, 0x8a, 0x2f, 0x7b, 0xe0, 0xe2, 0x32, 0x58, 0x75, 0xec,
- 0xec, 0x2f, 0x78, 0xa5, 0x9a, 0x7b, 0xa3, 0x3c, 0xf6, 0x67, 0x00, 0x83, 0xe5, 0x77, 0x1d, 0x2b, 0xdd, 0x74, 0xd0, 0x45,
- 0xcf, 0xa4, 0x0c, 0xf2, 0xe2, 0x60, 0xa8, 0x70, 0x87, 0x05, 0x0b, 0x7c, 0xef, 0x88, 0x09, 0x23, 0x15, 0xdf, 0xdb, 0x9f,
- 0xc2, 0x80, 0x1f, 0x0a, 0x12, 0xcb, 0x00, 0xa4, 0x8a, 0x77, 0xa7, 0x54, 0x8f, 0xcb, 0x91, 0xbb, 0x55, 0x52, 0x51, 0x8f,
- 0xca, 0xf6, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c,
- 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
- 0x20, 0x30, 0x1e, 0x81, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8c, 0x44, 0x70, 0xda, 0xd9, 0x65, 0x52,
- 0xfd, 0x46, 0x0e, 0xab, 0xbb, 0xb5, 0x1c, 0x46, 0x0a, 0xcb, 0x3d, 0xc3, 0x71, 0x79, 0xa8, 0x5f, 0x3b, 0x45, 0x49, 0x29,
- 0x0c, 0xf5, 0x69, 0xb4, 0x27, 0x4d, 0x79, 0xad, 0xa9, 0x93, 0x11, 0x7b, 0xad, 0x45, 0xc6, 0x49, 0x54, 0x8b, 0x5d, 0x5f,
- 0xcc, 0x9d, 0xd9, 0xe4, 0x8f, 0xff, 0x21, 0x0f, 0x7a, 0x40, 0xf2, 0xd6, 0xce, 0xe1, 0x97, 0x5f, 0x7d, 0x9c, 0x76, 0x22,
- 0x73, 0x30, 0x3b, 0xb4, 0x5b, 0xa0, 0x07, 0x70, 0x96, 0x97, 0x84, 0xe1, 0x47, 0x5b, 0x3e, 0xd2, 0xed, 0x3f, 0xca, 0x97,
- 0x3a, 0x33, 0x52, 0xb8, 0x22, 0x89, 0xe2, 0x2e, 0x61, 0x5e, 0x20, 0x1a, 0xf9, 0x4f, 0x9a, 0x18, 0xde, 0xf3, 0x8e, 0x11,
- 0x3b, 0x19, 0x09, 0xce, 0x8e, 0xb9, 0x28, 0x5f, 0x64, 0x54, 0xc1, 0x33, 0x19, 0x68, 0x96, 0x54, 0x53, 0x84, 0xb6, 0xf2,
- 0xdb, 0xb3, 0x6b, 0xca, 0x36, 0x08, 0xb1, 0xa3, 0x0d, 0x19, 0x4e, 0xac, 0x17, 0x25, 0x96, 0x0d, 0x4c, 0x9e, 0xc5, 0xa0,
- 0xcc, 0xe4, 0x52, 0x98, 0x1c, 0xcf, 0x0a, 0x77, 0x91, 0xf2, 0xc8, 0xae, 0x8c, 0x1c, 0x1d, 0xae, 0x79, 0xf6, 0x0c, 0x65,
- 0xf0, 0xb4, 0xdd, 0x0c, 0x6f, 0x35, 0x12, 0x93, 0xb7, 0x20, 0xd1, 0x29, 0xa3, 0x40, 0xb5, 0x66, 0x67, 0x69, 0xdd, 0x97,
- 0xcf, 0x48, 0x9f, 0xe9, 0x00, 0x33, 0x0e, 0x8e, 0xae, 0xc6, 0x40, 0xe3, 0x40, 0xdb, 0xab, 0x8b, 0x1e, 0x34, 0xbb, 0x0b,
- 0xb7, 0x42, 0xd4, 0x0d, 0x9e, 0x86, 0x99, 0x3c, 0xbd, 0x34, 0xc5, 0xba, 0xac, 0x03, 0x8b, 0xcd, 0xa3, 0xee, 0x36, 0x52,
- 0x28, 0x59, 0x7a, 0x29, 0xd7, 0x1f, 0xa1, 0x18, 0xc5, 0xba, 0x7a, 0xc4, 0xf0, 0x67, 0x4a, 0x61, 0x5c, 0x83, 0xad, 0x6c,
- 0x89, 0x0b, 0xdd, 0x40, 0xf8, 0xfd, 0x8c, 0xce, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63,
- 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
- 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65,
- 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
- 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
- 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
- 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61,
- 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72,
- 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41,
- 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
- 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45,
- 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07,
- 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01,
- 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x12, 0x5c,
- 0x00, 0x00, 0x14, 0xd0, 0x00, 0x00, 0x15, 0x18, 0x00, 0x00, 0x15, 0x9c, 0x00, 0x00, 0x17, 0xe4, 0x00, 0x00, 0x1a, 0x2c,
- 0x00, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x1a, 0x98, 0x00, 0x00, 0x02, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x03, 0x63, 0x74, 0x79, 0x70, 0x69, 0x73, 0x73, 0x75, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x12, 0x94, 0x00, 0x00, 0x13, 0x48, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31,
- 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65,
- 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
- 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
- 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04,
- 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31,
- 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73,
- 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
- 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46,
- 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e,
- 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43,
- 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
- 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65,
- 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
- 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
- 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
- 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61,
- 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x48,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x63, 0x74, 0x79, 0x70, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x00, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0x48, 0x00, 0x00, 0x15, 0x60,
- 0x00, 0x00, 0x15, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
- 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63,
- 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
- 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x75, 0x62, 0x6a,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x15, 0xcc, 0x00, 0x00, 0x16, 0x74, 0x00, 0x00, 0x17, 0x24, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0, 0x30, 0x81, 0x9d, 0x31,
- 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65,
- 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
- 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
- 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xac,
- 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65,
- 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x4d, 0x45, 0x4e,
- 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
- 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10,
- 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40,
- 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xb8,
- 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73,
- 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x14, 0x30, 0x12,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21,
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50,
- 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
- 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31,
- 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c, 0x6e, 0x6f, 0x62, 0x6f,
- 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x69, 0x73, 0x73, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x18, 0x14, 0x00, 0x00, 0x18, 0xbc, 0x00, 0x00, 0x19, 0x6c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa0,
- 0x30, 0x81, 0x9d, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73,
- 0x6d, 0x69, 0x6d, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65,
- 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52,
- 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c,
- 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75,
- 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
- 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xa5, 0x30, 0x81, 0xa2, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x14,
- 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56, 0x45, 0x4c,
- 0x4f, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f,
- 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x62,
- 0x6f, 0x64, 0x79, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
- 0x00, 0x00, 0x00, 0xb8, 0x30, 0x81, 0xb5, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65,
- 0x73, 0x74, 0x5f, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
- 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x18, 0x46, 0x4f, 0x52, 0x20, 0x44, 0x45, 0x56,
- 0x45, 0x4c, 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x55, 0x53, 0x45, 0x20, 0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
- 0x69, 0x6e, 0x6f, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x1c,
- 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x40, 0x61,
- 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x73, 0x6e, 0x62, 0x72, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1a, 0x5c, 0x00, 0x00, 0x1a, 0x68,
- 0x00, 0x00, 0x1a, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0xfb, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x06, 0xe0, 0x2a, 0x1d,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x56, 0x81, 0x44, 0xc1, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73, 0x6b, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
- 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x70, 0x6b, 0x79, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x1a, 0xc8, 0x00, 0x00, 0x1a, 0xe4, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xc7, 0xc5, 0x36, 0xbc, 0xce, 0x8e, 0x86, 0xa8,
- 0x02, 0x33, 0x38, 0xb5, 0x23, 0xb6, 0xef, 0x97, 0x20, 0x1e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14,
- 0xc9, 0x58, 0x3f, 0x54, 0xf7, 0x9c, 0x21, 0xee, 0x29, 0x26, 0x07, 0x8d, 0x1b, 0xb4, 0x93, 0xc4, 0x3e, 0xfd, 0x6a, 0x65,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0xd7, 0x58, 0x0b, 0xdf, 0xe7, 0x97, 0x49, 0x7e, 0xd7, 0x44, 0x80, 0x01,
- 0xf5, 0xf3, 0x7f, 0xf6, 0x1d, 0x5c, 0x24, 0x16, 0x00, 0x00, 0x00, 0xe8, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20,
- 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8,
- 0x00, 0x00, 0x00, 0x00, 0xfa, 0xde, 0x07, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xa8,
- 0x52, 0xba, 0xd6, 0xe8, 0x80, 0xd9, 0x0e, 0xbb, 0x2e, 0x64, 0x65, 0xce, 0xcd, 0xe6, 0xa9, 0x71, 0x00, 0x00, 0x00, 0x00,
- 0x7f, 0xff, 0xff, 0xff, 0x00, 0x7f, 0x00, 0x00, 0x58, 0xcc, 0x46, 0xd5, 0x94, 0x46, 0x74, 0xb1, 0x30, 0x40, 0x9b, 0x78,
- 0xb0, 0x30, 0x4b, 0x1a, 0xa1, 0x93, 0x58, 0x1f, 0x48, 0xd4, 0x81, 0x1e, 0x1e, 0x1e, 0xe2, 0xaf, 0xda, 0x6a, 0x3e, 0x6e,
- 0x08, 0x90, 0x5e, 0xd5, 0xf1, 0xce, 0x8b, 0x78, 0x8a, 0x5e, 0xe2, 0x36, 0x45, 0x92, 0xee, 0xeb, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0xe6, 0xb4, 0xf8, 0xd6, 0xa3, 0x68, 0x66, 0xde, 0x70, 0xd4, 0xe0, 0xd6, 0x9a, 0x46, 0x5d, 0xbd,
- 0x60, 0x41, 0x2b, 0x19, 0x2b, 0x4b, 0x55, 0x64, 0x60, 0xe4, 0x91, 0x17, 0x5e, 0xa2, 0x08, 0xe0, 0x1c, 0x6e, 0xbd, 0xf1,
- 0x08, 0xfd, 0x2d, 0x7b, 0x42, 0x6a, 0x7c, 0xa3, 0x73, 0x6d, 0xb0, 0xfd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48
-};
-unsigned int test_keychain_len = 45864;
+extern unsigned int test_keychain_len;
@interface TimeStampClient : NSObject
{
- id delegate;
+ __weak id delegate;
NSURL *url;
NSMutableURLRequest *urlRequest;
}
typedef CSSM_DL_HANDLE MDS_HANDLE;
-typedef CSSM_DL_DB_HANDLE MDS_DB_HANDLE;
+typedef CSSM_DL_DB_HANDLE MDS_DB_HANDLE DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
-typedef struct mds_funcs {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER mds_funcs {
CSSM_RETURN (CSSMAPI *DbOpen)
(MDS_HANDLE MdsHandle,
const char *DbName,
CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts");
CFTypeRef kSecCMSHashAgility = CFSTR("kSecCMSHashAgility");
CFTypeRef kSecCMSHashAgilityV2 = CFSTR("kSecCMSHashAgilityV2");
+CFTypeRef kSecCMSExpirationDate = CFSTR("kSecCMSExpirationDate");
CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm");
CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC");
CFDictionarySetValue(attrs, kSecCMSHashAgilityV2, hash_agility_values);
}
}
+
+ CFAbsoluteTime expiration_time;
+ if (errSecSuccess == SecCmsSignerInfoGetAppleExpirationTime(sigd->signerInfos[0], &expiration_time)) {
+ CFDateRef expiration_date = CFDateCreate(NULL, expiration_time);
+ if (expiration_date) {
+ CFDictionarySetValue(attrs, kSecCMSExpirationDate, expiration_date);
+ CFRetainSafe(expiration_date);
+ }
+ }
*signed_attributes = attrs;
if (certs) CFRelease(certs);
SecCmsSignedDataRef sigd = NULL;
CFMutableArrayRef certs = NULL;
+ if (!message) {
+ return NULL;
+ }
+
CSSM_DATA encoded_message = { CFDataGetLength(message), (uint8_t*)CFDataGetBytePtr(message) };
require_noerr_quiet(SecCmsMessageDecode(&encoded_message, NULL, NULL, NULL, NULL, NULL, NULL, &cmsg), out);
/* expected to be a signed data message at the top level */
}
out:
- if (cmsg)
- SecCmsMessageDestroy(cmsg);
+ if (cmsg) { SecCmsMessageDestroy(cmsg); }
+ if (certs && CFArrayGetCount(certs) < 1) {
+ CFReleaseNull(certs);
+ }
return certs;
}
extern const void * kSecCMSAllCerts;
extern const void * kSecCMSHashAgility;
extern const void * kSecCMSHashAgilityV2;
+extern const void * kSecCMSExpirationDate;
extern const void * kSecCMSHashingAlgorithmSHA1;
extern const void * kSecCMSHashingAlgorithmSHA256;
@typedef
@discussion XXX We might want to get rid of this alltogether.
*/
-typedef CSSM_X509_ALGORITHM_IDENTIFIER SECAlgorithmID;
+typedef CSSM_X509_ALGORITHM_IDENTIFIER SECAlgorithmID DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@typedef
@typedef
@discussion Type of function passed to SecCmsDecode or SecCmsDecoderStart to retrieve the decryption key. This function is intended to be used for EncryptedData content info's which do not have a key available in a certificate, etc.
*/
-typedef SecSymmetricKeyRef(*SecCmsGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid);
+typedef SecSymmetricKeyRef(*SecCmsGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@enum SecCmsVerificationStatus
SEC_OID_APPLE_HASH_AGILITY = 214,
SEC_OID_APPLE_HASH_AGILITY_V2 = 215,
+ /* Apple Expiration Time Attribute */
+ SEC_OID_APPLE_EXPIRATION_TIME = 216,
+
SEC_OID_TOTAL
} SECOidTag;
@discussion This is typically only called by SecCmsMessageGetContent().
*/
extern CSSM_DATA_PTR
-SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo);
+SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
@discussion Caches pointer to lookup result for future reference.
*/
extern CSSM_OID *
-SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo);
+SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
@discussion Caches pointer to lookup result for future reference.
*/
extern SECAlgorithmID *
-SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo);
+SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*! @functiongroup Message construction */
@availability 10.4 and later
*/
extern OSStatus
-SecCmsContentInfoSetContentData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached);
+SecCmsContentInfoSetContentData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
SecCmsContentInfoSetContentEncryptedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsEncryptedDataRef encd);
OSStatus
-SecCmsContentInfoSetContentOther(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached, const CSSM_OID *eContentType);
+SecCmsContentInfoSetContentOther(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached, const CSSM_OID *eContentType) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
*/
extern OSStatus
SecCmsContentInfoSetContentEncAlg(SecArenaPoolRef pool, SecCmsContentInfoRef cinfo,
- SECOidTag bulkalgtag, CSSM_DATA_PTR parameters, int keysize);
+ SECOidTag bulkalgtag, CSSM_DATA_PTR parameters, int keysize) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
*/
extern OSStatus
SecCmsContentInfoSetContentEncAlgID(SecArenaPoolRef pool, SecCmsContentInfoRef cinfo,
- SECAlgorithmID *algid, int keysize);
+ SECAlgorithmID *algid, int keysize) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
PK11PasswordFunc pwfn, void *pwfn_arg,
SecCmsGetDecryptKeyCallback decrypt_key_cb, void
*decrypt_key_cb_arg,
- SecCmsDecoderRef *outDecoder);
+ SecCmsDecoderRef *outDecoder) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
SecCmsContentCallback cb, void *cb_arg,
PK11PasswordFunc pwfn, void *pwfn_arg,
SecCmsGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
- SecCmsMessageRef *outMessage);
+ SecCmsMessageRef *outMessage) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
#if defined(__cplusplus)
@abstract Start digest calculation using all the digest algorithms in "digestalgs" in parallel.
*/
extern SecCmsDigestContextRef
-SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs);
+SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
*/
extern OSStatus
SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, SecArenaPoolRef arena,
- CSSM_DATA_PTR **digestsp);
+ CSSM_DATA_PTR **digestsp) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
#if defined(__cplusplus)
}
digest will be calculated while encoding
*/
extern SecCmsDigestedDataRef
-SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg);
+SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
PK11PasswordFunc pwfn, void *pwfn_arg,
SecCmsGetDecryptKeyCallback encrypt_key_cb, void *encrypt_key_cb_arg,
SECAlgorithmID **detached_digestalgs, CSSM_DATA_PTR *detached_digests,
- SecCmsEncoderRef *outEncoder);
+ SecCmsEncoderRef *outEncoder) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
*/
extern OSStatus
SecCmsMessageEncode(SecCmsMessageRef cmsg, const CSSM_DATA *input, SecArenaPoolRef arena,
- CSSM_DATA_PTR outBer);
+ CSSM_DATA_PTR outBer) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
#if defined(__cplusplus)
}
In case of nested contentInfos, this descends and retrieves the innermost content.
*/
extern CSSM_DATA_PTR
-SecCmsMessageGetContent(SecCmsMessageRef cmsg);
+SecCmsMessageGetContent(SecCmsMessageRef cmsg) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
extern SecCmsRecipientInfoRef
SecCmsRecipientInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg,
CSSM_DATA_PTR subjKeyID,
- SecPublicKeyRef pubKey);
+ SecPublicKeyRef pubKey) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
@abstract Retrieve the SignedData's digest algorithm list.
*/
extern SECAlgorithmID **
-SecCmsSignedDataGetDigestAlgs(SecCmsSignedDataRef sigd);
+SecCmsSignedDataGetDigestAlgs(SecCmsSignedDataRef sigd) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
@abstract Retrieve the SignedData's certificate list.
*/
extern CSSM_DATA_PTR *
-SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd);
+SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
extern OSStatus
SecCmsSignedDataSetDigests(SecCmsSignedDataRef sigd,
SECAlgorithmID **digestalgs,
- CSSM_DATA_PTR *digests);
+ CSSM_DATA_PTR *digests) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
@function
*/
extern SecCmsSignerInfoRef
-SecCmsSignerInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, CSSM_DATA_PTR subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag);
+SecCmsSignerInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, CSSM_DATA_PTR subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
@function
*/
extern CSSM_DATA *
-SecCmsSignerInfoGetEncDigest(SecCmsSignerInfoRef signerinfo);
+SecCmsSignerInfoGetEncDigest(SecCmsSignerInfoRef signerinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
extern OSStatus
SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict);
+/*!
+ @function SecCmsSignerInfoGetAppleExpirationTime
+ @abstract Return the expriation time, in CFAbsoluteTime, of a CMS signerInfo.
+ @param sinfo SignerInfo data for this signer.
+ @discussion Returns a CFAbsoluteTime
+ @result A return value of SECFailure is an error.
+ */
+extern OSStatus
+SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime);
+
/*!
@function
@abstract Return the signing cert of a CMS signerInfo.
@abstract Create a timestamp unsigned attribute with a TimeStampToken.
*/
OSStatus
-SecCmsSignerInfoAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA *tstoken);
+SecCmsSignerInfoAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA *tstoken) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
/*!
@function
OSStatus
SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues);
+/*!
+ @function SecCmsSignerInfoAddAppleExpirationTime
+ @abstract Add the expiration time to the authenticated (i.e. signed) attributes of "signerinfo".
+ @discussion This is expected to be included in outgoing signed messages for Asset Receipts but is likely
+ useful in other situations. This should only be added once; a second call will do nothing.
+ @result A result of SECFailure indicates an error adding the attribute.
+ */
+extern OSStatus
+SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t);
+
/*!
@function
@abstract The following needs to be done in the S/MIME layer code after signature of a signerinfo has been verified.
SecTrustRef trust = NULL;
CFMutableArrayRef certs = NULL;
OSStatus status = 0;
+ SecTrustResultType trustResult = kSecTrustResultInvalid;
if (!cert)
goto loser;
/* SecTrustEvaluate will build us the best chain available using its heuristics.
* We'll ignore the trust result. */
- status = SecTrustEvaluate(trust, NULL);
+ status = SecTrustEvaluate(trust, &trustResult);
if (status)
goto loser;
CFIndex idx, count = SecTrustGetCertificateCount(trust);
// Extract a public key object from a SubjectPublicKeyInfo
SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert)
{
- SecPublicKeyRef keyRef = NULL;
- SecCertificateCopyPublicKey(cert,&keyRef);
- return keyRef;
+ return SecCertificateCopyKey(cert);
}
SECStatus CERT_CheckCertUsage (SecCertificateRef cert,unsigned char usage)
return cert;
}
-static int compareCssmData(
- const CSSM_DATA *d1,
- const CSSM_DATA *d2)
+int CERT_CompareCssmData(const CSSM_DATA *d1, const CSSM_DATA *d2)
{
if((d1 == NULL) || (d2 == NULL)) {
return 0;
CFRelease(certificate);
continue;
}
- if(!compareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) {
+ if(!CERT_CompareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) {
CFRelease(certificate);
continue;
}
- if(!compareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) {
+ if(!CERT_CompareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) {
CFRelease(certificate);
continue;
}
if(isn == NULL) {
continue;
}
- if(!compareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) {
+ if(!CERT_CompareCssmData(&isn->derIssuer, &issuerAndSN->derIssuer)) {
continue;
}
- if(!compareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) {
+ if(!CERT_CompareCssmData(&isn->serialNumber, &issuerAndSN->serialNumber)) {
continue;
}
certificate = cert;
/* not present */
continue;
}
- match = compareCssmData(subjKeyID, &skid);
+ match = CERT_CompareCssmData(subjKeyID, &skid);
SECITEM_FreeItem(&skid, PR_FALSE);
if(match) {
/* got it */
CFTypeRef CERT_PolicyForCertUsage(SECCertUsage certUsage);
+int CERT_CompareCssmData(const CSSM_DATA *d1, const CSSM_DATA *d2);
+
/************************************************************************/
SEC_END_PROTOS
theTemplate = SEC_ASN1_GET(kSecAsn1OctetStringTemplate);
break;
case SEC_OID_PKCS9_SIGNING_TIME:
+ case SEC_OID_APPLE_EXPIRATION_TIME:
encoded = PR_FALSE;
theTemplate = SEC_ASN1_GET(kSecAsn1UTCTimeTemplate); // @@@ This should be a choice between UTCTime and GeneralizedTime -- mb
break;
* Implemented in siginfoUtils.cpp for access to C++ Dictionary class.
*/
extern bool
-SecCmsMsEcdsaCompatMode();
+SecCmsMsEcdsaCompatMode(void);
/************************************************************************
* 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)
{
- SecPublicKeyRef publickey = SecCertificateCopyPublicKey_ios(cert);
+ OSStatus rv;
+ SecPublicKeyRef publickey = SecCertificateCopyKey(cert);
if (publickey == NULL)
return SECFailure;
- OSStatus rv = SecCmsUtilEncryptSymKeyRSAPubKey(poolp, publickey, bulkkey, encKey);
+ rv = SecCmsUtilEncryptSymKeyRSAPubKey(poolp, publickey, bulkkey, encKey);
CFRelease(publickey);
return rv;
}
mark = PORT_ArenaMark(poolp);
if (!mark)
goto loser;
-
-#if 0
- /* sanity check */
- keyType = SECKEY_GetPublicKeyType(publickey);
- PORT_Assert(keyType == rsaKey);
- if (keyType != rsaKey) {
- goto loser;
- }
-#endif
/* allocate memory for the encrypted key */
theirKeyAttrs = SecKeyCopyAttributes(publickey);
if (!theirKeyAttrs) {
encKey->Length = 0;
/* Copy the recipient's static public ECDH key */
-#if TARGET_OS_IPHONE
- theirPubKey = SecCertificateCopyPublicKey(cert);
-#else
- rv = SecCertificateCopyPublicKey(cert, &theirPubKey);
-#endif
+ theirPubKey = SecCertificateCopyKey(cert);
if (rv || !theirPubKey) {
dprintf("SecCmsUtilEncryptSymKeyECDH: failed to get public key from cert, %d\n", (int)rv);
goto out;
extern const SecAsn1Template kSecAsn1TSATSTInfoTemplate;
-OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR encDigest,
+OSStatus createTSAMessageImprint(SecCmsSignerInfoRef signerInfo, SECAlgorithmID *digestAlg, CSSM_DATA_PTR encDigest,
SecAsn1TSAMessageImprint *messageImprint)
{
// Calculate hash of encDigest and put in messageImprint.hashedMessage
OSStatus status = SECFailure;
- require(signedData && messageImprint, xit);
-
- SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData);
- require(digestAlgorithms, xit);
+ require(signerInfo && digestAlg && messageImprint, xit);
- SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms);
+ SecCmsDigestContextRef digcx = SecCmsDigestContextStartSingle(digestAlg);
require(digcx, xit);
require(encDigest, xit);
- SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(signedData, 0); // NB - assume 1 signer only!
- messageImprint->hashAlgorithm = signerinfo->digestAlg;
+ messageImprint->hashAlgorithm = *digestAlg;
SecCmsDigestContextUpdate(digcx, encDigest->Data, encDigest->Length);
- require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signedData->cmsg->poolp,
+ require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signerInfo->cmsg->poolp,
&messageImprint->hashedMessage), xit);
status = SECSuccess;
The code for this is essentially the same code taht is done during a timestamp
verify, except that we also need to check the nonce.
*/
- require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, NULL, expectedNonce), xit);
+ CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo);
+ require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, encDigest, expectedNonce), xit);
status = SecCmsSignerInfoAddTimeStamp(signerinfo, &respDER.timeStampTokenDER);
// Calculate hash of encDigest and put in messageImprint.hashedMessage
SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(sigd, 0); // NB - assume 1 signer only!
CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo);
- require_noerr(createTSAMessageImprint(sigd, encDigest, &messageImprint), tsxit);
+ require_noerr(createTSAMessageImprint(signerinfo, &signerinfo->digestAlg, encDigest, &messageImprint), tsxit);
// Callback to fire up XPC service to talk to TimeStamping server, etc.
require_noerr(rv =(*sigd->cmsg->tsaCallback)(sigd->cmsg->tsaContext, &messageImprint,
#include <Security/SecKeyPriv.h>
#include <CoreFoundation/CFTimeZone.h>
#include <utilities/SecCFWrappers.h>
+#include <utilities/debugging.h>
#include <AssertMacros.h>
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
#include <Security/SecPolicyPriv.h>
debugShowSigningCertificate(signerinfo);
- OSStatus status;
- if ((status = SecCertificateCopyPublicKey(cert, &publickey))) {
- syslog(LOG_ERR, "SecCmsSignerInfoVerifyWithPolicy: copy public key failed %d", (int)status);
+ if (NULL == (publickey = SecCertificateCopyKey(cert))) {
vs = SecCmsVSProcessingError;
goto loser;
}
dprintf("found an id-ct-TSTInfo\n");
// Don't check the nonce in this case
status = decodeTimeStampTokenWithPolicy(signerinfo, timeStampPolicy, (attr->values)[0], &signerinfo->encDigest, 0);
+ if (status != errSecSuccess) {
+ secerror("timestamp verification failed: %d", (int)status);
+ }
+
xit:
return status;
}
return errSecAllocate;
}
+/*
+ * SecCmsSignerInfoGetAppleExpirationTime - return the expiration time,
+ * in UTCTime format, of a CMS signerInfo.
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to XXXX (what?)
+ * A return value of NULL is an error.
+ */
+OSStatus
+SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime)
+{
+ SecCmsAttribute *attr = NULL;
+ SecAsn1Item * value = NULL;
+
+ if (sinfo == NULL || etime == NULL) {
+ return SECFailure;
+ }
+
+ if (sinfo->expirationTime != 0) {
+ *etime = sinfo->expirationTime; /* cached copy */
+ return SECSuccess;
+ }
+
+ attr = SecCmsAttributeArrayFindAttrByOidTag(sinfo->authAttr, SEC_OID_APPLE_EXPIRATION_TIME, PR_TRUE);
+ if (attr == NULL || (value = SecCmsAttributeGetValue(attr)) == NULL) {
+ return SECFailure;
+ }
+ if (DER_UTCTimeToCFDate(value, etime) != SECSuccess) {
+ return SECFailure;
+ }
+ sinfo->expirationTime = *etime; /* make cached copy */
+ return SECSuccess;
+}
+
/*
* Return the signing cert of a CMS signerInfo.
*
return status;
}
+/*
+ * SecCmsSignerInfoAddAppleExpirationTime - add the expiration time to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed
+ * messages for Asset Receipts but is likely useful in other situations.
+ *
+ * This should only be added once; a second call will do nothing.
+ */
+OSStatus
+SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t)
+{
+ SecCmsAttribute *attr = NULL;
+ PLArenaPool *poolp = signerinfo->cmsg->poolp;
+ void *mark = PORT_ArenaMark(poolp);
+
+ /* create new expiration time attribute */
+ SecAsn1Item etime;
+ if (DER_CFDateToUTCTime(t, &etime) != SECSuccess) {
+ goto loser;
+ }
+
+ if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_APPLE_EXPIRATION_TIME, &etime, PR_FALSE)) == NULL) {
+ SECITEM_FreeItem (&etime, PR_FALSE);
+ goto loser;
+ }
+
+ SECITEM_FreeItem(&etime, PR_FALSE);
+
+ if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) {
+ goto loser;
+ }
+
+ PORT_ArenaUnmark(poolp, mark);
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease(poolp, mark);
+ return SECFailure;
+}
SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo) {
SecCertificateRef cert = NULL;
SecCertificateRef timestampCert;
CFDataRef hashAgilityAttrValue;
CFDictionaryRef hashAgilityV2AttrValues;
+ CFAbsoluteTime expirationTime;
};
#define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */
#define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */
CONST_OID appleHashAgility[] = {APPLE_CMS_ATTRIBUTES, 1};
CONST_OID appleHashAgilityV2[] = {APPLE_CMS_ATTRIBUTES, 2};
+/* Apple Expiration Time */
+CONST_OID appleExpirationTime[] = {APPLE_CMS_ATTRIBUTES, 3};
+
/* a special case: always associated with a caller-specified OID */
CONST_OID noOid[] = { 0 };
OD( appleHashAgilityV2, SEC_OID_APPLE_HASH_AGILITY_V2,
"appleCodesigningHashAgilityAttribute", CSSM_ALGID_NONE,
INVALID_CERT_EXTENSION),
+
+ /* Apple Expiration Time */
+ OD( appleExpirationTime, SEC_OID_APPLE_EXPIRATION_TIME,
+ "appleExpirationTimeAttribute", CSSM_ALGID_NONE,
+ INVALID_CERT_EXTENSION),
};
/*
static smime_cipher_map_entry smime_cipher_map[] = {
/* cipher algtag parms enabled allowed */
/* ---------------------------------------------------------------------------------- */
- { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, ¶m_int40, PR_TRUE, PR_TRUE },
- { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_TRUE, PR_TRUE },
- { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, ¶m_int64, PR_TRUE, PR_TRUE },
+ { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, ¶m_int40, PR_FALSE,PR_TRUE },
+ { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_FALSE,PR_TRUE },
+ { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, ¶m_int64, PR_FALSE,PR_TRUE },
{ SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, ¶m_int128, PR_TRUE, PR_TRUE },
{ SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL, PR_TRUE, PR_TRUE },
{ SMIME_AES_CBC_128, SEC_OID_AES_128_CBC, NULL, PR_TRUE, PR_TRUE },
- { SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL, PR_TRUE, PR_TRUE }
+ { SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL, PR_FALSE, PR_TRUE }
};
static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry);
{
PRArenaPool *poolp;
long cipher;
- long chosen_cipher;
+ long chosen_cipher = SMIME_DES_EDE3_168;
int *cipher_abilities;
int *cipher_votes;
- int weak_mapi;
int strong_mapi;
int rcount, mapi, max, i;
#if 1
Boolean scert_is_fortezza = (scert == NULL) ? PR_FALSE : PK11_FortezzaHasKEA(scert);
#endif
- chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
- weak_mapi = smime_mapi_by_cipher(chosen_cipher);
-
poolp = PORT_NewArena (1024); /* XXX what is right value? */
if (poolp == NULL)
goto done;
}
}
} else {
- /* no profile found - so we can only assume that the user can do
- * the mandatory algorithms which is RC2-40 (weak crypto) and 3DES (strong crypto) */
- SecPublicKeyRef key;
- unsigned int pklen_bits;
-
- /*
- * if recipient's public key length is > 512, vote for a strong cipher
- * please not that the side effect of this is that if only one recipient
- * has an export-level public key, the strong cipher is disabled.
- *
- * XXX This is probably only good for RSA keys. What I would
- * really like is a function to just say; Is the public key in
- * this cert an export-length key? Then I would not have to
- * know things like the value 512, or the kind of key, or what
- * a subjectPublicKeyInfo is, etc.
- */
- key = CERT_ExtractPublicKey(rcerts[rcount]);
- pklen_bits = 0;
- if (key != NULL) {
- SecKeyGetStrengthInBits(key, NULL, &pklen_bits);
- SECKEY_DestroyPublicKey (key);
- }
-
- if (pklen_bits > 512) {
- /* cast votes for the strong algorithm */
- cipher_abilities[strong_mapi]++;
- cipher_votes[strong_mapi] += pref;
- pref--;
- }
-
- /* always cast (possibly less) votes for the weak algorithm */
- cipher_abilities[weak_mapi]++;
- cipher_votes[weak_mapi] += pref;
+ /* cast votes for the strong algorithm */
+ cipher_abilities[strong_mapi]++;
+ cipher_votes[strong_mapi] += pref;
+ pref--;
}
if (profile != NULL)
SECITEM_FreeItem(profile, PR_TRUE);
#include <Security/SecCertificatePriv.h>
#include <utilities/SecCFRelease.h>
#include <utilities/SecDispatchRelease.h>
+#include <utilities/debugging.h>
#include "tsaSupport.h"
#include "tsaSupportPriv.h"
#include "tsaTemplates.h"
#include "cmslocal.h"
+#include "cert.h"
#include "secoid.h"
#include "secitem.h"
return result;
}
-static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, SecCertificateRef signerCert, SecAsn1TSATSTInfo *tstInfo, CFAbsoluteTime *timestampTime, uint64_t expectedNonce)
+static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, SecCmsSignerInfoRef signerinfo, SecAsn1TSATSTInfo *tstInfo, CFAbsoluteTime *timestampTime, uint64_t expectedNonce, CSSM_DATA_PTR encDigest)
{
OSStatus status = paramErr;
SecAsn1CoderRef coder = NULL;
if (!tstInfo)
return SECFailure;
+ SecCertificateRef signerCert = SecCmsSignerInfoGetTimestampSigningCert(signerinfo);
+ SecAsn1TSAMessageImprint expectedMessageImprint;
+
require_noerr(SecAsn1CoderCreate(&coder), xit);
require_noerr(SecAsn1Decode(coder, content->Data, content->Length,
kSecAsn1TSATSTInfoTemplate, tstInfo), xit);
require_action(expectedNonce==nonce, xit, status = errSecTimestampRejection);
}
- status = SecTSAValidateTimestamp(tstInfo, signerCert, timestampTime);
+ // Check the times in the timestamp
+ require_noerr(status = SecTSAValidateTimestamp(tstInfo, signerCert, timestampTime), xit);
dtprintf("SecTSAValidateTimestamp result: %ld\n", (long)status);
+ // Check the message imprint against the encDigest from the signerInfo containing this timestamp
+ SECOidTag hashAlg = SECOID_GetAlgorithmTag(&tstInfo->messageImprint.hashAlgorithm);
+ require_action(hashAlg == SEC_OID_SHA256 || hashAlg == SEC_OID_SHA1, xit, status = errSecInvalidDigestAlgorithm);
+ require_noerr(status = createTSAMessageImprint(signerinfo, &tstInfo->messageImprint.hashAlgorithm,
+ encDigest, &expectedMessageImprint), xit);
+ require_action(CERT_CompareCssmData(&expectedMessageImprint.hashedMessage, &tstInfo->messageImprint.hashedMessage), xit,
+ status = errSecTimestampInvalid; secerror("Timestamp MessageImprint did not match the signature's hash"));
+
xit:
if (coder)
SecAsn1CoderRelease(coder);
OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRef timeStampPolicy, CSSM_DATA_PTR inData, CSSM_DATA_PTR encDigest, uint64_t expectedNonce)
{
/*
- We update signerinfo with timestamp and tsa certificate chain.
- encDigest is the original signed blob, which we must hash and compare.
- inData comes from the unAuthAttr section of the CMS message
-
- These are set in signerinfo as side effects:
- timestampTime
- timestampCertList
- timestampCert
- */
+ We update signerinfo with timestamp and tsa certificate chain.
+ encDigest is the original signed blob, which we must hash and compare.
+ inData comes from the unAuthAttr section of the CMS message
+
+ These are set in signerinfo as side effects:
+ timestampTime
+ timestampCertList
+ timestampCert
+ */
SecCmsDecoderRef decoderContext = NULL;
SecCmsMessageRef cmsMessage = NULL;
/* decode the message */
require_noerr(result = SecCmsDecoderCreate (NULL, NULL, NULL, NULL, NULL, NULL, NULL, &decoderContext), xit);
result = SecCmsDecoderUpdate(decoderContext, inData->Data, inData->Length);
- if (result)
- {
+ if (result) {
result = errSecTimestampInvalid;
SecCmsDecoderDestroy(decoderContext);
goto xit;
- }
+ }
require_noerr(result = SecCmsDecoderFinish(decoderContext, &cmsMessage), xit);
// process the results
contentLevelCount = SecCmsMessageContentLevelCount(cmsMessage);
- if (encDigest)
+ if (encDigest) {
printDataAsHex("encDigest",encDigest, 0);
+ }
- for (ix = 0; ix < contentLevelCount; ++ix)
- {
+ for (ix = 0; ix < contentLevelCount; ++ix) {
dtprintf("\n----- Content Level %d -----\n", ix);
// get content information
contentInfo = SecCmsMessageContentLevel (cmsMessage, ix);
debugShowContentTypeOID(contentInfo);
- switch (contentTypeTag)
- {
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- require((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(contentInfo)) != NULL, xit);
+ switch (contentTypeTag) {
+ case SEC_OID_PKCS7_SIGNED_DATA: {
+ require((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(contentInfo)) != NULL, xit);
+
+ debugShowSignerInfo(signedData);
+
+ SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData);
+ unsigned digestAlgCount = SecCmsArrayCount((void **)digestAlgorithms);
+ dtprintf("digestAlgCount: %d\n", digestAlgCount);
+ if (signedData->digests) {
+ int jx;
+ char buffer[128];
+ for (jx=0;jx < digestAlgCount;jx++) {
+ sprintf(buffer, " digest[%u]", jx);
+ printDataAsHex(buffer,signedData->digests[jx], 0);
+ }
+ } else {
+ dtprintf("digests not yet computed\n");
+ CSSM_DATA_PTR innerContent = SecCmsContentInfoGetInnerContent(contentInfo);
+ if (innerContent)
+ {
+ dtprintf("inner content length: %ld\n", innerContent->Length);
+ SecAsn1TSAMessageImprint fakeMessageImprint = {{{0}},};
+ SecCmsSignerInfoRef tsaSigner = SecCmsSignedDataGetSignerInfo(signedData, 0);
+ OSStatus status = createTSAMessageImprint(tsaSigner, &tsaSigner->digestAlg, innerContent, &fakeMessageImprint);
+ require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status);
+ printDataAsHex("inner content hash",&fakeMessageImprint.hashedMessage, 0);
+ CSSM_DATA_PTR digestdata = &fakeMessageImprint.hashedMessage;
+ CSSM_DATA_PTR digests[2] = {digestdata, NULL};
+ status = SecCmsSignedDataSetDigests(signedData, digestAlgorithms, (CSSM_DATA_PTR *)&digests);
+ require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status);
+ } else {
+ dtprintf("no inner content\n");
+ }
+ }
- debugShowSignerInfo(signedData);
+ /*
+ Import the certificates. We leave this as a warning, since
+ there are configurations where the certificates are not returned.
+ */
+ signingCerts = SecCmsSignedDataGetCertificateList(signedData);
+ if (signingCerts == NULL) {
+ dtprintf("SecCmsSignedDataGetCertificateList returned NULL\n");
+ } else {
+ if (!signerinfo->timestampCertList) {
+ signerinfo->timestampCertList = CFArrayCreateMutable(kCFAllocatorDefault, 10, &kCFTypeArrayCallBacks);
+ }
+ saveTSACertificates(signingCerts, signerinfo->timestampCertList);
+ require_noerr(result = setTSALeafValidityDates(signerinfo), xit);
+ debugSaveCertificates(signingCerts);
+ }
- SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData);
- unsigned digestAlgCount = SecCmsArrayCount((void **)digestAlgorithms);
- dtprintf("digestAlgCount: %d\n", digestAlgCount);
- if (signedData->digests)
- {
- int jx;
- char buffer[128];
- for (jx=0;jx < digestAlgCount;jx++)
- {
- sprintf(buffer, " digest[%u]", jx);
- printDataAsHex(buffer,signedData->digests[jx], 0);
+ 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));
}
- }
- else
- {
- dtprintf("No digests\n");
- CSSM_DATA_PTR innerContent = SecCmsContentInfoGetInnerContent(contentInfo);
- if (innerContent)
- {
- dtprintf("inner content length: %ld\n", innerContent->Length);
- SecAsn1TSAMessageImprint fakeMessageImprint = {{{0}},};
- OSStatus status = createTSAMessageImprint(signedData, innerContent, &fakeMessageImprint);
- require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status);
- printDataAsHex("inner content hash",&fakeMessageImprint.hashedMessage, 0);
- CSSM_DATA_PTR digestdata = &fakeMessageImprint.hashedMessage;
- CSSM_DATA_PTR digests[2] = {digestdata, NULL};
- status = SecCmsSignedDataSetDigests(signedData, digestAlgorithms, (CSSM_DATA_PTR *)&digests);
- require_noerr_action(status, xit, dtprintf("createTSAMessageImprint status: %d\n", (int)status); result = status);
+
+ result = verifySigners(signedData, numberOfSigners, timeStampPolicy);
+ if (result) {
+ dtprintf("verifySigners failed: %ld\n", (long)result); // warning
+ goto xit; // remap to SecCmsVSTimestampNotTrusted ?
}
- else
- dtprintf("no inner content\n");
- }
- /*
- Import the certificates. We leave this as a warning, since
- there are configurations where the certificates are not returned.
- */
- signingCerts = SecCmsSignedDataGetCertificateList(signedData);
- if (signingCerts == NULL)
- { dtprintf("SecCmsSignedDataGetCertificateList returned NULL\n"); }
- else
- {
- if (!signerinfo->timestampCertList)
- signerinfo->timestampCertList = CFArrayCreateMutable(kCFAllocatorDefault, 10, &kCFTypeArrayCallBacks);
- saveTSACertificates(signingCerts, signerinfo->timestampCertList);
- require_noerr(result = setTSALeafValidityDates(signerinfo), xit);
- debugSaveCertificates(signingCerts);
+ break;
}
-
- 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));
+ case SEC_OID_PKCS9_SIGNING_CERTIFICATE: {
+ dtprintf("SEC_OID_PKCS9_SIGNING_CERTIFICATE seen\n");
+ break;
}
-
- result = verifySigners(signedData, numberOfSigners, timeStampPolicy);
- if (result)
- dtprintf("verifySigners failed: %ld\n", (long)result); // warning
-
-
- if (result) // remap to SecCmsVSTimestampNotTrusted ?
- goto xit;
-
- break;
- }
- case SEC_OID_PKCS9_SIGNING_CERTIFICATE:
- {
- dtprintf("SEC_OID_PKCS9_SIGNING_CERTIFICATE seen\n");
- break;
- }
-
- case SEC_OID_PKCS9_ID_CT_TSTInfo:
- {
- SecAsn1TSATSTInfo tstInfo = {{0},};
- SecCertificateRef signerCert = SecCmsSignerInfoGetTimestampSigningCert(signerinfo);
- result = verifyTSTInfo(contentInfo->rawContent, signerCert, &tstInfo, &signerinfo->timestampTime, expectedNonce);
- if (signerinfo->timestampTime)
- {
- const char *tstamp = cfabsoluteTimeToString(signerinfo->timestampTime);
- if (tstamp)
- {
- dtprintf("Timestamp Authority timestamp: %s\n", tstamp);
- free((void *)tstamp);
+ case SEC_OID_PKCS9_ID_CT_TSTInfo: {
+ SecAsn1TSATSTInfo tstInfo = {{0},};
+ result = verifyTSTInfo(contentInfo->rawContent, signerinfo, &tstInfo, &signerinfo->timestampTime, expectedNonce, encDigest);
+ if (signerinfo->timestampTime) {
+ const char *tstamp = cfabsoluteTimeToString(signerinfo->timestampTime);
+ if (tstamp) {
+ dtprintf("Timestamp Authority timestamp: %s\n", tstamp);
+ free((void *)tstamp);
+ }
}
+ break;
}
- break;
- }
- case SEC_OID_OTHER:
- {
- dtprintf("otherContent : %p\n", (char *)SecCmsContentInfoGetContent (contentInfo));
- break;
- }
- default:
- dtprintf("ContentTypeTag : %x\n", contentTypeTag);
- break;
+ case SEC_OID_OTHER: {
+ dtprintf("otherContent : %p\n", (char *)SecCmsContentInfoGetContent (contentInfo));
+ break;
+ }
+ default:
+ dtprintf("ContentTypeTag : %x\n", contentTypeTag);
+ break;
}
}
xit:
- if (cmsMessage)
- SecCmsMessageDestroy(cmsMessage);
+ if (cmsMessage) {
+ SecCmsMessageDestroy(cmsMessage);
+ }
return result;
}
extern const CFStringRef kTSAContextKeyURL; // CFURLRef
extern const CFStringRef kTSAContextKeyNoCerts; // CFBooleanRef
-OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprint, uint64_t nonce, CSSM_DATA *signedDERBlob);
+OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprint, uint64_t nonce, CSSM_DATA *signedDERBlob) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
CFMutableDictionaryRef SecCmsTSAGetDefaultContext(CFErrorRef *error);
void SecCmsMessageSetTSAContext(SecCmsMessageRef cmsg, CFTypeRef tsaContext);
OSStatus SecTSAResponseCopyDEREncoding(SecAsn1CoderRef coder, const CSSM_DATA *tsaResponse, SecAsn1TimeStampRespDER *respDER);
OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inData, CSSM_DATA_PTR encDigest, uint64_t expectedNonce);
OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRef timeStampPolicy, CSSM_DATA_PTR inData, CSSM_DATA_PTR encDigest, uint64_t expectedNonce);
-OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR encDigest, SecAsn1TSAMessageImprint *messageImprint);
+OSStatus createTSAMessageImprint(SecCmsSignerInfoRef signerInfo, SECAlgorithmID *digestAlg,
+ CSSM_DATA_PTR encDigest, SecAsn1TSAMessageImprint *messageImprint);
#ifndef NDEBUG
int tsaWriteFileX(const char *fileName, const unsigned char *bytes, size_t numBytes);
4C2741E803E9FBAF00A80181 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0810;
+ LastUpgradeCheck = 1000;
};
buildConfigurationList = C23B0CD909A298C100B7FCED /* Build configuration list for PBXProject "libsecurity_smime" */;
compatibilityVersion = "Xcode 3.2";
054049910A3769AC0035F195 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
};
name = Debug;
};
054049950A3769AC0035F195 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
};
name = Release;
};
isa = XCBuildConfiguration;
baseConfigurationReference = 182BB39F146F1A68000BF1F3 /* debug.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COMBINE_HIDPI_IMAGES = YES;
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
};
isa = XCBuildConfiguration;
baseConfigurationReference = 182BB3A1146F1A68000BF1F3 /* release.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COMBINE_HIDPI_IMAGES = YES;
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
};
buildSettings = {
ASSETCATALOG_COMPRESSION = lossless;
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_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = 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;
buildSettings = {
ASSETCATALOG_COMPRESSION = "respect-asset-catalog";
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_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = 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;
kSSLClientCertRejected
};
+/*
+ * Convenience ciphersuite groups that collate ciphersuites of comparable security
+ * properties into a single alias.
+ */
+typedef CF_ENUM(int, SSLCiphersuiteGroup) {
+ kSSLCiphersuiteGroupDefault,
+ kSSLCiphersuiteGroupCompatibility,
+ kSSLCiphersuiteGroupLegacy,
+ kSSLCiphersuiteGroupATS,
+ kSSLCiphersuiteGroupATSCompatibility,
+};
+
/*
* R/W functions. The application using this library provides
* these functions via SSLSetIOFuncs().
#include <Security/sslTypes.h>
+/* Return the list of ciphersuites associated with a SSLCiphersuiteGroup */
+const SSLCipherSuite *SSLCiphersuiteGroupToCiphersuiteList(SSLCiphersuiteGroup group,
+ size_t *listSize);
+
+/* Determine minimum allowed TLS version for the given ciphersuite */
+SSLProtocol SSLCiphersuiteMinimumTLSVersion(SSLCipherSuite ciphersuite);
+
+/* Determine maximum allowed TLS version for the given ciphersuite */
+SSLProtocol SSLCiphersuiteMaximumTLSVersion(SSLCipherSuite ciphersuite);
+
/* Create an SSL Context with an external record layer - eg: kernel accelerated layer */
SSLContextRef
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc,
OSStatus
_SSLSetProtocolVersionEnabled (SSLContextRef context,
SSLProtocol protocol,
- Boolean enable);
+ Boolean enable) API_UNAVAILABLE(iosmac);
/*
* Obtain a value specified in SSLSetProtocolVersionEnabled.
OSStatus
_SSLGetProtocolVersionEnabled(SSLContextRef context,
SSLProtocol protocol,
- Boolean *enable); /* RETURNED */
+ Boolean *enable) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Get/set SSL protocol version; optional. Default is kSSLProtocolUnknown,
*/
OSStatus
_SSLSetProtocolVersion (SSLContextRef context,
- SSLProtocol version);
+ SSLProtocol version) API_UNAVAILABLE(iosmac);
/*
* Obtain the protocol version specified in SSLSetProtocolVersion.
*/
OSStatus
_SSLGetProtocolVersion (SSLContextRef context,
- SSLProtocol *protocol); /* RETURNED */
+ SSLProtocol *protocol) API_UNAVAILABLE(iosmac); /* RETURNED */
/* API REVIEW:
The following 15 calls were used to change the behaviour of the trust
*/
OSStatus
_SSLSetEnableCertVerify (SSLContextRef context,
- Boolean enableVerify);
+ Boolean enableVerify) API_UNAVAILABLE(iosmac);
OSStatus
_SSLGetEnableCertVerify (SSLContextRef context,
- Boolean *enableVerify); /* RETURNED */
+ Boolean *enableVerify) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Specify the option of ignoring certificates' "expired" times.
*/
OSStatus
_SSLSetAllowsExpiredCerts (SSLContextRef context,
- Boolean allowsExpired);
+ Boolean allowsExpired) API_UNAVAILABLE(iosmac);
/*
* Obtain the current value of an SSLContext's "allowExpiredCerts" flag.
*/
OSStatus
_SSLGetAllowsExpiredCerts (SSLContextRef context,
- Boolean *allowsExpired); /* RETURNED */
+ Boolean *allowsExpired) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Similar to SSLSetAllowsExpiredCerts(), this function allows the
*/
OSStatus
_SSLSetAllowsExpiredRoots (SSLContextRef context,
- Boolean allowsExpired);
+ Boolean allowsExpired) API_UNAVAILABLE(iosmac);
OSStatus
_SSLGetAllowsExpiredRoots (SSLContextRef context,
- Boolean *allowsExpired); /* RETURNED */
+ Boolean *allowsExpired) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Specify option of allowing for an unknown root cert, i.e., one which
*/
OSStatus
_SSLSetAllowsAnyRoot (SSLContextRef context,
- Boolean anyRoot);
+ Boolean anyRoot) API_UNAVAILABLE(iosmac);
/*
* Obtain the current value of an SSLContext's "allow any root" flag.
*/
OSStatus
_SSLGetAllowsAnyRoot (SSLContextRef context,
- Boolean *anyRoot); /* RETURNED */
+ Boolean *anyRoot) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Augment or replace the system's default trusted root certificate set
OSStatus
_SSLSetTrustedRoots (SSLContextRef context,
CFArrayRef trustedRoots,
- Boolean replaceExisting);
+ Boolean replaceExisting) API_UNAVAILABLE(iosmac);
/*
* Obtain an array of SecCertificateRefs representing the current
*/
OSStatus
_SSLCopyTrustedRoots (SSLContextRef context,
- CFArrayRef *trustedRoots); /* RETURNED */
+ CFArrayRef *trustedRoots) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Add a SecCertificateRef, or a CFArray of them, to a server's list
OSStatus
_SSLSetCertificateAuthorities(SSLContextRef context,
CFTypeRef certificateOrArray,
- Boolean replaceExisting);
+ Boolean replaceExisting) API_UNAVAILABLE(iosmac);
/*
* Obtain the certificates specified in SSLSetCertificateAuthorities(),
OSStatus
_SSLCopyCertificateAuthorities(SSLContextRef context,
- CFArrayRef *certificates); /* RETURNED */
+ CFArrayRef *certificates) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Request peer certificates. Valid anytime, subsequent to
*/
OSStatus
_SSLCopyPeerCertificates (SSLContextRef context,
- CFArrayRef *certs); /* RETURNED */
+ CFArrayRef *certs) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Specify Diffie-Hellman parameters. Optional; if we are configured to allow
*/
OSStatus _SSLSetDiffieHellmanParams (SSLContextRef context,
const void *dhParams,
- size_t dhParamsLen);
+ size_t dhParamsLen) API_UNAVAILABLE(iosmac);
/*
* Return parameter block specified in SSLSetDiffieHellmanParams.
*/
OSStatus _SSLGetDiffieHellmanParams (SSLContextRef context,
const void **dhParams,
- size_t *dhParamsLen);
+ size_t *dhParamsLen) API_UNAVAILABLE(iosmac);
/*
* Enable/Disable RSA blinding. This feature thwarts a known timing
* enabled.
*/
OSStatus _SSLSetRsaBlinding (SSLContextRef context,
- Boolean blinding);
+ Boolean blinding) API_UNAVAILABLE(iosmac);
OSStatus _SSLGetRsaBlinding (SSLContextRef context,
- Boolean *blinding);
+ Boolean *blinding) API_UNAVAILABLE(iosmac);
/*
* Create a new SSL/TLS session context.
*/
OSStatus
_SSLNewContext (Boolean isServer,
- SSLContextRef *tlsContextPtr); /* RETURNED */
+ SSLContextRef *tlsContextPtr) API_UNAVAILABLE(iosmac); /* RETURNED */
/*
* Dispose of an SSLContextRef. This is effectivly a CFRelease.
* Deprecated.
*/
OSStatus
-_SSLDisposeContext (SSLContextRef context);
+_SSLDisposeContext (SSLContextRef context) API_UNAVAILABLE(iosmac);
/* We redefine the names of all SPIs to avoid collision with unavailable APIs */
#define SSLSetProtocolVersionEnabled _SSLSetProtocolVersionEnabled
*/
OSStatus
SSLNewDatagramContext (Boolean isServer,
- SSLContextRef *dtlsContextPtr); /* RETURNED */
+ SSLContextRef *dtlsContextPtr) API_UNAVAILABLE(iosmac); /* RETURNED */
#define ENABLE_DTLS 1
#define ENABLE_3DES 1 /* normally enabled */
-#define ENABLE_RC4 1 /* normally enabled */
#define ENABLE_DES 0 /* normally disabled */
#define ENABLE_RC2 0 /* normally disabled */
#define ENABLE_AES 1 /* normally enabled, our first preference */
TLS_RSA_WITH_AES_128_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
-#if ENABLE_RC4
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDH_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_MD5,
-#endif
-
/* TLS 1.3 ciphersuites */
#if ENABLE_AES_GCM
TLS_AES_128_GCM_SHA256,
TLS_DH_anon_WITH_AES_256_CBC_SHA256,
TLS_DH_anon_WITH_AES_128_CBC_SHA,
TLS_DH_anon_WITH_AES_256_CBC_SHA,
- SSL_DH_anon_WITH_RC4_128_MD5,
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
TLS_PSK_WITH_AES_128_CBC_SHA256,
TLS_PSK_WITH_AES_256_CBC_SHA,
TLS_PSK_WITH_AES_128_CBC_SHA,
- TLS_PSK_WITH_RC4_128_SHA,
TLS_PSK_WITH_3DES_EDE_CBC_SHA,
TLS_PSK_WITH_NULL_SHA384,
TLS_PSK_WITH_NULL_SHA256,
TLS_RSA_WITH_NULL_SHA256,
SSL_RSA_WITH_NULL_SHA,
SSL_RSA_WITH_NULL_MD5
-
};
static const unsigned STCipherSuiteCount = sizeof(STKnownCipherSuites)/sizeof(STKnownCipherSuites[0]);
+#define CiphersuitesTLS13 \
+ TLS_AES_128_GCM_SHA256, \
+ TLS_AES_256_GCM_SHA384, \
+ TLS_CHACHA20_POLY1305_SHA256
+
+#define CiphersuitesPFS \
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, \
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, \
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, \
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, \
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, \
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, \
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, \
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, \
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, \
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, \
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, \
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, \
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, \
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+
+#define CiphersuitesNonPFS \
+ TLS_RSA_WITH_AES_256_GCM_SHA384, \
+ TLS_RSA_WITH_AES_128_GCM_SHA256, \
+ TLS_RSA_WITH_AES_256_CBC_SHA256, \
+ TLS_RSA_WITH_AES_128_CBC_SHA256, \
+ TLS_RSA_WITH_AES_256_CBC_SHA, \
+ TLS_RSA_WITH_AES_128_CBC_SHA
+
+#define CiphersuitesTLS10 \
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, \
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, \
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, \
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, \
+ TLS_RSA_WITH_AES_256_CBC_SHA, \
+ TLS_RSA_WITH_AES_128_CBC_SHA
+
+#define CiphersuitesTLS10_3DES \
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, \
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, \
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA
+
+#define CiphersuitesDHE \
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, \
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, \
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, \
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, \
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA, \
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, \
+ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+
+
+#define DefineTLSCiphersuiteGroupList(XXX, ...) \
+static const SSLCipherSuite List##XXX[] = { \
+ __VA_ARGS__ \
+};
+
+DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupDefault,
+ CiphersuitesTLS13,
+ CiphersuitesPFS);
+DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupCompatibility,
+ CiphersuitesNonPFS,
+ CiphersuitesTLS10,
+ CiphersuitesTLS10_3DES);
+DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupLegacy,
+ CiphersuitesDHE);
+DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupATS,
+ CiphersuitesTLS13,
+ CiphersuitesPFS);
+DefineTLSCiphersuiteGroupList(kSSLCiphersuiteGroupATSCompatibility,
+ CiphersuitesNonPFS);
+
+typedef struct tls_ciphersuite_definition {
+ SSLCipherSuite ciphersuite;
+ SSLProtocol min_version;
+ SSLProtocol max_version;
+ char ciphersuite_name[64];
+} *tls_ciphersuite_definition_t;
+
+#define DefineTLSCiphersuiteDefinition(XXX, MIN_VERSION, MAX_VERSION) \
+{ \
+ .ciphersuite = XXX, \
+ .ciphersuite_name = "##XXX", \
+ .min_version = MIN_VERSION, \
+ .max_version = MAX_VERSION, \
+}
+
+static const struct tls_ciphersuite_definition tls_ciphersuite_definitions[] = {
+ // TLS 1.3 ciphersuites
+ DefineTLSCiphersuiteDefinition(TLS_AES_128_GCM_SHA256, kTLSProtocol13, kTLSProtocolMaxSupported),
+ DefineTLSCiphersuiteDefinition(TLS_AES_256_GCM_SHA384, kTLSProtocol13, kTLSProtocolMaxSupported),
+ DefineTLSCiphersuiteDefinition(TLS_CHACHA20_POLY1305_SHA256, kTLSProtocol13, kTLSProtocolMaxSupported),
+
+ // RFC 7905: ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS)
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, kTLSProtocol12, kTLSProtocol12),
+
+ // RFC 5289: TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM)
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12),
+
+ // RFC 5288: AES Galois Counter Mode (GCM) Cipher Suites for TLS
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, kTLSProtocol12, kTLSProtocol12),
+
+ // RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(SSL_RSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, kTLSProtocol12, kTLSProtocol12),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, kTLSProtocol12, kTLSProtocol12),
+
+ // RFC 4492: Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+
+ // RFC 3268: Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS)
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+ DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, kTLSProtocol1, kTLSProtocol11),
+};
+
+// Size of the definition list
+static const size_t tls_ciphersuite_definitions_length = \
+ sizeof(tls_ciphersuite_definitions) / sizeof(struct tls_ciphersuite_definition);
+
+// Remove macro definitions
+#undef CiphersuitesTLS13
+#undef CiphersuitesPFS
+#undef CiphersuitesNonPFS
+#undef CiphersuitesTLS10_3DES
+#undef CiphersuitesTLS10
+#undef CiphersuitesDHE
+#undef DefineTLSCiphersuiteGroupList
+#undef DefineTLSCiphersuiteDefinition
+
+const SSLCipherSuite *
+SSLCiphersuiteGroupToCiphersuiteList(SSLCiphersuiteGroup group, size_t *listSize)
+{
+ if (listSize == NULL) {
+ return NULL;
+ }
+
+ const SSLCipherSuite *ciphersuites = NULL;
+ size_t count = 0;
+
+#define CASE_CONFIG(GROUPNAME) \
+ case GROUPNAME: \
+ ciphersuites = List##GROUPNAME; \
+ count = sizeof(List##GROUPNAME) / sizeof(SSLCipherSuite); \
+ break;
+
+ switch (group) {
+ CASE_CONFIG(kSSLCiphersuiteGroupDefault);
+ CASE_CONFIG(kSSLCiphersuiteGroupCompatibility);
+ CASE_CONFIG(kSSLCiphersuiteGroupLegacy);
+ CASE_CONFIG(kSSLCiphersuiteGroupATS);
+ CASE_CONFIG(kSSLCiphersuiteGroupATSCompatibility);
+ }
+
+#undef CASE_CONFIG
+
+ if (ciphersuites != NULL) {
+ *listSize = count;
+ return ciphersuites;
+ }
+
+ *listSize = 0;
+ return NULL;
+}
+
+SSLProtocol
+SSLCiphersuiteMinimumTLSVersion(SSLCipherSuite ciphersuite)
+{
+ for (size_t i = 0; i < tls_ciphersuite_definitions_length; i++) {
+ if (tls_ciphersuite_definitions[i].ciphersuite == ciphersuite) {
+ return tls_ciphersuite_definitions[i].min_version;
+ }
+ }
+ return kSSLProtocolUnknown;
+}
+
+SSLProtocol
+SSLCiphersuiteMaximumTLSVersion(SSLCipherSuite ciphersuite)
+{
+ for (size_t i = 0; i < tls_ciphersuite_definitions_length; i++) {
+ if (tls_ciphersuite_definitions[i].ciphersuite == ciphersuite) {
+ return tls_ciphersuite_definitions[i].max_version;
+ }
+ }
+ return kSSLProtocolUnknown;
+}
/*
* Convert an array of uint16_t
if (version > MINIMUM_DATAGRAM_VERSION ||
version < MAXIMUM_DATAGRAM_VERSION)
return errSSLIllegalParam;
- if (version > ctx->minProtocolVersion)
+ if (version > (SSLProtocolVersion)ctx->minProtocolVersion)
ctx->minProtocolVersion = version;
} else {
if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
return errSSLIllegalParam;
- if (version < ctx->minProtocolVersion)
+ if (version < (SSLProtocolVersion)ctx->minProtocolVersion)
ctx->minProtocolVersion = version;
}
ctx->maxProtocolVersion = version;
if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) {
return errSecParam;
}
- if (version > ctx->maxProtocolVersion) {
+ if (version > (SSLProtocolVersion)ctx->maxProtocolVersion) {
ctx->maxProtocolVersion = version;
if (ctx->minProtocolVersion == SSL_Version_Undetermined)
ctx->minProtocolVersion = version;
}
- if (version < ctx->minProtocolVersion) {
+ if (version < (SSLProtocolVersion)ctx->minProtocolVersion) {
ctx->minProtocolVersion = version;
}
} else {
nextVersion = SSL_Version_Undetermined;
break;
}
- ctx->minProtocolVersion = max(ctx->minProtocolVersion, nextVersion);
+ ctx->minProtocolVersion = (tls_protocol_version)max((SSLProtocolVersion)ctx->minProtocolVersion, nextVersion);
if (ctx->minProtocolVersion > ctx->maxProtocolVersion) {
ctx->minProtocolVersion = SSL_Version_Undetermined;
ctx->maxProtocolVersion = SSL_Version_Undetermined;
case kTLSProtocol12:
{
SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
- *enable = (ctx->minProtocolVersion <= version
- && ctx->maxProtocolVersion >= version);
+ *enable = ((SSLProtocolVersion)ctx->minProtocolVersion <= version
+ && (SSLProtocolVersion)ctx->maxProtocolVersion >= version);
break;
}
case kSSLProtocolAll:
*/
CFIndex sslPubKeyGetAlgorithmID(SecKeyRef pubKey)
{
-#if TARGET_OS_IPHONE
- return SecKeyGetAlgorithmID(pubKey);
-#else
return SecKeyGetAlgorithmId(pubKey);
-#endif
}
/*
*/
CFIndex sslPrivKeyGetAlgorithmID(SecKeyRef privKey)
{
-#if TARGET_OS_IPHONE
- return SecKeyGetAlgorithmID(privKey);
-#else
return SecKeyGetAlgorithmId(privKey);
-#endif
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
--- /dev/null
+#include <AssertMacros.h>
+#import "STLegacyTests.h"
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/array_size.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#include <tls_ciphersuites.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+
+/*
+ SSL CipherSuite tests
+*/
+@implementation STLegacyTests (ciphers)
+
+static const SSLCipherSuite SupportedCipherSuites[] = {
+
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+
+ /* Unsafe ciphersuites */
+
+ TLS_DH_anon_WITH_AES_256_GCM_SHA384,
+ TLS_DH_anon_WITH_AES_128_GCM_SHA256,
+ TLS_DH_anon_WITH_AES_128_CBC_SHA256,
+ TLS_DH_anon_WITH_AES_256_CBC_SHA256,
+ TLS_DH_anon_WITH_AES_128_CBC_SHA,
+ TLS_DH_anon_WITH_AES_256_CBC_SHA,
+ SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
+
+ TLS_ECDH_anon_WITH_NULL_SHA,
+ TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
+ TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+
+ TLS_ECDHE_ECDSA_WITH_NULL_SHA,
+ TLS_ECDHE_RSA_WITH_NULL_SHA,
+
+ TLS_PSK_WITH_AES_256_CBC_SHA384,
+ TLS_PSK_WITH_AES_128_CBC_SHA256,
+ TLS_PSK_WITH_AES_256_CBC_SHA,
+ TLS_PSK_WITH_AES_128_CBC_SHA,
+ TLS_PSK_WITH_3DES_EDE_CBC_SHA,
+ TLS_PSK_WITH_NULL_SHA384,
+ TLS_PSK_WITH_NULL_SHA256,
+ TLS_PSK_WITH_NULL_SHA,
+
+ TLS_RSA_WITH_NULL_SHA256,
+ SSL_RSA_WITH_NULL_SHA,
+ SSL_RSA_WITH_NULL_MD5
+
+};
+
+static const unsigned SupportedCipherSuitesCount = sizeof(SupportedCipherSuites)/sizeof(SupportedCipherSuites[0]);
+
+
+static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12, kDTLSProtocol1 };
+static int nprotos = sizeof(protos)/sizeof(protos[0]);
+
+
+static unsigned char dh_param_1024_bytes[] = {
+ 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xf2, 0x56, 0xb9, 0x41, 0x74,
+ 0x8c, 0x54, 0x22, 0xad, 0x94, 0x2b, 0xed, 0x83, 0xb9, 0xa0, 0x2f, 0x40,
+ 0xce, 0xf8, 0xec, 0x96, 0xed, 0xcd, 0x8e, 0xfc, 0xf8, 0xdd, 0x06, 0x15,
+ 0xbc, 0x68, 0x0d, 0x0e, 0x2c, 0xef, 0x00, 0x71, 0x28, 0x3d, 0x27, 0x6d,
+ 0x5e, 0x42, 0x8c, 0xbd, 0x0f, 0x07, 0x23, 0x9d, 0x07, 0x8e, 0x52, 0x47,
+ 0xa2, 0x5d, 0xf8, 0xd9, 0x9a, 0x7b, 0xb4, 0xab, 0xd2, 0xa3, 0x39, 0xe9,
+ 0x2c, 0x3b, 0x9b, 0xaa, 0xbe, 0x4e, 0x01, 0x36, 0x16, 0xc2, 0x9e, 0x7b,
+ 0x38, 0x78, 0x82, 0xd0, 0xed, 0x8e, 0x1e, 0xce, 0xa6, 0x23, 0x95, 0xae,
+ 0x31, 0x66, 0x58, 0x60, 0x44, 0xdf, 0x1f, 0x9c, 0x68, 0xbf, 0x8b, 0xf1,
+ 0xb4, 0xa8, 0xe7, 0xb2, 0x43, 0x8b, 0xa9, 0x3d, 0xa1, 0xb7, 0x1a, 0x11,
+ 0xcf, 0xf4, 0x5e, 0xf7, 0x08, 0xf6, 0x84, 0x1c, 0xd7, 0xfa, 0x40, 0x10,
+ 0xdc, 0x64, 0x83, 0x02, 0x01, 0x02
+};
+static unsigned char *dh_param_der = dh_param_1024_bytes;
+static unsigned int dh_param_der_len = sizeof(dh_param_1024_bytes);
+
+
+typedef struct {
+ uint32_t session_id;
+ bool is_session_resume;
+ SSLContextRef st;
+ bool is_server;
+ bool is_dtls;
+ SSLAuthenticate client_side_auth;
+ bool dh_anonymous;
+ int comm;
+ CFArrayRef certs;
+ CFArrayRef peer_certs;
+ SSLProtocol proto;
+ uint64_t time; // output
+} ssl_test_handle;
+
+#if 0 // currently unused
+static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity)
+{
+ CFMutableArrayRef chain = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ SecTrustResultType trust_result;
+
+ do {
+ policy = SecPolicyCreateSSL(false, NULL);
+ if (!policy)
+ break;
+
+ SecCertificateRef cert = NULL;
+ if (SecIdentityCopyCertificate(identity, &cert))
+ break;
+
+ CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert,
+ 1, &kCFTypeArrayCallBacks);
+ CFRelease(cert);
+ if (!certs)
+ break;
+
+ if (SecTrustCreateWithCertificates(certs, policy, &trust))
+ break;
+ CFRelease(certs);
+ CFRelease(policy);
+ if (SecTrustEvaluate(trust, &trust_result))
+ break;
+
+ int i, count = SecTrustGetCertificateCount(trust);
+ chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue(chain, identity);
+ for (i = 1; i < count; i++) {
+ if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified))
+ continue; /* skip anchor if chain is complete */
+ SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i);
+ CFArrayAppendValue(chain, s);
+ }
+ } while (0);
+ if (trust)
+ CFRelease(trust);
+ if (policy)
+ CFRelease(policy);
+ return chain;
+}
+#endif // currently unused
+
+// MARK: -
+// MARK: SecureTransport support
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+ size_t ix;
+ printf("socket write(%p, %lu)\n", bytes, len);
+ for (ix = 0; ix < len; ++ix) {
+ if (!(ix % 16))
+ printf("\n");
+ printf("%02X ", bytes[ix]);
+ }
+ printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ hexdump(ptr, len);
+ ret = write((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ } else {
+ printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno);
+ return -errno;
+ }
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static unsigned char dn[] = {
+ 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
+};
+static unsigned int dn_len = 96;
+
+static SSLContextRef make_ssl_ref(bool server, SSLAuthenticate client_side_auth, bool dh_anonymous,
+ bool dtls, int sock, CFArrayRef certs, SSLProtocol proto)
+{
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType);
+ require(ctx, out);
+
+ if(dtls) {
+ size_t mtu;
+ require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out);
+ require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out);
+ }
+ require_noerr(SSLSetProtocolVersionMax(ctx, proto), out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
+ static const char *peer_domain_name = "localhost";
+ require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+ strlen(peer_domain_name)), out);
+
+ require_noerr(SSLSetMinimumDHGroupSize(ctx, 512), out);
+
+ if (!dh_anonymous) {
+ if (server)
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+ if ((client_side_auth != kNeverAuthenticate) && server) {
+ SSLAuthenticate auth;
+ require_noerr(SSLSetClientSideAuthenticate(ctx, client_side_auth), out);
+ require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
+ require(auth==client_side_auth, out);
+ require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
+ }
+#if 0 /* Setting client certificate in advance */
+ if ((client_side_auth == kAlwaysAuthenticate) && !server)
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+#endif
+ if ((client_side_auth != kNeverAuthenticate) && !server) /* enable break from SSLHandshake */
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnCertRequested, true), out);
+ }
+
+ /* Set this option, even if doing anonDH or PSK - it should NOT break out in those case */
+ require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out);
+
+ /* Tell SecureTransport to not check certs itself: it will break out of the
+ handshake to let us take care of it instead. */
+ require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+ if (server) {
+ require_noerr(SSLSetDiffieHellmanParams(ctx,
+ dh_param_der, dh_param_der_len), out);
+ }
+ else /* if client */ {
+ }
+
+ return ctx;
+out:
+ if (ctx)
+ CFRelease(ctx);
+ return NULL;
+}
+
+static bool check_peer_cert(SSLContextRef ctx, const ssl_test_handle *ssl, SecTrustRef *trust)
+{
+ CFMutableArrayRef peer_cert_array = NULL;
+ CFMutableArrayRef orig_peer_cert_array = NULL;
+
+ /* verify peer cert chain */
+ require_noerr(SSLCopyPeerTrust(ctx, trust), out);
+ SecTrustResultType trust_result = 0;
+ /* this won't verify without setting up a trusted anchor */
+ require_noerr(SecTrustEvaluate(*trust, &trust_result), out);
+
+ CFIndex n_certs = SecTrustGetCertificateCount(*trust);
+
+ peer_cert_array = CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
+ orig_peer_cert_array = CFArrayCreateMutableCopy(NULL, n_certs, ssl->peer_certs);
+ while (n_certs--)
+ CFArrayInsertValueAtIndex(peer_cert_array, 0,
+ SecTrustGetCertificateAtIndex(*trust, n_certs));
+
+ SecIdentityRef ident =
+ (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
+ SecCertificateRef peer_cert = NULL;
+ require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
+ CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
+ CFRelease(peer_cert);
+
+ require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
+ CFReleaseNull(orig_peer_cert_array);
+ CFReleaseNull(peer_cert_array);
+
+ return true;
+out:
+ CFReleaseNull(orig_peer_cert_array);
+ CFReleaseNull(peer_cert_array);
+ return false;
+}
+
+
+#include <mach/mach_time.h>
+
+#define perf_start() uint64_t _perf_time = mach_absolute_time();
+#define perf_scale_factor() ({struct mach_timebase_info info; mach_timebase_info(&info); ((double)info.numer) / (1000000.0 * info.denom);})
+#define perf_time() ((mach_absolute_time() - _perf_time) * perf_scale_factor())
+
+
+static void *securetransport_ssl_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_test_handle * ssl = (ssl_test_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SecTrustRef trust = NULL;
+ bool got_server_auth = false, got_client_cert_req = false;
+ SSLSessionState ssl_state;
+
+ perf_start();
+
+ pthread_setname_np(ssl->is_server?"server thread":"client thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLPeerAuthCompleted)
+ {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ require_string(!got_server_auth, out, "second server auth");
+ require_string(!ssl->dh_anonymous, out, "server auth with anon cipher");
+ // Note: Previously, the implementation always returned errSSLPeerAuthCompleted before
+ // errSSLClientCertRequested. Due to OCSP stappling implementation, this is no longer guaranteed.
+ // This behavior change should not be an issue, but it's possible that some applications will
+ // have issue with this new behavior. If we do find out that this is causing an issue, then
+ // the following require statement should be re-enabled, and the implementation changed
+ // to implement the former behavior.
+ //require_string(!got_client_cert_req, out, "got client cert req before server auth");
+ got_server_auth = true;
+ require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+ require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed");
+ } else if (ortn == errSSLClientCertRequested) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ require_string(!got_client_cert_req, out, "second client cert req");
+ // Note: see Note above.
+ //require_string(got_server_auth, out, "didn't get server auth first");
+ got_client_cert_req = true;
+
+ /* set client cert */
+ require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
+ require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
+
+ CFArrayRef DNs = NULL;
+ require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
+ require(DNs, out);
+ CFRelease(DNs);
+
+ require_string(ssl->client_side_auth != kNeverAuthenticate, out, "errSSLClientCertRequested in run not testing that");
+ if(ssl->client_side_auth == kAlwaysAuthenticate) { // Only set a client cert in mode 1.
+ require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
+ }
+ } else if (ortn == errSSLWouldBlock) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ }
+ } while (ortn == errSSLWouldBlock
+ || ortn == errSSLServerAuthCompleted
+ || ortn == errSSLClientCertRequested);
+ require_noerr_action_quiet(ortn, out,
+ fprintf(stderr, "Fell out of SSLHandshake with error: %d (%s)\n", (int)ortn, ssl->is_server?"server":"client"));
+
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+
+ if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
+ require_string(got_server_auth, out, "never got server auth");
+ if (ssl->client_side_auth != kNeverAuthenticate)
+ require_string(got_client_cert_req, out, "never got client cert req");
+ }
+
+ if (!ssl->is_server && !ssl->dh_anonymous && ssl->is_session_resume) {
+ require_string(!got_server_auth, out, "got server auth during resumption??");
+ require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed (resumption case)");
+ }
+
+ SSLCipherSuite cipherSuite;
+ require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
+
+ if(ssl->is_dtls) {
+ size_t sz;
+ SSLGetDatagramWriteSize(ctx, &sz);
+ }
+
+ Boolean sessionWasResumed = false;
+ uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
+ size_t session_id_length = sizeof(session_id_data);
+ require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
+ require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
+
+#define BUFSIZE (8*1024)
+ unsigned char ibuf[BUFSIZE], obuf[BUFSIZE];
+
+ for(int i=0; i<10; i++) {
+ size_t len;
+ if (ssl->is_server) {
+ memset(obuf, i, BUFSIZE);
+ require_noerr(ortn = SSLWrite(ctx, obuf, BUFSIZE, &len), out);
+ require_action(len == BUFSIZE, out, ortn = -1);
+
+ require_noerr(ortn = SSLWrite(ctx, obuf, 0, &len), out);
+ require_action(len == 0, out, ortn = -1);
+ }
+
+ len=0;
+ while(len<BUFSIZE) {
+ size_t l=len;
+ ortn = SSLRead(ctx, ibuf+len, BUFSIZE-len, &l);
+ len+=l;
+ }
+
+ require_noerr(ortn, out);
+ require_action(len == BUFSIZE, out, ortn = -1);
+
+ if (ssl->is_server) {
+ require_noerr(memcmp(ibuf, obuf, BUFSIZE), out);
+ } else {
+ require_noerr(ortn = SSLWrite(ctx, ibuf, BUFSIZE, &len), out);
+ require_action(len == BUFSIZE, out, ortn = -1);
+ }
+ }
+
+out:
+ SSLClose(ctx);
+ CFRelease(ctx);
+ if (trust) CFRelease(trust);
+ close(ssl->comm);
+
+ ssl->time = perf_time();
+
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+
+static ssl_test_handle *
+ssl_test_handle_create(uint32_t session_id, bool resume, bool server, SSLAuthenticate client_side_auth, bool dh_anonymous, bool dtls,
+ int comm, CFArrayRef certs, CFArrayRef peer_certs, SSLProtocol proto)
+{
+ ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+ if (handle) {
+ handle->session_id = session_id;
+ handle->is_session_resume = resume;
+ handle->is_server = server;
+ handle->is_dtls = dtls;
+ handle->client_side_auth = client_side_auth;
+ handle->dh_anonymous = dh_anonymous;
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->peer_certs = peer_certs;
+ handle->proto = proto;
+ handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto);
+ }
+ return handle;
+}
+
+-(void)testCiphers
+{
+ pthread_t client_thread, server_thread;
+
+ CFArrayRef server_rsa_certs = server_chain();
+ CFArrayRef server_ec_certs = server_ec_chain();
+ CFArrayRef client_certs = trusted_client_chain();
+ XCTAssert(server_rsa_certs != NULL);
+ XCTAssert(server_ec_certs != NULL);
+ XCTAssert(client_certs != NULL);
+
+ int i,k,l, p;
+
+ for (p=0; p<nprotos; p++)
+ for (k=0; k<3; k++) /* client side auth mode:
+ 0 (kSSLNeverAuthenticate): server doesn't request ,
+ 1 (kSSLAlwaysAuthenticate): server request, client provide,
+ 2 (kSSLTryAuthenticate): server request, client does not provide */
+ {
+
+ for (i=0; i<SupportedCipherSuitesCount; i++)
+ for (l = 0; l<2; l++) { /* resumption or not */
+ uint16_t cs = (uint16_t)(SupportedCipherSuites[i]);
+ KeyExchangeMethod kem = sslCipherSuiteGetKeyExchangeMethod(cs);
+ SSL_CipherAlgorithm cipher = sslCipherSuiteGetSymmetricCipherAlgorithm(cs);
+ tls_protocol_version min_version = sslCipherSuiteGetMinSupportedTLSVersion(cs);
+
+ CFArrayRef server_certs;
+
+ if(kem == SSL_ECDHE_ECDSA) {
+ server_certs = server_ec_certs;
+ } else {
+ server_certs = server_rsa_certs;
+ }
+
+
+ SKIP:{
+ bool dtls = (protos[p] == kDTLSProtocol1);
+ bool server_ok = ((kem != SSL_ECDH_ECDSA) && (kem != SSL_ECDH_RSA) && (kem != SSL_ECDH_anon));
+ bool dh_anonymous = ((kem == SSL_DH_anon) || (kem == TLS_PSK));
+ bool version_ok;
+
+ switch(protos[p]) {
+ case kDTLSProtocol1:
+ version_ok = cipher != SSL_CipherAlgorithmRC4_128 && (min_version != tls_protocol_version_TLS_1_2);
+ break;
+ case kSSLProtocol3:
+ version_ok = (min_version == tls_protocol_version_SSL_3);
+ break;
+ case kTLSProtocol1:
+ case kTLSProtocol11:
+ version_ok = (min_version != tls_protocol_version_TLS_1_2);
+ break;
+ case kTLSProtocol12:
+ version_ok = true;
+ break;
+ default:
+ version_ok = false;
+
+ }
+
+ if (!server_ok) continue;
+ if (!version_ok) continue;
+
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) {
+ exit(errno);
+ }
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ ssl_test_handle *server, *client;
+ size_t num_supported_ciphers = 0;
+ SSLCipherSuite *supported_ciphers = NULL;
+
+ SSLAuthenticate client_side_auth = k;
+
+ uint32_t session_id = (p<<24) | (k<<16) | (i+1);
+ server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
+ client_side_auth, dh_anonymous, dtls,
+ sp[0], server_certs, client_certs, protos[p]);
+ client = ssl_test_handle_create(session_id, (l == 1), false /*client*/,
+ client_side_auth, dh_anonymous, dtls,
+ sp[1], client_certs, server_certs, protos[p]);
+
+ XCTAssertEqual(errSecSuccess, SSLSetPeerID(server->st, &session_id, sizeof(session_id)));
+ XCTAssertEqual(errSecSuccess, SSLSetPeerID(client->st, &session_id, sizeof(session_id)));
+
+ /* set single cipher on client, default ciphers on server */
+ num_supported_ciphers = 0;
+ XCTAssertEqual(errSecSuccess, SSLSetEnabledCiphers(client->st, &(SupportedCipherSuites[i]), 1));
+ XCTAssertEqual(errSecSuccess, SSLGetNumberSupportedCiphers(server->st, &num_supported_ciphers));
+ XCTAssert(supported_ciphers=malloc(num_supported_ciphers*sizeof(SSLCipherSuite)));
+ XCTAssertEqual(errSecSuccess, SSLGetSupportedCiphers(server->st, supported_ciphers, &num_supported_ciphers));
+ XCTAssertEqual(errSecSuccess, SSLSetEnabledCiphers(server->st, supported_ciphers, num_supported_ciphers));
+
+ XCTAssertEqual(errSecSuccess, SSLSetPSKSharedSecret(client->st, "123456789", 9));
+ XCTAssertEqual(errSecSuccess, SSLSetPSKSharedSecret(server->st, "123456789", 9));
+
+ pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
+
+ intptr_t server_err, client_err;
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+#if 0
+ // If you want to print an approximate time for each handshake.
+ printf("%4llu - %40s CSA:%d RESUME:%d PROTO:0x%04x\n",
+ client->time,
+ ciphersuite_name(SupportedCipherSuites[i]),
+ server->client_side_auth,
+ l, protos[p]);
+#endif
+
+ XCTAssert(!server_err && !client_err,
+ "%40s CSA:%d RESUME:%d PROTO:0x%04x",
+ ciphersuite_name(SupportedCipherSuites[i]),
+ server->client_side_auth,
+ l, protos[p]);
+out:
+ free(client);
+ free(server);
+ free(supported_ciphers);
+ }
+ } /* all ciphers */
+ } /* all configs */
+
+
+end:
+ CFReleaseSafe(client_certs);
+ CFReleaseSafe(server_ec_certs);
+ CFReleaseSafe(server_rsa_certs);
+}
+
+@end
+
+/*
+TODO: count errSSLWouldBlock
+TODO: skip tests that don't matter: client_auth and anonymous dh
+TODO: we seem to only be negotiating tls - force a round of sslv3
+TODO: allow secure transport to also defer client side auth to client
+TODO: make sure anonymous dh is never selected if not expicitly enabled
+TODO: make sure DHE is not available if not explicitly enabled and no parameters
+ are set
+TODO: resumable sessions
+*/
--- /dev/null
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/array_size.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (clientauth)
+
+/*
+ SSL Client Auth tests:
+
+ Test both the client and server side.
+
+ Server side test goals:
+ Verify Server behavior in the following cases:
+ Server configuration:
+ - when using kTryAuthenticate vs kAlwaysAuthenticate
+ - with or without breakOnClientAuth.
+ - AnonDH and PSK ciphersuites.
+ Client configuration:
+ - Client sends back no cert vs a cert.
+ - Client sends back an unsupported cert.
+ - Client sends back a malformed cert.
+ - Client cert is trusted vs untrusted.
+ - Client does not have private key (ie: Certificate Verify message should fail).
+ Behavior to verify:
+ - handshake pass or fail
+ - SSLGetClientCertificateState returns expected results
+
+ Client side test goals:
+ Client configuration:
+ - with or without breakOnCertRequest.
+ - no cert, vs cert.
+ Server config:
+ - No client cert requested, vs client cert requested vs client cert required.
+ Behavior to verify:
+ - handshake pass or fail
+ - SSLGetClientCertificateState returns expected results
+
+*/
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = write((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ } else {
+ printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno);
+ return -errno;
+ }
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ bool break_on_req;
+ CFArrayRef certs;
+ int auth; //expected client auth behavior of the server (0=no request, 1=optional , 2=required)
+} ssl_client_handle;
+
+static ssl_client_handle *
+ssl_client_handle_create(bool break_on_req, int comm, CFArrayRef certs, CFArrayRef trustedCA, int auth)
+{
+ ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+ static const char *peer_domain_name = "localhost";
+ require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+ strlen(peer_domain_name)), out);
+
+ require_noerr(SSLSetTrustedRoots(ctx, trustedCA, true), out);
+
+
+ /* Setting client certificate in advance */
+ if (!break_on_req && certs) {
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+ }
+
+ if (break_on_req) {
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnCertRequested, true), out);
+ }
+
+ handle->break_on_req = break_on_req;
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->st = ctx;
+ handle->auth = auth;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_client_handle_destroy(ssl_client_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_client_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_client_handle * ssl = (ssl_client_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ bool got_client_cert_req = false;
+ SSLSessionState ssl_state;
+
+ pthread_setname_np("client thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLClientCertRequested) {
+ require_string(ssl->auth, out, "cert req not expected");
+ require_string(ssl_state==kSSLHandshake, out, "wrong client handshake state after errSSLClientCertRequested");
+ require_string(!got_client_cert_req, out, "second client cert req");
+ got_client_cert_req = true;
+
+ SSLClientCertificateState clientState;
+ SSLGetClientCertificateState(ctx, &clientState);
+ require_string(clientState==kSSLClientCertRequested, out, "Wrong client cert state after cert request");
+
+ require_string(ssl->break_on_req, out, "errSSLClientCertRequested in run not testing that");
+ if(ssl->certs) {
+ require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
+ }
+
+ } else if (ortn == errSSLWouldBlock) {
+ require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock");
+ }
+ } while (ortn == errSSLWouldBlock || ortn == errSSLClientCertRequested);
+
+ require_string((got_client_cert_req || !ssl->auth || !ssl->break_on_req), out, "didn't get client cert req as expected");
+
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ SSLAuthenticate client_auth;
+ CFArrayRef certs;
+} ssl_server_handle;
+
+static ssl_server_handle *
+ssl_server_handle_create(SSLAuthenticate client_auth, int comm, CFArrayRef certs, CFArrayRef trustedCA)
+{
+ ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+
+ require_noerr(SSLSetTrustedRoots(ctx, trustedCA, true), out);
+
+ SSLAuthenticate auth;
+ require_noerr(SSLSetClientSideAuthenticate(ctx, client_auth), out);
+ require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
+ require(auth==client_auth, out);
+
+ handle->client_auth = client_auth;
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->st = ctx;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_server_handle_destroy(ssl_server_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_server_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_server_handle * ssl = (ssl_server_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SSLSessionState ssl_state;
+
+ pthread_setname_np("server thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLWouldBlock) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ }
+ } while (ortn == errSSLWouldBlock);
+
+ require_noerr_quiet(ortn, out);
+
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+
+-(void)testClientAuth
+{
+ pthread_t client_thread, server_thread;
+ CFArrayRef server_certs = server_chain();
+ CFArrayRef trusted_ca = trusted_roots();
+
+ XCTAssert(server_certs, "got server certs");
+ XCTAssert(trusted_ca, "got trusted roots");
+
+ int i, j, k;
+
+ for (i=0; i<3; i++) {/* client side cert: 0 = no cert, 1 = trusted cert, 2 = untrusted cert. */
+ for (j=0; j<2; j++) { /* break on cert request */
+ for (k=0; k<3; k++) { /* server behvior: 0 = no cert request, 1 = optional cert, 2 = required cert */
+
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ bool break_on_req = (j!=0);
+ SSLClientAuthenticationType auth = (k == 0) ? kNeverAuthenticate
+ : (k == 1) ? kTryAuthenticate
+ : kAlwaysAuthenticate;
+
+ CFArrayRef client_certs = (i == 0) ? NULL
+ : (i == 1) ? trusted_client_chain()
+ : untrusted_client_chain();
+
+ ssl_client_handle *client;
+ client = ssl_client_handle_create(break_on_req, sp[0], client_certs, trusted_ca, auth);
+
+ ssl_server_handle *server;
+ server = ssl_server_handle_create(auth, sp[1], server_certs, trusted_ca);
+
+ pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server);
+
+ intptr_t server_err, client_err;
+ int expected_server_err = 0, expected_client_err = 0;
+ SSLClientCertificateState client_cauth_state, server_cauth_state;
+ SSLClientCertificateState expected_client_cauth_state = 0, expected_server_cauth_state = 0;
+
+
+ if(((k == 2) && (i != 1)) // Server requires good cert, but client not sending good cert,
+ || ((k == 1) && (i == 2)) // Or server request optionally, and client sending bad cert.
+ ) {
+ expected_client_err = errSSLPeerCertUnknown;
+ expected_server_err = errSSLXCertChainInvalid;
+ }
+
+
+ if(k != 0) {
+ if(i == 0) {
+ expected_client_cauth_state = kSSLClientCertRequested;
+ expected_server_cauth_state = kSSLClientCertRequested;
+ } else {
+ expected_client_cauth_state = kSSLClientCertSent;
+ expected_server_cauth_state = kSSLClientCertSent;
+ }
+ }
+
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+
+ XCTAssertEqual(errSecSuccess, SSLGetClientCertificateState(client->st, &client_cauth_state), "SSLGetClientCertificateState (client %d:%d:%d)", i, j, k);
+ XCTAssertEqual(errSecSuccess, SSLGetClientCertificateState(client->st, &server_cauth_state), "SSLGetClientCertificateState (server %d:%d:%d)", i, j, k);
+
+ XCTAssertEqual(client_err, expected_client_err, "unexpected error %d!=%d (client %d:%d:%d)", (int)client_err, expected_client_err, i, j, k);
+ XCTAssertEqual(server_err, expected_server_err, "unexpected error %d!=%d (server %d:%d:%d)", (int)server_err, expected_server_err, i, j, k);
+
+ XCTAssertEqual(client_cauth_state, expected_client_cauth_state, "unexpected client auth state %d!=%d (client %d:%d:%d)", client_cauth_state, expected_client_cauth_state, i, j, k);
+ XCTAssertEqual(server_cauth_state, expected_server_cauth_state, "unexpected client auth state %d!=%d (server %d:%d:%d)", server_cauth_state, expected_server_cauth_state, i, j, k);
+
+
+ ssl_server_handle_destroy(server);
+ ssl_client_handle_destroy(client);
+
+ CFReleaseSafe(client_certs);
+ }
+ }
+ }
+
+ CFReleaseSafe(server_certs);
+ CFReleaseSafe(trusted_ca);
+}
+
+@end
--- /dev/null
+/*
+ * ssl-40-clientauth.c
+ * Security
+ *
+ * Copyright (c) 2008-2010,2012-2014 Apple Inc. All Rights Reserved.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecureTransport.h>
+#include <utilities/array_size.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <AssertMacros.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (clientauth41)
+
+#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) { CFRelease(_cf); } }
+#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) { (CF) = NULL; CFRelease(_cf); } }
+
+/*
+ Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com
+issuer=/CN=plutoCA/emailAddress=pluto@pluto.com
+ */
+static const uint8_t _c1[] = {
+ 0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8,
+ 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+ 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43,
+ 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+ 0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40,
+ 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31,
+ 0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32,
+ 0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32,
+ 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35,
+ 0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72,
+ 0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66,
+ 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
+ 0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40,
+ 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 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, 0xa6, 0x82, 0x8e, 0xc6, 0x7e,
+ 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35,
+ 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8,
+ 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80,
+ 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93,
+ 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7,
+ 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb,
+ 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac,
+ 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a,
+ 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3,
+ 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78,
+ 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b,
+ 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6,
+ 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7,
+ 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc,
+ 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa,
+ 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2,
+ 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f,
+ 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04,
+ 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2,
+ 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71,
+ 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44,
+ 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48,
+ 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b,
+ 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47,
+ 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08,
+ 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32,
+ 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26,
+ 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23,
+ 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4,
+ 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e,
+ 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8,
+ 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed,
+ 0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28,
+ 0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1,
+ 0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0,
+ 0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64,
+ 0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88,
+ 0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94,
+ 0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea,
+ 0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70,
+ 0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72,
+ 0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c,
+ 0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5,
+ 0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2,
+ 0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a,
+ 0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26,
+ 0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9,
+ 0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24,
+ 0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a,
+ 0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94,
+ 0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e,
+ 0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e,
+ 0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6,
+ 0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61,
+ 0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a,
+ 0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba,
+ 0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd,
+ 0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88,
+ 0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81,
+ 0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1,
+ 0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1,
+ 0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1,
+ 0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b,
+ 0x9b, 0x78, 0x78, 0x10
+};
+
+/*
+ Bag Attributes
+friendlyName: uranusLeaf
+localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+Key Attributes: <No Attributes>
+ */
+
+#if TARGET_OS_IPHONE
+/* we use _k1 on iPhone */
+static const uint8_t _k1[] = {
+ 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
+ 0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6,
+ 0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32,
+ 0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72,
+ 0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80,
+ 0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93,
+ 0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b,
+ 0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9,
+ 0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08,
+ 0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0,
+ 0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c,
+ 0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde,
+ 0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e,
+ 0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1,
+ 0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03,
+ 0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57,
+ 0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64,
+ 0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43,
+ 0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9,
+ 0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd,
+ 0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5,
+ 0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e,
+ 0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23,
+ 0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1,
+ 0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5,
+ 0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1,
+ 0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25,
+ 0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a,
+ 0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae,
+ 0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72,
+ 0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2,
+ 0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75,
+ 0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d,
+ 0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2,
+ 0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde,
+ 0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9,
+ 0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02,
+ 0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b,
+ 0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43,
+ 0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63,
+ 0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa,
+ 0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab,
+ 0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84,
+ 0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47,
+ 0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02,
+ 0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a,
+ 0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf,
+ 0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11,
+ 0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f,
+ 0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98,
+ 0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5,
+ 0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a,
+ 0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69,
+ 0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab,
+ 0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78,
+ 0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e,
+ 0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e,
+ 0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6,
+ 0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e,
+ 0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3,
+ 0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f,
+ 0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4,
+ 0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64,
+ 0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82,
+ 0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b,
+ 0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81,
+ 0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9,
+ 0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd,
+ 0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7,
+ 0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2,
+ 0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46,
+ 0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b,
+ 0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9,
+ 0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80,
+ 0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c,
+ 0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69,
+ 0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc,
+ 0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd,
+ 0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1,
+ 0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b,
+ 0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4,
+ 0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6,
+ 0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d,
+ 0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf,
+ 0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f,
+ 0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93,
+ 0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b,
+ 0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d,
+ 0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30,
+ 0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d,
+ 0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a,
+ 0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48,
+ 0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74,
+ 0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde,
+ 0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d,
+ 0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94,
+ 0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80,
+ 0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49,
+ 0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81,
+ 0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10,
+ 0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c,
+ 0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13,
+ 0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73,
+ 0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93,
+ 0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa,
+ 0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff,
+ 0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19,
+ 0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61,
+ 0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe,
+ 0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a,
+ 0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9,
+ 0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6,
+ 0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d,
+ 0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76,
+ 0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6,
+ 0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84,
+ 0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c,
+ 0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e,
+ 0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d,
+ 0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d,
+ 0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84,
+ 0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97,
+ 0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03,
+ 0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69,
+ 0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c,
+ 0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9,
+ 0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61,
+ 0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2,
+ 0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad,
+ 0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e,
+ 0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b,
+ 0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00,
+ 0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a,
+ 0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58,
+ 0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b,
+ 0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb,
+ 0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47,
+ 0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46,
+ 0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c,
+ 0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4,
+ 0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d,
+ 0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0,
+ 0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78,
+ 0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84,
+ 0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0,
+ 0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f,
+ 0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36,
+ 0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69
+};
+#else
+ /* don’t use _k1 */
+#endif
+
+__unused static const uint8_t _k1_digest[] = {
+ 0x46, 0xE0, 0x8A, 0x05, 0x63, 0x4D, 0x17, 0x3F,
+ 0xCA, 0xA4, 0xAA, 0xB6, 0x5A, 0xDA, 0xCF, 0xBA,
+ 0x84, 0x22, 0x7C, 0x23
+};
+
+/* Create and identity and try to retrieve it. */
+-(void) testClientAuth41
+{
+ SecCertificateRef cert = NULL, cert2 = NULL;
+ SecKeyRef privKey = NULL;
+ SecIdentityRef identity = NULL;
+ CFArrayRef trust_chain = NULL;
+ SSLContextRef ctx = NULL;
+
+ XCTAssertNotEqual(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+ NULL, "create certificate");
+ XCTAssertNotEqual(cert2 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+ NULL, "create certificate2");
+#if TARGET_OS_IPHONE
+ privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
+ kSecKeyEncodingPkcs1);
+#else
+ privKey = NULL; /* TODO */
+#endif
+ XCTAssertNotEqual(privKey, NULL, "create private key");
+
+ XCTAssert(identity = SecIdentityCreate(kCFAllocatorDefault, cert, privKey), "SecIdentityCreate");
+ CFReleaseSafe(cert);
+ CFReleaseSafe(privKey);
+ const void *values[] = { identity, cert2 };
+ XCTAssert(trust_chain = CFArrayCreate(kCFAllocatorDefault, values,
+ array_size(values), &kCFTypeArrayCallBacks), "CFArrayCreate");
+ CFReleaseSafe(identity);
+ CFReleaseSafe(cert2);
+
+ XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+ XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+ XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+ XCTAssert(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext");
+ require(ctx, errOut);
+ XCTAssertEqual(errSecSuccess, SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+ CFReleaseSafe(ctx);
+
+ XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+ XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+ XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+ XCTAssert(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLCreateContext");
+ require(ctx, errOut);
+ XCTAssertEqual(errSecSuccess, SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+ CFReleaseSafe(ctx);
+
+ XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+ XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+ XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+ XCTAssert(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLCreateContext");
+ require(ctx, errOut);
+ XCTAssertEqual(errSecSuccess,SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+ XCTAssertEqual(errSecSuccess,SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
+ CFReleaseSafe(ctx);
+
+ XCTAssertEqual(CFGetRetainCount(trust_chain), 1, "trust_chain rc = 1");
+ XCTAssertEqual(CFGetRetainCount(identity), 1, "identity rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert), 1, "cert rc = 1");
+ XCTAssertEqual(CFGetRetainCount(cert2), 1, "cert2 rc = 1");
+ XCTAssertEqual(CFGetRetainCount(privKey), 1, "privKey rc = 1");
+
+errOut:
+ CFReleaseNull(trust_chain);
+}
+@end
--- /dev/null
+/*
+ * Copyright (c) 2012-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 <AssertMacros.h>
+#import "STLegacyTests.h"
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+
+@implementation STLegacyTests (crashes)
+
+typedef struct {
+ SSLContextRef st;
+ bool is_server;
+ int comm;
+ CFArrayRef certs;
+ int test;
+} ssl_test_handle;
+
+
+#pragma mark -
+#pragma mark SecureTransport support
+
+#if 0
+static void hexdump(const char *s, const uint8_t *bytes, size_t len) {
+ size_t ix;
+ printf("socket %s(%p, %lu)\n", s, bytes, len);
+ for (ix = 0; ix < len; ++ix) {
+ if (!(ix % 16))
+ printf("\n");
+ printf("%02X ", bytes[ix]);
+ }
+ printf("\n");
+}
+#else
+#define hexdump(string, bytes, len)
+#endif
+
+static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
+{
+ int conn = ((const ssl_test_handle *)h)->comm;
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ hexdump("write", ptr, len);
+ ret = write((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static int changepad=0;
+
+static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
+{
+ const ssl_test_handle *handle=h;
+ int conn = handle->comm;
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ if(len!=0)
+ printf("Something went wrong here... len=%d\n", (int)len);
+
+ *length = *length - len;
+
+ ptr=data;
+
+ /* change pad in the data */
+ if(changepad==1) {
+ changepad=0;
+ ptr[31]=ptr[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow.
+ }
+
+ /* We are reading the server cert */
+ if((ptr[0]==0x0b) && (handle->test==3)) {
+#if 1 // cert length for TARGET_OS_IPHONE
+ size_t expected_len = 631;
+#else
+ size_t expected_len = 500;
+#endif
+ if(*length!=expected_len) {
+ fprintf(stderr, "Expected cert length %ld, got %ld... test might fail\n",
+ (long)expected_len, (long)*length);
+ }
+ ptr[0x16] = 0x4; // version = 4 certificate should cause error, but not crash .
+ }
+
+ /* We are reading a data application header */
+ if(*length==5 && ptr[0]==0x17) {
+ switch(handle->test) {
+ case 0:
+ ptr[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
+ break;
+ case 1:
+ ptr[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
+ break;
+ case 2:
+ changepad=1;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ return errSecSuccess;
+}
+
+
+
+static void *securetransport_ssl_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_test_handle * ssl = (ssl_test_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ bool got_server_auth = false;
+
+ //uint64_t start = mach_absolute_time();
+ do {
+ ortn = SSLHandshake(ctx);
+
+ if (ortn == errSSLServerAuthCompleted)
+ {
+ require_string(!got_server_auth, out, "second server auth");
+ got_server_auth = true;
+ }
+ } while (ortn == errSSLWouldBlock
+ || ortn == errSSLServerAuthCompleted);
+
+ require_noerr_quiet(ortn, out);
+
+ unsigned char ibuf[8], obuf[8];
+ size_t len;
+ if (ssl->is_server) {
+ require_action_quiet(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf), out, ortn = -1);
+ require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
+ require_action_quiet(len == sizeof(obuf), out, ortn = -1);
+ } else {
+ require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
+ require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
+ }
+
+out:
+ SSLClose(ctx);
+ CFRelease(ctx);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+static ssl_test_handle *
+ssl_test_handle_create(bool server, int comm, CFArrayRef certs)
+{
+ ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
+
+ if (server)
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnServerAuth, true), out);
+
+ /* Tell SecureTransport to not check certs itself: it will break out of the
+ handshake to let us take care of it instead. */
+ require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+ handle->is_server = server;
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->st = ctx;
+
+ return handle;
+
+out:
+ if (handle) free(handle);
+ if (ctx) CFRelease(ctx);
+ return NULL;
+}
+
+-(void)testCrashes
+{
+ pthread_t client_thread, server_thread;
+ CFArrayRef server_certs = server_chain();
+ XCTAssert(server_certs, "got server certs");
+
+ int i;
+
+ for(i=0; i<4; i++)
+ {
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ ssl_test_handle *server, *client;
+
+ server = ssl_test_handle_create(true /*server*/, sp[0], server_certs);
+ client = ssl_test_handle_create(false/*client*/, sp[1], NULL);
+
+ server->test=i;
+ client->test=i;
+
+ require(client, out);
+ require(server, out);
+
+ SSLCipherSuite cipher = TLS_RSA_WITH_AES_128_CBC_SHA256;
+ require_noerr(SSLSetEnabledCiphers(client->st, &cipher, 1), out);
+
+ pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
+
+ intptr_t server_err, client_err;
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+ XCTAssert(server_err==((i==3)?errSSLPeerCertUnknown:0), "Server error = %zu (i=%d)", server_err, i);
+ /* tests 0/1 should cause errSSLClosedAbort, 2 should cause errSSLBadRecordMac, 3 should cause errSSLXCertChainInvalid */
+ XCTAssert(client_err==((i==3)?errSSLXCertChainInvalid:(i==2)?errSSLBadRecordMac:errSSLClosedAbort), "Client error = %zu (i=%d)", client_err, i);
+
+out:
+ free(client);
+ free(server);
+
+ }
+ CFReleaseNull(server_certs);
+}
+
+@end
--- /dev/null
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/array_size.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (dhe)
+
+/*
+ SSL DHE tests:
+
+ Test both the client and server side.
+
+ Test Goal:
+ - Make sure that handshake fail when dh param size is too small.
+
+ Behavior to verify:
+ - handshake pass or fail
+
+*/
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = write((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ } else {
+ printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno);
+ return -errno;
+ }
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ unsigned dhe_size;
+} ssl_client_handle;
+
+static ssl_client_handle *
+ssl_client_handle_create(int comm, CFArrayRef trustedCA, unsigned dhe_size)
+{
+ ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+ static const char *peer_domain_name = "localhost";
+ require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+ strlen(peer_domain_name)), out);
+
+ require_noerr(SSLSetTrustedRoots(ctx, trustedCA, true), out);
+
+ require_noerr(SSLSetDHEEnabled(ctx, true), out);
+
+ if(dhe_size)
+ require_noerr(SSLSetMinimumDHGroupSize(ctx, dhe_size), out);
+
+ handle->comm = comm;
+ handle->st = ctx;
+ handle->dhe_size = dhe_size;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_client_handle_destroy(ssl_client_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_client_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_client_handle * ssl = (ssl_client_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SSLSessionState ssl_state;
+
+ pthread_setname_np("client thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLWouldBlock) {
+ require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock");
+ }
+ } while (ortn == errSSLWouldBlock);
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ CFArrayRef certs;
+
+} ssl_server_handle;
+
+static ssl_server_handle *
+ssl_server_handle_create(int comm, CFArrayRef certs, const void *dhParams, size_t dhParamsLen)
+{
+ ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType);
+ SSLCipherSuite cipher = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+
+ require_noerr(SSLSetEnabledCiphers(ctx, &cipher, 1), out);
+
+ if(dhParams)
+ require_noerr(SSLSetDiffieHellmanParams(ctx, dhParams, dhParamsLen), out);
+
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->st = ctx;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_server_handle_destroy(ssl_server_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_server_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_server_handle * ssl = (ssl_server_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SSLSessionState ssl_state;
+
+ pthread_setname_np("server thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLWouldBlock) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ }
+ } while (ortn == errSSLWouldBlock);
+
+ require_noerr_quiet(ortn, out);
+
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+
+static
+unsigned client_dhe_sizes[] = {
+ 0, // default, don't set.
+ 256, // will resolve to 512.
+ 512,
+ 768,
+ 1024,
+ 2048,
+ 4096, // will resolve to 2048.
+};
+
+
+static const unsigned n_client_dhe_sizes = sizeof(client_dhe_sizes)/sizeof(client_dhe_sizes[0]);
+
+static uint8_t dh_parameters_256_data[] = {
+ 0x30, 0x26, 0x02, 0x21, 0x00, 0xd8, 0x23, 0xeb, 0xcb, 0x41, 0xd0, 0x3a,
+ 0xc4, 0x9a, 0x2a, 0x2a, 0x4f, 0x35, 0xf7, 0x4f, 0xd9, 0xc5, 0x2e, 0xf8,
+ 0x44, 0xa7, 0x74, 0xe3, 0x84, 0x98, 0x9f, 0xad, 0x58, 0xd5, 0x15, 0xb4,
+ 0xf3, 0x02, 0x01, 0x02
+};
+
+static uint8_t dh_parameters_512_data[] = {
+ 0x30, 0x46, 0x02, 0x41, 0x00, 0x85, 0xcd, 0xc1, 0x7e, 0x26, 0xeb, 0x37,
+ 0x84, 0x13, 0xd0, 0x3b, 0x07, 0xc1, 0x57, 0x7d, 0xf3, 0x55, 0x8d, 0xa0,
+ 0xc4, 0xa5, 0x03, 0xc4, 0x2c, 0xc6, 0xd5, 0xa6, 0x31, 0xcb, 0x68, 0xdf,
+ 0x5d, 0x96, 0x20, 0x1a, 0x15, 0x57, 0x49, 0x7d, 0xd7, 0x51, 0x65, 0x6e,
+ 0x37, 0xa8, 0xe3, 0xe9, 0xe1, 0x59, 0x2e, 0xd4, 0x57, 0x4a, 0xf0, 0xcb,
+ 0x0e, 0x85, 0x07, 0xdd, 0x35, 0xa7, 0xe3, 0xc6, 0xbb, 0x02, 0x01, 0x02
+};
+
+static uint8_t dh_parameters_768_data[] = {
+ 0x30, 0x66, 0x02, 0x61, 0x00, 0xe1, 0xa2, 0x50, 0xab, 0xb0, 0xdc, 0xef,
+ 0xe1, 0x2f, 0xd9, 0xde, 0x59, 0x86, 0x24, 0x43, 0x3b, 0xf3, 0x40, 0x9d,
+ 0x02, 0xcc, 0xe2, 0x70, 0x63, 0x46, 0x8d, 0x0f, 0xf3, 0x8a, 0xc6, 0xa0,
+ 0x1d, 0x7b, 0x30, 0x83, 0x10, 0x48, 0x40, 0x28, 0xa4, 0x3e, 0xbe, 0x4d,
+ 0xb6, 0xea, 0x90, 0x02, 0xae, 0x25, 0x93, 0xc0, 0xe8, 0x36, 0x5c, 0xc8,
+ 0xc8, 0x0b, 0x04, 0xd5, 0x05, 0xac, 0x67, 0x24, 0x4b, 0xa9, 0x42, 0x5a,
+ 0x03, 0x65, 0x4d, 0xd0, 0xc0, 0xbd, 0x78, 0x32, 0xd0, 0x8c, 0x0a, 0xf4,
+ 0xbf, 0xd1, 0x61, 0x86, 0x13, 0x13, 0x3b, 0x83, 0xce, 0xbf, 0x3b, 0xbc,
+ 0x8f, 0xf9, 0x4e, 0x50, 0xe3, 0x02, 0x01, 0x02
+};
+
+static uint8_t dh_parameters_1024_data[] = {
+ 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xd5, 0x06, 0x69, 0xc6, 0xd4,
+ 0x98, 0x2b, 0xe3, 0x49, 0xe2, 0xa1, 0x9b, 0x82, 0xaf, 0x3f, 0xaa, 0xc3,
+ 0x86, 0x2a, 0x7a, 0xfa, 0x62, 0x12, 0x33, 0x45, 0x9f, 0x34, 0x57, 0xc6,
+ 0x6c, 0x88, 0x81, 0xa6, 0x5d, 0xa3, 0x43, 0xe5, 0x4d, 0x87, 0x4f, 0x69,
+ 0x3d, 0x2b, 0xc8, 0x18, 0xb6, 0xd7, 0x29, 0x53, 0x94, 0x0d, 0x73, 0x9b,
+ 0x08, 0x22, 0x73, 0x84, 0x7b, 0x5a, 0x03, 0x2e, 0xfc, 0x10, 0x9b, 0x35,
+ 0xc6, 0xa1, 0xca, 0x36, 0xd0, 0xcc, 0x3e, 0xa2, 0x04, 0x3a, 0x8a, 0xe8,
+ 0x87, 0xe8, 0x60, 0x72, 0xee, 0x99, 0xf3, 0x04, 0x0a, 0xd8, 0x1a, 0xe6,
+ 0xfc, 0xbc, 0xe1, 0xc5, 0x9d, 0x3a, 0xca, 0xf9, 0xfd, 0xbf, 0x58, 0xd3,
+ 0x4d, 0xde, 0x8b, 0x4a, 0xb5, 0x37, 0x1e, 0x6d, 0xf4, 0x22, 0x0f, 0xb7,
+ 0x48, 0x0a, 0xda, 0x82, 0x40, 0xc9, 0x55, 0x20, 0x01, 0x3b, 0x35, 0xb2,
+ 0x94, 0x68, 0xab, 0x02, 0x01, 0x02
+};
+
+
+static
+struct {
+ const void *dhParams;
+ size_t dhParamsLen;
+} server_dhe_params[] = {
+ {dh_parameters_256_data, sizeof(dh_parameters_256_data)},
+ {dh_parameters_512_data, sizeof(dh_parameters_512_data)},
+ {dh_parameters_768_data, sizeof(dh_parameters_768_data)},
+ {dh_parameters_1024_data, sizeof(dh_parameters_1024_data)},
+ {NULL, 0}, // default is a 2048
+};
+
+static const unsigned n_server_dhe_params = sizeof(server_dhe_params)/sizeof(server_dhe_params[0]);
+
+static
+int expected_client_error[n_server_dhe_params][n_client_dhe_sizes] = {
+//Client:
+// (default)
+// 1024, 512, 512, 768, 1024, 2048, 2048 // Server:
+ { -9850, -9850, -9850, -9850, -9850, -9850, -9850}, // 256
+ { -9850, 0, 0, -9850, -9850, -9850, -9850}, // 512
+ { -9850, 0, 0, 0, -9850, -9850, -9850}, // 768
+ { 0, 0, 0, 0, 0, -9850, -9850}, // 1024
+ { 0, 0, 0, 0, 0, 0, 0}, // default(2048)
+};
+
+-(void)testDHE
+{
+ pthread_t client_thread, server_thread;
+ CFArrayRef server_certs = server_chain();
+ CFArrayRef trusted_ca = trusted_roots();
+
+ XCTAssert(server_certs, "got server certs");
+ XCTAssert(trusted_ca, "got trusted roots");
+
+ int i, j;
+
+ for (i=0; i<n_server_dhe_params; i++) {
+ for (j=0; j<n_client_dhe_sizes; j++) {
+
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ ssl_client_handle *client;
+ client = ssl_client_handle_create(sp[0], trusted_ca, client_dhe_sizes[j]);
+ XCTAssert(client!=NULL, "could not create client handle (%d:%d)", i, j);
+
+
+ ssl_server_handle *server;
+ server = ssl_server_handle_create(sp[1], server_certs, server_dhe_params[i].dhParams, server_dhe_params[i].dhParamsLen);
+ XCTAssert(server!=NULL, "could not create server handle (%d:%d)", i, j);
+
+ pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server);
+
+ intptr_t server_err, client_err;
+
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+
+ XCTAssertEqual(client_err, expected_client_error[i][j], "unexpected error %d!=%d (client %d:%d)", (int)client_err, expected_client_error[i][j], i, j);
+
+ ssl_server_handle_destroy(server);
+ ssl_client_handle_destroy(client);
+ }
+ }
+
+ CFReleaseSafe(server_certs);
+ CFReleaseSafe(trusted_ca);
+}
+
+@end
--- /dev/null
+/*
+ * Copyright (c) 2011,2013-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 <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (falsestart)
+
+typedef struct {
+ uint32_t session_id;
+ bool is_session_resume;
+ SSLContextRef st;
+ bool is_server;
+ bool client_side_auth;
+ bool dh_anonymous;
+ int comm;
+ CFArrayRef certs;
+} ssl_test_handle;
+
+
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+ size_t ix;
+ printf("socket write(%p, %lu)\n", bytes, len);
+ for (ix = 0; ix < len; ++ix) {
+ if (!(ix % 16))
+ printf("\n");
+ printf("%02X ", bytes[ix]);
+ }
+ printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static int SocketConnect(const char *hostName, int port)
+{
+ struct sockaddr_in addr;
+ struct in_addr host;
+ int sock;
+ int err;
+ struct hostent *ent;
+
+ if (hostName[0] >= '0' && hostName[0] <= '9') {
+ host.s_addr = inet_addr(hostName);
+ } else {
+ ent = gethostbyname(hostName);
+ if(ent == NULL) {
+ printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
+ return -2;
+ }
+ memcpy(&host, ent->h_addr, sizeof(struct in_addr));
+ }
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ addr.sin_addr = host;
+ addr.sin_port = htons((u_short)port);
+
+ addr.sin_family = AF_INET;
+ err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
+
+ if(err!=0)
+ {
+ perror("connect failed");
+ return -1;
+ }
+
+ /* make non blocking */
+ fcntl(sock, F_SETFL, O_NONBLOCK);
+
+ return sock;
+}
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ hexdump(ptr, len);
+ ret = write((int)conn, ptr, len);
+ if (ret < 0)
+ perror("send");
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static
+OSStatus SocketRead(
+ SSLConnectionRef connection,
+ void *data,
+ size_t *dataLength)
+{
+ int fd = (int)connection;
+ ssize_t len;
+
+ len = read(fd, data, *dataLength);
+
+ if(len<0) {
+ int theErr = errno;
+ switch(theErr) {
+ case EAGAIN:
+ //printf("SocketRead: EAGAIN\n");
+ *dataLength=0;
+ /* nonblocking, no data */
+ return errSSLWouldBlock;
+ default:
+ perror("SocketRead");
+ return -36;
+ }
+ }
+
+ if(len<(ssize_t)*dataLength) {
+ *dataLength=len;
+ return errSSLWouldBlock;
+ }
+
+ return errSecSuccess;
+}
+
+static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, Boolean false_start)
+{
+ SSLContextRef ctx = NULL;
+
+ require_noerr(SSLNewContext(false, &ctx), out);
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
+
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnServerAuth, true), out);
+
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionFalseStart, false_start), out);
+
+ require_noerr(SSLSetProtocolVersionMax(ctx, maxprot), out);
+
+ return ctx;
+out:
+ if (ctx)
+ SSLDisposeContext(ctx);
+ return NULL;
+}
+
+const char request[]="GET / HTTP/1.1\n\n";
+char reply[2048];
+
+static OSStatus securetransport(ssl_test_handle * ssl)
+{
+ OSStatus ortn;
+ SSLContextRef ctx = ssl->st;
+ SecTrustRef trust = NULL;
+ bool got_server_auth = false, got_client_cert_req = false;
+
+ ortn = SSLHandshake(ctx);
+
+ require_action_quiet(ortn==errSSLWouldBlock, out, printf("SSLHandshake failed with err %ld\n", (long)ortn));
+
+ size_t sent, received;
+ const char *r=request;
+ size_t l=sizeof(request);
+
+ do {
+
+ ortn = SSLWrite(ctx, r, l, &sent);
+
+ if(ortn == errSSLWouldBlock) {
+ r+=sent;
+ l-=sent;
+ }
+
+ if (ortn == errSSLServerAuthCompleted)
+ {
+ require_string(!got_server_auth, out, "second server auth");
+ require_string(!got_client_cert_req, out, "got client cert req before server auth");
+ got_server_auth = true;
+ require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+ /* verify peer cert chain */
+ require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+ SecTrustResultType trust_result = 0;
+ /* this won't verify without setting up a trusted anchor */
+ require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+ }
+ } while(ortn == errSSLWouldBlock || ortn == errSSLServerAuthCompleted);
+
+ //fprintf(stderr, "\nHTTP Request Sent\n");
+
+ require_noerr_action_quiet(ortn, out, printf("SSLWrite failed with err %ld\n", (long)ortn));
+
+ require_string(got_server_auth, out, "never got server auth");
+
+ do {
+ ortn = SSLRead(ctx, reply, sizeof(reply)-1, &received);
+ //fprintf(stderr, "r"); usleep(1000);
+ } while(ortn == errSSLWouldBlock);
+
+ //fprintf(stderr, "\n");
+
+ require_noerr_action_quiet(ortn, out, printf("SSLRead failed with err %ld\n", (long)ortn));
+
+ reply[received]=0;
+
+ //fprintf(stderr, "HTTP reply:\n");
+ //fprintf(stderr, "%s\n",reply);
+
+out:
+ SSLClose(ctx);
+ SSLDisposeContext(ctx);
+ if (trust) CFRelease(trust);
+
+ return ortn;
+}
+
+static ssl_test_handle *
+ssl_test_handle_create(int comm, SSLProtocol maxprot, Boolean false_start)
+{
+ ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+ if (handle) {
+ handle->comm = comm;
+ handle->st = make_ssl_ref(comm, maxprot, false_start);
+ }
+ return handle;
+}
+
+static
+struct s_server {
+ char *host;
+ int port;
+ SSLProtocol maxprot;
+} servers[] = {
+ /* Good tls 1.2 servers */
+ {"encrypted.google.com", 443, kTLSProtocol12 },
+ {"www.amazon.com",443, kTLSProtocol12 },
+ //{"www.mikestoolbox.org",443, kTLSProtocol12 },
+};
+
+#define NSERVERS (int)(sizeof(servers)/sizeof(servers[0]))
+#define NLOOPS 1
+#define CONNECT_TRIES 3
+
+-(void)testFalseStart
+{
+ int p;
+ int fs;
+
+ for(p=0; p<NSERVERS;p++) {
+ for(int loops=0; loops<NLOOPS; loops++) {
+ for(fs=0;fs<2; fs++) {
+
+ ssl_test_handle *client;
+ OSStatus r;
+ int s = -1;
+
+ for(int try = 0; s<0 && try<CONNECT_TRIES; try++) {
+ s=SocketConnect(servers[p].host, servers[p].port);
+ }
+
+ if(s<0) {
+ XCTFail("connect failed with err=%d - %s:%d (try %d)", s, servers[p].host, servers[p].port, loops);
+ break;
+ }
+
+ client = ssl_test_handle_create(s, servers[p].maxprot, fs);
+
+ r=securetransport(client);
+ XCTAssert(!r, "handshake failed with err=%ld - %s:%d (try %d), false start=%d", (long)r, servers[p].host, servers[p].port, loops, fs);
+
+ close(s);
+ free(client);
+ } } }
+}
+
+@end
+
--- /dev/null
+//
+// ssl-52-noconn.c
+// libsecurity_ssl
+//
+
+#include <stdio.h>
+#include <Security/SecureTransport.h>
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (dhe)
+
+static
+OSStatus r(SSLConnectionRef connection, void *data, size_t *dataLength) {
+ return errSSLWouldBlock;
+}
+
+static
+OSStatus w(SSLConnectionRef connection, const void *data, size_t *dataLength) {
+ return errSSLWouldBlock;
+}
+
+//Testing <rdar://problem/13539215> Trivial SecureTransport example crashes on Cab, where it worked on Zin
+-(void) testNoConn
+{
+ OSStatus ortn;
+ SSLContextRef ctx;
+ ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+ SSLSetIOFuncs(ctx, r, w);
+ ortn = SSLHandshake(ctx);
+
+ XCTAssertEqual(ortn, errSSLWouldBlock, "SSLHandshake unexpected return\n");
+
+ CFRelease(ctx);
+}
+
+
+@end
+
--- /dev/null
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/array_size.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (renegotiation)
+
+/*
+ SSL Renegotiation tests:
+
+ Test both the client and server side.
+
+ Test Goal:
+ - Make sure that renegotiation works on both client and server.
+
+ Behavior to verify:
+ - handshake pass or fail
+
+*/
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = write((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ } else {
+ printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno);
+ return -errno;
+ }
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ unsigned dhe_size;
+ bool renegotiate;
+} ssl_client_handle;
+
+static ssl_client_handle *
+ssl_client_handle_create(int comm, bool renegotiate)
+{
+ ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+ static const char *peer_domain_name = "localhost";
+ require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+ strlen(peer_domain_name)), out);
+
+ require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, TRUE), out);
+
+ require_noerr(SSLSetAllowsAnyRoot(ctx, TRUE), out);
+
+
+ handle->comm = comm;
+ handle->st = ctx;
+ handle->renegotiate = renegotiate;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_client_handle_destroy(ssl_client_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_client_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_client_handle * ssl = (ssl_client_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SSLSessionState ssl_state;
+ bool peer_auth_received = false;
+
+ pthread_setname_np("client thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLPeerAuthCompleted) {
+ require_action(!peer_auth_received, out, ortn = -1);
+ peer_auth_received = true;
+ }
+ if (ortn == errSSLWouldBlock) {
+ require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock");
+ }
+ } while (ortn == errSSLWouldBlock || ortn == errSSLPeerAuthCompleted);
+
+ require_noerr(ortn, out);
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+ require_action(peer_auth_received, out, ortn = -1);
+
+ if(ssl->renegotiate) {
+ // Renegotiate then write
+ require_noerr(SSLReHandshake(ctx), out);
+
+ peer_auth_received = false;
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+ if (ortn == errSSLPeerAuthCompleted) {
+ require_action(!peer_auth_received, out, ortn = -1);
+ peer_auth_received = true;
+ }
+ if (ortn == errSSLWouldBlock) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ }
+ } while (ortn == errSSLWouldBlock || ortn == errSSLPeerAuthCompleted);
+
+ require_noerr(ortn, out);
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+ require_action(peer_auth_received, out, ortn = -1);
+
+ unsigned char obuf[100];
+
+ size_t len = sizeof(obuf);
+ size_t olen;
+ unsigned char *p = obuf;
+
+ require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, len, p), out, ortn = -1);
+
+ while (len) {
+ require_noerr(ortn = SSLWrite(ctx, p, len, &olen), out);
+ len -= olen;
+ p += olen;
+ }
+ } else {
+ // just read.
+ unsigned char ibuf[100];
+
+ peer_auth_received = false;
+
+ size_t len = sizeof(ibuf);
+ size_t olen;
+ unsigned char *p = ibuf;
+ while (len) {
+ ortn = SSLRead(ctx, p, len, &olen);
+
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLPeerAuthCompleted) {
+ require_action(!peer_auth_received, out, ortn = -1);
+ peer_auth_received = true;
+ } else {
+ require_noerr(ortn, out);
+ }
+
+ /* If we get data, we should have renegotiated */
+ if(olen) {
+ require_noerr(ortn, out);
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+ require_action(peer_auth_received, out, ortn = -1);
+ }
+
+ len -= olen;
+ p += olen;
+ }
+ }
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ CFArrayRef certs;
+ bool renegotiate;
+} ssl_server_handle;
+
+static ssl_server_handle *
+ssl_server_handle_create(int comm, CFArrayRef certs, bool renegotiate)
+{
+ ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType);
+ SSLCipherSuite cipher = TLS_RSA_WITH_AES_256_CBC_SHA256;
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+
+ require_noerr(SSLSetEnabledCiphers(ctx, &cipher, 1), out);
+
+ require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnClientHello, TRUE), out);
+ require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionAllowRenegotiation, TRUE), out);
+
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->st = ctx;
+ handle->renegotiate = renegotiate;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_server_handle_destroy(ssl_server_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_server_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_server_handle * ssl = (ssl_server_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SSLSessionState ssl_state;
+ bool client_hello_received = false;
+
+ pthread_setname_np("server thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+ if (ortn == errSSLClientHelloReceived) {
+ require_action(!client_hello_received, out, ortn = -1);
+ client_hello_received = true;
+ }
+ if (ortn == errSSLWouldBlock) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ }
+ } while (ortn == errSSLWouldBlock || ortn == errSSLClientHelloReceived);
+
+ require_noerr(ortn, out);
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+ require_action(client_hello_received, out, ortn = -1);
+
+ if(ssl->renegotiate) {
+ // Renegotiate then write
+ require_noerr(SSLReHandshake(ctx), out);
+
+ client_hello_received = false;
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+ if (ortn == errSSLClientHelloReceived) {
+ require_action(!client_hello_received, out, ortn = -1);
+ client_hello_received = true;
+ }
+ if (ortn == errSSLWouldBlock) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ }
+ } while (ortn == errSSLWouldBlock || ortn == errSSLClientHelloReceived);
+
+ require_noerr(ortn, out);
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+ require_action(client_hello_received, out, ortn = -1);
+
+ unsigned char obuf[100];
+
+ size_t len = sizeof(obuf);
+ size_t olen;
+ unsigned char *p = obuf;
+
+ require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, len, p), out, ortn = -1);
+
+ while (len) {
+ require_noerr(ortn = SSLWrite(ctx, p, len, &olen), out);
+ len -= olen;
+ p += olen;
+ }
+ } else {
+ // just read
+ unsigned char ibuf[100];
+
+ client_hello_received = false;
+
+ size_t len = sizeof(ibuf);
+ size_t olen;
+ unsigned char *p = ibuf;
+ while (len) {
+ ortn = SSLRead(ctx, p, len, &olen);
+
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLClientHelloReceived) {
+ require_action(!client_hello_received, out, ortn = -1);
+ client_hello_received = true;
+ } else {
+ require_noerr(ortn, out);
+ }
+
+ /* If we get data, we should have renegotiated */
+ if(olen) {
+ require_noerr(ortn, out);
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+ require_action(client_hello_received, out, ortn = -1);
+ }
+
+ len -= olen;
+ p += olen;
+ }
+ }
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+-(void) test_renego: (bool) client_renego
+{
+ pthread_t client_thread, server_thread;
+ CFArrayRef server_certs = server_chain();
+
+ XCTAssert(server_certs, "renego: got server certs");
+
+
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ ssl_client_handle *client;
+ client = ssl_client_handle_create(sp[0], client_renego);
+ XCTAssert(client!=NULL, "renego: could not create client handle");
+
+
+ ssl_server_handle *server;
+ server = ssl_server_handle_create(sp[1], server_certs, !client_renego);
+ XCTAssert(server!=NULL, "renego: could not create server handle");
+
+ pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server);
+
+ intptr_t server_err, client_err;
+
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+ XCTAssert(client_err==0, "renego: unexpected error %ld (client)", client_err);
+ XCTAssert(server_err==0, "renego: unexpected error %ld (server)", server_err);
+
+ ssl_server_handle_destroy(server);
+ ssl_client_handle_destroy(client);
+
+
+ CFReleaseSafe(server_certs);
+}
+
+
+-(void) testRenegotiation
+{
+
+ [self test_renego:false]; // server side trigger renego.
+ [self test_renego:true]; // client side trigger renego.
+
+}
+@end
+
--- /dev/null
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <utilities/array_size.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (sessioncache)
+
+/*
+ SSL Session Cache tests:
+
+ Test both the client and server side.
+
+ Test Goal:
+ - Make sure that resumption fails after session cache TTL.
+
+ Behavior to verify:
+ - handshake pass or fail
+
+*/
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = write((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ } else {
+ printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno);
+ return -errno;
+ }
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ unsigned dhe_size;
+} ssl_client_handle;
+
+static ssl_client_handle *
+ssl_client_handle_create(int comm, bool anyRoot, CFArrayRef trustedCA, bool trustedCAOnly, CFArrayRef trustedLeafs, uint32_t cache_ttl, uintptr_t peerID)
+{
+ ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+ static const char *peer_domain_name = "localhost";
+ require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
+ strlen(peer_domain_name)), out);
+
+ require_noerr(SSLSetAllowsAnyRoot(ctx, anyRoot), out);
+ require_noerr(SSLSetTrustedRoots(ctx, trustedCA, trustedCAOnly), out);
+#if !TARGET_OS_IPHONE
+ require_noerr(SSLSetTrustedLeafCertificates(ctx, trustedLeafs), out);
+#endif
+
+ require_noerr(SSLSetSessionCacheTimeout(ctx, cache_ttl), out);
+
+ require_noerr(SSLSetPeerID(ctx, &peerID, sizeof(peerID)), out);
+
+ handle->comm = comm;
+ handle->st = ctx;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_client_handle_destroy(ssl_client_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_client_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_client_handle * ssl = (ssl_client_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SSLSessionState ssl_state;
+
+ pthread_setname_np("client thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLWouldBlock) {
+ require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock");
+ }
+ } while (ortn == errSSLWouldBlock);
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+typedef struct {
+ SSLContextRef st;
+ int comm;
+ CFArrayRef certs;
+
+} ssl_server_handle;
+
+static ssl_server_handle *
+ssl_server_handle_create(int comm, CFArrayRef certs, uint32_t cache_ttl)
+{
+ ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType);
+ SSLCipherSuite cipher = TLS_RSA_WITH_AES_256_CBC_SHA256;
+ uintptr_t peerID = 0xdeadbeef;
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+
+ require_noerr(SSLSetEnabledCiphers(ctx, &cipher, 1), out);
+
+ require_noerr(SSLSetSessionCacheTimeout(ctx, cache_ttl), out);
+
+ require_noerr(SSLSetPeerID(ctx, &peerID, sizeof(peerID)), out);
+
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->st = ctx;
+
+ return handle;
+
+out:
+ if (ctx)
+ CFRelease(ctx);
+ if (handle)
+ free(handle);
+
+ return NULL;
+}
+
+static void
+ssl_server_handle_destroy(ssl_server_handle *handle)
+{
+ if(handle) {
+ SSLClose(handle->st);
+ CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static void *securetransport_ssl_server_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_server_handle * ssl = (ssl_server_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ SSLSessionState ssl_state;
+
+ pthread_setname_np("server thread");
+
+ require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
+ require_action(ssl_state==kSSLIdle, out, ortn = -1);
+
+ do {
+ ortn = SSLHandshake(ctx);
+ require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
+
+ if (ortn == errSSLWouldBlock) {
+ require_action(ssl_state==kSSLHandshake, out, ortn = -1);
+ }
+ } while (ortn == errSSLWouldBlock);
+
+ require_noerr_quiet(ortn, out);
+
+ require_action(ssl_state==kSSLConnected, out, ortn = -1);
+
+out:
+ SSLClose(ssl->st);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+
+-(void)cache_ttl_test
+{
+ pthread_t client_thread, server_thread;
+ CFArrayRef server_certs = server_chain();
+ CFArrayRef trusted_ca = trusted_roots();
+
+ XCTAssert(server_certs, "ttl: got server certs");
+ XCTAssert(trusted_ca, "ttl: got trusted roots");
+
+ int i, j, k;
+
+ for (i=0; i<2; i++) { // client cache TTL
+ for (j=0; j<2; j++) { // Server cache TTL
+ for (k=0; k<2; k++) {
+ ssl_client_handle *client = NULL;
+ ssl_server_handle *server = NULL;
+
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ client = ssl_client_handle_create(sp[0], false, trusted_ca, true, NULL, i, (i<<8)|(j+1));
+ XCTAssert(client!=NULL, "ttl: could not create client handle (%d:%d:%d)", i, j, k);
+ require(client, errOut);
+
+ server = ssl_server_handle_create(sp[1], server_certs, j);
+ XCTAssert(server!=NULL, "ttl: could not create server handle (%d:%d:%d)", i, j, k);
+ require(server, errOut);
+ pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server);
+
+ intptr_t server_err, client_err;
+
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+ Boolean resumed;
+ unsigned char sessionID[32];
+ size_t sessionIDLength = sizeof(sessionID);
+
+ XCTAssertEqual(client_err, 0, "ttl: unexpected error %ld (client %d:%d:%d)", client_err, i, j, k);
+ XCTAssertEqual(server_err, 0, "ttl: unexpected error %ld (server %d:%d:%d)", server_err, i, j, k);
+ XCTAssertEqual(errSecSuccess, SSLGetResumableSessionInfo(client->st, &resumed, sessionID, &sessionIDLength), "SSLGetResumableSessionInfo");
+
+ XCTAssertEqual((bool)resumed, (bool)(k && (!i) && (!j)), "ttl: Unexpected resumption state=%d (%d:%d:%d)", resumed, i, j, k);
+
+ errOut:
+ ssl_server_handle_destroy(server);
+ ssl_client_handle_destroy(client);
+
+ /* Sleep two seconds so that Session cache TTL can expire */
+ sleep(2);
+ }
+ }
+ }
+
+ CFReleaseSafe(server_certs);
+ CFReleaseSafe(trusted_ca);
+}
+
+-(void) cache_trust_test
+{
+ pthread_t client_thread, server_thread;
+ CFArrayRef server_certs = server_chain();
+ CFArrayRef trusted_ca = trusted_roots();
+ CFMutableArrayRef trusted_ca2 = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, trusted_ca);
+ CFArrayAppendArray(trusted_ca2, trusted_ca, CFRangeMake(0, CFArrayGetCount(trusted_ca)));
+
+ XCTAssert(server_certs, "trust: got server certs");
+ XCTAssert(trusted_ca, "trust: got trusted roots");
+ XCTAssert(trusted_ca2, "trust: got trusted roots extra");
+
+ int any, ca, caonly, leaf, k;
+
+ // Test cache and trust options:
+
+
+ for (any=0; any<2; any++) // any root ?
+ for (ca=0; ca<2; ca++) // trustedCA ?
+ for (caonly=0; caonly<2; caonly++) // leaf>
+#if TARGET_OS_IPHONE
+ {
+ leaf = 0;
+#else
+ for (leaf=0; leaf<2; leaf++)
+ {
+#endif
+ // attempt initial connection, then resumed connection, but all with same peer id (0xdeadbeef)
+ for (k=0; k<2; k++) {
+ ssl_client_handle *client = NULL;
+ ssl_server_handle *server = NULL;
+
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ client = ssl_client_handle_create(sp[0], any, ca?trusted_ca:trusted_ca2, caonly, leaf?NULL:trusted_ca, 300, 0xdeadbeef);
+ XCTAssert(client!=NULL, "trust: could not create client handle (%d:%d:%d:%d:%d)", any, ca, caonly, leaf, k);
+ require(client, errOut);
+
+ server = ssl_server_handle_create(sp[1], server_certs, 300);
+ XCTAssert(server!=NULL, "trust: could not create server handle (%d:%d:%d:%d:%d)", any, ca, caonly, leaf, k);
+ require(server, errOut);
+
+ pthread_create(&client_thread, NULL, securetransport_ssl_client_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_server_thread, server);
+
+ intptr_t server_err, client_err;
+
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+ Boolean resumed;
+ unsigned char sessionID[32];
+ size_t sessionIDLength = sizeof(sessionID);
+
+ XCTAssertEqual(client_err, 0, "trust: unexpected error %ld (client %d:%d:%d:%d:%d)", client_err, any, ca, caonly, leaf, k);
+ XCTAssertEqual(server_err, 0, "trust: unexpected error %ld (server %d:%d:%d:%d:%d)", server_err, any, ca, caonly, leaf, k);
+ XCTAssertEqual(errSecSuccess, SSLGetResumableSessionInfo(client->st, &resumed, sessionID, &sessionIDLength), "SSLGetResumableSessionInfo");
+
+ XCTAssertEqual((bool)resumed, (bool)(k), "trust: Unexpected resumption state=%d (%d:%d:%d:%d:%d)", resumed, any, ca, caonly, leaf, k);
+
+ errOut:
+ ssl_server_handle_destroy(server);
+ ssl_client_handle_destroy(client);
+
+ }
+ }
+
+ CFReleaseSafe(server_certs);
+ CFReleaseSafe(trusted_ca);
+}
+
+-(void) testSessionCache
+{
+
+ [self cache_ttl_test];
+
+ [self cache_trust_test];
+
+}
+@end
+
--- /dev/null
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+
+#include <tls_stream_parser.h>
+#include <tls_handshake.h>
+#include <tls_record.h>
+
+#include <sys/queue.h>
+
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (sessionstate)
+
+#define test_printf(x...)
+
+/* extern struct ccrng_state *ccDRBGGetRngState(); */
+#include <CommonCrypto/CommonRandomSPI.h>
+#define CCRNGSTATE ccDRBGGetRngState()
+
+struct RecQueueItem {
+ STAILQ_ENTRY(RecQueueItem) next; /* link to next queued entry or NULL */
+ tls_buffer record;
+ size_t offset; /* byte reads from this one */
+};
+
+typedef struct {
+ SSLContextRef st;
+ tls_stream_parser_t parser;
+ tls_record_t record;
+ tls_handshake_t hdsk;
+ STAILQ_HEAD(, RecQueueItem) rec_queue; // coretls server queue packet in this queue
+ int ready_count;
+} ssl_test_handle;
+
+
+static
+int tls_buffer_alloc(tls_buffer *buf, size_t length)
+{
+ buf->data = malloc(length);
+ if(!buf->data) return -ENOMEM;
+ buf->length = length;
+ return 0;
+}
+
+static
+int tls_buffer_free(tls_buffer *buf)
+{
+ free(buf->data);
+ buf->data = NULL;
+ buf->length = 0;
+ return 0;
+}
+
+#pragma mark -
+#pragma mark SecureTransport support
+
+#if 0
+static void hexdump(const char *s, const uint8_t *bytes, size_t len) {
+ size_t ix;
+ printf("socket %s(%p, %lu)\n", s, bytes, len);
+ for (ix = 0; ix < len; ++ix) {
+ if (!(ix % 16))
+ printf("\n");
+ printf("%02X ", bytes[ix]);
+ }
+ printf("\n");
+}
+#else
+#define hexdump(string, bytes, len)
+#endif
+
+static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
+{
+ ssl_test_handle *handle =(ssl_test_handle *)h;
+
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ tls_buffer buffer;
+ buffer.data = ptr;
+ buffer.length = len;
+ return tls_stream_parser_parse(handle->parser, buffer);
+}
+
+static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
+{
+ ssl_test_handle *handle =(ssl_test_handle *)h;
+
+ test_printf("%s: %p requesting len=%zd\n", __FUNCTION__, h, *length);
+
+ struct RecQueueItem *item = STAILQ_FIRST(&handle->rec_queue);
+
+ if(item==NULL) {
+ test_printf("%s: %p no data available\n", __FUNCTION__, h);
+ return errSSLWouldBlock;
+ }
+
+ size_t avail = item->record.length - item->offset;
+
+ test_printf("%s: %p %zd bytes available in %p\n", __FUNCTION__, h, avail, item);
+
+ if(avail > *length) {
+ memcpy(data, item->record.data+item->offset, *length);
+ item->offset += *length;
+ } else {
+ memcpy(data, item->record.data+item->offset, avail);
+ *length = avail;
+ STAILQ_REMOVE_HEAD(&handle->rec_queue, next);
+ tls_buffer_free(&item->record);
+ free(item);
+ }
+
+ test_printf("%s: %p %zd bytes read\n", __FUNCTION__, h, *length);
+
+
+ return 0;
+}
+
+static int process(tls_stream_parser_ctx_t ctx, tls_buffer record)
+{
+ ssl_test_handle *h = (ssl_test_handle *)ctx;
+ tls_buffer decrypted;
+ uint8_t ct;
+ int err;
+
+ test_printf("%s: %p processing %zd bytes\n", __FUNCTION__, ctx, record.length);
+
+
+ decrypted.length = tls_record_decrypted_size(h->record, record.length);
+ decrypted.data = malloc(decrypted.length);
+
+ require_action(decrypted.data, errOut, err=-ENOMEM);
+ require_noerr((err=tls_record_decrypt(h->record, record, &decrypted, &ct)), errOut);
+
+ test_printf("%s: %p decrypted %zd bytes, ct=%d\n", __FUNCTION__, ctx, decrypted.length, ct);
+
+ err=tls_handshake_process(h->hdsk, decrypted, ct);
+
+ test_printf("%s: %p processed, err=%d\n", __FUNCTION__, ctx, err);
+
+errOut:
+ free(decrypted.data);
+ return err;
+}
+
+static int
+tls_handshake_write_callback(tls_handshake_ctx_t ctx, const tls_buffer data, uint8_t content_type)
+{
+ int err = 0;
+ ssl_test_handle *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p writing data ct=%d, len=%zd\n", __FUNCTION__, ctx, content_type, data.length);
+
+ struct RecQueueItem *item = malloc(sizeof(struct RecQueueItem));
+ require_action(item, errOut, err=-ENOMEM);
+
+ err=tls_buffer_alloc(&item->record, tls_record_encrypted_size(handle->record, content_type, data.length));
+ require_noerr(err, errOut);
+
+ err=tls_record_encrypt(handle->record, data, content_type, &item->record);
+ require_noerr(err, errOut);
+
+ item->offset = 0;
+
+ test_printf("%s: %p queing %zd encrypted bytes, item=%p\n", __FUNCTION__, ctx, item->record.length, item);
+
+ STAILQ_INSERT_TAIL(&handle->rec_queue, item, next);
+
+ return 0;
+
+errOut:
+ if(item) {
+ tls_buffer_free(&item->record);
+ free(item);
+ }
+ return err;
+}
+
+
+static int
+tls_handshake_message_callback(tls_handshake_ctx_t ctx, tls_handshake_message_t event)
+{
+ ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p event = %d\n", __FUNCTION__, handle, event);
+
+ int err = 0;
+
+ return err;
+}
+
+
+
+static uint8_t appdata[] = "appdata";
+
+tls_buffer appdata_buffer = {
+ .data = appdata,
+ .length = sizeof(appdata),
+};
+
+
+static void
+tls_handshake_ready_callback(tls_handshake_ctx_t ctx, bool write, bool ready)
+{
+ ssl_test_handle *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p %s ready=%d\n", __FUNCTION__, handle, write?"write":"read", ready);
+
+ if(ready) {
+ if(write) {
+ if(handle->ready_count == 0) {
+ tls_handshake_request_renegotiation(handle->hdsk);
+ } else {
+ tls_handshake_write_callback(ctx, appdata_buffer, tls_record_type_AppData);
+ }
+ handle->ready_count++;;
+ }
+ }
+}
+
+static int
+tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx, int attempt)
+{
+ ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p attempt = %d\n", __FUNCTION__, handle, attempt);
+
+ return -1;
+}
+
+static
+int mySSLRecordInitPendingCiphersFunc(tls_handshake_ctx_t ref,
+ uint16_t selectedCipher,
+ bool server,
+ tls_buffer key)
+{
+ ssl_test_handle *handle = (ssl_test_handle *)ref;
+
+ test_printf("%s: %p, cipher=%04x, server=%d\n", __FUNCTION__, ref, selectedCipher, server);
+ return tls_record_init_pending_ciphers(handle->record, selectedCipher, server, key);
+}
+
+static
+int mySSLRecordAdvanceWriteCipherFunc(tls_handshake_ctx_t ref)
+{
+ ssl_test_handle *handle = (ssl_test_handle *)ref;
+ test_printf("%s: %p\n", __FUNCTION__, ref);
+ return tls_record_advance_write_cipher(handle->record);
+}
+
+static
+int mySSLRecordRollbackWriteCipherFunc(tls_handshake_ctx_t ref)
+{
+ ssl_test_handle *handle = (ssl_test_handle *)ref;
+ test_printf("%s: %p\n", __FUNCTION__, ref);
+ return tls_record_rollback_write_cipher(handle->record);
+}
+
+static
+int mySSLRecordAdvanceReadCipherFunc(tls_handshake_ctx_t ref)
+{
+ ssl_test_handle *handle = (ssl_test_handle *)ref;
+ test_printf("%s: %p\n", __FUNCTION__, ref);
+ return tls_record_advance_read_cipher(handle->record);
+}
+
+static
+int mySSLRecordSetProtocolVersionFunc(tls_handshake_ctx_t ref,
+ tls_protocol_version protocolVersion)
+{
+ ssl_test_handle *handle = (ssl_test_handle *)ref;
+ test_printf("%s: %p, version=%04x\n", __FUNCTION__, ref, protocolVersion);
+ return tls_record_set_protocol_version(handle->record, protocolVersion);
+}
+
+
+static int
+tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey, tls_buffer sessionData)
+{
+ ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p\n", __FUNCTION__, handle);
+
+ return -1;
+}
+
+static int
+tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey, tls_buffer *sessionData)
+{
+ ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p\n", __FUNCTION__, handle);
+
+ return -1;
+}
+
+static int
+tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey)
+{
+ ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p\n", __FUNCTION__, handle);
+
+ return -1;
+}
+
+static int
+tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx)
+{
+ ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
+
+ test_printf("%s: %p\n", __FUNCTION__, handle);
+
+ return -1;
+}
+
+/* TLS callbacks */
+tls_handshake_callbacks_t myTLS_handshake_callbacks = {
+ .write = tls_handshake_write_callback,
+ .message = tls_handshake_message_callback,
+ .ready = tls_handshake_ready_callback,
+ .set_retransmit_timer = tls_handshake_set_retransmit_timer_callback,
+ .init_pending_cipher = mySSLRecordInitPendingCiphersFunc,
+ .advance_write_cipher = mySSLRecordAdvanceWriteCipherFunc,
+ .rollback_write_cipher = mySSLRecordRollbackWriteCipherFunc,
+ .advance_read_cipher = mySSLRecordAdvanceReadCipherFunc,
+ .set_protocol_version = mySSLRecordSetProtocolVersionFunc,
+ .load_session_data = tls_handshake_load_session_data_callback,
+ .save_session_data = tls_handshake_save_session_data_callback,
+ .delete_session_data = tls_handshake_delete_session_data_callback,
+ .delete_all_sessions = tls_handshake_delete_all_sessions_callback,
+};
+
+
+static void
+ssl_test_handle_destroy(ssl_test_handle *handle)
+{
+ if(handle) {
+ if(handle->parser) tls_stream_parser_destroy(handle->parser);
+ if(handle->record) tls_record_destroy(handle->record);
+ if(handle->hdsk) tls_handshake_destroy(handle->hdsk);
+ if(handle->st) CFRelease(handle->st);
+ free(handle);
+ }
+}
+
+static uint16_t ciphers[] = {
+ TLS_PSK_WITH_AES_128_CBC_SHA,
+};
+static int nciphers = sizeof(ciphers)/sizeof(ciphers[0]);
+
+static SSLCipherSuite ciphersuites[] = {
+ TLS_PSK_WITH_AES_128_CBC_SHA,
+};
+static int nciphersuites = sizeof(ciphersuites)/sizeof(ciphersuites[0]);
+
+
+
+static uint8_t shared_secret[] = "secret";
+
+tls_buffer psk_secret = {
+ .data = shared_secret,
+ .length = sizeof(shared_secret),
+};
+
+static ssl_test_handle *
+ssl_test_handle_create(bool server)
+{
+ ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx, (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
+ require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out);
+ require_noerr(SSLSetEnabledCiphers(ctx, ciphersuites, nciphersuites), out);
+ require_noerr(SSLSetPSKSharedSecret(ctx, shared_secret, sizeof(shared_secret)), out);
+
+ handle->st = ctx;
+ handle->parser = tls_stream_parser_create(handle, process);
+ handle->record = tls_record_create(false, CCRNGSTATE);
+ handle->hdsk = tls_handshake_create(false, true); // server.
+
+ require_noerr(tls_handshake_set_ciphersuites(handle->hdsk, ciphers, nciphers), out);
+ require_noerr(tls_handshake_set_callbacks(handle->hdsk, &myTLS_handshake_callbacks, handle), out);
+ require_noerr(tls_handshake_set_psk_secret(handle->hdsk, &psk_secret), out);
+ require_noerr(tls_handshake_set_renegotiation(handle->hdsk, true), out);
+
+ // Initialize the record queue
+ STAILQ_INIT(&handle->rec_queue);
+
+ return handle;
+
+out:
+ if (handle) free(handle);
+ if (ctx) CFRelease(ctx);
+ return NULL;
+}
+
+-(void)testSessionState
+{
+ OSStatus ortn;
+
+ ssl_test_handle *client;
+ SSLSessionState state;
+
+ client = ssl_test_handle_create(false);
+
+ require_action(client, out, ortn = -1);
+
+ ortn = SSLGetSessionState(client->st, &state);
+ require_noerr(ortn, out);
+ XCTAssertEqual(state, kSSLIdle, "State should be Idle");
+
+ do {
+ ortn = SSLHandshake(client->st);
+ test_printf("SSLHandshake returned err=%d\n", (int)ortn);
+
+ require_noerr(SSLGetSessionState(client->st, &state), out);
+
+ if (ortn == errSSLPeerAuthCompleted || ortn == errSSLWouldBlock)
+ {
+ require_action(state==kSSLHandshake, out, ortn = -1);
+ }
+
+ } while(ortn==errSSLWouldBlock ||
+ ortn==errSSLPeerAuthCompleted);
+
+
+ XCTAssertEqual(ortn, 0, "Unexpected SSLHandshake exit code");
+ XCTAssertEqual(state, kSSLConnected, "State should be Connected");
+
+ uint8_t buffer[128];
+ size_t available = 0;
+
+ test_printf("Initial handshake done\n");
+
+ do {
+ ortn = SSLRead(client->st, buffer, sizeof(buffer), &available);
+ test_printf("SSLRead returned err=%d, avail=%zd\n", (int)ortn, available);
+ require_noerr(SSLGetSessionState(client->st, &state), out);
+
+ if (ortn == errSSLPeerAuthCompleted)
+ {
+ require_action(state==kSSLHandshake, out, ortn = -1);
+ }
+
+ } while(available==0);
+
+ XCTAssertEqual(ortn, 0, "Unexpected SSLRead exit code");
+ XCTAssertEqual(state, kSSLConnected, "State should be Connected");
+
+
+out:
+ XCTAssertEqual(ortn, 0, "Final result is non zero");
+ ssl_test_handle_destroy(client);
+
+}
+
+@end
--- /dev/null
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (sni)
+
+typedef struct {
+ SSLContextRef handle;
+ uint32_t session_id;
+ bool is_server;
+ int comm;
+} ssl_test_handle;
+
+
+#pragma mark -
+#pragma mark SecureTransport support
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+ size_t ix;
+ printf("socket write(%p, %lu)\n", bytes, len);
+ for (ix = 0; ix < len; ++ix) {
+ if (!(ix % 16))
+ printf("\n");
+ printf("%02X ", bytes[ix]);
+ }
+ printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+
+static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ hexdump(ptr, len);
+ ret = write((int)h, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)h, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ } else {
+ printf("read error(%d): ret=%zd, errno=%d\n", (int)h, ret, errno);
+ return -errno;
+ }
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static char peername[] = "localhost";
+
+static void *securetransport_server_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_test_handle * ssl = (ssl_test_handle *)arg;
+ SSLContextRef ctx = ssl->handle;
+ CFArrayRef server_certs = server_chain();
+
+ do {
+ ortn = SSLHandshake(ctx);
+ } while (ortn == errSSLWouldBlock);
+
+ ok(ortn==errSSLClientHelloReceived, "Unexpected Handshake exit code");
+
+ if (ortn == errSSLClientHelloReceived) {
+ char *sni = NULL;
+ size_t length = 0;
+ SSLCopyRequestedPeerNameLength(ctx, &length);
+ if (length > 0) {
+ sni = malloc(length);
+ SSLCopyRequestedPeerName(ctx, sni, &length);
+ }
+
+ SSLProtocol version = 0;
+ require_noerr(SSLGetProtocolVersionMax(ctx, &version), out);
+ if (version == kSSLProtocol3) {
+ ok(sni==NULL, "Unexpected SNI");
+ } else {
+ ok(sni!=NULL &&
+ length == sizeof(peername) &&
+ (memcmp(sni, peername, sizeof(peername))==0),
+ "SNI does not match");
+ }
+ require_noerr(SSLSetCertificate(ctx, server_certs), out);
+ free(sni);
+ }
+
+out:
+ SSLClose(ctx);
+ SSLDisposeContext(ctx);
+ close(ssl->comm);
+ CFReleaseSafe(server_certs);
+
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+static void *securetransport_client_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_test_handle * ssl = (ssl_test_handle *)arg;
+ SSLContextRef ctx = ssl->handle;
+
+ do {
+ ortn = SSLHandshake(ctx);
+ } while (ortn == errSSLWouldBlock || ortn != errSSLClosedGraceful);
+
+ SSLClose(ctx);
+ SSLDisposeContext(ctx);
+ close(ssl->comm);
+
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+static SSLCipherSuite ciphers[] = {
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+};
+
+static ssl_test_handle *
+ssl_test_handle_create(uint32_t session_id, bool server, int comm)
+{
+ ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
+
+ if (server)
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnClientHello, true), out);
+ else
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnServerAuth, true), out);
+
+ /* Tell SecureTransport to not check certs itself: it will break out of the
+ handshake to let us take care of it instead. */
+ require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+ handle->handle = ctx;
+ handle->is_server = server;
+ handle->session_id = session_id;
+ handle->comm = comm;
+
+ return handle;
+
+out:
+ if (handle) free(handle);
+ if (ctx) CFRelease(ctx);
+ return NULL;
+}
+
+static SSLProtocol versions[] = {
+ kSSLProtocol3,
+ kTLSProtocol1,
+ kTLSProtocol11,
+ kTLSProtocol12,
+};
+static int nversions = sizeof(versions)/sizeof(versions[0]);
+
+-(void)testSNI
+{
+ int j;
+ pthread_t client_thread, server_thread;
+
+ for(j=0; j<nversions; j++)
+ {
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+
+ ssl_test_handle *server, *client;
+
+ uint32_t session_id = (j+1) << 16 | 1 << 8;
+ server = ssl_test_handle_create(session_id, true /*server*/, sp[0]);
+ client = ssl_test_handle_create(session_id, false/*client*/, sp[1]);
+
+ require_noerr(SSLSetPeerID(server->handle, &session_id, sizeof(session_id)), out);
+ require_noerr(SSLSetPeerID(client->handle, &session_id, sizeof(session_id)), out);
+
+ /* set fixed cipher on client and server */
+ require_noerr(SSLSetEnabledCiphers(client->handle, &ciphers[0], 1), out);
+ require_noerr(SSLSetEnabledCiphers(server->handle, &ciphers[0], 1), out);
+
+ require_noerr(SSLSetProtocolVersionMax(client->handle, versions[j]), out);
+ require_noerr(SSLSetPeerDomainName(client->handle, peername, sizeof(peername)), out);
+
+ require_noerr(SSLSetProtocolVersionMax(server->handle, versions[j]), out);
+
+ pthread_create(&client_thread, NULL, securetransport_client_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_server_thread, server);
+
+ intptr_t server_err, client_err;
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+ out:
+ free(client);
+ free(server);
+
+ }
+}
+
+@end
--- /dev/null
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#if TARGET_OS_IPHONE
+#include <Security/SecRSAKey.h>
+#endif
+
+#include "ssl-utils.h"
+
+#include <tls_stream_parser.h>
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (split)
+
+typedef struct {
+ SSLContextRef st;
+ bool is_server;
+ int comm;
+ CFArrayRef certs;
+ int write_counter;
+ tls_stream_parser_t parser;
+ size_t write_size;
+} ssl_test_handle;
+
+
+#pragma mark -
+#pragma mark SecureTransport support
+
+#if 0
+static void hexdump(const char *s, const uint8_t *bytes, size_t len) {
+ size_t ix;
+ printf("socket %s(%p, %lu)\n", s, bytes, len);
+ for (ix = 0; ix < len; ++ix) {
+ if (!(ix % 16))
+ printf("\n");
+ printf("%02X ", bytes[ix]);
+ }
+ printf("\n");
+}
+#else
+#define hexdump(string, bytes, len)
+#endif
+
+static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
+{
+ ssl_test_handle *handle =(ssl_test_handle *)h;
+ int conn = handle->comm;
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ if(handle->is_server) {
+ //printf("SocketWrite: server write len=%zd\n", len);
+
+ tls_buffer buffer;
+ buffer.data = ptr;
+ buffer.length = len;
+ tls_stream_parser_parse(handle->parser, buffer);
+ }
+
+ do {
+ ssize_t ret;
+ do {
+ hexdump("write", ptr, len);
+ ret = write((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
+{
+ const ssl_test_handle *handle=h;
+ int conn = handle->comm;
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ if(len!=0)
+ printf("Something went wrong here... len=%d\n", (int)len);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static int process(tls_stream_parser_ctx_t ctx, tls_buffer record)
+{
+ ssl_test_handle *handle = (ssl_test_handle *)ctx;
+
+ // printf("processing record len=%zd, type=%d\n", record.length, record.data[0]);
+ if(record.data[0]==tls_record_type_AppData) {
+ handle->write_counter++;
+ // printf("record count = %d\n", handle->write_counter);
+ }
+
+ return 0;
+}
+
+
+static void *securetransport_ssl_thread(void *arg)
+{
+ OSStatus ortn;
+ ssl_test_handle * ssl = (ssl_test_handle *)arg;
+ SSLContextRef ctx = ssl->st;
+ bool got_server_auth = false;
+
+ //uint64_t start = mach_absolute_time();
+ do {
+ ortn = SSLHandshake(ctx);
+
+ if (ortn == errSSLServerAuthCompleted)
+ {
+ require_string(!got_server_auth, out, "second server auth");
+ got_server_auth = true;
+ }
+ } while (ortn == errSSLWouldBlock
+ || ortn == errSSLServerAuthCompleted);
+
+ require_noerr_action_quiet(ortn, out,
+ fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
+
+ unsigned char ibuf[90000], obuf[45000];
+
+ if (ssl->is_server) {
+ size_t len;
+ require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, ssl->write_size, obuf), out, ortn = -1);
+ require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out);
+ require_action(len == ssl->write_size, out, ortn = -1);
+ require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out);
+ require_action(len == ssl->write_size, out, ortn = -1);
+ } else {
+ size_t len = ssl->write_size*2;
+ size_t olen;
+ unsigned char *p = ibuf;
+ while (len) {
+ require_noerr(ortn = SSLRead(ctx, p, len, &olen), out);
+ len -= olen;
+ p += olen;
+ }
+ }
+
+out:
+ SSLClose(ctx);
+ CFRelease(ctx);
+ close(ssl->comm);
+ pthread_exit((void *)(intptr_t)ortn);
+ return NULL;
+}
+
+static void
+ssl_test_handle_destroy(ssl_test_handle *handle)
+{
+ if(handle) {
+ if(handle->parser) tls_stream_parser_destroy(handle->parser);
+ free(handle);
+ }
+}
+
+static ssl_test_handle *
+ssl_test_handle_create(bool server, int comm, CFArrayRef certs)
+{
+ ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+ SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
+
+ require(handle, out);
+ require(ctx, out);
+
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
+
+ if (server)
+ require_noerr(SSLSetCertificate(ctx, certs), out);
+
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnServerAuth, true), out);
+
+ /* Tell SecureTransport to not check certs itself: it will break out of the
+ handshake to let us take care of it instead. */
+ require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+ handle->is_server = server;
+ handle->comm = comm;
+ handle->certs = certs;
+ handle->st = ctx;
+ handle->write_counter = 0;
+ handle->parser = tls_stream_parser_create(handle, process);
+
+ return handle;
+
+out:
+ if (handle) free(handle);
+ if (ctx) CFRelease(ctx);
+ return NULL;
+}
+
+static SSLCipherSuite ciphers[] = {
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+};
+static int nciphers = sizeof(ciphers)/sizeof(ciphers[0]);
+
+static SSLProtocol versions[] = {
+ kSSLProtocol3,
+ kTLSProtocol1,
+ kTLSProtocol11,
+ kTLSProtocol12,
+};
+static int nversions = sizeof(versions)/sizeof(versions[0]);
+
+// { write size, expected count when nosplit, expected count when split }
+static size_t wsizes[][3] = {
+ { 1, 2, 2 },
+ { 2, 2, 3 },
+ { 3, 2, 3 },
+ { 4, 2, 3 },
+ { 16384, 2, 3 },
+ { 16385, 4, 4 },
+ { 16386, 4, 5 },
+ { 16387, 4, 5 },
+ { 16388, 4, 5 },
+ { 32768, 4, 5 },
+ { 32769, 6, 6 },
+ { 32770, 6, 7 },
+ { 32771, 6, 7 },
+ { 32772, 6, 7 },
+};
+static int nwsizes = sizeof(wsizes)/sizeof(wsizes[0]);
+
+-(void) testSplit
+{
+ pthread_t client_thread, server_thread;
+ CFArrayRef server_certs = server_chain();
+ XCTAssert(server_certs, "got server certs");
+
+ int i,j,k,s;
+
+ for(i=0; i<nciphers; i++)
+ for(j=0; j<nversions; j++)
+ for(k=0; k<nwsizes; k++)
+ for(s=0; s<3; s++)
+ {
+ int sp[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
+ fcntl(sp[0], F_SETNOSIGPIPE, 1);
+ fcntl(sp[1], F_SETNOSIGPIPE, 1);
+
+ ssl_test_handle *server, *client;
+
+ server = ssl_test_handle_create(true /*server*/, sp[0], server_certs);
+ client = ssl_test_handle_create(false/*client*/, sp[1], NULL);
+
+ server->write_size = wsizes[k][0];
+ client->write_size = wsizes[k][0];
+
+ require(client, out);
+ require(server, out);
+
+ require_noerr(SSLSetProtocolVersionMin(server->st, kSSLProtocol3), out); // We need this server to do SSL3.
+ require_noerr(SSLSetProtocolVersionMax(client->st, versions[j]), out);
+ require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i], 1), out);
+ if(s) {
+ // s=0: default (should be enabled)
+ // s=1: explicit enable
+ // s=2: expliciti disable
+ require_noerr(SSLSetSessionOption(server->st, kSSLSessionOptionSendOneByteRecord, (s==1)?true:false), out);
+ }
+ // printf("**** Test Case: i=%d, j=%d, k=%d (%zd), s=%d ****\n", i, j, k, wsizes[k][0], s);
+
+ pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
+ pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
+
+ intptr_t server_err, client_err;
+ pthread_join(client_thread, (void*)&client_err);
+ pthread_join(server_thread, (void*)&server_err);
+
+ XCTAssert(!server_err, "Server error = %ld", server_err);
+ XCTAssert(!client_err, "Client error = %ld", client_err);
+
+ /* one byte split is expected only for AES when using TLS 1.0 or lower, and when not disabled */
+ bool expected_split = (i==0) && (s!=2) && (versions[j]<=kTLSProtocol1);
+ int expected_count = (int)(expected_split ? wsizes[k][2]: wsizes[k][1]);
+
+ XCTAssertEqual(server->write_counter, expected_count, "wrong number of data records");
+
+ // fprintf(stderr, "Server write counter = %d, expected %d\n", server->write_counter, expected_count);
+
+out:
+ ssl_test_handle_destroy(client);
+ ssl_test_handle_destroy(server);
+
+ }
+ CFReleaseNull(server_certs);
+}
+
+@end
--- /dev/null
+/*
+ * 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@
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Security/SecureTransportPriv.h>
+#include <AssertMacros.h>
+
+#include "ssl-utils.h"
+
+
+#include "cipherSpecs.h"
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests (sslciphers)
+
+static int test_GetSupportedCiphers(SSLContextRef ssl, bool server)
+{
+ size_t max_ciphers = 0;
+ int fail=1;
+ SSLCipherSuite *ciphers = NULL;
+
+ require_noerr(SSLGetNumberSupportedCiphers(ssl, &max_ciphers), out);
+
+ size_t size = max_ciphers * sizeof (SSLCipherSuite);
+ ciphers = (SSLCipherSuite *) malloc(size);
+
+ require_string(ciphers, out, "out of memory");
+ memset(ciphers, 0xff, size);
+
+ size_t num_ciphers = max_ciphers;
+ require_noerr(SSLGetSupportedCiphers(ssl, ciphers, &num_ciphers), out);
+
+ for (size_t i = 0; i < num_ciphers; i++) {
+ require(ciphers[i]!=(SSLCipherSuite)(-1), out);
+ }
+
+ /* Success! */
+ fail=0;
+
+out:
+ if(ciphers) free(ciphers);
+ return fail;
+}
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ return errSSLWouldBlock;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+ return errSSLWouldBlock;
+}
+
+
+
+static const SSLCipherSuite legacy_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+};
+
+const SSLCipherSuite legacy_DHE_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+};
+
+
+
+const SSLCipherSuite standard_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+};
+
+const SSLCipherSuite default_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+};
+
+const SSLCipherSuite ATSv1_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+};
+
+const SSLCipherSuite ATSv1_noPFS_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+};
+
+const SSLCipherSuite TLSv1_RC4_fallback_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+};
+
+const SSLCipherSuite TLSv1_fallback_ciphersuites[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+};
+
+const SSLCipherSuite anonymous_ciphersuites[] = {
+ TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+ TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
+ TLS_DH_anon_WITH_AES_256_CBC_SHA256,
+ TLS_DH_anon_WITH_AES_256_CBC_SHA,
+ TLS_DH_anon_WITH_AES_128_CBC_SHA256,
+ TLS_DH_anon_WITH_AES_128_CBC_SHA
+};
+
+
+static int test_GetEnabledCiphers(SSLContextRef ssl, unsigned expected_num_ciphers, const SSLCipherSuite *expected_ciphers)
+{
+ size_t num_ciphers;
+ size_t size;
+ int fail=1;
+ SSLCipherSuite *ciphers = NULL;
+
+ require_noerr(SSLSetIOFuncs(ssl, &SocketRead, &SocketWrite), out);
+ require_noerr(SSLSetConnection(ssl, NULL), out);
+
+ require_noerr(SSLGetNumberEnabledCiphers(ssl, &num_ciphers), out);
+ require_string(num_ciphers==expected_num_ciphers, out, "wrong ciphersuites number");
+
+ size = num_ciphers * sizeof (SSLCipherSuite);
+ ciphers = (SSLCipherSuite *) malloc(size);
+ require_string(ciphers, out, "out of memory");
+ memset(ciphers, 0xff, size);
+
+ require_noerr(SSLGetEnabledCiphers(ssl, ciphers, &num_ciphers), out);
+ require_string(memcmp(ciphers, expected_ciphers, size)==0, out, "wrong ciphersuites");
+
+ free(ciphers);
+ ciphers = NULL;
+
+ require(SSLHandshake(ssl) == errSSLWouldBlock, out);
+
+ require_noerr(SSLGetNumberEnabledCiphers(ssl, &num_ciphers), out);
+ require_string(num_ciphers==expected_num_ciphers, out, "wrong ciphersuites number");
+
+ size = num_ciphers * sizeof (SSLCipherSuite);
+ ciphers = (SSLCipherSuite *) malloc(size);
+ require_string(ciphers, out, "out of memory");
+ memset(ciphers, 0xff, size);
+
+ require_noerr(SSLGetEnabledCiphers(ssl, ciphers, &num_ciphers), out);
+ require_string(memcmp(ciphers, expected_ciphers, size)==0, out, "wrong ciphersuites");
+
+ /* Success! */
+ fail=0;
+
+out:
+ free(ciphers);
+ return fail;
+}
+
+static int test_SetEnabledCiphers(SSLContextRef ssl)
+{
+ int fail=1;
+ size_t num_enabled;
+
+ /* This should not fail as long as we have one valid cipher in this table */
+ SSLCipherSuite ciphers[] = {
+ SSL_RSA_WITH_RC2_CBC_MD5, /* unsupported */
+ TLS_RSA_WITH_NULL_SHA, /* supported by not enabled by default */
+ TLS_RSA_WITH_AES_128_CBC_SHA, /* Supported and enabled by default */
+ };
+
+ require_noerr(SSLSetEnabledCiphers(ssl, ciphers, sizeof(ciphers)/sizeof(SSLCipherSuite)), out);
+ require_noerr(SSLGetNumberEnabledCiphers(ssl, &num_enabled), out);
+
+ require(num_enabled==2, out); /* 2 ciphers in the above table are supported */
+
+ /* Success! */
+ fail=0;
+
+out:
+ return fail;
+}
+
+
+- (void)test_dhe: (SSLProtocolSide) side dhe_enabled: (bool) dhe_enabled
+{
+ SSLContextRef ssl = NULL;
+ bool server = (side == kSSLServerSide);
+
+ ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType);
+ XCTAssert(ssl != NULL, "test_dhe: SSLCreateContext(1) failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled");
+ require(ssl, out);
+
+ XCTAssertEqual(noErr, SSLSetDHEEnabled(ssl, dhe_enabled),"test_dhe: SSLSetDHEEnabled failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled");
+
+ unsigned num = (dhe_enabled?sizeof(legacy_DHE_ciphersuites):sizeof(legacy_ciphersuites))/sizeof(SSLCipherSuite);
+ const SSLCipherSuite *ciphers = dhe_enabled?legacy_DHE_ciphersuites:legacy_ciphersuites;
+ /* The order of this tests does matter, be careful when adding tests */
+ XCTAssert(!test_GetSupportedCiphers(ssl, server), "test_dhe: GetSupportedCiphers test failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled");
+ XCTAssert(!test_GetEnabledCiphers(ssl, num, ciphers), "test_dhe: GetEnabledCiphers test failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled");
+
+ CFRelease(ssl); ssl=NULL;
+
+ ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType);
+ XCTAssert(ssl, "test_dhe: SSLCreateContext(2) failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled");
+ require(ssl, out);
+
+ XCTAssert(!test_SetEnabledCiphers(ssl), "test_dhe: SetEnabledCiphers test failed (%s, %s)", server?"server":"client", dhe_enabled?"enabled":"disabled");
+
+out:
+ if(ssl) CFRelease(ssl);
+}
+
+-(void) test_config: (SSLProtocolSide) side config: (CFStringRef) config num: (unsigned) num cipherList: (const SSLCipherSuite*) ciphers
+{
+ SSLContextRef ssl = NULL;
+ bool server = (side == kSSLServerSide);
+
+ ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType);
+ XCTAssert(ssl, "test_config: SSLCreateContext(1) failed (%s,%@)", server?"server":"client", config);
+ require(ssl, out);
+
+ XCTAssertEqual(errSecSuccess, SSLSetSessionConfig(ssl, config), "test_config: SSLSetSessionConfig failed (%s,%@)", server?"server":"client", config);
+
+ /* The order of this tests does matter, be careful when adding tests */
+ XCTAssert(!test_GetSupportedCiphers(ssl, server), "test_config: GetSupportedCiphers test failed (%s,%@)", server?"server":"client", config);
+ XCTAssert(!test_GetEnabledCiphers(ssl, num, ciphers), "test_config: GetEnabledCiphers test failed (%s,%@)", server?"server":"client", config);
+
+ CFRelease(ssl); ssl=NULL;
+
+ ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType);
+ XCTAssert(ssl, "test_config: SSLCreateContext(2) failed (%s,%@)", server?"server":"client", config);
+ require(ssl, out);
+
+ XCTAssert(!test_SetEnabledCiphers(ssl), "test_config: SetEnabledCiphers test failed (%s,%@)", server?"server":"client", config);
+
+out:
+ if(ssl) CFRelease(ssl);
+}
+
+-(void) test_default: (SSLProtocolSide) side
+{
+ SSLContextRef ssl = NULL;
+ bool server = (side == kSSLServerSide);
+
+ ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType);
+ XCTAssert(ssl!=NULL, "test_config: SSLCreateContext(1) failed (%s)", server?"server":"client");
+ require(ssl, out);
+
+ /* The order of this tests does matter, be careful when adding tests */
+ XCTAssert(!test_GetSupportedCiphers(ssl, server), "test_default: GetSupportedCiphers test failed (%s)", server?"server":"client");
+ XCTAssert(!test_GetEnabledCiphers(ssl, sizeof(default_ciphersuites)/sizeof(SSLCipherSuite), default_ciphersuites), "test_default: GetEnabledCiphers test failed (%s)", server?"server":"client");
+
+ CFRelease(ssl); ssl=NULL;
+
+ ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType);
+ XCTAssert(ssl, "test_default: SSLCreateContext(2) failed (%s)", server?"server":"client");
+ require(ssl, out);
+
+ XCTAssert(!test_SetEnabledCiphers(ssl), "test_config: SetEnabledCiphers test failed (%s)", server?"server":"client");
+
+out:
+ if(ssl) CFRelease(ssl);
+}
+
+
+
+
+-(void) testSSLCiphers
+{
+ [self test_dhe:kSSLClientSide dhe_enabled:true];
+ [self test_dhe:kSSLServerSide dhe_enabled:true];
+ [self test_dhe:kSSLClientSide dhe_enabled:false];
+ [self test_dhe:kSSLServerSide dhe_enabled:false];
+
+ [self test_default:kSSLClientSide];
+ [self test_default:kSSLServerSide];
+
+#define TEST_CONFIG(x, y) do { \
+ [self test_config:kSSLClientSide config:x num:sizeof(y)/sizeof(SSLCipherSuite) cipherList:y]; \
+ [self test_config:kSSLServerSide config:x num:sizeof(y)/sizeof(SSLCipherSuite) cipherList:y]; \
+} while(0)
+
+ TEST_CONFIG(kSSLSessionConfig_ATSv1, ATSv1_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_ATSv1_noPFS, ATSv1_noPFS_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_legacy, legacy_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_legacy_DHE, legacy_DHE_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_standard, standard_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_RC4_fallback, legacy_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_TLSv1_fallback, default_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_TLSv1_RC4_fallback, legacy_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_default, default_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_anonymous, anonymous_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_3DES_fallback, default_ciphersuites);
+ TEST_CONFIG(kSSLSessionConfig_TLSv1_3DES_fallback, default_ciphersuites);
+
+}
+
+@end
+
--- /dev/null
+/*
+ * Copyright (c) 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@
+ */
+
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecureTransportPriv.h> /* SSLSetOption */
+#include <Security/SecureTransport.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecIdentityPriv.h>
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecRandom.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#include "STLegacyTests.h"
+
+@implementation STLegacyTests (tls12)
+
+struct s_server {
+ char *host;
+ int port;
+ SSLProtocol maxprot;
+};
+
+typedef struct {
+ struct s_server *server;
+ uint32_t session_id;
+ bool is_session_resume;
+ SSLContextRef st;
+ bool client_side_auth;
+ bool dh_anonymous;
+ int comm;
+ CFArrayRef certs;
+} ssl_test_handle;
+
+
+
+#if 0
+static void hexdump(const uint8_t *bytes, size_t len) {
+ size_t ix;
+ printf("socket write(%p, %lu)\n", bytes, len);
+ for (ix = 0; ix < len; ++ix) {
+ if (!(ix % 16))
+ printf("\n");
+ printf("%02X ", bytes[ix]);
+ }
+ printf("\n");
+}
+#else
+#define hexdump(bytes, len)
+#endif
+
+static int SocketConnect(const char *hostName, int port)
+{
+ struct sockaddr_in addr;
+ struct in_addr host;
+ int sock;
+ int err;
+ struct hostent *ent;
+
+ if (hostName[0] >= '0' && hostName[0] <= '9') {
+ host.s_addr = inet_addr(hostName);
+ } else {
+ ent = gethostbyname(hostName);
+ if(ent == NULL) {
+ printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
+ return -2;
+ }
+ memcpy(&host, ent->h_addr, sizeof(struct in_addr));
+ }
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ addr.sin_addr = host;
+ addr.sin_port = htons((u_short)port);
+
+ addr.sin_family = AF_INET;
+ err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
+
+ if(err!=0)
+ {
+ perror("connect failed");
+ return -1;
+ }
+
+ return sock;
+}
+
+
+static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ hexdump(ptr, len);
+ ret = write((int)conn, ptr, len);
+ if (ret < 0)
+ perror("send");
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
+{
+ size_t len = *length;
+ uint8_t *ptr = (uint8_t *)data;
+
+ do {
+ ssize_t ret;
+ do {
+ ret = read((int)conn, ptr, len);
+ if (ret < 0)
+ perror("send");
+ } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
+ if (ret > 0) {
+ len -= ret;
+ ptr += ret;
+ }
+ else
+ return -36;
+ } while (len > 0);
+
+ *length = *length - len;
+ return errSecSuccess;
+}
+
+static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, const char *peerName)
+{
+ SSLContextRef ctx = NULL;
+
+ require_noerr(SSLNewContext(false, &ctx), out);
+ require_noerr(SSLSetIOFuncs(ctx,
+ (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
+ require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
+
+ require_noerr(SSLSetSessionOption(ctx,
+ kSSLSessionOptionBreakOnServerAuth, true), out);
+
+ require_noerr(SSLSetProtocolVersionMax(ctx, maxprot), out);
+
+ require_noerr(SSLSetPeerDomainName(ctx, peerName, strlen(peerName)), out);
+ /* Tell SecureTransport to not check certs itself: it will break out of the
+ handshake to let us take care of it instead. */
+ require_noerr(SSLSetEnableCertVerify(ctx, false), out);
+
+ return ctx;
+out:
+ if (ctx)
+ SSLDisposeContext(ctx);
+ return NULL;
+}
+
+static OSStatus securetransport(ssl_test_handle * ssl)
+{
+ OSStatus ortn;
+ SSLContextRef ctx = ssl->st;
+ SecTrustRef trust = NULL;
+ bool got_server_auth = false, got_client_cert_req = false;
+
+ //uint64_t start = mach_absolute_time();
+ do {
+ ortn = SSLHandshake(ctx);
+
+ if (ortn == errSSLServerAuthCompleted)
+ {
+ require_string(!got_server_auth, out, "second server auth");
+ require_string(!got_client_cert_req, out, "got client cert req before server auth");
+ got_server_auth = true;
+ require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
+ /* verify peer cert chain */
+ require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
+ SecTrustResultType trust_result = 0;
+ /* this won't verify without setting up a trusted anchor */
+ require_noerr(SecTrustEvaluate(trust, &trust_result), out);
+ require((trust_result == kSecTrustResultUnspecified), out);
+
+ }
+ } while (ortn == errSSLWouldBlock
+ || ortn == errSSLServerAuthCompleted);
+ require_noerr_action_quiet(ortn, out,
+ fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
+
+ require_string(got_server_auth, out, "never got server auth");
+
+ //uint64_t elapsed = mach_absolute_time() - start;
+ //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
+
+ /*
+ SSLProtocol proto = kSSLProtocolUnknown;
+ require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
+
+ SSLCipherSuite cipherSuite;
+ require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
+ //fprintf(stderr, "st negotiated %02x\n", cipherSuite);
+
+
+out:
+ SSLClose(ctx);
+ SSLDisposeContext(ctx);
+ if (trust) CFRelease(trust);
+
+ return ortn;
+}
+
+
+
+#define CONNECT_TRIES 3
+
+-(ssl_test_handle*)ssl_test_handle_create:(struct s_server *)server
+{
+ int comm = -1;
+
+ for(int try = 0; comm<0 && try<CONNECT_TRIES; try++) {
+ comm=SocketConnect(server->host, server->port);
+ }
+
+ if(comm<0) {
+ XCTFail("connect failed with err=%d - %s:%d", comm, server->host, server->port);
+ return NULL;
+ }
+
+ ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
+ if (handle) {
+ handle->comm = comm;
+ handle->st = make_ssl_ref(comm, server->maxprot, server->host);
+ handle->server = server;
+ }
+ return handle;
+}
+
+static void
+ssl_test_handle_destroy(ssl_test_handle *handle)
+{
+ close(handle->comm);
+ free(handle);
+}
+
+
+struct s_server servers[] = {
+#if !TARGET_OS_IPHONE //This test run on AppleWifi on iPhone, so we can't connect to internal servers.
+ {"nod.apple.com", 636, kTLSProtocol12 }, // This one has only the server eku, not the client one.
+#endif
+ {"gsa.apple.com", 443, kTLSProtocol12 }, // This one has only the server eku, not the client one.
+ /* Good tls 1.2 servers */
+ {"sslanalyzer.comodoca.com", 443, kTLSProtocol12 }, // This one has a stapled OCSP response with SCTs.
+ {"encrypted.google.com", 443, kTLSProtocol12 },
+ {"www.amazon.com",443, kTLSProtocol12 },
+ //{"www.mikestoolbox.org",443, kTLSProtocol12 },
+ /* servers with issues */
+ // This server went offline as of May 2016 -- {"vpp.visa.co.uk", 443, kTLSProtocol12 }, // Doesnt like SSL 3.0 in initial record layer version
+ {"imap.softbank.jp",993, kTLSProtocol12 }, // softbank imap server, there are multiple servers behind this, one of them is not able to handle downgrading to TLS 1.2 properly (126.240.66.17).
+ {"mobile.charter.net",993, kTLSProtocol12 }, // Support 1.2 but fail to negotiate properly
+ {"mybill.vodafone.com.au", 443, kTLSProtocol1 }, /* 2056 bit server key */
+};
+
+#define NSERVERS (int)(sizeof(servers)/sizeof(servers[0]))
+#define NLOOPS 1
+
+-(void)testTls12
+{
+ int p;
+ OSStatus r;
+
+ for(p=0; p<NSERVERS;p++) {
+ for(int loops=0; loops<NLOOPS; loops++) {
+ ssl_test_handle *client;
+
+ SKIP: {
+ if(!(client = [self ssl_test_handle_create:&servers[p]]))
+ continue;
+ r=securetransport(client);
+ XCTAssert(r==errSecSuccess, "handshake failed with err=%ld - %s:%d (try %d)", (long)r, servers[p].host, servers[p].port, loops);
+
+ ssl_test_handle_destroy(client);
+ }
+ }
+ }
+}
+
+@end
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.keystore.access-keychain-keys</key>
+ <true/>
+ <key>restore-keychain</key>
+ <true/>
+ <key>migrate-keychain</key>
+ <true/>
+ <key>modify-anchor-certificates</key>
+ <true/>
+ <key>application-identifier</key>
+ <string>com.apple.security.regressions</string>
+ <key>keychain-access-groups</key>
+ <array>
+ <string>com.apple.security.regressions</string>
+ <string>lockdown-identities</string>
+ <string>apple</string>
+ </array>
+</dict>
+</plist>
--- /dev/null
+//
+// STLegacyTests.h
+// Security
+//
+//
+
+#ifndef STLegacyTests_h
+#define STLegacyTests_h
+
+#import <Foundation/Foundation.h>
+#include <CoreFoundation/CoreFoundation.h>
+#import <XCTest/XCTest.h>
+#define SKIP switch(0) default
+
+@interface STLegacyTests : XCTestCase
+
+@end
+
+
+#endif /* STLegacyTests_h */
--- /dev/null
+//
+// STLegacyTests.m
+// Security
+//
+//
+
+#import "STLegacyTests.h"
+
+@implementation STLegacyTests
+
+@end
--- /dev/null
+//
+// SecureTransportTests.m
+// SecureTransportTests
+//
+//
+
+#import <XCTest/XCTest.h>
+
+@interface SecureTransportTests : XCTestCase
+
+@end
+
+@implementation SecureTransportTests
+
+@end
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Project</key>
+ <string>Security</string>
+ <key>Tests</key>
+ <array>
+ <dict>
+ <key>TestName</key>
+ <string>SecureTransportTests</string>
+ <key>WorkingDirectory</key>
+ <string>/AppleInternal/XCTests/com.apple.security/</string>
+ <key>Command</key>
+ <array>
+ <string>BATS_XCTEST_CMD -NSTreatUnknownArgumentsAsOpen NO -ApplePersistenceIgnoreState YES -XCTest Self SecureTransport_ios_tests.xctest</string>
+ </array>
+ </dict>
+ </array>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Project</key>
+ <string>Security</string>
+ <key>Tests</key>
+ <array>
+ <dict>
+ <key>TestName</key>
+ <string>SecureTransportTests</string>
+ <key>WorkingDirectory</key>
+ <string>/AppleInternal/XCTests/com.apple.security/</string>
+ <key>Command</key>
+ <array>
+ <string>BATS_XCTEST_CMD -NSTreatUnknownArgumentsAsOpen NO -ApplePersistenceIgnoreState YES -XCTest Self SecureTransport_macos_tests.xctest</string>
+ </array>
+ </dict>
+ </array>
+</dict>
+</plist>
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_MD5,
};
const SSLCipherSuite legacy_DHE_ciphersuites[] = {
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_MD5,
};
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_MD5,
};
const SSLCipherSuite TLSv1_fallback_ciphersuites[] = {
/* Server provided RSA certificate for key exchange. */
C(TLS_RSA_WITH_NULL_MD5)
C(TLS_RSA_WITH_NULL_SHA)
- C(TLS_RSA_WITH_RC4_128_MD5)
- C(TLS_RSA_WITH_RC4_128_SHA)
C(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
C(TLS_RSA_WITH_AES_128_CBC_SHA)
C(TLS_RSA_WITH_AES_256_CBC_SHA)
C(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
/* Completely anonymous Diffie-Hellman */
- C(TLS_DH_anon_WITH_RC4_128_MD5)
C(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA)
C(TLS_DH_anon_WITH_AES_128_CBC_SHA)
C(TLS_DH_anon_WITH_AES_256_CBC_SHA)
/* ECDSA addenda, RFC 4492 */
C(TLS_ECDH_ECDSA_WITH_NULL_SHA)
- C(TLS_ECDH_ECDSA_WITH_RC4_128_SHA)
C(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA)
C(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA)
C(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA)
C(TLS_ECDHE_ECDSA_WITH_NULL_SHA)
- C(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
C(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)
C(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
C(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
C(TLS_ECDH_RSA_WITH_NULL_SHA)
- C(TLS_ECDH_RSA_WITH_RC4_128_SHA)
C(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA)
C(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA)
C(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA)
C(TLS_ECDHE_RSA_WITH_NULL_SHA)
- C(TLS_ECDHE_RSA_WITH_RC4_128_SHA)
C(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
C(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
C(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
C(TLS_ECDH_anon_WITH_NULL_SHA)
- C(TLS_ECDH_anon_WITH_RC4_128_SHA)
C(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA)
C(TLS_ECDH_anon_WITH_AES_128_CBC_SHA)
C(TLS_ECDH_anon_WITH_AES_256_CBC_SHA)
C(SSL_RSA_WITH_3DES_EDE_CBC_MD5)
C(SSL_NO_SUCH_CIPHERSUITE)
- C(SSL_RSA_EXPORT_WITH_RC4_40_MD5)
C(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5)
C(SSL_RSA_WITH_IDEA_CBC_SHA)
C(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA)
C(SSL_DHE_DSS_WITH_DES_CBC_SHA)
C(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA)
C(SSL_DHE_RSA_WITH_DES_CBC_SHA)
- C(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5)
C(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA)
C(SSL_DH_anon_WITH_DES_CBC_SHA)
C(SSL_FORTEZZA_DMS_WITH_NULL_SHA)
C(TLS_PSK_WITH_AES_128_CBC_SHA256)
C(TLS_PSK_WITH_AES_256_CBC_SHA)
C(TLS_PSK_WITH_AES_128_CBC_SHA)
- C(TLS_PSK_WITH_RC4_128_SHA)
C(TLS_PSK_WITH_3DES_EDE_CBC_SHA)
C(TLS_PSK_WITH_NULL_SHA384)
C(TLS_PSK_WITH_NULL_SHA256)
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 2c:10:5b:40:8c:b3:1f:3c:c8:37:ae:60:be:7e:23:eb:1a:79:96
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: CN=SecurityTest CA Cert (ECC)
+ Validity
+ Not Before: May 26 01:25:33 2018 GMT
+ Not After : May 17 01:25:33 2055 GMT
+ Subject: OU=SecurityTests Client Cert (ECC), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:10:73:9e:25:d4:2a:14:b0:ed:6c:a7:cd:5b:f5:
+ f2:34:36:4e:1f:52:30:53:b4:c6:8c:19:72:35:d5:
+ 7d:8a:7a:87:50:d5:72:c2:ec:a6:ee:00:ef:a3:e8:
+ c5:7a:ec:c5:53:6f:20:6f:74:a1:11:d4:69:d0:68:
+ 5d:1b:04:c3:01
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Subject Alternative Name:
+ DNS:localhost
+ X509v3 Subject Key Identifier:
+ 91:13:09:3A:DE:84:E6:6E:80:4C:7D:E9:6C:F6:16:8A:24:7E:BC:B6
+ X509v3 Authority Key Identifier:
+ keyid:2A:8E:DC:15:F2:1D:69:64:39:77:8F:EE:F4:6D:3F:34:D9:85:F0:8C
+
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:45:02:20:35:e7:6c:1f:fa:4c:0a:bf:9b:e9:ad:df:91:31:
+ b7:b2:56:09:98:07:1f:f3:5f:fd:f1:71:8e:43:36:52:a5:f4:
+ 02:21:00:b9:78:65:4d:b3:25:11:64:f7:85:29:70:52:85:64:
+ 93:cd:d4:8d:a1:4e:fe:66:de:d3:35:cd:e4:90:e8:2e:7f
-----BEGIN CERTIFICATE-----
-MIIBYTCCAQegAwIBAgICA+wwCQYHKoZIzj0EATAlMSMwIQYDVQQDExpTZWN1cml0
-eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xNTAzMjMwNzEwMjZaGA8yMDU1MDMxMzA3
-MTAyNlowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0cyBDbGllbnQgQ2VydCAoRUND
-KTESMBAGA1UEAxMJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
-EHOeJdQqFLDtbKfNW/XyNDZOH1IwU7TGjBlyNdV9inqHUNVywuym7gDvo+jFeuzF
-U28gb3ShEdRp0GhdGwTDAaMNMAswCQYDVR0TBAIwADAJBgcqhkjOPQQBA0kAMEYC
-IQDxZsr1M+IXVJmDSGxlX/pKFDUdNWme4hRc8Heo26YRogIhAN9Jw2fsAbq/Fgl1
-df8sSk5DlkOAjnqtL3YMhkG+miiZ
+MIIB8zCCAZmgAwIBAgITLBBbQIyzHzzIN65gvn4j6xp5ljAKBggqhkjOPQQDAjAl
+MSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xODA1MjYw
+MTI1MzNaGA8yMDU1MDUxNzAxMjUzM1owPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0
+cyBDbGllbnQgQ2VydCAoRUNDKTESMBAGA1UEAxMJbG9jYWxob3N0MFkwEwYHKoZI
+zj0CAQYIKoZIzj0DAQcDQgAEEHOeJdQqFLDtbKfNW/XyNDZOH1IwU7TGjBlyNdV9
+inqHUNVywuym7gDvo+jFeuzFU28gb3ShEdRp0GhdGwTDAaOBjDCBiTAMBgNVHRMB
+Af8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNV
+HREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFJETCTrehOZugEx96Wz2Fookfry2
+MB8GA1UdIwQYMBaAFCqO3BXyHWlkOXeP7vRtPzTZhfCMMAoGCCqGSM49BAMCA0gA
+MEUCIDXnbB/6TAq/m+mt35Ext7JWCZgHH/Nf/fFxjkM2UqX0AiEAuXhlTbMlEWT3
+hSlwUoVkk83UjaFO/mbe0zXN5JDoLn8=
-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ b9:18:42:fe:df:e7:25:9c:ce:fa:d7:d0:e8:56:e3:d5:d3:20:96
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=SecurityTest CA Cert (RSA)
+ Validity
+ Not Before: May 26 01:21:39 2018 GMT
+ Not After : May 17 01:21:39 2055 GMT
+ Subject: OU=SecurityTests Client Cert (ECC), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:10:73:9e:25:d4:2a:14:b0:ed:6c:a7:cd:5b:f5:
+ f2:34:36:4e:1f:52:30:53:b4:c6:8c:19:72:35:d5:
+ 7d:8a:7a:87:50:d5:72:c2:ec:a6:ee:00:ef:a3:e8:
+ c5:7a:ec:c5:53:6f:20:6f:74:a1:11:d4:69:d0:68:
+ 5d:1b:04:c3:01
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature
+ X509v3 Extended Key Usage:
+ TLS Web Client Authentication
+ X509v3 Subject Key Identifier:
+ 91:13:09:3A:DE:84:E6:6E:80:4C:7D:E9:6C:F6:16:8A:24:7E:BC:B6
+ X509v3 Authority Key Identifier:
+ keyid:5D:A7:1B:3B:57:D2:0E:08:1E:AA:47:CF:03:34:68:BE:53:00:D9:64
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 49:e6:6c:0a:20:0f:cc:a2:7d:08:13:ae:f5:11:c5:9d:65:b0:
+ f1:b8:21:b3:88:de:98:b8:b7:44:9f:81:0c:30:e4:5e:56:33:
+ f8:6c:20:ab:45:62:8e:ad:49:e7:48:3a:1a:9f:8c:c3:b5:9c:
+ 3b:c6:ff:50:eb:3d:b1:7f:e9:9e:42:5c:27:ba:05:1e:7d:91:
+ b1:1b:df:13:6b:77:0e:79:a5:46:22:65:62:3d:69:0f:67:f6:
+ 5e:b1:1d:a3:e7:c2:d0:22:75:01:f5:c8:49:31:a2:c5:c6:4b:
+ 00:fd:24:d2:5e:6d:ce:e0:38:3e:ed:4b:02:d8:df:0e:f7:0b:
+ ab:c1:a9:4c:91:62:89:b3:48:39:a0:58:0c:e5:10:cb:4c:64:
+ 3b:87:46:cc:34:50:1e:64:3c:8d:91:5d:49:41:0b:4c:8f:00:
+ 57:e3:d7:ff:fc:b7:19:0a:5e:94:f7:9d:e2:38:9c:6d:e2:50:
+ cf:fd:78:4f:a0:52:34:67:fb:b8:0a:07:a4:36:31:66:d8:72:
+ 90:d0:b1:67:a1:b9:6e:15:b5:b2:69:8d:7b:5d:f9:dd:66:52:
+ 7f:e2:bc:30:0d:37:29:8e:7d:49:d6:f4:f9:e9:c5:f9:b8:90:
+ a2:61:63:71:a2:85:e2:db:69:d1:35:f2:2b:4c:cc:79:c0:87:
+ 00:d7:31:81
-----BEGIN CERTIFICATE-----
-MIICIzCCAQugAwIBAgICA+swDQYJKoZIhvcNAQEFBQAwJTEjMCEGA1UEAxMaU2Vj
-dXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTUwMzIzMDcxMDI2WhgPMjA1NTAz
-MTMwNzEwMjZaMD4xKDAmBgNVBAsTH1NlY3VyaXR5VGVzdHMgQ2xpZW50IENlcnQg
-KEVDQykxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEH
-A0IABBBzniXUKhSw7WynzVv18jQ2Th9SMFO0xowZcjXVfYp6h1DVcsLspu4A76Po
-xXrsxVNvIG90oRHUadBoXRsEwwGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEF
-BQADggEBAFLinyMi9q13pInfx9+O+ZRfv2VkAnU65f1wayo9TbCP7JaOZ1cZpjZd
-T6MvYt14erzZWQdywze4YBR6D0JRNztUCEdpv1CZIRtqwEJ+o2hHT5j/0OvKdjYk
-UTKwR+6NNbU6MwXsNpFw+o8nk0mxvhXpudSEE2see62nXBaIDN8+GvrI1Inmd7sa
-MPwlnQy7K6QWPvc6OLAMpnUO1n+0XqPJx9nf7nHFUBLS+QdPDn4XU4VbO88AYwG7
-aiAujteueK0ww3+H4bUmtQedQfABgkwtcH2gZXtESybHsr/PPoYbWTHE+cYCUgjQ
-92beynxqrGYyR0E+y37aOLbQQs3xwkE=
+MIICnTCCAYWgAwIBAgIUALkYQv7f5yWczvrX0OhW49XTIJYwDQYJKoZIhvcNAQEL
+BQAwJTEjMCEGA1UEAxMaU2VjdXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTgw
+NTI2MDEyMTM5WhgPMjA1NTA1MTcwMTIxMzlaMD4xKDAmBgNVBAsTH1NlY3VyaXR5
+VGVzdHMgQ2xpZW50IENlcnQgKEVDQykxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMG
+ByqGSM49AgEGCCqGSM49AwEHA0IABBBzniXUKhSw7WynzVv18jQ2Th9SMFO0xowZ
+cjXVfYp6h1DVcsLspu4A76PoxXrsxVNvIG90oRHUadBoXRsEwwGjdTBzMAwGA1Ud
+EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMB0G
+A1UdDgQWBBSREwk63oTmboBMfels9haKJH68tjAfBgNVHSMEGDAWgBRdpxs7V9IO
+CB6qR88DNGi+UwDZZDANBgkqhkiG9w0BAQsFAAOCAQEASeZsCiAPzKJ9CBOu9RHF
+nWWw8bghs4jemLi3RJ+BDDDkXlYz+Gwgq0Vijq1J50g6Gp+Mw7WcO8b/UOs9sX/p
+nkJcJ7oFHn2RsRvfE2t3DnmlRiJlYj1pD2f2XrEdo+fC0CJ1AfXISTGixcZLAP0k
+0l5tzuA4Pu1LAtjfDvcLq8GpTJFiibNIOaBYDOUQy0xkO4dGzDRQHmQ8jZFdSUEL
+TI8AV+PX//y3GQpelPed4jicbeJQz/14T6BSNGf7uAoHpDYxZthykNCxZ6G5bhW1
+smmNe1353WZSf+K8MA03KY59Sdb0+enF+biQomFjcaKF4ttp0TXyK0zMecCHANcx
+gQ==
-----END CERTIFICATE-----
unsigned char ClientECC_Cert_CA_ECC_der[] = {
- 0x30, 0x82, 0x01, 0x61, 0x30, 0x82, 0x01, 0x07, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x02, 0x03, 0xec, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48,
- 0xce, 0x3d, 0x04, 0x01, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
- 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72,
- 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31,
- 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a,
- 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, 0x33, 0x30, 0x37,
- 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
- 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43,
- 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09,
- 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, 0x30,
- 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08,
- 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04,
- 0x10, 0x73, 0x9e, 0x25, 0xd4, 0x2a, 0x14, 0xb0, 0xed, 0x6c, 0xa7, 0xcd,
- 0x5b, 0xf5, 0xf2, 0x34, 0x36, 0x4e, 0x1f, 0x52, 0x30, 0x53, 0xb4, 0xc6,
- 0x8c, 0x19, 0x72, 0x35, 0xd5, 0x7d, 0x8a, 0x7a, 0x87, 0x50, 0xd5, 0x72,
- 0xc2, 0xec, 0xa6, 0xee, 0x00, 0xef, 0xa3, 0xe8, 0xc5, 0x7a, 0xec, 0xc5,
- 0x53, 0x6f, 0x20, 0x6f, 0x74, 0xa1, 0x11, 0xd4, 0x69, 0xd0, 0x68, 0x5d,
- 0x1b, 0x04, 0xc3, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a,
- 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02,
- 0x21, 0x00, 0xf1, 0x66, 0xca, 0xf5, 0x33, 0xe2, 0x17, 0x54, 0x99, 0x83,
- 0x48, 0x6c, 0x65, 0x5f, 0xfa, 0x4a, 0x14, 0x35, 0x1d, 0x35, 0x69, 0x9e,
- 0xe2, 0x14, 0x5c, 0xf0, 0x77, 0xa8, 0xdb, 0xa6, 0x11, 0xa2, 0x02, 0x21,
- 0x00, 0xdf, 0x49, 0xc3, 0x67, 0xec, 0x01, 0xba, 0xbf, 0x16, 0x09, 0x75,
- 0x75, 0xff, 0x2c, 0x4a, 0x4e, 0x43, 0x96, 0x43, 0x80, 0x8e, 0x7a, 0xad,
- 0x2f, 0x76, 0x0c, 0x86, 0x41, 0xbe, 0x9a, 0x28, 0x99
+ 0x30, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0x99, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x13, 0x2c, 0x10, 0x5b, 0x40, 0x8c, 0xb3, 0x1f, 0x3c, 0xc8,
+ 0x37, 0xae, 0x60, 0xbe, 0x7e, 0x23, 0xeb, 0x1a, 0x79, 0x96, 0x30, 0x0a,
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25,
+ 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20,
+ 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43,
+ 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x32, 0x36, 0x30,
+ 0x31, 0x32, 0x35, 0x33, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35,
+ 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x35, 0x33, 0x33, 0x5a, 0x30,
+ 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74,
+ 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72,
+ 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
+ 0x6f, 0x73, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48,
+ 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
+ 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x10, 0x73, 0x9e, 0x25, 0xd4, 0x2a,
+ 0x14, 0xb0, 0xed, 0x6c, 0xa7, 0xcd, 0x5b, 0xf5, 0xf2, 0x34, 0x36, 0x4e,
+ 0x1f, 0x52, 0x30, 0x53, 0xb4, 0xc6, 0x8c, 0x19, 0x72, 0x35, 0xd5, 0x7d,
+ 0x8a, 0x7a, 0x87, 0x50, 0xd5, 0x72, 0xc2, 0xec, 0xa6, 0xee, 0x00, 0xef,
+ 0xa3, 0xe8, 0xc5, 0x7a, 0xec, 0xc5, 0x53, 0x6f, 0x20, 0x6f, 0x74, 0xa1,
+ 0x11, 0xd4, 0x69, 0xd0, 0x68, 0x5d, 0x1b, 0x04, 0xc3, 0x01, 0xa3, 0x81,
+ 0x8c, 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+ 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13,
+ 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55,
+ 0x1d, 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61,
+ 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+ 0x04, 0x16, 0x04, 0x14, 0x91, 0x13, 0x09, 0x3a, 0xde, 0x84, 0xe6, 0x6e,
+ 0x80, 0x4c, 0x7d, 0xe9, 0x6c, 0xf6, 0x16, 0x8a, 0x24, 0x7e, 0xbc, 0xb6,
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+ 0x14, 0x2a, 0x8e, 0xdc, 0x15, 0xf2, 0x1d, 0x69, 0x64, 0x39, 0x77, 0x8f,
+ 0xee, 0xf4, 0x6d, 0x3f, 0x34, 0xd9, 0x85, 0xf0, 0x8c, 0x30, 0x0a, 0x06,
+ 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00,
+ 0x30, 0x45, 0x02, 0x20, 0x35, 0xe7, 0x6c, 0x1f, 0xfa, 0x4c, 0x0a, 0xbf,
+ 0x9b, 0xe9, 0xad, 0xdf, 0x91, 0x31, 0xb7, 0xb2, 0x56, 0x09, 0x98, 0x07,
+ 0x1f, 0xf3, 0x5f, 0xfd, 0xf1, 0x71, 0x8e, 0x43, 0x36, 0x52, 0xa5, 0xf4,
+ 0x02, 0x21, 0x00, 0xb9, 0x78, 0x65, 0x4d, 0xb3, 0x25, 0x11, 0x64, 0xf7,
+ 0x85, 0x29, 0x70, 0x52, 0x85, 0x64, 0x93, 0xcd, 0xd4, 0x8d, 0xa1, 0x4e,
+ 0xfe, 0x66, 0xde, 0xd3, 0x35, 0xcd, 0xe4, 0x90, 0xe8, 0x2e, 0x7f
};
-unsigned int ClientECC_Cert_CA_ECC_der_len = 357;
+unsigned int ClientECC_Cert_CA_ECC_der_len = 503;
unsigned char ClientECC_Cert_CA_RSA_der[] = {
- 0x30, 0x82, 0x02, 0x23, 0x30, 0x82, 0x01, 0x0b, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x02, 0x03, 0xeb, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23,
- 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41,
- 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30,
- 0x20, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31,
- 0x30, 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33,
- 0x31, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31,
- 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65,
- 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20,
- 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
- 0x28, 0x45, 0x43, 0x43, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
- 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
- 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
- 0x03, 0x42, 0x00, 0x04, 0x10, 0x73, 0x9e, 0x25, 0xd4, 0x2a, 0x14, 0xb0,
- 0xed, 0x6c, 0xa7, 0xcd, 0x5b, 0xf5, 0xf2, 0x34, 0x36, 0x4e, 0x1f, 0x52,
- 0x30, 0x53, 0xb4, 0xc6, 0x8c, 0x19, 0x72, 0x35, 0xd5, 0x7d, 0x8a, 0x7a,
- 0x87, 0x50, 0xd5, 0x72, 0xc2, 0xec, 0xa6, 0xee, 0x00, 0xef, 0xa3, 0xe8,
- 0xc5, 0x7a, 0xec, 0xc5, 0x53, 0x6f, 0x20, 0x6f, 0x74, 0xa1, 0x11, 0xd4,
- 0x69, 0xd0, 0x68, 0x5d, 0x1b, 0x04, 0xc3, 0x01, 0xa3, 0x0d, 0x30, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x52, 0xe2, 0x9f, 0x23, 0x22,
- 0xf6, 0xad, 0x77, 0xa4, 0x89, 0xdf, 0xc7, 0xdf, 0x8e, 0xf9, 0x94, 0x5f,
- 0xbf, 0x65, 0x64, 0x02, 0x75, 0x3a, 0xe5, 0xfd, 0x70, 0x6b, 0x2a, 0x3d,
- 0x4d, 0xb0, 0x8f, 0xec, 0x96, 0x8e, 0x67, 0x57, 0x19, 0xa6, 0x36, 0x5d,
- 0x4f, 0xa3, 0x2f, 0x62, 0xdd, 0x78, 0x7a, 0xbc, 0xd9, 0x59, 0x07, 0x72,
- 0xc3, 0x37, 0xb8, 0x60, 0x14, 0x7a, 0x0f, 0x42, 0x51, 0x37, 0x3b, 0x54,
- 0x08, 0x47, 0x69, 0xbf, 0x50, 0x99, 0x21, 0x1b, 0x6a, 0xc0, 0x42, 0x7e,
- 0xa3, 0x68, 0x47, 0x4f, 0x98, 0xff, 0xd0, 0xeb, 0xca, 0x76, 0x36, 0x24,
- 0x51, 0x32, 0xb0, 0x47, 0xee, 0x8d, 0x35, 0xb5, 0x3a, 0x33, 0x05, 0xec,
- 0x36, 0x91, 0x70, 0xfa, 0x8f, 0x27, 0x93, 0x49, 0xb1, 0xbe, 0x15, 0xe9,
- 0xb9, 0xd4, 0x84, 0x13, 0x6b, 0x1e, 0x7b, 0xad, 0xa7, 0x5c, 0x16, 0x88,
- 0x0c, 0xdf, 0x3e, 0x1a, 0xfa, 0xc8, 0xd4, 0x89, 0xe6, 0x77, 0xbb, 0x1a,
- 0x30, 0xfc, 0x25, 0x9d, 0x0c, 0xbb, 0x2b, 0xa4, 0x16, 0x3e, 0xf7, 0x3a,
- 0x38, 0xb0, 0x0c, 0xa6, 0x75, 0x0e, 0xd6, 0x7f, 0xb4, 0x5e, 0xa3, 0xc9,
- 0xc7, 0xd9, 0xdf, 0xee, 0x71, 0xc5, 0x50, 0x12, 0xd2, 0xf9, 0x07, 0x4f,
- 0x0e, 0x7e, 0x17, 0x53, 0x85, 0x5b, 0x3b, 0xcf, 0x00, 0x63, 0x01, 0xbb,
- 0x6a, 0x20, 0x2e, 0x8e, 0xd7, 0xae, 0x78, 0xad, 0x30, 0xc3, 0x7f, 0x87,
- 0xe1, 0xb5, 0x26, 0xb5, 0x07, 0x9d, 0x41, 0xf0, 0x01, 0x82, 0x4c, 0x2d,
- 0x70, 0x7d, 0xa0, 0x65, 0x7b, 0x44, 0x4b, 0x26, 0xc7, 0xb2, 0xbf, 0xcf,
- 0x3e, 0x86, 0x1b, 0x59, 0x31, 0xc4, 0xf9, 0xc6, 0x02, 0x52, 0x08, 0xd0,
- 0xf7, 0x66, 0xde, 0xca, 0x7c, 0x6a, 0xac, 0x66, 0x32, 0x47, 0x41, 0x3e,
- 0xcb, 0x7e, 0xda, 0x38, 0xb6, 0xd0, 0x42, 0xcd, 0xf1, 0xc2, 0x41
+ 0x30, 0x82, 0x02, 0x9d, 0x30, 0x82, 0x01, 0x85, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x14, 0x00, 0xb9, 0x18, 0x42, 0xfe, 0xdf, 0xe7, 0x25, 0x9c,
+ 0xce, 0xfa, 0xd7, 0xd0, 0xe8, 0x56, 0xe3, 0xd5, 0xd3, 0x20, 0x96, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54,
+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
+ 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30,
+ 0x35, 0x32, 0x36, 0x30, 0x31, 0x32, 0x31, 0x33, 0x39, 0x5a, 0x18, 0x0f,
+ 0x32, 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x31,
+ 0x33, 0x39, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+ 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x31,
+ 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f,
+ 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06,
+ 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86,
+ 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x10, 0x73,
+ 0x9e, 0x25, 0xd4, 0x2a, 0x14, 0xb0, 0xed, 0x6c, 0xa7, 0xcd, 0x5b, 0xf5,
+ 0xf2, 0x34, 0x36, 0x4e, 0x1f, 0x52, 0x30, 0x53, 0xb4, 0xc6, 0x8c, 0x19,
+ 0x72, 0x35, 0xd5, 0x7d, 0x8a, 0x7a, 0x87, 0x50, 0xd5, 0x72, 0xc2, 0xec,
+ 0xa6, 0xee, 0x00, 0xef, 0xa3, 0xe8, 0xc5, 0x7a, 0xec, 0xc5, 0x53, 0x6f,
+ 0x20, 0x6f, 0x74, 0xa1, 0x11, 0xd4, 0x69, 0xd0, 0x68, 0x5d, 0x1b, 0x04,
+ 0xc3, 0x01, 0xa3, 0x75, 0x30, 0x73, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
+ 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06,
+ 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x91, 0x13, 0x09, 0x3a,
+ 0xde, 0x84, 0xe6, 0x6e, 0x80, 0x4c, 0x7d, 0xe9, 0x6c, 0xf6, 0x16, 0x8a,
+ 0x24, 0x7e, 0xbc, 0xb6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0x5d, 0xa7, 0x1b, 0x3b, 0x57, 0xd2, 0x0e,
+ 0x08, 0x1e, 0xaa, 0x47, 0xcf, 0x03, 0x34, 0x68, 0xbe, 0x53, 0x00, 0xd9,
+ 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x49, 0xe6, 0x6c,
+ 0x0a, 0x20, 0x0f, 0xcc, 0xa2, 0x7d, 0x08, 0x13, 0xae, 0xf5, 0x11, 0xc5,
+ 0x9d, 0x65, 0xb0, 0xf1, 0xb8, 0x21, 0xb3, 0x88, 0xde, 0x98, 0xb8, 0xb7,
+ 0x44, 0x9f, 0x81, 0x0c, 0x30, 0xe4, 0x5e, 0x56, 0x33, 0xf8, 0x6c, 0x20,
+ 0xab, 0x45, 0x62, 0x8e, 0xad, 0x49, 0xe7, 0x48, 0x3a, 0x1a, 0x9f, 0x8c,
+ 0xc3, 0xb5, 0x9c, 0x3b, 0xc6, 0xff, 0x50, 0xeb, 0x3d, 0xb1, 0x7f, 0xe9,
+ 0x9e, 0x42, 0x5c, 0x27, 0xba, 0x05, 0x1e, 0x7d, 0x91, 0xb1, 0x1b, 0xdf,
+ 0x13, 0x6b, 0x77, 0x0e, 0x79, 0xa5, 0x46, 0x22, 0x65, 0x62, 0x3d, 0x69,
+ 0x0f, 0x67, 0xf6, 0x5e, 0xb1, 0x1d, 0xa3, 0xe7, 0xc2, 0xd0, 0x22, 0x75,
+ 0x01, 0xf5, 0xc8, 0x49, 0x31, 0xa2, 0xc5, 0xc6, 0x4b, 0x00, 0xfd, 0x24,
+ 0xd2, 0x5e, 0x6d, 0xce, 0xe0, 0x38, 0x3e, 0xed, 0x4b, 0x02, 0xd8, 0xdf,
+ 0x0e, 0xf7, 0x0b, 0xab, 0xc1, 0xa9, 0x4c, 0x91, 0x62, 0x89, 0xb3, 0x48,
+ 0x39, 0xa0, 0x58, 0x0c, 0xe5, 0x10, 0xcb, 0x4c, 0x64, 0x3b, 0x87, 0x46,
+ 0xcc, 0x34, 0x50, 0x1e, 0x64, 0x3c, 0x8d, 0x91, 0x5d, 0x49, 0x41, 0x0b,
+ 0x4c, 0x8f, 0x00, 0x57, 0xe3, 0xd7, 0xff, 0xfc, 0xb7, 0x19, 0x0a, 0x5e,
+ 0x94, 0xf7, 0x9d, 0xe2, 0x38, 0x9c, 0x6d, 0xe2, 0x50, 0xcf, 0xfd, 0x78,
+ 0x4f, 0xa0, 0x52, 0x34, 0x67, 0xfb, 0xb8, 0x0a, 0x07, 0xa4, 0x36, 0x31,
+ 0x66, 0xd8, 0x72, 0x90, 0xd0, 0xb1, 0x67, 0xa1, 0xb9, 0x6e, 0x15, 0xb5,
+ 0xb2, 0x69, 0x8d, 0x7b, 0x5d, 0xf9, 0xdd, 0x66, 0x52, 0x7f, 0xe2, 0xbc,
+ 0x30, 0x0d, 0x37, 0x29, 0x8e, 0x7d, 0x49, 0xd6, 0xf4, 0xf9, 0xe9, 0xc5,
+ 0xf9, 0xb8, 0x90, 0xa2, 0x61, 0x63, 0x71, 0xa2, 0x85, 0xe2, 0xdb, 0x69,
+ 0xd1, 0x35, 0xf2, 0x2b, 0x4c, 0xcc, 0x79, 0xc0, 0x87, 0x00, 0xd7, 0x31,
+ 0x81
};
-unsigned int ClientECC_Cert_CA_RSA_der_len = 551;
+unsigned int ClientECC_Cert_CA_RSA_der_len = 673;
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 2c:10:5b:40:8c:b3:1f:3c:c8:37:ae:60:be:7e:23:eb:1a:79:97
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: CN=SecurityTest CA Cert (ECC)
+ Validity
+ Not Before: May 26 01:25:40 2018 GMT
+ Not After : May 17 01:25:40 2055 GMT
+ Subject: OU=SecurityTests Client Cert (RSA), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a7:97:26:3d:78:29:db:d8:11:c9:b2:f6:be:36:
+ a3:e5:f1:a4:b3:ee:87:cd:bf:ba:b3:74:38:2a:de:
+ 22:4c:a0:3e:cb:2a:bb:dd:8a:07:b9:f6:70:6d:6f:
+ 27:09:4b:dd:f3:68:d4:93:5b:bf:40:4c:50:27:ad:
+ a7:8e:15:36:1b:f2:63:4e:50:69:c3:ba:f6:62:b3:
+ e7:69:1c:6a:f8:29:4a:8c:06:e3:87:58:8d:20:c5:
+ 5c:d1:6d:68:b2:50:da:1a:e5:11:dc:6a:26:92:c5:
+ 41:50:c6:d1:dc:7e:a1:87:27:7a:fb:0c:d8:fa:9e:
+ b5:33:55:e6:73:26:40:d8:7a:4b:7b:54:ed:4d:1d:
+ 3d:71:ad:e5:06:49:c2:60:3a:d9:16:32:20:b4:6f:
+ c8:44:5a:c3:93:04:99:92:ae:4a:68:91:1d:20:c1:
+ 68:4e:22:62:a9:c8:75:c9:92:21:e7:3d:72:41:e2:
+ 9f:c1:f8:2f:e3:55:12:cd:f0:c1:db:ac:4b:e6:7d:
+ b2:ac:0b:fe:e1:f7:e0:3f:89:97:75:0c:51:b5:5a:
+ 0c:06:12:3e:67:8f:7b:3c:8e:4d:af:c1:75:7b:94:
+ bf:38:ce:8c:70:bd:a9:a0:9d:ea:3f:37:5e:35:a0:
+ 1c:6c:9d:cd:a9:b4:b0:fa:13:af:39:ff:14:9e:e1:
+ 0b:b3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Subject Alternative Name:
+ DNS:localhost
+ X509v3 Subject Key Identifier:
+ EA:37:FA:FD:51:69:13:98:CF:A1:47:05:8B:A3:FA:C4:7D:D1:AB:8C
+ X509v3 Authority Key Identifier:
+ keyid:2A:8E:DC:15:F2:1D:69:64:39:77:8F:EE:F4:6D:3F:34:D9:85:F0:8C
+
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:45:02:21:00:c2:ae:7d:05:21:72:fc:2a:ff:82:a2:8f:a7:
+ b0:8d:9c:e1:cf:a4:8c:c9:7e:cc:25:65:be:cc:76:82:67:2f:
+ 32:02:20:48:c5:93:ad:61:3e:32:8b:56:a6:ea:c4:59:df:63:
+ 9d:ea:fa:49:01:b5:3a:2b:17:57:a9:c6:e0:57:de:45:67
-----BEGIN CERTIFICATE-----
-MIIBpjCCAU6gAwIBAgICA+owCQYHKoZIzj0EATAlMSMwIQYDVQQDExpTZWN1cml0
-eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xNTAzMjMwNzEwMjZaGA8yMDU1MDMxMzA3
-MTAyNlowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0cyBDbGllbnQgQ2VydCAoUlNB
-KTESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQDAISkTabv/uwVt0fApWaJiW+urOqQmOBaiMw7k4KXxBugp8gNKdbmHpWUbtEZo
-z2ZsEfI3XTHCGMHN5H0dY+NcopMD1hWjWz7Uybq1cW/oiUk2uvjKghpKZ8aTZw18
-ymdM32Vl2Vkd4ago9NvqmtzopDfbjSQ0UJohIuJA2qRD0QIDAQABow0wCzAJBgNV
-HRMEAjAAMAkGByqGSM49BAEDRwAwRAIgHt1NxrjKxZ3biHvouJvvOBmeA0qv0+xK
-8JVr49cx4hcCIHAW6dR4/LYm1rGbN00RjpYTjT3SxS1rKmLoruu0mCuo
+MIICvjCCAmSgAwIBAgITLBBbQIyzHzzIN65gvn4j6xp5lzAKBggqhkjOPQQDAjAl
+MSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xODA1MjYw
+MTI1NDBaGA8yMDU1MDUxNzAxMjU0MFowPjEoMCYGA1UECwwfU2VjdXJpdHlUZXN0
+cyBDbGllbnQgQ2VydCAoUlNBKTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp5cmPXgp29gRybL2vjaj5fGks+6Hzb+6
+s3Q4Kt4iTKA+yyq73YoHufZwbW8nCUvd82jUk1u/QExQJ62njhU2G/JjTlBpw7r2
+YrPnaRxq+ClKjAbjh1iNIMVc0W1oslDaGuUR3GomksVBUMbR3H6hhyd6+wzY+p61
+M1XmcyZA2HpLe1TtTR09ca3lBknCYDrZFjIgtG/IRFrDkwSZkq5KaJEdIMFoTiJi
+qch1yZIh5z1yQeKfwfgv41USzfDB26xL5n2yrAv+4ffgP4mXdQxRtVoMBhI+Z497
+PI5Nr8F1e5S/OM6McL2poJ3qPzdeNaAcbJ3NqbSw+hOvOf8UnuELswIDAQABo4GM
+MIGJMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG
+AQUFBwMBMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNVHQ4EFgQU6jf6/VFpE5jP
+oUcFi6P6xH3Rq4wwHwYDVR0jBBgwFoAUKo7cFfIdaWQ5d4/u9G0/NNmF8IwwCgYI
+KoZIzj0EAwIDSAAwRQIhAMKufQUhcvwq/4Kij6ewjZzhz6SMyX7MJWW+zHaCZy8y
+AiBIxZOtYT4yi1am6sRZ32Od6vpJAbU6KxdXqcbgV95FZw==
-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ b9:18:42:fe:df:e7:25:9c:ce:fa:d7:d0:e8:56:e3:d5:d3:20:95
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=SecurityTest CA Cert (RSA)
+ Validity
+ Not Before: May 26 01:14:45 2018 GMT
+ Not After : May 17 01:14:45 2055 GMT
+ Subject: OU=SecurityTests Client Cert (RSA), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a7:97:26:3d:78:29:db:d8:11:c9:b2:f6:be:36:
+ a3:e5:f1:a4:b3:ee:87:cd:bf:ba:b3:74:38:2a:de:
+ 22:4c:a0:3e:cb:2a:bb:dd:8a:07:b9:f6:70:6d:6f:
+ 27:09:4b:dd:f3:68:d4:93:5b:bf:40:4c:50:27:ad:
+ a7:8e:15:36:1b:f2:63:4e:50:69:c3:ba:f6:62:b3:
+ e7:69:1c:6a:f8:29:4a:8c:06:e3:87:58:8d:20:c5:
+ 5c:d1:6d:68:b2:50:da:1a:e5:11:dc:6a:26:92:c5:
+ 41:50:c6:d1:dc:7e:a1:87:27:7a:fb:0c:d8:fa:9e:
+ b5:33:55:e6:73:26:40:d8:7a:4b:7b:54:ed:4d:1d:
+ 3d:71:ad:e5:06:49:c2:60:3a:d9:16:32:20:b4:6f:
+ c8:44:5a:c3:93:04:99:92:ae:4a:68:91:1d:20:c1:
+ 68:4e:22:62:a9:c8:75:c9:92:21:e7:3d:72:41:e2:
+ 9f:c1:f8:2f:e3:55:12:cd:f0:c1:db:ac:4b:e6:7d:
+ b2:ac:0b:fe:e1:f7:e0:3f:89:97:75:0c:51:b5:5a:
+ 0c:06:12:3e:67:8f:7b:3c:8e:4d:af:c1:75:7b:94:
+ bf:38:ce:8c:70:bd:a9:a0:9d:ea:3f:37:5e:35:a0:
+ 1c:6c:9d:cd:a9:b4:b0:fa:13:af:39:ff:14:9e:e1:
+ 0b:b3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature
+ X509v3 Extended Key Usage:
+ TLS Web Client Authentication
+ X509v3 Subject Key Identifier:
+ EA:37:FA:FD:51:69:13:98:CF:A1:47:05:8B:A3:FA:C4:7D:D1:AB:8C
+ X509v3 Authority Key Identifier:
+ keyid:5D:A7:1B:3B:57:D2:0E:08:1E:AA:47:CF:03:34:68:BE:53:00:D9:64
+
+ Signature Algorithm: sha256WithRSAEncryption
+ b2:6a:95:8d:f8:09:c6:27:8a:bb:61:8a:a7:93:4d:d1:81:36:
+ d8:2e:33:97:71:0a:36:26:2d:4f:3e:4d:89:78:67:a6:f8:79:
+ 40:be:ea:eb:64:9c:63:11:9a:f8:bd:e4:fb:e7:5a:91:39:a0:
+ 41:76:81:29:cd:92:7e:bc:02:3b:5d:40:fe:af:12:50:fb:6e:
+ 19:49:67:f2:1c:21:8d:4a:06:52:0d:fa:81:a9:6d:57:cf:c8:
+ f0:52:99:44:a7:37:b2:80:c8:a9:90:60:89:35:47:1e:f1:ed:
+ 02:c0:68:2b:27:74:17:c8:55:b9:02:8c:f4:4d:bc:94:90:0a:
+ 45:34:f7:43:01:3c:b1:4b:d3:59:6c:cc:64:2e:de:8e:14:d0:
+ bc:cb:11:d0:43:95:7d:56:5c:51:27:6f:4c:bb:c3:3b:7d:c9:
+ 95:09:60:5b:05:6a:9c:61:16:ab:28:d2:09:c3:4a:7d:ba:3e:
+ 52:e9:fa:18:c1:0c:88:83:bc:6e:7c:08:48:99:76:ea:08:8d:
+ a9:5a:4b:31:b6:84:f7:fd:73:28:d6:fb:5e:99:6f:d7:22:5f:
+ ad:0c:9b:f0:91:c7:d5:37:d1:21:11:0f:14:88:ea:4d:14:39:
+ d0:92:4d:96:10:42:d7:5f:e2:d9:84:96:ce:bf:ab:3f:d0:2f:
+ 8b:9b:75:77
-----BEGIN CERTIFICATE-----
-MIICajCCAVKgAwIBAgICA+kwDQYJKoZIhvcNAQEFBQAwJTEjMCEGA1UEAxMaU2Vj
-dXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTUwMzIzMDcxMDI2WhgPMjA1NTAz
-MTMwNzEwMjZaMD4xKDAmBgNVBAsTH1NlY3VyaXR5VGVzdHMgQ2xpZW50IENlcnQg
-KFJTQSkxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAwCEpE2m7/7sFbdHwKVmiYlvrqzqkJjgWojMO5OCl8QboKfIDSnW5h6Vl
-G7RGaM9mbBHyN10xwhjBzeR9HWPjXKKTA9YVo1s+1Mm6tXFv6IlJNrr4yoIaSmfG
-k2cNfMpnTN9lZdlZHeGoKPTb6prc6KQ3240kNFCaISLiQNqkQ9ECAwEAAaMNMAsw
-CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAl08VXo+EJYViCUaOHQ8+KUaH
-yJW9z46PmZwWR29DBxQZmYC2NTm6KdHlhBhn1g8GFWLKIBkw5JBXLRgwIAkDCn7Q
-+ba9EGmeAHFAipxEwqTQcP1DMr9PzMbKShay0AsJ3rmKZbqFwROUkh8NyeBfJdQo
-8JLJ2oxvQOZON0akRTuT2m4BwtXhQUiaFiZibaNumXvqzra6RL2dGBRVpN2wh1R8
-bO9p7hdsdFjyRgJu8OdB6mLcERqqjla5ewgAGO1r6TgpzOGcvWFXlqIrpYEJ0xJ3
-sDvYtYPenkHsPy2ZZWpOUMrbwlrqEe1hFkmj2QZoIxPBJuyyz135JsGvZwxL5g==
+MIIDaDCCAlCgAwIBAgIUALkYQv7f5yWczvrX0OhW49XTIJUwDQYJKoZIhvcNAQEL
+BQAwJTEjMCEGA1UEAxMaU2VjdXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTgw
+NTI2MDExNDQ1WhgPMjA1NTA1MTcwMTE0NDVaMD4xKDAmBgNVBAsMH1NlY3VyaXR5
+VGVzdHMgQ2xpZW50IENlcnQgKFJTQSkxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeXJj14KdvYEcmy9r42o+XxpLPu
+h82/urN0OCreIkygPssqu92KB7n2cG1vJwlL3fNo1JNbv0BMUCetp44VNhvyY05Q
+acO69mKz52kcavgpSowG44dYjSDFXNFtaLJQ2hrlEdxqJpLFQVDG0dx+oYcnevsM
+2PqetTNV5nMmQNh6S3tU7U0dPXGt5QZJwmA62RYyILRvyERaw5MEmZKuSmiRHSDB
+aE4iYqnIdcmSIec9ckHin8H4L+NVEs3wwdusS+Z9sqwL/uH34D+Jl3UMUbVaDAYS
+PmePezyOTa/BdXuUvzjOjHC9qaCd6j83XjWgHGydzam0sPoTrzn/FJ7hC7MCAwEA
+AaN1MHMwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
+KwYBBQUHAwIwHQYDVR0OBBYEFOo3+v1RaROYz6FHBYuj+sR90auMMB8GA1UdIwQY
+MBaAFF2nGztX0g4IHqpHzwM0aL5TANlkMA0GCSqGSIb3DQEBCwUAA4IBAQCyapWN
++AnGJ4q7YYqnk03RgTbYLjOXcQo2Ji1PPk2JeGem+HlAvurrZJxjEZr4veT751qR
+OaBBdoEpzZJ+vAI7XUD+rxJQ+24ZSWfyHCGNSgZSDfqBqW1Xz8jwUplEpzeygMip
+kGCJNUce8e0CwGgrJ3QXyFW5Aoz0TbyUkApFNPdDATyxS9NZbMxkLt6OFNC8yxHQ
+Q5V9VlxRJ29Mu8M7fcmVCWBbBWqcYRarKNIJw0p9uj5S6foYwQyIg7xufAhImXbq
+CI2pWksxtoT3/XMo1vtemW/XIl+tDJvwkcfVN9EhEQ8UiOpNFDnQkk2WEELXX+LZ
+hJbOv6s/0C+Lm3V3
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQDAISkTabv/uwVt0fApWaJiW+urOqQmOBaiMw7k4KXxBugp8gNK
-dbmHpWUbtEZoz2ZsEfI3XTHCGMHN5H0dY+NcopMD1hWjWz7Uybq1cW/oiUk2uvjK
-ghpKZ8aTZw18ymdM32Vl2Vkd4ago9NvqmtzopDfbjSQ0UJohIuJA2qRD0QIDAQAB
-AoGAEsbq4cfSpNKdXDdJVnE5Ko27QZfQlR+kLqP4z6uY7C51oCvT4IIS6MvkTsnW
-m8WxR9yVJI4KH+MVhc7P34B0ptyblKObQ0n1DP6jrjA1X8nhvaLFW5pMz640nMyk
-dMs8qaVYdfNwcvKBzshvYFFF6umdhkOA3ZO5IuBuAsyJZjECQQDrV60K8iWo1V0k
-zzkY9/2VEAZbn44hnFs70rnOKTfJfxRIyoNqCNe2Lsg0lVtWO/7++IolxWBD7k8Y
-WBP2IG89AkEA0P507CghrhTvcWnBBDEX3mEY2bF40sk8eHsk42IdIIEQ+ppF68zh
-nDIkWTrRlx1eNo5ryDWoQpm7CVhdeQfwJQJAUffFk2xnZXh66pkqP+IP9l0QedUG
-wfodZKauhHmirpGOVRQD1WijCRceMAJdP5nB5LhYFXO7Za2Y6teyjCUb2QJALqrD
-HQCRFLgkB2Uf7nmv5L41uFaCrj61PAnzYLrF2j43tl3AgzjKoAAqUapqpp2uLex7
-cMdafRSqyRlsNdxp6QJAH9R89iqTolQ4y9H3FhKY8iv82vYLOcrv1VBmGso/CJSm
-CG2uPS2L3l8BWnkqnO+nuu23r54WDOOx6lWQiyiT0g==
+MIIEowIBAAKCAQEAp5cmPXgp29gRybL2vjaj5fGks+6Hzb+6s3Q4Kt4iTKA+yyq7
+3YoHufZwbW8nCUvd82jUk1u/QExQJ62njhU2G/JjTlBpw7r2YrPnaRxq+ClKjAbj
+h1iNIMVc0W1oslDaGuUR3GomksVBUMbR3H6hhyd6+wzY+p61M1XmcyZA2HpLe1Tt
+TR09ca3lBknCYDrZFjIgtG/IRFrDkwSZkq5KaJEdIMFoTiJiqch1yZIh5z1yQeKf
+wfgv41USzfDB26xL5n2yrAv+4ffgP4mXdQxRtVoMBhI+Z497PI5Nr8F1e5S/OM6M
+cL2poJ3qPzdeNaAcbJ3NqbSw+hOvOf8UnuELswIDAQABAoIBADQdkMq0v2+aNY3f
+lVN5cmZjSrCZkKmu4cREc+MAyPHDM0PCukEeV2DA/h1J333IlfDHvLNGaKb6FEMC
+gYRxnC38pl0ILJutXEk9YM0TBUC+tmvtCHxiUSDLvx1xRImPEwQiD/fXGr+xj6oq
+6cADsP9yi4/eYussx3R7Vfqg/rFSdZRkpT5E7N5K+zIHAKnR5nNuSTWPS4iIGBXU
+tQClgFPMLTh8htknERAr0d3BtM9b4khSPZ1rbG6bMoY3uni+DrWk01D9BSjY6CL3
+ZG6+vW/R2ExUuBF/7pH3DLPNEGSlSXPXwRJfH02TyDpcXM4pyOFB3JXh8EExSFx4
+T18cdWECgYEA1wfLhb5Bykth5Irz1Oy1mA20nbku9TPaMNkDMgRUeXG5vUxNx9Q4
+sbTz3HuHhATMYDSIux1hUZZDJJg1pIG7JRXJCIf2E6cAJloarQdV+0tUK1PiOdHT
+HGy0mP49Hy9g2b30OkxIhasjxTwTuiz3A3p1Sbge7CUjkFdV4y1FAL8CgYEAx4Vy
+RWejfMGba8sMIjLSlAWRGWr+Fb4BCvCDAHxhvif5lCCATAr/UbNmYp49B+OJ0iMz
+iBhkTFzzxOP0FY6xZa0JkTJNAtJ7TmxMNClwcapLt55HE1REIeQHWGg8r0+ZKiat
+PUOOmARPnUXOr7WSjJ9rhQCGxNe7fofPFIJ+fg0CgYAm4JDqgGiSs6hiUsEdCSMX
+97plHdsgmBxl4oaSX3gKcQZc9FPHwlXxwz6n6Wmp89gjuLvT4M78mkdPcXmZYZ89
+aD/tm+9gxDvhsz7Jc98WzRrNrp/jRk1+ASVx192jKsS++XoTpEEkcbnI6kDC02hh
+p51XE8P7fAd/DFtJ9KBaLwKBgQCIqEZUc1/vG0yw0CpHYjgJWqa/miDeE33zWDji
+JE9uR0MSyhAWBZJLC22dLnTu6lKDs8if9tT72M6+lMOh4FJxKcvbv3Av9qquVE79
+i0SRFes2oRpdiuH/tIezbfHiwcpOrJ8LzzHjvVAqkJ24i80MtESYnHuyZ3DsgWi8
+y4SIIQKBgC1CmnmYij3H7S+rQC8mw/bHeY0EbHGSu2sv3lvm/1HAY9zQ5BKTTft+
+JxSYggMLBbfQerANvJ68+unOBRT64aonLY7S4/64dFCpnBai5HlTKrcy5K4yprpd
+ht0cZrEYr8X+RLn75VpaHkVKi+w8fe3AAlOlsVzb9iWg6+4WhHne
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
-MIIBfTCB5wIBADA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIENsaWVudCBDZXJ0
-IChSU0EpMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
-MIGJAoGBAMAhKRNpu/+7BW3R8ClZomJb66s6pCY4FqIzDuTgpfEG6CnyA0p1uYel
-ZRu0RmjPZmwR8jddMcIYwc3kfR1j41yikwPWFaNbPtTJurVxb+iJSTa6+MqCGkpn
-xpNnDXzKZ0zfZWXZWR3hqCj02+qa3OikN9uNJDRQmiEi4kDapEPRAgMBAAGgADAN
-BgkqhkiG9w0BAQUFAAOBgQBic3QNIuqVwj46T21GEK82lXbTlM/dSKfxQrSnf3if
-CCZ4Hdp/lT/xDGuB3HatPxR48kh6kns8YHID1T2eqZndiKc+KDjatARwmzmYAsi0
-E/oNAdYo7qnNhZnV++CzJQiqNsJZHotbnJcbNxVt03P/pGelVbhXENWnGzhlN0qz
-Nw==
+MIICgzCCAWsCAQAwPjEoMCYGA1UECwwfU2VjdXJpdHlUZXN0cyBDbGllbnQgQ2Vy
+dCAoUlNBKTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAp5cmPXgp29gRybL2vjaj5fGks+6Hzb+6s3Q4Kt4iTKA+yyq7
+3YoHufZwbW8nCUvd82jUk1u/QExQJ62njhU2G/JjTlBpw7r2YrPnaRxq+ClKjAbj
+h1iNIMVc0W1oslDaGuUR3GomksVBUMbR3H6hhyd6+wzY+p61M1XmcyZA2HpLe1Tt
+TR09ca3lBknCYDrZFjIgtG/IRFrDkwSZkq5KaJEdIMFoTiJiqch1yZIh5z1yQeKf
+wfgv41USzfDB26xL5n2yrAv+4ffgP4mXdQxRtVoMBhI+Z497PI5Nr8F1e5S/OM6M
+cL2poJ3qPzdeNaAcbJ3NqbSw+hOvOf8UnuELswIDAQABoAAwDQYJKoZIhvcNAQEL
+BQADggEBAF+sUbhhGM/GGG400QhMr+esqcEaXjuEjOD98LpORG2L750qyimb9bQo
+A4dLmC79j2m0LgvQX5+91qg4XDes2T/X31Oj/p9sPYSQzxLz0mmlQuvZUzfzMdlT
+w3PzyuGtN511GypID3mOpBhnd0GIAA2no16wDih9ioZbtoBxVI5pu+4x5JCvpxY0
+1p2CVwR1yUAv3VD36tdQrsRAB2L3j3QpOZegZQkSe/52g55sqwHsL4/7MVNol6et
+OOvyGRRXhhDZjE6nRVGwd0jjivDV65Z+04mU2+VSKJfSR9diaK7S/6VJ1a1LMGwq
+yARjlRT/+9YCgOpcG42vyDxjyk9qXX0=
-----END CERTIFICATE REQUEST-----
unsigned char ClientRSA_Cert_CA_ECC_der[] = {
- 0x30, 0x82, 0x01, 0xa6, 0x30, 0x82, 0x01, 0x4e, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x02, 0x03, 0xea, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48,
- 0xce, 0x3d, 0x04, 0x01, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
- 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72,
- 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31,
- 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a,
- 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, 0x33, 0x30, 0x37,
- 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
- 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41,
- 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09,
- 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xc0, 0x21, 0x29, 0x13, 0x69, 0xbb, 0xff, 0xbb, 0x05, 0x6d,
- 0xd1, 0xf0, 0x29, 0x59, 0xa2, 0x62, 0x5b, 0xeb, 0xab, 0x3a, 0xa4, 0x26,
- 0x38, 0x16, 0xa2, 0x33, 0x0e, 0xe4, 0xe0, 0xa5, 0xf1, 0x06, 0xe8, 0x29,
- 0xf2, 0x03, 0x4a, 0x75, 0xb9, 0x87, 0xa5, 0x65, 0x1b, 0xb4, 0x46, 0x68,
- 0xcf, 0x66, 0x6c, 0x11, 0xf2, 0x37, 0x5d, 0x31, 0xc2, 0x18, 0xc1, 0xcd,
- 0xe4, 0x7d, 0x1d, 0x63, 0xe3, 0x5c, 0xa2, 0x93, 0x03, 0xd6, 0x15, 0xa3,
- 0x5b, 0x3e, 0xd4, 0xc9, 0xba, 0xb5, 0x71, 0x6f, 0xe8, 0x89, 0x49, 0x36,
- 0xba, 0xf8, 0xca, 0x82, 0x1a, 0x4a, 0x67, 0xc6, 0x93, 0x67, 0x0d, 0x7c,
- 0xca, 0x67, 0x4c, 0xdf, 0x65, 0x65, 0xd9, 0x59, 0x1d, 0xe1, 0xa8, 0x28,
- 0xf4, 0xdb, 0xea, 0x9a, 0xdc, 0xe8, 0xa4, 0x37, 0xdb, 0x8d, 0x24, 0x34,
- 0x50, 0x9a, 0x21, 0x22, 0xe2, 0x40, 0xda, 0xa4, 0x43, 0xd1, 0x02, 0x03,
- 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86,
- 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20,
- 0x1e, 0xdd, 0x4d, 0xc6, 0xb8, 0xca, 0xc5, 0x9d, 0xdb, 0x88, 0x7b, 0xe8,
- 0xb8, 0x9b, 0xef, 0x38, 0x19, 0x9e, 0x03, 0x4a, 0xaf, 0xd3, 0xec, 0x4a,
- 0xf0, 0x95, 0x6b, 0xe3, 0xd7, 0x31, 0xe2, 0x17, 0x02, 0x20, 0x70, 0x16,
- 0xe9, 0xd4, 0x78, 0xfc, 0xb6, 0x26, 0xd6, 0xb1, 0x9b, 0x37, 0x4d, 0x11,
- 0x8e, 0x96, 0x13, 0x8d, 0x3d, 0xd2, 0xc5, 0x2d, 0x6b, 0x2a, 0x62, 0xe8,
- 0xae, 0xeb, 0xb4, 0x98, 0x2b, 0xa8
+ 0x30, 0x82, 0x02, 0xbe, 0x30, 0x82, 0x02, 0x64, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x13, 0x2c, 0x10, 0x5b, 0x40, 0x8c, 0xb3, 0x1f, 0x3c, 0xc8,
+ 0x37, 0xae, 0x60, 0xbe, 0x7e, 0x23, 0xeb, 0x1a, 0x79, 0x97, 0x30, 0x0a,
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25,
+ 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20,
+ 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43,
+ 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x32, 0x36, 0x30,
+ 0x31, 0x32, 0x35, 0x34, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35,
+ 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x35, 0x34, 0x30, 0x5a, 0x30,
+ 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1f,
+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74,
+ 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72,
+ 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
+ 0x6f, 0x73, 0x74, 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,
+ 0xa7, 0x97, 0x26, 0x3d, 0x78, 0x29, 0xdb, 0xd8, 0x11, 0xc9, 0xb2, 0xf6,
+ 0xbe, 0x36, 0xa3, 0xe5, 0xf1, 0xa4, 0xb3, 0xee, 0x87, 0xcd, 0xbf, 0xba,
+ 0xb3, 0x74, 0x38, 0x2a, 0xde, 0x22, 0x4c, 0xa0, 0x3e, 0xcb, 0x2a, 0xbb,
+ 0xdd, 0x8a, 0x07, 0xb9, 0xf6, 0x70, 0x6d, 0x6f, 0x27, 0x09, 0x4b, 0xdd,
+ 0xf3, 0x68, 0xd4, 0x93, 0x5b, 0xbf, 0x40, 0x4c, 0x50, 0x27, 0xad, 0xa7,
+ 0x8e, 0x15, 0x36, 0x1b, 0xf2, 0x63, 0x4e, 0x50, 0x69, 0xc3, 0xba, 0xf6,
+ 0x62, 0xb3, 0xe7, 0x69, 0x1c, 0x6a, 0xf8, 0x29, 0x4a, 0x8c, 0x06, 0xe3,
+ 0x87, 0x58, 0x8d, 0x20, 0xc5, 0x5c, 0xd1, 0x6d, 0x68, 0xb2, 0x50, 0xda,
+ 0x1a, 0xe5, 0x11, 0xdc, 0x6a, 0x26, 0x92, 0xc5, 0x41, 0x50, 0xc6, 0xd1,
+ 0xdc, 0x7e, 0xa1, 0x87, 0x27, 0x7a, 0xfb, 0x0c, 0xd8, 0xfa, 0x9e, 0xb5,
+ 0x33, 0x55, 0xe6, 0x73, 0x26, 0x40, 0xd8, 0x7a, 0x4b, 0x7b, 0x54, 0xed,
+ 0x4d, 0x1d, 0x3d, 0x71, 0xad, 0xe5, 0x06, 0x49, 0xc2, 0x60, 0x3a, 0xd9,
+ 0x16, 0x32, 0x20, 0xb4, 0x6f, 0xc8, 0x44, 0x5a, 0xc3, 0x93, 0x04, 0x99,
+ 0x92, 0xae, 0x4a, 0x68, 0x91, 0x1d, 0x20, 0xc1, 0x68, 0x4e, 0x22, 0x62,
+ 0xa9, 0xc8, 0x75, 0xc9, 0x92, 0x21, 0xe7, 0x3d, 0x72, 0x41, 0xe2, 0x9f,
+ 0xc1, 0xf8, 0x2f, 0xe3, 0x55, 0x12, 0xcd, 0xf0, 0xc1, 0xdb, 0xac, 0x4b,
+ 0xe6, 0x7d, 0xb2, 0xac, 0x0b, 0xfe, 0xe1, 0xf7, 0xe0, 0x3f, 0x89, 0x97,
+ 0x75, 0x0c, 0x51, 0xb5, 0x5a, 0x0c, 0x06, 0x12, 0x3e, 0x67, 0x8f, 0x7b,
+ 0x3c, 0x8e, 0x4d, 0xaf, 0xc1, 0x75, 0x7b, 0x94, 0xbf, 0x38, 0xce, 0x8c,
+ 0x70, 0xbd, 0xa9, 0xa0, 0x9d, 0xea, 0x3f, 0x37, 0x5e, 0x35, 0xa0, 0x1c,
+ 0x6c, 0x9d, 0xcd, 0xa9, 0xb4, 0xb0, 0xfa, 0x13, 0xaf, 0x39, 0xff, 0x14,
+ 0x9e, 0xe1, 0x0b, 0xb3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x8c,
+ 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+ 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, 0x06,
+ 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d,
+ 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+ 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0xea, 0x37, 0xfa, 0xfd, 0x51, 0x69, 0x13, 0x98, 0xcf,
+ 0xa1, 0x47, 0x05, 0x8b, 0xa3, 0xfa, 0xc4, 0x7d, 0xd1, 0xab, 0x8c, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0x2a, 0x8e, 0xdc, 0x15, 0xf2, 0x1d, 0x69, 0x64, 0x39, 0x77, 0x8f, 0xee,
+ 0xf4, 0x6d, 0x3f, 0x34, 0xd9, 0x85, 0xf0, 0x8c, 0x30, 0x0a, 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30,
+ 0x45, 0x02, 0x21, 0x00, 0xc2, 0xae, 0x7d, 0x05, 0x21, 0x72, 0xfc, 0x2a,
+ 0xff, 0x82, 0xa2, 0x8f, 0xa7, 0xb0, 0x8d, 0x9c, 0xe1, 0xcf, 0xa4, 0x8c,
+ 0xc9, 0x7e, 0xcc, 0x25, 0x65, 0xbe, 0xcc, 0x76, 0x82, 0x67, 0x2f, 0x32,
+ 0x02, 0x20, 0x48, 0xc5, 0x93, 0xad, 0x61, 0x3e, 0x32, 0x8b, 0x56, 0xa6,
+ 0xea, 0xc4, 0x59, 0xdf, 0x63, 0x9d, 0xea, 0xfa, 0x49, 0x01, 0xb5, 0x3a,
+ 0x2b, 0x17, 0x57, 0xa9, 0xc6, 0xe0, 0x57, 0xde, 0x45, 0x67
};
-unsigned int ClientRSA_Cert_CA_ECC_der_len = 426;
+unsigned int ClientRSA_Cert_CA_ECC_der_len = 706;
unsigned char ClientRSA_Cert_CA_RSA_der[] = {
- 0x30, 0x82, 0x02, 0x6a, 0x30, 0x82, 0x01, 0x52, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x02, 0x03, 0xe9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23,
- 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41,
- 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30,
- 0x20, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31,
- 0x30, 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33,
- 0x31, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31,
- 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65,
- 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20,
- 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
- 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
- 0x74, 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, 0xc0, 0x21, 0x29, 0x13, 0x69, 0xbb,
- 0xff, 0xbb, 0x05, 0x6d, 0xd1, 0xf0, 0x29, 0x59, 0xa2, 0x62, 0x5b, 0xeb,
- 0xab, 0x3a, 0xa4, 0x26, 0x38, 0x16, 0xa2, 0x33, 0x0e, 0xe4, 0xe0, 0xa5,
- 0xf1, 0x06, 0xe8, 0x29, 0xf2, 0x03, 0x4a, 0x75, 0xb9, 0x87, 0xa5, 0x65,
- 0x1b, 0xb4, 0x46, 0x68, 0xcf, 0x66, 0x6c, 0x11, 0xf2, 0x37, 0x5d, 0x31,
- 0xc2, 0x18, 0xc1, 0xcd, 0xe4, 0x7d, 0x1d, 0x63, 0xe3, 0x5c, 0xa2, 0x93,
- 0x03, 0xd6, 0x15, 0xa3, 0x5b, 0x3e, 0xd4, 0xc9, 0xba, 0xb5, 0x71, 0x6f,
- 0xe8, 0x89, 0x49, 0x36, 0xba, 0xf8, 0xca, 0x82, 0x1a, 0x4a, 0x67, 0xc6,
- 0x93, 0x67, 0x0d, 0x7c, 0xca, 0x67, 0x4c, 0xdf, 0x65, 0x65, 0xd9, 0x59,
- 0x1d, 0xe1, 0xa8, 0x28, 0xf4, 0xdb, 0xea, 0x9a, 0xdc, 0xe8, 0xa4, 0x37,
- 0xdb, 0x8d, 0x24, 0x34, 0x50, 0x9a, 0x21, 0x22, 0xe2, 0x40, 0xda, 0xa4,
- 0x43, 0xd1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x97, 0x4f, 0x15, 0x5e, 0x8f, 0x84,
- 0x25, 0x85, 0x62, 0x09, 0x46, 0x8e, 0x1d, 0x0f, 0x3e, 0x29, 0x46, 0x87,
- 0xc8, 0x95, 0xbd, 0xcf, 0x8e, 0x8f, 0x99, 0x9c, 0x16, 0x47, 0x6f, 0x43,
- 0x07, 0x14, 0x19, 0x99, 0x80, 0xb6, 0x35, 0x39, 0xba, 0x29, 0xd1, 0xe5,
- 0x84, 0x18, 0x67, 0xd6, 0x0f, 0x06, 0x15, 0x62, 0xca, 0x20, 0x19, 0x30,
- 0xe4, 0x90, 0x57, 0x2d, 0x18, 0x30, 0x20, 0x09, 0x03, 0x0a, 0x7e, 0xd0,
- 0xf9, 0xb6, 0xbd, 0x10, 0x69, 0x9e, 0x00, 0x71, 0x40, 0x8a, 0x9c, 0x44,
- 0xc2, 0xa4, 0xd0, 0x70, 0xfd, 0x43, 0x32, 0xbf, 0x4f, 0xcc, 0xc6, 0xca,
- 0x4a, 0x16, 0xb2, 0xd0, 0x0b, 0x09, 0xde, 0xb9, 0x8a, 0x65, 0xba, 0x85,
- 0xc1, 0x13, 0x94, 0x92, 0x1f, 0x0d, 0xc9, 0xe0, 0x5f, 0x25, 0xd4, 0x28,
- 0xf0, 0x92, 0xc9, 0xda, 0x8c, 0x6f, 0x40, 0xe6, 0x4e, 0x37, 0x46, 0xa4,
- 0x45, 0x3b, 0x93, 0xda, 0x6e, 0x01, 0xc2, 0xd5, 0xe1, 0x41, 0x48, 0x9a,
- 0x16, 0x26, 0x62, 0x6d, 0xa3, 0x6e, 0x99, 0x7b, 0xea, 0xce, 0xb6, 0xba,
- 0x44, 0xbd, 0x9d, 0x18, 0x14, 0x55, 0xa4, 0xdd, 0xb0, 0x87, 0x54, 0x7c,
- 0x6c, 0xef, 0x69, 0xee, 0x17, 0x6c, 0x74, 0x58, 0xf2, 0x46, 0x02, 0x6e,
- 0xf0, 0xe7, 0x41, 0xea, 0x62, 0xdc, 0x11, 0x1a, 0xaa, 0x8e, 0x56, 0xb9,
- 0x7b, 0x08, 0x00, 0x18, 0xed, 0x6b, 0xe9, 0x38, 0x29, 0xcc, 0xe1, 0x9c,
- 0xbd, 0x61, 0x57, 0x96, 0xa2, 0x2b, 0xa5, 0x81, 0x09, 0xd3, 0x12, 0x77,
- 0xb0, 0x3b, 0xd8, 0xb5, 0x83, 0xde, 0x9e, 0x41, 0xec, 0x3f, 0x2d, 0x99,
- 0x65, 0x6a, 0x4e, 0x50, 0xca, 0xdb, 0xc2, 0x5a, 0xea, 0x11, 0xed, 0x61,
- 0x16, 0x49, 0xa3, 0xd9, 0x06, 0x68, 0x23, 0x13, 0xc1, 0x26, 0xec, 0xb2,
- 0xcf, 0x5d, 0xf9, 0x26, 0xc1, 0xaf, 0x67, 0x0c, 0x4b, 0xe6
+ 0x30, 0x82, 0x03, 0x68, 0x30, 0x82, 0x02, 0x50, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x14, 0x00, 0xb9, 0x18, 0x42, 0xfe, 0xdf, 0xe7, 0x25, 0x9c,
+ 0xce, 0xfa, 0xd7, 0xd0, 0xe8, 0x56, 0xe3, 0xd5, 0xd3, 0x20, 0x95, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54,
+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
+ 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30,
+ 0x35, 0x32, 0x36, 0x30, 0x31, 0x31, 0x34, 0x34, 0x35, 0x5a, 0x18, 0x0f,
+ 0x32, 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x31, 0x34,
+ 0x34, 0x35, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x0c, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+ 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31,
+ 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f,
+ 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xa7, 0x97, 0x26, 0x3d, 0x78, 0x29, 0xdb, 0xd8,
+ 0x11, 0xc9, 0xb2, 0xf6, 0xbe, 0x36, 0xa3, 0xe5, 0xf1, 0xa4, 0xb3, 0xee,
+ 0x87, 0xcd, 0xbf, 0xba, 0xb3, 0x74, 0x38, 0x2a, 0xde, 0x22, 0x4c, 0xa0,
+ 0x3e, 0xcb, 0x2a, 0xbb, 0xdd, 0x8a, 0x07, 0xb9, 0xf6, 0x70, 0x6d, 0x6f,
+ 0x27, 0x09, 0x4b, 0xdd, 0xf3, 0x68, 0xd4, 0x93, 0x5b, 0xbf, 0x40, 0x4c,
+ 0x50, 0x27, 0xad, 0xa7, 0x8e, 0x15, 0x36, 0x1b, 0xf2, 0x63, 0x4e, 0x50,
+ 0x69, 0xc3, 0xba, 0xf6, 0x62, 0xb3, 0xe7, 0x69, 0x1c, 0x6a, 0xf8, 0x29,
+ 0x4a, 0x8c, 0x06, 0xe3, 0x87, 0x58, 0x8d, 0x20, 0xc5, 0x5c, 0xd1, 0x6d,
+ 0x68, 0xb2, 0x50, 0xda, 0x1a, 0xe5, 0x11, 0xdc, 0x6a, 0x26, 0x92, 0xc5,
+ 0x41, 0x50, 0xc6, 0xd1, 0xdc, 0x7e, 0xa1, 0x87, 0x27, 0x7a, 0xfb, 0x0c,
+ 0xd8, 0xfa, 0x9e, 0xb5, 0x33, 0x55, 0xe6, 0x73, 0x26, 0x40, 0xd8, 0x7a,
+ 0x4b, 0x7b, 0x54, 0xed, 0x4d, 0x1d, 0x3d, 0x71, 0xad, 0xe5, 0x06, 0x49,
+ 0xc2, 0x60, 0x3a, 0xd9, 0x16, 0x32, 0x20, 0xb4, 0x6f, 0xc8, 0x44, 0x5a,
+ 0xc3, 0x93, 0x04, 0x99, 0x92, 0xae, 0x4a, 0x68, 0x91, 0x1d, 0x20, 0xc1,
+ 0x68, 0x4e, 0x22, 0x62, 0xa9, 0xc8, 0x75, 0xc9, 0x92, 0x21, 0xe7, 0x3d,
+ 0x72, 0x41, 0xe2, 0x9f, 0xc1, 0xf8, 0x2f, 0xe3, 0x55, 0x12, 0xcd, 0xf0,
+ 0xc1, 0xdb, 0xac, 0x4b, 0xe6, 0x7d, 0xb2, 0xac, 0x0b, 0xfe, 0xe1, 0xf7,
+ 0xe0, 0x3f, 0x89, 0x97, 0x75, 0x0c, 0x51, 0xb5, 0x5a, 0x0c, 0x06, 0x12,
+ 0x3e, 0x67, 0x8f, 0x7b, 0x3c, 0x8e, 0x4d, 0xaf, 0xc1, 0x75, 0x7b, 0x94,
+ 0xbf, 0x38, 0xce, 0x8c, 0x70, 0xbd, 0xa9, 0xa0, 0x9d, 0xea, 0x3f, 0x37,
+ 0x5e, 0x35, 0xa0, 0x1c, 0x6c, 0x9d, 0xcd, 0xa9, 0xb4, 0xb0, 0xfa, 0x13,
+ 0xaf, 0x39, 0xff, 0x14, 0x9e, 0xe1, 0x0b, 0xb3, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x75, 0x30, 0x73, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30,
+ 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xea, 0x37, 0xfa, 0xfd, 0x51,
+ 0x69, 0x13, 0x98, 0xcf, 0xa1, 0x47, 0x05, 0x8b, 0xa3, 0xfa, 0xc4, 0x7d,
+ 0xd1, 0xab, 0x8c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0x5d, 0xa7, 0x1b, 0x3b, 0x57, 0xd2, 0x0e, 0x08,
+ 0x1e, 0xaa, 0x47, 0xcf, 0x03, 0x34, 0x68, 0xbe, 0x53, 0x00, 0xd9, 0x64,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb2, 0x6a, 0x95, 0x8d,
+ 0xf8, 0x09, 0xc6, 0x27, 0x8a, 0xbb, 0x61, 0x8a, 0xa7, 0x93, 0x4d, 0xd1,
+ 0x81, 0x36, 0xd8, 0x2e, 0x33, 0x97, 0x71, 0x0a, 0x36, 0x26, 0x2d, 0x4f,
+ 0x3e, 0x4d, 0x89, 0x78, 0x67, 0xa6, 0xf8, 0x79, 0x40, 0xbe, 0xea, 0xeb,
+ 0x64, 0x9c, 0x63, 0x11, 0x9a, 0xf8, 0xbd, 0xe4, 0xfb, 0xe7, 0x5a, 0x91,
+ 0x39, 0xa0, 0x41, 0x76, 0x81, 0x29, 0xcd, 0x92, 0x7e, 0xbc, 0x02, 0x3b,
+ 0x5d, 0x40, 0xfe, 0xaf, 0x12, 0x50, 0xfb, 0x6e, 0x19, 0x49, 0x67, 0xf2,
+ 0x1c, 0x21, 0x8d, 0x4a, 0x06, 0x52, 0x0d, 0xfa, 0x81, 0xa9, 0x6d, 0x57,
+ 0xcf, 0xc8, 0xf0, 0x52, 0x99, 0x44, 0xa7, 0x37, 0xb2, 0x80, 0xc8, 0xa9,
+ 0x90, 0x60, 0x89, 0x35, 0x47, 0x1e, 0xf1, 0xed, 0x02, 0xc0, 0x68, 0x2b,
+ 0x27, 0x74, 0x17, 0xc8, 0x55, 0xb9, 0x02, 0x8c, 0xf4, 0x4d, 0xbc, 0x94,
+ 0x90, 0x0a, 0x45, 0x34, 0xf7, 0x43, 0x01, 0x3c, 0xb1, 0x4b, 0xd3, 0x59,
+ 0x6c, 0xcc, 0x64, 0x2e, 0xde, 0x8e, 0x14, 0xd0, 0xbc, 0xcb, 0x11, 0xd0,
+ 0x43, 0x95, 0x7d, 0x56, 0x5c, 0x51, 0x27, 0x6f, 0x4c, 0xbb, 0xc3, 0x3b,
+ 0x7d, 0xc9, 0x95, 0x09, 0x60, 0x5b, 0x05, 0x6a, 0x9c, 0x61, 0x16, 0xab,
+ 0x28, 0xd2, 0x09, 0xc3, 0x4a, 0x7d, 0xba, 0x3e, 0x52, 0xe9, 0xfa, 0x18,
+ 0xc1, 0x0c, 0x88, 0x83, 0xbc, 0x6e, 0x7c, 0x08, 0x48, 0x99, 0x76, 0xea,
+ 0x08, 0x8d, 0xa9, 0x5a, 0x4b, 0x31, 0xb6, 0x84, 0xf7, 0xfd, 0x73, 0x28,
+ 0xd6, 0xfb, 0x5e, 0x99, 0x6f, 0xd7, 0x22, 0x5f, 0xad, 0x0c, 0x9b, 0xf0,
+ 0x91, 0xc7, 0xd5, 0x37, 0xd1, 0x21, 0x11, 0x0f, 0x14, 0x88, 0xea, 0x4d,
+ 0x14, 0x39, 0xd0, 0x92, 0x4d, 0x96, 0x10, 0x42, 0xd7, 0x5f, 0xe2, 0xd9,
+ 0x84, 0x96, 0xce, 0xbf, 0xab, 0x3f, 0xd0, 0x2f, 0x8b, 0x9b, 0x75, 0x77
};
-unsigned int ClientRSA_Cert_CA_RSA_der_len = 622;
+unsigned int ClientRSA_Cert_CA_RSA_der_len = 876;
unsigned char ClientRSA_Key_der[] = {
- 0x30, 0x82, 0x02, 0x5b, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xc0,
- 0x21, 0x29, 0x13, 0x69, 0xbb, 0xff, 0xbb, 0x05, 0x6d, 0xd1, 0xf0, 0x29,
- 0x59, 0xa2, 0x62, 0x5b, 0xeb, 0xab, 0x3a, 0xa4, 0x26, 0x38, 0x16, 0xa2,
- 0x33, 0x0e, 0xe4, 0xe0, 0xa5, 0xf1, 0x06, 0xe8, 0x29, 0xf2, 0x03, 0x4a,
- 0x75, 0xb9, 0x87, 0xa5, 0x65, 0x1b, 0xb4, 0x46, 0x68, 0xcf, 0x66, 0x6c,
- 0x11, 0xf2, 0x37, 0x5d, 0x31, 0xc2, 0x18, 0xc1, 0xcd, 0xe4, 0x7d, 0x1d,
- 0x63, 0xe3, 0x5c, 0xa2, 0x93, 0x03, 0xd6, 0x15, 0xa3, 0x5b, 0x3e, 0xd4,
- 0xc9, 0xba, 0xb5, 0x71, 0x6f, 0xe8, 0x89, 0x49, 0x36, 0xba, 0xf8, 0xca,
- 0x82, 0x1a, 0x4a, 0x67, 0xc6, 0x93, 0x67, 0x0d, 0x7c, 0xca, 0x67, 0x4c,
- 0xdf, 0x65, 0x65, 0xd9, 0x59, 0x1d, 0xe1, 0xa8, 0x28, 0xf4, 0xdb, 0xea,
- 0x9a, 0xdc, 0xe8, 0xa4, 0x37, 0xdb, 0x8d, 0x24, 0x34, 0x50, 0x9a, 0x21,
- 0x22, 0xe2, 0x40, 0xda, 0xa4, 0x43, 0xd1, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0x02, 0x81, 0x80, 0x12, 0xc6, 0xea, 0xe1, 0xc7, 0xd2, 0xa4, 0xd2, 0x9d,
- 0x5c, 0x37, 0x49, 0x56, 0x71, 0x39, 0x2a, 0x8d, 0xbb, 0x41, 0x97, 0xd0,
- 0x95, 0x1f, 0xa4, 0x2e, 0xa3, 0xf8, 0xcf, 0xab, 0x98, 0xec, 0x2e, 0x75,
- 0xa0, 0x2b, 0xd3, 0xe0, 0x82, 0x12, 0xe8, 0xcb, 0xe4, 0x4e, 0xc9, 0xd6,
- 0x9b, 0xc5, 0xb1, 0x47, 0xdc, 0x95, 0x24, 0x8e, 0x0a, 0x1f, 0xe3, 0x15,
- 0x85, 0xce, 0xcf, 0xdf, 0x80, 0x74, 0xa6, 0xdc, 0x9b, 0x94, 0xa3, 0x9b,
- 0x43, 0x49, 0xf5, 0x0c, 0xfe, 0xa3, 0xae, 0x30, 0x35, 0x5f, 0xc9, 0xe1,
- 0xbd, 0xa2, 0xc5, 0x5b, 0x9a, 0x4c, 0xcf, 0xae, 0x34, 0x9c, 0xcc, 0xa4,
- 0x74, 0xcb, 0x3c, 0xa9, 0xa5, 0x58, 0x75, 0xf3, 0x70, 0x72, 0xf2, 0x81,
- 0xce, 0xc8, 0x6f, 0x60, 0x51, 0x45, 0xea, 0xe9, 0x9d, 0x86, 0x43, 0x80,
- 0xdd, 0x93, 0xb9, 0x22, 0xe0, 0x6e, 0x02, 0xcc, 0x89, 0x66, 0x31, 0x02,
- 0x41, 0x00, 0xeb, 0x57, 0xad, 0x0a, 0xf2, 0x25, 0xa8, 0xd5, 0x5d, 0x24,
- 0xcf, 0x39, 0x18, 0xf7, 0xfd, 0x95, 0x10, 0x06, 0x5b, 0x9f, 0x8e, 0x21,
- 0x9c, 0x5b, 0x3b, 0xd2, 0xb9, 0xce, 0x29, 0x37, 0xc9, 0x7f, 0x14, 0x48,
- 0xca, 0x83, 0x6a, 0x08, 0xd7, 0xb6, 0x2e, 0xc8, 0x34, 0x95, 0x5b, 0x56,
- 0x3b, 0xfe, 0xfe, 0xf8, 0x8a, 0x25, 0xc5, 0x60, 0x43, 0xee, 0x4f, 0x18,
- 0x58, 0x13, 0xf6, 0x20, 0x6f, 0x3d, 0x02, 0x41, 0x00, 0xd0, 0xfe, 0x74,
- 0xec, 0x28, 0x21, 0xae, 0x14, 0xef, 0x71, 0x69, 0xc1, 0x04, 0x31, 0x17,
- 0xde, 0x61, 0x18, 0xd9, 0xb1, 0x78, 0xd2, 0xc9, 0x3c, 0x78, 0x7b, 0x24,
- 0xe3, 0x62, 0x1d, 0x20, 0x81, 0x10, 0xfa, 0x9a, 0x45, 0xeb, 0xcc, 0xe1,
- 0x9c, 0x32, 0x24, 0x59, 0x3a, 0xd1, 0x97, 0x1d, 0x5e, 0x36, 0x8e, 0x6b,
- 0xc8, 0x35, 0xa8, 0x42, 0x99, 0xbb, 0x09, 0x58, 0x5d, 0x79, 0x07, 0xf0,
- 0x25, 0x02, 0x40, 0x51, 0xf7, 0xc5, 0x93, 0x6c, 0x67, 0x65, 0x78, 0x7a,
- 0xea, 0x99, 0x2a, 0x3f, 0xe2, 0x0f, 0xf6, 0x5d, 0x10, 0x79, 0xd5, 0x06,
- 0xc1, 0xfa, 0x1d, 0x64, 0xa6, 0xae, 0x84, 0x79, 0xa2, 0xae, 0x91, 0x8e,
- 0x55, 0x14, 0x03, 0xd5, 0x68, 0xa3, 0x09, 0x17, 0x1e, 0x30, 0x02, 0x5d,
- 0x3f, 0x99, 0xc1, 0xe4, 0xb8, 0x58, 0x15, 0x73, 0xbb, 0x65, 0xad, 0x98,
- 0xea, 0xd7, 0xb2, 0x8c, 0x25, 0x1b, 0xd9, 0x02, 0x40, 0x2e, 0xaa, 0xc3,
- 0x1d, 0x00, 0x91, 0x14, 0xb8, 0x24, 0x07, 0x65, 0x1f, 0xee, 0x79, 0xaf,
- 0xe4, 0xbe, 0x35, 0xb8, 0x56, 0x82, 0xae, 0x3e, 0xb5, 0x3c, 0x09, 0xf3,
- 0x60, 0xba, 0xc5, 0xda, 0x3e, 0x37, 0xb6, 0x5d, 0xc0, 0x83, 0x38, 0xca,
- 0xa0, 0x00, 0x2a, 0x51, 0xaa, 0x6a, 0xa6, 0x9d, 0xae, 0x2d, 0xec, 0x7b,
- 0x70, 0xc7, 0x5a, 0x7d, 0x14, 0xaa, 0xc9, 0x19, 0x6c, 0x35, 0xdc, 0x69,
- 0xe9, 0x02, 0x40, 0x1f, 0xd4, 0x7c, 0xf6, 0x2a, 0x93, 0xa2, 0x54, 0x38,
- 0xcb, 0xd1, 0xf7, 0x16, 0x12, 0x98, 0xf2, 0x2b, 0xfc, 0xda, 0xf6, 0x0b,
- 0x39, 0xca, 0xef, 0xd5, 0x50, 0x66, 0x1a, 0xca, 0x3f, 0x08, 0x94, 0xa6,
- 0x08, 0x6d, 0xae, 0x3d, 0x2d, 0x8b, 0xde, 0x5f, 0x01, 0x5a, 0x79, 0x2a,
- 0x9c, 0xef, 0xa7, 0xba, 0xed, 0xb7, 0xaf, 0x9e, 0x16, 0x0c, 0xe3, 0xb1,
- 0xea, 0x55, 0x90, 0x8b, 0x28, 0x93, 0xd2
+ 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xa7, 0x97, 0x26, 0x3d, 0x78, 0x29, 0xdb, 0xd8, 0x11, 0xc9, 0xb2, 0xf6,
+ 0xbe, 0x36, 0xa3, 0xe5, 0xf1, 0xa4, 0xb3, 0xee, 0x87, 0xcd, 0xbf, 0xba,
+ 0xb3, 0x74, 0x38, 0x2a, 0xde, 0x22, 0x4c, 0xa0, 0x3e, 0xcb, 0x2a, 0xbb,
+ 0xdd, 0x8a, 0x07, 0xb9, 0xf6, 0x70, 0x6d, 0x6f, 0x27, 0x09, 0x4b, 0xdd,
+ 0xf3, 0x68, 0xd4, 0x93, 0x5b, 0xbf, 0x40, 0x4c, 0x50, 0x27, 0xad, 0xa7,
+ 0x8e, 0x15, 0x36, 0x1b, 0xf2, 0x63, 0x4e, 0x50, 0x69, 0xc3, 0xba, 0xf6,
+ 0x62, 0xb3, 0xe7, 0x69, 0x1c, 0x6a, 0xf8, 0x29, 0x4a, 0x8c, 0x06, 0xe3,
+ 0x87, 0x58, 0x8d, 0x20, 0xc5, 0x5c, 0xd1, 0x6d, 0x68, 0xb2, 0x50, 0xda,
+ 0x1a, 0xe5, 0x11, 0xdc, 0x6a, 0x26, 0x92, 0xc5, 0x41, 0x50, 0xc6, 0xd1,
+ 0xdc, 0x7e, 0xa1, 0x87, 0x27, 0x7a, 0xfb, 0x0c, 0xd8, 0xfa, 0x9e, 0xb5,
+ 0x33, 0x55, 0xe6, 0x73, 0x26, 0x40, 0xd8, 0x7a, 0x4b, 0x7b, 0x54, 0xed,
+ 0x4d, 0x1d, 0x3d, 0x71, 0xad, 0xe5, 0x06, 0x49, 0xc2, 0x60, 0x3a, 0xd9,
+ 0x16, 0x32, 0x20, 0xb4, 0x6f, 0xc8, 0x44, 0x5a, 0xc3, 0x93, 0x04, 0x99,
+ 0x92, 0xae, 0x4a, 0x68, 0x91, 0x1d, 0x20, 0xc1, 0x68, 0x4e, 0x22, 0x62,
+ 0xa9, 0xc8, 0x75, 0xc9, 0x92, 0x21, 0xe7, 0x3d, 0x72, 0x41, 0xe2, 0x9f,
+ 0xc1, 0xf8, 0x2f, 0xe3, 0x55, 0x12, 0xcd, 0xf0, 0xc1, 0xdb, 0xac, 0x4b,
+ 0xe6, 0x7d, 0xb2, 0xac, 0x0b, 0xfe, 0xe1, 0xf7, 0xe0, 0x3f, 0x89, 0x97,
+ 0x75, 0x0c, 0x51, 0xb5, 0x5a, 0x0c, 0x06, 0x12, 0x3e, 0x67, 0x8f, 0x7b,
+ 0x3c, 0x8e, 0x4d, 0xaf, 0xc1, 0x75, 0x7b, 0x94, 0xbf, 0x38, 0xce, 0x8c,
+ 0x70, 0xbd, 0xa9, 0xa0, 0x9d, 0xea, 0x3f, 0x37, 0x5e, 0x35, 0xa0, 0x1c,
+ 0x6c, 0x9d, 0xcd, 0xa9, 0xb4, 0xb0, 0xfa, 0x13, 0xaf, 0x39, 0xff, 0x14,
+ 0x9e, 0xe1, 0x0b, 0xb3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01,
+ 0x00, 0x34, 0x1d, 0x90, 0xca, 0xb4, 0xbf, 0x6f, 0x9a, 0x35, 0x8d, 0xdf,
+ 0x95, 0x53, 0x79, 0x72, 0x66, 0x63, 0x4a, 0xb0, 0x99, 0x90, 0xa9, 0xae,
+ 0xe1, 0xc4, 0x44, 0x73, 0xe3, 0x00, 0xc8, 0xf1, 0xc3, 0x33, 0x43, 0xc2,
+ 0xba, 0x41, 0x1e, 0x57, 0x60, 0xc0, 0xfe, 0x1d, 0x49, 0xdf, 0x7d, 0xc8,
+ 0x95, 0xf0, 0xc7, 0xbc, 0xb3, 0x46, 0x68, 0xa6, 0xfa, 0x14, 0x43, 0x02,
+ 0x81, 0x84, 0x71, 0x9c, 0x2d, 0xfc, 0xa6, 0x5d, 0x08, 0x2c, 0x9b, 0xad,
+ 0x5c, 0x49, 0x3d, 0x60, 0xcd, 0x13, 0x05, 0x40, 0xbe, 0xb6, 0x6b, 0xed,
+ 0x08, 0x7c, 0x62, 0x51, 0x20, 0xcb, 0xbf, 0x1d, 0x71, 0x44, 0x89, 0x8f,
+ 0x13, 0x04, 0x22, 0x0f, 0xf7, 0xd7, 0x1a, 0xbf, 0xb1, 0x8f, 0xaa, 0x2a,
+ 0xe9, 0xc0, 0x03, 0xb0, 0xff, 0x72, 0x8b, 0x8f, 0xde, 0x62, 0xeb, 0x2c,
+ 0xc7, 0x74, 0x7b, 0x55, 0xfa, 0xa0, 0xfe, 0xb1, 0x52, 0x75, 0x94, 0x64,
+ 0xa5, 0x3e, 0x44, 0xec, 0xde, 0x4a, 0xfb, 0x32, 0x07, 0x00, 0xa9, 0xd1,
+ 0xe6, 0x73, 0x6e, 0x49, 0x35, 0x8f, 0x4b, 0x88, 0x88, 0x18, 0x15, 0xd4,
+ 0xb5, 0x00, 0xa5, 0x80, 0x53, 0xcc, 0x2d, 0x38, 0x7c, 0x86, 0xd9, 0x27,
+ 0x11, 0x10, 0x2b, 0xd1, 0xdd, 0xc1, 0xb4, 0xcf, 0x5b, 0xe2, 0x48, 0x52,
+ 0x3d, 0x9d, 0x6b, 0x6c, 0x6e, 0x9b, 0x32, 0x86, 0x37, 0xba, 0x78, 0xbe,
+ 0x0e, 0xb5, 0xa4, 0xd3, 0x50, 0xfd, 0x05, 0x28, 0xd8, 0xe8, 0x22, 0xf7,
+ 0x64, 0x6e, 0xbe, 0xbd, 0x6f, 0xd1, 0xd8, 0x4c, 0x54, 0xb8, 0x11, 0x7f,
+ 0xee, 0x91, 0xf7, 0x0c, 0xb3, 0xcd, 0x10, 0x64, 0xa5, 0x49, 0x73, 0xd7,
+ 0xc1, 0x12, 0x5f, 0x1f, 0x4d, 0x93, 0xc8, 0x3a, 0x5c, 0x5c, 0xce, 0x29,
+ 0xc8, 0xe1, 0x41, 0xdc, 0x95, 0xe1, 0xf0, 0x41, 0x31, 0x48, 0x5c, 0x78,
+ 0x4f, 0x5f, 0x1c, 0x75, 0x61, 0x02, 0x81, 0x81, 0x00, 0xd7, 0x07, 0xcb,
+ 0x85, 0xbe, 0x41, 0xca, 0x4b, 0x61, 0xe4, 0x8a, 0xf3, 0xd4, 0xec, 0xb5,
+ 0x98, 0x0d, 0xb4, 0x9d, 0xb9, 0x2e, 0xf5, 0x33, 0xda, 0x30, 0xd9, 0x03,
+ 0x32, 0x04, 0x54, 0x79, 0x71, 0xb9, 0xbd, 0x4c, 0x4d, 0xc7, 0xd4, 0x38,
+ 0xb1, 0xb4, 0xf3, 0xdc, 0x7b, 0x87, 0x84, 0x04, 0xcc, 0x60, 0x34, 0x88,
+ 0xbb, 0x1d, 0x61, 0x51, 0x96, 0x43, 0x24, 0x98, 0x35, 0xa4, 0x81, 0xbb,
+ 0x25, 0x15, 0xc9, 0x08, 0x87, 0xf6, 0x13, 0xa7, 0x00, 0x26, 0x5a, 0x1a,
+ 0xad, 0x07, 0x55, 0xfb, 0x4b, 0x54, 0x2b, 0x53, 0xe2, 0x39, 0xd1, 0xd3,
+ 0x1c, 0x6c, 0xb4, 0x98, 0xfe, 0x3d, 0x1f, 0x2f, 0x60, 0xd9, 0xbd, 0xf4,
+ 0x3a, 0x4c, 0x48, 0x85, 0xab, 0x23, 0xc5, 0x3c, 0x13, 0xba, 0x2c, 0xf7,
+ 0x03, 0x7a, 0x75, 0x49, 0xb8, 0x1e, 0xec, 0x25, 0x23, 0x90, 0x57, 0x55,
+ 0xe3, 0x2d, 0x45, 0x00, 0xbf, 0x02, 0x81, 0x81, 0x00, 0xc7, 0x85, 0x72,
+ 0x45, 0x67, 0xa3, 0x7c, 0xc1, 0x9b, 0x6b, 0xcb, 0x0c, 0x22, 0x32, 0xd2,
+ 0x94, 0x05, 0x91, 0x19, 0x6a, 0xfe, 0x15, 0xbe, 0x01, 0x0a, 0xf0, 0x83,
+ 0x00, 0x7c, 0x61, 0xbe, 0x27, 0xf9, 0x94, 0x20, 0x80, 0x4c, 0x0a, 0xff,
+ 0x51, 0xb3, 0x66, 0x62, 0x9e, 0x3d, 0x07, 0xe3, 0x89, 0xd2, 0x23, 0x33,
+ 0x88, 0x18, 0x64, 0x4c, 0x5c, 0xf3, 0xc4, 0xe3, 0xf4, 0x15, 0x8e, 0xb1,
+ 0x65, 0xad, 0x09, 0x91, 0x32, 0x4d, 0x02, 0xd2, 0x7b, 0x4e, 0x6c, 0x4c,
+ 0x34, 0x29, 0x70, 0x71, 0xaa, 0x4b, 0xb7, 0x9e, 0x47, 0x13, 0x54, 0x44,
+ 0x21, 0xe4, 0x07, 0x58, 0x68, 0x3c, 0xaf, 0x4f, 0x99, 0x2a, 0x26, 0xad,
+ 0x3d, 0x43, 0x8e, 0x98, 0x04, 0x4f, 0x9d, 0x45, 0xce, 0xaf, 0xb5, 0x92,
+ 0x8c, 0x9f, 0x6b, 0x85, 0x00, 0x86, 0xc4, 0xd7, 0xbb, 0x7e, 0x87, 0xcf,
+ 0x14, 0x82, 0x7e, 0x7e, 0x0d, 0x02, 0x81, 0x80, 0x26, 0xe0, 0x90, 0xea,
+ 0x80, 0x68, 0x92, 0xb3, 0xa8, 0x62, 0x52, 0xc1, 0x1d, 0x09, 0x23, 0x17,
+ 0xf7, 0xba, 0x65, 0x1d, 0xdb, 0x20, 0x98, 0x1c, 0x65, 0xe2, 0x86, 0x92,
+ 0x5f, 0x78, 0x0a, 0x71, 0x06, 0x5c, 0xf4, 0x53, 0xc7, 0xc2, 0x55, 0xf1,
+ 0xc3, 0x3e, 0xa7, 0xe9, 0x69, 0xa9, 0xf3, 0xd8, 0x23, 0xb8, 0xbb, 0xd3,
+ 0xe0, 0xce, 0xfc, 0x9a, 0x47, 0x4f, 0x71, 0x79, 0x99, 0x61, 0x9f, 0x3d,
+ 0x68, 0x3f, 0xed, 0x9b, 0xef, 0x60, 0xc4, 0x3b, 0xe1, 0xb3, 0x3e, 0xc9,
+ 0x73, 0xdf, 0x16, 0xcd, 0x1a, 0xcd, 0xae, 0x9f, 0xe3, 0x46, 0x4d, 0x7e,
+ 0x01, 0x25, 0x71, 0xd7, 0xdd, 0xa3, 0x2a, 0xc4, 0xbe, 0xf9, 0x7a, 0x13,
+ 0xa4, 0x41, 0x24, 0x71, 0xb9, 0xc8, 0xea, 0x40, 0xc2, 0xd3, 0x68, 0x61,
+ 0xa7, 0x9d, 0x57, 0x13, 0xc3, 0xfb, 0x7c, 0x07, 0x7f, 0x0c, 0x5b, 0x49,
+ 0xf4, 0xa0, 0x5a, 0x2f, 0x02, 0x81, 0x81, 0x00, 0x88, 0xa8, 0x46, 0x54,
+ 0x73, 0x5f, 0xef, 0x1b, 0x4c, 0xb0, 0xd0, 0x2a, 0x47, 0x62, 0x38, 0x09,
+ 0x5a, 0xa6, 0xbf, 0x9a, 0x20, 0xde, 0x13, 0x7d, 0xf3, 0x58, 0x38, 0xe2,
+ 0x24, 0x4f, 0x6e, 0x47, 0x43, 0x12, 0xca, 0x10, 0x16, 0x05, 0x92, 0x4b,
+ 0x0b, 0x6d, 0x9d, 0x2e, 0x74, 0xee, 0xea, 0x52, 0x83, 0xb3, 0xc8, 0x9f,
+ 0xf6, 0xd4, 0xfb, 0xd8, 0xce, 0xbe, 0x94, 0xc3, 0xa1, 0xe0, 0x52, 0x71,
+ 0x29, 0xcb, 0xdb, 0xbf, 0x70, 0x2f, 0xf6, 0xaa, 0xae, 0x54, 0x4e, 0xfd,
+ 0x8b, 0x44, 0x91, 0x15, 0xeb, 0x36, 0xa1, 0x1a, 0x5d, 0x8a, 0xe1, 0xff,
+ 0xb4, 0x87, 0xb3, 0x6d, 0xf1, 0xe2, 0xc1, 0xca, 0x4e, 0xac, 0x9f, 0x0b,
+ 0xcf, 0x31, 0xe3, 0xbd, 0x50, 0x2a, 0x90, 0x9d, 0xb8, 0x8b, 0xcd, 0x0c,
+ 0xb4, 0x44, 0x98, 0x9c, 0x7b, 0xb2, 0x67, 0x70, 0xec, 0x81, 0x68, 0xbc,
+ 0xcb, 0x84, 0x88, 0x21, 0x02, 0x81, 0x80, 0x2d, 0x42, 0x9a, 0x79, 0x98,
+ 0x8a, 0x3d, 0xc7, 0xed, 0x2f, 0xab, 0x40, 0x2f, 0x26, 0xc3, 0xf6, 0xc7,
+ 0x79, 0x8d, 0x04, 0x6c, 0x71, 0x92, 0xbb, 0x6b, 0x2f, 0xde, 0x5b, 0xe6,
+ 0xff, 0x51, 0xc0, 0x63, 0xdc, 0xd0, 0xe4, 0x12, 0x93, 0x4d, 0xfb, 0x7e,
+ 0x27, 0x14, 0x98, 0x82, 0x03, 0x0b, 0x05, 0xb7, 0xd0, 0x7a, 0xb0, 0x0d,
+ 0xbc, 0x9e, 0xbc, 0xfa, 0xe9, 0xce, 0x05, 0x14, 0xfa, 0xe1, 0xaa, 0x27,
+ 0x2d, 0x8e, 0xd2, 0xe3, 0xfe, 0xb8, 0x74, 0x50, 0xa9, 0x9c, 0x16, 0xa2,
+ 0xe4, 0x79, 0x53, 0x2a, 0xb7, 0x32, 0xe4, 0xae, 0x32, 0xa6, 0xba, 0x5d,
+ 0x86, 0xdd, 0x1c, 0x66, 0xb1, 0x18, 0xaf, 0xc5, 0xfe, 0x44, 0xb9, 0xfb,
+ 0xe5, 0x5a, 0x5a, 0x1e, 0x45, 0x4a, 0x8b, 0xec, 0x3c, 0x7d, 0xed, 0xc0,
+ 0x02, 0x53, 0xa5, 0xb1, 0x5c, 0xdb, 0xf6, 0x25, 0xa0, 0xeb, 0xee, 0x16,
+ 0x84, 0x79, 0xde
};
-unsigned int ClientRSA_Key_der_len = 607;
+unsigned int ClientRSA_Key_der_len = 1191;
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 2c:10:5b:40:8c:b3:1f:3c:c8:37:ae:60:be:7e:23:eb:1a:79:95
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: CN=SecurityTest CA Cert (ECC)
+ Validity
+ Not Before: May 26 01:25:20 2018 GMT
+ Not After : May 17 01:25:20 2055 GMT
+ Subject: OU=SecurityTests Server Cert (ECC), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:2d:d9:4f:91:d0:70:46:ad:b7:29:02:54:a5:e0:
+ b0:a8:d1:58:b5:1f:a6:b1:bf:f9:5c:5d:30:ea:ac:
+ 7d:76:dc:6b:57:84:2e:87:25:39:03:63:62:1f:1b:
+ a7:df:4e:f6:ed:8c:48:44:ed:8a:d8:52:5e:e5:42:
+ c3:5b:e6:01:2d
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Subject Alternative Name:
+ DNS:localhost
+ X509v3 Subject Key Identifier:
+ 5A:27:76:15:E3:AA:09:29:08:95:B9:CF:D1:BF:47:40:13:2A:C6:FF
+ X509v3 Authority Key Identifier:
+ keyid:2A:8E:DC:15:F2:1D:69:64:39:77:8F:EE:F4:6D:3F:34:D9:85:F0:8C
+
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:44:02:20:51:82:14:47:09:3f:6c:d6:bc:81:3e:84:26:b4:
+ f4:4f:99:cf:25:93:80:43:4b:b3:7f:36:0f:bb:da:77:43:6d:
+ 02:20:67:85:8f:8e:d7:ca:1f:25:24:30:09:0a:60:f1:ee:f7:
+ 04:8a:ef:9b:11:c8:ba:cc:db:06:d2:18:b2:48:60:35
-----BEGIN CERTIFICATE-----
-MIIBXzCCAQagAwIBAgIBBDAJBgcqhkjOPQQBMCUxIzAhBgNVBAMTGlNlY3VyaXR5
-VGVzdCBDQSBDZXJ0IChFQ0MpMCAXDTE1MDMyMzA3MTAyNloYDzIwNTUwMzEzMDcx
-MDI2WjA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIFNlcnZlciBDZXJ0IChFQ0Mp
-MRIwEAYDVQQDEwlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQt
-2U+R0HBGrbcpAlSl4LCo0Vi1H6axv/lcXTDqrH123GtXhC6HJTkDY2IfG6ffTvbt
-jEhE7YrYUl7lQsNb5gEtow0wCzAJBgNVHRMEAjAAMAkGByqGSM49BAEDSAAwRQIh
-AKLHCOfKzXS5bsWYdbCdRdwaYL49gpWTVJqOvCVhbF7AAiBnDDTkKjUu+23OgpKv
-eCU1XVcB3uIEwy/DOUU1xW9RkA==
+MIIB8jCCAZmgAwIBAgITLBBbQIyzHzzIN65gvn4j6xp5lTAKBggqhkjOPQQDAjAl
+MSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xODA1MjYw
+MTI1MjBaGA8yMDU1MDUxNzAxMjUyMFowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0
+cyBTZXJ2ZXIgQ2VydCAoRUNDKTESMBAGA1UEAxMJbG9jYWxob3N0MFkwEwYHKoZI
+zj0CAQYIKoZIzj0DAQcDQgAELdlPkdBwRq23KQJUpeCwqNFYtR+msb/5XF0w6qx9
+dtxrV4QuhyU5A2NiHxun30727YxIRO2K2FJe5ULDW+YBLaOBjDCBiTAMBgNVHRMB
+Af8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNV
+HREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFFondhXjqgkpCJW5z9G/R0ATKsb/
+MB8GA1UdIwQYMBaAFCqO3BXyHWlkOXeP7vRtPzTZhfCMMAoGCCqGSM49BAMCA0cA
+MEQCIFGCFEcJP2zWvIE+hCa09E+ZzyWTgENLs382D7vad0NtAiBnhY+O18ofJSQw
+CQpg8e73BIrvmxHIuszbBtIYskhgNQ==
-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ b9:18:42:fe:df:e7:25:9c:ce:fa:d7:d0:e8:56:e3:d5:d3:20:94
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=SecurityTest CA Cert (RSA)
+ Validity
+ Not Before: May 25 23:48:59 2018 GMT
+ Not After : May 16 23:48:59 2055 GMT
+ Subject: OU=SecurityTests Server Cert (ECC), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:2d:d9:4f:91:d0:70:46:ad:b7:29:02:54:a5:e0:
+ b0:a8:d1:58:b5:1f:a6:b1:bf:f9:5c:5d:30:ea:ac:
+ 7d:76:dc:6b:57:84:2e:87:25:39:03:63:62:1f:1b:
+ a7:df:4e:f6:ed:8c:48:44:ed:8a:d8:52:5e:e5:42:
+ c3:5b:e6:01:2d
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Subject Alternative Name:
+ DNS:localhost
+ X509v3 Subject Key Identifier:
+ 5A:27:76:15:E3:AA:09:29:08:95:B9:CF:D1:BF:47:40:13:2A:C6:FF
+ X509v3 Authority Key Identifier:
+ keyid:5D:A7:1B:3B:57:D2:0E:08:1E:AA:47:CF:03:34:68:BE:53:00:D9:64
+
+ Signature Algorithm: sha256WithRSAEncryption
+ c3:87:06:61:77:9e:53:35:12:0f:4e:f8:8c:52:69:18:aa:b0:
+ c5:27:b2:1c:7c:0c:be:04:f6:9e:2a:8e:fd:84:82:2d:ff:b7:
+ 64:17:3e:59:f2:d3:64:52:f1:6e:17:79:8e:ef:81:15:52:02:
+ d3:6e:00:e6:da:90:50:4d:46:21:e4:3a:88:e6:87:59:5a:b6:
+ da:ff:ed:0a:70:af:3c:48:50:c2:91:49:a5:80:41:89:81:ae:
+ df:1c:6d:d6:0e:84:2c:f9:4f:82:8b:94:65:07:13:ed:2e:06:
+ 4d:2e:15:16:4c:15:bd:fb:14:35:d7:7e:81:94:68:8e:84:c0:
+ 30:0a:16:25:d8:f8:d9:73:e9:19:96:6c:a7:f7:ce:4a:53:0d:
+ 14:ee:a2:9d:45:3f:f7:a8:2f:5d:61:2f:11:ed:bd:84:36:b6:
+ a3:76:1c:77:b8:ec:5e:52:be:90:4c:02:d3:fb:bd:a4:1f:49:
+ d8:74:18:07:68:00:b8:01:91:88:75:3a:3f:78:69:00:4d:d9:
+ 09:3b:de:15:b7:5b:92:91:94:5b:f3:0f:1d:de:11:1c:84:c0:
+ f1:70:50:24:ad:d0:d8:3e:46:98:67:d9:a5:6c:1f:41:90:4c:
+ 8a:71:60:ac:59:4e:1f:08:21:e1:16:83:b2:e6:1c:7f:1d:0b:
+ fc:06:ac:05
-----BEGIN CERTIFICATE-----
-MIICIjCCAQqgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAlMSMwIQYDVQQDExpTZWN1
-cml0eVRlc3QgQ0EgQ2VydCAoUlNBKTAgFw0xNTAzMjMwNzEwMjZaGA8yMDU1MDMx
-MzA3MTAyNlowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0cyBTZXJ2ZXIgQ2VydCAo
-RUNDKTESMBAGA1UEAxMJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
-QgAELdlPkdBwRq23KQJUpeCwqNFYtR+msb/5XF0w6qx9dtxrV4QuhyU5A2NiHxun
-30727YxIRO2K2FJe5ULDW+YBLaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQUF
-AAOCAQEArwIdgAVDfhbYWlND10NAr7dwc5IhgYq2whK0jRu/VaSY/U7GttWj5Du8
-3Kzt2Q+tr6zScYjOKHktEpQQFjV8o8RSN4DhKvkS7vvvvLIjfGRQJhr1XeOvgfxM
-6v3vgEEWFQvZxwUFMULFiVnJI8JlugILSO9VEAe6xlG3U/W2BnWWaIJuDBM8W1GG
-2bzGQNxQC/Kmdli/dSOBH93hTqsOYmmjjuYp9KgMpQdiknryTmqZKS5TtoAH6dyQ
-r4Aem6l2/QRU+EFcH6FdmtdusYv3n1pp0JwrrrxFBjAVR60gCZSkV9Kme8EoHTvC
-QdROQfUKstCfQFj1Qux4B9xxOJHPag==
+MIICtTCCAZ2gAwIBAgIUALkYQv7f5yWczvrX0OhW49XTIJQwDQYJKoZIhvcNAQEL
+BQAwJTEjMCEGA1UEAxMaU2VjdXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTgw
+NTI1MjM0ODU5WhgPMjA1NTA1MTYyMzQ4NTlaMD4xKDAmBgNVBAsTH1NlY3VyaXR5
+VGVzdHMgU2VydmVyIENlcnQgKEVDQykxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMG
+ByqGSM49AgEGCCqGSM49AwEHA0IABC3ZT5HQcEattykCVKXgsKjRWLUfprG/+Vxd
+MOqsfXbca1eELoclOQNjYh8bp99O9u2MSETtithSXuVCw1vmAS2jgYwwgYkwDAYD
+VR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEw
+FAYDVR0RBA0wC4IJbG9jYWxob3N0MB0GA1UdDgQWBBRaJ3YV46oJKQiVuc/Rv0dA
+EyrG/zAfBgNVHSMEGDAWgBRdpxs7V9IOCB6qR88DNGi+UwDZZDANBgkqhkiG9w0B
+AQsFAAOCAQEAw4cGYXeeUzUSD074jFJpGKqwxSeyHHwMvgT2niqO/YSCLf+3ZBc+
+WfLTZFLxbhd5ju+BFVIC024A5tqQUE1GIeQ6iOaHWVq22v/tCnCvPEhQwpFJpYBB
+iYGu3xxt1g6ELPlPgouUZQcT7S4GTS4VFkwVvfsUNdd+gZRojoTAMAoWJdj42XPp
+GZZsp/fOSlMNFO6inUU/96gvXWEvEe29hDa2o3Ycd7jsXlK+kEwC0/u9pB9J2HQY
+B2gAuAGRiHU6P3hpAE3ZCTveFbdbkpGUW/MPHd4RHITA8XBQJK3Q2D5GmGfZpWwf
+QZBMinFgrFlOHwgh4RaDsuYcfx0L/AasBQ==
-----END CERTIFICATE-----
unsigned char ServerECC_Cert_CA_ECC_der[] = {
- 0x30, 0x82, 0x01, 0x5f, 0x30, 0x82, 0x01, 0x06, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x04, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x01, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x35,
- 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x18,
- 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, 0x33, 0x30, 0x37, 0x31,
- 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03,
- 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
- 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65,
- 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29,
- 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c,
- 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, 0x30, 0x13,
- 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
- 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x2d,
- 0xd9, 0x4f, 0x91, 0xd0, 0x70, 0x46, 0xad, 0xb7, 0x29, 0x02, 0x54, 0xa5,
- 0xe0, 0xb0, 0xa8, 0xd1, 0x58, 0xb5, 0x1f, 0xa6, 0xb1, 0xbf, 0xf9, 0x5c,
- 0x5d, 0x30, 0xea, 0xac, 0x7d, 0x76, 0xdc, 0x6b, 0x57, 0x84, 0x2e, 0x87,
- 0x25, 0x39, 0x03, 0x63, 0x62, 0x1f, 0x1b, 0xa7, 0xdf, 0x4e, 0xf6, 0xed,
- 0x8c, 0x48, 0x44, 0xed, 0x8a, 0xd8, 0x52, 0x5e, 0xe5, 0x42, 0xc3, 0x5b,
- 0xe6, 0x01, 0x2d, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86,
- 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21,
- 0x00, 0xa2, 0xc7, 0x08, 0xe7, 0xca, 0xcd, 0x74, 0xb9, 0x6e, 0xc5, 0x98,
- 0x75, 0xb0, 0x9d, 0x45, 0xdc, 0x1a, 0x60, 0xbe, 0x3d, 0x82, 0x95, 0x93,
- 0x54, 0x9a, 0x8e, 0xbc, 0x25, 0x61, 0x6c, 0x5e, 0xc0, 0x02, 0x20, 0x67,
- 0x0c, 0x34, 0xe4, 0x2a, 0x35, 0x2e, 0xfb, 0x6d, 0xce, 0x82, 0x92, 0xaf,
- 0x78, 0x25, 0x35, 0x5d, 0x57, 0x01, 0xde, 0xe2, 0x04, 0xc3, 0x2f, 0xc3,
- 0x39, 0x45, 0x35, 0xc5, 0x6f, 0x51, 0x90
+ 0x30, 0x82, 0x01, 0xf2, 0x30, 0x82, 0x01, 0x99, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x13, 0x2c, 0x10, 0x5b, 0x40, 0x8c, 0xb3, 0x1f, 0x3c, 0xc8,
+ 0x37, 0xae, 0x60, 0xbe, 0x7e, 0x23, 0xeb, 0x1a, 0x79, 0x95, 0x30, 0x0a,
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25,
+ 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20,
+ 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43,
+ 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x32, 0x36, 0x30,
+ 0x31, 0x32, 0x35, 0x32, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35,
+ 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x35, 0x32, 0x30, 0x5a, 0x30,
+ 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74,
+ 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72,
+ 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
+ 0x6f, 0x73, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48,
+ 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
+ 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x2d, 0xd9, 0x4f, 0x91, 0xd0, 0x70,
+ 0x46, 0xad, 0xb7, 0x29, 0x02, 0x54, 0xa5, 0xe0, 0xb0, 0xa8, 0xd1, 0x58,
+ 0xb5, 0x1f, 0xa6, 0xb1, 0xbf, 0xf9, 0x5c, 0x5d, 0x30, 0xea, 0xac, 0x7d,
+ 0x76, 0xdc, 0x6b, 0x57, 0x84, 0x2e, 0x87, 0x25, 0x39, 0x03, 0x63, 0x62,
+ 0x1f, 0x1b, 0xa7, 0xdf, 0x4e, 0xf6, 0xed, 0x8c, 0x48, 0x44, 0xed, 0x8a,
+ 0xd8, 0x52, 0x5e, 0xe5, 0x42, 0xc3, 0x5b, 0xe6, 0x01, 0x2d, 0xa3, 0x81,
+ 0x8c, 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+ 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13,
+ 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55,
+ 0x1d, 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61,
+ 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+ 0x04, 0x16, 0x04, 0x14, 0x5a, 0x27, 0x76, 0x15, 0xe3, 0xaa, 0x09, 0x29,
+ 0x08, 0x95, 0xb9, 0xcf, 0xd1, 0xbf, 0x47, 0x40, 0x13, 0x2a, 0xc6, 0xff,
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+ 0x14, 0x2a, 0x8e, 0xdc, 0x15, 0xf2, 0x1d, 0x69, 0x64, 0x39, 0x77, 0x8f,
+ 0xee, 0xf4, 0x6d, 0x3f, 0x34, 0xd9, 0x85, 0xf0, 0x8c, 0x30, 0x0a, 0x06,
+ 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00,
+ 0x30, 0x44, 0x02, 0x20, 0x51, 0x82, 0x14, 0x47, 0x09, 0x3f, 0x6c, 0xd6,
+ 0xbc, 0x81, 0x3e, 0x84, 0x26, 0xb4, 0xf4, 0x4f, 0x99, 0xcf, 0x25, 0x93,
+ 0x80, 0x43, 0x4b, 0xb3, 0x7f, 0x36, 0x0f, 0xbb, 0xda, 0x77, 0x43, 0x6d,
+ 0x02, 0x20, 0x67, 0x85, 0x8f, 0x8e, 0xd7, 0xca, 0x1f, 0x25, 0x24, 0x30,
+ 0x09, 0x0a, 0x60, 0xf1, 0xee, 0xf7, 0x04, 0x8a, 0xef, 0x9b, 0x11, 0xc8,
+ 0xba, 0xcc, 0xdb, 0x06, 0xd2, 0x18, 0xb2, 0x48, 0x60, 0x35
};
-unsigned int ServerECC_Cert_CA_ECC_der_len = 355;
+unsigned int ServerECC_Cert_CA_ECC_der_len = 502;
unsigned char ServerECC_Cert_CA_RSA_der[] = {
- 0x30, 0x82, 0x02, 0x22, 0x30, 0x82, 0x01, 0x0a, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30,
- 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75,
- 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20,
- 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30,
- 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31,
- 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28,
- 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53,
- 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28,
- 0x45, 0x43, 0x43, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
- 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
- 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
- 0x42, 0x00, 0x04, 0x2d, 0xd9, 0x4f, 0x91, 0xd0, 0x70, 0x46, 0xad, 0xb7,
- 0x29, 0x02, 0x54, 0xa5, 0xe0, 0xb0, 0xa8, 0xd1, 0x58, 0xb5, 0x1f, 0xa6,
- 0xb1, 0xbf, 0xf9, 0x5c, 0x5d, 0x30, 0xea, 0xac, 0x7d, 0x76, 0xdc, 0x6b,
- 0x57, 0x84, 0x2e, 0x87, 0x25, 0x39, 0x03, 0x63, 0x62, 0x1f, 0x1b, 0xa7,
- 0xdf, 0x4e, 0xf6, 0xed, 0x8c, 0x48, 0x44, 0xed, 0x8a, 0xd8, 0x52, 0x5e,
- 0xe5, 0x42, 0xc3, 0x5b, 0xe6, 0x01, 0x2d, 0xa3, 0x0d, 0x30, 0x0b, 0x30,
- 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x02, 0x1d, 0x80, 0x05, 0x43,
- 0x7e, 0x16, 0xd8, 0x5a, 0x53, 0x43, 0xd7, 0x43, 0x40, 0xaf, 0xb7, 0x70,
- 0x73, 0x92, 0x21, 0x81, 0x8a, 0xb6, 0xc2, 0x12, 0xb4, 0x8d, 0x1b, 0xbf,
- 0x55, 0xa4, 0x98, 0xfd, 0x4e, 0xc6, 0xb6, 0xd5, 0xa3, 0xe4, 0x3b, 0xbc,
- 0xdc, 0xac, 0xed, 0xd9, 0x0f, 0xad, 0xaf, 0xac, 0xd2, 0x71, 0x88, 0xce,
- 0x28, 0x79, 0x2d, 0x12, 0x94, 0x10, 0x16, 0x35, 0x7c, 0xa3, 0xc4, 0x52,
- 0x37, 0x80, 0xe1, 0x2a, 0xf9, 0x12, 0xee, 0xfb, 0xef, 0xbc, 0xb2, 0x23,
- 0x7c, 0x64, 0x50, 0x26, 0x1a, 0xf5, 0x5d, 0xe3, 0xaf, 0x81, 0xfc, 0x4c,
- 0xea, 0xfd, 0xef, 0x80, 0x41, 0x16, 0x15, 0x0b, 0xd9, 0xc7, 0x05, 0x05,
- 0x31, 0x42, 0xc5, 0x89, 0x59, 0xc9, 0x23, 0xc2, 0x65, 0xba, 0x02, 0x0b,
- 0x48, 0xef, 0x55, 0x10, 0x07, 0xba, 0xc6, 0x51, 0xb7, 0x53, 0xf5, 0xb6,
- 0x06, 0x75, 0x96, 0x68, 0x82, 0x6e, 0x0c, 0x13, 0x3c, 0x5b, 0x51, 0x86,
- 0xd9, 0xbc, 0xc6, 0x40, 0xdc, 0x50, 0x0b, 0xf2, 0xa6, 0x76, 0x58, 0xbf,
- 0x75, 0x23, 0x81, 0x1f, 0xdd, 0xe1, 0x4e, 0xab, 0x0e, 0x62, 0x69, 0xa3,
- 0x8e, 0xe6, 0x29, 0xf4, 0xa8, 0x0c, 0xa5, 0x07, 0x62, 0x92, 0x7a, 0xf2,
- 0x4e, 0x6a, 0x99, 0x29, 0x2e, 0x53, 0xb6, 0x80, 0x07, 0xe9, 0xdc, 0x90,
- 0xaf, 0x80, 0x1e, 0x9b, 0xa9, 0x76, 0xfd, 0x04, 0x54, 0xf8, 0x41, 0x5c,
- 0x1f, 0xa1, 0x5d, 0x9a, 0xd7, 0x6e, 0xb1, 0x8b, 0xf7, 0x9f, 0x5a, 0x69,
- 0xd0, 0x9c, 0x2b, 0xae, 0xbc, 0x45, 0x06, 0x30, 0x15, 0x47, 0xad, 0x20,
- 0x09, 0x94, 0xa4, 0x57, 0xd2, 0xa6, 0x7b, 0xc1, 0x28, 0x1d, 0x3b, 0xc2,
- 0x41, 0xd4, 0x4e, 0x41, 0xf5, 0x0a, 0xb2, 0xd0, 0x9f, 0x40, 0x58, 0xf5,
- 0x42, 0xec, 0x78, 0x07, 0xdc, 0x71, 0x38, 0x91, 0xcf, 0x6a
+ 0x30, 0x82, 0x02, 0xb5, 0x30, 0x82, 0x01, 0x9d, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x14, 0x00, 0xb9, 0x18, 0x42, 0xfe, 0xdf, 0xe7, 0x25, 0x9c,
+ 0xce, 0xfa, 0xd7, 0xd0, 0xe8, 0x56, 0xe3, 0xd5, 0xd3, 0x20, 0x94, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54,
+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
+ 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30,
+ 0x35, 0x32, 0x35, 0x32, 0x33, 0x34, 0x38, 0x35, 0x39, 0x5a, 0x18, 0x0f,
+ 0x32, 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x36, 0x32, 0x33, 0x34, 0x38,
+ 0x35, 0x39, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+ 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+ 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x31,
+ 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f,
+ 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06,
+ 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86,
+ 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x2d, 0xd9,
+ 0x4f, 0x91, 0xd0, 0x70, 0x46, 0xad, 0xb7, 0x29, 0x02, 0x54, 0xa5, 0xe0,
+ 0xb0, 0xa8, 0xd1, 0x58, 0xb5, 0x1f, 0xa6, 0xb1, 0xbf, 0xf9, 0x5c, 0x5d,
+ 0x30, 0xea, 0xac, 0x7d, 0x76, 0xdc, 0x6b, 0x57, 0x84, 0x2e, 0x87, 0x25,
+ 0x39, 0x03, 0x63, 0x62, 0x1f, 0x1b, 0xa7, 0xdf, 0x4e, 0xf6, 0xed, 0x8c,
+ 0x48, 0x44, 0xed, 0x8a, 0xd8, 0x52, 0x5e, 0xe5, 0x42, 0xc3, 0x5b, 0xe6,
+ 0x01, 0x2d, 0xa3, 0x81, 0x8c, 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03,
+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
+ 0x05, 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30,
+ 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30,
+ 0x14, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09,
+ 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06,
+ 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x5a, 0x27, 0x76, 0x15,
+ 0xe3, 0xaa, 0x09, 0x29, 0x08, 0x95, 0xb9, 0xcf, 0xd1, 0xbf, 0x47, 0x40,
+ 0x13, 0x2a, 0xc6, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0x5d, 0xa7, 0x1b, 0x3b, 0x57, 0xd2, 0x0e,
+ 0x08, 0x1e, 0xaa, 0x47, 0xcf, 0x03, 0x34, 0x68, 0xbe, 0x53, 0x00, 0xd9,
+ 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xc3, 0x87, 0x06,
+ 0x61, 0x77, 0x9e, 0x53, 0x35, 0x12, 0x0f, 0x4e, 0xf8, 0x8c, 0x52, 0x69,
+ 0x18, 0xaa, 0xb0, 0xc5, 0x27, 0xb2, 0x1c, 0x7c, 0x0c, 0xbe, 0x04, 0xf6,
+ 0x9e, 0x2a, 0x8e, 0xfd, 0x84, 0x82, 0x2d, 0xff, 0xb7, 0x64, 0x17, 0x3e,
+ 0x59, 0xf2, 0xd3, 0x64, 0x52, 0xf1, 0x6e, 0x17, 0x79, 0x8e, 0xef, 0x81,
+ 0x15, 0x52, 0x02, 0xd3, 0x6e, 0x00, 0xe6, 0xda, 0x90, 0x50, 0x4d, 0x46,
+ 0x21, 0xe4, 0x3a, 0x88, 0xe6, 0x87, 0x59, 0x5a, 0xb6, 0xda, 0xff, 0xed,
+ 0x0a, 0x70, 0xaf, 0x3c, 0x48, 0x50, 0xc2, 0x91, 0x49, 0xa5, 0x80, 0x41,
+ 0x89, 0x81, 0xae, 0xdf, 0x1c, 0x6d, 0xd6, 0x0e, 0x84, 0x2c, 0xf9, 0x4f,
+ 0x82, 0x8b, 0x94, 0x65, 0x07, 0x13, 0xed, 0x2e, 0x06, 0x4d, 0x2e, 0x15,
+ 0x16, 0x4c, 0x15, 0xbd, 0xfb, 0x14, 0x35, 0xd7, 0x7e, 0x81, 0x94, 0x68,
+ 0x8e, 0x84, 0xc0, 0x30, 0x0a, 0x16, 0x25, 0xd8, 0xf8, 0xd9, 0x73, 0xe9,
+ 0x19, 0x96, 0x6c, 0xa7, 0xf7, 0xce, 0x4a, 0x53, 0x0d, 0x14, 0xee, 0xa2,
+ 0x9d, 0x45, 0x3f, 0xf7, 0xa8, 0x2f, 0x5d, 0x61, 0x2f, 0x11, 0xed, 0xbd,
+ 0x84, 0x36, 0xb6, 0xa3, 0x76, 0x1c, 0x77, 0xb8, 0xec, 0x5e, 0x52, 0xbe,
+ 0x90, 0x4c, 0x02, 0xd3, 0xfb, 0xbd, 0xa4, 0x1f, 0x49, 0xd8, 0x74, 0x18,
+ 0x07, 0x68, 0x00, 0xb8, 0x01, 0x91, 0x88, 0x75, 0x3a, 0x3f, 0x78, 0x69,
+ 0x00, 0x4d, 0xd9, 0x09, 0x3b, 0xde, 0x15, 0xb7, 0x5b, 0x92, 0x91, 0x94,
+ 0x5b, 0xf3, 0x0f, 0x1d, 0xde, 0x11, 0x1c, 0x84, 0xc0, 0xf1, 0x70, 0x50,
+ 0x24, 0xad, 0xd0, 0xd8, 0x3e, 0x46, 0x98, 0x67, 0xd9, 0xa5, 0x6c, 0x1f,
+ 0x41, 0x90, 0x4c, 0x8a, 0x71, 0x60, 0xac, 0x59, 0x4e, 0x1f, 0x08, 0x21,
+ 0xe1, 0x16, 0x83, 0xb2, 0xe6, 0x1c, 0x7f, 0x1d, 0x0b, 0xfc, 0x06, 0xac,
+ 0x05
};
-unsigned int ServerECC_Cert_CA_RSA_der_len = 550;
+unsigned int ServerECC_Cert_CA_RSA_der_len = 697;
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 2c:10:5b:40:8c:b3:1f:3c:c8:37:ae:60:be:7e:23:eb:1a:79:94
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: CN=SecurityTest CA Cert (ECC)
+ Validity
+ Not Before: May 26 01:25:05 2018 GMT
+ Not After : May 17 01:25:05 2055 GMT
+ Subject: OU=SecurityTests Server Cert (RSA), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b1:d0:30:71:42:b1:df:f4:79:ea:e9:7a:ae:53:
+ c2:7f:a9:2e:5f:cc:a3:6e:96:0d:d1:42:2e:ba:da:
+ 06:91:61:e6:10:63:b9:39:41:eb:06:e2:51:d2:65:
+ db:64:0d:2e:7f:a5:45:bb:0f:a8:26:17:45:66:b0:
+ 7e:1c:44:4c:f6:5c:8f:fe:68:24:eb:73:c7:42:60:
+ d3:96:2a:e8:4e:3e:ac:61:36:5d:53:b2:31:ae:81:
+ 12:00:20:48:89:6b:a5:50:2e:01:b9:5a:31:b6:55:
+ 8e:14:2c:32:50:9e:44:a7:0e:61:26:ee:fc:22:0a:
+ e0:f5:af:68:1b:5f:ed:20:3d:61:59:38:00:8b:18:
+ 39:fd:48:14:90:68:5d:3e:b8:bd:e1:25:6d:d4:dc:
+ c4:2b:cc:ec:51:2b:92:32:06:ac:58:25:a7:a6:6e:
+ 12:9c:85:a2:6a:3a:2c:07:cb:f0:4a:47:85:14:1f:
+ 1b:bd:c8:e6:54:b8:89:7c:1a:fa:bf:93:28:d4:65:
+ 38:0d:f3:24:cf:14:f9:ff:0e:d3:e5:fd:5e:09:1a:
+ 8a:e8:64:36:25:9d:ce:ae:bf:1b:74:b8:37:8b:d5:
+ 00:59:14:e5:33:8f:f4:5c:33:23:2c:9f:64:1b:65:
+ 9a:b2:f2:6a:cb:2a:a0:af:04:93:8f:66:f9:eb:2b:
+ 4b:91
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Subject Alternative Name:
+ DNS:localhost
+ X509v3 Subject Key Identifier:
+ C1:70:26:38:44:78:79:AB:FD:87:87:94:56:83:8C:C8:08:56:DB:98
+ X509v3 Authority Key Identifier:
+ keyid:2A:8E:DC:15:F2:1D:69:64:39:77:8F:EE:F4:6D:3F:34:D9:85:F0:8C
+
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:45:02:20:1c:72:67:58:df:e3:e3:41:9b:ef:ba:dc:8f:18:
+ 4a:c8:84:9a:54:0c:7e:ad:ce:0b:89:9a:8b:9c:6f:3e:34:19:
+ 02:21:00:a3:25:87:af:fc:38:1e:0a:82:f5:bd:70:28:5c:17:
+ fd:b9:03:3b:c3:7f:97:ca:ff:fe:49:70:1e:e7:55:14:c1
-----BEGIN CERTIFICATE-----
-MIIBpzCCAU2gAwIBAgIBAjAJBgcqhkjOPQQBMCUxIzAhBgNVBAMTGlNlY3VyaXR5
-VGVzdCBDQSBDZXJ0IChFQ0MpMCAXDTE1MDMyMzA3MTAyNloYDzIwNTUwMzEzMDcx
-MDI2WjA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIFNlcnZlciBDZXJ0IChSU0Ep
-MRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
-AKsFutwtswPxbGB/XoCFVCTHh27l8a52WeNLnP+iQfxA+KgzEqkbGsXo77HjdQvS
-KElIZJw9ibb4pZPQKYyeevYAIAhSCNwdF4tETjIT3LFQpfCUJVD6HuOuZhkTPiCG
-BZza2f+Pcm71wf2GribMS8ifqdY6H7aKjwQtu6RHs/v5AgMBAAGjDTALMAkGA1Ud
-EwQCMAAwCQYHKoZIzj0EAQNJADBGAiEAsfj+ftfT76cjWqE5ITgeL6v9MQ/z+YxW
-3CwoEcW+/hYCIQC5G6fgsC/GsoZbJydIG6s8nangb0/oV0773drm9TKQmw==
+MIICvjCCAmSgAwIBAgITLBBbQIyzHzzIN65gvn4j6xp5lDAKBggqhkjOPQQDAjAl
+MSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoRUNDKTAgFw0xODA1MjYw
+MTI1MDVaGA8yMDU1MDUxNzAxMjUwNVowPjEoMCYGA1UECwwfU2VjdXJpdHlUZXN0
+cyBTZXJ2ZXIgQ2VydCAoUlNBKTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsdAwcUKx3/R56ul6rlPCf6kuX8yjbpYN
+0UIuutoGkWHmEGO5OUHrBuJR0mXbZA0uf6VFuw+oJhdFZrB+HERM9lyP/mgk63PH
+QmDTliroTj6sYTZdU7IxroESACBIiWulUC4BuVoxtlWOFCwyUJ5Epw5hJu78Igrg
+9a9oG1/tID1hWTgAixg5/UgUkGhdPri94SVt1NzEK8zsUSuSMgasWCWnpm4SnIWi
+ajosB8vwSkeFFB8bvcjmVLiJfBr6v5Mo1GU4DfMkzxT5/w7T5f1eCRqK6GQ2JZ3O
+rr8bdLg3i9UAWRTlM4/0XDMjLJ9kG2WasvJqyyqgrwSTj2b56ytLkQIDAQABo4GM
+MIGJMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG
+AQUFBwMBMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNVHQ4EFgQUwXAmOER4eav9
+h4eUVoOMyAhW25gwHwYDVR0jBBgwFoAUKo7cFfIdaWQ5d4/u9G0/NNmF8IwwCgYI
+KoZIzj0EAwIDSAAwRQIgHHJnWN/j40Gb77rcjxhKyISaVAx+rc4LiZqLnG8+NBkC
+IQCjJYev/DgeCoL1vXAoXBf9uQM7w3+Xyv/+SXAe51UUwQ==
-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ b9:18:42:fe:df:e7:25:9c:ce:fa:d7:d0:e8:56:e3:d5:d3:20:93
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=SecurityTest CA Cert (RSA)
+ Validity
+ Not Before: May 25 23:48:38 2018 GMT
+ Not After : May 16 23:48:38 2055 GMT
+ Subject: OU=SecurityTests Server Cert (RSA), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b1:d0:30:71:42:b1:df:f4:79:ea:e9:7a:ae:53:
+ c2:7f:a9:2e:5f:cc:a3:6e:96:0d:d1:42:2e:ba:da:
+ 06:91:61:e6:10:63:b9:39:41:eb:06:e2:51:d2:65:
+ db:64:0d:2e:7f:a5:45:bb:0f:a8:26:17:45:66:b0:
+ 7e:1c:44:4c:f6:5c:8f:fe:68:24:eb:73:c7:42:60:
+ d3:96:2a:e8:4e:3e:ac:61:36:5d:53:b2:31:ae:81:
+ 12:00:20:48:89:6b:a5:50:2e:01:b9:5a:31:b6:55:
+ 8e:14:2c:32:50:9e:44:a7:0e:61:26:ee:fc:22:0a:
+ e0:f5:af:68:1b:5f:ed:20:3d:61:59:38:00:8b:18:
+ 39:fd:48:14:90:68:5d:3e:b8:bd:e1:25:6d:d4:dc:
+ c4:2b:cc:ec:51:2b:92:32:06:ac:58:25:a7:a6:6e:
+ 12:9c:85:a2:6a:3a:2c:07:cb:f0:4a:47:85:14:1f:
+ 1b:bd:c8:e6:54:b8:89:7c:1a:fa:bf:93:28:d4:65:
+ 38:0d:f3:24:cf:14:f9:ff:0e:d3:e5:fd:5e:09:1a:
+ 8a:e8:64:36:25:9d:ce:ae:bf:1b:74:b8:37:8b:d5:
+ 00:59:14:e5:33:8f:f4:5c:33:23:2c:9f:64:1b:65:
+ 9a:b2:f2:6a:cb:2a:a0:af:04:93:8f:66:f9:eb:2b:
+ 4b:91
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Subject Alternative Name:
+ DNS:localhost
+ X509v3 Subject Key Identifier:
+ C1:70:26:38:44:78:79:AB:FD:87:87:94:56:83:8C:C8:08:56:DB:98
+ X509v3 Authority Key Identifier:
+ keyid:5D:A7:1B:3B:57:D2:0E:08:1E:AA:47:CF:03:34:68:BE:53:00:D9:64
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 2d:d1:12:47:d2:98:b6:1c:18:2a:58:f1:a1:e4:f9:aa:0d:9d:
+ d5:bb:7d:de:e9:d2:7f:4e:68:aa:06:fd:da:5a:83:79:fd:5d:
+ 0a:d1:cd:f3:a3:bf:84:31:45:9a:3a:72:7a:57:5b:00:de:20:
+ 8b:63:30:3d:55:d1:af:2c:1e:fb:a1:ce:f6:c3:45:aa:4a:40:
+ 6b:38:f3:a6:43:36:b5:f5:cd:f8:0b:c2:f7:2f:02:73:a3:3b:
+ cb:7f:98:15:af:d2:c9:1a:df:8e:2c:02:04:53:a7:7c:4d:6a:
+ d9:0b:49:0c:9b:98:9d:1b:8c:2d:f3:9a:26:2f:e3:c6:cb:25:
+ a2:4e:a7:8d:e6:71:07:b8:f2:ba:b5:bd:88:79:62:86:31:82:
+ 86:03:dc:af:87:ed:ba:6e:57:06:7e:96:a7:b4:e8:1f:56:d4:
+ 55:80:27:aa:d0:62:fd:22:ab:2e:37:0d:47:53:12:10:e5:3b:
+ 7c:c4:4a:0a:c0:1d:10:f0:cd:c2:fe:85:58:ac:74:fe:ec:5c:
+ 32:1e:18:f0:19:fc:91:21:71:67:d0:38:bb:7c:4d:5b:a5:cd:
+ 00:1d:4e:73:5b:e8:16:d5:29:8c:72:aa:a3:b5:5d:ee:84:b1:
+ 04:fb:0b:3d:4d:7c:0f:7e:63:bb:7d:17:a3:4a:ff:3e:e0:f6:
+ b5:77:cc:3b
-----BEGIN CERTIFICATE-----
-MIICaTCCAVGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAlMSMwIQYDVQQDExpTZWN1
-cml0eVRlc3QgQ0EgQ2VydCAoUlNBKTAgFw0xNTAzMjMwNzEwMjZaGA8yMDU1MDMx
-MzA3MTAyNlowPjEoMCYGA1UECxMfU2VjdXJpdHlUZXN0cyBTZXJ2ZXIgQ2VydCAo
-UlNBKTESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
-iQKBgQCrBbrcLbMD8Wxgf16AhVQkx4du5fGudlnjS5z/okH8QPioMxKpGxrF6O+x
-43UL0ihJSGScPYm2+KWT0CmMnnr2ACAIUgjcHReLRE4yE9yxUKXwlCVQ+h7jrmYZ
-Ez4ghgWc2tn/j3Ju9cH9hq4mzEvIn6nWOh+2io8ELbukR7P7+QIDAQABow0wCzAJ
-BgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQCnNWPICveuD+gQULB5BKXzSF0K
-emvQ7xdD5SHUu++sBCFQfdjo8T/Rt6WTtKjsI7622cy+PIE0JSSBHtmM1iAUNoMp
-f1bNw5DQLVSLBcursfJE/Lpzv5fCK1pqSScpfLexSh8oQQVjWI7VfkZ0EQFykx/q
-9zdK+oRTtjwO3uUcEoYK9ousyLWam9IoFRiDCvxHGs/toZVOzDwqmt8J7Cgg/cVC
-8dgvIYjs4iSy4kVazrR4szA4DhxqowQOrKSX48FGCp1lmukCEvCIWMbe5SNCPFhS
-Jxri9UohR7ITDLLQzLP9ZiqmOFvmLpCeYj9+YO7UAlh9XPg5J6nbPiQ8wN7I
+MIIDgDCCAmigAwIBAgIUALkYQv7f5yWczvrX0OhW49XTIJMwDQYJKoZIhvcNAQEL
+BQAwJTEjMCEGA1UEAxMaU2VjdXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTgw
+NTI1MjM0ODM4WhgPMjA1NTA1MTYyMzQ4MzhaMD4xKDAmBgNVBAsMH1NlY3VyaXR5
+VGVzdHMgU2VydmVyIENlcnQgKFJTQSkxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHQMHFCsd/0eerpeq5Twn+pLl/M
+o26WDdFCLrraBpFh5hBjuTlB6wbiUdJl22QNLn+lRbsPqCYXRWawfhxETPZcj/5o
+JOtzx0Jg05Yq6E4+rGE2XVOyMa6BEgAgSIlrpVAuAblaMbZVjhQsMlCeRKcOYSbu
+/CIK4PWvaBtf7SA9YVk4AIsYOf1IFJBoXT64veElbdTcxCvM7FErkjIGrFglp6Zu
+EpyFomo6LAfL8EpHhRQfG73I5lS4iXwa+r+TKNRlOA3zJM8U+f8O0+X9Xgkaiuhk
+NiWdzq6/G3S4N4vVAFkU5TOP9FwzIyyfZBtlmrLyassqoK8Ek49m+esrS5ECAwEA
+AaOBjDCBiTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAK
+BggrBgEFBQcDATAUBgNVHREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFMFwJjhE
+eHmr/YeHlFaDjMgIVtuYMB8GA1UdIwQYMBaAFF2nGztX0g4IHqpHzwM0aL5TANlk
+MA0GCSqGSIb3DQEBCwUAA4IBAQAt0RJH0pi2HBgqWPGh5PmqDZ3Vu33e6dJ/Tmiq
+Bv3aWoN5/V0K0c3zo7+EMUWaOnJ6V1sA3iCLYzA9VdGvLB77oc72w0WqSkBrOPOm
+Qza19c34C8L3LwJzozvLf5gVr9LJGt+OLAIEU6d8TWrZC0kMm5idG4wt85omL+PG
+yyWiTqeN5nEHuPK6tb2IeWKGMYKGA9yvh+26blcGfpantOgfVtRVgCeq0GL9Iqsu
+Nw1HUxIQ5Tt8xEoKwB0Q8M3C/oVYrHT+7FwyHhjwGfyRIXFn0Di7fE1bpc0AHU5z
+W+gW1SmMcqqjtV3uhLEE+ws9TXwPfmO7fRejSv8+4Pa1d8w7
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQCrBbrcLbMD8Wxgf16AhVQkx4du5fGudlnjS5z/okH8QPioMxKp
-GxrF6O+x43UL0ihJSGScPYm2+KWT0CmMnnr2ACAIUgjcHReLRE4yE9yxUKXwlCVQ
-+h7jrmYZEz4ghgWc2tn/j3Ju9cH9hq4mzEvIn6nWOh+2io8ELbukR7P7+QIDAQAB
-AoGAOATxd0u01rbO9DDkaJ7DuCRvdWD2sFnuCajr7URd7t3tVVMdaq0JMQii8xb5
-cPzO22pOImt536hEvE00Pu5ugfrl9GKVMM5JEUIrLmqHDGofryLsMms+G8PLtEbW
-FNBSa0xjdMu+6/i/MdbjQh93aPLy8PQkEF+cPFy7WxntMAECQQDScovZGo3LolZr
-O3jzetSXkM3NWjIGPbDC+5+VUWPPzVzLS6flX9DTWsiS4d7gg4b+3eG0AHIltCAZ
-9pT4/U4BAkEA0AqJKplJNWAUjSzncqAZ1oZgDaZEiTCY6uvf+7VWIzzkyXZPkI5V
-fVHLQfFzsKmLNvka/m+jLhMwxOMsUX0d+QJAbnJVeQSZpGS3jCGzUb2GM2F40Sxk
-Eqhvy3U5hKkphBbYe41iOVx3AWWk3ImUaio9QCd82/Zb8fO94UJrXt26AQJAa1YU
-QSNHLz+8Or6BR5Ws3w8DfedcEwA81XAPZxm/MH0ZeYwOLwIQv5C08vf1fZ9sEVfj
-AoVsxrfmAJ9I3V5VWQJAUbWvNkuRbIkZRJZsSpRYKVw41Gsk3DuxZsE8yBeXtwXZ
-GLZDFvj5Xu1+b8SmajrHwCFrOazz9kDVJfdEHdSyNw==
+MIIEpAIBAAKCAQEAsdAwcUKx3/R56ul6rlPCf6kuX8yjbpYN0UIuutoGkWHmEGO5
+OUHrBuJR0mXbZA0uf6VFuw+oJhdFZrB+HERM9lyP/mgk63PHQmDTliroTj6sYTZd
+U7IxroESACBIiWulUC4BuVoxtlWOFCwyUJ5Epw5hJu78Igrg9a9oG1/tID1hWTgA
+ixg5/UgUkGhdPri94SVt1NzEK8zsUSuSMgasWCWnpm4SnIWiajosB8vwSkeFFB8b
+vcjmVLiJfBr6v5Mo1GU4DfMkzxT5/w7T5f1eCRqK6GQ2JZ3Orr8bdLg3i9UAWRTl
+M4/0XDMjLJ9kG2WasvJqyyqgrwSTj2b56ytLkQIDAQABAoIBAHYqtda/DPiZPuB3
+cxkg/tPZ+cCefUoDnIEha26vb8fz+HGR5EkB3o//nYKmQCt4extHGVUcLZHKy0tY
+JSbh2QesMeFPEqIKmjQpptNYBnPhQKuF9nWlqVCf4/eDfNEeYYksWeb04q6aosYT
+LQjYdSVT8Apwrcxt0FxVymjO0gYmx9VrES0+2AH6B2OyMo6Ew4n9NoX3ZAeTJYZq
+R8N8xa9j6PMMO/vGATTVeIUQzcI332BMvuBm7CCUKQeIuUjf0xxL0m8CSsVoEyvg
+jGw2yQvcSaO2kFTbj6/YeQvHazx1gXwVWbzJbT1ZrwH0WZUUwEJfqVe78XapuVYP
+Hzs7WgECgYEA6ADZfFE3EfCBhmoVTkHzHJE+OhePx/MsI1tqH1g1ICzwbUwgn5Ub
+Y7mvs9dzvzgLZYVzbSjNQt7M/ZPJbLFVgIIOJrK2Gq3nV7rJvQHk+e7pYo3WJAkv
+bowTXBbN6RdO/5+w/cr8H2At4As4ui4oz11zEeTnCiHE62mr80LxyOECgYEAxDR0
+sjmD1OP3FL5ORb9enqIc40agYwCWUN2KNQXLN02CAMXre3Uz0lHeFhtsVJRYIMFg
+5v9ErJSGTVPMHzHrRePCeGWb0Oj5h16lSQlmq9saRCN3VDMb1Du1tI/SXZ7wmsxJ
+5TKWiSAqCEDzk8m7p6eHowLzzOUszPA7r4DkaLECgYEA4i0p2aOHj4qri3HSMYfj
+zX7fblzYBDNSXWnaTJJ+wE5vWe50g38mw5Mb8rThl5K4sZFnVQ0JBt8Uc0XngXpk
+g7LGvv1MwTe2qHVmBUhahTpf9n+WO21k+1295fIpbcsWbeit8M45+xCVyKzH8eHc
+UUSmUNSaVOtVAbf0NWSXOKECgYBWf/3WuS6aw+ohdgkSDN2NOFFeDbwWCaM7gYA2
+Ahjmh8BB0QARTMmM9tTfkDWBUGlN/5NWI8JGB7DyFHiQZDSielg5NiqsvpmMCbj6
+6y8doxoAYlZwg5vIRI7GTQXkinbu+BO3/UaKq+h7/Q6l4DFgJ6bPwjRz57GJpHvb
+0wpf8QKBgQDPi87hg50Ylghi0WaztiR7J0sIs9qdLWVBWPCjs8FAS++Vm7vEmIIc
+ozvWysJHmR4hhcxE1mAYGz8yxoxd0QRkAhGoSOVt4qxFDQSqMpunp8P3zepJDIXL
+Sq6JrlYg57w6eNVXKqozma+Dlt8ArB4L7oKnPPCyPCZg/ISsgzV6+w==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
-MIIBfTCB5wIBADA+MSgwJgYDVQQLEx9TZWN1cml0eVRlc3RzIFNlcnZlciBDZXJ0
-IChSU0EpMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
-MIGJAoGBAKsFutwtswPxbGB/XoCFVCTHh27l8a52WeNLnP+iQfxA+KgzEqkbGsXo
-77HjdQvSKElIZJw9ibb4pZPQKYyeevYAIAhSCNwdF4tETjIT3LFQpfCUJVD6HuOu
-ZhkTPiCGBZza2f+Pcm71wf2GribMS8ifqdY6H7aKjwQtu6RHs/v5AgMBAAGgADAN
-BgkqhkiG9w0BAQUFAAOBgQCn41FvcqnSHb6KOkK9n1bo132Co5lfn/ory7az66pU
-dCfBOoM366rth2/a+NfGprKnwEbDZFcwFQf3DYfU6uF2b+6GsXgntxDJpwVoQWl4
-0dsNGBfr+ZnjoE9HlNAQ4v5EpIPCp/ZwcAOSXAiEHufvuf+S6LNOnrFVNVb1LoGn
-Xw==
+MIICgzCCAWsCAQAwPjEoMCYGA1UECwwfU2VjdXJpdHlUZXN0cyBTZXJ2ZXIgQ2Vy
+dCAoUlNBKTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAsdAwcUKx3/R56ul6rlPCf6kuX8yjbpYN0UIuutoGkWHmEGO5
+OUHrBuJR0mXbZA0uf6VFuw+oJhdFZrB+HERM9lyP/mgk63PHQmDTliroTj6sYTZd
+U7IxroESACBIiWulUC4BuVoxtlWOFCwyUJ5Epw5hJu78Igrg9a9oG1/tID1hWTgA
+ixg5/UgUkGhdPri94SVt1NzEK8zsUSuSMgasWCWnpm4SnIWiajosB8vwSkeFFB8b
+vcjmVLiJfBr6v5Mo1GU4DfMkzxT5/w7T5f1eCRqK6GQ2JZ3Orr8bdLg3i9UAWRTl
+M4/0XDMjLJ9kG2WasvJqyyqgrwSTj2b56ytLkQIDAQABoAAwDQYJKoZIhvcNAQEL
+BQADggEBACSObPnNbkzEqRja47CloL8azcq6YHgoS2Oz3utsLrVi/FdbkGCO+CP9
+q71yaenmZM4HfLxVB1xv0PMveve8gsLuhAAsEtrobSctgKZYXBBFVMnQSKt+84J6
+jeoWvDjYmP+KofiV2+vCdLQoBm8bmxOf3AZJSpzm23Pi3Eb0ksEe1+nHkLP6ilXY
+UjjlQZeByd8bodm7Fr9iOdhJqYuFm7acVlgwrNbUHrGVIiwwP+rk2plcPN258HvM
+qFChjZU03L2ha351GLDnqv7v9fbK0fhceEWIEI1p+4tXZbYft1J7x2TNYKOooJUj
+l0VyibZul2ehFoVWTnocNCUE5KVknuE=
-----END CERTIFICATE REQUEST-----
unsigned char ServerRSA_Cert_CA_ECC_der[] = {
- 0x30, 0x82, 0x01, 0xa7, 0x30, 0x82, 0x01, 0x4d, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x01, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x20, 0x28, 0x45, 0x43, 0x43, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x35,
- 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x18,
- 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31, 0x33, 0x30, 0x37, 0x31,
- 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03,
- 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
- 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65,
- 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29,
- 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c,
- 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xab, 0x05, 0xba, 0xdc, 0x2d, 0xb3, 0x03, 0xf1, 0x6c, 0x60, 0x7f,
- 0x5e, 0x80, 0x85, 0x54, 0x24, 0xc7, 0x87, 0x6e, 0xe5, 0xf1, 0xae, 0x76,
- 0x59, 0xe3, 0x4b, 0x9c, 0xff, 0xa2, 0x41, 0xfc, 0x40, 0xf8, 0xa8, 0x33,
- 0x12, 0xa9, 0x1b, 0x1a, 0xc5, 0xe8, 0xef, 0xb1, 0xe3, 0x75, 0x0b, 0xd2,
- 0x28, 0x49, 0x48, 0x64, 0x9c, 0x3d, 0x89, 0xb6, 0xf8, 0xa5, 0x93, 0xd0,
- 0x29, 0x8c, 0x9e, 0x7a, 0xf6, 0x00, 0x20, 0x08, 0x52, 0x08, 0xdc, 0x1d,
- 0x17, 0x8b, 0x44, 0x4e, 0x32, 0x13, 0xdc, 0xb1, 0x50, 0xa5, 0xf0, 0x94,
- 0x25, 0x50, 0xfa, 0x1e, 0xe3, 0xae, 0x66, 0x19, 0x13, 0x3e, 0x20, 0x86,
- 0x05, 0x9c, 0xda, 0xd9, 0xff, 0x8f, 0x72, 0x6e, 0xf5, 0xc1, 0xfd, 0x86,
- 0xae, 0x26, 0xcc, 0x4b, 0xc8, 0x9f, 0xa9, 0xd6, 0x3a, 0x1f, 0xb6, 0x8a,
- 0x8f, 0x04, 0x2d, 0xbb, 0xa4, 0x47, 0xb3, 0xfb, 0xf9, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
- 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48,
- 0xce, 0x3d, 0x04, 0x01, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00,
- 0xb1, 0xf8, 0xfe, 0x7e, 0xd7, 0xd3, 0xef, 0xa7, 0x23, 0x5a, 0xa1, 0x39,
- 0x21, 0x38, 0x1e, 0x2f, 0xab, 0xfd, 0x31, 0x0f, 0xf3, 0xf9, 0x8c, 0x56,
- 0xdc, 0x2c, 0x28, 0x11, 0xc5, 0xbe, 0xfe, 0x16, 0x02, 0x21, 0x00, 0xb9,
- 0x1b, 0xa7, 0xe0, 0xb0, 0x2f, 0xc6, 0xb2, 0x86, 0x5b, 0x27, 0x27, 0x48,
- 0x1b, 0xab, 0x3c, 0x9d, 0xa9, 0xe0, 0x6f, 0x4f, 0xe8, 0x57, 0x4e, 0xfb,
- 0xdd, 0xda, 0xe6, 0xf5, 0x32, 0x90, 0x9b
+ 0x30, 0x82, 0x02, 0xbe, 0x30, 0x82, 0x02, 0x64, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x13, 0x2c, 0x10, 0x5b, 0x40, 0x8c, 0xb3, 0x1f, 0x3c, 0xc8,
+ 0x37, 0xae, 0x60, 0xbe, 0x7e, 0x23, 0xeb, 0x1a, 0x79, 0x94, 0x30, 0x0a,
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25,
+ 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20,
+ 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x45, 0x43, 0x43,
+ 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x32, 0x36, 0x30,
+ 0x31, 0x32, 0x35, 0x30, 0x35, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35,
+ 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x35, 0x30, 0x35, 0x5a, 0x30,
+ 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1f,
+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74,
+ 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72,
+ 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
+ 0x6f, 0x73, 0x74, 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,
+ 0xb1, 0xd0, 0x30, 0x71, 0x42, 0xb1, 0xdf, 0xf4, 0x79, 0xea, 0xe9, 0x7a,
+ 0xae, 0x53, 0xc2, 0x7f, 0xa9, 0x2e, 0x5f, 0xcc, 0xa3, 0x6e, 0x96, 0x0d,
+ 0xd1, 0x42, 0x2e, 0xba, 0xda, 0x06, 0x91, 0x61, 0xe6, 0x10, 0x63, 0xb9,
+ 0x39, 0x41, 0xeb, 0x06, 0xe2, 0x51, 0xd2, 0x65, 0xdb, 0x64, 0x0d, 0x2e,
+ 0x7f, 0xa5, 0x45, 0xbb, 0x0f, 0xa8, 0x26, 0x17, 0x45, 0x66, 0xb0, 0x7e,
+ 0x1c, 0x44, 0x4c, 0xf6, 0x5c, 0x8f, 0xfe, 0x68, 0x24, 0xeb, 0x73, 0xc7,
+ 0x42, 0x60, 0xd3, 0x96, 0x2a, 0xe8, 0x4e, 0x3e, 0xac, 0x61, 0x36, 0x5d,
+ 0x53, 0xb2, 0x31, 0xae, 0x81, 0x12, 0x00, 0x20, 0x48, 0x89, 0x6b, 0xa5,
+ 0x50, 0x2e, 0x01, 0xb9, 0x5a, 0x31, 0xb6, 0x55, 0x8e, 0x14, 0x2c, 0x32,
+ 0x50, 0x9e, 0x44, 0xa7, 0x0e, 0x61, 0x26, 0xee, 0xfc, 0x22, 0x0a, 0xe0,
+ 0xf5, 0xaf, 0x68, 0x1b, 0x5f, 0xed, 0x20, 0x3d, 0x61, 0x59, 0x38, 0x00,
+ 0x8b, 0x18, 0x39, 0xfd, 0x48, 0x14, 0x90, 0x68, 0x5d, 0x3e, 0xb8, 0xbd,
+ 0xe1, 0x25, 0x6d, 0xd4, 0xdc, 0xc4, 0x2b, 0xcc, 0xec, 0x51, 0x2b, 0x92,
+ 0x32, 0x06, 0xac, 0x58, 0x25, 0xa7, 0xa6, 0x6e, 0x12, 0x9c, 0x85, 0xa2,
+ 0x6a, 0x3a, 0x2c, 0x07, 0xcb, 0xf0, 0x4a, 0x47, 0x85, 0x14, 0x1f, 0x1b,
+ 0xbd, 0xc8, 0xe6, 0x54, 0xb8, 0x89, 0x7c, 0x1a, 0xfa, 0xbf, 0x93, 0x28,
+ 0xd4, 0x65, 0x38, 0x0d, 0xf3, 0x24, 0xcf, 0x14, 0xf9, 0xff, 0x0e, 0xd3,
+ 0xe5, 0xfd, 0x5e, 0x09, 0x1a, 0x8a, 0xe8, 0x64, 0x36, 0x25, 0x9d, 0xce,
+ 0xae, 0xbf, 0x1b, 0x74, 0xb8, 0x37, 0x8b, 0xd5, 0x00, 0x59, 0x14, 0xe5,
+ 0x33, 0x8f, 0xf4, 0x5c, 0x33, 0x23, 0x2c, 0x9f, 0x64, 0x1b, 0x65, 0x9a,
+ 0xb2, 0xf2, 0x6a, 0xcb, 0x2a, 0xa0, 0xaf, 0x04, 0x93, 0x8f, 0x66, 0xf9,
+ 0xeb, 0x2b, 0x4b, 0x91, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x8c,
+ 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+ 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, 0x06,
+ 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d,
+ 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+ 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0xc1, 0x70, 0x26, 0x38, 0x44, 0x78, 0x79, 0xab, 0xfd,
+ 0x87, 0x87, 0x94, 0x56, 0x83, 0x8c, 0xc8, 0x08, 0x56, 0xdb, 0x98, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0x2a, 0x8e, 0xdc, 0x15, 0xf2, 0x1d, 0x69, 0x64, 0x39, 0x77, 0x8f, 0xee,
+ 0xf4, 0x6d, 0x3f, 0x34, 0xd9, 0x85, 0xf0, 0x8c, 0x30, 0x0a, 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30,
+ 0x45, 0x02, 0x20, 0x1c, 0x72, 0x67, 0x58, 0xdf, 0xe3, 0xe3, 0x41, 0x9b,
+ 0xef, 0xba, 0xdc, 0x8f, 0x18, 0x4a, 0xc8, 0x84, 0x9a, 0x54, 0x0c, 0x7e,
+ 0xad, 0xce, 0x0b, 0x89, 0x9a, 0x8b, 0x9c, 0x6f, 0x3e, 0x34, 0x19, 0x02,
+ 0x21, 0x00, 0xa3, 0x25, 0x87, 0xaf, 0xfc, 0x38, 0x1e, 0x0a, 0x82, 0xf5,
+ 0xbd, 0x70, 0x28, 0x5c, 0x17, 0xfd, 0xb9, 0x03, 0x3b, 0xc3, 0x7f, 0x97,
+ 0xca, 0xff, 0xfe, 0x49, 0x70, 0x1e, 0xe7, 0x55, 0x14, 0xc1
};
-unsigned int ServerRSA_Cert_CA_ECC_der_len = 427;
+unsigned int ServerRSA_Cert_CA_ECC_der_len = 706;
unsigned char ServerRSA_Cert_CA_RSA_der[] = {
- 0x30, 0x82, 0x02, 0x69, 0x30, 0x82, 0x01, 0x51, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30,
- 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75,
- 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20,
- 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20,
- 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31, 0x30,
- 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33, 0x31,
- 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x3e, 0x31, 0x28,
- 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53,
- 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28,
- 0x52, 0x53, 0x41, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
- 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, 0xab, 0x05, 0xba, 0xdc, 0x2d, 0xb3, 0x03,
- 0xf1, 0x6c, 0x60, 0x7f, 0x5e, 0x80, 0x85, 0x54, 0x24, 0xc7, 0x87, 0x6e,
- 0xe5, 0xf1, 0xae, 0x76, 0x59, 0xe3, 0x4b, 0x9c, 0xff, 0xa2, 0x41, 0xfc,
- 0x40, 0xf8, 0xa8, 0x33, 0x12, 0xa9, 0x1b, 0x1a, 0xc5, 0xe8, 0xef, 0xb1,
- 0xe3, 0x75, 0x0b, 0xd2, 0x28, 0x49, 0x48, 0x64, 0x9c, 0x3d, 0x89, 0xb6,
- 0xf8, 0xa5, 0x93, 0xd0, 0x29, 0x8c, 0x9e, 0x7a, 0xf6, 0x00, 0x20, 0x08,
- 0x52, 0x08, 0xdc, 0x1d, 0x17, 0x8b, 0x44, 0x4e, 0x32, 0x13, 0xdc, 0xb1,
- 0x50, 0xa5, 0xf0, 0x94, 0x25, 0x50, 0xfa, 0x1e, 0xe3, 0xae, 0x66, 0x19,
- 0x13, 0x3e, 0x20, 0x86, 0x05, 0x9c, 0xda, 0xd9, 0xff, 0x8f, 0x72, 0x6e,
- 0xf5, 0xc1, 0xfd, 0x86, 0xae, 0x26, 0xcc, 0x4b, 0xc8, 0x9f, 0xa9, 0xd6,
- 0x3a, 0x1f, 0xb6, 0x8a, 0x8f, 0x04, 0x2d, 0xbb, 0xa4, 0x47, 0xb3, 0xfb,
- 0xf9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0xa7, 0x35, 0x63, 0xc8, 0x0a, 0xf7, 0xae,
- 0x0f, 0xe8, 0x10, 0x50, 0xb0, 0x79, 0x04, 0xa5, 0xf3, 0x48, 0x5d, 0x0a,
- 0x7a, 0x6b, 0xd0, 0xef, 0x17, 0x43, 0xe5, 0x21, 0xd4, 0xbb, 0xef, 0xac,
- 0x04, 0x21, 0x50, 0x7d, 0xd8, 0xe8, 0xf1, 0x3f, 0xd1, 0xb7, 0xa5, 0x93,
- 0xb4, 0xa8, 0xec, 0x23, 0xbe, 0xb6, 0xd9, 0xcc, 0xbe, 0x3c, 0x81, 0x34,
- 0x25, 0x24, 0x81, 0x1e, 0xd9, 0x8c, 0xd6, 0x20, 0x14, 0x36, 0x83, 0x29,
- 0x7f, 0x56, 0xcd, 0xc3, 0x90, 0xd0, 0x2d, 0x54, 0x8b, 0x05, 0xcb, 0xab,
- 0xb1, 0xf2, 0x44, 0xfc, 0xba, 0x73, 0xbf, 0x97, 0xc2, 0x2b, 0x5a, 0x6a,
- 0x49, 0x27, 0x29, 0x7c, 0xb7, 0xb1, 0x4a, 0x1f, 0x28, 0x41, 0x05, 0x63,
- 0x58, 0x8e, 0xd5, 0x7e, 0x46, 0x74, 0x11, 0x01, 0x72, 0x93, 0x1f, 0xea,
- 0xf7, 0x37, 0x4a, 0xfa, 0x84, 0x53, 0xb6, 0x3c, 0x0e, 0xde, 0xe5, 0x1c,
- 0x12, 0x86, 0x0a, 0xf6, 0x8b, 0xac, 0xc8, 0xb5, 0x9a, 0x9b, 0xd2, 0x28,
- 0x15, 0x18, 0x83, 0x0a, 0xfc, 0x47, 0x1a, 0xcf, 0xed, 0xa1, 0x95, 0x4e,
- 0xcc, 0x3c, 0x2a, 0x9a, 0xdf, 0x09, 0xec, 0x28, 0x20, 0xfd, 0xc5, 0x42,
- 0xf1, 0xd8, 0x2f, 0x21, 0x88, 0xec, 0xe2, 0x24, 0xb2, 0xe2, 0x45, 0x5a,
- 0xce, 0xb4, 0x78, 0xb3, 0x30, 0x38, 0x0e, 0x1c, 0x6a, 0xa3, 0x04, 0x0e,
- 0xac, 0xa4, 0x97, 0xe3, 0xc1, 0x46, 0x0a, 0x9d, 0x65, 0x9a, 0xe9, 0x02,
- 0x12, 0xf0, 0x88, 0x58, 0xc6, 0xde, 0xe5, 0x23, 0x42, 0x3c, 0x58, 0x52,
- 0x27, 0x1a, 0xe2, 0xf5, 0x4a, 0x21, 0x47, 0xb2, 0x13, 0x0c, 0xb2, 0xd0,
- 0xcc, 0xb3, 0xfd, 0x66, 0x2a, 0xa6, 0x38, 0x5b, 0xe6, 0x2e, 0x90, 0x9e,
- 0x62, 0x3f, 0x7e, 0x60, 0xee, 0xd4, 0x02, 0x58, 0x7d, 0x5c, 0xf8, 0x39,
- 0x27, 0xa9, 0xdb, 0x3e, 0x24, 0x3c, 0xc0, 0xde, 0xc8
+ 0x30, 0x82, 0x03, 0x80, 0x30, 0x82, 0x02, 0x68, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x14, 0x00, 0xb9, 0x18, 0x42, 0xfe, 0xdf, 0xe7, 0x25, 0x9c,
+ 0xce, 0xfa, 0xd7, 0xd0, 0xe8, 0x56, 0xe3, 0xd5, 0xd3, 0x20, 0x93, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54,
+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
+ 0x28, 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30,
+ 0x35, 0x32, 0x35, 0x32, 0x33, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x18, 0x0f,
+ 0x32, 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x36, 0x32, 0x33, 0x34, 0x38,
+ 0x33, 0x38, 0x5a, 0x30, 0x3e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x0c, 0x1f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+ 0x54, 0x65, 0x73, 0x74, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+ 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x31,
+ 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f,
+ 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xb1, 0xd0, 0x30, 0x71, 0x42, 0xb1, 0xdf, 0xf4,
+ 0x79, 0xea, 0xe9, 0x7a, 0xae, 0x53, 0xc2, 0x7f, 0xa9, 0x2e, 0x5f, 0xcc,
+ 0xa3, 0x6e, 0x96, 0x0d, 0xd1, 0x42, 0x2e, 0xba, 0xda, 0x06, 0x91, 0x61,
+ 0xe6, 0x10, 0x63, 0xb9, 0x39, 0x41, 0xeb, 0x06, 0xe2, 0x51, 0xd2, 0x65,
+ 0xdb, 0x64, 0x0d, 0x2e, 0x7f, 0xa5, 0x45, 0xbb, 0x0f, 0xa8, 0x26, 0x17,
+ 0x45, 0x66, 0xb0, 0x7e, 0x1c, 0x44, 0x4c, 0xf6, 0x5c, 0x8f, 0xfe, 0x68,
+ 0x24, 0xeb, 0x73, 0xc7, 0x42, 0x60, 0xd3, 0x96, 0x2a, 0xe8, 0x4e, 0x3e,
+ 0xac, 0x61, 0x36, 0x5d, 0x53, 0xb2, 0x31, 0xae, 0x81, 0x12, 0x00, 0x20,
+ 0x48, 0x89, 0x6b, 0xa5, 0x50, 0x2e, 0x01, 0xb9, 0x5a, 0x31, 0xb6, 0x55,
+ 0x8e, 0x14, 0x2c, 0x32, 0x50, 0x9e, 0x44, 0xa7, 0x0e, 0x61, 0x26, 0xee,
+ 0xfc, 0x22, 0x0a, 0xe0, 0xf5, 0xaf, 0x68, 0x1b, 0x5f, 0xed, 0x20, 0x3d,
+ 0x61, 0x59, 0x38, 0x00, 0x8b, 0x18, 0x39, 0xfd, 0x48, 0x14, 0x90, 0x68,
+ 0x5d, 0x3e, 0xb8, 0xbd, 0xe1, 0x25, 0x6d, 0xd4, 0xdc, 0xc4, 0x2b, 0xcc,
+ 0xec, 0x51, 0x2b, 0x92, 0x32, 0x06, 0xac, 0x58, 0x25, 0xa7, 0xa6, 0x6e,
+ 0x12, 0x9c, 0x85, 0xa2, 0x6a, 0x3a, 0x2c, 0x07, 0xcb, 0xf0, 0x4a, 0x47,
+ 0x85, 0x14, 0x1f, 0x1b, 0xbd, 0xc8, 0xe6, 0x54, 0xb8, 0x89, 0x7c, 0x1a,
+ 0xfa, 0xbf, 0x93, 0x28, 0xd4, 0x65, 0x38, 0x0d, 0xf3, 0x24, 0xcf, 0x14,
+ 0xf9, 0xff, 0x0e, 0xd3, 0xe5, 0xfd, 0x5e, 0x09, 0x1a, 0x8a, 0xe8, 0x64,
+ 0x36, 0x25, 0x9d, 0xce, 0xae, 0xbf, 0x1b, 0x74, 0xb8, 0x37, 0x8b, 0xd5,
+ 0x00, 0x59, 0x14, 0xe5, 0x33, 0x8f, 0xf4, 0x5c, 0x33, 0x23, 0x2c, 0x9f,
+ 0x64, 0x1b, 0x65, 0x9a, 0xb2, 0xf2, 0x6a, 0xcb, 0x2a, 0xa0, 0xaf, 0x04,
+ 0x93, 0x8f, 0x66, 0xf9, 0xeb, 0x2b, 0x4b, 0x91, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x81, 0x8c, 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55,
+ 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05,
+ 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14,
+ 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c,
+ 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc1, 0x70, 0x26, 0x38, 0x44,
+ 0x78, 0x79, 0xab, 0xfd, 0x87, 0x87, 0x94, 0x56, 0x83, 0x8c, 0xc8, 0x08,
+ 0x56, 0xdb, 0x98, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0x5d, 0xa7, 0x1b, 0x3b, 0x57, 0xd2, 0x0e, 0x08,
+ 0x1e, 0xaa, 0x47, 0xcf, 0x03, 0x34, 0x68, 0xbe, 0x53, 0x00, 0xd9, 0x64,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2d, 0xd1, 0x12, 0x47,
+ 0xd2, 0x98, 0xb6, 0x1c, 0x18, 0x2a, 0x58, 0xf1, 0xa1, 0xe4, 0xf9, 0xaa,
+ 0x0d, 0x9d, 0xd5, 0xbb, 0x7d, 0xde, 0xe9, 0xd2, 0x7f, 0x4e, 0x68, 0xaa,
+ 0x06, 0xfd, 0xda, 0x5a, 0x83, 0x79, 0xfd, 0x5d, 0x0a, 0xd1, 0xcd, 0xf3,
+ 0xa3, 0xbf, 0x84, 0x31, 0x45, 0x9a, 0x3a, 0x72, 0x7a, 0x57, 0x5b, 0x00,
+ 0xde, 0x20, 0x8b, 0x63, 0x30, 0x3d, 0x55, 0xd1, 0xaf, 0x2c, 0x1e, 0xfb,
+ 0xa1, 0xce, 0xf6, 0xc3, 0x45, 0xaa, 0x4a, 0x40, 0x6b, 0x38, 0xf3, 0xa6,
+ 0x43, 0x36, 0xb5, 0xf5, 0xcd, 0xf8, 0x0b, 0xc2, 0xf7, 0x2f, 0x02, 0x73,
+ 0xa3, 0x3b, 0xcb, 0x7f, 0x98, 0x15, 0xaf, 0xd2, 0xc9, 0x1a, 0xdf, 0x8e,
+ 0x2c, 0x02, 0x04, 0x53, 0xa7, 0x7c, 0x4d, 0x6a, 0xd9, 0x0b, 0x49, 0x0c,
+ 0x9b, 0x98, 0x9d, 0x1b, 0x8c, 0x2d, 0xf3, 0x9a, 0x26, 0x2f, 0xe3, 0xc6,
+ 0xcb, 0x25, 0xa2, 0x4e, 0xa7, 0x8d, 0xe6, 0x71, 0x07, 0xb8, 0xf2, 0xba,
+ 0xb5, 0xbd, 0x88, 0x79, 0x62, 0x86, 0x31, 0x82, 0x86, 0x03, 0xdc, 0xaf,
+ 0x87, 0xed, 0xba, 0x6e, 0x57, 0x06, 0x7e, 0x96, 0xa7, 0xb4, 0xe8, 0x1f,
+ 0x56, 0xd4, 0x55, 0x80, 0x27, 0xaa, 0xd0, 0x62, 0xfd, 0x22, 0xab, 0x2e,
+ 0x37, 0x0d, 0x47, 0x53, 0x12, 0x10, 0xe5, 0x3b, 0x7c, 0xc4, 0x4a, 0x0a,
+ 0xc0, 0x1d, 0x10, 0xf0, 0xcd, 0xc2, 0xfe, 0x85, 0x58, 0xac, 0x74, 0xfe,
+ 0xec, 0x5c, 0x32, 0x1e, 0x18, 0xf0, 0x19, 0xfc, 0x91, 0x21, 0x71, 0x67,
+ 0xd0, 0x38, 0xbb, 0x7c, 0x4d, 0x5b, 0xa5, 0xcd, 0x00, 0x1d, 0x4e, 0x73,
+ 0x5b, 0xe8, 0x16, 0xd5, 0x29, 0x8c, 0x72, 0xaa, 0xa3, 0xb5, 0x5d, 0xee,
+ 0x84, 0xb1, 0x04, 0xfb, 0x0b, 0x3d, 0x4d, 0x7c, 0x0f, 0x7e, 0x63, 0xbb,
+ 0x7d, 0x17, 0xa3, 0x4a, 0xff, 0x3e, 0xe0, 0xf6, 0xb5, 0x77, 0xcc, 0x3b
};
-unsigned int ServerRSA_Cert_CA_RSA_der_len = 621;
+unsigned int ServerRSA_Cert_CA_RSA_der_len = 900;
unsigned char ServerRSA_Key_der[] = {
- 0x30, 0x82, 0x02, 0x5b, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xab,
- 0x05, 0xba, 0xdc, 0x2d, 0xb3, 0x03, 0xf1, 0x6c, 0x60, 0x7f, 0x5e, 0x80,
- 0x85, 0x54, 0x24, 0xc7, 0x87, 0x6e, 0xe5, 0xf1, 0xae, 0x76, 0x59, 0xe3,
- 0x4b, 0x9c, 0xff, 0xa2, 0x41, 0xfc, 0x40, 0xf8, 0xa8, 0x33, 0x12, 0xa9,
- 0x1b, 0x1a, 0xc5, 0xe8, 0xef, 0xb1, 0xe3, 0x75, 0x0b, 0xd2, 0x28, 0x49,
- 0x48, 0x64, 0x9c, 0x3d, 0x89, 0xb6, 0xf8, 0xa5, 0x93, 0xd0, 0x29, 0x8c,
- 0x9e, 0x7a, 0xf6, 0x00, 0x20, 0x08, 0x52, 0x08, 0xdc, 0x1d, 0x17, 0x8b,
- 0x44, 0x4e, 0x32, 0x13, 0xdc, 0xb1, 0x50, 0xa5, 0xf0, 0x94, 0x25, 0x50,
- 0xfa, 0x1e, 0xe3, 0xae, 0x66, 0x19, 0x13, 0x3e, 0x20, 0x86, 0x05, 0x9c,
- 0xda, 0xd9, 0xff, 0x8f, 0x72, 0x6e, 0xf5, 0xc1, 0xfd, 0x86, 0xae, 0x26,
- 0xcc, 0x4b, 0xc8, 0x9f, 0xa9, 0xd6, 0x3a, 0x1f, 0xb6, 0x8a, 0x8f, 0x04,
- 0x2d, 0xbb, 0xa4, 0x47, 0xb3, 0xfb, 0xf9, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0x02, 0x81, 0x80, 0x38, 0x04, 0xf1, 0x77, 0x4b, 0xb4, 0xd6, 0xb6, 0xce,
- 0xf4, 0x30, 0xe4, 0x68, 0x9e, 0xc3, 0xb8, 0x24, 0x6f, 0x75, 0x60, 0xf6,
- 0xb0, 0x59, 0xee, 0x09, 0xa8, 0xeb, 0xed, 0x44, 0x5d, 0xee, 0xdd, 0xed,
- 0x55, 0x53, 0x1d, 0x6a, 0xad, 0x09, 0x31, 0x08, 0xa2, 0xf3, 0x16, 0xf9,
- 0x70, 0xfc, 0xce, 0xdb, 0x6a, 0x4e, 0x22, 0x6b, 0x79, 0xdf, 0xa8, 0x44,
- 0xbc, 0x4d, 0x34, 0x3e, 0xee, 0x6e, 0x81, 0xfa, 0xe5, 0xf4, 0x62, 0x95,
- 0x30, 0xce, 0x49, 0x11, 0x42, 0x2b, 0x2e, 0x6a, 0x87, 0x0c, 0x6a, 0x1f,
- 0xaf, 0x22, 0xec, 0x32, 0x6b, 0x3e, 0x1b, 0xc3, 0xcb, 0xb4, 0x46, 0xd6,
- 0x14, 0xd0, 0x52, 0x6b, 0x4c, 0x63, 0x74, 0xcb, 0xbe, 0xeb, 0xf8, 0xbf,
- 0x31, 0xd6, 0xe3, 0x42, 0x1f, 0x77, 0x68, 0xf2, 0xf2, 0xf0, 0xf4, 0x24,
- 0x10, 0x5f, 0x9c, 0x3c, 0x5c, 0xbb, 0x5b, 0x19, 0xed, 0x30, 0x01, 0x02,
- 0x41, 0x00, 0xd2, 0x72, 0x8b, 0xd9, 0x1a, 0x8d, 0xcb, 0xa2, 0x56, 0x6b,
- 0x3b, 0x78, 0xf3, 0x7a, 0xd4, 0x97, 0x90, 0xcd, 0xcd, 0x5a, 0x32, 0x06,
- 0x3d, 0xb0, 0xc2, 0xfb, 0x9f, 0x95, 0x51, 0x63, 0xcf, 0xcd, 0x5c, 0xcb,
- 0x4b, 0xa7, 0xe5, 0x5f, 0xd0, 0xd3, 0x5a, 0xc8, 0x92, 0xe1, 0xde, 0xe0,
- 0x83, 0x86, 0xfe, 0xdd, 0xe1, 0xb4, 0x00, 0x72, 0x25, 0xb4, 0x20, 0x19,
- 0xf6, 0x94, 0xf8, 0xfd, 0x4e, 0x01, 0x02, 0x41, 0x00, 0xd0, 0x0a, 0x89,
- 0x2a, 0x99, 0x49, 0x35, 0x60, 0x14, 0x8d, 0x2c, 0xe7, 0x72, 0xa0, 0x19,
- 0xd6, 0x86, 0x60, 0x0d, 0xa6, 0x44, 0x89, 0x30, 0x98, 0xea, 0xeb, 0xdf,
- 0xfb, 0xb5, 0x56, 0x23, 0x3c, 0xe4, 0xc9, 0x76, 0x4f, 0x90, 0x8e, 0x55,
- 0x7d, 0x51, 0xcb, 0x41, 0xf1, 0x73, 0xb0, 0xa9, 0x8b, 0x36, 0xf9, 0x1a,
- 0xfe, 0x6f, 0xa3, 0x2e, 0x13, 0x30, 0xc4, 0xe3, 0x2c, 0x51, 0x7d, 0x1d,
- 0xf9, 0x02, 0x40, 0x6e, 0x72, 0x55, 0x79, 0x04, 0x99, 0xa4, 0x64, 0xb7,
- 0x8c, 0x21, 0xb3, 0x51, 0xbd, 0x86, 0x33, 0x61, 0x78, 0xd1, 0x2c, 0x64,
- 0x12, 0xa8, 0x6f, 0xcb, 0x75, 0x39, 0x84, 0xa9, 0x29, 0x84, 0x16, 0xd8,
- 0x7b, 0x8d, 0x62, 0x39, 0x5c, 0x77, 0x01, 0x65, 0xa4, 0xdc, 0x89, 0x94,
- 0x6a, 0x2a, 0x3d, 0x40, 0x27, 0x7c, 0xdb, 0xf6, 0x5b, 0xf1, 0xf3, 0xbd,
- 0xe1, 0x42, 0x6b, 0x5e, 0xdd, 0xba, 0x01, 0x02, 0x40, 0x6b, 0x56, 0x14,
- 0x41, 0x23, 0x47, 0x2f, 0x3f, 0xbc, 0x3a, 0xbe, 0x81, 0x47, 0x95, 0xac,
- 0xdf, 0x0f, 0x03, 0x7d, 0xe7, 0x5c, 0x13, 0x00, 0x3c, 0xd5, 0x70, 0x0f,
- 0x67, 0x19, 0xbf, 0x30, 0x7d, 0x19, 0x79, 0x8c, 0x0e, 0x2f, 0x02, 0x10,
- 0xbf, 0x90, 0xb4, 0xf2, 0xf7, 0xf5, 0x7d, 0x9f, 0x6c, 0x11, 0x57, 0xe3,
- 0x02, 0x85, 0x6c, 0xc6, 0xb7, 0xe6, 0x00, 0x9f, 0x48, 0xdd, 0x5e, 0x55,
- 0x59, 0x02, 0x40, 0x51, 0xb5, 0xaf, 0x36, 0x4b, 0x91, 0x6c, 0x89, 0x19,
- 0x44, 0x96, 0x6c, 0x4a, 0x94, 0x58, 0x29, 0x5c, 0x38, 0xd4, 0x6b, 0x24,
- 0xdc, 0x3b, 0xb1, 0x66, 0xc1, 0x3c, 0xc8, 0x17, 0x97, 0xb7, 0x05, 0xd9,
- 0x18, 0xb6, 0x43, 0x16, 0xf8, 0xf9, 0x5e, 0xed, 0x7e, 0x6f, 0xc4, 0xa6,
- 0x6a, 0x3a, 0xc7, 0xc0, 0x21, 0x6b, 0x39, 0xac, 0xf3, 0xf6, 0x40, 0xd5,
- 0x25, 0xf7, 0x44, 0x1d, 0xd4, 0xb2, 0x37
+ 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xb1, 0xd0, 0x30, 0x71, 0x42, 0xb1, 0xdf, 0xf4, 0x79, 0xea, 0xe9, 0x7a,
+ 0xae, 0x53, 0xc2, 0x7f, 0xa9, 0x2e, 0x5f, 0xcc, 0xa3, 0x6e, 0x96, 0x0d,
+ 0xd1, 0x42, 0x2e, 0xba, 0xda, 0x06, 0x91, 0x61, 0xe6, 0x10, 0x63, 0xb9,
+ 0x39, 0x41, 0xeb, 0x06, 0xe2, 0x51, 0xd2, 0x65, 0xdb, 0x64, 0x0d, 0x2e,
+ 0x7f, 0xa5, 0x45, 0xbb, 0x0f, 0xa8, 0x26, 0x17, 0x45, 0x66, 0xb0, 0x7e,
+ 0x1c, 0x44, 0x4c, 0xf6, 0x5c, 0x8f, 0xfe, 0x68, 0x24, 0xeb, 0x73, 0xc7,
+ 0x42, 0x60, 0xd3, 0x96, 0x2a, 0xe8, 0x4e, 0x3e, 0xac, 0x61, 0x36, 0x5d,
+ 0x53, 0xb2, 0x31, 0xae, 0x81, 0x12, 0x00, 0x20, 0x48, 0x89, 0x6b, 0xa5,
+ 0x50, 0x2e, 0x01, 0xb9, 0x5a, 0x31, 0xb6, 0x55, 0x8e, 0x14, 0x2c, 0x32,
+ 0x50, 0x9e, 0x44, 0xa7, 0x0e, 0x61, 0x26, 0xee, 0xfc, 0x22, 0x0a, 0xe0,
+ 0xf5, 0xaf, 0x68, 0x1b, 0x5f, 0xed, 0x20, 0x3d, 0x61, 0x59, 0x38, 0x00,
+ 0x8b, 0x18, 0x39, 0xfd, 0x48, 0x14, 0x90, 0x68, 0x5d, 0x3e, 0xb8, 0xbd,
+ 0xe1, 0x25, 0x6d, 0xd4, 0xdc, 0xc4, 0x2b, 0xcc, 0xec, 0x51, 0x2b, 0x92,
+ 0x32, 0x06, 0xac, 0x58, 0x25, 0xa7, 0xa6, 0x6e, 0x12, 0x9c, 0x85, 0xa2,
+ 0x6a, 0x3a, 0x2c, 0x07, 0xcb, 0xf0, 0x4a, 0x47, 0x85, 0x14, 0x1f, 0x1b,
+ 0xbd, 0xc8, 0xe6, 0x54, 0xb8, 0x89, 0x7c, 0x1a, 0xfa, 0xbf, 0x93, 0x28,
+ 0xd4, 0x65, 0x38, 0x0d, 0xf3, 0x24, 0xcf, 0x14, 0xf9, 0xff, 0x0e, 0xd3,
+ 0xe5, 0xfd, 0x5e, 0x09, 0x1a, 0x8a, 0xe8, 0x64, 0x36, 0x25, 0x9d, 0xce,
+ 0xae, 0xbf, 0x1b, 0x74, 0xb8, 0x37, 0x8b, 0xd5, 0x00, 0x59, 0x14, 0xe5,
+ 0x33, 0x8f, 0xf4, 0x5c, 0x33, 0x23, 0x2c, 0x9f, 0x64, 0x1b, 0x65, 0x9a,
+ 0xb2, 0xf2, 0x6a, 0xcb, 0x2a, 0xa0, 0xaf, 0x04, 0x93, 0x8f, 0x66, 0xf9,
+ 0xeb, 0x2b, 0x4b, 0x91, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01,
+ 0x00, 0x76, 0x2a, 0xb5, 0xd6, 0xbf, 0x0c, 0xf8, 0x99, 0x3e, 0xe0, 0x77,
+ 0x73, 0x19, 0x20, 0xfe, 0xd3, 0xd9, 0xf9, 0xc0, 0x9e, 0x7d, 0x4a, 0x03,
+ 0x9c, 0x81, 0x21, 0x6b, 0x6e, 0xaf, 0x6f, 0xc7, 0xf3, 0xf8, 0x71, 0x91,
+ 0xe4, 0x49, 0x01, 0xde, 0x8f, 0xff, 0x9d, 0x82, 0xa6, 0x40, 0x2b, 0x78,
+ 0x7b, 0x1b, 0x47, 0x19, 0x55, 0x1c, 0x2d, 0x91, 0xca, 0xcb, 0x4b, 0x58,
+ 0x25, 0x26, 0xe1, 0xd9, 0x07, 0xac, 0x31, 0xe1, 0x4f, 0x12, 0xa2, 0x0a,
+ 0x9a, 0x34, 0x29, 0xa6, 0xd3, 0x58, 0x06, 0x73, 0xe1, 0x40, 0xab, 0x85,
+ 0xf6, 0x75, 0xa5, 0xa9, 0x50, 0x9f, 0xe3, 0xf7, 0x83, 0x7c, 0xd1, 0x1e,
+ 0x61, 0x89, 0x2c, 0x59, 0xe6, 0xf4, 0xe2, 0xae, 0x9a, 0xa2, 0xc6, 0x13,
+ 0x2d, 0x08, 0xd8, 0x75, 0x25, 0x53, 0xf0, 0x0a, 0x70, 0xad, 0xcc, 0x6d,
+ 0xd0, 0x5c, 0x55, 0xca, 0x68, 0xce, 0xd2, 0x06, 0x26, 0xc7, 0xd5, 0x6b,
+ 0x11, 0x2d, 0x3e, 0xd8, 0x01, 0xfa, 0x07, 0x63, 0xb2, 0x32, 0x8e, 0x84,
+ 0xc3, 0x89, 0xfd, 0x36, 0x85, 0xf7, 0x64, 0x07, 0x93, 0x25, 0x86, 0x6a,
+ 0x47, 0xc3, 0x7c, 0xc5, 0xaf, 0x63, 0xe8, 0xf3, 0x0c, 0x3b, 0xfb, 0xc6,
+ 0x01, 0x34, 0xd5, 0x78, 0x85, 0x10, 0xcd, 0xc2, 0x37, 0xdf, 0x60, 0x4c,
+ 0xbe, 0xe0, 0x66, 0xec, 0x20, 0x94, 0x29, 0x07, 0x88, 0xb9, 0x48, 0xdf,
+ 0xd3, 0x1c, 0x4b, 0xd2, 0x6f, 0x02, 0x4a, 0xc5, 0x68, 0x13, 0x2b, 0xe0,
+ 0x8c, 0x6c, 0x36, 0xc9, 0x0b, 0xdc, 0x49, 0xa3, 0xb6, 0x90, 0x54, 0xdb,
+ 0x8f, 0xaf, 0xd8, 0x79, 0x0b, 0xc7, 0x6b, 0x3c, 0x75, 0x81, 0x7c, 0x15,
+ 0x59, 0xbc, 0xc9, 0x6d, 0x3d, 0x59, 0xaf, 0x01, 0xf4, 0x59, 0x95, 0x14,
+ 0xc0, 0x42, 0x5f, 0xa9, 0x57, 0xbb, 0xf1, 0x76, 0xa9, 0xb9, 0x56, 0x0f,
+ 0x1f, 0x3b, 0x3b, 0x5a, 0x01, 0x02, 0x81, 0x81, 0x00, 0xe8, 0x00, 0xd9,
+ 0x7c, 0x51, 0x37, 0x11, 0xf0, 0x81, 0x86, 0x6a, 0x15, 0x4e, 0x41, 0xf3,
+ 0x1c, 0x91, 0x3e, 0x3a, 0x17, 0x8f, 0xc7, 0xf3, 0x2c, 0x23, 0x5b, 0x6a,
+ 0x1f, 0x58, 0x35, 0x20, 0x2c, 0xf0, 0x6d, 0x4c, 0x20, 0x9f, 0x95, 0x1b,
+ 0x63, 0xb9, 0xaf, 0xb3, 0xd7, 0x73, 0xbf, 0x38, 0x0b, 0x65, 0x85, 0x73,
+ 0x6d, 0x28, 0xcd, 0x42, 0xde, 0xcc, 0xfd, 0x93, 0xc9, 0x6c, 0xb1, 0x55,
+ 0x80, 0x82, 0x0e, 0x26, 0xb2, 0xb6, 0x1a, 0xad, 0xe7, 0x57, 0xba, 0xc9,
+ 0xbd, 0x01, 0xe4, 0xf9, 0xee, 0xe9, 0x62, 0x8d, 0xd6, 0x24, 0x09, 0x2f,
+ 0x6e, 0x8c, 0x13, 0x5c, 0x16, 0xcd, 0xe9, 0x17, 0x4e, 0xff, 0x9f, 0xb0,
+ 0xfd, 0xca, 0xfc, 0x1f, 0x60, 0x2d, 0xe0, 0x0b, 0x38, 0xba, 0x2e, 0x28,
+ 0xcf, 0x5d, 0x73, 0x11, 0xe4, 0xe7, 0x0a, 0x21, 0xc4, 0xeb, 0x69, 0xab,
+ 0xf3, 0x42, 0xf1, 0xc8, 0xe1, 0x02, 0x81, 0x81, 0x00, 0xc4, 0x34, 0x74,
+ 0xb2, 0x39, 0x83, 0xd4, 0xe3, 0xf7, 0x14, 0xbe, 0x4e, 0x45, 0xbf, 0x5e,
+ 0x9e, 0xa2, 0x1c, 0xe3, 0x46, 0xa0, 0x63, 0x00, 0x96, 0x50, 0xdd, 0x8a,
+ 0x35, 0x05, 0xcb, 0x37, 0x4d, 0x82, 0x00, 0xc5, 0xeb, 0x7b, 0x75, 0x33,
+ 0xd2, 0x51, 0xde, 0x16, 0x1b, 0x6c, 0x54, 0x94, 0x58, 0x20, 0xc1, 0x60,
+ 0xe6, 0xff, 0x44, 0xac, 0x94, 0x86, 0x4d, 0x53, 0xcc, 0x1f, 0x31, 0xeb,
+ 0x45, 0xe3, 0xc2, 0x78, 0x65, 0x9b, 0xd0, 0xe8, 0xf9, 0x87, 0x5e, 0xa5,
+ 0x49, 0x09, 0x66, 0xab, 0xdb, 0x1a, 0x44, 0x23, 0x77, 0x54, 0x33, 0x1b,
+ 0xd4, 0x3b, 0xb5, 0xb4, 0x8f, 0xd2, 0x5d, 0x9e, 0xf0, 0x9a, 0xcc, 0x49,
+ 0xe5, 0x32, 0x96, 0x89, 0x20, 0x2a, 0x08, 0x40, 0xf3, 0x93, 0xc9, 0xbb,
+ 0xa7, 0xa7, 0x87, 0xa3, 0x02, 0xf3, 0xcc, 0xe5, 0x2c, 0xcc, 0xf0, 0x3b,
+ 0xaf, 0x80, 0xe4, 0x68, 0xb1, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x2d, 0x29,
+ 0xd9, 0xa3, 0x87, 0x8f, 0x8a, 0xab, 0x8b, 0x71, 0xd2, 0x31, 0x87, 0xe3,
+ 0xcd, 0x7e, 0xdf, 0x6e, 0x5c, 0xd8, 0x04, 0x33, 0x52, 0x5d, 0x69, 0xda,
+ 0x4c, 0x92, 0x7e, 0xc0, 0x4e, 0x6f, 0x59, 0xee, 0x74, 0x83, 0x7f, 0x26,
+ 0xc3, 0x93, 0x1b, 0xf2, 0xb4, 0xe1, 0x97, 0x92, 0xb8, 0xb1, 0x91, 0x67,
+ 0x55, 0x0d, 0x09, 0x06, 0xdf, 0x14, 0x73, 0x45, 0xe7, 0x81, 0x7a, 0x64,
+ 0x83, 0xb2, 0xc6, 0xbe, 0xfd, 0x4c, 0xc1, 0x37, 0xb6, 0xa8, 0x75, 0x66,
+ 0x05, 0x48, 0x5a, 0x85, 0x3a, 0x5f, 0xf6, 0x7f, 0x96, 0x3b, 0x6d, 0x64,
+ 0xfb, 0x5d, 0xbd, 0xe5, 0xf2, 0x29, 0x6d, 0xcb, 0x16, 0x6d, 0xe8, 0xad,
+ 0xf0, 0xce, 0x39, 0xfb, 0x10, 0x95, 0xc8, 0xac, 0xc7, 0xf1, 0xe1, 0xdc,
+ 0x51, 0x44, 0xa6, 0x50, 0xd4, 0x9a, 0x54, 0xeb, 0x55, 0x01, 0xb7, 0xf4,
+ 0x35, 0x64, 0x97, 0x38, 0xa1, 0x02, 0x81, 0x80, 0x56, 0x7f, 0xfd, 0xd6,
+ 0xb9, 0x2e, 0x9a, 0xc3, 0xea, 0x21, 0x76, 0x09, 0x12, 0x0c, 0xdd, 0x8d,
+ 0x38, 0x51, 0x5e, 0x0d, 0xbc, 0x16, 0x09, 0xa3, 0x3b, 0x81, 0x80, 0x36,
+ 0x02, 0x18, 0xe6, 0x87, 0xc0, 0x41, 0xd1, 0x00, 0x11, 0x4c, 0xc9, 0x8c,
+ 0xf6, 0xd4, 0xdf, 0x90, 0x35, 0x81, 0x50, 0x69, 0x4d, 0xff, 0x93, 0x56,
+ 0x23, 0xc2, 0x46, 0x07, 0xb0, 0xf2, 0x14, 0x78, 0x90, 0x64, 0x34, 0xa2,
+ 0x7a, 0x58, 0x39, 0x36, 0x2a, 0xac, 0xbe, 0x99, 0x8c, 0x09, 0xb8, 0xfa,
+ 0xeb, 0x2f, 0x1d, 0xa3, 0x1a, 0x00, 0x62, 0x56, 0x70, 0x83, 0x9b, 0xc8,
+ 0x44, 0x8e, 0xc6, 0x4d, 0x05, 0xe4, 0x8a, 0x76, 0xee, 0xf8, 0x13, 0xb7,
+ 0xfd, 0x46, 0x8a, 0xab, 0xe8, 0x7b, 0xfd, 0x0e, 0xa5, 0xe0, 0x31, 0x60,
+ 0x27, 0xa6, 0xcf, 0xc2, 0x34, 0x73, 0xe7, 0xb1, 0x89, 0xa4, 0x7b, 0xdb,
+ 0xd3, 0x0a, 0x5f, 0xf1, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x8b, 0xce, 0xe1,
+ 0x83, 0x9d, 0x18, 0x96, 0x08, 0x62, 0xd1, 0x66, 0xb3, 0xb6, 0x24, 0x7b,
+ 0x27, 0x4b, 0x08, 0xb3, 0xda, 0x9d, 0x2d, 0x65, 0x41, 0x58, 0xf0, 0xa3,
+ 0xb3, 0xc1, 0x40, 0x4b, 0xef, 0x95, 0x9b, 0xbb, 0xc4, 0x98, 0x82, 0x1c,
+ 0xa3, 0x3b, 0xd6, 0xca, 0xc2, 0x47, 0x99, 0x1e, 0x21, 0x85, 0xcc, 0x44,
+ 0xd6, 0x60, 0x18, 0x1b, 0x3f, 0x32, 0xc6, 0x8c, 0x5d, 0xd1, 0x04, 0x64,
+ 0x02, 0x11, 0xa8, 0x48, 0xe5, 0x6d, 0xe2, 0xac, 0x45, 0x0d, 0x04, 0xaa,
+ 0x32, 0x9b, 0xa7, 0xa7, 0xc3, 0xf7, 0xcd, 0xea, 0x49, 0x0c, 0x85, 0xcb,
+ 0x4a, 0xae, 0x89, 0xae, 0x56, 0x20, 0xe7, 0xbc, 0x3a, 0x78, 0xd5, 0x57,
+ 0x2a, 0xaa, 0x33, 0x99, 0xaf, 0x83, 0x96, 0xdf, 0x00, 0xac, 0x1e, 0x0b,
+ 0xee, 0x82, 0xa7, 0x3c, 0xf0, 0xb2, 0x3c, 0x26, 0x60, 0xfc, 0x84, 0xac,
+ 0x83, 0x35, 0x7a, 0xfb
};
-unsigned int ServerRSA_Key_der_len = 607;
+unsigned int ServerRSA_Key_der_len = 1192;
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 3e:69:a0:98:7e:a1:7b:2f:1f:ea:6a:d7:e7:25:5e:b3:49:67:3a
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=SecurityTest CA Cert (RSA)
+ Validity
+ Not Before: May 26 01:29:08 2018 GMT
+ Not After : May 17 01:29:08 2055 GMT
+ Subject: OU=SecurityTests Client Cert (RSA)(Untrusted), CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b2:82:19:20:7d:6c:3c:65:e8:ba:37:36:0e:98:
+ d6:5d:cd:09:84:ef:d3:2c:c8:a5:7c:57:09:8c:8a:
+ 23:16:53:fa:a9:98:d4:ed:fe:4c:f1:35:35:95:92:
+ cc:cd:12:86:5c:f5:ba:62:34:52:01:a7:3c:53:2b:
+ 0e:83:07:a8:ad:d2:6a:58:ea:8c:ae:1b:6d:80:a7:
+ 70:7e:d7:48:7d:47:1f:7a:7f:45:fc:c1:63:04:d6:
+ 68:19:e2:4a:b9:ce:1d:6f:82:6f:3c:61:7b:29:6c:
+ 92:75:27:3f:fd:af:91:6d:91:83:ea:73:ef:06:2f:
+ c5:e3:f6:9f:41:27:02:03:35:16:2a:da:b0:01:73:
+ 12:3c:8b:83:24:f3:bf:6e:70:c7:b6:69:6d:c0:23:
+ 21:65:e3:f9:94:fc:98:04:ae:87:4f:4a:5c:84:5e:
+ 5b:50:6c:05:a4:6e:5d:6e:80:b2:6d:9e:59:d7:0e:
+ b1:fa:b6:41:a3:b3:a6:9c:b3:fc:cc:ea:8a:37:de:
+ 9f:17:f3:a2:c6:4e:f0:67:d0:0c:bf:e3:52:22:4d:
+ 91:9c:48:6c:cc:20:ac:b0:7a:06:79:e7:01:a7:c7:
+ 75:0d:30:ad:ec:35:69:30:f4:b2:73:3c:3d:97:c8:
+ a0:62:d7:c1:f5:b5:36:1b:54:8a:56:a9:de:ca:6a:
+ 9d:19
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature
+ X509v3 Extended Key Usage:
+ TLS Web Client Authentication
+ X509v3 Subject Key Identifier:
+ C4:64:B9:16:40:A6:81:7F:A0:26:36:C4:44:3A:C6:AE:21:26:86:A2
+ X509v3 Authority Key Identifier:
+ keyid:83:C8:7C:54:9E:94:80:B4:14:5E:91:A6:1B:10:5F:74:E7:43:8A:3E
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 4c:ca:4d:9c:e6:ec:8b:54:70:49:d1:c1:c7:70:8b:59:42:ff:
+ 3e:bd:63:02:c7:8d:2d:32:8a:f5:f4:aa:c5:46:47:17:60:62:
+ 99:ea:32:03:e7:2b:c2:0f:e0:51:6a:5c:59:73:d0:1c:5c:37:
+ bf:2f:18:fb:67:45:80:8e:96:6c:82:bb:6c:09:1c:2a:df:cc:
+ de:77:e3:67:4a:53:b8:a4:a5:c6:f1:15:b9:f0:4a:5e:ae:52:
+ c6:03:01:66:a9:1f:36:3d:ec:ae:6a:45:9b:0a:e6:56:d1:42:
+ 9b:a1:3b:b1:b4:76:82:88:7e:3c:3f:23:98:22:d7:16:0a:87:
+ 17:68:eb:8c:8f:07:c5:5c:9d:73:b6:c5:94:87:9e:58:1d:a3:
+ 15:33:33:e0:19:01:f5:4c:48:99:af:f1:ed:66:5f:14:99:7d:
+ ba:77:ed:22:26:5f:6d:11:13:e6:48:92:01:0d:c1:27:42:77:
+ e4:82:e8:05:a9:4c:c4:f0:5c:14:71:3a:86:ce:14:1e:ce:fe:
+ fa:fd:ab:df:3b:49:4c:35:7f:3c:19:1b:d9:49:21:71:be:07:
+ e7:98:78:40:36:8e:02:43:86:c6:a2:65:b0:7b:11:6f:97:ba:
+ c7:82:5c:a6:75:be:69:4e:67:56:88:6c:1f:dd:72:f3:91:3d:
+ c5:34:57:55
-----BEGIN CERTIFICATE-----
-MIICdTCCAV2gAwIBAgICJw8wDQYJKoZIhvcNAQEFBQAwJTEjMCEGA1UEAxMaU2Vj
-dXJpdHlUZXN0IENBIENlcnQgKFJTQSkwIBcNMTUwMzIzMDcxMDI2WhgPMjA1NTAz
-MTMwNzEwMjZaMEkxMzAxBgNVBAsTKlNlY3VyaXR5VGVzdHMgQ2xpZW50IENlcnQg
-KFJTQSkoVW50cnVzdGVkKTESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3
-DQEBAQUAA4GNADCBiQKBgQCyZYzwOvKnz/liopGIspHTgIqdN9cEjXWakdMLIYO/
-AyfvUzaz0Wduo55NwA+sNPkUS99vEeOTjuATwie4AI2o1aLLMXduPE17QkcIotzw
-k7h1y8yZLH+5hlpSiuZ4jjcpnKR1zOgXmX0hMRL0+fjCp1/5rc3TUNIF0K9DGJBb
-6QIDAQABow0wCzAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQB5QHD/SxDn
-FCP9Mb19UMjT97DXhig1ztfqEK6qt+oOb6b7mOWygUSXMrFgawQaCwoC1+1F17pD
-hsNK8BNX4nlhivfl62zW7jNn/6ktErX5bQxJFZwMrDfc4hKtgok5legOcgD2aynj
-fNkp5s/ufPds8zZ/EDRU8b9dzyatDPnR3dxbJNFRsNuwmYvpBa8TfYx41bQemgvI
-TS92JFHn1KWUNoktyPkpIi8nTFYeeX/Yun8SW/9D4yuj0IubtX9SkYeA3ONOKrxk
-yZIg60/6oM/APguTV2ew46z26Nxd3jRb2ZpODnGOpb18Y+8SikDsZFBfGKOmdduO
-QVBGM7qiD0vU
+MIIDcjCCAlqgAwIBAgITPmmgmH6hey8f6mrX5yVes0lnOjANBgkqhkiG9w0BAQsF
+ADAlMSMwIQYDVQQDExpTZWN1cml0eVRlc3QgQ0EgQ2VydCAoUlNBKTAgFw0xODA1
+MjYwMTI5MDhaGA8yMDU1MDUxNzAxMjkwOFowSTEzMDEGA1UECwwqU2VjdXJpdHlU
+ZXN0cyBDbGllbnQgQ2VydCAoUlNBKShVbnRydXN0ZWQpMRIwEAYDVQQDDAlsb2Nh
+bGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyghkgfWw8Zei6
+NzYOmNZdzQmE79MsyKV8VwmMiiMWU/qpmNTt/kzxNTWVkszNEoZc9bpiNFIBpzxT
+Kw6DB6it0mpY6oyuG22Ap3B+10h9Rx96f0X8wWME1mgZ4kq5zh1vgm88YXspbJJ1
+Jz/9r5FtkYPqc+8GL8Xj9p9BJwIDNRYq2rABcxI8i4Mk879ucMe2aW3AIyFl4/mU
+/JgErodPSlyEXltQbAWkbl1ugLJtnlnXDrH6tkGjs6acs/zM6oo33p8X86LGTvBn
+0Ay/41IiTZGcSGzMIKywegZ55wGnx3UNMK3sNWkw9LJzPD2XyKBi18H1tTYbVIpW
+qd7Kap0ZAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMG
+A1UdJQQMMAoGCCsGAQUFBwMCMB0GA1UdDgQWBBTEZLkWQKaBf6AmNsREOsauISaG
+ojAfBgNVHSMEGDAWgBSDyHxUnpSAtBRekaYbEF9050OKPjANBgkqhkiG9w0BAQsF
+AAOCAQEATMpNnObsi1RwSdHBx3CLWUL/Pr1jAseNLTKK9fSqxUZHF2BimeoyA+cr
+wg/gUWpcWXPQHFw3vy8Y+2dFgI6WbIK7bAkcKt/M3nfjZ0pTuKSlxvEVufBKXq5S
+xgMBZqkfNj3srmpFmwrmVtFCm6E7sbR2goh+PD8jmCLXFgqHF2jrjI8HxVydc7bF
+lIeeWB2jFTMz4BkB9UxIma/x7WZfFJl9unftIiZfbRET5kiSAQ3BJ0J35ILoBalM
+xPBcFHE6hs4UHs7++v2r3ztJTDV/PBkb2Ukhcb4H55h4QDaOAkOGxqJlsHsRb5e6
+x4JcpnW+aU5nVohsH91y85E9xTRXVQ==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQCyZYzwOvKnz/liopGIspHTgIqdN9cEjXWakdMLIYO/AyfvUzaz
-0Wduo55NwA+sNPkUS99vEeOTjuATwie4AI2o1aLLMXduPE17QkcIotzwk7h1y8yZ
-LH+5hlpSiuZ4jjcpnKR1zOgXmX0hMRL0+fjCp1/5rc3TUNIF0K9DGJBb6QIDAQAB
-AoGBAKNLaz/2ZWmQaHGN53NeKTeVgMw6cdob9ltfQfP9YI/2vpZF8FuWwXu3z07S
-EEaMUrbuYH5VvJ+z945+eUbnUsKCAisSMfHY3UeQl0iH1QVAu0kaeN3eLd49+FU6
-mcFFg2aVdsoDS16X87iihs4EDFJv2kjhb35sL/SKlmJHxDrVAkEA3rgzWJN4iGyJ
-mhzkITeztJFjAZZJDzRpbSRYDZcT90wBnYc9Q7lHffZyJO2mTFMNjJQYZ9BX6eIr
-VwcvcQnUiwJBAM0N2KE7/RCXvho2fOFq3xu9VLtGthftRyEFqETSbO1OUqMxE0N8
-OZSWiOvGdxmnrUtkGvQUQyVLHS1qJNNyu9sCQHdoqNbHkisKjifbb5BDrgyUmlFi
-gt8tCY0jnDYFFwZScNdFh9pEfwkQ1Zfo9m0bZjtFt2QJdukFgpkRWCUx0QsCQQCo
-qArWExFC5Ixn4wk0H0MC/ecDYlXDuFYYwx5z/N+7EADIWUUO7M4veOGFi+fKIjBX
-Ii9JMqFHu1B0WimQAX6hAkEAiuUxXWg0iR24NvVGMlQ0n9JD7z82TZp+6I4fZjXK
-dnWKyKUKwZTIwsJfN6t1tYJ74K5Ho8fQcOwmJUCKh7Ab/A==
+MIIEogIBAAKCAQEAsoIZIH1sPGXoujc2DpjWXc0JhO/TLMilfFcJjIojFlP6qZjU
+7f5M8TU1lZLMzRKGXPW6YjRSAac8UysOgweordJqWOqMrhttgKdwftdIfUcfen9F
+/MFjBNZoGeJKuc4db4JvPGF7KWySdSc//a+RbZGD6nPvBi/F4/afQScCAzUWKtqw
+AXMSPIuDJPO/bnDHtmltwCMhZeP5lPyYBK6HT0pchF5bUGwFpG5dboCybZ5Z1w6x
++rZBo7OmnLP8zOqKN96fF/Oixk7wZ9AMv+NSIk2RnEhszCCssHoGeecBp8d1DTCt
+7DVpMPSyczw9l8igYtfB9bU2G1SKVqneymqdGQIDAQABAoIBAHLsoWKyfQmRjri8
+rPfO3Ew9okBM6sctUqVvn700fgx0+q9Prt6eV0j/ucTXYzUwFQMqTNnG13krAwKE
+eO5Q8v8dtcwTDYlWLTSkGCABWDEXpiOGZzeoBajqpNDtSLDBC2BsOFNGazWrKct0
+/pTEALvq8GP0SdHQ1fXDJJqck4YeByUHkMQnhW+eCB3+MIZGGDvQC5sB9VkWV1fH
+Z2ZklMNFlBrXNemAd1eqtQi0xSuvKGg3XZ05/4YgGcwKgQqOW3KgcELhjVCUIUlg
+kXVpG82U8Lyh7n5TF9lcY2hVTGFQImnvTspwzWKV5vVXuEf68frzPpElcW35uRhj
+0D/1z9ECgYEA2HZFr87KEzpcwtHM/QfiiwURGAVBnzWlOgdF/mjMz+i4v4pA8bt7
+URl5PcrwAcOLI9UPa3XK0uTTGOwGN80IwfrYZVhRx/jhU1ZHwfI7ufrBvxH8BPK9
+m3McWrsokdYxjkpHzREzO3ip71cINlb4UZ1/uCZA8pWioA7oysReaE0CgYEA0x0c
+upIS2xU2jKexLUrg7pzMnotF4n7OoIAG4Et7t5VlBA2EMejTQuTywMkRl4Ms220L
+gJFu0p6gGCcG3kBjP1c3wQx23cTC5B05niaXtW5tNe6kdeAWfXwToFJrSRAR9M0B
+6Gkv9sP2wZwr/DyW5gr4tf/lV/qU6aqzg4foLf0CgYBWscfnSeMVIGLWhECddvL8
+yuK1xCUsJsguHYujAUZGXubfj/fC2Vvid1lfrk/B5RdtGoA6gcrh/FOvv5gd8Th4
+uIbC0ESw2rUkM4I541KYgh3m8MUHFlFqWQgaLqto/WiLnKR1NVZXk1Q8T5cybFK4
+HWRx1KBeiB/CCzahP1SwYQKBgEl77LAUgHO54o77H/UAB2OHOMJHAEBim1HKvpn8
+LEguvEa43bbxr/es8cKhOnpespJ+Vm6eMNEnXdqKWx2pk+JMXZ/Y0tdG0f/NHG0s
+ScphcapAMwbExY9QTRSVG7sG2Pk5EtzvID7o309tKPJXtL7GOuQ++nmxQ3xCatHx
+0KORAoGAB5OpcrjeA6Ns/MH60+PIu87d5kVK63+1cLNj9yadpw0egni5sJvdpVI+
+CrgWeW4dKQ1U11xWhgpeyjL/xfO40rCHixo90YyPeTqDF7J1GdeUiMNSHx4mPsBq
+BWlsc2IeYVlUe3sy5r5oxjhlEgMCxc4eIbrCC0EYbKYUXK9kP28=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
-MIIBiDCB8gIBADBJMTMwMQYDVQQLEypTZWN1cml0eVRlc3RzIENsaWVudCBDZXJ0
-IChSU0EpKFVudHJ1c3RlZCkxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAsmWM8Dryp8/5YqKRiLKR04CKnTfXBI11mpHTCyGD
-vwMn71M2s9FnbqOeTcAPrDT5FEvfbxHjk47gE8InuACNqNWiyzF3bjxNe0JHCKLc
-8JO4dcvMmSx/uYZaUormeI43KZykdczoF5l9ITES9Pn4wqdf+a3N01DSBdCvQxiQ
-W+kCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAHwoEtLs6TKO0aqVBgf9+GeF4qlz
-jrSRobVCzneQI7EqrUjCSQZoSgEMbraw7siTC+/eFb/aMF6Lh3kiXzMpBuFtl62d
-+c3tKMq3Kpff+lvLy9VB8webD2FGOX0dnUQTqtxcY2TWdkuQUr+DWFieAbqpVEfJ
-gN+7XRqcEKy1VR95
+MIICjjCCAXYCAQAwSTEzMDEGA1UECwwqU2VjdXJpdHlUZXN0cyBDbGllbnQgQ2Vy
+dCAoUlNBKShVbnRydXN0ZWQpMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyghkgfWw8Zei6NzYOmNZdzQmE79MsyKV8
+VwmMiiMWU/qpmNTt/kzxNTWVkszNEoZc9bpiNFIBpzxTKw6DB6it0mpY6oyuG22A
+p3B+10h9Rx96f0X8wWME1mgZ4kq5zh1vgm88YXspbJJ1Jz/9r5FtkYPqc+8GL8Xj
+9p9BJwIDNRYq2rABcxI8i4Mk879ucMe2aW3AIyFl4/mU/JgErodPSlyEXltQbAWk
+bl1ugLJtnlnXDrH6tkGjs6acs/zM6oo33p8X86LGTvBn0Ay/41IiTZGcSGzMIKyw
+egZ55wGnx3UNMK3sNWkw9LJzPD2XyKBi18H1tTYbVIpWqd7Kap0ZAgMBAAGgADAN
+BgkqhkiG9w0BAQsFAAOCAQEALlUXJdlmD8meWpE4UdZj4Qaiy4aOSSGdYqLl6yOK
+AWbPrEB5U07zizbYmJzAG9xsbg5v5MZKEiQsRwwY2neqJOVtyVIC7EjcDll8pK0M
+JOOXpfYCxScXRhWxnRe9nUDYkhsdWRSMSHguNCK+mEEpcDLXe61eZV1BWgzkaYZJ
+Zer4lHNlSbEFzs+WlZSvggfAFNPi7OB+nLREZlrfW2uptdk77/JBKOwAeHxasK+H
+rB/Is53KOKYpaqTPqx7UpMWP3PwkTT1Zo1OfgDnMyhPcBhnI2eZ4UuWB9uI3BHpL
+omBVTl6LcsYK2kIK1yLNM/e50N77kdT/euqGNPErf/woyw==
-----END CERTIFICATE REQUEST-----
unsigned char UntrustedClientRSA_Cert_Untrusted_CA_RSA_der[] = {
- 0x30, 0x82, 0x02, 0x75, 0x30, 0x82, 0x01, 0x5d, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x02, 0x27, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x25, 0x31, 0x23,
- 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41,
- 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x30,
- 0x20, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x32, 0x33, 0x30, 0x37, 0x31,
- 0x30, 0x32, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x35, 0x35, 0x30, 0x33,
- 0x31, 0x33, 0x30, 0x37, 0x31, 0x30, 0x32, 0x36, 0x5a, 0x30, 0x49, 0x31,
- 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x53, 0x65,
- 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x20,
- 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20,
- 0x28, 0x52, 0x53, 0x41, 0x29, 0x28, 0x55, 0x6e, 0x74, 0x72, 0x75, 0x73,
- 0x74, 0x65, 0x64, 0x29, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
- 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, 0xb2, 0x65, 0x8c, 0xf0, 0x3a, 0xf2, 0xa7,
- 0xcf, 0xf9, 0x62, 0xa2, 0x91, 0x88, 0xb2, 0x91, 0xd3, 0x80, 0x8a, 0x9d,
- 0x37, 0xd7, 0x04, 0x8d, 0x75, 0x9a, 0x91, 0xd3, 0x0b, 0x21, 0x83, 0xbf,
- 0x03, 0x27, 0xef, 0x53, 0x36, 0xb3, 0xd1, 0x67, 0x6e, 0xa3, 0x9e, 0x4d,
- 0xc0, 0x0f, 0xac, 0x34, 0xf9, 0x14, 0x4b, 0xdf, 0x6f, 0x11, 0xe3, 0x93,
- 0x8e, 0xe0, 0x13, 0xc2, 0x27, 0xb8, 0x00, 0x8d, 0xa8, 0xd5, 0xa2, 0xcb,
- 0x31, 0x77, 0x6e, 0x3c, 0x4d, 0x7b, 0x42, 0x47, 0x08, 0xa2, 0xdc, 0xf0,
- 0x93, 0xb8, 0x75, 0xcb, 0xcc, 0x99, 0x2c, 0x7f, 0xb9, 0x86, 0x5a, 0x52,
- 0x8a, 0xe6, 0x78, 0x8e, 0x37, 0x29, 0x9c, 0xa4, 0x75, 0xcc, 0xe8, 0x17,
- 0x99, 0x7d, 0x21, 0x31, 0x12, 0xf4, 0xf9, 0xf8, 0xc2, 0xa7, 0x5f, 0xf9,
- 0xad, 0xcd, 0xd3, 0x50, 0xd2, 0x05, 0xd0, 0xaf, 0x43, 0x18, 0x90, 0x5b,
- 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x0d, 0x30, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x79, 0x40, 0x70, 0xff, 0x4b, 0x10, 0xe7,
- 0x14, 0x23, 0xfd, 0x31, 0xbd, 0x7d, 0x50, 0xc8, 0xd3, 0xf7, 0xb0, 0xd7,
- 0x86, 0x28, 0x35, 0xce, 0xd7, 0xea, 0x10, 0xae, 0xaa, 0xb7, 0xea, 0x0e,
- 0x6f, 0xa6, 0xfb, 0x98, 0xe5, 0xb2, 0x81, 0x44, 0x97, 0x32, 0xb1, 0x60,
- 0x6b, 0x04, 0x1a, 0x0b, 0x0a, 0x02, 0xd7, 0xed, 0x45, 0xd7, 0xba, 0x43,
- 0x86, 0xc3, 0x4a, 0xf0, 0x13, 0x57, 0xe2, 0x79, 0x61, 0x8a, 0xf7, 0xe5,
- 0xeb, 0x6c, 0xd6, 0xee, 0x33, 0x67, 0xff, 0xa9, 0x2d, 0x12, 0xb5, 0xf9,
- 0x6d, 0x0c, 0x49, 0x15, 0x9c, 0x0c, 0xac, 0x37, 0xdc, 0xe2, 0x12, 0xad,
- 0x82, 0x89, 0x39, 0x95, 0xe8, 0x0e, 0x72, 0x00, 0xf6, 0x6b, 0x29, 0xe3,
- 0x7c, 0xd9, 0x29, 0xe6, 0xcf, 0xee, 0x7c, 0xf7, 0x6c, 0xf3, 0x36, 0x7f,
- 0x10, 0x34, 0x54, 0xf1, 0xbf, 0x5d, 0xcf, 0x26, 0xad, 0x0c, 0xf9, 0xd1,
- 0xdd, 0xdc, 0x5b, 0x24, 0xd1, 0x51, 0xb0, 0xdb, 0xb0, 0x99, 0x8b, 0xe9,
- 0x05, 0xaf, 0x13, 0x7d, 0x8c, 0x78, 0xd5, 0xb4, 0x1e, 0x9a, 0x0b, 0xc8,
- 0x4d, 0x2f, 0x76, 0x24, 0x51, 0xe7, 0xd4, 0xa5, 0x94, 0x36, 0x89, 0x2d,
- 0xc8, 0xf9, 0x29, 0x22, 0x2f, 0x27, 0x4c, 0x56, 0x1e, 0x79, 0x7f, 0xd8,
- 0xba, 0x7f, 0x12, 0x5b, 0xff, 0x43, 0xe3, 0x2b, 0xa3, 0xd0, 0x8b, 0x9b,
- 0xb5, 0x7f, 0x52, 0x91, 0x87, 0x80, 0xdc, 0xe3, 0x4e, 0x2a, 0xbc, 0x64,
- 0xc9, 0x92, 0x20, 0xeb, 0x4f, 0xfa, 0xa0, 0xcf, 0xc0, 0x3e, 0x0b, 0x93,
- 0x57, 0x67, 0xb0, 0xe3, 0xac, 0xf6, 0xe8, 0xdc, 0x5d, 0xde, 0x34, 0x5b,
- 0xd9, 0x9a, 0x4e, 0x0e, 0x71, 0x8e, 0xa5, 0xbd, 0x7c, 0x63, 0xef, 0x12,
- 0x8a, 0x40, 0xec, 0x64, 0x50, 0x5f, 0x18, 0xa3, 0xa6, 0x75, 0xdb, 0x8e,
- 0x41, 0x50, 0x46, 0x33, 0xba, 0xa2, 0x0f, 0x4b, 0xd4
+ 0x30, 0x82, 0x03, 0x72, 0x30, 0x82, 0x02, 0x5a, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x13, 0x3e, 0x69, 0xa0, 0x98, 0x7e, 0xa1, 0x7b, 0x2f, 0x1f,
+ 0xea, 0x6a, 0xd7, 0xe7, 0x25, 0x5e, 0xb3, 0x49, 0x67, 0x3a, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x65,
+ 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x28,
+ 0x52, 0x53, 0x41, 0x29, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35,
+ 0x32, 0x36, 0x30, 0x31, 0x32, 0x39, 0x30, 0x38, 0x5a, 0x18, 0x0f, 0x32,
+ 0x30, 0x35, 0x35, 0x30, 0x35, 0x31, 0x37, 0x30, 0x31, 0x32, 0x39, 0x30,
+ 0x38, 0x5a, 0x30, 0x49, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x0c, 0x2a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54,
+ 0x65, 0x73, 0x74, 0x73, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x20, 0x28, 0x52, 0x53, 0x41, 0x29, 0x28, 0x55,
+ 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x29, 0x31, 0x12, 0x30,
+ 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61,
+ 0x6c, 0x68, 0x6f, 0x73, 0x74, 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, 0xb2, 0x82, 0x19, 0x20, 0x7d, 0x6c, 0x3c, 0x65, 0xe8, 0xba,
+ 0x37, 0x36, 0x0e, 0x98, 0xd6, 0x5d, 0xcd, 0x09, 0x84, 0xef, 0xd3, 0x2c,
+ 0xc8, 0xa5, 0x7c, 0x57, 0x09, 0x8c, 0x8a, 0x23, 0x16, 0x53, 0xfa, 0xa9,
+ 0x98, 0xd4, 0xed, 0xfe, 0x4c, 0xf1, 0x35, 0x35, 0x95, 0x92, 0xcc, 0xcd,
+ 0x12, 0x86, 0x5c, 0xf5, 0xba, 0x62, 0x34, 0x52, 0x01, 0xa7, 0x3c, 0x53,
+ 0x2b, 0x0e, 0x83, 0x07, 0xa8, 0xad, 0xd2, 0x6a, 0x58, 0xea, 0x8c, 0xae,
+ 0x1b, 0x6d, 0x80, 0xa7, 0x70, 0x7e, 0xd7, 0x48, 0x7d, 0x47, 0x1f, 0x7a,
+ 0x7f, 0x45, 0xfc, 0xc1, 0x63, 0x04, 0xd6, 0x68, 0x19, 0xe2, 0x4a, 0xb9,
+ 0xce, 0x1d, 0x6f, 0x82, 0x6f, 0x3c, 0x61, 0x7b, 0x29, 0x6c, 0x92, 0x75,
+ 0x27, 0x3f, 0xfd, 0xaf, 0x91, 0x6d, 0x91, 0x83, 0xea, 0x73, 0xef, 0x06,
+ 0x2f, 0xc5, 0xe3, 0xf6, 0x9f, 0x41, 0x27, 0x02, 0x03, 0x35, 0x16, 0x2a,
+ 0xda, 0xb0, 0x01, 0x73, 0x12, 0x3c, 0x8b, 0x83, 0x24, 0xf3, 0xbf, 0x6e,
+ 0x70, 0xc7, 0xb6, 0x69, 0x6d, 0xc0, 0x23, 0x21, 0x65, 0xe3, 0xf9, 0x94,
+ 0xfc, 0x98, 0x04, 0xae, 0x87, 0x4f, 0x4a, 0x5c, 0x84, 0x5e, 0x5b, 0x50,
+ 0x6c, 0x05, 0xa4, 0x6e, 0x5d, 0x6e, 0x80, 0xb2, 0x6d, 0x9e, 0x59, 0xd7,
+ 0x0e, 0xb1, 0xfa, 0xb6, 0x41, 0xa3, 0xb3, 0xa6, 0x9c, 0xb3, 0xfc, 0xcc,
+ 0xea, 0x8a, 0x37, 0xde, 0x9f, 0x17, 0xf3, 0xa2, 0xc6, 0x4e, 0xf0, 0x67,
+ 0xd0, 0x0c, 0xbf, 0xe3, 0x52, 0x22, 0x4d, 0x91, 0x9c, 0x48, 0x6c, 0xcc,
+ 0x20, 0xac, 0xb0, 0x7a, 0x06, 0x79, 0xe7, 0x01, 0xa7, 0xc7, 0x75, 0x0d,
+ 0x30, 0xad, 0xec, 0x35, 0x69, 0x30, 0xf4, 0xb2, 0x73, 0x3c, 0x3d, 0x97,
+ 0xc8, 0xa0, 0x62, 0xd7, 0xc1, 0xf5, 0xb5, 0x36, 0x1b, 0x54, 0x8a, 0x56,
+ 0xa9, 0xde, 0xca, 0x6a, 0x9d, 0x19, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+ 0x75, 0x30, 0x73, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+ 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x13, 0x06,
+ 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc4, 0x64, 0xb9, 0x16, 0x40, 0xa6, 0x81,
+ 0x7f, 0xa0, 0x26, 0x36, 0xc4, 0x44, 0x3a, 0xc6, 0xae, 0x21, 0x26, 0x86,
+ 0xa2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0x83, 0xc8, 0x7c, 0x54, 0x9e, 0x94, 0x80, 0xb4, 0x14, 0x5e,
+ 0x91, 0xa6, 0x1b, 0x10, 0x5f, 0x74, 0xe7, 0x43, 0x8a, 0x3e, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4c, 0xca, 0x4d, 0x9c, 0xe6, 0xec,
+ 0x8b, 0x54, 0x70, 0x49, 0xd1, 0xc1, 0xc7, 0x70, 0x8b, 0x59, 0x42, 0xff,
+ 0x3e, 0xbd, 0x63, 0x02, 0xc7, 0x8d, 0x2d, 0x32, 0x8a, 0xf5, 0xf4, 0xaa,
+ 0xc5, 0x46, 0x47, 0x17, 0x60, 0x62, 0x99, 0xea, 0x32, 0x03, 0xe7, 0x2b,
+ 0xc2, 0x0f, 0xe0, 0x51, 0x6a, 0x5c, 0x59, 0x73, 0xd0, 0x1c, 0x5c, 0x37,
+ 0xbf, 0x2f, 0x18, 0xfb, 0x67, 0x45, 0x80, 0x8e, 0x96, 0x6c, 0x82, 0xbb,
+ 0x6c, 0x09, 0x1c, 0x2a, 0xdf, 0xcc, 0xde, 0x77, 0xe3, 0x67, 0x4a, 0x53,
+ 0xb8, 0xa4, 0xa5, 0xc6, 0xf1, 0x15, 0xb9, 0xf0, 0x4a, 0x5e, 0xae, 0x52,
+ 0xc6, 0x03, 0x01, 0x66, 0xa9, 0x1f, 0x36, 0x3d, 0xec, 0xae, 0x6a, 0x45,
+ 0x9b, 0x0a, 0xe6, 0x56, 0xd1, 0x42, 0x9b, 0xa1, 0x3b, 0xb1, 0xb4, 0x76,
+ 0x82, 0x88, 0x7e, 0x3c, 0x3f, 0x23, 0x98, 0x22, 0xd7, 0x16, 0x0a, 0x87,
+ 0x17, 0x68, 0xeb, 0x8c, 0x8f, 0x07, 0xc5, 0x5c, 0x9d, 0x73, 0xb6, 0xc5,
+ 0x94, 0x87, 0x9e, 0x58, 0x1d, 0xa3, 0x15, 0x33, 0x33, 0xe0, 0x19, 0x01,
+ 0xf5, 0x4c, 0x48, 0x99, 0xaf, 0xf1, 0xed, 0x66, 0x5f, 0x14, 0x99, 0x7d,
+ 0xba, 0x77, 0xed, 0x22, 0x26, 0x5f, 0x6d, 0x11, 0x13, 0xe6, 0x48, 0x92,
+ 0x01, 0x0d, 0xc1, 0x27, 0x42, 0x77, 0xe4, 0x82, 0xe8, 0x05, 0xa9, 0x4c,
+ 0xc4, 0xf0, 0x5c, 0x14, 0x71, 0x3a, 0x86, 0xce, 0x14, 0x1e, 0xce, 0xfe,
+ 0xfa, 0xfd, 0xab, 0xdf, 0x3b, 0x49, 0x4c, 0x35, 0x7f, 0x3c, 0x19, 0x1b,
+ 0xd9, 0x49, 0x21, 0x71, 0xbe, 0x07, 0xe7, 0x98, 0x78, 0x40, 0x36, 0x8e,
+ 0x02, 0x43, 0x86, 0xc6, 0xa2, 0x65, 0xb0, 0x7b, 0x11, 0x6f, 0x97, 0xba,
+ 0xc7, 0x82, 0x5c, 0xa6, 0x75, 0xbe, 0x69, 0x4e, 0x67, 0x56, 0x88, 0x6c,
+ 0x1f, 0xdd, 0x72, 0xf3, 0x91, 0x3d, 0xc5, 0x34, 0x57, 0x55
};
-unsigned int UntrustedClientRSA_Cert_Untrusted_CA_RSA_der_len = 633;
+unsigned int UntrustedClientRSA_Cert_Untrusted_CA_RSA_der_len = 886;
unsigned char UntrustedClientRSA_Key_der[] = {
- 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xb2,
- 0x65, 0x8c, 0xf0, 0x3a, 0xf2, 0xa7, 0xcf, 0xf9, 0x62, 0xa2, 0x91, 0x88,
- 0xb2, 0x91, 0xd3, 0x80, 0x8a, 0x9d, 0x37, 0xd7, 0x04, 0x8d, 0x75, 0x9a,
- 0x91, 0xd3, 0x0b, 0x21, 0x83, 0xbf, 0x03, 0x27, 0xef, 0x53, 0x36, 0xb3,
- 0xd1, 0x67, 0x6e, 0xa3, 0x9e, 0x4d, 0xc0, 0x0f, 0xac, 0x34, 0xf9, 0x14,
- 0x4b, 0xdf, 0x6f, 0x11, 0xe3, 0x93, 0x8e, 0xe0, 0x13, 0xc2, 0x27, 0xb8,
- 0x00, 0x8d, 0xa8, 0xd5, 0xa2, 0xcb, 0x31, 0x77, 0x6e, 0x3c, 0x4d, 0x7b,
- 0x42, 0x47, 0x08, 0xa2, 0xdc, 0xf0, 0x93, 0xb8, 0x75, 0xcb, 0xcc, 0x99,
- 0x2c, 0x7f, 0xb9, 0x86, 0x5a, 0x52, 0x8a, 0xe6, 0x78, 0x8e, 0x37, 0x29,
- 0x9c, 0xa4, 0x75, 0xcc, 0xe8, 0x17, 0x99, 0x7d, 0x21, 0x31, 0x12, 0xf4,
- 0xf9, 0xf8, 0xc2, 0xa7, 0x5f, 0xf9, 0xad, 0xcd, 0xd3, 0x50, 0xd2, 0x05,
- 0xd0, 0xaf, 0x43, 0x18, 0x90, 0x5b, 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0x02, 0x81, 0x81, 0x00, 0xa3, 0x4b, 0x6b, 0x3f, 0xf6, 0x65, 0x69, 0x90,
- 0x68, 0x71, 0x8d, 0xe7, 0x73, 0x5e, 0x29, 0x37, 0x95, 0x80, 0xcc, 0x3a,
- 0x71, 0xda, 0x1b, 0xf6, 0x5b, 0x5f, 0x41, 0xf3, 0xfd, 0x60, 0x8f, 0xf6,
- 0xbe, 0x96, 0x45, 0xf0, 0x5b, 0x96, 0xc1, 0x7b, 0xb7, 0xcf, 0x4e, 0xd2,
- 0x10, 0x46, 0x8c, 0x52, 0xb6, 0xee, 0x60, 0x7e, 0x55, 0xbc, 0x9f, 0xb3,
- 0xf7, 0x8e, 0x7e, 0x79, 0x46, 0xe7, 0x52, 0xc2, 0x82, 0x02, 0x2b, 0x12,
- 0x31, 0xf1, 0xd8, 0xdd, 0x47, 0x90, 0x97, 0x48, 0x87, 0xd5, 0x05, 0x40,
- 0xbb, 0x49, 0x1a, 0x78, 0xdd, 0xde, 0x2d, 0xde, 0x3d, 0xf8, 0x55, 0x3a,
- 0x99, 0xc1, 0x45, 0x83, 0x66, 0x95, 0x76, 0xca, 0x03, 0x4b, 0x5e, 0x97,
- 0xf3, 0xb8, 0xa2, 0x86, 0xce, 0x04, 0x0c, 0x52, 0x6f, 0xda, 0x48, 0xe1,
- 0x6f, 0x7e, 0x6c, 0x2f, 0xf4, 0x8a, 0x96, 0x62, 0x47, 0xc4, 0x3a, 0xd5,
- 0x02, 0x41, 0x00, 0xde, 0xb8, 0x33, 0x58, 0x93, 0x78, 0x88, 0x6c, 0x89,
- 0x9a, 0x1c, 0xe4, 0x21, 0x37, 0xb3, 0xb4, 0x91, 0x63, 0x01, 0x96, 0x49,
- 0x0f, 0x34, 0x69, 0x6d, 0x24, 0x58, 0x0d, 0x97, 0x13, 0xf7, 0x4c, 0x01,
- 0x9d, 0x87, 0x3d, 0x43, 0xb9, 0x47, 0x7d, 0xf6, 0x72, 0x24, 0xed, 0xa6,
- 0x4c, 0x53, 0x0d, 0x8c, 0x94, 0x18, 0x67, 0xd0, 0x57, 0xe9, 0xe2, 0x2b,
- 0x57, 0x07, 0x2f, 0x71, 0x09, 0xd4, 0x8b, 0x02, 0x41, 0x00, 0xcd, 0x0d,
- 0xd8, 0xa1, 0x3b, 0xfd, 0x10, 0x97, 0xbe, 0x1a, 0x36, 0x7c, 0xe1, 0x6a,
- 0xdf, 0x1b, 0xbd, 0x54, 0xbb, 0x46, 0xb6, 0x17, 0xed, 0x47, 0x21, 0x05,
- 0xa8, 0x44, 0xd2, 0x6c, 0xed, 0x4e, 0x52, 0xa3, 0x31, 0x13, 0x43, 0x7c,
- 0x39, 0x94, 0x96, 0x88, 0xeb, 0xc6, 0x77, 0x19, 0xa7, 0xad, 0x4b, 0x64,
- 0x1a, 0xf4, 0x14, 0x43, 0x25, 0x4b, 0x1d, 0x2d, 0x6a, 0x24, 0xd3, 0x72,
- 0xbb, 0xdb, 0x02, 0x40, 0x77, 0x68, 0xa8, 0xd6, 0xc7, 0x92, 0x2b, 0x0a,
- 0x8e, 0x27, 0xdb, 0x6f, 0x90, 0x43, 0xae, 0x0c, 0x94, 0x9a, 0x51, 0x62,
- 0x82, 0xdf, 0x2d, 0x09, 0x8d, 0x23, 0x9c, 0x36, 0x05, 0x17, 0x06, 0x52,
- 0x70, 0xd7, 0x45, 0x87, 0xda, 0x44, 0x7f, 0x09, 0x10, 0xd5, 0x97, 0xe8,
- 0xf6, 0x6d, 0x1b, 0x66, 0x3b, 0x45, 0xb7, 0x64, 0x09, 0x76, 0xe9, 0x05,
- 0x82, 0x99, 0x11, 0x58, 0x25, 0x31, 0xd1, 0x0b, 0x02, 0x41, 0x00, 0xa8,
- 0xa8, 0x0a, 0xd6, 0x13, 0x11, 0x42, 0xe4, 0x8c, 0x67, 0xe3, 0x09, 0x34,
- 0x1f, 0x43, 0x02, 0xfd, 0xe7, 0x03, 0x62, 0x55, 0xc3, 0xb8, 0x56, 0x18,
- 0xc3, 0x1e, 0x73, 0xfc, 0xdf, 0xbb, 0x10, 0x00, 0xc8, 0x59, 0x45, 0x0e,
- 0xec, 0xce, 0x2f, 0x78, 0xe1, 0x85, 0x8b, 0xe7, 0xca, 0x22, 0x30, 0x57,
- 0x22, 0x2f, 0x49, 0x32, 0xa1, 0x47, 0xbb, 0x50, 0x74, 0x5a, 0x29, 0x90,
- 0x01, 0x7e, 0xa1, 0x02, 0x41, 0x00, 0x8a, 0xe5, 0x31, 0x5d, 0x68, 0x34,
- 0x89, 0x1d, 0xb8, 0x36, 0xf5, 0x46, 0x32, 0x54, 0x34, 0x9f, 0xd2, 0x43,
- 0xef, 0x3f, 0x36, 0x4d, 0x9a, 0x7e, 0xe8, 0x8e, 0x1f, 0x66, 0x35, 0xca,
- 0x76, 0x75, 0x8a, 0xc8, 0xa5, 0x0a, 0xc1, 0x94, 0xc8, 0xc2, 0xc2, 0x5f,
- 0x37, 0xab, 0x75, 0xb5, 0x82, 0x7b, 0xe0, 0xae, 0x47, 0xa3, 0xc7, 0xd0,
- 0x70, 0xec, 0x26, 0x25, 0x40, 0x8a, 0x87, 0xb0, 0x1b, 0xfc
+ 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xb2, 0x82, 0x19, 0x20, 0x7d, 0x6c, 0x3c, 0x65, 0xe8, 0xba, 0x37, 0x36,
+ 0x0e, 0x98, 0xd6, 0x5d, 0xcd, 0x09, 0x84, 0xef, 0xd3, 0x2c, 0xc8, 0xa5,
+ 0x7c, 0x57, 0x09, 0x8c, 0x8a, 0x23, 0x16, 0x53, 0xfa, 0xa9, 0x98, 0xd4,
+ 0xed, 0xfe, 0x4c, 0xf1, 0x35, 0x35, 0x95, 0x92, 0xcc, 0xcd, 0x12, 0x86,
+ 0x5c, 0xf5, 0xba, 0x62, 0x34, 0x52, 0x01, 0xa7, 0x3c, 0x53, 0x2b, 0x0e,
+ 0x83, 0x07, 0xa8, 0xad, 0xd2, 0x6a, 0x58, 0xea, 0x8c, 0xae, 0x1b, 0x6d,
+ 0x80, 0xa7, 0x70, 0x7e, 0xd7, 0x48, 0x7d, 0x47, 0x1f, 0x7a, 0x7f, 0x45,
+ 0xfc, 0xc1, 0x63, 0x04, 0xd6, 0x68, 0x19, 0xe2, 0x4a, 0xb9, 0xce, 0x1d,
+ 0x6f, 0x82, 0x6f, 0x3c, 0x61, 0x7b, 0x29, 0x6c, 0x92, 0x75, 0x27, 0x3f,
+ 0xfd, 0xaf, 0x91, 0x6d, 0x91, 0x83, 0xea, 0x73, 0xef, 0x06, 0x2f, 0xc5,
+ 0xe3, 0xf6, 0x9f, 0x41, 0x27, 0x02, 0x03, 0x35, 0x16, 0x2a, 0xda, 0xb0,
+ 0x01, 0x73, 0x12, 0x3c, 0x8b, 0x83, 0x24, 0xf3, 0xbf, 0x6e, 0x70, 0xc7,
+ 0xb6, 0x69, 0x6d, 0xc0, 0x23, 0x21, 0x65, 0xe3, 0xf9, 0x94, 0xfc, 0x98,
+ 0x04, 0xae, 0x87, 0x4f, 0x4a, 0x5c, 0x84, 0x5e, 0x5b, 0x50, 0x6c, 0x05,
+ 0xa4, 0x6e, 0x5d, 0x6e, 0x80, 0xb2, 0x6d, 0x9e, 0x59, 0xd7, 0x0e, 0xb1,
+ 0xfa, 0xb6, 0x41, 0xa3, 0xb3, 0xa6, 0x9c, 0xb3, 0xfc, 0xcc, 0xea, 0x8a,
+ 0x37, 0xde, 0x9f, 0x17, 0xf3, 0xa2, 0xc6, 0x4e, 0xf0, 0x67, 0xd0, 0x0c,
+ 0xbf, 0xe3, 0x52, 0x22, 0x4d, 0x91, 0x9c, 0x48, 0x6c, 0xcc, 0x20, 0xac,
+ 0xb0, 0x7a, 0x06, 0x79, 0xe7, 0x01, 0xa7, 0xc7, 0x75, 0x0d, 0x30, 0xad,
+ 0xec, 0x35, 0x69, 0x30, 0xf4, 0xb2, 0x73, 0x3c, 0x3d, 0x97, 0xc8, 0xa0,
+ 0x62, 0xd7, 0xc1, 0xf5, 0xb5, 0x36, 0x1b, 0x54, 0x8a, 0x56, 0xa9, 0xde,
+ 0xca, 0x6a, 0x9d, 0x19, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01,
+ 0x00, 0x72, 0xec, 0xa1, 0x62, 0xb2, 0x7d, 0x09, 0x91, 0x8e, 0xb8, 0xbc,
+ 0xac, 0xf7, 0xce, 0xdc, 0x4c, 0x3d, 0xa2, 0x40, 0x4c, 0xea, 0xc7, 0x2d,
+ 0x52, 0xa5, 0x6f, 0x9f, 0xbd, 0x34, 0x7e, 0x0c, 0x74, 0xfa, 0xaf, 0x4f,
+ 0xae, 0xde, 0x9e, 0x57, 0x48, 0xff, 0xb9, 0xc4, 0xd7, 0x63, 0x35, 0x30,
+ 0x15, 0x03, 0x2a, 0x4c, 0xd9, 0xc6, 0xd7, 0x79, 0x2b, 0x03, 0x02, 0x84,
+ 0x78, 0xee, 0x50, 0xf2, 0xff, 0x1d, 0xb5, 0xcc, 0x13, 0x0d, 0x89, 0x56,
+ 0x2d, 0x34, 0xa4, 0x18, 0x20, 0x01, 0x58, 0x31, 0x17, 0xa6, 0x23, 0x86,
+ 0x67, 0x37, 0xa8, 0x05, 0xa8, 0xea, 0xa4, 0xd0, 0xed, 0x48, 0xb0, 0xc1,
+ 0x0b, 0x60, 0x6c, 0x38, 0x53, 0x46, 0x6b, 0x35, 0xab, 0x29, 0xcb, 0x74,
+ 0xfe, 0x94, 0xc4, 0x00, 0xbb, 0xea, 0xf0, 0x63, 0xf4, 0x49, 0xd1, 0xd0,
+ 0xd5, 0xf5, 0xc3, 0x24, 0x9a, 0x9c, 0x93, 0x86, 0x1e, 0x07, 0x25, 0x07,
+ 0x90, 0xc4, 0x27, 0x85, 0x6f, 0x9e, 0x08, 0x1d, 0xfe, 0x30, 0x86, 0x46,
+ 0x18, 0x3b, 0xd0, 0x0b, 0x9b, 0x01, 0xf5, 0x59, 0x16, 0x57, 0x57, 0xc7,
+ 0x67, 0x66, 0x64, 0x94, 0xc3, 0x45, 0x94, 0x1a, 0xd7, 0x35, 0xe9, 0x80,
+ 0x77, 0x57, 0xaa, 0xb5, 0x08, 0xb4, 0xc5, 0x2b, 0xaf, 0x28, 0x68, 0x37,
+ 0x5d, 0x9d, 0x39, 0xff, 0x86, 0x20, 0x19, 0xcc, 0x0a, 0x81, 0x0a, 0x8e,
+ 0x5b, 0x72, 0xa0, 0x70, 0x42, 0xe1, 0x8d, 0x50, 0x94, 0x21, 0x49, 0x60,
+ 0x91, 0x75, 0x69, 0x1b, 0xcd, 0x94, 0xf0, 0xbc, 0xa1, 0xee, 0x7e, 0x53,
+ 0x17, 0xd9, 0x5c, 0x63, 0x68, 0x55, 0x4c, 0x61, 0x50, 0x22, 0x69, 0xef,
+ 0x4e, 0xca, 0x70, 0xcd, 0x62, 0x95, 0xe6, 0xf5, 0x57, 0xb8, 0x47, 0xfa,
+ 0xf1, 0xfa, 0xf3, 0x3e, 0x91, 0x25, 0x71, 0x6d, 0xf9, 0xb9, 0x18, 0x63,
+ 0xd0, 0x3f, 0xf5, 0xcf, 0xd1, 0x02, 0x81, 0x81, 0x00, 0xd8, 0x76, 0x45,
+ 0xaf, 0xce, 0xca, 0x13, 0x3a, 0x5c, 0xc2, 0xd1, 0xcc, 0xfd, 0x07, 0xe2,
+ 0x8b, 0x05, 0x11, 0x18, 0x05, 0x41, 0x9f, 0x35, 0xa5, 0x3a, 0x07, 0x45,
+ 0xfe, 0x68, 0xcc, 0xcf, 0xe8, 0xb8, 0xbf, 0x8a, 0x40, 0xf1, 0xbb, 0x7b,
+ 0x51, 0x19, 0x79, 0x3d, 0xca, 0xf0, 0x01, 0xc3, 0x8b, 0x23, 0xd5, 0x0f,
+ 0x6b, 0x75, 0xca, 0xd2, 0xe4, 0xd3, 0x18, 0xec, 0x06, 0x37, 0xcd, 0x08,
+ 0xc1, 0xfa, 0xd8, 0x65, 0x58, 0x51, 0xc7, 0xf8, 0xe1, 0x53, 0x56, 0x47,
+ 0xc1, 0xf2, 0x3b, 0xb9, 0xfa, 0xc1, 0xbf, 0x11, 0xfc, 0x04, 0xf2, 0xbd,
+ 0x9b, 0x73, 0x1c, 0x5a, 0xbb, 0x28, 0x91, 0xd6, 0x31, 0x8e, 0x4a, 0x47,
+ 0xcd, 0x11, 0x33, 0x3b, 0x78, 0xa9, 0xef, 0x57, 0x08, 0x36, 0x56, 0xf8,
+ 0x51, 0x9d, 0x7f, 0xb8, 0x26, 0x40, 0xf2, 0x95, 0xa2, 0xa0, 0x0e, 0xe8,
+ 0xca, 0xc4, 0x5e, 0x68, 0x4d, 0x02, 0x81, 0x81, 0x00, 0xd3, 0x1d, 0x1c,
+ 0xba, 0x92, 0x12, 0xdb, 0x15, 0x36, 0x8c, 0xa7, 0xb1, 0x2d, 0x4a, 0xe0,
+ 0xee, 0x9c, 0xcc, 0x9e, 0x8b, 0x45, 0xe2, 0x7e, 0xce, 0xa0, 0x80, 0x06,
+ 0xe0, 0x4b, 0x7b, 0xb7, 0x95, 0x65, 0x04, 0x0d, 0x84, 0x31, 0xe8, 0xd3,
+ 0x42, 0xe4, 0xf2, 0xc0, 0xc9, 0x11, 0x97, 0x83, 0x2c, 0xdb, 0x6d, 0x0b,
+ 0x80, 0x91, 0x6e, 0xd2, 0x9e, 0xa0, 0x18, 0x27, 0x06, 0xde, 0x40, 0x63,
+ 0x3f, 0x57, 0x37, 0xc1, 0x0c, 0x76, 0xdd, 0xc4, 0xc2, 0xe4, 0x1d, 0x39,
+ 0x9e, 0x26, 0x97, 0xb5, 0x6e, 0x6d, 0x35, 0xee, 0xa4, 0x75, 0xe0, 0x16,
+ 0x7d, 0x7c, 0x13, 0xa0, 0x52, 0x6b, 0x49, 0x10, 0x11, 0xf4, 0xcd, 0x01,
+ 0xe8, 0x69, 0x2f, 0xf6, 0xc3, 0xf6, 0xc1, 0x9c, 0x2b, 0xfc, 0x3c, 0x96,
+ 0xe6, 0x0a, 0xf8, 0xb5, 0xff, 0xe5, 0x57, 0xfa, 0x94, 0xe9, 0xaa, 0xb3,
+ 0x83, 0x87, 0xe8, 0x2d, 0xfd, 0x02, 0x81, 0x80, 0x56, 0xb1, 0xc7, 0xe7,
+ 0x49, 0xe3, 0x15, 0x20, 0x62, 0xd6, 0x84, 0x40, 0x9d, 0x76, 0xf2, 0xfc,
+ 0xca, 0xe2, 0xb5, 0xc4, 0x25, 0x2c, 0x26, 0xc8, 0x2e, 0x1d, 0x8b, 0xa3,
+ 0x01, 0x46, 0x46, 0x5e, 0xe6, 0xdf, 0x8f, 0xf7, 0xc2, 0xd9, 0x5b, 0xe2,
+ 0x77, 0x59, 0x5f, 0xae, 0x4f, 0xc1, 0xe5, 0x17, 0x6d, 0x1a, 0x80, 0x3a,
+ 0x81, 0xca, 0xe1, 0xfc, 0x53, 0xaf, 0xbf, 0x98, 0x1d, 0xf1, 0x38, 0x78,
+ 0xb8, 0x86, 0xc2, 0xd0, 0x44, 0xb0, 0xda, 0xb5, 0x24, 0x33, 0x82, 0x39,
+ 0xe3, 0x52, 0x98, 0x82, 0x1d, 0xe6, 0xf0, 0xc5, 0x07, 0x16, 0x51, 0x6a,
+ 0x59, 0x08, 0x1a, 0x2e, 0xab, 0x68, 0xfd, 0x68, 0x8b, 0x9c, 0xa4, 0x75,
+ 0x35, 0x56, 0x57, 0x93, 0x54, 0x3c, 0x4f, 0x97, 0x32, 0x6c, 0x52, 0xb8,
+ 0x1d, 0x64, 0x71, 0xd4, 0xa0, 0x5e, 0x88, 0x1f, 0xc2, 0x0b, 0x36, 0xa1,
+ 0x3f, 0x54, 0xb0, 0x61, 0x02, 0x81, 0x80, 0x49, 0x7b, 0xec, 0xb0, 0x14,
+ 0x80, 0x73, 0xb9, 0xe2, 0x8e, 0xfb, 0x1f, 0xf5, 0x00, 0x07, 0x63, 0x87,
+ 0x38, 0xc2, 0x47, 0x00, 0x40, 0x62, 0x9b, 0x51, 0xca, 0xbe, 0x99, 0xfc,
+ 0x2c, 0x48, 0x2e, 0xbc, 0x46, 0xb8, 0xdd, 0xb6, 0xf1, 0xaf, 0xf7, 0xac,
+ 0xf1, 0xc2, 0xa1, 0x3a, 0x7a, 0x5e, 0xb2, 0x92, 0x7e, 0x56, 0x6e, 0x9e,
+ 0x30, 0xd1, 0x27, 0x5d, 0xda, 0x8a, 0x5b, 0x1d, 0xa9, 0x93, 0xe2, 0x4c,
+ 0x5d, 0x9f, 0xd8, 0xd2, 0xd7, 0x46, 0xd1, 0xff, 0xcd, 0x1c, 0x6d, 0x2c,
+ 0x49, 0xca, 0x61, 0x71, 0xaa, 0x40, 0x33, 0x06, 0xc4, 0xc5, 0x8f, 0x50,
+ 0x4d, 0x14, 0x95, 0x1b, 0xbb, 0x06, 0xd8, 0xf9, 0x39, 0x12, 0xdc, 0xef,
+ 0x20, 0x3e, 0xe8, 0xdf, 0x4f, 0x6d, 0x28, 0xf2, 0x57, 0xb4, 0xbe, 0xc6,
+ 0x3a, 0xe4, 0x3e, 0xfa, 0x79, 0xb1, 0x43, 0x7c, 0x42, 0x6a, 0xd1, 0xf1,
+ 0xd0, 0xa3, 0x91, 0x02, 0x81, 0x80, 0x07, 0x93, 0xa9, 0x72, 0xb8, 0xde,
+ 0x03, 0xa3, 0x6c, 0xfc, 0xc1, 0xfa, 0xd3, 0xe3, 0xc8, 0xbb, 0xce, 0xdd,
+ 0xe6, 0x45, 0x4a, 0xeb, 0x7f, 0xb5, 0x70, 0xb3, 0x63, 0xf7, 0x26, 0x9d,
+ 0xa7, 0x0d, 0x1e, 0x82, 0x78, 0xb9, 0xb0, 0x9b, 0xdd, 0xa5, 0x52, 0x3e,
+ 0x0a, 0xb8, 0x16, 0x79, 0x6e, 0x1d, 0x29, 0x0d, 0x54, 0xd7, 0x5c, 0x56,
+ 0x86, 0x0a, 0x5e, 0xca, 0x32, 0xff, 0xc5, 0xf3, 0xb8, 0xd2, 0xb0, 0x87,
+ 0x8b, 0x1a, 0x3d, 0xd1, 0x8c, 0x8f, 0x79, 0x3a, 0x83, 0x17, 0xb2, 0x75,
+ 0x19, 0xd7, 0x94, 0x88, 0xc3, 0x52, 0x1f, 0x1e, 0x26, 0x3e, 0xc0, 0x6a,
+ 0x05, 0x69, 0x6c, 0x73, 0x62, 0x1e, 0x61, 0x59, 0x54, 0x7b, 0x7b, 0x32,
+ 0xe6, 0xbe, 0x68, 0xc6, 0x38, 0x65, 0x12, 0x03, 0x02, 0xc5, 0xce, 0x1e,
+ 0x21, 0xba, 0xc2, 0x0b, 0x41, 0x18, 0x6c, 0xa6, 0x14, 0x5c, 0xaf, 0x64,
+ 0x3f, 0x6f
};
-unsigned int UntrustedClientRSA_Key_der_len = 610;
+unsigned int UntrustedClientRSA_Key_der_len = 1190;
CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue);
CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue) CF_RETURNS_RETAINED
{
- cc_unit paddingBuffer[ccn_nof_size(desired_message_length)];
- bzero(paddingBuffer, sizeof(cc_unit) * ccn_nof_size(desired_message_length)); // XXX needed??
+ size_t pBufferSize = ccn_sizeof_size(desired_message_length);
+ cc_unit *paddingBuffer = malloc(pBufferSize);
+ if (paddingBuffer == NULL){
+ return (void*)GetNoMemoryErrorAndRetain();
+ }
+
+ bzero(paddingBuffer, pBufferSize); // XXX needed??
static dispatch_once_t randomNumberGenneratorInitialzed;
static struct ccrng_system_state rng;
dispatch_once(&randomNumberGenneratorInitialzed, ^{
ccrsa_oaep_encode(ccsha1_di(),
(struct ccrng_state*)&rng,
- sizeof(paddingBuffer), (cc_unit*)paddingBuffer,
+ pBufferSize, (cc_unit*)paddingBuffer,
CFDataGetLength(dataValue), CFDataGetBytePtr(dataValue));
- ccn_swap(ccn_nof_size(sizeof(paddingBuffer)), (cc_unit*)paddingBuffer);
+ ccn_swap(ccn_nof_size(pBufferSize), (cc_unit*)paddingBuffer);
CFDataRef paddedValue = CFDataCreate(NULL, (UInt8*)paddingBuffer, desired_message_length);
- return paddedValue ? paddedValue : (void*)GetNoMemoryErrorAndRetain();
+ free(paddingBuffer);
+ return paddedValue ? paddedValue : (void*)GetNoMemoryErrorAndRetain();
}
CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage);
CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage) CF_RETURNS_RETAINED
{
size_t mlen = CFDataGetLength(encodedMessage);
- cc_size n = ccn_nof_size(mlen);
- cc_unit paddingBuffer[n];
- UInt8 plainText[mlen];
+ size_t pBufferSize = ccn_sizeof_size(mlen);
+ cc_unit *paddingBuffer = malloc(pBufferSize);
+ UInt8 *plainText = malloc(mlen);
+ if (plainText == NULL || paddingBuffer == NULL) {
+ free(plainText);
+ free(paddingBuffer);
+ return (void*)GetNoMemoryErrorAndRetain();
+ }
- ccn_read_uint(n, paddingBuffer, mlen, CFDataGetBytePtr(encodedMessage));
+ ccn_read_uint(ccn_nof_size(mlen), paddingBuffer, mlen, CFDataGetBytePtr(encodedMessage));
size_t plainTextLength = mlen;
int err = ccrsa_oaep_decode(ccsha1_di(), &plainTextLength, plainText, mlen, paddingBuffer);
// XXX should make a CFError or something.
CFErrorRef error = fancy_error(CFSTR("CoreCrypto"), err, CFSTR("OAEP decode error"));
CFRetainSafe(error);
+ free(plainText);
+ free(paddingBuffer);
return (void*)error;
}
- CFDataRef result = CFDataCreate(NULL, (UInt8*)plainText, plainTextLength);
- return result;
+
+ CFDataRef result = CFDataCreate(NULL, (UInt8*)plainText, plainTextLength);
+
+ free(plainText);
+ free(paddingBuffer);
+
+ return result;
}
#include "Utilities.h"
#include "misc.h"
-static const CFStringRef kSecCustom = CFSTR("CustomTransform");
+const CFStringRef kSecCustom = CFSTR("CustomTransform");
const CFStringRef kSecTransformPreviousErrorKey = CFSTR("PreviousError");
const CFStringRef kSecTransformAbortOriginatorKey = CFSTR("Originating Transform");
const CFStringRef kSecTransformActionCanExecute = CFSTR("CanExecute");
};
-static SecTransformActionBlock default_can_run = ^{ return (CFTypeRef)NULL; };
-static SecTransformActionBlock default_execute_starting = default_can_run;
-static SecTransformActionBlock default_finalize = default_execute_starting;
-static SecTransformActionBlock default_externalize_data = default_finalize;
+static const SecTransformActionBlock default_can_run = ^{ return (CFTypeRef)NULL; };
+static const SecTransformActionBlock default_execute_starting = default_can_run;
+static const SecTransformActionBlock default_finalize = default_execute_starting;
+static const SecTransformActionBlock default_externalize_data = default_finalize;
-static SecTransformDataBlock default_process_data = ^(CFTypeRef value) { return value; };
+static const SecTransformDataBlock default_process_data = ^(CFTypeRef value) { return value; };
//static SecTransformDataBlock default_validate = ^(CFTypeRef value) { return (CFTypeRef)NULL; };
-static SecTransformAttributeActionBlock default_generic_attribute_set_notification =
+static const SecTransformAttributeActionBlock default_generic_attribute_set_notification =
^(SecTransformAttributeRef ah, CFTypeRef value) { return value; };
static SecTransformAttributeActionBlock default_generic_attribute_validation =
{
// make an array big enough to hold all of the attributes
CFIndex numAttributes = CFSetGetCount(mAttributes);
- transform_attribute* attributes[numAttributes];
+ transform_attribute **attributes = (transform_attribute**)malloc(numAttributes*sizeof(transform_attribute));
+
+ if (attributes == NULL) {
+ // No more memory, we assume it's orphaned
+ return true;
+ }
TAGetAll(attributes);
{
if (attributes[i]->connections && CFArrayGetCount(attributes[i]->connections) != 0)
{
+ free(attributes);
return false;
}
}
+ free(attributes);
+
return true;
}
{
// make an array big enough to hold all of the attributes
CFIndex numAttributes = CFSetGetCount(mAttributes);
- transform_attribute* attributes[numAttributes];
+ transform_attribute **attributes = (transform_attribute**)malloc(numAttributes*sizeof(transform_attribute));
+
+ if (attributes == NULL) {
+ // No more memory, we assume it's orphaned
+ return true;
+ }
TAGetAll(attributes);
{
if (attributes[i]->has_incoming_connection)
{
+ free(attributes);
return false;
}
}
+ free(attributes);
+
return true;
}
void Transform::FinalizeForClang()
{
CFIndex numAttributes = CFSetGetCount(mAttributes);
- SecTransformAttributeRef handles[numAttributes];
- CFSetGetValues(mAttributes, (const void**)&handles);
+ SecTransformAttributeRef *handles = (const void**)malloc(numAttributes*sizeof(SecTransformAttributeRef));
+
+ if (handles == NULL) {
+ syslog(LOG_ERR, "Unable to allocate SecTransformAttributeRef handles in FinalizeForClang");
+ return;
+ }
+
+ CFSetGetValues(mAttributes, handles);
for(CFIndex i = 0; i < numAttributes; ++i) {
SecTransformAttributeRef ah = handles[i];
}
dispatch_release(ta->q);
}
-
+
// We might be finalizing a transform as it is being activated, make sure that is complete before we do the rest
dispatch_group_notify(mActivationPending, mDispatchQueue, ^{
if (mActivationQueue != NULL) {
});
dispatch_release(mDispatchQueue);
});
+
+ free(handles);
}
void Transform::Finalize()
CFDictionaryRef Transform::CopyState()
{
CFIndex i, j, cnt = CFSetGetCount(mAttributes);
- transform_attribute *attrs[cnt];
- CFStringRef names[cnt];
- CFDictionaryRef values[cnt];
+ transform_attribute **attrs = (transform_attribute**)malloc(cnt*sizeof(transform_attribute));
+ CFStringRef *names = (CFStringRef*)malloc(cnt*sizeof(CFStringRef));
+ CFDictionaryRef *values = (CFDictionaryRef*)malloc(sizeof(CFDictionaryRef) * cnt);
+
+ if (attrs == NULL || names == NULL || values == NULL) {
+ free(attrs);
+ free(names);
+ free(values);
+ return NULL;
+ }
+
TAGetAll(attrs);
for(i = j = 0; i < cnt; ++i)
{
}
CFDictionaryRef result = CFDictionaryCreate(NULL, (const void**)&names, (const void**)&values, j, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
+
+ free(names);
+
for(i = j = 0; i < cnt; ++i)
{
transform_attribute *ta = attrs[i];
}
}
+ free(attrs);
+ free(values);
return result;
}
// now walk the attribute list
CFIndex numAttributes = CFSetGetCount(mAttributes);
- transform_attribute *attributes[numAttributes];
+ transform_attribute **attributes = (transform_attribute**)malloc(numAttributes*sizeof(transform_attribute));
+
+ if (attributes == NULL) {
+ return GetNoMemoryErrorAndRetain();
+ }
+
TAGetAll(attributes);
CFIndex i;
}
}
+ free(attributes);
+
return NULL;
}
dispatch_barrier_sync(gRegisteredQueue, ^(void) {
CFMutableStringRef transformNames = CFStringCreateMutable(NULL, 0);
CFIndex numberRegistered = CFDictionaryGetCount(gRegistered);
- CFStringRef names[numberRegistered];
+ CFStringRef *names = (CFStringRef*)malloc(numberRegistered * sizeof(CFStringRef));
+ if (names == NULL) {
+ *baseError = CreateSecTransformErrorRef(errSecMemoryError,
+ "The %s transform names can't be allocated.", type);
+ return NULL;
+ }
+
CFDictionaryGetKeysAndValues(gRegistered, (const void**)names, NULL);
for(int i = 0; i < numberRegistered; i++) {
if (i != 0) {
CFStringAppend(transformNames, names[i]);
}
+ free(names);
+
*baseError = CreateSecTransformErrorRef(kSecTransformTransformIsNotRegistered,
"The %s transform is not registered, choose from: %@", type,transformNames);
CFErrorRef fancy_error(CFStringRef domain, CFIndex code, CFStringRef description);
extern void graphviz(FILE *f, SecTransformRef tr);
extern void CFfprintf(FILE *f, const char *format, ...);
- CFErrorRef GetNoMemoryError();
- CFErrorRef GetNoMemoryErrorAndRetain();
+ CFErrorRef GetNoMemoryError(void);
+ CFErrorRef GetNoMemoryErrorAndRetain(void);
void CFSafeRelease(CFTypeRef object);
// NOTE: the return may or allocate a fair bit more space then it needs.
#undef DEBUGGING
#if !defined(NDEBUG)
# define DEBUGGING 1
-# define DEBUGDUMP 1
+// No more debugdump, it emits thread-unsafe buggy code which hampers actual debugging, ironically enough
+// # define DEBUGDUMP 1
#else //NDEBUG
# define DEBUGGING 0
#endif //NDEBUG
#include <security_utilities/utilities_dtrace.h>
// The following are deprecated functions. Don't use them (but they need to be here for symbol reasons).
-void secdebug_internal(const char* scope, const char* format, ...);
-void secdebugfunc_internal(const char* scope, const char* functionname, const char* format, ...);
+__attribute__((visibility("default"))) void secdebug_internal(const char* scope, const char* format, ...);
+__attribute__((visibility("default"))) void secdebugfunc_internal(const char* scope, const char* functionname, const char* format, ...);
__END_DECLS
#include <typeinfo>
#include <stdio.h>
#include <Security/SecBase.h>
+#include <Security/CSCommon.h>
#include <execinfo.h>
#include <cxxabi.h>
SECURITY_EXCEPTION_THROW_OSSTATUS(this, err);
snprintf(whatBuffer, whatBufferSize, "MacOS error: %d", this->error);
- secnotice("security_exception", "%s", what());
- LogBacktrace();
+ switch (err) {
+ case errSecCSReqFailed:
+ // This 'error' isn't an actual error and doesn't warrant being logged.
+ break;
+ default:
+ secnotice("security_exception", "%s", what());
+ LogBacktrace();
+ }
}
const char *MacOSError::what() const throw ()
//
// mach++ - C++ bindings for useful Mach primitives
//
+#define __STDC_WANT_LIB_EXT1__ 1
+#include <string.h>
+
#include <security_utilities/mach++.h>
#include <mach/mach_error.h>
#include <security_utilities/debugging.h>
assert(size >= sizeof(mach_msg_header_t));
release();
mSize = size + MAX_TRAILER_SIZE;
- mBuffer = reinterpret_cast<mig_reply_error_t *>(new char[mSize]);
+ mBuffer = reinterpret_cast<mig_reply_error_t *>(new char[mSize]());
mRelease = true;
}
+void Message::clearBuffer(void)
+{
+ (void)memset_s(mBuffer, mSize, 0, mSize);
+}
void Message::release()
{
void setBuffer(void *buffer, mach_msg_size_t size); // use buffer with size
void setBuffer(mach_msg_size_t size); // allocate buffer with size
+ void clearBuffer(void);
void release(); // discard buffer (if any)
operator mig_reply_error_t & () const { return *mBuffer; }
char *name;
function_ptr_t function;
} function_table_entry;
-typedef function_table_entry *function_table_t;
+typedef function_table_entry *function_table_t;
#endif /* FUNCTION_PTR_T */
#endif /* AUTOTEST */
#endif /* notify_MSG_COUNT */
#include <mach/std_types.h>
+#include <mach/mig.h>
#ifdef __BeforeMigUserHeader
__BeforeMigUserHeader
#endif /* __BeforeMigUserHeader */
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+
/* SimpleRoutine mach_notify_port_deleted */
#ifdef mig_external
#else
extern
#endif /* mig_external */
-kern_return_t mach_notify_port_deleted
+kern_return_t cdsa_mach_notify_port_deleted
(
mach_port_t notify,
mach_port_name_t name
#else
extern
#endif /* mig_external */
-kern_return_t mach_notify_port_destroyed
+kern_return_t cdsa_mach_notify_port_destroyed
(
mach_port_t notify,
- mach_port_t rights,
- mach_msg_type_name_t rightsPoly
+ mach_port_t rights
);
/* SimpleRoutine mach_notify_no_senders */
#else
extern
#endif /* mig_external */
-kern_return_t mach_notify_no_senders
+kern_return_t cdsa_mach_notify_no_senders
(
mach_port_t notify,
mach_port_mscount_t mscount
#else
extern
#endif /* mig_external */
-kern_return_t mach_notify_send_once
+kern_return_t cdsa_mach_notify_send_once
(
mach_port_t notify
);
#else
extern
#endif /* mig_external */
-kern_return_t mach_notify_dead_name
+kern_return_t cdsa_mach_notify_dead_name
(
mach_port_t notify,
mach_port_name_t name
);
+__END_DECLS
+
#ifndef subsystem_to_name_map_notify
#define subsystem_to_name_map_notify \
{ "mach_notify_port_deleted", 65 },\
continue;
}
+ // reset the buffer each time, handlers don't consistently set out params
+ bufReply.clearBuffer();
+
// process received message
if (bufRequest.msgId() >= MACH_NOTIFY_FIRST &&
bufRequest.msgId() <= MACH_NOTIFY_LAST) {
//
// Notification hooks and shims. Defaults do nothing.
//
-void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port)
+kern_return_t cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port)
{
try {
MachServer::active().notifyDeadName(port);
} catch (...) {
}
+ return KERN_SUCCESS;
}
void MachServer::notifyDeadName(Port) { }
-void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port)
+kern_return_t cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port)
{
try {
MachServer::active().notifyPortDeleted(port);
} catch (...) {
}
+ return KERN_SUCCESS;
}
void MachServer::notifyPortDeleted(Port) { }
-void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port)
+kern_return_t cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port)
{
try {
MachServer::active().notifyPortDestroyed(port);
} catch (...) {
}
+ return KERN_SUCCESS;
}
void MachServer::notifyPortDestroyed(Port) { }
-void cdsa_mach_notify_send_once(mach_port_t port)
+kern_return_t cdsa_mach_notify_send_once(mach_port_t port)
{
try {
MachServer::active().notifySendOnce(port);
} catch (...) {
}
+ return KERN_SUCCESS;
}
void MachServer::notifySendOnce(Port) { }
-void cdsa_mach_notify_no_senders(mach_port_t port, mach_port_mscount_t count)
+kern_return_t cdsa_mach_notify_no_senders(mach_port_t port, mach_port_mscount_t count)
{
try {
MachServer::active().notifyNoSenders(port, count);
} catch (...) {
}
+ return KERN_SUCCESS;
}
void MachServer::notifyNoSenders(Port, mach_port_mscount_t) { }
extern "C" {
- void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port);
- void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port);
- void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port);
- void cdsa_mach_notify_send_once(mach_port_t);
- void cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t);
+ kern_return_t cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port);
+ kern_return_t cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port);
+ kern_return_t cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port);
+ kern_return_t cdsa_mach_notify_send_once(mach_port_t);
+ kern_return_t cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t);
};
void setup(const char *name);
void runServerThread(bool doTimeout = false);
- friend void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port);
- friend void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port);
- friend void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port);
- friend void cdsa_mach_notify_send_once(mach_port_t);
- friend void cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t);
+ friend kern_return_t cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port);
+ friend kern_return_t cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port);
+ friend kern_return_t cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port);
+ friend kern_return_t cdsa_mach_notify_send_once(mach_port_t);
+ friend kern_return_t cdsa_mach_notify_no_senders(mach_port_t, mach_port_mscount_t);
};
RCDEBUG(DOWN, mRefCount - 1);
return OSAtomicDecrement32(&mRefCount);
}
-
- // if you call this for anything but debug output, you will go to hell (free handbasket included)
- unsigned int refCountForDebuggingOnly() const { return mRefCount; }
private:
volatile mutable int32_t mRefCount;
#include <sqlite3.h>
#include <xpc/xpc.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wvisibility"
+
CFDataRef SecDistinguishedNameCopyNormalizedContent(CFDataRef distinguished_name);
+SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certificate);
CFDataRef _SecItemCreatePersistentRef(CFTypeRef iclass, sqlite_int64 rowid, CFDictionaryRef attributes);
CFDictionaryRef SecTokenItemValueCopy(CFDataRef db_value, CFErrorRef *error);
CFArrayRef SecTrustCopyProperties_ios(SecTrustRef trust);
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));
+typedef void (^securityd_handler_t)(xpc_object_t reply, CFErrorRef error);
+void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq,
+ bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
+ securityd_handler_t handler);
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);
CFStringRef SecFrameworkCopyLocalizedString(CFStringRef key,
CFStringRef tableName);
+#pragma clang diagnostic pop
+
#endif /* macos_tapi_hack_h */
return retval;
};
+static SOSCloudTransportRef defaultTransport = NULL;
+
+void
+SOSCloudTransportSetDefaultTransport(SOSCloudTransportRef transport)
+{
+ defaultTransport = transport;
+}
static SOSCloudTransportRef SOSCloudTransportDefaultTransport(void)
{
static dispatch_once_t sTransportOnce;
- static SOSCloudTransportRef sTransport = NULL;
dispatch_once(&sTransportOnce, ^{
- sTransport = SOSCloudTransportCreateXPCTransport();
- // provide state handler to sysdiagnose and logging
- os_state_add_handler(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), kvsStateBlock);
+ if (defaultTransport == NULL) {
+ defaultTransport = SOSCloudTransportCreateXPCTransport();
+ // provide state handler to sysdiagnose and logging
+ os_state_add_handler(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), kvsStateBlock);
+ }
});
- return sTransport;
+ return defaultTransport;
}
{
struct SOSCloudTransport transport;
xpc_connection_t serviceConnection;
- xpc_connection_t idsProxyServiceConnection;
dispatch_queue_t xpc_queue;
};
return false;
}
-static void setupIDSProxyServiceConnection(SOSXPCCloudTransportRef transport)
-{
- secnotice(SOSCKCSCOPE, "IDS Transport: setting up xpc connection");
- transport->idsProxyServiceConnection = xpc_connection_create_mach_service(xpcIDSServiceName, transport->xpc_queue, 0);
-
- secdebug(SOSCKCSCOPE, "ids service connection: %p\n", transport->idsProxyServiceConnection);
-
- xpc_connection_set_event_handler(transport->idsProxyServiceConnection, ^(xpc_object_t event) {
- secdebug(SOSCKCSCOPE, "IDS Transport, xpc_connection_set_event_handler\n");
- if(event == XPC_ERROR_CONNECTION_INVALID){
- secnotice(SOSCKCSCOPE, "IDS Transport: xpc connection invalid. Oh well.");
- }
- });
-
- xpc_connection_activate(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;
-}
-
static void setupServiceConnection(SOSXPCCloudTransportRef transport)
{
secnotice(SOSCKCSCOPE, "CKP Transport: setting up xpc connection");
transport->xpc_queue = dispatch_queue_create(xpcServiceName, DISPATCH_QUEUE_SERIAL);
setupServiceConnection(transport);
- setupIDSProxyServiceConnection(transport);
// Any time a new session starts, reestablish the XPC connections.
int token;
notify_register_dispatch("com.apple.system.loginwindow.desktopUp", &token, transport->xpc_queue, ^(int token2) {
- secnotice(SOSCKCSCOPE, "CKP/IDS Transport: desktopUp happened, reestablishing xpc connections");
+ secnotice(SOSCKCSCOPE, "CKP Transport: desktopUp happened, reestablishing xpc connections");
teardownServiceConnection(transport);
setupServiceConnection(transport);
- teardownIDSProxyServiceConnection(transport);
- setupIDSProxyServiceConnection(transport);
});
}
-static void talkWithIDS(SOSXPCCloudTransportRef transport, xpc_object_t message, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
-{
- CFErrorRef connectionError = NULL;
-
- os_activity_t trace_activity = os_activity_start("talkWithIDS", OS_ACTIVITY_FLAG_DEFAULT);
- require_action(transport->idsProxyServiceConnection, xit, connectionError = makeError(kSOSConnectionNotOpen));
- require_action(message, xit, connectionError = makeError(kSOSObjectNotFoundError));
- dispatch_retain(processQueue);
-
- xpc_connection_send_message_with_reply(transport->idsProxyServiceConnection, message, transport->xpc_queue, ^(xpc_object_t reply)
- {
- CFErrorRef serverError = NULL;
- CFTypeRef object = NULL;
- if (xpc_event_filter(transport->idsProxyServiceConnection, reply, &serverError) && reply)
- {
- if (serverError)
- secerror("Error from xpc_event_filter: %@", serverError);
- xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue);
- if (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("talkwithIDS", "converted CF object: %@", object);
- }
- else
- secerror("missing value reply");
-
- xpc_object_t xerror = xpc_dictionary_get_value(reply, kMessageKeyError);
- if (xerror)
- serverError = SecCreateCFErrorWithXPCObject(xerror); // use SecCFCreateErrorWithFormat?
- }
- dispatch_async(processQueue, ^{
- if (replyBlock)
- replyBlock(object, serverError);
- CFReleaseSafe(object);
- if (serverError)
- {
- secerror("talkwithIDS callback error: %@", serverError);
- CFReleaseSafe(serverError);
- }
- dispatch_release(processQueue);
- });
- });
- return;
-
-xit:
- secerror("talkWithIDS error: %@", connectionError);
- dispatch_async(processQueue, ^{
- if (replyBlock)
- replyBlock(NULL, connectionError);
- CFReleaseSafe(connectionError);
- dispatch_release(processQueue);
- });
-
- os_activity_end(trace_activity);
-}
-
typedef void (^ProxyReplyBlock)(xpc_object_t reply);
static bool messageToProxy(SOSXPCCloudTransportRef transport, xpc_object_t message, CFErrorRef *error, dispatch_queue_t processQueue, ProxyReplyBlock replyBlock) {
xpc_release(xpc_obj);
}
-static void SOSCloudTransportGetIDSDeviceID(SOSCloudTransportRef transport, CloudKeychainReplyBlock replyBlock)
-{
- dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
-
- SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
-
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
- xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGetDeviceID);
-
- talkWithIDS(xpcTransport, message, processQueue, replyBlock);
- xpc_release(message);
-}
-
-static void SOSCloudTransportGetPerformanceStats(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
-{
- SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
-
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
- xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGetIDSPerfCounters);
-
- talkWithIDS(xpcTransport, message, processQueue, replyBlock);
- xpc_release(message);
-}
-
-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);
-
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
- xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSendFragmentedIDSMessage);
-
- 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);
- xpc_release(message);
-}
-
-static void SOSCloudTransportRetrievePendingMessagesInFlight(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){
-
- SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
-
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
- xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGetPendingMesages);
-
- talkWithIDS(xpcTransport, message, processQueue, replyBlock);
-
- xpc_release(message);
-}
-
-static void SOSCloudTransportCheckIDSDeviceIDAvailability(SOSCloudTransportRef transport, CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
-{
- secdebug(SOSCKCSCOPE, "start");
- SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
-
- xpc_object_t xIDSArray = _CFXPCCreateXPCObjectFromCFObject(ids);
-
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
- xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSendDeviceList);
-
- SecXPCDictionarySetCFObject(message, kMessageKeyPeerID, peerID);
- xpc_dictionary_set_value(message, kMessageKeyValue, xIDSArray);
-
- talkWithIDS(xpcTransport, message, processQueue, replyBlock);
-
- xpc_release(xIDSArray);
- xpc_release(message);
-
-}
-
-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);
-
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
- xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSendIDSMessage);
-
- 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);
- xpc_release(message);
-}
-
static void SOSCloudTransportUpdateKeys(SOSCloudTransportRef transport,
CFDictionaryRef keys,
CFStringRef accountUUID,
st = calloc(1, sizeof(*st));
st->transport.put = SOSCloudTransportPut;
st->transport.updateKeys = SOSCloudTransportUpdateKeys;
- st->transport.sendIDSMessage = SOSCloudTransportSendIDSMessage;
- st->transport.sendFragmentedIDSMessage = SOSCloudTransportSendFragmentedIDSMessage;
- st->transport.retrieveMessages = SOSCloudTransportRetrievePendingMessagesInFlight;
- st->transport.getDeviceID = SOSCloudTransportGetIDSDeviceID;
st->transport.get = SOSCloudTransportGet;
st->transport.getAll = SOSCloudTransportGetAll;
st->transport.synchronize = SOSCloudTransportSync;
st->transport.hasPendingKey = SOSCloudTransportHasPendingKey;
st->transport.requestEnsurePeerRegistration = SOSCloudTransportRequestEnsurePeerRegistration;
st->transport.requestPerfCounters = SOSCloudTransportRequestPerfCounters;
- st->transport.getIDSDeviceAvailability = SOSCloudTransportCheckIDSDeviceIDAvailability;
st->transport.flush = SOSCloudTransportFlush;
st->transport.removeKeys = SOSCloudTransportRemoveKeys;
- st->transport.counters = SOSCloudTransportGetPerformanceStats;
st->transport.itemsChangedBlock = Block_copy(^CFArrayRef(CFDictionaryRef changes) {
secerror("Calling default itemsChangedBlock - fatal: %@", changes);
assert(false);
cTransportRef->removeKeys(cTransportRef, keys, accountUUID, processQueue, 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, myDeviceID, processQueue, replyBlock);
- else if(cTransportRef)
- cTransportRef->sendIDSMessage(cTransportRef, message, deviceName, peerID, myDeviceID, processQueue, replyBlock);
-
-}
-
-void SOSCloudKeychainRetrievePendingMessageFromProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
-{
- SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
-
- if(cTransportRef)
- cTransportRef->retrieveMessages(cTransportRef, processQueue, replyBlock);
-
-}
-void SOSCloudKeychainRetrieveCountersFromIDSProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
-{
- SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
-
- if(cTransportRef)
- cTransportRef->counters(cTransportRef, processQueue, replyBlock);
-
-}
-void SOSCloudKeychainGetIDSDeviceID(CloudKeychainReplyBlock replyBlock)
-{
- SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
- if (cTransportRef)
- cTransportRef->getDeviceID(cTransportRef, replyBlock);
-
-}
-void SOSCloudKeychainGetIDSDeviceAvailability(CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){
-
- SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
-
- if (cTransportRef)
- cTransportRef->getIDSDeviceAvailability(cTransportRef, ids, peerID, processQueue, replyBlock);
-}
CF_RETURNS_RETAINED CFArrayRef SOSCloudKeychainHandleUpdateMessage(CFDictionaryRef updates)
{
CFArrayRef result = NULL;
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, 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);
// Debug calls
void (*requestPerfCounters)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
void (*flush)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
const void *itemsChangedBlock;
- void (*getIDSDeviceAvailability)(SOSCloudTransportRef transport, CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
void (*removeKeys)(SOSCloudTransportRef transport, CFArrayRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
void (*counters)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
};
-void SOSCloudKeychainGetIDSDeviceID(CloudKeychainReplyBlock replyBlock);
-void SOSCloudKeychainRetrievePendingMessageFromProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
-
void SOSCloudKeychainUpdateKeys(CFDictionaryRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
void SOSCloudKeychainFlush(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock);
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);
+// For unit tests
+void
+SOSCloudTransportSetDefaultTransport(SOSCloudTransportRef transport);
__END_DECLS
// seems like launchd looks for the BundleIdentifier, not the name
const char *xpcServiceName = "com.apple.security.cloudkeychainproxy3"; //"CloudKeychainProxy";
-const char *xpcIDSServiceName = "com.apple.security.keychainsyncingoveridsproxy";
const char *kMessageKeyOperation = "operation";
const char *kMessageKeyKey = "key";
const char *kMessageKeyNotificationFlags = "NotificationFlags";
const char *kMessageKeyPeerIDList = "peerIDList";
const char *kMesssgeKeyBackupPeerIDList = "backupPeerIDList";
-const char *kOperationSendDeviceList = "IDSDeviceList";
/* parameters within the dictionary */
const char *kMessageAlwaysKeys = "AlwaysKeys";
const char *kMessageCircle = "Circle";
const char *kMessageMessage = "Message";
const char *kMessageKeyDeviceName = "deviceName";
-const char *kMessageKeyIDSDataMessage = "idsDataMessage";
-const char *kMessageKeyDeviceID = "deviceID";
const char *kMessageKeyPeerID = "peerID";
const char *kMessageKeySendersPeerID = "sendersPeerID";
const char *kMessageKeyAccountUUID = "AcctUUID";
-const char *kMessageKeySenderDeviceID = "SendersDeviceID";
const char *kMessageOperationItemChanged = "ItemChanged";
const char *kOperationRegisterKeys = "RegisterKeys";
const char *kOperationRemoveKeys = "RemoveKeys";
-const char *kOperationGetDeviceID = "DeviceID";
-const char *kOperationGetIDSPerfCounters = "IDSPerf";
-
const char *kOperationHasPendingKey = "hasPendingKey";
-const char *kOperationSendIDSMessage = "IDSMessage";
-const char *kOperationSendFragmentedIDSMessage = "IDSMessageFragmented";
-const char *kOperationGetPendingMesages = "IDSPendingMessages";
-
const char *kOperationRequestSyncWithPeers = "requestSyncWithPeers";
const char *kOperationHasPendingSyncWithPeer = "hasPendingSyncWithPeer";
const char *kOperationRequestEnsurePeerRegistration = "requestEnsurePeerRegistration";
__BEGIN_DECLS
extern const char *xpcServiceName;
-extern const char *xpcIDSServiceName;;
extern const char *kMessageKeyOperation;
extern const char *kMessageKeyKey;
extern const char *kMessageOperationItemChanged;
extern const char *kMessageKeyNotificationFlags;
extern const char *kMessageKeyPeerIDList;
-extern const char *kMesssgeKeyBackupPeerIDList;
-extern const char *kMessageKeyIDS;
-extern const char *kMessageKeyDeviceName;
-extern const char *kMessageKeyIDSDataMessage;
-extern const char *kMessageKeyDeviceID;
extern const char *kMessageKeyPeerID;
-extern const char *kMessageKeySendersPeerID;
+extern const char *kMesssgeKeyBackupPeerIDList;
extern const char *kMessageKeyAccountUUID;
-extern const char *kOperationSendDeviceList;
-extern const char *kMessageKeySenderDeviceID;
extern const char *kMessageContext;
extern const char *kMessageKeyParameter;
extern const char *kOperationRegisterKeys;
extern const char *kOperationRemoveKeys;
-extern const char *kOperationGetDeviceID;
extern const char *kOperationHasPendingKey;
-extern const char *kOperationGetIDSPerfCounters;
extern const uint64_t kCKDXPCVersion;
extern const char *kOperationHasPendingSyncWithPeer;
extern const char *kOperationRequestEnsurePeerRegistration;
-extern const char *kOperationSendIDSMessage;
-extern const char *kOperationSendFragmentedIDSMessage;
extern const char *kOperationGetPendingMesages;
#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
#include <Security/SecureObjectSync/SOSTransportCircle.h>
#include <Security/SecureObjectSync/SOSRing.h>
-#include <Security/SecureObjectSync/SOSPeerInfoSecurityProperties.h>
#include <Security/SecureObjectSync/SOSRecoveryKeyBag.h>
#include <Security/SecureObjectSync/SOSAccountTransaction.h>
#include <dispatch/dispatch.h>
#define RETIREMENT_FINALIZATION_SECONDS (24*60*60)
-typedef void (^SOSAccountCircleMembershipChangeBlock)(SOSCircleRef new_circle,
+typedef void (^SOSAccountCircleMembershipChangeBlock)(SOSAccount* account,
+ SOSCircleRef new_circle,
CFSetRef added_peers, CFSetRef removed_peers,
CFSetRef added_applicants, CFSetRef removed_applicants);
CFDictionaryRef gestalt,
SOSDataSourceFactoryRef factory);
-//
-// MARK: Persistent Encode decode
-//
-
-//
-//MARK: IDS Device ID
-CFStringRef SOSAccountCopyDeviceID(SOSAccount* account, CFErrorRef *error);
-bool SOSAccountSetMyDSID(SOSAccountTransaction* txn, CFStringRef IDS, CFErrorRef* errror);
-bool SOSAccountSendIDSTestMessage(SOSAccount* account, CFStringRef message, CFErrorRef *error);
-bool SOSAccountStartPingTest(SOSAccount* account, CFStringRef message, CFErrorRef *error);
-bool SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(SOSAccount* account, CFErrorRef *error);
-
//
// MARK: Credential management
//
CFStringRef SOSAccountGetSOSCCStatusString(SOSCCStatus status);
SOSCCStatus SOSAccountGetSOSCCStatusFromString(CFStringRef status);
bool SOSAccountJoinCircles(SOSAccountTransaction* aTxn, CFErrorRef* error);
+bool SOSAccountJoinCirclesWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error);
bool SOSAccountJoinCirclesAfterRestore(SOSAccountTransaction* aTxn, CFErrorRef* error);
+bool SOSAccountJoinCirclesAfterRestoreWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error);
bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFErrorRef* error);
+bool SOSAccountRemovePeersFromCircleWithAnalytics(SOSAccount* account, CFArrayRef peers, NSData* parentEvent, CFErrorRef* error);
bool SOSAccountBail(SOSAccount* account, uint64_t limit_in_seconds, CFErrorRef* error);
bool SOSAccountAcceptApplicants(SOSAccount* account, CFArrayRef applicants, CFErrorRef* error);
bool SOSAccountRejectApplicants(SOSAccount* account, CFArrayRef applicants, CFErrorRef* error);
//
bool SOSAccountRequestSyncWithAllPeers(SOSAccountTransaction* txn, CFErrorRef *error);
CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peerIDs, CFErrorRef *error);
-CF_RETURNS_RETAINED CFSetRef SOSAccountSyncWithPeersOverIDS(SOSAccountTransaction* txn, CFSetRef peers);
CFSetRef SOSAccountSyncWithPeersOverKVS(SOSAccountTransaction* txn, CFSetRef peers);
bool SOSAccountInflateTransports(SOSAccount* account, CFStringRef circleName, CFErrorRef *error);
//
bool SOSAccountSyncWithKVSPeerWithMessage(SOSAccountTransaction* txn, CFStringRef peerid, CFDataRef message, CFErrorRef *error);
-bool SOSAccountClearPeerMessageKey(SOSAccountTransaction* txn, CFStringRef peerID, CFErrorRef *error);
CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peers, CFSetRef /* CFStringRef */ backupPeers, CFErrorRef *error);
CF_RETURNS_RETAINED CFSetRef SOSAccountCopyBackupPeersAndForceSync(SOSAccountTransaction* txn, CFErrorRef *error);
-bool SOSAccountSendIKSPSyncList(SOSAccount* account, CFErrorRef *error);
-bool SOSAccountSyncWithKVSUsingIDSID(SOSAccount* account, CFStringRef deviceID, CFErrorRef *error);
-
-
//
// MARK: Cleanup functions
//
bool SOSAccountIsBackupRingEmpty(SOSAccount* account, CFStringRef viewName);
bool SOSAccountNewBKSBForView(SOSAccount* account, CFStringRef viewName, CFErrorRef *error);
+
bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef backupKey, CFErrorRef *error);
bool SOSAccountRemoveBackupPublickey(SOSAccountTransaction* aTxn, CFErrorRef *error);
+bool SOSAccountBackupUpdateBackupPublicKey(SOSAccount *account, CFDataRef backupKey);
bool SOSAccountSetBSKBagForAllSlices(SOSAccount* account, CFDataRef backupSlice, bool setupV0Only, CFErrorRef *error);
CF_RETURNS_RETAINED SOSBackupSliceKeyBagRef SOSAccountBackupSliceKeyBagForView(SOSAccount* account, CFStringRef viewName, CFErrorRef* error);
#import "Security/SecureObjectSync/SOSTransportCircleKVS.h"
#include <Security/SecureObjectSync/SOSTransportMessage.h>
#include <Security/SecureObjectSync/SOSTransportMessageKVS.h>
-#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#include <Security/SecureObjectSync/SOSTransportKeyParameter.h>
#include <Security/SecureObjectSync/SOSKVSKeys.h>
#include <Security/SecureObjectSync/SOSTransport.h>
#include <Security/SecureObjectSync/SOSRing.h>
#include <Security/SecureObjectSync/SOSRingUtils.h>
#include <Security/SecureObjectSync/SOSRingRecovery.h>
-#include <Security/SecureObjectSync/SOSPeerInfoSecurityProperties.h>
#include <Security/SecureObjectSync/SOSAccountTransaction.h>
#include <Security/SecureObjectSync/SOSAccountGhost.h>
#include <Security/SecureObjectSync/SOSPiggyback.h>
#include <utilities/der_plist_internal.h>
#include <corecrypto/ccder.h>
+const CFStringRef kSOSAccountName = CFSTR("AccountName");
const CFStringRef kSOSEscrowRecord = CFSTR("EscrowRecord");
const CFStringRef kSOSUnsyncedViewsKey = CFSTR("unsynced");
const CFStringRef kSOSInitialSyncTimeoutV0 = CFSTR("initialsynctimeout");
const CFStringRef kSOSAccountRenegotiationRetryCount = CFSTR("NegotiationRetryCount");
const CFStringRef kOTRConfigVersion = CFSTR("OTRConfigVersion");
NSString* const SecSOSAggdReattemptOTRNegotiation = @"com.apple.security.sos.otrretry";
+NSString* const SOSAccountUserDefaultsSuite = @"com.apple.security.sosaccount";
+NSString* const SOSAccountLastKVSCleanup = @"lastKVSCleanup";
const uint64_t max_packet_size_over_idms = 500;
self.isListeningForSync = false;
self.lock_notification_token = -1;
- self.key_transport = nil;
self.circle_transport = NULL;
- self.kvs_message_transport = nil;
- self.ids_message_transport = nil;
- self.ck_storage = nil;
self.circle_rings_retirements_need_attention = false;
self.engine_peer_state_needs_repair = false;
self.previousAccountKey = NULL;
self.saveBlock = nil;
+
+ self.notifyCircleChangeOnExit = false;
+ self.notifyViewChangeOnExit = false;
+ self.notifyBackupOnExit = false;
+
+ self.settings = [[NSUserDefaults alloc] initWithSuiteName:SOSAccountUserDefaultsSuite];
}
return self;
}
self.circle_transport = NULL;
self.ck_storage = nil;
self.kvs_message_transport = nil;
- self.ids_message_transport = nil;
self.circle_rings_retirements_need_attention = false;
self.engine_peer_state_needs_repair = false;
reply((__bridge NSDictionary *)returnedValues);
});
}
-- (void)idsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply
-{
- SOSCloudKeychainRetrieveCountersFromIDSProxy(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef error)
- {
- reply((__bridge NSDictionary *)returnedValues);
- });
-}
- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary <NSString *, NSString *> *))reply
{
[account.trust valueSubtractFrom:kSOSPendingEnableViewsToBeSetKey valuesToSubtract:disabledViews];
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-value"
SOSViewResultCode SOSAccountVirtualV0Behavior(SOSAccount* account, SOSViewActionCode actionCode) {
SOSViewResultCode retval = kSOSCCGeneralViewError;
// The V0 view switches on and off all on it's own, we allow people the delusion
errOut:
return retval;
}
+#pragma clang diagnostic pop
SOSAccount* SOSAccountCreate(CFAllocatorRef allocator,
CFDictionaryRef gestalt,
// update_interest_block;
// update_block;
SOSUnregisterTransportKeyParameter(a.key_transport);
- SOSUnregisterTransportMessage(a.ids_message_transport);
SOSUnregisterTransportMessage(a.kvs_message_transport);
SOSUnregisterTransportCircle(a.circle_transport);
a.circle_transport = NULL;
- a.kvs_message_transport = NULL;
- a.ids_message_transport = NULL;
+ a.kvs_message_transport = nil;
a.trust = nil;
a.trust = [[SOSAccountTrustClassic alloc]initWithRetirees:[NSMutableSet set] fpi:NULL circle:NULL departureCode:kSOSDepartureReasonError peerExpansion:[NSMutableDictionary dictionary]];
-(SOSCCStatus) getCircleStatus:(CFErrorRef*) error
{
- SOSCCStatus circleStatus = [self.trust getCircleStatus:error];
+ SOSCCStatus circleStatus = [self.trust getCircleStatusOnly:error];
if (!SOSAccountHasPublicKey(self, error)) {
if(circleStatus == kSOSCCInCircle) {
if(error) {
return circleStatus;
}
+-(bool) isInCircle:(CFErrorRef *)error
+{
+ SOSCCStatus result = [self getCircleStatus:error];
+ if (result != kSOSCCInCircle) {
+ SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("Not in circle"));
+ return false;
+ }
+ return true;
+}
+
+
bool SOSAccountScanForRetired(SOSAccount* account, SOSCircleRef circle, CFErrorRef *error) {
SOSAccountTrustClassic *trust = account.trust;
CFReleaseNull(new_circle);
return NULL;
}
+ account.notifyBackupOnExit = true;
} else {
// Do nothing. We can't resetToOffering without a userPrivKey. If we were to resetToEmpty
// we won't push the result later in handleUpdateCircle. If we leave the circle as it is
}
}
+bool sosAccountLeaveCircleWithAnalytics(SOSAccount* account, SOSCircleRef circle, NSData* parentData, CFErrorRef* error) {
+ SOSAccountTrustClassic *trust = account.trust;
+ SOSFullPeerInfoRef identity = trust.fullPeerInfo;
+ NSMutableSet* retirees = trust.retirees;
+
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentData error:&localError];
+
+ SOSFullPeerInfoRef fpi = identity;
+ if(!fpi) return false;
+
+ CFErrorRef retiredError = NULL;
+
+ bool retval = false;
+
+ SFSignInAnalytics *promoteToRetiredEvent = [parent newSubTaskForEvent:@"promoteToRetiredEvent"];
+ SOSPeerInfoRef retire_peer = SOSFullPeerInfoPromoteToRetiredAndCopy(fpi, &retiredError);
+ if(retiredError){
+ [promoteToRetiredEvent logRecoverableError:(__bridge NSError*)retiredError];
+ secerror("SOSFullPeerInfoPromoteToRetiredAndCopy error: %@", retiredError);
+ if(error){
+ *error = retiredError;
+ }else{
+ CFReleaseNull(retiredError);
+ }
+ }
+ [promoteToRetiredEvent stopWithAttributes:nil];
+
+ if (!retire_peer) {
+ secerror("Create ticket failed for peer %@: %@", fpi, localError);
+ } else {
+ // See if we need to repost the circle we could either be an applicant or a peer already in the circle
+ if(SOSCircleHasApplicant(circle, retire_peer, NULL)) {
+ // Remove our application if we have one.
+ SOSCircleWithdrawRequest(circle, retire_peer, NULL);
+ } else if (SOSCircleHasPeer(circle, retire_peer, NULL)) {
+ if (SOSCircleUpdatePeerInfo(circle, retire_peer)) {
+ CFErrorRef cleanupError = NULL;
+ SFSignInAnalytics *cleanupEvent = [parent newSubTaskForEvent:@"cleanupAfterPeerEvent"];
+ if (![account.trust cleanupAfterPeer:account.kvs_message_transport circleTransport:account.circle_transport seconds:RETIREMENT_FINALIZATION_SECONDS circle:circle cleanupPeer:retire_peer err:&cleanupError]) {
+ secerror("Error cleanup up after peer (%@): %@", retire_peer, cleanupError);
+ }
+ [cleanupEvent stopWithAttributes:nil];
+ CFReleaseSafe(cleanupError);
+ }
+ }
+
+ // Store the retirement record locally.
+ CFSetAddValue((__bridge CFMutableSetRef)retirees, retire_peer);
+
+ trust.retirees = retirees;
+
+ // Write retirement to Transport
+ CFErrorRef postError = NULL;
+ SFSignInAnalytics *postRestirementEvent = [parent newSubTaskForEvent:@"postRestirementEvent"];
+ if(![account.circle_transport postRetirement:SOSCircleGetName(circle) peer:retire_peer err:&postError]){
+ [postRestirementEvent logRecoverableError:(__bridge NSError*)postError];
+ secwarning("Couldn't post retirement (%@)", postError);
+ }
+ [postRestirementEvent stopWithAttributes:nil];
+
+ SFSignInAnalytics *flushChangesEvent = [parent newSubTaskForEvent:@"flushChangesEvent"];
+
+ if(![account.circle_transport flushChanges:&postError]){
+ [flushChangesEvent logRecoverableError:(__bridge NSError*)postError];
+ secwarning("Couldn't flush retirement data (%@)", postError);
+ }
+ [flushChangesEvent stopWithAttributes:nil];
+ CFReleaseNull(postError);
+ }
+ SFSignInAnalytics *purgeIdentityEvent = [parent newSubTaskForEvent:@"purgeIdentityEvent"];
+ SOSAccountPurgeIdentity(account);
+ [purgeIdentityEvent stopWithAttributes:nil];
+ retval = true;
+
+ CFReleaseNull(retire_peer);
+ return retval;
+}
+
bool sosAccountLeaveCircle(SOSAccount* account, SOSCircleRef circle, CFErrorRef* error) {
SOSAccountTrustClassic *trust = account.trust;
SOSFullPeerInfoRef identity = trust.fullPeerInfo;
// MARK: Joining
//
+static bool SOSAccountJoinCircleWithAnalytics(SOSAccountTransaction* aTxn, SecKeyRef user_key,
+ bool use_cloud_peer, NSData* parentEvent, CFErrorRef* error) {
+ SOSAccount* account = aTxn.account;
+ SOSAccountTrustClassic *trust = account.trust;
+ __block bool result = false;
+ __block SOSFullPeerInfoRef cloud_full_peer = NULL;
+ SFSignInAnalytics *ensureFullPeerAvailableEvent = nil;
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError];
+
+ require_action_quiet(trust.trustedCircle, fail, SOSCreateErrorWithFormat(kSOSErrorPeerNotFound, NULL, error, NULL, CFSTR("Don't have circle when joining???")));
+ ensureFullPeerAvailableEvent = [parent newSubTaskForEvent:@"ensureFullPeerAvailableEvent"];
+ require_quiet([account.trust ensureFullPeerAvailable:(__bridge CFDictionaryRef)account.gestalt deviceID:(__bridge CFStringRef)account.deviceID backupKey:(__bridge CFDataRef)account.backup_key err:error], fail);
+ [ensureFullPeerAvailableEvent stopWithAttributes:nil];
+
+ SOSFullPeerInfoRef myCirclePeer = trust.fullPeerInfo;
+ if (SOSCircleCountPeers(trust.trustedCircle) == 0 || SOSAccountGhostResultsInReset(account)) {
+ secnotice("resetToOffering", "Resetting circle to offering since there are no peers");
+ // this also clears initial sync data
+ result = [account.trust resetCircleToOffering:aTxn userKey:user_key err:error];
+ } else {
+ SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL);
+ if (use_cloud_peer) {
+ cloud_full_peer = SOSCircleCopyiCloudFullPeerInfoRef(trust.trustedCircle, NULL);
+ }
+ SFSignInAnalytics *acceptApplicantEvent = [parent newSubTaskForEvent:@"acceptApplicantEvent"];
+ [account.trust modifyCircle:account.circle_transport err:error action:^bool(SOSCircleRef circle) {
+ result = SOSAccountAddEscrowToPeerInfo(account, myCirclePeer, error);
+ result &= SOSCircleRequestAdmission(circle, user_key, myCirclePeer, error);
+ trust.departureCode = kSOSNeverLeftCircle;
+ if(result && cloud_full_peer) {
+ CFErrorRef localError = NULL;
+ CFStringRef cloudid = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(cloud_full_peer));
+ require_quiet(cloudid, finish);
+ require_quiet(SOSCircleHasActivePeerWithID(circle, cloudid, &localError), finish);
+ require_quiet(SOSCircleAcceptRequest(circle, user_key, cloud_full_peer, SOSFullPeerInfoGetPeerInfo(myCirclePeer), &localError), finish);
+ finish:
+ if (localError){
+ [acceptApplicantEvent logRecoverableError:(__bridge NSError *)(localError)];
+ secerror("Failed to join with cloud identity: %@", localError);
+ CFReleaseNull(localError);
+ }
+ }
+ return result;
+ }];
+ [acceptApplicantEvent stopWithAttributes:nil];
+ if (use_cloud_peer) {
+ SFSignInAnalytics *updateOutOfDateSyncViewsEvent = [acceptApplicantEvent newSubTaskForEvent:@"updateOutOfDateSyncViewsEvent"];
+ SOSAccountUpdateOutOfSyncViews(aTxn, SOSViewsGetAllCurrent());
+ [updateOutOfDateSyncViewsEvent stopWithAttributes:nil];
+ }
+ }
+fail:
+ CFReleaseNull(cloud_full_peer);
+ return result;
+}
static bool SOSAccountJoinCircle(SOSAccountTransaction* aTxn, SecKeyRef user_key,
bool use_cloud_peer, CFErrorRef* error) {
return result;
}
-static bool SOSAccountJoinCircles_internal(SOSAccountTransaction* aTxn, bool use_cloud_identity, CFErrorRef* error) {
+static bool SOSAccountJoinCirclesWithAnalytics_internal(SOSAccountTransaction* aTxn, bool use_cloud_identity, NSData* parentEvent, CFErrorRef* error) {
SOSAccount* account = aTxn.account;
SOSAccountTrustClassic *trust = account.trust;
bool success = false;
require_quiet(user_key, done); // Fail if we don't get one.
require_action_quiet(trust.trustedCircle, done, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to join")));
-
+
if (trust.fullPeerInfo != NULL) {
SOSPeerInfoRef myPeer = trust.peerInfo;
success = SOSCircleHasPeer(trust.trustedCircle, myPeer, NULL);
SOSCircleRemoveRejectedPeer(trust.trustedCircle, myPeer, NULL); // If we were rejected we should remove it now.
if (!SOSCircleHasApplicant(trust.trustedCircle, myPeer, NULL)) {
- secerror("Resetting my peer (ID: %@) for circle '%@' during application", SOSPeerInfoGetPeerID(myPeer), SOSCircleGetName(trust.trustedCircle));
-
+ secerror("Resetting my peer (ID: %@) for circle '%@' during application", SOSPeerInfoGetPeerID(myPeer), SOSCircleGetName(trust.trustedCircle));
+
trust.fullPeerInfo = NULL;
}
}
-
- success = SOSAccountJoinCircle(aTxn, user_key, use_cloud_identity, error);
+
+ success = SOSAccountJoinCircleWithAnalytics(aTxn, user_key, use_cloud_identity, parentEvent, error);
require_quiet(success, done);
-
+
trust.departureCode = kSOSNeverLeftCircle;
done:
return success;
}
-bool SOSAccountJoinCircles(SOSAccountTransaction* aTxn, CFErrorRef* error) {
- secnotice("circleOps", "Normal path circle join (SOSAccountJoinCircles)");
- return SOSAccountJoinCircles_internal(aTxn, false, error);
-}
-
-CFStringRef SOSAccountCopyDeviceID(SOSAccount* account, CFErrorRef *error){
- CFStringRef result = NULL;
+static bool SOSAccountJoinCircles_internal(SOSAccountTransaction* aTxn, bool use_cloud_identity, CFErrorRef* error) {
+ SOSAccount* account = aTxn.account;
SOSAccountTrustClassic *trust = account.trust;
+ bool success = false;
- require_action_quiet(trust.fullPeerInfo, fail, SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("No peer for me")));
-
- result = SOSPeerInfoCopyDeviceID(trust.peerInfo);
+ SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error);
+ require_quiet(user_key, done); // Fail if we don't get one.
-fail:
- return result;
-}
+ require_action_quiet(trust.trustedCircle, done, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to join")));
+
+ if (trust.fullPeerInfo != NULL) {
+ SOSPeerInfoRef myPeer = trust.peerInfo;
+ success = SOSCircleHasPeer(trust.trustedCircle, myPeer, NULL);
+ require_quiet(!success, done);
-bool SOSAccountSetMyDSID(SOSAccountTransaction* txn, CFStringRef IDS, CFErrorRef* error){
- bool result = true;
- SOSAccount* account = txn.account;
- SOSAccountTrustClassic *trust = account.trust;
+ SOSCircleRemoveRejectedPeer(trust.trustedCircle, myPeer, NULL); // If we were rejected we should remove it now.
- secdebug("IDS Transport", "We are setting our device ID: %@", IDS);
- if(IDS != NULL && (CFStringGetLength(IDS) > 0)){
- if(!trust.fullPeerInfo){
- account.deviceID = [[NSString alloc] initWithString:(__bridge NSString * _Nonnull)(IDS)];
- SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("No peer for me"));
- return result;
- }
- result = [trust modifyCircle:account.circle_transport err:error action:^bool(SOSCircleRef circle) {
+ if (!SOSCircleHasApplicant(trust.trustedCircle, myPeer, NULL)) {
+ secerror("Resetting my peer (ID: %@) for circle '%@' during application", SOSPeerInfoGetPeerID(myPeer), SOSCircleGetName(trust.trustedCircle));
- SOSFullPeerInfoUpdateDeviceID(trust.fullPeerInfo, IDS, error);
- SOSFullPeerInfoUpdateTransportType(trust.fullPeerInfo, SOSTransportMessageTypeKVS, error);
- SOSFullPeerInfoUpdateTransportPreference(trust.fullPeerInfo, kCFBooleanFalse, error);
- SOSFullPeerInfoUpdateTransportFragmentationPreference(trust.fullPeerInfo, kCFBooleanTrue, error);
- SOSFullPeerInfoUpdateTransportAckModelPreference(trust.fullPeerInfo, kCFBooleanTrue, error);
- return SOSCircleHasPeer(circle, trust.peerInfo, NULL);
- }];
+ trust.fullPeerInfo = NULL;
+ }
}
- else
- result = false;
+
+ success = SOSAccountJoinCircle(aTxn, user_key, use_cloud_identity, error);
- // Initiate sync with all IDS peers, since we just learned we can talk that way.
- SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) {
- if (SOSPeerInfoShouldUseIDSTransport(account.peerInfo, peer)) {
- [txn requestSyncWith:(__bridge NSString*) SOSPeerInfoGetPeerID(peer)];
- }
- });
+ require_quiet(success, done);
+
+ trust.departureCode = kSOSNeverLeftCircle;
- account.deviceID = [[NSString alloc] initWithString:(__bridge NSString * _Nonnull)(IDS)];
- return result;
+done:
+ return success;
}
-bool SOSAccountSendIDSTestMessage(SOSAccount* account, CFStringRef message, CFErrorRef *error){
- bool result = true;
- //construct message dictionary, circle -> peerID -> message
-
- CFMutableDictionaryRef peerToMessage = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+bool SOSAccountJoinCirclesWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error) {
+ secnotice("circleOps", "Normal path circle join (SOSAccountJoinCirclesWithAnalytics)");
+ return SOSAccountJoinCirclesWithAnalytics_internal(aTxn, false, parentEvent, error);
+}
- CFStringRef operationString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSSendOneMessage);
- CFDictionaryRef rawMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- kIDSOperationType, operationString,
- kIDSMessageToSendKey, CFSTR("send IDS test message"),
- NULL);
+bool SOSAccountJoinCircles(SOSAccountTransaction* aTxn, CFErrorRef* error) {
+ secnotice("circleOps", "Normal path circle join (SOSAccountJoinCircles)");
+ return SOSAccountJoinCircles_internal(aTxn, false, error);
+}
- SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) {
- CFDictionaryAddValue(peerToMessage, SOSPeerInfoGetPeerID(peer), rawMessage);
- });
+bool SOSAccountJoinCirclesAfterRestore(SOSAccountTransaction* aTxn, CFErrorRef* error) {
+ secnotice("circleOps", "Joining after restore (SOSAccountJoinCirclesAfterRestore)");
+ return SOSAccountJoinCircles_internal(aTxn, true, error);
+}
- result = [account.ids_message_transport SOSTransportMessageSendMessages:account.ids_message_transport pm:peerToMessage err:error];
-
- CFReleaseNull(peerToMessage);
- CFReleaseNull(operationString);
- CFReleaseNull(rawMessage);
- return result;
+bool SOSAccountJoinCirclesAfterRestoreWithAnalytics(SOSAccountTransaction* aTxn, NSData* parentEvent, CFErrorRef* error) {
+ secnotice("circleOps", "Joining after restore (SOSAccountJoinCirclesAfterRestore)");
+ return SOSAccountJoinCirclesWithAnalytics_internal(aTxn, true, parentEvent, error);
}
-bool SOSAccountStartPingTest(SOSAccount* account, CFStringRef message, CFErrorRef *error){
+bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFErrorRef* error)
+{
bool result = false;
- //construct message dictionary, circle -> peerID -> message
- SOSAccountTrustClassic *trust = account.trust;
- if(account.ids_message_transport == NULL)
- account.ids_message_transport = [[SOSMessageIDS alloc] initWithAccount:account andName:(__bridge NSString *)(SOSCircleGetName(trust.trustedCircle))];
+ CFMutableSetRef peersToRemove = NULL;
+ SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error);
+ if(!user_key){
+ secnotice("circleOps", "Can't remove without userKey");
+ return result;
+ }
+ SOSFullPeerInfoRef me_full = account.fullPeerInfo;
+ SOSPeerInfoRef me = account.peerInfo;
+ if(!(me_full && me))
+ {
+ secnotice("circleOps", "Can't remove without being active peer");
+ SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("Can't remove without being active peer"));
+ return result;
+ }
- require_quiet(account.ids_message_transport, fail);
- CFMutableDictionaryRef peerToMessage = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+ result = true; // beyond this point failures would be rolled up in AccountModifyCircle.
- CFStringRef operationString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSStartPingTestMessage);
- CFDictionaryRef rawMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- kIDSOperationType, operationString,
- kIDSMessageToSendKey, CFSTR("send IDS test message"),
- NULL);
+ peersToRemove = CFSetCreateMutableForSOSPeerInfosByIDWithArray(kCFAllocatorDefault, peers);
+ if(!peersToRemove)
+ {
+ CFReleaseNull(peersToRemove);
+ secnotice("circleOps", "No peerSet to remove");
+ return result;
+ }
-
- SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) {
- CFDictionaryAddValue(peerToMessage, SOSPeerInfoGetPeerID(peer), rawMessage);
- });
-
- result = [account.ids_message_transport SOSTransportMessageSendMessages:account.ids_message_transport pm:peerToMessage err:error];
+ // If we're one of the peers expected to leave - note that and then remove ourselves from the set (different handling).
+ bool leaveCircle = CFSetContainsValue(peersToRemove, me);
+ CFSetRemoveValue(peersToRemove, me);
- CFReleaseNull(peerToMessage);
- CFReleaseNull(rawMessage);
- CFReleaseNull(operationString);
-fail:
- return result;
-}
+ result &= [account.trust modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle) {
+ bool success = false;
-bool SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(SOSAccount* account, CFErrorRef *error){
- bool result = true;
-
- __block bool success = true;
- __block CFErrorRef localError = NULL;
- dispatch_semaphore_t wait_for = dispatch_semaphore_create(0);
+ if(CFSetGetCount(peersToRemove) != 0) {
+ require_quiet(SOSCircleRemovePeers(circle, user_key, me_full, peersToRemove, error), done);
+ success = SOSAccountGenerationSignatureUpdate(account, error);
+ } else success = true;
- SOSCloudKeychainGetIDSDeviceID(^(CFDictionaryRef returnedValues, CFErrorRef sync_error){
- success = (sync_error == NULL);
- if (!success) {
- CFRetainAssign(localError, sync_error);
+ if (success && leaveCircle) {
+ secnotice("circleOps", "Leaving circle by client request (SOSAccountRemovePeersFromCircle)");
+ success = sosAccountLeaveCircle(account, circle, error);
}
-
- dispatch_semaphore_signal(wait_for);
- });
-
- dispatch_semaphore_wait(wait_for, DISPATCH_TIME_FOREVER);
- if(!success && localError != NULL && error != NULL){
- secerror("Could not ask KeychainSyncingOverIDSProxy for Device ID: %@", localError);
- *error = localError;
- result = false;
- }
- else{
- secdebug("IDS Transport", "Attempting to retrieve the IDS Device ID");
+ done:
+ return success;
+
+ }];
+
+ if(result) {
+ CFStringSetPerformWithDescription(peersToRemove, ^(CFStringRef description) {
+ secnotice("circleOps", "Removed Peers from circle %@", description);
+ });
}
+
+ CFReleaseNull(peersToRemove);
return result;
}
-bool SOSAccountJoinCirclesAfterRestore(SOSAccountTransaction* aTxn, CFErrorRef* error) {
- secnotice("circleOps", "Joining after restore (SOSAccountJoinCirclesAfterRestore)");
- return SOSAccountJoinCircles_internal(aTxn, true, error);
-}
-bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFErrorRef* error)
+bool SOSAccountRemovePeersFromCircleWithAnalytics(SOSAccount* account, CFArrayRef peers, NSData* parentEvent, CFErrorRef* error)
{
+
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError];
+
bool result = false;
CFMutableSetRef peersToRemove = NULL;
SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error);
SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("Can't remove without being active peer"));
return result;
}
-
+
result = true; // beyond this point failures would be rolled up in AccountModifyCircle.
peersToRemove = CFSetCreateMutableForSOSPeerInfosByIDWithArray(kCFAllocatorDefault, peers);
if(CFSetGetCount(peersToRemove) != 0) {
require_quiet(SOSCircleRemovePeers(circle, user_key, me_full, peersToRemove, error), done);
+ SFSignInAnalytics *generationSignatureUpdateEvent = [parent newSubTaskForEvent:@"generationSignatureUpdateEvent"];
success = SOSAccountGenerationSignatureUpdate(account, error);
+ if(error && *error){
+ NSError* signatureUpdateError = (__bridge NSError*)*error;
+ [generationSignatureUpdateEvent logUnrecoverableError:signatureUpdateError];
+ }
+ [generationSignatureUpdateEvent stopWithAttributes:nil];
} else success = true;
if (success && leaveCircle) {
secnotice("circleOps", "Leaving circle by client request (SOSAccountRemovePeersFromCircle)");
- success = sosAccountLeaveCircle(account, circle, error);
+ success = sosAccountLeaveCircleWithAnalytics(account, circle, parentEvent, error);
}
done:
return success;
}];
-
+
if(result) {
CFStringSetPerformWithDescription(peersToRemove, ^(CFStringRef description) {
secnotice("circleOps", "Removed Peers from circle %@", description);
return result;
}
-
bool SOSAccountBail(SOSAccount* account, uint64_t limit_in_seconds, CFErrorRef* error) {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
if (!user_key)
return false;
- __block bool success = true;
- __block int64_t num_peers = 0;
+ __block int64_t acceptedPeers = 0;
for_each_applicant_in_each_circle(account, applicants, ^(SOSCircleRef circle, SOSFullPeerInfoRef myCirclePeer, SOSPeerInfoRef peer) {
bool accepted = SOSCircleAcceptRequest(circle, user_key, myCirclePeer, peer, error);
- if (!accepted)
- success = false;
- else
- num_peers = MAX(num_peers, SOSCircleCountPeers(circle));
+ if (accepted)
+ acceptedPeers++;
return accepted;
});
- return success;
+ if (acceptedPeers == CFArrayGetCount(applicants))
+ return true;
+ return false;
}
bool SOSAccountRejectApplicants(SOSAccount* account, CFArrayRef applicants, CFErrorRef* error) {
secnotice("updates", "Ensuring peer registration.");
- if(!trust.trustedCircle || !trust.fullPeerInfo || !account.accountKeyIsTrusted)
+ if(!trust) {
+ secnotice("updates", "Failed to get trust object in Ensuring peer registration.");
return result;
-
+ }
+
+ if([account getCircleStatus: NULL] != kSOSCCInCircle) {
+ return result;
+ }
+
// If we are not in the circle, there is no point in setting up peers
- if(!SOSAccountIsMyPeerActive(account, NULL))
+ if(!SOSAccountIsMyPeerActive(account, NULL)) {
return result;
+ }
// This code only uses the SOSFullPeerInfoRef for two things:
// - Finding out if this device is in the trusted circle
SOSCircleForEachValidSyncingPeer(trust.trustedCircle, account.accountKey, ^(SOSPeerInfoRef peer) {
if (!SOSPeerInfoPeerIDEqual(peer, my_id)) {
CFErrorRef localError = NULL;
-
- SOSMessage *messageTransport = SOSPeerInfoHasDeviceID(peer) ? account.ids_message_transport : account.kvs_message_transport;
- SOSEngineInitializePeerCoder((SOSEngineRef)[messageTransport SOSTransportMessageGetEngine], trust.fullPeerInfo, peer, &localError);
+ SOSEngineInitializePeerCoder((SOSEngineRef)[account.kvs_message_transport SOSTransportMessageGetEngine], trust.fullPeerInfo, peer, &localError);
if (localError)
secnotice("updates", "can't initialize transport for peer %@ with %@ (%@)", peer, trust.fullPeerInfo, localError);
CFReleaseSafe(localError);
}
});
-
- //Initialize our device ID
- [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account];
return result;
}
return success;
}
-bool SOSAccountCheckPeerAvailability(SOSAccount* account, CFErrorRef *error)
-{
- CFStringRef operationString = NULL;
- CFDictionaryRef rawMessage = NULL;
- CFMutableSetRef peers = NULL;
- CFMutableDictionaryRef peerList = NULL;
- char* message = NULL;
- bool result = false;
- SOSAccountTrustClassic* trust = account.trust;
- if(account.ids_message_transport == NULL)
- account.ids_message_transport = [[SOSMessageIDS alloc] initWithAccount:account andName:(__bridge NSString *)SOSCircleGetName(trust.trustedCircle)];
-
- if(!account.ids_message_transport)
- return result;
-
- //adding message type kIDSPeerAvailability so KeychainSyncingOverIDSProxy does not send this message as a keychain item
-
- operationString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSPeerAvailability);
- rawMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- kIDSOperationType, operationString,
- kIDSMessageToSendKey, CFSTR("checking peers"),
- NULL);
-
- peerList = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- SOSCircleRef circle = trust.trustedCircle;
-
- //check each peer to make sure they have the right view set enabled
- CFSetRef mySubSet = SOSViewsGetV0SubviewSet();
- SOSCircleForEachValidPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) {
- if(!CFEqualSafe(peer, account.peerInfo)){
- CFMutableSetRef peerViews = SOSPeerInfoCopyEnabledViews(peer);
- CFSetRef intersectSets = CFSetCreateIntersection(kCFAllocatorDefault, mySubSet, peerViews);
- if(CFEqualSafe(intersectSets, mySubSet)){
- CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer);
- if(deviceID != NULL)
- CFDictionaryAddValue(peerList, SOSPeerInfoGetPeerID(peer), rawMessage);
- CFReleaseNull(deviceID);
- }
- CFReleaseNull(peerViews);
- CFReleaseNull(intersectSets);
- }
- });
-
- require_quiet(CFDictionaryGetCount(peerList) > 0 , fail);
-
- result = [account.ids_message_transport SOSTransportMessageSendMessages:account.ids_message_transport pm:peerList err:error];
-
-fail:
- CFReleaseNull(rawMessage);
- CFReleaseNull(operationString);
- CFReleaseNull(peerList);
- CFReleaseNull(peers);
- free(message);
- return result;
-}
-
-
void SOSAccountRecordRetiredPeersInCircle(SOSAccount* account) {
- if (![account.trust isInCircle:NULL])
+ if (![account isInCircle:NULL]) {
return;
+ }
SOSAccountTrustClassic *trust = account.trust;
[trust modifyCircle:account.circle_transport err:NULL action:^bool (SOSCircleRef circle) {
__block bool updated = false;
static void SOSAccountWriteLastCleanupTimestampToKVS(SOSAccount* account)
{
+ NSDate *now = [NSDate date];
+ [account.settings setObject:now forKey:SOSAccountLastKVSCleanup];
+
NSMutableDictionary *writeTimestamp = [NSMutableDictionary dictionary];
CFMutableStringRef timeDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("["));
+
CFAbsoluteTime currentTimeAndDate = CFAbsoluteTimeGetCurrent();
withStringOfAbsoluteTime(currentTimeAndDate, ^(CFStringRef decription) {
dispatch_semaphore_wait(waitSemaphore, finishTime);
}
+// set the cleanup frequency to 3 days.
+#define KVS_CLEANUP_FREQUENCY_LIMIT 60*60*24*3
+
//Get all the key/values in KVS and remove old entries
bool SOSAccountCleanupAllKVSKeys(SOSAccount* account, CFErrorRef* error)
{
+ // This should only happen on some number of days
+ NSDate *lastKVSCleanup = [account.settings objectForKey:SOSAccountLastKVSCleanup];
+ NSDate *now = [NSDate date];
+ NSTimeInterval timeSinceCleanup = [now timeIntervalSinceDate:lastKVSCleanup];
+
+ if(timeSinceCleanup < KVS_CLEANUP_FREQUENCY_LIMIT) {
+ return true;
+ }
+
dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSDictionary *keysAndValues = (__bridge_transfer NSDictionary*)SOSAccountGetObjectsFromCloud(processQueue, error);
rank_type(NSString *view)
{
if ([view isEqualToString:@"Manatee"])
- return 4;
+ return 5;
else if ([view isEqualToString:@"Engram"])
- return 3;
+ return 4;
else if ([view isEqualToString:@"AutoUnlock"])
- return 2;
+ return 3;
if ([view isEqualToString:@"Health"])
- return 1;
+ return 2;
return 0;
}
return CFBridgingRetain(SOSPiggyCreateInitialSyncData(encodedIdenities, tlks));
}
+static void pbNotice(CFStringRef operation, SOSAccount* account, SOSGenCountRef gencount, SecKeyRef pubKey, CFDataRef signature, PiggyBackProtocolVersion version) {
+ CFStringRef pkeyID = SOSCopyIDOfKey(pubKey, NULL);
+ if(pkeyID == NULL) pkeyID = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("Unknown"));
+ CFStringRef sigID = SOSCopyIDOfDataBuffer(signature, NULL);
+ if(sigID == NULL) sigID = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("No Signature"));
+ CFStringRef accountName = SOSAccountGetValue(account, kSOSAccountName, NULL);
+ if(accountName == NULL) {
+ accountName = CFSTR("Unavailable");
+ }
+ CFStringRef circleHash = SOSCircleCopyHashString(account.trust.trustedCircle);
+
+ secnotice("circleOps",
+ "%@: Joining blob for account: %@ for piggyback (V%d) gencount: %@ pubkey: %@ signatureID: %@ starting circle hash: %@",
+ operation, accountName, version, gencount, pkeyID, sigID, circleHash);
+ CFReleaseNull(pkeyID);
+ CFReleaseNull(sigID);
+ CFReleaseNull(circleHash);
+}
+
CFDataRef SOSAccountCopyCircleJoiningBlob(SOSAccount* account, SOSPeerInfoRef applicant, CFErrorRef *error) {
SOSGenCountRef gencount = NULL;
CFDataRef signature = NULL;
CFDataRef pbblob = NULL;
SOSCircleRef prunedCircle = NULL;
- secnotice("circleOps", "Making circle joining blob as sponsor (SOSAccountCopyCircleJoiningBlob)");
+ secnotice("circleOps", "Making circle joining piggyback blob as sponsor (SOSAccountCopyCircleJoiningBlob)");
+
+ SOSCCStatus circleStat = [account getCircleStatus:error];
+ if(circleStat != kSOSCCInCircle) {
+ secnotice("circleOps", "Invalid circle status: %@ to accept piggyback as sponsor (SOSAccountCopyCircleJoiningBlob)", SOSCCGetStatusDescription(circleStat));
+ return NULL;
+ }
SecKeyRef userKey = SOSAccountGetTrustedPublicCredential(account, error);
require_quiet(userKey, errOut);
require_action_quiet(applicant, errOut, SOSCreateError(kSOSErrorProcessingFailure, CFSTR("No applicant provided"), (error != NULL) ? *error : NULL, error));
- require_quiet(SOSPeerInfoApplicationVerify(applicant, userKey, error), errOut);
+ require_action_quiet(SOSPeerInfoApplicationVerify(applicant, userKey, error), errOut,
+ secnotice("circleOps", "Peer application wasn't signed with the correct userKey"));
{
SOSFullPeerInfoRef fpi = account.fullPeerInfo;
signature = SOSCircleCopyNextGenSignatureWithPeerAdded(prunedCircle, applicant, ourKey, error);
require_quiet(signature, errOut);
-
+ pbNotice(CFSTR("Accepting"), account, gencount, ourKey, signature, kPiggyV1);
pbblob = SOSPiggyBackBlobCopyEncodedData(gencount, ourKey, signature, error);
errOut:
CFReleaseNull(ourKey);
if(!pbblob && error != NULL) {
- secnotice("circleOps", "Failed to make circle joining blob as sponsor %@", *error);
+ secnotice("circleOps", "Failed to make circle joining piggyback blob as sponsor %@", *error);
}
return pbblob;
SecKeyRef pubKey = NULL;
bool setInitialSyncTimeoutToV0 = false;
- secnotice("circleOps", "Joining circles through piggy-back (SOSAccountCopyCircleJoiningBlob)");
+ secnotice("circleOps", "Joining circles through piggyback (SOSAccountCopyCircleJoiningBlob)");
- if (!isData(joiningBlob))
+ if (!isData(joiningBlob)) {
+ secnotice("circleOps", "Bad data blob: piggyback (SOSAccountCopyCircleJoiningBlob)");
return false;
+ }
userKey = SOSAccountGetPrivateCredential(account, error);
- if(!userKey)
+ if(!userKey) {
+ secnotice("circleOps", "Failed - no private credential %@: piggyback (SOSAccountCopyCircleJoiningBlob)", *error);
return retval;
+ }
- if (!SOSPiggyBackBlobCreateFromData(&gencount, &pubKey, &signature, joiningBlob, version, &setInitialSyncTimeoutToV0, error))
+ if (!SOSPiggyBackBlobCreateFromData(&gencount, &pubKey, &signature, joiningBlob, version, &setInitialSyncTimeoutToV0, error)) {
+ secnotice("circleOps", "Failed - decoding blob %@: piggyback (SOSAccountCopyCircleJoiningBlob)", *error);
return retval;
+ }
if(setInitialSyncTimeoutToV0){
- secnotice("piggy", "setting flag in account for piggybacking v0");
+ secnotice("circleOps", "setting flag in account for piggyback v0");
SOSAccountSetValue(account, kSOSInitialSyncTimeoutV0, kCFBooleanTrue, NULL);
- }
- else{
- secnotice("piggy", "setting flag in account for piggybacking v0");
+ } else {
+ secnotice("circleOps", "clearing flag in account for piggyback v0");
SOSAccountClearValue(account, kSOSInitialSyncTimeoutV0, NULL);
}
SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL);
+ pbNotice(CFSTR("Joining"), account, gencount, pubKey, signature, version);
+
retval = [trust modifyCircle:account.circle_transport err:error action:^bool(SOSCircleRef copyOfCurrent) {
return SOSCircleAcceptPeerFromHSA2(copyOfCurrent, userKey,
gencount,
pubKey,
signature,
trust.fullPeerInfo, error);;
-
}];
CFReleaseNull(gencount);
}
void SOSAccountLogViewState(SOSAccount* account) {
- bool isInCircle = [account.trust isInCircle:NULL];
+ bool isInCircle = [account.trust isInCircleOnly:NULL];
require_quiet(isInCircle, imOut);
SOSPeerInfoRef mpi = account.peerInfo;
bool isInitialComplete = SOSAccountHasCompletedInitialSync(account);
if(message){
secnotice("ratelimit","SOSPeerRateLimiter timer went off! sending:%@ \n to peer:%@", message, peer_id);
- bool sendResult = [account.ids_message_transport SOSTransportMessageSendMessage:account.ids_message_transport id:(__bridge CFStringRef)peer_id messageToSend:(__bridge CFDataRef)message err:&error];
+ bool sendResult = [account.kvs_message_transport SOSTransportMessageSendMessage:account.kvs_message_transport id:(__bridge CFStringRef)peer_id messageToSend:(__bridge CFDataRef)message err:&error];
if(!sendResult || error){
secnotice("ratelimit", "could not send message: %@", error);
#include <Security/SecureObjectSync/SOSBackupSliceKeyBag.h>
#include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
+#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
#include <Security/SecureObjectSync/SOSViews.h>
#include <Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h>
#include <Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h>
return peercnt == 0;
}
-bool SOSAccountUpdatePeerInfo(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, bool (^update)(SOSFullPeerInfoRef fpi, CFErrorRef *error)) {
-
- if (!account.hasPeerInfo)
- return true;
-
- bool result = update(account.fullPeerInfo, error);
-
- if (result && SOSAccountHasCircle(account, NULL)) {
- return [account.trust modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle_to_change) {
- secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for %@", updateDescription);
- return SOSCircleUpdatePeerInfo(circle_to_change, account.peerInfo);
- }];
- }
-
- return result;
-}
-
bool SOSAccountIsMyPeerInBackupAndCurrentInView(SOSAccount* account, CFStringRef viewname){
bool result = false;
CFErrorRef bsError = NULL;
{
SOSAccount* account = aTxn.account;
NSData* backupKey = [[NSData alloc]initWithData:(__bridge NSData * _Nonnull)(cfBackupKey)];
-
__block bool result = false;
+ if(![account isInCircle:error]) {
+ return result;
+ }
+
CFDataPerformWithHexString((__bridge CFDataRef)(backupKey), ^(CFStringRef backupKeyString) {
CFDataPerformWithHexString((__bridge CFDataRef)((account.backup_key)), ^(CFStringRef oldBackupKey) {
secnotice("backup", "SetBackupPublic: %@ from %@", backupKeyString, oldBackupKey);
});
});
- require_quiet([account.trust isInCircle:error], exit);
-
if ([backupKey isEqual:account.backup_key])
return true;
result = true;
-exit:
if (!result) {
secnotice("backupkey", "SetBackupPublic Failed: %@", error ? (CFTypeRef) *error : (CFTypeRef) CFSTR("No error space"));
}
__block bool result = false;
SOSBackupSliceKeyBagRef backup_slice = NULL;
- require_quiet([account.trust isInCircle:error], exit);
+ if(![account isInCircle:error]) {
+ return result;
+ }
if (setupV0Only) {
result = SOSSaveV0Keybag(aks_bag, error);
bool SOSAccountIsLastBackupPeer(SOSAccount* account, CFErrorRef *error) {
__block bool retval = false;
SOSPeerInfoRef pi = account.peerInfo;
+
+ if(![account isInCircle:error]) {
+ return retval;
+ }
+
if(!SOSPeerInfoHasBackupKey(pi))
return retval;
SOSCircleRef circle = [account.trust getCircle:error];
- if(![account.trust isInCircle:error])
- return retval;
+
if(SOSCircleCountValidSyncingPeers(circle, SOSAccountGetTrustedPublicCredential(account, error)) == 1){
retval = true;
return retval;
#import <Security/SecureObjectSync/SOSTransport.h>
#import <Security/SecureObjectSync/SOSTransportKeyParameter.h>
#import <Security/SecureObjectSync/SOSTransportMessageKVS.h>
-#import <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#import <Security/SecureObjectSync/SOSTransportCircleKVS.h>
#import <Security/SecureObjectSync/SOSTransportCircleCK.h>
#import <Security/SecureObjectSync/SOSAccountTrust.h>
-bool SOSAccountAssertUserCredentials(SOSAccount* account, CFStringRef user_account __unused, CFDataRef user_password, CFErrorRef *error)
+bool SOSAccountAssertUserCredentials(SOSAccount* account, CFStringRef user_account, CFDataRef user_password, CFErrorRef *error)
{
bool public_was_trusted = account.accountKeyIsTrusted;
account.accountKeyIsTrusted = false;
CFReleaseNull(publishError);
recordCred:
SOSAccountStashAccountKey(account);
+ SOSAccountSetValue(account, kSOSAccountName, user_account, NULL);
errOut:
CFReleaseNull(parameters);
CFReleaseNull(user_private);
}
-bool SOSAccountTryUserCredentials(SOSAccount* account, CFStringRef user_account __unused, CFDataRef user_password, CFErrorRef *error) {
+bool SOSAccountTryUserCredentials(SOSAccount* account, CFStringRef user_account, CFDataRef user_password, CFErrorRef *error) {
bool success = sosAccountValidatePasswordOrFail(account, user_password, error);
if(success) {
SOSAccountStashAccountKey(account);
+ SOSAccountSetValue(account, kSOSAccountName, user_account, NULL);
}
secnotice("circleop", "Setting account.key_interests_need_updating to true in SOSAccountTryUserCredentials");
account.key_interests_need_updating = true;
#include "SOSInternal.h"
#include "SOSViews.h"
#include "SOSPeerInfoV2.h"
+#include "SOSPeerInfoPriv.h"
+#import <Security/SecureObjectSync/SOSAccountPriv.h>
#import <Security/SecureObjectSync/SOSAccountTrust.h>
#import <Security/SecureObjectSync/SOSAccountTrustClassic.h>
+#include <Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h>
+#include <Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h>
+
static CFStringRef kicloud_identity_name = CFSTR("Cloud Identity");
return cloud_peer;
}
+
+
+bool SOSAccountUpdatePeerInfo(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, bool (^update)(SOSFullPeerInfoRef fpi, CFErrorRef *error)) {
+
+ if (!account.hasPeerInfo)
+ return true;
+
+ bool result = update(account.fullPeerInfo, error);
+
+ if (result && SOSAccountHasCircle(account, NULL)) {
+ return [account.trust modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle_to_change) {
+ secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for %@", updateDescription);
+ return SOSCircleUpdatePeerInfo(circle_to_change, account.peerInfo);
+ }];
+ }
+
+ return result;
+}
+
+
+bool SOSAccountUpdatePeerInfoAndPush(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error,
+ bool (^update)(SOSPeerInfoRef pi, CFErrorRef *error)) {
+ return SOSAccountUpdatePeerInfo(account, updateDescription, error, ^bool(SOSFullPeerInfoRef fpi, CFErrorRef *localError) {
+ return SOSFullPeerInfoUpdate(fpi, localError, ^SOSPeerInfoRef(SOSPeerInfoRef pi, SecKeyRef peerPriv, CFErrorRef *localError) {
+ SOSPeerInfoRef newPI = SOSPeerInfoCreateCopy(kCFAllocatorDefault, pi, localError);
+ if(update(newPI, error)) {
+ if(peerPriv && SOSPeerInfoSign(peerPriv, newPI, localError)) {
+ secnotice("circleOp", "Signed Peerinfo to update");
+ return newPI;
+ }
+ }
+ secnotice("circleOp", "Failed updating PeerInfo");
+ CFReleaseNull(newPI);
+ return NULL;
+ });
+ });
+}
![account.trust addiCloudIdentity:newCircle key:userPrivKey err:NULL]){
CFReleaseNull(newCircle);
}
+ account.notifyBackupOnExit = true;
} else {
CFReleaseNull(newCircle);
}
* @APPLE_LICENSE_HEADER_END@
*/
-
-#include <stdio.h>
#include "SOSAccountPriv.h"
+#include "SOSAccount.h"
#include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
#include <Security/SecureObjectSync/SOSTransportMessage.h>
#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
-#include <Security/SecureObjectSync/SOSPeerInfoSecurityProperties.h>
#import <Security/SecureObjectSync/SOSAccountTrust.h>
#include <Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h>
CFMutableSetRef viewsRemaining = NULL;
CFSetRef viewsToLookFor = NULL;
- if(!SOSAccountHasPublicKey(account, error))
- {
+ if(![account isInCircle:error]) {
CFReleaseNull(viewsToLookFor);
CFReleaseNull(viewsRemaining);
-
- return result;
- }
- if(![account.trust isInCircle:error]){
- CFReleaseNull(viewsToLookFor);
- CFReleaseNull(viewsRemaining);
-
return result;
}
#import <Security/SecureObjectSync/SOSCircleDer.h>
#import "Security/SecureObjectSync/SOSAccountTrustClassic.h"
-#define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable"
-
@implementation SOSAccount (Persistence)
{
SOSUnregisterTransportKeyParameter(account.key_transport);
SOSUnregisterTransportCircle((SOSCircleStorageTransport*)account.circle_transport);
- SOSUnregisterTransportMessage((SOSMessage*)account.ids_message_transport);
SOSUnregisterTransportMessage(account.kvs_message_transport);
secnotice("account", "No private key associated with my_identity, resetting");
return nil;
}
- notify_post(kSecServerPeerInfoAvailable);
- if(account.deviceID && [account.deviceID length] != 0){
- SOSFullPeerInfoUpdateDeviceID(identity, (__bridge CFStringRef)(account.deviceID), error);
- account.trust.fullPeerInfo = identity;
- }
}
if (![account ensureFactoryCircles]) {
SOSPeerInfoRef oldPI = CFRetainSafe(account.peerInfo);
if (oldPI) {
SOSAccountCheckForAlwaysOnViews(account);
- // if UpdateFullPeerInfo did something - we need to make sure we have the right Ref
- SOSPeerInfoRef myPI = account.peerInfo;
- CFStringRef transportTypeInflatedFromDER = SOSPeerInfoCopyTransportType(myPI);
-
- if(CFStringCompare(transportTypeInflatedFromDER, CFSTR("KVS"), 0) != 0){
- SOSFullPeerInfoUpdateTransportType(identity, SOSTransportMessageTypeKVS, NULL);
- }
-
- CFReleaseNull(transportTypeInflatedFromDER);
}
CFReleaseNull(oldPI);
extern const CFStringRef kSOSAccountPeerNegotiationTimeouts;
extern const CFStringRef kSOSRecoveryRing;
extern const CFStringRef kSOSEscrowRecord;
+extern const CFStringRef kSOSAccountName;
extern const CFStringRef kSOSTestV2Settings;
extern const CFStringRef kSOSRateLimitingCounters;
extern const CFStringRef kSOSAccountPeerLastSentTimestamp;
extern const CFStringRef kSOSAccountRenegotiationRetryCount;
extern const CFStringRef kSOSInitialSyncTimeoutV0;
-#define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable"
-
typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flattenFailError);
-@class SOSMessageIDS;
@class SOSMessageKVS;
@class CKKeyParameter;
@class SOSAccountTrustClassic;
@property (nonatomic, retain) CKKeyParameter* key_transport;
@property (nonatomic) SOSKVSCircleStorageTransport* circle_transport;
@property (nonatomic, retain) SOSMessageKVS* kvs_message_transport;
-@property (nonatomic, retain) SOSMessageIDS* ids_message_transport;
@property (nonatomic, retain) SOSCKCircleStorage* ck_storage;
@property (readonly, nonatomic) SOSFullPeerInfoRef fullPeerInfo;
@property (readonly, nonatomic) NSString* peerID;
+@property (nonatomic, assign) BOOL notifyCircleChangeOnExit;
+@property (nonatomic, assign) BOOL notifyViewChangeOnExit;
+@property (nonatomic, assign) BOOL notifyBackupOnExit;
+
+@property (nonatomic, retain) NSUserDefaults* settings;
+
+
-(id) init;
-(id) initWithGestalt:(CFDictionaryRef)gestalt factory:(SOSDataSourceFactoryRef)factory;
// Update
-(SOSCCStatus) getCircleStatus:(CFErrorRef*) error;
+-(bool) isInCircle:(CFErrorRef *)error;
bool SOSAccountHandleCircleMessage(SOSAccount* account,
CFStringRef circleName, CFDataRef encodedCircleMessage, CFErrorRef *error);
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));
+bool SOSAccountUpdatePeerInfoAndPush(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error,
+ bool (^update)(SOSPeerInfoRef pi, CFErrorRef *error));
// Currently permitted backup rings.
void SOSAccountForEachBackupRingName(SOSAccount* account, void (^operation)(CFStringRef value));
void SOSAccountPurgeIdentity(SOSAccount*);
bool sosAccountLeaveCircle(SOSAccount* account, SOSCircleRef circle, CFErrorRef* error);
+bool sosAccountLeaveCircleWithAnalytics(SOSAccount* account, SOSCircleRef circle, NSData* parentData, CFErrorRef* error);
+
bool sosAccountLeaveRing(SOSAccount* account, SOSRingRef ring, CFErrorRef* error);
bool SOSAccountForEachRing(SOSAccount* account, SOSRingRef (^action)(CFStringRef name, SOSRingRef ring));
bool SOSAccountUpdateBackUp(SOSAccount* account, CFStringRef viewname, CFErrorRef *error);
CFDataRef oldRecoveryKey = NULL;
SOSRecoveryKeyBagRef rkbg = NULL;
- require_quiet([account.trust isInCircle:error], exit);
+ require_quiet([account isInCircle:error], exit);
oldRecoveryKey = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); // ok to fail here. don't collect error
require_action_quiet(!CFEqualSafe(pubData, oldRecoveryKey), exit, result = true);
void SOSAccountEnsureRecoveryRing(SOSAccount* account) {
static SOSRecoveryKeyBagRef oldRingRKBG = NULL;
- bool inCircle = [account.trust isInCircle:NULL];
+
+ if(![account isInCircle:NULL]) {
+ return;
+ }
+
CFStringRef accountDSID = SOSAccountGetValue(account, kSOSDSIDKey, NULL); // murfxxx this needs to be consulted still
SOSRecoveryKeyBagRef acctRKBG = SOSAccountCopyRecoveryKeyBagEntry(kCFAllocatorDefault, account, NULL);
SOSRecoveryKeyBagRef ringRKBG = SOSAccountCopyRecoveryKeyBag(kCFAllocatorDefault, account, NULL);
if(!SOSRecoveryKeyBagDSIDIs(ringRKBG, accountDSID)) CFReleaseNull(ringRKBG);
if(!SOSRecoveryKeyBagDSIDIs(acctRKBG, accountDSID)) CFReleaseNull(acctRKBG);
- if(inCircle && acctRKBG == NULL && ringRKBG == NULL) {
+ if(acctRKBG == NULL && ringRKBG == NULL) {
// Nothing to do at this time - notify if this is a change down below.
- } else if(inCircle && acctRKBG == NULL) { // then we have a ringRKBG
+ } else if(acctRKBG == NULL) { // then we have a ringRKBG
secnotice("recovery", "Harvesting account recovery key from ring");
SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, ringRKBG, NULL);
} else if(ringRKBG == NULL) {
// Nothing to do at this time - notify if this is a change down below.
secnotice("recovery", "Account has a recovery key, but none found in recovery ring");
- } else if(!CFEqual(acctRKBG, ringRKBG)) {
+ } else if(!CFEqualSafe(acctRKBG, ringRKBG)) {
secnotice("recovery", "Harvesting account recovery key from ring");
SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, ringRKBG, NULL);
}
#include <Security/SecureObjectSync/SOSTransportCircle.h>
#include <Security/SecureObjectSync/SOSTransportCircleKVS.h>
#include <Security/SecureObjectSync/SOSTransportMessage.h>
-#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#include <Security/SecureObjectSync/SOSKVSKeys.h>
#include <Security/SecureObjectSync/SOSTransport.h>
#include <Security/SecureObjectSync/SOSTransportKeyParameter.h>
#import <Security/SecureObjectSync/SOSTransport.h>
#import <Security/SecureObjectSync/SOSTransportKeyParameter.h>
#import <Security/SecureObjectSync/SOSTransportMessage.h>
-#import "Security/SecureObjectSync/SOSTransportMessageIDS.h"
#import <Security/SecureObjectSync/SOSTransportMessageKVS.h>
#include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
#include <Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h>
SOSUnregisterTransportKeyParameter(account.key_transport);
if(account.circle_transport)
SOSUnregisterTransportCircle(account.circle_transport);
- if(account.ids_message_transport)
- SOSUnregisterTransportMessage((SOSMessage*)account.ids_message_transport);
if(account.kvs_message_transport)
SOSUnregisterTransportMessage((SOSMessage*)account.kvs_message_transport);
require_quiet(account.key_transport, fail);
require_quiet(account.circle_transport, fail);
-
- account.ids_message_transport = [[SOSMessageIDS alloc] initWithAccount:account andName:(__bridge NSString *)(circleName)];
- require_quiet(account.ids_message_transport, fail);
-
+
account.kvs_message_transport = [[SOSMessageKVS alloc] initWithAccount:account andName:(__bridge NSString*)circleName];
require_quiet(account.kvs_message_transport, fail);
return success;
}
-static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) {
- NSString* myPeerID = account.peerID;
-
- return myPeerID && [myPeerID isEqualToString: (__bridge NSString*) peerID];
-}
-
-bool SOSAccountSendIKSPSyncList(SOSAccount* account, CFErrorRef *error){
- bool result = true;
- __block CFErrorRef localError = NULL;
- __block CFMutableArrayRef ids = NULL;
- SOSCircleRef circle = NULL;
- SOSFullPeerInfoRef identity = NULL;
-
- if(![account.trust isInCircle:NULL])
- {
- SOSCreateError(kSOSErrorNoCircle, CFSTR("This device is not in circle"), NULL, &localError);
- if(error && *error != NULL)
- secerror("SOSAccountSendIKSPSyncList had an error: %@", *error);
-
- if(localError)
- secerror("SOSAccountSendIKSPSyncList had an error: %@", localError);
-
- CFReleaseNull(ids);
- CFReleaseNull(localError);
-
- return result;
- }
-
- circle = account.trust.trustedCircle;
- identity = account.fullPeerInfo;
- ids = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
-
- SOSCircleForEachValidPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) {
- if (!SOSAccountIsThisPeerIDMe(account, SOSPeerInfoGetPeerID(peer))) {
- if(SOSPeerInfoShouldUseIDSTransport(SOSFullPeerInfoGetPeerInfo(identity), peer) &&
- SOSPeerInfoShouldUseIDSMessageFragmentation(SOSFullPeerInfoGetPeerInfo(identity), peer) &&
- !SOSPeerInfoShouldUseACKModel(SOSFullPeerInfoGetPeerInfo(identity), peer)){
- [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref:kCFBooleanTrue];
- CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer);
- if(deviceID != NULL){
- CFArrayAppendValue(ids, deviceID);
- }
- CFReleaseNull(deviceID);
- }
- }
- });
- require_quiet(CFArrayGetCount(ids) != 0, xit);
- secnotice("IDS Transport", "List of IDS Peers to ping: %@", ids);
-
- SOSCloudKeychainGetIDSDeviceAvailability(ids, (__bridge CFStringRef)(account.peerID), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef sync_error) {
- bool success = (sync_error == NULL);
- if(!success)
- secerror("Failed to send list of IDS peers to IDSKSP: %@", sync_error);
- });
-xit:
- if(error && *error != NULL)
- secerror("SOSAccountSendIKSPSyncList had an error: %@", *error);
-
- if(localError)
- secerror("SOSAccountSendIKSPSyncList had an error: %@", localError);
-
- CFReleaseNull(ids);
- CFReleaseNull(localError);
-
- return result;
-}
//
// MARK: KVS Syncing
//
CFErrorRef localError = NULL;
bool result = false;
- require_quiet([account.trust isInCircle:error], xit);
+ require_quiet([account isInCircle:error], xit);
result =[account.kvs_message_transport SOSTransportMessageSyncWithPeers:account.kvs_message_transport p:peerIDs err:&localError];
return result;
}
-static CFMutableArrayRef SOSAccountCopyPeerIDsForDSID(SOSAccount* account, CFStringRef deviceID, CFErrorRef* error) {
- CFMutableArrayRef peerIDs = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
-
- SOSCircleForEachValidPeer(account.trust.trustedCircle, account.accountKey, ^(SOSPeerInfoRef peer) {
- CFStringRef peerDeviceID = SOSPeerInfoCopyDeviceID(peer);
- if(peerDeviceID != NULL && CFStringCompare(peerDeviceID, deviceID, 0) == 0){
- CFArrayAppendValue(peerIDs, SOSPeerInfoGetPeerID(peer));
- }
- CFReleaseNull(peerDeviceID);
- });
-
- if (peerIDs == NULL || CFArrayGetCount(peerIDs) == 0) {
- CFReleaseNull(peerIDs);
- SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("No peer with DSID: %@"), deviceID);
- }
-
- return peerIDs;
-}
-
-static bool SOSAccountSyncWithKVSPeerFromPing(SOSAccount* account, CFArrayRef peerIDs, CFErrorRef *error) {
-
- CFErrorRef localError = NULL;
- bool result = false;
-
- CFSetRef peerSet = CFSetCreateCopyOfArrayForCFTypes(peerIDs);
- result = [account.kvs_message_transport SOSTransportMessageSyncWithPeers:account.kvs_message_transport p:peerSet err:&localError];
-
- CFReleaseNull(peerSet);
-
- return result;
-}
-
-bool SOSAccountSyncWithKVSUsingIDSID(SOSAccount* account, CFStringRef deviceID, CFErrorRef *error) {
- bool result = false;
- CFErrorRef localError = NULL;
-
- secnotice("KVS Transport","Syncing with KVS capable peer via DSID: %@", deviceID);
-
- CFArrayRef peerIDs = SOSAccountCopyPeerIDsForDSID(account, deviceID, &localError);
- require_quiet(peerIDs, xit);
-
- CFStringArrayPerfromWithDescription(peerIDs, ^(CFStringRef peerIDList) {
- secnotice("KVS Transport", "Syncing with KVS capable peers: %@", peerIDList);
- });
-
- result = SOSAccountSyncWithKVSPeerFromPing(account, peerIDs, &localError);
- secerror("KVS sync %s. (%@)", result ? "succeeded" : "failed", localError);
-
-xit:
- CFReleaseNull(peerIDs);
- CFErrorPropagate(localError, error);
-
- return result;
-}
CFSetRef SOSAccountSyncWithPeersOverKVS(SOSAccountTransaction* txn, CFSetRef peers) {
CFMutableSetRef handled = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
return handled;
}
-CF_RETURNS_RETAINED CFSetRef SOSAccountSyncWithPeersOverIDS(SOSAccountTransaction* txn, CFSetRef peers) {
- CFErrorRef localError = NULL;
- SOSAccount* account = txn.account;
-
- CFStringSetPerformWithDescription(peers, ^(CFStringRef peerDescription) {
- secnotice("IDS Transport","Syncing with IDS capable peers: %@", peerDescription);
- });
-
- // We should change this to return a set of peers we succeeded with, but for now assume they all worked.
- bool result = [account.ids_message_transport SOSTransportMessageSyncWithPeers:account.ids_message_transport p:peers err:&localError];
- secnotice("IDS Transport", "IDS Sync result: %d", result);
-
- return CFSetCreateCopy(kCFAllocatorDefault, peers);
-}
-
CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peerIDs, CFErrorRef *error) {
CFMutableSetRef notMePeers = NULL;
CFMutableSetRef handledPeerIDs = NULL;
- CFMutableSetRef peersForIDS = NULL;
CFMutableSetRef peersForKVS = NULL;
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.
- bool canUseIDS = [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account];
-
- if(![account.trust isInCircle:error])
+ if(![account isInCircle:error])
{
handledPeerIDs = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs);
CFReleaseNull(notMePeers);
- CFReleaseNull(peersForIDS);
CFReleaseNull(peersForKVS);
return handledPeerIDs;
}
handledPeerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- peersForIDS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
peersForKVS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
SOSPeerInfoRef myPeerInfo = account.peerInfo;
if(!myPeerInfo)
{
CFReleaseNull(notMePeers);
- CFReleaseNull(peersForIDS);
CFReleaseNull(peersForKVS);
return handledPeerIDs;
notMePeers = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs);
CFSetRemoveValue(notMePeers, myPeerID);
-
- if(!SOSAccountSendIKSPSyncList(account, error)){
- if(error != NULL)
- secnotice("IDS Transport", "Did not send list of peers to ping (pre-E): %@", *error);
- }
CFSetForEach(notMePeers, ^(const void *value) {
CFErrorRef localError = NULL;
require_quiet(peerID, skip);
peerInfo = SOSCircleCopyPeerWithID(circle, peerID, NULL);
- if (peerInfo && SOSCircleHasValidSyncingPeer(circle, peerInfo, account.accountKey, NULL)) {
- if (ENABLE_IDS && canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo) && SOSPeerInfoShouldUseACKModel(myPeerInfo, peerInfo)) {
- CFSetAddValue(peersForIDS, peerID);
- } else {
- CFSetAddValue(peersForKVS, peerID);
- }
+ if (peerInfo && SOSCircleHasValidSyncingPeer(circle, peerInfo, account.accountKey, NULL)){
+ CFSetAddValue(peersForKVS, peerID);
} else {
CFSetAddValue(handledPeerIDs, peerID);
}
CFReleaseNull(localError);
});
- CFSetRef handledIDSPeerIDs = SOSAccountSyncWithPeersOverIDS(txn, peersForIDS);
- CFSetUnion(handledPeerIDs, handledIDSPeerIDs);
- CFReleaseNull(handledIDSPeerIDs);
-
CFSetRef handledKVSPeerIDs = SOSAccountSyncWithPeersOverKVS(txn, peersForKVS);
CFSetUnion(handledPeerIDs, handledKVSPeerIDs);
CFReleaseNull(handledKVSPeerIDs);
SOSAccountConsiderLoggingEngineState(txn);
CFReleaseNull(notMePeers);
- CFReleaseNull(peersForIDS);
CFReleaseNull(peersForKVS);
return handledPeerIDs;
}
-bool SOSAccountClearPeerMessageKey(SOSAccountTransaction* txn, CFStringRef peerID, CFErrorRef *error)
-{
- if (peerID == NULL) {
- return false;
- }
-
- SOSAccount* account = txn.account;
-
- secnotice("IDS Transport", "clearing peer message for %@", peerID);
- CFTypeRef dsid = SOSAccountGetValue(account, kSOSDSIDKey, error);
-
- if(dsid == NULL)
- dsid = kCFNull;
-
- CFStringRef myID = (__bridge CFStringRef)(account.peerID);
- CFStringRef message_to_peer_key = SOSMessageKeyCreateFromTransportToPeer(account.kvs_message_transport, myID, peerID);
- CFDictionaryRef a_message_to_a_peer = CFDictionaryCreateForCFTypes(NULL, message_to_peer_key, kCFNull, kSOSKVSRequiredKey, dsid, NULL);
-
- CloudKeychainReplyBlock log_error = ^(CFDictionaryRef returnedValues __unused, CFErrorRef block_error) {
- if (block_error) {
- secerror("Error putting: %@", block_error);
- }
- };
-
- SOSCloudKeychainPutObjectsInCloud(a_message_to_a_peer, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), log_error);
-
- CFReleaseNull(a_message_to_a_peer);
- CFReleaseNull(message_to_peer_key);
-
- return true;
-}
-
CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransaction* txn, CFSetRef /* CFStringRef */ peers, CFSetRef /* CFStringRef */ backupPeers, CFErrorRef *error)
{
CFErrorRef localError = NULL;
CFMutableSetRef handled = SOSAccountSyncWithPeers(txn, peers, &localError);
- [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account];
-
if (!handled) {
secnotice("account-sync", "Peer Sync failed: %@", localError);
handled = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
SOSAccount* account = txn.account;
SOSAccountTrustClassic *trust = account.trust;
- if (![account.trust isInCircle:error])
+ if (![account isInCircle:error])
return false;
NSMutableSet<NSString*>* allSyncingPeers = [NSMutableSet set];
SOSCircleRef circle = trust.trustedCircle;
- // Tickle IDS in case we haven't even tried when we're syncing.
- [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account];
-
SOSCircleForEachValidSyncingPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) {
[allSyncingPeers addObject: (__bridge NSString*) SOSPeerInfoGetPeerID(peer)];
});
bool SOSAccountMessageFromPeerIsPending(SOSAccountTransaction* txn, SOSPeerInfoRef peer, CFErrorRef *error) {
bool success = false;
SOSAccount* account = txn.account;
- require_quiet([account.trust isInCircle:error], xit);
+ require_quiet([account isInCircle:error], xit);
// This translation belongs inside KVS..way down in CKD, but for now we reach over and do it here.
CFStringRef peerMessage = SOSMessageKeyCreateFromPeerToTransport([account kvs_message_transport], (__bridge CFStringRef)(account.peerID), SOSPeerInfoGetPeerID(peer));
bool SOSAccountSendToPeerIsPending(SOSAccountTransaction* txn, SOSPeerInfoRef peer, CFErrorRef *error) {
bool success = false;
SOSAccount* account = txn.account;
- require_quiet([account.trust isInCircle:error], xit);
+ require_quiet([account isInCircle:error], xit);
success = SOSCCIsSyncPendingFor(SOSPeerInfoGetPeerID(peer), error);
xit:
#import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h"
#import "Security/SecureObjectSync/SOSAccountTrustClassic.h"
#import "Security/SecureObjectSync/SOSTransportMessageKVS.h"
+#import "Security/SecItemBackup.h"
#include <keychain/ckks/CKKS.h>
@property BOOL initialTrusted;
@property NSData* initialKeyParameters;
+@property uint initialCirclePeerCount;
+
@property bool quiet;
@property NSMutableSet<NSString*>* peersToRequestSync;
@implementation SOSAccountTransaction
+static void SOSCircleSetCachedStatus(SOSAccount *account) {
+ static SOSCCStatus lastStatus = -2;
+ SOSCCStatus currentStatus = [account getCircleStatus:NULL];
+
+ if(lastStatus != currentStatus) {
+ lastStatus = currentStatus;
+ account.notifyCircleChangeOnExit = true;
+ }
+
+ if(account.notifyCircleChangeOnExit) {
+ __block uint64_t circleStatus = [account.trust getCircleStatusOnly:NULL] | CC_STATISVALID;
+ if(account.accountKeyIsTrusted) {
+ circleStatus |= CC_UKEY_TRUSTED;
+ if(account.accountPrivateKey) {
+ circleStatus |= CC_CAN_AUTH;
+ }
+ }
+ // we might be in circle, but invalid - let client see this in bitmask.
+ if([account.trust isInCircleOnly:NULL]) {
+ circleStatus |= CC_PEER_IS_IN;
+ }
+
+ SOSCachedNotificationOperation(kSOSCCCircleChangedNotification, ^bool(int token, bool gtg) {
+ if(gtg) {
+ uint32_t status = notify_set_state(token, circleStatus);
+ if(status == NOTIFY_STATUS_OK) {
+ notify_post(kSOSCCCircleChangedNotification);
+ account.notifyCircleChangeOnExit = false;
+ }
+ return true;
+ }
+ return false;
+ });
+ }
+}
+
+static void SOSViewsSetCachedStatus(SOSAccount *account) {
+ static uint64_t lastViewBitmask = 0;
+ __block uint64_t viewBitMask = ([account getCircleStatus:NULL] == kSOSCCInCircle) ? SOSPeerInfoViewBitMask(account.peerInfo) :0;
+
+ if(viewBitMask != lastViewBitmask) {
+ lastViewBitmask = viewBitMask;
+ account.notifyViewChangeOnExit = true; // this is also set within operations and might want the notification for other reasons.
+ }
+
+ if(account.notifyViewChangeOnExit) {
+ SOSCachedNotificationOperation(kSOSCCViewMembershipChangedNotification, ^bool(int token, bool gtg) {
+ if(gtg) {
+ uint32_t status = notify_set_state(token, viewBitMask);
+ if(status == NOTIFY_STATUS_OK) {
+ notify_post(kSOSCCViewMembershipChangedNotification);
+ account.notifyViewChangeOnExit = false;
+ }
+ return true;
+ }
+ return false;
+ });
+ }
+}
+
- (NSString*) description {
return [NSString stringWithFormat:@"<SOSAccountTransaction*@%p %ld>",
self, (unsigned long)(self.initialViews ? [self.initialViews count] : 0)];
}
- (void) start {
- self.initialInCircle = [self.account.trust isInCircle:NULL];
+ SOSCircleSetCachedStatus(_account);
+ SOSViewsSetCachedStatus(_account);
+
+ self.initialInCircle = [self.account isInCircle:NULL];
self.initialTrusted = self.account.accountKeyIsTrusted;
+ self.initialCirclePeerCount = 0;
+ if(self.initialInCircle) {
+ self.initialCirclePeerCount = SOSCircleCountPeers(self.account.trust.trustedCircle);
+ }
if (self.initialInCircle) {
SOSAccountEnsureSyncChecking(self.account);
SOSPeerInfoRef mpi = self.account.peerInfo;
- bool isInCircle = [self.account.trust isInCircle:NULL];
+ bool isInCircle = [self.account isInCircle:NULL];
if (isInCircle && self.peersToRequestSync) {
SOSCCRequestSyncWithPeers((__bridge CFSetRef)(self.peersToRequestSync));
[self.account flattenToSaveBlock];
// Refresh isInCircle since we could have changed our mind
- isInCircle = [self.account.trust isInCircle:NULL];
+ isInCircle = [self.account isInCircle:NULL];
+
+ uint finalCirclePeerCount = 0;
+ if(isInCircle) {
+ finalCirclePeerCount = SOSCircleCountPeers(self.account.trust.trustedCircle);
+ }
+
+ if(isInCircle && (finalCirclePeerCount < self.initialCirclePeerCount)) {
+ (void) SOSAccountCleanupAllKVSKeys(_account, NULL);
+ }
mpi = self.account.peerInfo;
CFSetRef views = mpi ? SOSPeerInfoCopyEnabledViews(mpi) : NULL;
doViewChanged = true;
}
- if(doCircleChanged) notify_post(kSOSCCCircleChangedNotification);
- if(doViewChanged) notify_post(kSOSCCViewMembershipChangedNotification);
+ if(doCircleChanged) {
+ SOSCircleSetCachedStatus(_account);
+ }
+ if(doViewChanged) {
+ SOSViewsSetCachedStatus(_account);
+ }
+ if(self.account.notifyBackupOnExit) {
+ notify_post(kSecItemBackupNotification);
+ self.account.notifyBackupOnExit = false;
+ }
+
if(do_account_state_at_zero <= 0) {
SOSAccountLogState(self.account);
@interface SOSAccountTrustClassic (Circle)
//Circle
--(SOSCCStatus) getCircleStatus:(CFErrorRef*) error;
+-(SOSCCStatus) getCircleStatusOnly:(CFErrorRef*) error;
-(SOSCircleRef) ensureCircle:(SOSAccount*)account name:(CFStringRef)name err:(CFErrorRef *)error;
-(bool) modifyCircle:(SOSCircleStorageTransport*)circleTransport err:(CFErrorRef*)error action:(SOSModifyCircleBlock)block;
-(SOSCircleRef) getCircle:(CFErrorRef *)error;
-(bool) hasCircle:(CFErrorRef*) error;
-(void) generationSignatureUpdateWith:(SOSAccount*)account key:(SecKeyRef) privKey;
--(bool) isInCircle:(CFErrorRef *)error;
+-(bool) isInCircleOnly:(CFErrorRef *)error;
-(void) forEachCirclePeerExceptMe:(SOSIteratePeerBlock)block;
-(bool) leaveCircle:(SOSAccount*)account err:(CFErrorRef*) error;
+-(bool) leaveCircleWithAccount:(SOSAccount*)account withAnalytics:(NSData*)parentEvent err:(CFErrorRef*) error;
-(bool) resetToOffering:(SOSAccountTransaction*) aTxn key:(SecKeyRef)userKey err:(CFErrorRef*) error;
-(bool) resetCircleToOffering:(SOSAccountTransaction*) aTxn userKey:(SecKeyRef) user_key err:(CFErrorRef *)error;
-(SOSCCStatus) thisDeviceStatusInCircle:(SOSCircleRef) circle peer:(SOSPeerInfoRef) this_peer;
-(bool) updateCircle:(SOSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef) newCircle err:(CFErrorRef*)error;
+-(bool) updateCircleWithAnalytics:(SOSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef) newCircle parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error;
+
-(bool) updateCircleFromRemote:(SOSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef)newCircle err:(CFErrorRef*)error;
-(CFArrayRef) copySortedPeerArray:(CFErrorRef *)error
action:(SOSModifyPeersInCircleBlock)block;
-(bool) handleUpdateCircle:(SOSCircleRef) prospective_circle transport:(SOSCircleStorageTransport*)circleTransport update:(bool) writeUpdate err:(CFErrorRef*)error;
+-(bool) handleUpdateCircleWithAnalytics:(SOSCircleRef) prospective_circle transport:(SOSCircleStorageTransport*)circleTransport update:(bool) writeUpdate parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error;
-(bool) joinCircle:(SOSAccountTransaction*) aTxn userKey:(SecKeyRef)user_key useCloudPeer:(bool)use_cloud_peer err:(CFErrorRef*) error;
@end
@implementation SOSAccountTrustClassic (Circle)
--(bool) isInCircle:(CFErrorRef *)error
+-(bool) isInCircleOnly:(CFErrorRef *)error
{
- SOSCCStatus result = [self getCircleStatus:error];
+ SOSCCStatus result = [self getCircleStatusOnly:error];
if (result != kSOSCCInCircle) {
SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("Not in circle"));
return kSOSCCNotInCircle;
}
--(SOSCCStatus) getCircleStatus:(CFErrorRef*) error
+-(SOSCCStatus) getCircleStatusOnly:(CFErrorRef*) error
{
return [self thisDeviceStatusInCircle:self.trustedCircle peer:self.peerInfo];
}
return hasUpdated;
}
+-(bool) handleUpdateCircleWithAnalytics:(SOSCircleRef) prospective_circle transport:(SOSCircleStorageTransport*)circleTransport update:(bool) writeUpdate parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error
+{
+ bool success = true;
+ bool haveOldCircle = true;
+ const char *local_remote = writeUpdate ? "local": "remote";
+
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError];
+
+ SOSAccount* account = [circleTransport getAccount];
+
+ secnotice("signing", "start:[%s]", local_remote);
+ if (!account.accountKey || !account.accountKeyIsTrusted) {
+ SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Can't handle updates with no trusted public key here"), NULL, error);
+ return false;
+ }
+
+ if (!prospective_circle) {
+ secerror("##### Can't update to a NULL circle ######");
+ return false; // Can't update one we don't have.
+ }
+
+ // If this is a remote circle, check to see if this is our first opportunity to trust a circle where we
+ // 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;
+
+ }
+
+ CFStringRef newCircleName = SOSCircleGetName(prospective_circle);
+
+ SOSCircleRef oldCircle = self.trustedCircle;
+ SOSCircleRef emptyCircle = NULL;
+
+ if(oldCircle == NULL) {
+ SOSCreateErrorWithFormat(kSOSErrorIncompatibleCircle, NULL, error, NULL, CFSTR("Current Entry is NULL; rejecting %@"), prospective_circle);
+ secerror("##### Can't replace circle - we don't care about it ######");
+ return false;
+ }
+ if (CFGetTypeID(oldCircle) != SOSCircleGetTypeID()) {
+ secdebug("signing", ">>>>>>>>>>>>>>> Non-Circle Circle found <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
+ // We don't know what is in our table, likely it was kCFNull indicating we didn't
+ // understand a circle that came by. We seem to like this one lets make our entry be empty circle
+ emptyCircle = SOSCircleCreate(kCFAllocatorDefault, newCircleName, NULL);
+ oldCircle = emptyCircle;
+ haveOldCircle = false;
+ // And we're paranoid, drop our old peer info if for some reason we didn't before.
+ // SOSAccountDestroyCirclePeerInfo(account, oldCircle, NULL);
+ }
+
+ CFErrorRef retiredError = NULL;
+ SFSignInAnalytics *scanForRetiredEvent = [parent newSubTaskForEvent:@"scanForRetiredEvent"];
+ SOSAccountScanForRetired(account, prospective_circle, &retiredError);
+ if(retiredError){
+ [scanForRetiredEvent logRecoverableError:(__bridge NSError*)retiredError];
+ secerror("scan for retired error: %@", retiredError);
+ if(error){
+ *error = retiredError;
+ }else{
+ CFReleaseNull(retiredError);
+ }
+ }
+ [scanForRetiredEvent stopWithAttributes:nil];
+
+ SOSCircleRef newCircle = SOSAccountCloneCircleWithRetirement(account, prospective_circle, error);
+ if(!newCircle) return false;
+
+ SFSignInAnalytics *ghostBustingEvent = [parent newSubTaskForEvent:@"ghostBustingEvent"];
+ if([self ghostBustingOK: oldCircle updatingTo:newCircle]) {
+ SOSCircleRef ghostCleaned = SOSAccountCloneCircleWithoutMyGhosts(account, newCircle);
+ if(ghostCleaned) {
+ CFRetainAssign(newCircle, ghostCleaned);
+ writeUpdate = true;
+ }
+ }
+ [ghostBustingEvent stopWithAttributes:nil];
+
+ SOSFullPeerInfoRef me_full = self.fullPeerInfo;
+ SOSPeerInfoRef me = SOSFullPeerInfoGetPeerInfo(me_full);
+ CFStringRef myPeerID = SOSPeerInfoGetPeerID(me);
+ myPeerID = (myPeerID) ? myPeerID: CFSTR("No Peer");
+
+ if (me && SOSCircleUpdatePeerInfo(newCircle, me)) {
+ writeUpdate = true; // If we update our peer in the new circle we should write it if we accept it.
+ }
+
+ typedef enum {
+ accept,
+ countersign,
+ leave,
+ revert,
+ ignore
+ } circle_action_t;
+
+ static const char *actionstring[] = {
+ "accept", "countersign", "leave", "revert", "ignore",
+ };
+
+ circle_action_t circle_action = ignore;
+ enum DepartureReason leave_reason = kSOSNeverLeftCircle;
+
+ SecKeyRef old_circle_key = NULL;
+
+ CFErrorRef verifyCircleError = NULL;
+ SFSignInAnalytics *verifyCircleEvent = [parent newSubTaskForEvent:@"verifyCircleEvent"];
+ if(SOSCircleVerify(oldCircle, account.accountKey, &verifyCircleError)){
+ old_circle_key = account.accountKey;
+ }
+ else if(account.previousAccountKey && SOSCircleVerify(oldCircle, account.previousAccountKey, &verifyCircleError)){
+ old_circle_key = account.previousAccountKey;
+ }
+ if(verifyCircleError){
+ [verifyCircleEvent logRecoverableError:(__bridge NSError*)verifyCircleError];
+ secerror("verifyCircle error: %@", verifyCircleError);
+ if(error){
+ *error = verifyCircleError;
+ }else{
+ CFReleaseNull(verifyCircleError);
+ }
+ }
+ [verifyCircleEvent stopWithAttributes:nil];
+
+ bool userTrustedOldCircle = (old_circle_key != NULL) && haveOldCircle;
+
+ SFSignInAnalytics *concordanceTrustEvent = [parent newSubTaskForEvent:@"concordanceTrustEvent"];
+ CFErrorRef concordanceError = NULL;
+ SOSConcordanceStatus concstat =
+ SOSCircleConcordanceTrust(oldCircle, newCircle,
+ old_circle_key, account.accountKey,
+ me, &concordanceError);
+ if(concordanceError){
+ [concordanceTrustEvent logRecoverableError:(__bridge NSError*)concordanceError];
+ secerror("concordance trust error: %@", concordanceError);
+ if(error){
+ *error = concordanceError;
+ }else{
+ CFReleaseNull(concordanceError);
+ }
+ }
+ [concordanceTrustEvent stopWithAttributes:nil];
+
+ CFStringRef concStr = NULL;
+ switch(concstat) {
+ case kSOSConcordanceTrusted:
+ circle_action = countersign;
+ concStr = CFSTR("Trusted");
+ break;
+ case kSOSConcordanceGenOld:
+ circle_action = userTrustedOldCircle ? revert : ignore;
+ concStr = CFSTR("Generation Old");
+ break;
+ case kSOSConcordanceBadUserSig:
+ case kSOSConcordanceBadPeerSig:
+ circle_action = userTrustedOldCircle ? revert : accept;
+ concStr = CFSTR("Bad Signature");
+ break;
+ case kSOSConcordanceNoUserSig:
+ circle_action = userTrustedOldCircle ? revert : accept;
+ concStr = CFSTR("No User Signature");
+ break;
+ case kSOSConcordanceNoPeerSig:
+ circle_action = accept; // We might like this one eventually but don't countersign.
+ concStr = CFSTR("No trusted peer signature");
+ secnotice("signing", "##### No trusted peer signature found, accepting hoping for concordance later");
+ break;
+ case kSOSConcordanceNoPeer:
+ circle_action = leave;
+ leave_reason = kSOSLeftUntrustedCircle;
+ concStr = CFSTR("No trusted peer left");
+ break;
+ case kSOSConcordanceNoUserKey:
+ secerror("##### No User Public Key Available, this shouldn't ever happen!!!");
+ abort();
+ break;
+ default:
+ secerror("##### Bad Error Return from ConcordanceTrust");
+ abort();
+ break;
+ }
+
+ 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;
+
+ if (circle_action == leave) {
+ circle_action = ignore; (void) circle_action; // Acknowledge this is a dead store.
+
+ if (me && SOSCircleHasPeer(oldCircle, me, NULL)) {
+ secnotice("account", "Leaving circle with peer %@", me);
+ debugDumpCircle(CFSTR("oldCircle"), oldCircle);
+ debugDumpCircle(CFSTR("newCircle"), newCircle);
+ debugDumpCircle(CFSTR("prospective_circle"), prospective_circle);
+ secnotice("account", "Key state: accountKey %@, previousAccountKey %@, old_circle_key %@",
+ account.accountKey, account.previousAccountKey, old_circle_key);
+
+ if (sosAccountLeaveCircleWithAnalytics(account, newCircle, parentEvent, error)) {
+ secnotice("circleOps", "Leaving circle by newcircle state");
+ circleToPush = newCircle;
+ } else {
+ secnotice("signing", "Can't leave circle, but dumping identities");
+ success = false;
+ }
+ self.departureCode = leave_reason;
+ circle_action = accept;
+ me = NULL;
+ me_full = NULL;
+ } else {
+ // We are not in this circle, but we need to update account with it, since we got it from cloud
+ secnotice("signing", "We are not in this circle, but we need to update account with it");
+ debugDumpCircle(CFSTR("oldCircle"), oldCircle);
+ debugDumpCircle(CFSTR("newCircle"), newCircle);
+ debugDumpCircle(CFSTR("prospective_circle"), prospective_circle);
+ circle_action = accept;
+ }
+ }
+
+ if (circle_action == countersign) {
+ if (me && SOSCircleHasPeer(newCircle, me, NULL)) {
+ SFSignInAnalytics *verifyPeerSignedEvent = [parent newSubTaskForEvent:@"verifyPeerSignedEvent"];
+ CFErrorRef verifyPeerSignedError = NULL;
+ if (SOSCircleVerifyPeerSigned(newCircle, me, &verifyPeerSignedError)) {
+ secnotice("signing", "Already concur with the new circle");
+ } else {
+ CFErrorRef signing_error = NULL;
+ SFSignInAnalytics *circleConcordanceSignEvent = [parent newSubTaskForEvent:@"circleConcordanceSignEvent"];
+ if (me_full && SOSCircleConcordanceSign(newCircle, me_full, &signing_error)) {
+ circleToPush = newCircle;
+ secnotice("signing", "Concurred with new circle");
+ } else {
+ secerror("Failed to concurrence sign, error: %@", signing_error);
+ success = false;
+ }
+ if(signing_error){
+ [circleConcordanceSignEvent logRecoverableError:(__bridge NSError*)signing_error];
+ secerror("circle concordance sign error: %@", signing_error);
+ if(error){
+ *error = signing_error;
+ }else{
+ CFReleaseNull(signing_error);
+ }
+ }
+ [circleConcordanceSignEvent stopWithAttributes:nil];
+ CFReleaseSafe(signing_error);
+ }
+ if(verifyPeerSignedError){
+ [verifyPeerSignedEvent logRecoverableError:(__bridge NSError*)verifyPeerSignedError];
+ secerror("verify peer signed error: %@", verifyPeerSignedError);
+ if(error){
+ *error = verifyPeerSignedError;
+ }else{
+ CFReleaseNull(verifyPeerSignedError);
+ }
+ }
+ [verifyPeerSignedEvent stopWithAttributes:nil];
+ } else {
+ secnotice("signing", "Not countersigning, not in new circle");
+ }
+ circle_action = accept;
+ }
+
+ if (circle_action == accept) {
+ if(SOSCircleHasUpdatedPeerInfoWithOctagonKey(oldCircle, newCircle)){
+ notify_post(kSOSCCCircleOctagonKeysChangedNotification);
+ }
+ 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("circleOps", "Member of old circle but not of new circle (%d)", self.departureCode);
+ debugDumpCircle(CFSTR("oldCircle"), oldCircle);
+ debugDumpCircle(CFSTR("newCircle"), newCircle);
+ }
+
+ if (me
+ && SOSCircleHasActivePeer(oldCircle, me, NULL)
+ && !(SOSCircleCountPeers(oldCircle) == 1 && SOSCircleHasPeer(oldCircle, me, NULL)) // If it was our offering, don't change ID to avoid ghosts
+ && !SOSCircleHasPeer(newCircle, me, NULL) && !SOSCircleHasApplicant(newCircle, me, NULL)) {
+ secnotice("circle", "Purging my peer (ID: %@) for circle '%@'!!!", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle));
+ if (self.fullPeerInfo)
+ SOSFullPeerInfoPurgePersistentKey(self.fullPeerInfo, NULL);
+ me = NULL;
+ me_full = NULL;
+ }
+
+ if (me && SOSCircleHasRejectedApplicant(newCircle, me, NULL)) {
+ SOSPeerInfoRef reject = SOSCircleCopyRejectedApplicant(newCircle, me, NULL);
+ if(CFEqualSafe(reject, me) && SOSPeerInfoApplicationVerify(me, account.accountKey, NULL)) {
+ secnotice("circle", "Rejected, Purging my applicant peer (ID: %@) for circle '%@'", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle));
+ debugDumpCircle(CFSTR("oldCircle"), oldCircle);
+ debugDumpCircle(CFSTR("newCircle"), newCircle);
+ if (self.fullPeerInfo)
+ SOSFullPeerInfoPurgePersistentKey(self.fullPeerInfo, NULL);
+ me = NULL;
+ me_full = NULL;
+ } else {
+ secnotice("circle", "Rejected, Reapplying (ID: %@) for circle '%@'", SOSPeerInfoGetPeerID(me), SOSCircleGetName(oldCircle));
+ debugDumpCircle(CFSTR("oldCircle"), oldCircle);
+ debugDumpCircle(CFSTR("newCircle"), newCircle);
+ SOSCircleRequestReadmission(newCircle, account.accountKey, me, NULL);
+ writeUpdate = true;
+ }
+ CFReleaseNull(reject);
+ }
+
+ CFRetainSafe(oldCircle);
+ account.previousAccountKey = account.accountKey;
+
+ secnotice("signing", "%@, Accepting new circle", concStr);
+ if (circle_action == accept) {
+ [self setTrustedCircle:newCircle];
+ }
+
+ if (me && account.accountKeyIsTrusted
+ && SOSCircleHasApplicant(oldCircle, me, NULL)
+ && SOSCircleCountPeers(newCircle) > 0
+ && !SOSCircleHasPeer(newCircle, me, NULL) && !SOSCircleHasApplicant(newCircle, me, NULL)) {
+ // We weren't rejected (above would have set me to NULL.
+ // We were applying and we weren't accepted.
+ // Our application is declared lost, let us reapply.
+
+ secnotice("signing", "requesting readmission to new circle");
+ if (SOSCircleRequestReadmission(newCircle, account.accountKey, me, NULL))
+ writeUpdate = true;
+ }
+
+ if (me && SOSCircleHasActivePeer(oldCircle, me, NULL)) {
+ SFSignInAnalytics *cleanupRetirementTicketsEvent = [parent newSubTaskForEvent:@"cleanupRetirementTicketsEvent"];
+ CFErrorRef cleanupError = NULL;
+ [account.trust cleanupRetirementTickets:account circle:oldCircle time:RETIREMENT_FINALIZATION_SECONDS err:&cleanupError];
+ if(cleanupError){
+ [cleanupRetirementTicketsEvent logRecoverableError:(__bridge NSError*)cleanupError];
+ secerror("cleanup retirement tickets error: %@", cleanupError);
+ if(error){
+ *error = cleanupError;
+ }else{
+ CFReleaseNull(cleanupError);
+ }
+ }
+ [cleanupRetirementTicketsEvent stopWithAttributes:nil];
+ }
+
+ SFSignInAnalytics *notifyOfChangeEvent = [parent newSubTaskForEvent:@"notifyOfChangeEvent"];
+ SOSAccountNotifyOfChange(account, oldCircle, newCircle);
+ [notifyOfChangeEvent stopWithAttributes:nil];
+
+ CFReleaseNull(oldCircle);
+
+ if (writeUpdate)
+ circleToPush = newCircle;
+ secnotice("circleop", "Setting key_interests_need_updating to true in handleUpdateCircle");
+ account.key_interests_need_updating = true;
+ }
+
+ /*
+ * In the revert section we'll guard the KVS idea of circles by rejecting "bad" new circles
+ * and pushing our current view of the circle (oldCircle). We'll only do this if we actually
+ * are a member of oldCircle - never for an empty circle.
+ */
+
+ if (circle_action == revert) {
+ if(haveOldCircle && me && SOSCircleHasActivePeer(oldCircle, me, NULL)) {
+ secnotice("signing", "%@, Rejecting new circle, re-publishing old circle", concStr);
+ circleToPush = oldCircle;
+ [self setTrustedCircle:oldCircle];
+ } else {
+ secnotice("canary", "%@, Rejecting: new circle Have no old circle - would reset", concStr);
+ }
+ }
+
+ if (circleToPush != NULL) {
+ secnotice("signing", "Pushing:[%s]", local_remote);
+ CFDataRef circle_data = SOSCircleCopyEncodedData(circleToPush, kCFAllocatorDefault, error);
+
+ if (circle_data) {
+ // Ensure we flush changes
+ account.circle_rings_retirements_need_attention = true;
+
+ //posting new circle to peers
+ SFSignInAnalytics *postCircleEvent = [parent newSubTaskForEvent:@"postCircleEvent"];
+ CFErrorRef postCircleError = NULL;
+ success &= [circleTransport postCircle:SOSCircleGetName(circleToPush) circleData:circle_data err:&postCircleError];
+ if(postCircleError){
+ [postCircleEvent logRecoverableError:(__bridge NSError*)postCircleError];
+ secerror("posting circle failed: %@", postCircleError);
+ if(error){
+ *error = postCircleError;
+ }else{
+ CFReleaseNull(postCircleError);
+ }
+ }
+ [postCircleEvent stopWithAttributes:nil];
+ } else {
+ success = false;
+ }
+ CFReleaseNull(circle_data);
+ }
+ CFReleaseSafe(newCircle);
+ CFReleaseNull(emptyCircle);
+
+ // There are errors collected above that are soft (worked around)
+ if(success && error && *error) {
+ CFReleaseNull(*error);
+ }
+
+ return success;
+}
+
-(bool) handleUpdateCircle:(SOSCircleRef) prospective_circle transport:(SOSKVSCircleStorageTransport*)circleTransport update:(bool) writeUpdate err:(CFErrorRef*)error
{
bool success = true;
}
} else {
secnotice("signing", "Not countersigning, not in new circle");
- debugDumpCircle(CFSTR("circle to countersign"), newCircle);
}
circle_action = accept;
}
if (circle_action == revert) {
if(haveOldCircle && me && SOSCircleHasActivePeer(oldCircle, me, NULL)) {
secnotice("signing", "%@, Rejecting new circle, re-publishing old circle", concStr);
- debugDumpCircle(CFSTR("oldCircle"), oldCircle);
- debugDumpCircle(CFSTR("newCircle"), newCircle);
circleToPush = oldCircle;
[self setTrustedCircle:oldCircle];
} else {
//posting new circle to peers
success &= [circleTransport postCircle:SOSCircleGetName(circleToPush) circleData:circle_data err:error];
- //cleanup old KVS keys
- (void) SOSAccountCleanupAllKVSKeys(account, NULL);
} else {
success = false;
}
return [self handleUpdateCircle:newCircle transport:circleTransport update:true err:error];
}
+-(bool) updateCircleWithAnalytics:(SOSKVSCircleStorageTransport*)circleTransport newCircle:(SOSCircleRef) newCircle parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error
+{
+ return [self handleUpdateCircle:newCircle transport:circleTransport update:true err:error];
+}
+
+-(bool) modifyCircleWithAnalytics:(SOSKVSCircleStorageTransport*)circleTransport parentEvent:(NSData*)parentEvent err:(CFErrorRef*)error action:(SOSModifyCircleBlock)block
+{
+ bool success = false;
+ SOSCircleRef circleCopy = NULL;
+ require_action_quiet(self.trustedCircle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from")));
+
+ circleCopy = SOSCircleCopyCircle(kCFAllocatorDefault, self.trustedCircle, error);
+ require_quiet(circleCopy, fail);
+
+ success = true;
+ require_quiet(block(circleCopy), fail);
+
+ success = [self updateCircleWithAnalytics:circleTransport newCircle:circleCopy parentEvent:parentEvent err:error];
+
+fail:
+ CFReleaseSafe(circleCopy);
+ return success;
+}
+
-(bool) modifyCircle:(SOSKVSCircleStorageTransport*)circleTransport err:(CFErrorRef*)error action:(SOSModifyCircleBlock)block
{
bool success = false;
SOSFullPeerInfoRef icfpi = SOSCircleCopyiCloudFullPeerInfoRef(circle, NULL);
if(!icfpi) {
SOSAccountRemoveIncompleteiCloudIdentities(account, circle, privKey, NULL);
- change |= [self addiCloudIdentity:circle key:privKey err:NULL];
+ bool identityAdded = [self addiCloudIdentity:circle key:privKey err:NULL];
+ if(identityAdded) {
+ account.notifyBackupOnExit = true;
+ }
+ change |= identityAdded;
} else {
CFReleaseNull(icfpi);
}
});
}
}
+
+-(bool) leaveCircleWithAccount:(SOSAccount*)account withAnalytics:(NSData*)parentEvent err:(CFErrorRef*) error
+{
+ bool result = true;
+ secnotice("circleOps", "leaveCircleWithAccount: Leaving circle by client request");
+ result &= [self modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle) {
+ return sosAccountLeaveCircleWithAnalytics(account, circle, parentEvent, error);
+ }];
+
+ self.departureCode = kSOSWithdrewMembership;
+
+ return result;
+}
+
-(bool) leaveCircle:(SOSAccount*)account err:(CFErrorRef*) error
{
bool result = true;
require_quiet([self addiCloudIdentity:circle key:user_key err:error], err_out);
result = true;
SOSAccountPublishCloudParameters(account, NULL);
-
+ account.notifyBackupOnExit = true;
+
err_out:
if (result == false)
secerror("error resetting circle (%@) to offering: %@", circle, localError);
-(bool) resetRing:(SOSAccount*)account ringName:(CFStringRef) ringName err:(CFErrorRef *)error;
-(bool) leaveRing:(SOSKVSCircleStorageTransport*)circle_transport ring:(SOSRingRef) ring err:(CFErrorRef*) error;
-(bool) resetAccountToEmpty:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport err:(CFErrorRef*) error;
+-(bool) resetAccountToEmptyWithAnalytics:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport parentEvent:(NSData*)parentEvent err:(CFErrorRef*) error;
+
-(SOSRingRef) copyRing:(CFStringRef) ringName err:(CFErrorRef *)error;
-(CFMutableDictionaryRef) getRings:(CFErrorRef *)error;
-(bool) forEachRing:(RingNameBlock)block;
#import "Security/SecureObjectSync/SOSViews.h"
#import "Security/SecureObjectSync/SOSPeerInfoV2.h"
#import "Security/SecureObjectSync/SOSTransportCircleKVS.h"
+#import "keychain/Signin Metrics/SFSignInAnalytics.h"
@implementation SOSAccountTrustClassic (Expansion)
typedef enum {
{
__block bool result = true;
-
+
result &= [self resetAllRings:account err:error];
-
+
self.fullPeerInfo = nil;
self.departureCode = kSOSWithdrewMembership;
return result;
}
+-(bool) resetAccountToEmptyWithAnalytics:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport parentEvent:(NSData*)parentEvent err:(CFErrorRef*) error
+{
+ __block bool result = true;
+
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError];
+
+ CFErrorRef resetError = NULL;
+ SFSignInAnalytics *resetAllRingsEvent = [parent newSubTaskForEvent:@"resetAllRingsEvent"];
+ result &= [self resetAllRings:account err:&resetError];
+ if(resetError){
+ [resetAllRingsEvent logRecoverableError:(__bridge NSError*)resetError];
+ secerror("reset all rings error: %@", resetError);
+ if(error){
+ *error = resetError;
+ }else{
+ CFReleaseNull(resetError);
+ }
+ }
+ [resetAllRingsEvent stopWithAttributes:nil];
+
+ self.fullPeerInfo = nil;
+
+ self.departureCode = kSOSWithdrewMembership;
+ secnotice("circleOps", "Reset Circle to empty by client request");
+
+ SFSignInAnalytics *resetCircleToEmptyEvent = [parent newSubTaskForEvent:@"resetCircleToEmptyEvent"];
+ result &= [self modifyCircle:circleTransport err:error action:^bool(SOSCircleRef circle) {
+ result = SOSCircleResetToEmpty(circle, error);
+ return result;
+ }];
+ [resetCircleToEmptyEvent stopWithAttributes:nil];
+
+ if (!result) {
+ secerror("error: %@", error ? *error : NULL);
+ }
+ return result;
+}
+
-(void) setRings:(CFMutableDictionaryRef) newrings
{
[self.expansion setObject:(__bridge NSMutableDictionary*)newrings forKey:(kSOSRingKey)];
SOSFullPeerInfoRef fpi = self.fullPeerInfo;
SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi);
CFStringRef peerID = SOSPeerInfoGetPeerID(pi);
- bool peerActive = (fpi && pi && peerID && [self isInCircle:NULL]);
+ bool peerActive = (fpi && pi && peerID && [self isInCircleOnly:NULL]);
SOSRingRef newRing = NULL;
SOSRingRef oldRing = NULL;
-
+
+ require_quiet(SOSAccountHasPublicKey(account, error), errOut);
+
secdebug("ringSigning", "start:[%s] %@", localRemote, prospectiveRing);
- require_quiet(SOSAccountHasPublicKey(account, error), errOut);
require_action_quiet(prospectiveRing, errOut,
SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("No Ring to work with"), NULL, error));
CFMutableDictionaryRef rings = [self getRings:error];
require_action_quiet(rings, errOut, SOSCreateError(kSOSErrorNoRing, CFSTR("No Rings found"), NULL, error));
CFTypeRef ringder = CFDictionaryGetValue(rings, ringName);
- require_action_quiet(ringder, errOut, SOSCreateError(kSOSErrorNoRing, CFSTR("No Ring found"), NULL, error));
+ require_action_quiet(ringder, errOut, SOSCreateErrorWithFormat(kSOSErrorNoRing, NULL, error, NULL, CFSTR("No Ring found %@"), ringName));
SOSRingRef ring = SOSRingCreateFromData(NULL, ringder);
return (SOSRingRef) ring;
CFReleaseNull(pendingDefaultViews);
[self setValueInExpansion:kSOSUnsyncedViewsKey value:kCFBooleanTrue err:NULL];
-
- if (!self.fullPeerInfo) {
- secerror("Can't make FullPeerInfo for %@-%@ (%@) - is AKS ok?", SOSPeerGestaltGetName(gestalt), SOSCircleGetName(self.trustedCircle), error ? (void*)*error : (void*)CFSTR("-"));
- }
- else{
- secnotice("fpi", "alert KeychainSyncingOverIDSProxy the fpi is available");
- notify_post(kSecServerPeerInfoAvailable);
- if(deviceID)
- SOSFullPeerInfoUpdateDeviceID(self.fullPeerInfo, deviceID, error);
- }
}
else {
secerror("No full_key: %@:", error ? *error : NULL);
+(instancetype)trustClassic;
-
-//Security Properties
--(SOSSecurityPropertyResultCode) UpdateSecurityProperty:(SOSAccount*)account property:(CFStringRef)property code:(SOSSecurityPropertyActionCode)actionCode err:(CFErrorRef*)error;
--(SOSSecurityPropertyResultCode) SecurityPropertyStatus:(CFStringRef)property err:(CFErrorRef *)error;
-
//Gestalt Dictionary
-(bool) updateGestalt:(SOSAccount*)account newGestalt:(CFDictionaryRef) new_gestalt;
-(SOSViewResultCode) updateView:(SOSAccount*)account name:(CFStringRef) viewname code:(SOSViewActionCode) actionCode err:(CFErrorRef *)error;
-(SOSViewResultCode) viewStatus:(SOSAccount*)account name:(CFStringRef) viewname err:(CFErrorRef *)error;
-(bool) updateViewSets:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews;
+-(bool) updateViewSetsWithAnalytics:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews parentEvent:(NSData*)parentEvent;
+
-(CFSetRef) copyPeerSetForView:(CFStringRef) viewName;
//DER
#import "Security/SecureObjectSync/SOSPeerInfoV2.h"
#import "Security/SecureObjectSync/SOSPeerInfoCollections.h"
#import "Security/SecureObjectSync/SOSTransportMessageKVS.h"
-#import "Security/SecureObjectSync/SOSTransportMessageIDS.h"
#include <Security/SecureObjectSync/SOSAccountTransaction.h>
#include <Security/SecureObjectSync/SOSTransportCircleKVS.h>
}
--(SOSSecurityPropertyResultCode) UpdateSecurityProperty:(SOSAccount*)account property:(CFStringRef)property code:(SOSSecurityPropertyActionCode)actionCode err:(CFErrorRef*)error
-{
- SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError;
- bool updateCircle = false;
-
- require_action_quiet(self.trustedCircle, errOut, SOSCreateError(kSOSErrorNoCircle, CFSTR("No Trusted Circle"), NULL, error));
- require_action_quiet(self.fullPeerInfo, errOut, SOSCreateError(kSOSErrorPeerNotFound, CFSTR("No Peer for Account"), NULL, error));
- retval = SOSFullPeerInfoUpdateSecurityProperty(self.fullPeerInfo, actionCode, property, error);
-
- if(actionCode == kSOSCCSecurityPropertyEnable && retval == kSOSCCSecurityPropertyValid) {
- updateCircle = true;
- } else if(actionCode == kSOSCCSecurityPropertyDisable && retval == kSOSCCSecurityPropertyNotValid) {
- updateCircle = true;
- } else if(actionCode == kSOSCCSecurityPropertyPending) {
- updateCircle = true;
- }
-
- if (updateCircle) {
- [self modifyCircle:account.circle_transport err:NULL action:^(SOSCircleRef circle_to_change) {
- secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for security property change");
- return SOSCircleUpdatePeerInfo(circle_to_change, self.peerInfo);
- }];
- }
-
-errOut:
- return retval;
-}
-
--(SOSSecurityPropertyResultCode) SecurityPropertyStatus:(CFStringRef)property err:(CFErrorRef *)error
-{
- SOSSecurityPropertyResultCode retval = kSOSCCGeneralViewError;
- require_action_quiet(self.trustedCircle, errOut, SOSCreateError(kSOSErrorNoCircle, CFSTR("No Trusted Circle"), NULL, error));
- require_action_quiet(self.fullPeerInfo, errOut, SOSCreateError(kSOSErrorPeerNotFound, CFSTR("No Peer for Account"), NULL, error));
- retval = SOSFullPeerInfoSecurityPropertyStatus(self.fullPeerInfo, property, error);
-errOut:
- return retval;
-}
-
-(bool) updateGestalt:(SOSAccount*)account newGestalt:(CFDictionaryRef)new_gestalt
{
return true;
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-value"
-(SOSViewResultCode) updateView:(SOSAccount*)account name:(CFStringRef) viewname code:(SOSViewActionCode) actionCode err:(CFErrorRef *)error
{
SOSViewResultCode retval = kSOSCCGeneralViewError;
errOut:
return retval;
}
+#pragma clang diagnostic pop
-(bool) activeValidInCircle:(SOSAccount*) account err:(CFErrorRef *)error {
return SOSCircleHasActiveValidPeer(self.trustedCircle, SOSFullPeerInfoGetPeerInfo(self.fullPeerInfo), SOSAccountGetTrustedPublicCredential(account, error), error);
{
SOSViewResultCode retval = kSOSCCGeneralViewError;
+ require_action_quiet(SOSAccountGetTrustedPublicCredential(account, error), errOut, SOSCreateError(kSOSErrorNoKey, CFSTR("No Trusted UserKey"), NULL, error));
require_action_quiet(self.trustedCircle, errOut, SOSCreateError(kSOSErrorNoCircle, CFSTR("No Trusted Circle"), NULL, error));
require_action_quiet(self.fullPeerInfo, errOut, SOSCreateError(kSOSErrorPeerNotFound, CFSTR("No Peer for Account"), NULL, error));
require_action_quiet([self activeValidInCircle: account err: error ],
return retval;
}
+-(bool) updateViewSetsWithAnalytics:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews parentEvent:(NSData*)parentEvent
+{
+ bool retval = false;
+ bool updateCircle = false;
+ SOSPeerInfoRef pi = NULL;
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError];
+
+ SFSignInAnalytics *hasCompletedInitialSyncEvent = nil;
+ SFSignInAnalytics *updatePeerInCircleEvent = nil;
+
+ CFMutableSetRef enabledViews = NULL;
+ CFMutableSetRef disabledViews = NULL;
+ if(origEnabledViews) enabledViews = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, origEnabledViews);
+ if(origDisabledViews) disabledViews = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, origDisabledViews);
+ dumpViewSet(CFSTR("Enabled"), enabledViews);
+ dumpViewSet(CFSTR("Disabled"), disabledViews);
+
+ require_action_quiet(self.trustedCircle, errOut, secnotice("views", "Attempt to set viewsets with no trusted circle"));
+
+ // Make sure we have a peerInfo capable of supporting views.
+ SOSFullPeerInfoRef fpi = self.fullPeerInfo;
+ require_action_quiet(fpi, errOut, secnotice("views", "Attempt to set viewsets with no fullPeerInfo"));
+ require_action_quiet(enabledViews || disabledViews, errOut, secnotice("views", "No work to do"));
+
+ pi = SOSPeerInfoCreateCopy(kCFAllocatorDefault, SOSFullPeerInfoGetPeerInfo(fpi), NULL);
+
+ require_action_quiet(pi, errOut, secnotice("views", "Couldn't copy PeerInfoRef"));
+
+ if(!SOSPeerInfoVersionIsCurrent(pi)) {
+ CFErrorRef updateFailure = NULL;
+ require_action_quiet(SOSPeerInfoUpdateToV2(pi, &updateFailure), errOut,
+ (secnotice("views", "Unable to update peer to V2- can't update views: %@", updateFailure), (void) CFReleaseNull(updateFailure)));
+ secnotice("V2update", "Updating PeerInfo to V2 within SOSAccountUpdateViewSets");
+ updateCircle = true;
+ }
+
+ CFStringSetPerformWithDescription(enabledViews, ^(CFStringRef description) {
+ secnotice("viewChange", "Enabling %@", description);
+ });
+
+ CFStringSetPerformWithDescription(disabledViews, ^(CFStringRef description) {
+ secnotice("viewChange", "Disabling %@", description);
+ });
+
+ require_action_quiet(SOSAccountScreenViewListForValidV0(account, enabledViews, kSOSCCViewEnable), errOut, secnotice("viewChange", "Bad view change (enable) with kSOSViewKeychainV0"));
+ require_action_quiet(SOSAccountScreenViewListForValidV0(account, disabledViews, kSOSCCViewDisable), errOut, secnotice("viewChange", "Bad view change (disable) with kSOSViewKeychainV0"));
+
+ hasCompletedInitialSyncEvent = [parent newSubTaskForEvent:@"hasCompletedInitialSyncEvent"];
+ if(SOSAccountHasCompletedInitialSync(account)) {
+ if(enabledViews) updateCircle |= SOSViewSetEnable(pi, enabledViews);
+ if(disabledViews) updateCircle |= SOSViewSetDisable(pi, disabledViews);
+ retval = true;
+ } else {
+ //hold on to the views and enable them later
+ if(enabledViews) [self pendEnableViewSet:enabledViews];
+ if(disabledViews) SOSAccountPendDisableViewSet(account, disabledViews);
+ retval = true;
+ }
+ [hasCompletedInitialSyncEvent stopWithAttributes:nil];
+ if(updateCircle) {
+ /* UPDATE FULLPEERINFO VIEWS */
+ require_quiet(SOSFullPeerInfoUpdateToThisPeer(fpi, pi, NULL), errOut);
+ updatePeerInCircleEvent = [parent newSubTaskForEvent:@"updatePeerInCircleEvent"];
+ require_quiet([self modifyCircle:account.circle_transport err:NULL action:^(SOSCircleRef circle_to_change) {
+ secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for views or peerInfo change");
+ bool updated= SOSCircleUpdatePeerInfo(circle_to_change, self.peerInfo);
+ return updated;
+ }], errOut);
+ [updatePeerInCircleEvent stopWithAttributes:nil];
+ // Make sure we update the engine
+ account.circle_rings_retirements_need_attention = true;
+ }
+
+errOut:
+ [updatePeerInCircleEvent stopWithAttributes:nil];
+ CFReleaseNull(enabledViews);
+ CFReleaseNull(disabledViews);
+ CFReleaseNull(pi);
+ return retval;
+}
-(bool) updateViewSets:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews
{
bool retval = false;
if (!changeBlock) return;
SOSAccount* account = txn.account;
CFRetainSafe(ds_name);
- SOSAccountCircleMembershipChangeBlock block_to_register = ^void (SOSCircleRef new_circle,
+ SOSAccountCircleMembershipChangeBlock block_to_register = ^void (SOSAccount *account, SOSCircleRef new_circle,
CFSetRef added_peers, CFSetRef removed_peers,
CFSetRef added_applicants, CFSetRef removed_applicants) {
CFSetRef empty = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault);
if (self.trustedCircle && CFEqualSafe(ds_name, SOSCircleGetName(self.trustedCircle))) {
- block_to_register(self.trustedCircle, empty, empty, empty, empty);
+ block_to_register(account, self.trustedCircle, empty, empty, empty, empty);
}
CFReleaseSafe(empty);
}
{
CFMutableSetRef notMePeers = NULL;
CFMutableSetRef handledPeerIDs = NULL;
- CFMutableSetRef peersForIDS = NULL;
CFMutableSetRef peersForKVS = NULL;
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])
+ if(![account isInCircle:error])
{
handledPeerIDs = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs);
CFReleaseNull(notMePeers);
- CFReleaseNull(peersForIDS);
CFReleaseNull(peersForKVS);
return handledPeerIDs;
}
handledPeerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- peersForIDS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
peersForKVS = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
SOSPeerInfoRef myPeerInfo = account.peerInfo;
if(!myPeerInfo)
{
CFReleaseNull(notMePeers);
- CFReleaseNull(peersForIDS);
CFReleaseNull(peersForKVS);
return handledPeerIDs;
peerInfo = SOSCircleCopyPeerWithID(self.trustedCircle, peerID, NULL);
if (peerInfo && SOSCircleHasValidSyncingPeer(self.trustedCircle, peerInfo, account.accountKey, NULL)) {
- if (ENABLE_IDS && canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo)) {
- CFSetAddValue(peersForIDS, peerID);
- } else {
- CFSetAddValue(peersForKVS, peerID);
- }
+ CFSetAddValue(peersForKVS, peerID);
} else {
CFSetAddValue(handledPeerIDs, peerID);
}
}
CFReleaseNull(localError);
});
-
- CFSetRef handledIDSPeerIDs = SOSAccountSyncWithPeersOverIDS(txn, peersForIDS);
- CFSetUnion(handledPeerIDs, handledIDSPeerIDs);
- CFReleaseNull(handledIDSPeerIDs);
-
+
CFSetRef handledKVSPeerIDs = SOSAccountSyncWithPeersOverKVS(txn, peersForKVS);
CFSetUnion(handledPeerIDs, handledKVSPeerIDs);
CFReleaseNull(handledKVSPeerIDs);
SOSAccountConsiderLoggingEngineState(txn);
CFReleaseNull(notMePeers);
- CFReleaseNull(peersForIDS);
CFReleaseNull(peersForKVS);
return handledPeerIDs;
}
-(bool) requestSyncWithAllPeers:(SOSAccountTransaction*) txn key:(SecKeyRef)userPublic err:(CFErrorRef *)error
{
- if (![self isInCircle: error]) {
+ if (![txn.account isInCircle: error]) {
return false;
}
+++ /dev/null
-//
-// SOSAccountTrustOctagon_h
-// Security
-//
-
-#ifndef SOSAccountTrustOctagon_h
-#define SOSAccountTrustOctagon_h
-
-#import "Security/SecureObjectSync/SOSAccountTrust.h"
-
-#endif /* SOSAccountTrustOctagon_h */
+++ /dev/null
-//
-// SOSAccountTrustOctagon.m
-// Security
-//
-
-#import <Foundation/Foundation.h>
DifferenceAndCall(old_applicants, new_applicants, ^(CFSetRef added_applicants, CFSetRef removed_applicants) {
CFArrayForEach((__bridge CFArrayRef)(account.change_blocks), ^(const void * notificationBlock) {
secnotice("updates", "calling change block");
- ((__bridge SOSAccountCircleMembershipChangeBlock) notificationBlock)(newCircle, added_members, removed_members, added_applicants, removed_applicants);
+ ((__bridge SOSAccountCircleMembershipChangeBlock) notificationBlock)(account, newCircle, added_members, removed_members, added_applicants, removed_applicants);
});
});
});
SOSCircleRef circle = NULL;
SOSAccountTrustClassic* trust = account.trust;
circle = trust.trustedCircle;
- if (circle && [account.trust isInCircle:NULL] && SOSCircleHasActivePeerWithID(circle, peerID, NULL)) {
+ if (circle && [account isInCircle:NULL] && SOSCircleHasActivePeerWithID(circle, peerID, NULL)) {
SOSAccountUpdateOutOfSyncViews(aTxn, views);
}
}
bool changed = false;
SOSPeerInfoRef myPI = account.peerInfo;
require_quiet(myPI, done);
- require_quiet([account.trust isInCircle:NULL], done);
+ require_quiet([account isInCircle:NULL], done);
require_quiet(SOSAccountHasCompletedInitialSync(account), done);
CFMutableSetRef viewsToEnsure = SOSViewCopyViewSet(kViewSetAlwaysOn);
// Previous version PeerInfo if we were syncing legacy keychain, ensure we include those legacy views.
--- /dev/null
+//
+// SOSAuthKitHelpers.h
+// Security
+//
+
+#ifndef SOSAuthKitHelpers_h
+#define SOSAuthKitHelpers_h
+
+#include <Security/SecureObjectSync/SOSAccount.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SOSAuthKitHelpers : NSObject
++ (NSString * _Nullable)machineID;
++ (bool) updateMIDInPeerInfo: (SOSAccount *) account;
++ (bool) peerinfoHasMID: (SOSAccount *) account;
+
+// activeMIDs might block on network
++ (void)activeMIDs:(void(^_Nonnull)(NSSet * _Nullable activeMIDs, NSError * _Nullable error))complete;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+#endif /* SOSAuthKitHelpers_h */
--- /dev/null
+//
+// SOSAuthKitHelpers.m
+// Security
+//
+// Created by murf on 6/19/18.
+//
+
+#import <Foundation/Foundation.h>
+#import "SOSAuthKitHelpers.h"
+#import <utilities/debugging.h>
+#import <Security/SecureObjectSync/SOSAccount.h>
+#import <Security/SecureObjectSync/SOSAccountPriv.h>
+#import <Security/SecureObjectSync/SOSFullPeerInfo.h>
+#import <Security/SecureObjectSync/SOSPeerInfoV2.h>
+#import <Security/SecureObjectSync/SOSPeerInfoPriv.h>
+
+#if !TARGET_OS_BRIDGE && !TARGET_OS_SIMULATOR
+#import <AppleAccount/AppleAccount_Private.h>
+#import <AuthKit/AuthKit.h>
+#import <AuthKit/AuthKit_Private.h>
+
+#define SUPPORT_MID 1
+#endif
+
+@implementation SOSAuthKitHelpers
+
+#if SUPPORT_MID
+
+SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit);
+SOFT_LINK_FRAMEWORK(Frameworks, Accounts);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wstrict-prototypes"
+SOFT_LINK_CLASS(AuthKit, AKAccountManager);
+SOFT_LINK_CLASS(AuthKit, AKAnisetteProvisioningController);
+SOFT_LINK_CLASS(AuthKit, AKAppleIDAuthenticationController);
+SOFT_LINK_CLASS(AuthKit, AKDeviceListRequestContext);
+SOFT_LINK_CLASS(Accounts, Accounts);
+SOFT_LINK_CLASS(Accounts, ACAccountStore);
+SOFT_LINK_CONSTANT(AuthKit, AKServiceNameiCloud, const NSString *);
+#pragma clang diagnostic pop
+
+
+
++ (NSString *) machineID {
+ NSError *error = nil;
+ NSString *retval = nil;
+ secnotice("sosauthkit", "Entering machineID");
+
+ AKAnisetteProvisioningController *anisetteController = [getAKAnisetteProvisioningControllerClass() new];
+ if(anisetteController) {
+ AKAnisetteData *anisetteData = [anisetteController anisetteDataWithError:&error];
+ if (anisetteData) {
+ retval = [anisetteData.machineID copy];
+ if(retval) {
+ secnotice("sosauthkit", "machineID is %@", retval);
+ } else {
+ secnotice("sosauthkit", "Failed to get machineID");
+ }
+ } else {
+ secnotice("sosauthkit", "can't get mID: %@", error);
+ }
+ } else {
+ secnotice("sosauthkit", "can't get controller");
+ }
+ return retval;
+}
+
++ (bool) peerinfoHasMID: (SOSAccount *) account {
+ SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(account.fullPeerInfo);
+ if(!pi) return false;
+ return SOSPeerInfoV2DictionaryHasString(pi, sMachineIDKey);
+}
+
++ (bool) updateMIDInPeerInfo: (SOSAccount *) account {
+ NSString *mid = [SOSAuthKitHelpers machineID];
+ if(!mid) return true;
+ CFErrorRef error = NULL;
+ SOSAccountSetValue(account, sMachineIDKey, (__bridge CFStringRef)mid, &error);
+ bool peerUpdated = SOSAccountUpdatePeerInfoAndPush(account, CFSTR("Add Machine ID"), &error, ^bool(SOSPeerInfoRef pi, CFErrorRef *error) {
+ if(SOSPeerInfoV2DictionaryHasString(pi, sMachineIDKey)) {
+ return false;
+ }
+ secnotice("sosauthkit", "Setting PeerInfo MID to %@", mid);
+ SOSPeerInfoV2DictionarySetValue(pi, sMachineIDKey, (__bridge CFStringRef)mid);
+ return true;
+ });
+ if(!peerUpdated) {
+ secnotice("sosauthkit", "Failed to record MID in PeerInfo: %@", error);
+ }
+ CFReleaseNull(error);
+ return peerUpdated;
+}
+
++ (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete {
+ AKDeviceListRequestContext *context;
+ ACAccount *primaryAccount;
+
+ ACAccountStore *store = [getACAccountStoreClass() new];
+ if(!store) {
+ complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get store"}]);
+ return;
+ }
+ primaryAccount = [store aa_primaryAppleAccount];
+ if(!primaryAccount) {
+ secnotice("sosauthkit", "can't get account");
+ complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"no primary account"}]);
+ return;
+ }
+
+ context = [getAKDeviceListRequestContextClass() new];
+ if (context == NULL) {
+ complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get AKDeviceListRequestContextClass"}]);
+ return;
+ }
+ context.altDSID = primaryAccount.aa_altDSID;
+ context.services = @[ getAKServiceNameiCloud() ];
+
+ AKAppleIDAuthenticationController *authController = [getAKAppleIDAuthenticationControllerClass() new];
+ if(!authController) {
+ complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get authController"}]);
+ return;
+ }
+
+ [authController fetchDeviceListWithContext:context completion:^(NSArray<AKRemoteDevice *> *deviceList, NSError *error) {
+ NSMutableSet *mids = [[NSMutableSet alloc] init];
+ if (deviceList != nil) {
+ for (AKRemoteDevice *device in deviceList) {
+ [mids addObject:device.machineId];
+ }
+ } else {
+ secnotice("sosauthkit", "got no mIDs: %@", error);
+ }
+ if([mids count] == 0) {
+ secnotice("sosauthkit", "found not devices in account");
+ mids = nil;
+ }
+
+ complete(mids, error);
+ }];
+}
+
+
+#else /* TARGET_OS_BRIDGE || TARGET_OS_SIMULATOR */
+
++ (NSString *) machineID {
+ return nil;
+}
+
++ (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete {
+ complete(NULL, NULL);
+}
+
++ (bool) updateMIDInPeerInfo: (SOSAccount *) account {
+ return true;
+}
+
++ (bool) peerinfoHasMID: (SOSAccount *) account {
+ return false;
+}
+
+#endif
+
+@end
+
}
int SOSBSKBCountPeers(SOSBackupSliceKeyBagRef backupSliceKeyBag) {
- return (int) CFSetGetCount(backupSliceKeyBag->peers);
+ return (backupSliceKeyBag->peers) ? (int) CFSetGetCount(backupSliceKeyBag->peers): 0;
}
bool SOSBSKBPeerIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, SOSPeerInfoRef pi) {
}
bool SOSBSKBHasRecoveryKey(SOSBackupSliceKeyBagRef bskb) {
+ if(!bskb) return false;
if(SOSBSKBHasPrefixedKey(bskb, bskbRkbgPrefix)) return true;
// old way for RecoveryKeys
- int keyCount = (int) CFDictionaryGetCount(bskb->wrapped_keys);
+ int keyCount = (bskb->wrapped_keys != NULL) ? (int) CFDictionaryGetCount(bskb->wrapped_keys): 0;
int peerCount = SOSBSKBCountPeers(bskb);
return !SOSBSKBIsDirect(bskb) && ((keyCount - peerCount) > 0);
}
void * a_digest = (void * )array_digest;
ccdigest_init(di, array_digest);
- CFArraySortValues(array, CFRangeMake(0, CFArrayGetCount(array)), SOSPeerInfoCompareByID, SOSPeerCmpPubKeyHash);
+ CFArraySortValues(array, CFRangeMake(0, CFArrayGetCount(array)), SOSPeerInfoCompareByID, (void *)SOSPeerCmpPubKeyHash);
CFArrayForEach(array, ^(const void *peer) {
if (!SOSPeerInfoUpdateDigestWithPublicKeyBytes((SOSPeerInfoRef)peer, di, a_digest, error))
success = false;
}
static bool SOSCircleHashNextGenWithAdditionalPeer(const struct ccdigest_info *di, SOSCircleRef circle, SOSPeerInfoRef additionalPeer, void *hash_result, CFErrorRef *error) {
+ bool result = false;
CFMutableSetRef peers = CFSetCreateMutableCopy(NULL, 0, circle->peers);
CFSetAddValue(peers, additionalPeer);
SOSGenCountRef nextGen = SOSGenerationIncrementAndCreate(circle->generation);
- return SOSCircleHashGenAndPeers(di, nextGen, peers, hash_result, error);
+ result = SOSCircleHashGenAndPeers(di, nextGen, peers, hash_result, error);
+
+ CFReleaseNull(nextGen);
+ CFReleaseNull(peers);
+
+ return result;
}
bool SOSCircleSetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFDataRef signature, CFErrorRef *error) {
bool SOSCircleVerifySignatureExists(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error) {
if(!pubKey) {
- // TODO ErrorRef
secerror("SOSCircleVerifySignatureExists no pubKey");
SOSCreateError(kSOSErrorBadFormat, CFSTR("SOSCircleVerifySignatureExists no pubKey"), (error != NULL) ? *error : NULL, error);
return false;
return NULL != signature;
}
+CFStringRef SOSCircleCopyHashString(SOSCircleRef circle) {
+ const struct ccdigest_info *di = ccsha256_di();
+ uint8_t hash_result[di->output_size];
+ SOSCircleHash(di, circle, hash_result, NULL);
+ return SOSCopyHashBufAsString(hash_result, sizeof(hash_result));
+}
+
bool SOSCircleVerify(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error) {
const struct ccdigest_info *di = ccsha256_di();
uint8_t hash_result[di->output_size];
CFDataGetBytePtr(signature), CFDataGetLength(signature)), error, CFSTR("Signature verification failed."));;
}
+bool SOSCircleVerifyPeerSignatureExists(SOSCircleRef circle, SOSPeerInfoRef peer) {
+ bool result = false;
+ SecKeyRef pub_key = SOSPeerInfoCopyPubKey(peer, NULL);
+ require_quiet(pub_key, fail);
+ result = SOSCircleVerifySignatureExists(circle, pub_key, NULL);
+fail:
+ CFReleaseSafe(pub_key);
+ return result;
+}
+
bool SOSCircleVerifyPeerSigned(SOSCircleRef circle, SOSPeerInfoRef peer, CFErrorRef *error) {
bool result = false;
SecKeyRef pub_key = SOSPeerInfoCopyPubKey(peer, error);
require_quiet(pub_key, fail);
-
+
result = SOSCircleVerify(circle, pub_key, error);
fail:
CFReleaseSafe(pub_key);
static inline void logPeerInfo(char *category, SOSCircleRef circle, SecKeyRef pubKey, CFStringRef myPID, SOSPeerInfoRef peer) {
char sigchr = 'v';
- if (SOSCircleVerifyPeerSigned(circle, peer, NULL)) {
+ if (SOSCircleVerifyPeerSignatureExists(circle, peer)) {
sigchr = 'V';
}
SOSPeerInfoLogState(category, peer, pubKey, myPID, sigchr);
if(!circle) return;
CFStringRef genString = SOSGenerationCountCopyDescription(SOSCircleGetGeneration(circle));
char sigchr = 'v';
- if(pubKey && SOSCircleVerify(circle, pubKey, NULL)) {
+ if(pubKey && SOSCircleVerifySignatureExists(circle, pubKey, NULL)) {
sigchr = 'V';
}
secnotice(category, "CIRCLE: [%20@] UserSigned: %c", genString, sigchr);
SOSCircleRef SOSCircleCreateFromData(CFAllocatorRef allocator, CFDataRef circleData, CFErrorRef *error);
SOSCircleRef SOSCircleCopyCircle(CFAllocatorRef allocator, SOSCircleRef otherCircle, CFErrorRef *error);
+CFStringRef SOSCircleCopyHashString(SOSCircleRef circle);
+
bool SOSCircleSetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFDataRef signature, CFErrorRef *error);
CFDataRef SOSCircleGetSignature(SOSCircleRef circle, SecKeyRef pubkey, CFErrorRef *error);
CFDictionaryRef SOSCircleCopyAllSignatures(SOSCircleRef circle);
bool SOSCircleSign(SOSCircleRef circle, SecKeyRef privkey, CFErrorRef *error);
bool SOSCircleVerifySignatureExists(SOSCircleRef circle, SecKeyRef pubKey, CFErrorRef *error);
+bool SOSCircleVerifyPeerSignatureExists(SOSCircleRef circle, SOSPeerInfoRef peer);
bool SOSCircleVerify(SOSCircleRef circle, SecKeyRef pubkey, CFErrorRef *error);
bool SOSCircleVerifyPeerSigned(SOSCircleRef circle, SOSPeerInfoRef peer, CFErrorRef *error);
#include <Security/SecureObjectSync/SOSTypes.h>
#include <Security/SecureObjectSync/SOSPeerInfo.h>
+#import <Security/SFSignInAnalytics.h>
__BEGIN_DECLS
*/
bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error);
+bool SOSCCSetUserCredentialsAndDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentevent, CFErrorRef *error);
/*!
@function SOSCCTryUserCredentials
*/
bool SOSCCTryUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error);
-/*!
- @function SOSCCCopyDeviceID
- @abstract Retrieves this device's IDS device ID
- @param error What went wrong if we returned false
- */
-CFStringRef SOSCCCopyDeviceID(CFErrorRef* error);
-
-/*!
- @function SOSCCSetDeviceID
- @abstract Sets this device's IDS device ID
- @param IDS The ID to set
- @param error What went wrong if we returned false
- */
-bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error);
/*!
@function SOSCCRegisterUserCredentials
@return if we waited successfully
*/
bool SOSCCWaitForInitialSync(CFErrorRef* error);
+bool SOSCCWaitForInitialSyncWithAnalytics(CFDataRef parentEvent, CFErrorRef* error);
/*!
@function SOSCCCopyYetToSyncViewsList
*/
SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef* error);
+/*!
+ @function SOSCCThisDeviceIsInCircleNonCached
+ @abstract Finds and returns if this devices status in the user's circle. This call is added explicitly for CDP.
+ @param error What went wrong if we returned kSOSCCError.
+ @result kSOSCCInCircle if we're in the circle.
+ @discussion If we have an error figuring out if we're in the circle we return false and the error.
+ */
+SOSCCStatus SOSCCThisDeviceIsInCircleNonCached(CFErrorRef* error);
+
/*!
@function SOSCCIsIcloudKeychainSyncing
@abstract determines whether baseline keychain syncing is occuring (V0/V2)
@discussion Requests to join the user's circle or all the pending circles (other than his) if there are multiple pending circles.
*/
bool SOSCCRequestToJoinCircle(CFErrorRef* error);
+bool SOSCCRequestToJoinCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error);
+
/*!
@function SOSCCRequestToJoinCircleAfterRestore
@discussion Uses the cloud identity to get in the circle if it can. If it cannot it falls back on simple application.
*/
bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error);
+bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(CFDataRef parentEvent, CFErrorRef* error);
/*!
@function SOSCCRequestEnsureFreshParameters
@result true if we posted the circle successfully. False if there was an error.
*/
bool SOSCCResetToEmpty(CFErrorRef* error);
+bool SOSCCResetToEmptyWithAnalytics(CFDataRef parentEvent, CFErrorRef* error);
/*!
@function SOSCCRemoveThisDeviceFromCircle
*/
bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error);
+bool SOSCCRemoveThisDeviceFromCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error);
+
/*!
@function SOSCCRemoveThisDeviceFromCircle
@abstract Removes a list of peers from the circle.
that we don't have the user credentail (need to prompt for password)
*/
bool SOSCCRemovePeersFromCircle(CFArrayRef peerList, CFErrorRef* error);
+bool SOSCCRemovePeersFromCircleWithAnalytics(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error);
/*!
@function SOSCCRemoveThisDeviceFromCircle
*/
CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error);
-/*!
- @function SOSCCCheckPeerAvailability
- @abstract Prompts KeychainSyncingOverIDSProxy to query all devices in the circle with the same view.
- @param error What went wrong.
- @result true if the operation succeeded, otherwise false.
- */
-bool SOSCCCheckPeerAvailability(CFErrorRef *error);
-
/*
* Return values for SOSCCGetLastDepartureReason
*/
extern const CFStringRef kCKKSViewAutoUnlock;
extern const CFStringRef kCKKSViewHealth;
extern const CFStringRef kCKKSViewApplePay;
+extern const CFStringRef kCKKSViewHome;
/*!
*/
bool SOSCCViewSet(CFSetRef enabledviews, CFSetRef disabledviews);
-
+bool SOSCCViewSetWithAnalytics(CFSetRef enabledviews, CFSetRef disabledviews, CFDataRef parentEvent);
/*
Security Attributes for PeerInfos
Initial View List - To be expanded
*/
-extern const CFStringRef kSOSSecPropertyHasEntropy;
-extern const CFStringRef kSOSSecPropertyScreenLock;
-extern const CFStringRef kSOSSecPropertySEP;
-extern const CFStringRef kSOSSecPropertyIOS;
-
-
-/*!
- @function SOSCCSecurityProperty
- @abstract Enable, disable or query status of a SecurityProperty for this peer.
- @param property The SecurityProperty for which the action should be performed.
- @param action The action code to take with the SecurityProperty
- @param error More description of the error if one occurred.
- @discussion
- For all actions any error return can fallback to kSOSCCGeneralSecurityPropertyError.
- For kSOSCCSecurityPropertyEnable actions other possible return codes are:
- kSOSCCSecurityPropertyValid if the operation was successful and the peer's SecurityProperty is valid
- kSOSCCSecurityPropertyNotValid if the operation was unsuccessful
- kSOSCCSecurityPropertyNotQualified if the device can't support prerequisite security capabilities
- kSOSCCNoSuchSecurityProperty if the CFStringRef doesn't match one of the known SecurityProperties
-
- For kSOSCCSecurityPropertyDisable actions other possible return codes are:
- kSOSCCSecurityPropertyNotMember for successfully disabling the SecurityProperty
- kSOSCCNoSuchSecurityProperty if the CFStringRef doesn't match one of the known SecurityProperties
-
- For kSOSCCSecurityPropertyQuery actions other possible return codes are:
- kSOSCCSecurityPropertyValid or kSOSCCDSNotValidMember for successful querying of the status for a SecurityProperty for this peer
- kSOSCCNoSuchSecurityProperty if the CFStringRef doesn't match one of the known SecurityProperties
-
- */
-
-SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error);
//
// Backup APIs
}
SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error)
+{
+ SOSCCStatus retval = SOSGetCachedCircleStatus(error);
+ if(retval != kSOSNoCachedValue) {
+ secnotice("circleOps", "Retrieved cached circle value %d", retval);
+ return retval;
+ }
+ return SOSCCThisDeviceIsInCircleNonCached(error);
+}
+
+
+SOSCCStatus SOSCCThisDeviceIsInCircleNonCached(CFErrorRef *error)
{
sec_trace_enter_api(NULL);
sec_trace_return_api(SOSCCStatus, ^{
SOSCCStatus result = kSOSCCError;
-
+
do_if_registered(soscc_ThisDeviceIsInCircle, error);
-
+
xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, 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_INT64)) {
result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
} else {
result = kSOSCCError;
}
-
+
if (result < 0) {
if (response && securityd_message_no_error(response, error))
{
}
}
}
-
+ secnotice("circleOps", "Retrieved non-cached circle value %d", result);
+
return result;
}, CFSTR("SOSCCStatus=%d"))
}
+static bool sfsigninanalytics_bool_error_request(enum SecXPCOperation op, CFDataRef parentEvent, CFErrorRef* error)
+{
+ __block bool result = false;
+
+ secdebug("sosops","enter - operation: %d", op);
+ securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+ return SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
+ }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+ result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+ return result;
+ });
+ return result;
+}
+
static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
{
__block bool result = false;
return result;
}
-static bool deviceid_to_bool_error_request(enum SecXPCOperation op,
- CFStringRef IDS,
- CFErrorRef* error)
-{
- __block bool result = false;
-
- securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
- CFStringPerformWithCString(IDS, ^(const char *utf8Str) {
- xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
- });
- return true;
- }, ^bool(xpc_object_t response, CFErrorRef *error) {
- result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
- return result;
- });
-
- return result;
-}
-
static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
{
__block bool result = false;
return result;
}
+static bool info_array_data_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFDataRef parentEvent, CFErrorRef* error)
+{
+ __block bool result = false;
+
+ secdebug("sosops", "enter - operation: %d", op);
+ securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+ SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
+ xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
+ if (encoded_peers)
+ xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers);
+ return encoded_peers != NULL;
+ }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+ result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+ return result;
+ });
+ return result;
+}
+
static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
uint64_t number,
CFErrorRef* error)
}, NULL)
}
+bool SOSCCRequestToJoinCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
+{
+ sec_trace_enter_api(NULL);
+ sec_trace_return_bool_api(^{
+ do_if_registered(soscc_RequestToJoinCircleWithAnalytics, parentEvent, error);
+
+ return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinWithAnalytics, parentEvent, error);
+ }, NULL)
+}
+
bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
{
sec_trace_enter_api(NULL);
}, NULL)
}
+bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
+{
+ sec_trace_enter_api(NULL);
+ sec_trace_return_bool_api(^{
+ do_if_registered(soscc_RequestToJoinCircleAfterRestoreWithAnalytics, parentEvent, error);
+
+ return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinAfterRestoreWithAnalytics, parentEvent, error);
+ }, NULL)
+}
+
bool SOSCCAccountHasPublicKey(CFErrorRef *error)
{
-
+ // murfxx
sec_trace_enter_api(NULL);
sec_trace_return_bool_api(^{
do_if_registered(soscc_AccountHasPublicKey, error);
}, NULL)
}
+bool SOSCCWaitForInitialSyncWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
+{
+ sec_trace_enter_api(NULL);
+ sec_trace_return_bool_api(^{
+ do_if_registered(soscc_WaitForInitialSyncWithAnalytics, parentEvent, error);
+
+ return sfsigninanalytics_bool_error_request(kSecXPCOpWaitForInitialSyncWithAnalytics, parentEvent, error);
+ }, NULL)
+}
+
bool SOSCCWaitForInitialSync(CFErrorRef* error)
{
sec_trace_enter_api(NULL);
}, NULL)
}
+bool SOSCCResetToEmptyWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
+{
+ secwarning("SOSCCResetToEmptyWithAnalytics called");
+ sec_trace_enter_api(NULL);
+ sec_trace_return_bool_api(^{
+ do_if_registered(soscc_ResetToEmptyWithAnalytics, parentEvent, error);
+
+ return sfsigninanalytics_bool_error_request(kSecXPCOpResetToEmptyWithAnalytics, parentEvent, error);
+ }, NULL)
+}
bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error)
{
sec_trace_enter_api(NULL);
}, NULL)
}
+bool SOSCCRemovePeersFromCircleWithAnalytics(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error)
+{
+ sec_trace_enter_api(NULL);
+ sec_trace_return_bool_api(^{
+ do_if_registered(soscc_RemovePeersFromCircleWithAnalytics, peers, parentEvent, error);
+
+ return info_array_data_to_bool_error_request(kSecXPCOpRemovePeersFromCircleWithAnalytics, peers, parentEvent, error);
+ }, NULL)
+}
+
+bool SOSCCRemoveThisDeviceFromCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
+{
+ sec_trace_enter_api(NULL);
+ sec_trace_return_bool_api(^{
+ do_if_registered(soscc_RemoveThisDeviceFromCircleWithAnalytics, parentEvent, error);
+
+ return sfsigninanalytics_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics, parentEvent, error);
+ }, NULL)
+}
+
bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
{
sec_trace_enter_api(NULL);
static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
CFStringRef user_label, CFDataRef user_password,
- CFStringRef dsid, CFErrorRef* error)
+ CFStringRef dsid, CFDataRef parentEvent, CFErrorRef* error)
{
__block bool result = false;
xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
});
xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
- return true;
- }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
- result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
- return result;
- });
-
- return result;
-}
-
-static bool cfstring_to_bool_error_request(enum SecXPCOperation op,
- CFStringRef string,
- CFErrorRef* error)
-{
- __block bool result = false;
-
- securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
- CFStringPerformWithCString(string, ^(const char *utf8Str) {
- xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
- });
- return true;
- }, ^bool(xpc_object_t response, CFErrorRef *error) {
- result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
- return result;
- });
-
- return result;
-}
-
-static int idsDict_to_int_error_request(enum SecXPCOperation op,
- CFDictionaryRef IDS,
- CFErrorRef* error)
-{
- __block int result = 0;
-
- securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
- SecXPCDictionarySetPListOptional(message, kSecXPCKeyIDSMessage, IDS, error);
- return true;
- }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
- int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
- if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
- result = (int)temp_result;
+ if(parentEvent){
+ SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
}
return true;
- });
-
- return result;
-}
-
-static bool idsData_peerID_to_bool_error_request(enum SecXPCOperation op, CFStringRef peerID,
- CFDataRef IDSMessage,
- CFErrorRef* error)
-{
- __block bool result = 0;
-
- securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
- SecXPCDictionarySetData(message, kSecXPCKeyIDSMessage, IDSMessage, error);
- SecXPCDictionarySetString(message, kSecXPCKeyDeviceID, peerID, error);
- return true;
- }, ^bool(xpc_object_t response, CFErrorRef *error) {
- result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
- return result;
- });
- return result;
-}
-
-static bool idscommand_to_bool_error_request(enum SecXPCOperation op,
- CFStringRef idsMessage,
- CFErrorRef* error)
-{
- __block bool result = false;
-
- securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
- CFStringPerformWithCString(idsMessage, ^(const char *utf8Str) {
- xpc_dictionary_set_string(message, kSecXPCKeySendIDSMessage, utf8Str);
- });
- return true;
}, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
return result;
if(account_dsid == NULL){
account_dsid = CFSTR("");
}
- return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, error);
+ return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, nil, error);
out:
return result;
}, NULL)
}
-
-bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error)
-{
- secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS);
- sec_trace_enter_api(NULL);
- sec_trace_return_bool_api(^{
- do_if_registered(soscc_SetDeviceID, IDS, error);
- bool result = cfstring_to_bool_error_request(kSecXPCOpSetDeviceID, IDS, error);
- return result;
- }, NULL)
-}
-
-bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error)
-{
- secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
- sec_trace_enter_api(NULL);
- sec_trace_return_bool_api(^{
- do_if_registered(soscc_CheckIDSRegistration, message, error);
- return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage, message, error);
- }, NULL)
-}
-
-bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error)
-{
- secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
- sec_trace_enter_api(NULL);
- sec_trace_return_bool_api(^{
- do_if_registered(soscc_PingTest, message, error);
- return idscommand_to_bool_error_request(kSecXPCOpPingTest, message, error);
- }, NULL)
-}
-
-bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error)
+bool SOSCCSetUserCredentialsAndDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error)
{
- secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
- sec_trace_enter_api(NULL);
+ secnotice("circleOps", "SOSCCSetUserCredentialsAndDSIDWithAnalytics for %@\n", user_label);
+ sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
sec_trace_return_bool_api(^{
- do_if_registered(soscc_GetIDSIDFromIDS, error);
- return simple_bool_error_request(kSecXPCOpIDSDeviceID, error);
- }, NULL)
-}
-
-HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error)
-{
- secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS);
- sec_trace_enter_api(NULL);
- sec_trace_return_api(HandleIDSMessageReason, ^{
- do_if_registered(soscc_HandleIDSMessage, IDS, error);
- return (HandleIDSMessageReason) idsDict_to_int_error_request(kSecXPCOpHandleIDSMessage, IDS, error);
- }, NULL)
-}
+ do_if_registered(soscc_SetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, dsid, parentEvent, error);
-bool SOSCCClearPeerMessageKeyInKVS(CFStringRef peerID, CFErrorRef *error)
-{
- secnotice("sosops", "SOSCCClearPeerMessageKeyInKVS!! %@\n", peerID);
- sec_trace_enter_api(NULL);
- sec_trace_return_bool_api(^{
- do_if_registered(socc_clearPeerMessageKeyInKVS, peerID, error);
- return cfstring_to_bool_error_request(kSecXPCOpClearKVSPeerMessage, peerID, error);
- }, NULL)
+ 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")));
-bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error)
-{
- secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVSUsingIDOnly!! %@\n", peerID);
- sec_trace_enter_api(NULL);
- sec_trace_return_bool_api(^{
- do_if_registered(soscc_requestSyncWithPeerOverKVSIDOnly, peerID, error);
- return deviceid_to_bool_error_request(kSecXPCOpSyncWithKVSPeerIDOnly, peerID, error);
- }, NULL)
-}
+ if(account_dsid == NULL){
+ account_dsid = CFSTR("");
+ }
+ return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, account_dsid, parentEvent, error);
+ out:
+ return result;
-bool SOSCCRequestSyncWithPeerOverKVS(CFStringRef peerID, CFDataRef message, CFErrorRef *error)
-{
- secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVS!! %@\n", peerID);
- sec_trace_enter_api(NULL);
- sec_trace_return_bool_api(^{
- do_if_registered(soscc_requestSyncWithPeerOverKVS, peerID, message, error);
- return idsData_peerID_to_bool_error_request(kSecXPCOpSyncWithKVSPeer, peerID, message, error);
}, NULL)
}
account_dsid = CFSTR("");
}
- return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, error);
+ return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, nil, error);
out:
return result;
}, NULL)
}
-CFStringRef SOSCCCopyDeviceID(CFErrorRef* error)
-{
- sec_trace_enter_api(NULL);
- sec_trace_return_api(CFStringRef, ^{
- do_if_registered(soscc_CopyDeviceID, error);
- CFStringRef deviceID = simple_cfstring_error_request(kSecXPCOpRequestDeviceID, error);
- return deviceID;
- }, NULL)
-}
-
bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
sec_trace_enter_api(NULL);
}
SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
+ if(actionCode == kSOSCCViewQuery) {
+ uint64_t circleStat = SOSGetCachedCircleBitmask();
+ if(circleStat & CC_STATISVALID) {
+ SOSViewResultCode retval = kSOSCCViewNotMember;
+ CFSetRef enabledViews = SOSCreateCachedViewStatus();
+ if(enabledViews) {
+ if(CFSetContainsValue(enabledViews, view)) {
+ retval = kSOSCCViewMember;
+ } else {
+ retval = kSOSCCViewNotMember;
+ }
+ CFReleaseNull(enabledViews);
+ }
+ return retval;
+ }
+ }
sec_trace_enter_api(NULL);
sec_trace_return_api(SOSViewResultCode, ^{
do_if_registered(soscc_View, view, actionCode, error);
}, NULL)
}
-SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode actionCode, CFErrorRef *error) {
+bool SOSCCViewSetWithAnalytics(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent) {
+ CFErrorRef *error = NULL;
+ __block bool result = false;
+
sec_trace_enter_api(NULL);
- sec_trace_return_api(SOSSecurityPropertyResultCode, ^{
- SOSSecurityPropertyResultCode result = kSOSCCGeneralSecurityPropertyError;
- do_if_registered(soscc_SecurityProperty, property, actionCode, error);
- xpc_object_t message = securityd_create_message(kSecXPCOpSecurityProperty, error);
- if (message) {
- int64_t bigac = actionCode;
- xpc_dictionary_set_string(message, kSecXPCKeyViewName, CFStringGetCStringPtr(property, kCFStringEncodingUTF8));
- xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, bigac);
-
- xpc_object_t response = securityd_message_with_reply_sync(message, error);
-
- if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
- result = (SOSSecurityPropertyResultCode) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
- }
-
- if (result == kSOSCCGeneralSecurityPropertyError) {
- if (response && securityd_message_no_error(response, error)) {
- char *desc = xpc_copy_description(response);
- SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
- free((void *)desc);
- }
- }
- if(response)
- response = nil;
- if(message)
- message = nil;
- }
-
- return result;
- }, CFSTR("SOSSecurityPropertyResultCode=%d"))
+ sec_trace_return_bool_api(^{
+ do_if_registered(soscc_ViewSetWithAnalytics, enabledViews, disabledViews, parentEvent);
+ return securityd_send_sync_and_do(kSecXPCOpViewSetWithAnalytics, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+ xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
+ xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
+ if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
+ if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
+ if(parentEvent) SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
+ return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
+ }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
+ result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
+ return result;
+ });
+ }, NULL)
}
static CFStringRef copyViewNames(size_t n, CFStringRef *views) {
}
if(retval == true) {
+ //murfxx
+ // use cached values if valid
+ uint64_t circleStat = SOSGetCachedCircleBitmask();
+ if(circleStat & CC_STATISVALID) {
+ CFSetRef enabledViews = SOSCreateCachedViewStatus();
+ if(enabledViews) {
+ for(size_t i = 0; i < n; i++) {
+ if(!CFSetContainsValue(enabledViews, views[i])) {
+ retval = false;
+ }
+ }
+ CFReleaseNull(enabledViews);
+ CFReleaseNull(viewString);
+ return retval;
+ }
+ }
+
+ // make the individual calls otherwise.
for(size_t i = 0; i < n; i++) {
SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, &error);
if(vstatus != kSOSCCViewMember) {
}, CFSTR("return=%@"))
}
-bool SOSCCCheckPeerAvailability(CFErrorRef *error){
- secnotice("peer", "enter SOSCCCheckPeerAvailability");
- sec_trace_enter_api(NULL);
- sec_trace_return_bool_api(^{
- do_if_registered(soscc_PeerAvailability, error);
-
- return simple_bool_error_request(kSecXPCOpCheckPeerAvailability, error);
- }, NULL)
-
-}
-
-
bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error) {
sec_trace_enter_api(NULL);
sec_trace_return_bool_api(^{
bool SOSCCAccountHasPublicKey(CFErrorRef *error);
bool SOSCCAccountIsNew(CFErrorRef *error);
-/*!
- @function SOSCCHandleIDSMessage
- @abstract Handles an IDS message from KeychainSyncingOverIDSProxy
- @param IDS The incoming IDS message
- @param error What went wrong if we returned false
- */
-HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error);
-
/*!
@function SOSCCProcessSyncWithPeers
@abstract Returns the peers for whom we handled syncing from the list send to us.
*/
SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error);
-/*!
- @function SOSCCIDSServiceRegistrationTest
- @abstract Attempts to send a message over IDS to test IDS service set up
- @param message The message to send over IDS
- @param error What went wrong if we returned false
- */
-bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error);
-
-/*!
- @function SOSCCIDSPingTest
- @abstract Attempts to ping devices within an IDS Account, check device availability
- @param message The message to send over IDS
- @param error What went wrong if we returned false
- */
-bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error);
-
-/*!
- @function SOSCCIDSDeviceIDIsAvailableTest
- @abstract Attempts to communicate with KeychainSyncingOverIDSProxy to retrieve the device ID using IDS framework
- @param error What went wrong if we returned false
- */
-bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error);
-
/*!
@function SOSWrapToBackupSliceKeyBagForView
@abstract Encrypts the given plaintext, and wraps the encryption key to the backup slice keybag for this view
bool SOSCCDeleteAccountState(CFErrorRef *error);
CFDataRef SOSCCCopyEngineData(CFErrorRef* error);
bool SOSCCDeleteEngineState(CFErrorRef *error);
-bool SOSCCRequestSyncWithPeerOverKVS( CFStringRef peerID, CFDataRef message, CFErrorRef *error);
-bool SOSCCClearPeerMessageKeyInKVS(CFStringRef peerID, CFErrorRef *error);
CFDataRef SOSCCCopyRecoveryPublicKey(CFErrorRef *error);
CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error);
-bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error);
bool SOSCCTestPopulateKVSWithBadKeys(CFErrorRef *error);
CFDataRef SOSCCCopyInitialSyncData(CFErrorRef *error);
[self.account kvsPerformanceCounters:reply];
}
-- (void)idsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply
-{
- [self.account idsPerformanceCounters:reply];
-}
-
- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary <NSString *, NSString *> *))reply
{
[self.account rateLimitingPerformanceCounters:reply];
dest += prev - source;
// 2) Skip remaining dupes
if (cur < end) {
- while (cur += SOSDigestSize, cur < end) {
+ cur += SOSDigestSize;
+ while (cur < end) {
int delta = SOSDigestCompare(prev, cur);
assert(delta <= 0);
- if (delta != 0)
+ if (delta != 0) {
break;
+ }
+ cur += SOSDigestSize;
}
}
// cur now points to the first new element that hasn't yet been copied
return der;
}
+#pragma clang diagnostic push
+#pragma clang diagnostic fatal "-Wshadow"
static bool SOSEngineSaveCoders(SOSEngineRef engine, SOSTransactionRef txn, CFErrorRef *error) {
// MUST hold engine lock
// Device must be unlocked for this to succeed
bool ok = true;
if (engine->codersNeedSaving) {
CFDataRef derCoders = SOSEngineCopyCoders(engine, error);
- bool ok = derCoders && SOSDataSourceSetStateWithKey(engine->dataSource, txn, kSOSEngineCoders,
+ ok = derCoders && SOSDataSourceSetStateWithKey(engine->dataSource, txn, kSOSEngineCoders,
kSOSEngineProtectionDomainClassA, derCoders, error);
if (ok) {
engine->codersNeedSaving = false;
}
return ok;
}
+#pragma clang diagnostic pop
bool SOSTestEngineSaveCoders(CFTypeRef engine, SOSTransactionRef txn, CFErrorRef *error){
return SOSEngineSaveCoders((SOSEngineRef)engine, txn, error);
}
}
-static CFDataRef SOSEngineLoadV0KeyBag(SOSEngineRef engine, CFErrorRef *error) {
+static CFDataRef SOSEngineCopyV0KeyBag(SOSEngineRef engine, CFErrorRef *error) {
// Return the keybag for the given peerID.
/*
Values for V0 are:
SOSPeerRef backupPeer = (SOSPeerRef)CFDictionaryGetValue(engine->peerMap, kSOSViewKeychainV0_tomb);
CFDataRef bag = NULL;
if (backupPeer && CFGetTypeID(backupPeer) == SOSPeerGetTypeID()) {
- bag = SOSPeerGetKeyBag(backupPeer);
+ bag = CFRetainSafe(SOSPeerGetKeyBag(backupPeer));
} else {
CFErrorRef localError = NULL;
- if (!(bag = SOSEngineLoadV0KeyBag(engine, &localError))) {
+ bag = SOSEngineCopyV0KeyBag(engine, &localError);
+ if (!bag) {
secnotice("engine", "No keybag found for v0 backup peer: %@", localError);
CFReleaseSafe(localError);
}
}
SOSEngineReferenceBackupPeer(engine, kSOSViewKeychainV0_tomb, SOSViewsGetV0BackupViewSet(), bag, newViewNameSet2ChangeTracker, newPeerMap);
+ CFReleaseNull(bag);
}
static void SOSEngineReferenceTrustedPeers(SOSEngineRef engine, CFMutableDictionaryRef newViewNameSet2ChangeTracker, CFMutableDictionaryRef newPeerMap, CFMutableArrayRef newPeerIDs, CFArrayRef trustedPeerMetas, CFMutableStringRef desc) {
#import "keychain/ckks/CKKSLockStateTracker.h"
#import "keychain/ckks/NSOperationCategories.h"
#include <Security/SecureObjectSync/SOSAccount.h>
-#import <WirelessDiagnostics/WirelessDiagnostics.h>
-#import "keychain/analytics/awd/AWDMetricIds_Keychain.h"
static NSOperationQueue *backupOperationQueue;
static CKKSLockStateTracker *lockStateTracker;
}];
[backupOperation addNullableDependency:lockStateTracker.unlockDependency];
[backupOperationQueue addOperation:backupOperation];
- AWDPostSimpleMetric(AWDMetricId_Keychain_SOSKeychainBackupFailed);
}
}
}
_SOSCCAccountSetToNew
_SOSCCBailFromCircle_BestEffort
_SOSCCCanAuthenticate
-_SOSCCCheckPeerAvailability
-_SOSCCClearPeerMessageKeyInKVS
_SOSCCCopyAccountState
_SOSCCCopyApplicantPeerInfo
_SOSCCCopyApplication
_SOSCCCopyBackupInformation
_SOSCCCopyCircleJoiningBlob
_SOSCCCopyConcurringPeerPeerInfo
-_SOSCCCopyDeviceID
_SOSCCCopyEngineData
_SOSCCCopyEscrowRecord
_SOSCCCopyGenerationPeerInfo
_SOSCCGetLastDepartureReason
_SOSCCGetStatusDescription
_SOSCCGetViewResultDescription
-_SOSCCHandleIDSMessage
-_SOSCCRequestSyncWithPeerOverKVS
-_SOSCCRequestSyncWithPeerOverKVSUsingIDOnly
-_SOSCCIDSDeviceIDIsAvailableTest
-_SOSCCIDSPingTest
-_SOSCCIDSServiceRegistrationTest
_SOSCCIsAppleTVSyncing
_SOSCCIsContinuityUnlockSyncing
_SOSCCIsHomeKitSyncing
_SOSCCRegisterUserCredentials
_SOSCCRejectApplicants
_SOSCCRemovePeersFromCircle
+_SOSCCRemovePeersFromCircleWithAnalytics
_SOSCCRemoveThisDeviceFromCircle
+_SOSCCRemoveThisDeviceFromCircleWithAnalytics
_SOSCCRequestEnsureFreshParameters
-_SOSCCRequestSyncWithPeerOverKVS
_SOSCCRequestToJoinCircle
+_SOSCCRequestToJoinCircleWithAnalytics
_SOSCCRequestToJoinCircleAfterRestore
+_SOSCCRequestToJoinCircleAfterRestoreWithAnalytics
_SOSCCResetToEmpty
+_SOSCCResetToEmptyWithAnalytics
_SOSCCResetToOffering
-_SOSCCSecurityProperty
_SOSCCSendToPeerIsPending
-_SOSCCSetDeviceID
_SOSCCSetEscrowRecord
_SOSCCSetLastDepartureReason
_SOSCCSetUserCredentials
_SOSCCSetUserCredentialsAndDSID
+_SOSCCSetUserCredentialsAndDSIDWithAnalytics
_SOSCCSignedOut
_SOSCCThisDeviceIsInCircle
+_SOSCCThisDeviceIsInCircleNonCached
_SOSCCTryUserCredentials
_SOSCCTryUserCredentialsAndDSID
_SOSCCValidateUserPublic
_SOSCCView
_SOSCCViewSet
+_SOSCCViewSetWithAnalytics
_SOSCCWaitForInitialSync
+_SOSCCWaitForInitialSyncWithAnalytics
_SOSCCCopyInitialSyncData
_kSOSCCEngineStateCoderKey
_SOSPeerInfoCopyEnabledViews
_SOSPeerInfoCopyEncodedData
_SOSPeerInfoCopyEscrowRecord
-_SOSPeerInfoCopyIDSACKModelPreference
-_SOSPeerInfoCopyIDSFragmentationPreference
-_SOSPeerInfoCopyIDSPreference
_SOSPeerInfoCopyOctagonSigningPublicKey
_SOSPeerInfoCopyOctagonEncryptionPublicKey
_SOSPeerInfoCopyPeerGestalt
_SOSPeerInfoCopyWithGestaltUpdate
_SOSPeerInfoCopyWithPing
_SOSPeerInfoCopyWithReplacedEscrowRecords
-_SOSPeerInfoCopyWithSecurityPropertyChange
_SOSPeerInfoCopyWithViewsChange
-_SOSPeerInfoCopyTransportType
_SOSPeerInfoCopySerialNumber
_SOSPeerInfoCopyOSVersion
_SOSPeerInfoCreate
_SOSPeerInfoGetTypeID
_SOSPeerInfoGetVersion
_SOSPeerInfoHasBackupKey
-_SOSPeerInfoHasDeviceID
_SOSPeerInfoHasOctagonEncryptionPubKey
_SOSPeerInfoHasOctagonSigningPubKey
_SOSPeerInfoInspectRetirementTicket
_SOSPeerInfoLookupGestaltValue
_SOSPeerInfoPeerIDEqual
_SOSPeerInfoRetireRetirementTicket
-_SOSPeerInfoSecurityPropertyStatus
-_SOSPeerInfoSetDeviceID
-_SOSPeerInfoSetIDSACKModelPreference
-_SOSPeerInfoSetIDSFragmentationPreference
-_SOSPeerInfoSetIDSPreference
_SOSPeerInfoSetOctagonEncryptionKey
_SOSPeerInfoSetOctagonSigningKey
-_SOSPeerInfoSetTransportType
-_SOSPeerInfoShouldUseACKModel
-_SOSPeerInfoShouldUseIDSMessageFragmentation
-_SOSPeerInfoShouldUseIDSTransport
-_SOSPeerInfoTransportTypeIs
_SOSPeerInfoUpdateDigestWithDescription
_SOSPeerInfoUpdateDigestWithPublicKeyBytes
_SOSPeerInfoUpgradeSignatures
_SOSPeerInfoViewStatus
_SOSPeerInfoWithEnabledViewSet
-
_SOSFullPeerInfoCreate
_SOSFullPeerInfoPromoteToApplication
_SOSFullPeerInfoGetPeerInfo
_SOSCircleAcceptPeerFromHSA2
+_SOSFullPeerInfoUpdate
-_SOSCCSetDeviceID
-_SOSCCHandleIDSMessage
-
-_SOSCCIDSServiceRegistrationTest
-_SOSCCIDSPingTest
-_SOSCCIDSDeviceIDIsAvailableTest
_SOSCCGetAllTheRings
_SOSCCApplyToARing
_SOSCCWithdrawlFromARing
_SOSCCEnableRing
_SOSCCIsThisDeviceLastBackup
-_SOSCloudKeychainSendIDSMessage
_SOSCloudKeychainRemoveKeys
-_SOSCloudKeychainRetrieveCountersFromIDSProxy
+
+_SOSCloudTransportSetDefaultTransport
_CFArrayOfSOSPeerInfosSortByID
_CFSetCreateMutableForSOSPeerInfosByID
_SOSCircleVerify
_SOSCircleVerifyPeerSigned
_SOSCircleVerifySignatureExists
+_SOSCircleVerifyPeerSignatureExists
_SOSCircleWithdrawRequest
_debugDumpCircle
_SOSFullPeerInfoPromoteToRetiredAndCopy
_SOSFullPeerInfoPurgePersistentKey
_SOSFullPeerInfoReplaceEscrowRecords
-_SOSFullPeerInfoSecurityPropertyStatus
_SOSFullPeerInfoUpdateBackupKey
-_SOSFullPeerInfoUpdateDeviceID
_SOSFullPeerInfoUpdateGestalt
_SOSFullPeerInfoUpdateOctagonEncryptionKey
_SOSFullPeerInfoUpdateOctagonSigningKey
-_SOSFullPeerInfoUpdateSecurityProperty
_SOSFullPeerInfoUpdateToCurrent
_SOSFullPeerInfoUpdateToThisPeer
-_SOSFullPeerInfoUpdateTransportAckModelPreference
-_SOSFullPeerInfoUpdateTransportFragmentationPreference
-_SOSFullPeerInfoUpdateTransportPreference
-_SOSFullPeerInfoUpdateTransportType
_SOSFullPeerInfoUpdateV2Dictionary
_SOSFullPeerInfoUpdateViews
_SOSFullPeerInfoUpgradeSignatures
_SOSPiggyBackBlobCopyEncodedData
_SOSPiggyBackAddToKeychain
-_SOSCloudKeychainRetrievePendingMessageFromProxy
_SOSCloudKeychainClearAll
_SOSCloudKeychainGetAllObjectsFromCloud
_SOSCloudKeychainGetObjectsFromCloud
_SOSCloudKeychainUpdateKeys
_SOSCloudCopyKVSState
_SOSCloudKeychainFlush
-_SOSCloudKeychainGetIDSDeviceAvailability
-_SOSCloudKeychainGetIDSDeviceID
_SOSCloudKeychainHandleUpdateMessage
_SOSCloudKeychainHasPendingKey
_SOSCloudKeychainHasPendingSyncWithPeer
_SOSMessageKeyCreateWithCircleAndPeerInfos
_SOSMessageKeyCreateWithCircleAndPeerNames
_SOSMessageKeyCreateWithCircleNameAndPeerNames
-_SOSMessageKeyCreateWithCircleNameAndTransportType
_SOSRetirementKeyCreateWithCircleAndPeer
_SOSRetirementKeyCreateWithCircleNameAndPeer
_SOSRingKeyCreateWithName
_SOSCopyDeviceBackupPublicKey
_SOSCopyECUnwrappedData
_SOSCopyECWrappedData
+_SOSCopyHashBufAsString
_SOSCopyIDOfDataBuffer
_SOSCopyIDOfDataBufferWithLength
_SOSCopyIDOfKey
_SOSTransportMessageTypeIDSV2
_SOSTransportMessageTypeKVS
_kSOSDSIDKey
+_kSOSNoCachedValue
_SOSPeerGestaltGetAnswer
_CreateXPCObjectWithCFSetRef
_kSOSErrorDomain
-_kSecIDSErrorDomain
_kSOSKVSAccountChangedKey
_kSOSKVSInitialSyncKey
_SOSKVSKeyGetKeyType
-_kSOSSecPropertyHasEntropy
-_kSOSSecPropertyScreenLock
-_kSOSSecPropertySEP
-_kSOSSecPropertyIOS
_SOSPeerInfoV2DictionaryCopyData
_SOSPeerInfoV2DictionaryCopyBoolean
_SOSPeerInfoV2DictionaryCopySet
_sViewsKey
_sSerialNumberKey
+_sMachineIDKey
_sPreferIDS
_sPreferIDSFragmentation
_sPreferIDSACKModel
_sBackupKeyKey
_sEscrowRecord
_sTransportType
-_sSecurityPropertiesKey
-_kIDSOperationType
-_kIDSMessageToSendKey
-_kIDSMessageUniqueID
-_kIDSMessageRecipientPeerID
-_kIDSMessageRecipientDeviceID
-_kIDSMessageUsesAckModel
_SOSGenerationCountCopyDescription
-_kIDSMessageSenderDeviceID
_kSOSHsaCrKeyDictionary
_SOSPeerInfoCopySerialNumber
_der_encode_data_or_null
_der_decode_data_or_null
+// Notification-based caching for clients
+#if __OBJC2__
+_OBJC_CLASS_$_SOSCachedNotification
+_OBJC_METACLASS_$_SOSCachedNotification
+#else
+.objc_class_name_SOSCachedNotification
+#endif
+_SOSCachedNotificationOperation
+_SOSGetCachedCircleStatus
+_SOSCreateCachedViewStatus
+_SOSCachedViewBitmask
+_SOSGetCachedCircleBitmask
+_SOSPeerInfoViewBitMask
+_SOSViewCreateSetFromBitmask
+
+_SOSCircleCopyHashString
+
+_kPIUserDefinedDeviceNameKey
+_kPIDeviceModelNameKey
+_kPIMessageProtocolVersionKey
+_kPIOSVersionKey
+
+_sGestaltKey
+_sVersionKey
+_SOSGestaltSerial
+
+__SOSControlSetupInterface
+
#if !(TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
CFDataRef SOSFullPeerInfoCopyEncodedData(SOSFullPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error);
-bool SOSFullPeerInfoUpdateTransportType(SOSFullPeerInfoRef peer, CFStringRef transportType, CFErrorRef* error);
-bool SOSFullPeerInfoUpdateDeviceID(SOSFullPeerInfoRef peer, CFStringRef deviceID, CFErrorRef* error);
-bool SOSFullPeerInfoUpdateTransportPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error);
-bool SOSFullPeerInfoUpdateTransportFragmentationPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error);
-bool SOSFullPeerInfoUpdateTransportAckModelPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error);
-
bool SOSFullPeerInfoUpdateOctagonSigningKey(SOSFullPeerInfoRef peer, SecKeyRef octagonSigningKey, CFErrorRef* error);
bool SOSFullPeerInfoUpdateOctagonEncryptionKey(SOSFullPeerInfoRef peer, SecKeyRef octagonEncryptionKey, CFErrorRef* error);
-SOSSecurityPropertyResultCode SOSFullPeerInfoUpdateSecurityProperty(SOSFullPeerInfoRef peer, SOSViewActionCode action, CFStringRef property, CFErrorRef* error);
-SOSSecurityPropertyResultCode SOSFullPeerInfoSecurityPropertyStatus(SOSFullPeerInfoRef peer, CFStringRef property, CFErrorRef *error);
CFDataRef SOSPeerInfoCopyData(SOSPeerInfoRef fpi, CFErrorRef *error);
+bool SOSFullPeerInfoUpdate(SOSFullPeerInfoRef fullPeerInfo, CFErrorRef *error, SOSPeerInfoRef (^create_modification)(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error));
+
__END_DECLS
#endif
CFStringRef kSOSFullPeerInfoNameKey = CFSTR("SOSFullPeerInfoName");
-static bool SOSFullPeerInfoUpdate(SOSFullPeerInfoRef fullPeerInfo, CFErrorRef *error, SOSPeerInfoRef (^create_modification)(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error)) {
+bool SOSFullPeerInfoUpdate(SOSFullPeerInfoRef fullPeerInfo, CFErrorRef *error, SOSPeerInfoRef (^create_modification)(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error)) {
bool result = false;
SOSPeerInfoRef newPeer = NULL;
return retval;
}
-bool SOSFullPeerInfoUpdateTransportType(SOSFullPeerInfoRef peer, CFStringRef transportType, CFErrorRef* error)
-{
- return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
- return SOSPeerInfoSetTransportType(kCFAllocatorDefault, peer, transportType, key, error);
- });
-}
-
-bool SOSFullPeerInfoUpdateDeviceID(SOSFullPeerInfoRef peer, CFStringRef deviceID, CFErrorRef* error){
- return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
- return SOSPeerInfoSetDeviceID(kCFAllocatorDefault, peer, deviceID, key, error);
- });
-}
-
-bool SOSFullPeerInfoUpdateTransportPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error){
- return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
- return SOSPeerInfoSetIDSPreference(kCFAllocatorDefault, peer, preference, key, error);
- });
-}
-
-bool SOSFullPeerInfoUpdateTransportFragmentationPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error){
- return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
- return SOSPeerInfoSetIDSFragmentationPreference(kCFAllocatorDefault, peer, preference, key, error);
- });
-}
-
-bool SOSFullPeerInfoUpdateTransportAckModelPreference(SOSFullPeerInfoRef peer, CFBooleanRef preference, CFErrorRef* error){
- return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
- return SOSPeerInfoSetIDSACKModelPreference(kCFAllocatorDefault, peer, preference, key, error);
- });
-}
-
bool SOSFullPeerInfoUpdateOctagonSigningKey(SOSFullPeerInfoRef peer, SecKeyRef octagonSigningKey, CFErrorRef* error){
return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) {
return SOSPeerInfoSetOctagonSigningKey(kCFAllocatorDefault, peer, octagonSigningKey, key, error);
if(!SOSPeerInfoVersionIsCurrent(peer->peer_info)) return true;
if(!SOSPeerInfoSerialNumberIsSet(peer->peer_info)) return true;
- if(!(SOSPeerInfoV2DictionaryHasString(peer->peer_info, sDeviceID)))return true;
- if(!(SOSPeerInfoV2DictionaryHasString(peer->peer_info, sTransportType))) return true;
- if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDS))) return true;
- if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDSFragmentation))) return true;
- if(!(SOSPeerInfoV2DictionaryHasBoolean(peer->peer_info, sPreferIDSACKModel))) return true;
if(SOSFullPeerInfoNeedsViewUpdate(peer, minimumViews, excludedViews)) return true;
return false;
return SOSPeerInfoViewStatus(pi, viewname, error);
}
-
-SOSSecurityPropertyResultCode SOSFullPeerInfoUpdateSecurityProperty(SOSFullPeerInfoRef peer, SOSViewActionCode action, CFStringRef property, CFErrorRef* error)
-{
- SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError;
- SecKeyRef device_key = SOSFullPeerInfoCopyDeviceKey(peer, error);
- require_quiet(device_key, fail);
-
- SOSPeerInfoRef newPeer = SOSPeerInfoCopyWithSecurityPropertyChange(kCFAllocatorDefault, peer->peer_info, action, property, &retval, device_key, error);
-
- require_quiet(newPeer, fail);
-
- CFReleaseNull(peer->peer_info);
- peer->peer_info = newPeer;
- newPeer = NULL;
-
-fail:
- CFReleaseNull(device_key);
- return retval;
-}
-
-SOSSecurityPropertyResultCode SOSFullPeerInfoSecurityPropertyStatus(SOSFullPeerInfoRef peer, CFStringRef property, CFErrorRef *error)
-{
- SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(peer);
- secnotice("secprop", "have pi %s", (pi)? "true": "false");
- if(!pi) return kSOSCCGeneralSecurityPropertyError;
- return SOSPeerInfoSecurityPropertyStatus(pi, property, error);
-}
-
-
SOSPeerInfoRef SOSFullPeerInfoGetPeerInfo(SOSFullPeerInfoRef fullPeer) {
return fullPeer?fullPeer->peer_info:NULL;
}
#define ENABLE_IDS 0
#define kSOSPeerIDLengthMax (26)
+#define CC_STATISVALID 0x8000000000000000
+#define CC_UKEY_TRUSTED 0x4000000000000000
+#define CC_CAN_AUTH 0x2000000000000000
+#define CC_PEER_IS_IN 0x1000000000000000
+#define CC_MASK 0x0fffffffffffffff
enum {
// Public errors are first (See SOSCloudCircle)
kSOSErrorNotInCircle = 1046,
};
-typedef enum {
- kSecIDSErrorNoDeviceID = -1, //default case
- kSecIDSErrorNotRegistered = -2,
- kSecIDSErrorFailedToSend=-3,
- kSecIDSErrorCouldNotFindMatchingAuthToken = -4,
- kSecIDSErrorDeviceIsLocked = -5,
- kSecIDSErrorNoPeersAvailable = -6
-
-} idsError;
-
-
extern const CFStringRef SOSTransportMessageTypeIDSV2;
extern const CFStringRef SOSTransportMessageTypeKVS;
extern const CFStringRef kSOSDSIDKey;
+extern const SOSCCStatus kSOSNoCachedValue;
// Returns false unless errorCode is 0.
bool SOSErrorCreate(CFIndex errorCode, CFErrorRef *error, CFDictionaryRef formatOptions, CFStringRef descriptionString, ...);
CFStringRef SOSItemsChangedCopyDescription(CFDictionaryRef changes, bool is_sender);
+CFStringRef SOSCopyHashBufAsString(uint8_t *digest, size_t len);
CFStringRef SOSCopyIDOfDataBuffer(CFDataRef data, CFErrorRef *error);
CFStringRef SOSCopyIDOfDataBufferWithLength(CFDataRef data, CFIndex len, CFErrorRef *error);
CFDataRef CFDataCreateWithDER(CFAllocatorRef allocator, CFIndex size, uint8_t*(^operation)(size_t size, uint8_t *buffer));
-extern const CFStringRef kSecIDSErrorDomain;
-extern const CFStringRef kIDSOperationType;
-extern const CFStringRef kIDSMessageToSendKey;
-extern const CFStringRef kIDSMessageUniqueID;
-extern const CFStringRef kIDSMessageRecipientPeerID;
-extern const CFStringRef kIDSMessageRecipientDeviceID;
-extern const CFStringRef kIDSMessageUsesAckModel;
-extern const CFStringRef kIDSMessageSenderDeviceID;
+
+// Expanded notification utilities
+#if __OBJC__
+@interface SOSCachedNotification : NSObject
+- (instancetype)init NS_UNAVAILABLE;
++ (NSString *)notificationName:(const char *)notificationString;
+@end
+#endif
+
+bool SOSCachedNotificationOperation(const char *notificationString, bool (^operation) (int token, bool gtg));
+uint64_t SOSGetCachedCircleBitmask(void);
+SOSCCStatus SOSGetCachedCircleStatus(CFErrorRef *error);
+uint64_t SOSCachedViewBitmask(void);
+CFSetRef SOSCreateCachedViewStatus(void);
+
+
__END_DECLS
#include <Security/SecureObjectSync/SOSCircle.h>
#include <Security/SecureObjectSync/SOSCloudCircle.h>
#include <Security/SecureObjectSync/SOSKVSKeys.h>
+#include <Security/SecureObjectSync/SOSViews.h>
#include "utilities/SecCFError.h"
#include "utilities/SecCFRelease.h"
#include "utilities/SecCFWrappers.h"
#include <CommonCrypto/CommonRandomSPI.h>
-#include <AssertMacros.h>
+#include <os/lock.h>
-const CFStringRef kSecIDSErrorDomain = CFSTR("com.apple.security.ids.error");
-const CFStringRef kIDSOperationType = CFSTR("IDSMessageOperation");
-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");
+#include <AssertMacros.h>
-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");
return string;
}
+CFStringRef SOSCopyHashBufAsString(uint8_t *digest, size_t len) {
+ char encoded[2 * len + 1]; // Big enough for base64 encoding.
-CFStringRef SOSCopyIDOfDataBuffer(CFDataRef data, CFErrorRef *error) {
- const struct ccdigest_info * di = ccsha1_di();
- uint8_t digest[di->output_size];
- char encoded[2 * di->output_size]; // Big enough for base64 encoding.
-
- ccdigest(di, CFDataGetLength(data), CFDataGetBytePtr(data), digest);
-
- size_t length = SecBase64Encode(digest, sizeof(digest), encoded, sizeof(encoded));
+ size_t length = SecBase64Encode(digest, len, encoded, sizeof(encoded));
assert(length && length < sizeof(encoded));
if (length > kSOSPeerIDLengthMax)
length = kSOSPeerIDLengthMax;
return CFStringCreateWithCString(kCFAllocatorDefault, encoded, kCFStringEncodingASCII);
}
+CFStringRef SOSCopyIDOfDataBuffer(CFDataRef data, CFErrorRef *error) {
+ const struct ccdigest_info * di = ccsha1_di();
+ uint8_t digest[di->output_size];
+ ccdigest(di, CFDataGetLength(data), CFDataGetBytePtr(data), digest);
+ return SOSCopyHashBufAsString(digest, sizeof(digest));
+}
+
CFStringRef SOSCopyIDOfDataBufferWithLength(CFDataRef data, CFIndex len, CFErrorRef *error) {
CFStringRef retval = NULL;
CFStringRef tmp = SOSCopyIDOfDataBuffer(data, error);
CFStringRef SOSCopyIDOfKey(SecKeyRef key, CFErrorRef *error) {
CFDataRef publicBytes = NULL;
CFStringRef result = NULL;
- require_quiet(SecError(SecKeyCopyPublicBytes(key, &publicBytes), error, CFSTR("Failed to export public bytes %@"), key), fail);
+ require_action_quiet(key, errOut, SOSErrorCreate(kSOSErrorNoKey, error, NULL, CFSTR("NULL key passed to SOSCopyIDOfKey")));
+ require_quiet(SecError(SecKeyCopyPublicBytes(key, &publicBytes), error, CFSTR("Failed to export public bytes %@"), key), errOut);
result = SOSCopyIDOfDataBuffer(publicBytes, error);
-fail:
+errOut:
CFReleaseNull(publicBytes);
return result;
}
}
return result;
}
+
+@implementation SOSCachedNotification
++ (NSString *)notificationName:(const char *)notificationString {
+#if TARGET_OS_OSX
+ return [NSString stringWithFormat:@"user.uid.%d.%s", getuid(), notificationString];
+#else
+ return @(notificationString);
+#endif
+}
+
+@end
+
+bool SOSCachedNotificationOperation(const char *notificationString, bool (^operation) (int token, bool gtg)) {
+ static os_unfair_lock token_lock = OS_UNFAIR_LOCK_INIT;
+ static NSMutableDictionary *tokenCache = NULL;
+ int token = NOTIFY_TOKEN_INVALID;
+
+ @autoreleasepool {
+ os_unfair_lock_lock(&token_lock);
+ if (tokenCache == NULL) {
+ tokenCache = [NSMutableDictionary dictionary];
+ }
+ NSString *notification = [SOSCachedNotification notificationName:notificationString];
+ if (notification == NULL) {
+ os_unfair_lock_unlock(&token_lock);
+ return false;
+ }
+
+ NSNumber *cachedToken = tokenCache[notification];
+ if (cachedToken == NULL) {
+ uint32_t status;
+
+ status = notify_register_check([notification UTF8String], &token);
+ if (status == NOTIFY_STATUS_OK) {
+ tokenCache[notification] = @(token);
+ } else {
+ secnotice("cachedStatus", "Failed to retreive token for %@: error %d",
+ notification, status);
+ }
+ } else {
+ token = [cachedToken intValue];
+ }
+ os_unfair_lock_unlock(&token_lock);
+ }
+
+ return operation(token, (token != NOTIFY_TOKEN_INVALID));
+}
+
+uint64_t SOSGetCachedCircleBitmask(void) {
+ __block uint64_t retval = 0; // If the following call fails and we return 0 the caller, checking CC_STATISVALID will see we didn't get anything.
+ SOSCachedNotificationOperation(kSOSCCCircleChangedNotification, ^bool(int token, bool gtg) {
+ if(gtg) {
+ notify_get_state(token, &retval);
+ }
+ return false;
+ });
+ return retval;
+}
+
+const SOSCCStatus kSOSNoCachedValue = -99;
+
+SOSCCStatus SOSGetCachedCircleStatus(CFErrorRef *error) {
+ uint64_t statusMask = SOSGetCachedCircleBitmask();
+ SOSCCStatus retval = kSOSNoCachedValue;
+
+ if(statusMask & CC_STATISVALID) {
+ if(statusMask & CC_UKEY_TRUSTED) {
+ retval = (SOSCCStatus) statusMask & CC_MASK;
+ } else {
+ retval = kSOSCCError;
+ if(error) {
+ CFReleaseNull(*error);
+ if(statusMask & CC_PEER_IS_IN) {
+ 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);
+ } else {
+ SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Public Key isn't available. The iCloud Password must be provided to keychain syncing subsystem to repair this."), NULL, error);
+ }
+ }
+ }
+ }
+ return retval;
+}
+
+uint64_t SOSCachedViewBitmask(void) {
+ __block uint64_t retval = 0;
+ if(SOSGetCachedCircleStatus(NULL) == kSOSCCInCircle) {
+ SOSCachedNotificationOperation(kSOSCCViewMembershipChangedNotification, ^bool(int token, bool gtg) {
+ if(gtg) {
+ notify_get_state(token, &retval);
+ return true;
+ }
+ return false;
+ });
+ }
+ return retval;
+}
+
+CFSetRef SOSCreateCachedViewStatus(void) {
+ __block CFSetRef retval = NULL;
+ uint64_t state = SOSCachedViewBitmask();
+ if(state) {
+ retval = SOSViewCreateSetFromBitmask(state);
+ }
+ return retval;
+}
+
CFStringRef SOSMessageKeyCreateFromTransportToPeer(SOSMessage* transport, CFStringRef myID, CFStringRef peer_name);
CFStringRef SOSMessageKeyCreateFromPeerToTransport(SOSMessage* transport, CFStringRef myID, CFStringRef peer_name);
CFStringRef SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(SOSAccount* account);
-CFStringRef SOSMessageKeyCreateWithCircleNameAndTransportType(CFStringRef circleName, CFStringRef transportType);
CFStringRef SOSRingKeyCreateWithRingName(CFStringRef ring_name);
CFStringRef SOSLastKeyParametersPushedKeyCreateWithPeerID(CFStringRef peerID);
circleName, sCircleSeparator, from_peer_name, sFromToSeparator, to_peer_name);
}
-CFStringRef SOSMessageKeyCreateWithCircleNameAndTransportType(CFStringRef circleName, CFStringRef transportType)
-{
- return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@%@%@"),
- circleName, sCircleSeparator, transportType, sFromToSeparator, SOSTransportMessageTypeIDSV2);
-}
-
CFStringRef SOSMessageKeyCreateWithCircleAndPeerNames(SOSCircleRef circle, CFStringRef from_peer_name, CFStringRef to_peer_name)
{
return SOSMessageKeyCreateWithCircleNameAndPeerNames(SOSCircleGetName(circle), from_peer_name, to_peer_name);
SecKeyRef signingKey, CFErrorRef* error);
SOSPeerInfoRef SOSPeerInfoCopyAsApplication(SOSPeerInfoRef pi, SecKeyRef userkey, SecKeyRef peerkey, CFErrorRef *error);
-SOSPeerInfoRef SOSPeerInfoCopyWithSecurityPropertyChange(CFAllocatorRef allocator, SOSPeerInfoRef toCopy,
- SOSSecurityPropertyActionCode action, CFStringRef property, SOSSecurityPropertyResultCode *retval,
- SecKeyRef signingKey, CFErrorRef* error);
-
SOSPeerInfoRef SOSPeerInfoCopyWithPing(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, SecKeyRef signingKey, CFErrorRef* error);
SOSPeerInfoRef SOSPeerInfoCopyAsApplication(SOSPeerInfoRef pi, SecKeyRef userkey, SecKeyRef peerkey, CFErrorRef *error);
bool SOSPeerInfoIsEnabledView(SOSPeerInfoRef peer, CFStringRef viewName);
CFMutableSetRef SOSPeerInfoCopyEnabledViews(SOSPeerInfoRef peer);
void SOSPeerInfoWithEnabledViewSet(SOSPeerInfoRef pi, void (^operation)(CFSetRef enabled));
+uint64_t SOSPeerInfoViewBitMask(SOSPeerInfoRef pi);
-SOSSecurityPropertyResultCode SOSPeerInfoSecurityPropertyStatus(SOSPeerInfoRef pi, CFStringRef property, CFErrorRef *error);
-
-//Transport
-CFBooleanRef SOSPeerInfoCopyIDSPreference(SOSPeerInfoRef peer);
-SOSPeerInfoRef SOSPeerInfoSetIDSPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error);
-
-CFBooleanRef SOSPeerInfoCopyIDSFragmentationPreference(SOSPeerInfoRef peer);
-CFBooleanRef SOSPeerInfoCopyIDSACKModelPreference(SOSPeerInfoRef peer);
-SOSPeerInfoRef SOSPeerInfoSetIDSFragmentationPreference(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);
-SOSPeerInfoRef SOSPeerInfoSetTransportType(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef transportType, SecKeyRef signingKey, CFErrorRef *error);
bool SOSPeerInfoKVSOnly(SOSPeerInfoRef pi);
-
-// IDSs device ID
-bool SOSPeerInfoHasDeviceID(SOSPeerInfoRef peer);
+CFStringRef SOSPeerInfoCopyTransportType(SOSPeerInfoRef peer);
CFStringRef SOSPeerInfoCopyDeviceID(SOSPeerInfoRef peer);
-SOSPeerInfoRef SOSPeerInfoSetDeviceID(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef IDS, SecKeyRef signingKey, CFErrorRef *error);
/* octagon keys */
SOSPeerInfoRef CF_RETURNS_RETAINED
CFStringRef SOSPeerInfoCopySerialNumber(SOSPeerInfoRef pi);
CFStringRef SOSPeerInfoCopyOSVersion(SOSPeerInfoRef pi);
-
-bool SOSPeerInfoShouldUseIDSTransport(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer);
-bool SOSPeerInfoShouldUseIDSMessageFragmentation(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer);
-bool SOSPeerInfoShouldUseACKModel(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer);
-
void SOSPeerInfoLogState(char *category, SOSPeerInfoRef pi, SecKeyRef pubKey, CFStringRef myPID, char sigchr);
enum {
#include <Security/SecureObjectSync/SOSPeerInfoInternal.h>
#include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
-#include <Security/SecureObjectSync/SOSPeerInfoSecurityProperties.h>
#include <Security/SecureObjectSync/SOSCircle.h>
#include <Security/SecureObjectSync/SOSInternal.h>
#include <ipc/securityd_client.h>
description_modifier(pi->description);
pi->peerID = SOSCopyIDOfKey(publicKey, error);
+
+ pi->verifiedAppKeyID = NULL;
+ pi->verifiedResult = false;
require_quiet(pi->peerID, exit);
// V2DictionarySetValue handles NULL as remove
if (backup_key != NULL) SOSPeerInfoV2DictionarySetValue(pi, sBackupKeyKey, backup_key);
- SOSPeerInfoV2DictionarySetValue(pi, sDeviceID, IDSID);
- SOSPeerInfoV2DictionarySetValue(pi, sTransportType, transportType);
- SOSPeerInfoV2DictionarySetValue(pi, sPreferIDS, preferIDS);
- SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSFragmentation, preferFragmentation);
- SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSACKModel, preferAckModel);
SOSPeerInfoV2DictionarySetValue(pi, sViewsKey, enabledViews);
// ================ V2 Additions End
pi->gestalt = CFDictionaryCreateCopy(allocator, toCopy->gestalt);
pi->peerID = CFStringCreateCopy(allocator, toCopy->peerID);
+ pi->verifiedAppKeyID = NULL; // The peer resulting from this will need to be re-evaluated for an application signature.
+ pi->verifiedResult = false;
pi->version = toCopy->version;
if(!SOSPeerInfoVersionHasV2Data(pi)) SOSPeerInfoExpandV2Data(pi, error);
SOSPeerInfoRef pi = SOSPeerInfoCreateCopy(allocator, toCopy, error);
if(!SOSPeerInfoVersionHasV2Data(pi)) SOSPeerInfoUpdateToV2(pi, error);
-
- //SOSPeerInfoSetSerialNumber(pi);
- if (IDSID) {
- SOSPeerInfoV2DictionarySetValue(pi, sDeviceID, IDSID);
- }
- if (transportType) {
- SOSPeerInfoV2DictionarySetValue(pi, sTransportType, transportType);
- }
- if (preferIDS) {
- SOSPeerInfoV2DictionarySetValue(pi, sPreferIDS, preferIDS);
- }
- if (preferFragmentation) {
- SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSFragmentation, preferFragmentation);
- }
- if (preferAckModel) {
- SOSPeerInfoV2DictionarySetValue(pi, sPreferIDSACKModel, preferAckModel);
- }
if (enabledViews) {
SOSPeerInfoV2DictionarySetValue(pi, sViewsKey, enabledViews);
}
return SOSViewsQuery(pi, view, error);
}
-
-SOSPeerInfoRef SOSPeerInfoCopyWithSecurityPropertyChange(CFAllocatorRef allocator, SOSPeerInfoRef toCopy,
- SOSSecurityPropertyActionCode action, CFStringRef property, SOSSecurityPropertyResultCode *retval,
- SecKeyRef signingKey, CFErrorRef* error) {
- SOSPeerInfoRef pi = SOSPeerInfoCreateCopy(allocator, toCopy, error);
- if(action == kSOSCCSecurityPropertyEnable) {
- *retval = SOSSecurityPropertyEnable(pi, property, error);
- require((kSOSCCSecurityPropertyValid == *retval), exit);
- } else if(action == kSOSCCSecurityPropertyDisable) {
- *retval = SOSSecurityPropertyDisable(pi, property, error);
- require((kSOSCCSecurityPropertyNotValid == *retval), exit);
- }
-
- require_action_quiet(SOSPeerInfoSign(signingKey, pi, error), exit, *retval = kSOSCCGeneralViewError);
- return pi;
-
-exit:
- CFReleaseNull(pi);
- return NULL;
-}
-
-SOSViewResultCode SOSPeerInfoSecurityPropertyStatus(SOSPeerInfoRef pi, CFStringRef property, CFErrorRef *error) {
- return SOSSecurityPropertyQuery(pi, property, error);
- }
-
-
-
static void SOSPeerInfoDestroy(CFTypeRef aObj) {
SOSPeerInfoRef pi = (SOSPeerInfoRef) aObj;
CFReleaseNull(pi->gestalt);
CFReleaseNull(pi->peerID);
CFReleaseNull(pi->v2Dictionary);
+ CFReleaseNull(pi->verifiedAppKeyID);
+ pi->verifiedResult = false;
}
static Boolean SOSPeerInfoCompare(CFTypeRef lhs, CFTypeRef rhs) {
description = CFStringCreateWithFormat(kCFAllocatorDefault, formatOptions,
CFSTR("<%@: [name: %20@] [%c%c%c%c%c%c%c] [type: %-20@] [spid: %8@] [os: %10@] [devid: %10@] [serial: %12@]"),
- objectPrefix,
- isKnown(SOSPeerInfoGetPeerName(pi)),
- '-',
- '-',
- boolToChars(selfValid, 'S', 's'),
- boolToChars(retired, 'R', 'r'),
- boolToChars(backingUp, 'B', 'b'),
- boolToChars(isKVS, 'K', 'I'),
- '-',
- isKnown(SOSPeerInfoGetPeerDeviceType(pi)), isKnown(peerID),
- isKnown(osVersion), isKnown(deviceID), isKnown(serialNum));
-
+ objectPrefix,
+ isKnown(SOSPeerInfoGetPeerName(pi)),
+ '-',
+ '-',
+ boolToChars(selfValid, 'S', 's'),
+ boolToChars(retired, 'R', 'r'),
+ boolToChars(backingUp, 'B', 'b'),
+ boolToChars(isKVS, 'K', 'I'),
+ '-',
+ isKnown(SOSPeerInfoGetPeerDeviceType(pi)), isKnown(peerID),
+ isKnown(osVersion), isKnown(deviceID), isKnown(serialNum));
CFReleaseNull(peerID);
CFReleaseNull(deviceID);
if(!pi) return;
bool appValid = SOSPeerInfoApplicationVerify(pi, pubKey, NULL);
bool retired = SOSPeerInfoIsRetirementTicket(pi);
- bool selfValid = SOSPeerInfoVerify(pi, NULL);
+ // We won't inflate invalid peerInfos. Mark this true to keep scanning utilities from breaking.
+ bool selfValid = true;
bool backingUp = SOSPeerInfoHasBackupKey(pi);
bool isMe = CFEqualSafe(SOSPeerInfoGetPeerID(pi), myPID) == true;
bool isKVS = SOSPeerInfoKVSOnly(pi);
sigchr,
isKnown(SOSPeerInfoGetPeerDeviceType(pi)), isKnown(peerID),
isKnown(osVersion), isKnown(deviceID), isKnown(serialNum));
-
+
CFReleaseNull(peerID);
CFReleaseNull(deviceID);
CFReleaseNull(serialNum);
SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to sign public key hash for peer"), NULL, error));
CFDictionarySetValue(pi->description, sApplicationUsig, usersig);
-
+ pi->verifiedAppKeyID = SOSCopyIDOfKey(userkey, error);
+ if(pi->verifiedAppKeyID == NULL) {
+ secnotice("PICache", "failed to get userKeyID");
+ } else {
+ pi->verifiedResult = true;
+ }
require_quiet(SOSPeerInfoSign(peerkey, pi, error), fail);
result = pi;
const struct ccdigest_info *di = ccsha256_di();
uint8_t hbuf[di->output_size];
bool result = false;
-
+ CFStringRef userKeyID = NULL;
+
+ // If we've already succeeded signature check with this key move on.
+ require_action_quiet(userkey, exit, SOSErrorCreate(kSOSErrorNoKey, error, NULL, CFSTR("Can't validate PeerInfos with no userKey")));
+ userKeyID = SOSCopyIDOfKey(userkey, error);
+ require_action_quiet(!CFEqualSafe(userKeyID, pi->verifiedAppKeyID), exit, result = pi->verifiedResult);
+
+ // verifiedAppKeyID was NULL or not the key we're looking for - clear it.
+ CFReleaseNull(pi->verifiedAppKeyID);
+ pi->verifiedResult = false;
CFDataRef usig = CFDictionaryGetValue(pi->description, sApplicationUsig);
require_action_quiet(usig, exit,
SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Peer is not an applicant"), NULL, error));
SOSCreateError(kSOSErrorUnexpectedType, CFSTR("Failed to create hash for peer applicant"), NULL, error));
require_action_quiet(sosVerifyHash(userkey, di, hbuf, usig), exit,
SOSCreateError(kSOSErrorUnexpectedType, CFSTR("user signature of public key hash fails to verify"), NULL, error));
+ // Remember the userkey we validated for this peerinfo.
+ pi->verifiedAppKeyID = CFStringCreateCopy(kCFAllocatorDefault, userKeyID);
+ pi->verifiedResult = true;
result = SOSPeerInfoVerify(pi, error);
exit:
+ CFReleaseNull(userKeyID);
return result;
}
return retval;
}
-CFBooleanRef SOSPeerInfoCopyIDSPreference(SOSPeerInfoRef peer){
- CFBooleanRef preference = (CFBooleanRef)SOSPeerInfoV2DictionaryCopyBoolean(peer, sPreferIDS);
- return (preference ? preference : CFRetain(kCFBooleanFalse));
-}
-
-
-SOSPeerInfoRef SOSPeerInfoSetIDSPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){
- return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error,
- ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) {
- SOSPeerInfoV2DictionarySetValue(peerToModify, sPreferIDS, preference);
- return true;
- });
-}
-
-CFBooleanRef SOSPeerInfoCopyIDSFragmentationPreference(SOSPeerInfoRef peer){
- CFBooleanRef preference = (CFBooleanRef)SOSPeerInfoV2DictionaryCopyBoolean(peer, sPreferIDSFragmentation);
- return (preference ? preference : CFRetain(kCFBooleanFalse));
-}
-
-CFBooleanRef SOSPeerInfoCopyIDSACKModelPreference(SOSPeerInfoRef peer){
- CFBooleanRef preference = (CFBooleanRef)SOSPeerInfoV2DictionaryCopyBoolean(peer, sPreferIDSACKModel);
- return (preference ? preference : CFRetain(kCFBooleanFalse));
-}
-
-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);
- return true;
- });
-}
-
-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);
- return true;
- });
-}
-
static SOSPeerInfoRef CF_RETURNS_RETAINED
SOSPeerInfoSetOctagonKey(CFAllocatorRef allocator,
SOSPeerInfoRef toCopy,
return SOSPeerInfoSetOctagonKey(allocator, toCopy, sOctagonPeerEncryptionPublicKeyKey, octagonEncryptionKey, signingKey, error);
}
-bool SOSPeerInfoTransportTypeIs(SOSPeerInfoRef pi, CFStringRef transportType) {
- return SOSPeerInfoV2DictionaryHasStringValue(pi, sTransportType, transportType);
-}
-
CFStringRef SOSPeerInfoCopyTransportType(SOSPeerInfoRef peer){
CFStringRef transportType = (CFStringRef)SOSPeerInfoV2DictionaryCopyString(peer, sTransportType);
return (transportType ? transportType : CFRetain(SOSTransportMessageTypeKVS));
}
-SOSPeerInfoRef SOSPeerInfoSetTransportType(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef transportType, SecKeyRef signingKey, CFErrorRef *error){
-
- return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error,
- ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) {
- SOSPeerInfoV2DictionarySetValue(peerToModify, sTransportType, transportType);
- return true;
- });
-}
-
bool SOSPeerInfoKVSOnly(SOSPeerInfoRef pi) {
CFStringRef transportType = SOSPeerInfoCopyTransportType(pi);
bool retval = CFEqualSafe(transportType, SOSTransportMessageTypeKVS);
return retval;
}
-bool SOSPeerInfoHasDeviceID(SOSPeerInfoRef peer) {
- return SOSPeerInfoV2DictionaryHasString(peer, sDeviceID);
-}
-
CFStringRef SOSPeerInfoCopyDeviceID(SOSPeerInfoRef peer){
- return (CFStringRef)SOSPeerInfoV2DictionaryCopyString(peer, sDeviceID);
-}
-
-SOSPeerInfoRef SOSPeerInfoSetDeviceID(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFStringRef IDS, SecKeyRef signingKey, CFErrorRef *error){
-
- return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error,
- ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) {
- SOSPeerInfoV2DictionarySetValue(peerToModify, sDeviceID, IDS);
- return true;
- });
-}
-
-bool SOSPeerInfoShouldUseIDSTransport(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer){
- return SOSPeerInfoHasDeviceID(myPeer) && SOSPeerInfoTransportTypeIs(myPeer, SOSTransportMessageTypeIDSV2) &&
- SOSPeerInfoHasDeviceID(theirPeer) && SOSPeerInfoTransportTypeIs(theirPeer, SOSTransportMessageTypeIDSV2);
-}
-
-bool SOSPeerInfoShouldUseIDSMessageFragmentation(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer){
-
- bool success = false;
-
- CFBooleanRef myPreference = SOSPeerInfoCopyIDSFragmentationPreference(myPeer);
-
- CFBooleanRef theirPreference = SOSPeerInfoCopyIDSFragmentationPreference(theirPeer);
- secnotice("IDS Transport", "mypreference: %@, theirpreference: %@", myPreference, theirPreference);
- if((myPreference == kCFBooleanTrue && theirPreference == kCFBooleanTrue))
- success = true;
-
- CFReleaseNull(myPreference);
- CFReleaseNull(theirPreference);
- return success;
-}
-
-bool SOSPeerInfoShouldUseACKModel(SOSPeerInfoRef myPeer, SOSPeerInfoRef theirPeer){
- bool success = false;
-
- CFBooleanRef myPreference = SOSPeerInfoCopyIDSACKModelPreference(myPeer);
-
- CFBooleanRef theirPreference = SOSPeerInfoCopyIDSACKModelPreference(theirPeer);
- secnotice("IDS Transport", "mypreference: %@, theirpreference: %@", myPreference, theirPreference);
- if((myPreference == kCFBooleanTrue && theirPreference == kCFBooleanTrue))
- success = true;
-
- CFReleaseNull(myPreference);
- CFReleaseNull(theirPreference);
- return success;
-
+ return CFSTR("not implemented");
}
SOSPeerInfoDeviceClass SOSPeerInfoGetClass(SOSPeerInfoRef pi) {
if(!SOSPeerInfoVerify(pi, error)) {
SOSCreateErrorWithFormat(kSOSErrorBadSignature, NULL, error, NULL, CFSTR("Signature doesn't validate"));
- if (error)
+ if (error) {
secerror("Can't validate PeerInfo: %@", *error);
+ }
goto fail;
}
#ifndef sec_SOSPeerInfoInternal_h
#define sec_SOSPeerInfoInternal_h
+/* Please don't use anything from this file unless you're part of the Security project. */
+
extern const CFStringRef kPIUserDefinedDeviceNameKey;
extern const CFStringRef kPIDeviceModelNameKey;
extern const CFStringRef kPIMessageProtocolVersionKey;
extern const CFStringRef sGestaltKey;
extern const CFStringRef sVersionKey;
+extern CFStringRef SOSGestaltSerial;
+
#endif
CFDictionaryRef gestalt;
CFStringRef peerID;
CFIndex version;
+ CFStringRef verifiedAppKeyID;
+ bool verifiedResult;
+
/* V2 and beyond are listed below */
CFMutableDictionaryRef v2Dictionary;
};
+++ /dev/null
-//
-// SOSPeerInfoSecurityProperties.h
-// sec
-//
-// Created by Richard Murphy on 3/14/15.
-//
-//
-
-#ifndef _sec_SOSPeerInfoSecurityProperties_
-#define _sec_SOSPeerInfoSecurityProperties_
-
-
-#include <CoreFoundation/CFRuntime.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include <Security/SecureObjectSync/SOSCloudCircle.h>
-#include <Security/SecureObjectSync/SOSPeerInfo.h>
-#include <Security/SecureObjectSync/SOSAccount.h>
-
-typedef struct __OpaqueSOSSecurityProperty {
- CFRuntimeBase _base;
- CFStringRef label;
-} *SOSSecurityPropertyRef;
-
-bool SOSSecurityPropertiesSetDefault(SOSPeerInfoRef pi, CFErrorRef *error);
-CFMutableSetRef SOSSecurityPropertiesCreateDefault(SOSPeerInfoRef pi, CFErrorRef *error);
-
-// Basic interfaces to change and query Security Properties
-SOSSecurityPropertyResultCode SOSSecurityPropertyEnable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error);
-SOSSecurityPropertyResultCode SOSSecurityPropertyDisable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error);
-SOSSecurityPropertyResultCode SOSSecurityPropertyQuery(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error);
-
-CFSetRef SOSSecurityPropertyGetAllCurrent(void);
-CFMutableSetRef SOSPeerInfoCopySecurityProperty(SOSPeerInfoRef pi);
-
-#endif /* defined(_sec_SOSPeerInfoSecurityProperties_) */
+++ /dev/null
-//
-// SOSPeerInfoSecurityProperties.c
-// sec
-//
-// Created by Richard Murphy on 3/14/15.
-//
-//
-
-
-#include <AssertMacros.h>
-#include <TargetConditionals.h>
-
-#include "SOSPeerInfoSecurityProperties.h"
-#include <utilities/SecCFWrappers.h>
-#include <utilities/SecCFRelease.h>
-#include <utilities/SecCFError.h>
-#include <Security/SecureObjectSync/SOSInternal.h>
-
-#include <Security/SecureObjectSync/SOSPeerInfo.h>
-#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
-#include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
-#include <Security/SecureObjectSync/SOSCloudCircle.h>
-
-#define secpropMemError CFSTR("Failed to get memory for SecurityProperties in PeerInfo")
-#define secpropUnknownError CFSTR("Unknown Security Property(%@) (SOSSecurityPropertyResultCode=%d)")
-#define secpropInvalidError CFSTR("Peer is invalid for this security property(%@) (SOSSecurityPropertyResultCode=%d)")
-
-const CFStringRef kSOSSecPropertyHasEntropy = CFSTR("SecPropEntropy");
-const CFStringRef kSOSSecPropertyScreenLock = CFSTR("SecPropScreenLock");
-const CFStringRef kSOSSecPropertySEP = CFSTR("SecPropSEP");
-const CFStringRef kSOSSecPropertyIOS = CFSTR("SecPropIOS");
-
-
-CFSetRef SOSSecurityPropertyGetAllCurrent(void) {
- static dispatch_once_t dot;
- static CFMutableSetRef allSecurityProperties = NULL;
- dispatch_once(&dot, ^{
- allSecurityProperties = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
- CFSetAddValue(allSecurityProperties, kSOSSecPropertyHasEntropy);
- CFSetAddValue(allSecurityProperties, kSOSSecPropertyScreenLock);
- CFSetAddValue(allSecurityProperties, kSOSSecPropertySEP);
- CFSetAddValue(allSecurityProperties, kSOSSecPropertyIOS);
- });
- return allSecurityProperties;
-}
-
-static bool SOSSecurityPropertyIsKnownProperty(CFStringRef secPropName) {
- CFSetRef allSecurityProperties = SOSSecurityPropertyGetAllCurrent();
- if(CFSetContainsValue(allSecurityProperties, secPropName)) return true;
- secnotice("SecurityProperties","Not a known Security Property");
- return false;
-}
-
-
-static CFMutableSetRef CFSetCreateMutableForSOSSecurityProperties(CFAllocatorRef allocator) {
- return CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
-}
-
-CFMutableSetRef SOSPeerInfoCopySecurityProperty(SOSPeerInfoRef pi) {
- if (!SOSPeerInfoVersionHasV2Data(pi)) {
- return NULL;
- } else {
- CFMutableSetRef secproperty = (CFMutableSetRef)SOSPeerInfoV2DictionaryCopySet(pi, sSecurityPropertiesKey);
- if (!secproperty)
- secerror("%@ v2 peer has no security properties", SOSPeerInfoGetPeerID(pi));
- return secproperty;
- }
-}
-
-static void SOSPeerInfoSetSecurityProperty(SOSPeerInfoRef pi, CFSetRef newproperties) {
- if(!newproperties) {
- secnotice("secproperty","Asked to swap to NULL Security Properties");
- return;
- }
- SOSPeerInfoV2DictionarySetValue(pi, sSecurityPropertiesKey, newproperties);
-}
-
-static bool SOSPeerInfoSecurityPropertyIsValid(SOSPeerInfoRef pi, CFStringRef propertyname) {
- return true;
-}
-
-CFMutableSetRef SOSSecurityPropertiesCreateDefault(SOSPeerInfoRef pi, CFErrorRef *error) {
- return CFSetCreateMutableForSOSSecurityProperties(NULL);
-}
-
-SOSSecurityPropertyResultCode SOSSecurityPropertyEnable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) {
- SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError;
-
- CFMutableSetRef newSecurityProperties = SOSPeerInfoCopySecurityProperty(pi);
- require_action_quiet(newSecurityProperties, fail,
- SOSCreateError(kSOSErrorAllocationFailure, secpropMemError, NULL, error));
- require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail,
- SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropUnknownError, propertyname, retval = kSOSCCNoSuchSecurityProperty));
- require_action_quiet(SOSPeerInfoSecurityPropertyIsValid(pi, propertyname), fail,
- SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropInvalidError, propertyname, retval = kSOSCCSecurityPropertyNotQualified));
- CFSetAddValue(newSecurityProperties, propertyname);
- SOSPeerInfoSetSecurityProperty(pi, newSecurityProperties);
- CFReleaseSafe(newSecurityProperties);
- return kSOSCCSecurityPropertyValid;
-
-fail:
- CFReleaseNull(newSecurityProperties);
- secnotice("SecurityProperties","Failed to enable Security Property(%@): %@", propertyname, *error);
- return retval;
-}
-
-SOSSecurityPropertyResultCode SOSSecurityPropertyDisable(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) {
- SOSSecurityPropertyResultCode retval = kSOSCCGeneralSecurityPropertyError;
- CFMutableSetRef newSecurityProperties = SOSPeerInfoCopySecurityProperty(pi);
- require_action_quiet(newSecurityProperties, fail,
- SOSCreateError(kSOSErrorAllocationFailure, secpropMemError, NULL, error));
- require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail,
- SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, secpropUnknownError, propertyname, retval = kSOSCCNoSuchSecurityProperty));
-
- CFSetRemoveValue(newSecurityProperties, propertyname);
- SOSPeerInfoSetSecurityProperty(pi, newSecurityProperties);
- CFReleaseSafe(newSecurityProperties);
- return kSOSCCSecurityPropertyNotValid;
-
-fail:
- CFReleaseNull(newSecurityProperties);
- secnotice("SecurityProperties","Failed to disable Security Property(%@): %@", propertyname, *error);
- return retval;
-}
-
-SOSSecurityPropertyResultCode SOSSecurityPropertyQuery(SOSPeerInfoRef pi, CFStringRef propertyname, CFErrorRef *error) {
- SOSSecurityPropertyResultCode retval = kSOSCCNoSuchSecurityProperty;
- secnotice("SecurityProperties", "Querying %@", propertyname);
- require_action_quiet(SOSSecurityPropertyIsKnownProperty(propertyname), fail,
- SOSCreateError(kSOSErrorNameMismatch, secpropUnknownError, NULL, error));
- CFMutableSetRef secproperty = SOSPeerInfoCopySecurityProperty(pi);
- if(!secproperty) return kSOSCCSecurityPropertyNotValid;
- retval = (CFSetContainsValue(secproperty, propertyname)) ? kSOSCCSecurityPropertyValid: kSOSCCSecurityPropertyNotValid;
- CFReleaseNull(secproperty);
-
-fail:
- secnotice("SecurityProperties","Failed to query Security Property(%@): %@", propertyname, *error);
- return retval;
-}
-
extern CFStringRef sV2DictionaryKey; // CFData wrapper for V2 extensions
extern CFStringRef sViewsKey; // Set of Views
extern CFStringRef sSerialNumberKey; // Device Serial Number
-extern CFStringRef sSecurityPropertiesKey; // Set of Security Properties
+extern CFStringRef sMachineIDKey; // Account MID
extern CFStringRef kSOSHsaCrKeyDictionary; // HSA Challenge-Response area
extern CFStringRef sPreferIDS; // Whether or not a peer requires to speak over IDS or KVS
extern CFStringRef sPreferIDSFragmentation; // Whether or not a peer requires to speak over fragmented IDS or not
CFStringRef sV2DictionaryKey = CFSTR("V2DictionaryData"); // CFData wrapper for V2 extensions
CFStringRef sViewsKey = CFSTR("Views"); // Array of View labels
CFStringRef sSerialNumberKey = CFSTR("SerialNumber");
+CFStringRef sMachineIDKey = CFSTR("MachineIDKey");
CFStringRef sViewsPending = CFSTR("ViewsPending"); // Array of View labels (pending)
-CFStringRef sSecurityPropertiesKey = CFSTR("SecurityProperties");
CFStringRef kSOSHsaCrKeyDictionary = CFSTR("HSADictionary");
CFStringRef sRingState = CFSTR("RingState");
CFStringRef sBackupKeyKey = CFSTR("BackupKey");
CFStringRef sEscrowRecord = CFSTR("EscrowRecord");
+CFStringRef SOSGestaltSerial = NULL;
+
#if TARGET_OS_IPHONE
// need entitlement for this:
#include <MobileGestalt.h>
static CFStringRef SOSCopySerialNumberAsString(CFErrorRef *error) {
+ if (SOSGestaltSerial)
+ return CFRetain(SOSGestaltSerial);
+
CFTypeRef iosAnswer = (CFStringRef) MGCopyAnswer(kMGQSerialNumber, NULL);
if(!iosAnswer) {
SOSCreateError(kSOSErrorAllocationFailure, CFSTR("No Memory"), NULL, error);
#include <IOKit/IOKitLib.h>
static CFStringRef SOSCopySerialNumberAsString(CFErrorRef *error) {
+ if (SOSGestaltSerial)
+ return CFRetain(SOSGestaltSerial);
CFStringRef serialNumber = NULL;
CFStringRef retval = NULL;
CFMutableSetRef views = SOSViewCopyViewSet(kViewSetDefault);
CFMutableSetRef secproperties = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
CFDictionaryAddValue(v2Dictionary, sViewsKey, views);
- CFDictionaryAddValue(v2Dictionary, sSecurityPropertiesKey, secproperties);
-
- CFDictionaryAddValue(v2Dictionary, sDeviceID, CFSTR(""));
- CFDictionaryAddValue(v2Dictionary, sTransportType, SOSTransportMessageTypeKVS);
- CFDictionaryAddValue(v2Dictionary, sPreferIDS, kCFBooleanFalse);
- CFDictionaryAddValue(v2Dictionary, sPreferIDSFragmentation, kCFBooleanTrue);
- CFDictionaryAddValue(v2Dictionary, sPreferIDSACKModel, kCFBooleanTrue);
require_action_quiet((v2data = SOSCreateDERFromDictionary(v2Dictionary, error)), out, SOSCreateError(kSOSErrorAllocationFailure, CFSTR("No Memory"), NULL, error));
CFDictionaryAddValue(pi->description, sV2DictionaryKey, v2data);
require_quiet(accumulate_size(&total_payload, der_sizeof_number(gencount, error)), errOut);
require_quiet(accumulate_size(&total_payload, der_sizeof_data_or_null(publicBytes, error)), errOut);
require_quiet(accumulate_size(&total_payload, der_sizeof_data_or_null(signature, error)), errOut);
+ CFReleaseNull(publicBytes);
return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, total_payload);
errOut:
SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
+ CFReleaseNull(publicBytes);
return 0;
}
der_encode_number(gencount, error, der,
der_encode_data_or_null(publicBytes, error, der,
der_encode_data_or_null(signature, error, der, der_end))));
+
+ CFReleaseNull(publicBytes);
+
return der_end;
}
#include <Security/SecItem.h>
-#include <CoreFoundation/CFNumber.h>
-#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFPriv.h>
#include <Security/SecureObjectSync/SOSCloudCircle.h>
#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
#include <Security/SecPasswordGenerate.h>
-/* Copied from CFPriv.h */
-// #include <CoreFoundation/CFPriv.h>
-
-CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
-CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
-CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
-CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
-
-
-
static char *CFDictionaryCopyCStringWithDefault(CFDictionaryRef dict, const void *key, char *defaultString) {
char *retval = NULL;
require_quiet(dict, use_default);
#include <Security/SecureObjectSync/SOSTransportKeyParameter.h>
#include <Security/SecureObjectSync/SOSTransportCircleKVS.h>
#include <Security/SecureObjectSync/SOSTransportMessageKVS.h>
-#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#include <Security/SecureObjectSync/SOSTransportMessage.h>
#include <Security/SecureObjectSync/SOSRing.h>
#include <Security/SecureObjectSync/SOSTransport.h>
#include <Security/SecureObjectSync/SOSTransportMessage.h>
-#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#include <Security/SecureObjectSync/SOSKVSKeys.h>
#include <Security/SecureObjectSync/SOSPeerCoder.h>
#include <Security/SecureObjectSync/SOSEngine.h>
+++ /dev/null
-//
-// SOSTransportMessageIDS.h
-// sec
-//
-//
-#ifndef sec_SOSTransportMessageIDS_h
-#define sec_SOSTransportMessageIDS_h
-
-@class SOSMessage;
-
-typedef enum {
- kIDSStartPingTestMessage = 1,
- kIDSEndPingTestMessage= 2,
- kIDSSendOneMessage = 3,
- kIDSPeerReceivedACK = 4,
- kIDSPeerAvailability = 6,
- kIDSPeerAvailabilityDone = 7,
- kIDSKeychainSyncIDSFragmentation = 8,
- kIDSPeerUsesACK = 9
-} idsOperation;
-
-
-extern const CFStringRef kSecIDSErrorDomain;
-extern const CFStringRef kIDSOperationType;
-extern const CFStringRef kIDSMessageToSendKey;
-extern const CFStringRef kIDSMessageUniqueID;
-extern const CFStringRef kIDSMessageRecipientPeerID;
-extern const CFStringRef kIDSMessageRecipientDeviceID;
-extern const CFStringRef kIDSMessageUsesAckModel;
-extern const CFStringRef kIDSMessageSenderDeviceID;;
-
-@interface SOSMessageIDS : SOSMessage
-{
- CFBooleanRef useFragmentation;
-}
-@property (atomic) CFBooleanRef useFragmentation;
-
--(id) initWithAcount:(SOSAccount*)acct circleName:(CFStringRef)name;
-
--(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)account m:(CFDictionaryRef) message err:(CFErrorRef *)error;
-
--(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct;
-
--(void) SOSTransportMessageIDSSetFragmentationPreference:(SOSMessage*) transport pref:(CFBooleanRef) preference;
--(CFBooleanRef) SOSTransportMessageIDSGetFragmentationPreference:(SOSMessage*) transport;
-
-@end
-#endif
+++ /dev/null
-//
-// SOSTransportMessageIDS.c
-// sec
-//
-//
-#include <Security/SecBasePriv.h>
-#include <Security/SecureObjectSync/SOSTransport.h>
-#import <Security/SecureObjectSync/SOSTransportMessage.h>
-#import <Security/SecureObjectSync/SOSAccountPriv.h>
-#include <Security/SecureObjectSync/SOSKVSKeys.h>
-#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
-
-#include <SOSCloudCircleServer.h>
-#include <Security/SecureObjectSync/SOSAccountPriv.h>
-#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
-
-#include <utilities/SecCFWrappers.h>
-#include <SOSInternal.h>
-#include <AssertMacros.h>
-
-#include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
-#include <SOSCircle/CKBridge/SOSCloudKeychainConstants.h>
-#include <Security/SecureObjectSync/SOSInternal.h>
-#include <utilities/SecADWrapper.h>
-#import "Security/SecureObjectSync/SOSAccountTrustClassic.h"
-
-#define IDS "IDS transport"
-
-@implementation SOSMessageIDS
-
-@synthesize useFragmentation = useFragmentation;
-
--(CFIndex) SOSTransportMessageGetTransportType
-{
- return kIDS;
-}
-
--(void) SOSTransportMessageIDSSetFragmentationPreference:(SOSMessageIDS*) transport pref:(CFBooleanRef) preference
-{
- useFragmentation = preference;
-}
-
--(CFBooleanRef) SOSTransportMessageIDSGetFragmentationPreference:(SOSMessageIDS*) transport
-{
- return useFragmentation;
-}
-
--(id) initWithAcount:(SOSAccount*)acct circleName:(CFStringRef)name
-{
- self = [super init];
-
- if (self) {
- self.useFragmentation = kCFBooleanTrue;
- self.account = acct;
- self.circleName = [[NSString alloc]initWithString:(__bridge NSString*)name];
- [self SOSTransportMessageIDSGetIDSDeviceID:account];
- SOSRegisterTransportMessage((SOSMessage*)self);
- }
-
- return self;
-}
-
--(CFDictionaryRef) CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessage*) transport peerMessages:(CFMutableDictionaryRef) circle_peer_messages_table err:(CFErrorRef *)error
-{
- return CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
-}
-
-static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFStringRef fromDeviceID, CFStringRef fromPeerID, CFStringRef *peerID, SOSPeerInfoRef *theirPeerInfo){
- SOSAccountTrustClassic *trust = account.trust;
- __block HandleIDSMessageReason reason = kHandleIDSMessageDontHandle;
-
- SOSCircleForEachPeer(trust.trustedCircle, ^(SOSPeerInfoRef peer) {
- CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer);
- CFStringRef pID = SOSPeerInfoGetPeerID(peer);
-
- if( deviceID && pID && fromPeerID && fromDeviceID && CFStringGetLength(fromPeerID) != 0 ){
- if(CFStringCompare(pID, fromPeerID, 0) == 0){
- if(CFStringGetLength(deviceID) == 0){
- secnotice("ids transport", "device ID was empty in the peer list, holding on to message");
- CFReleaseNull(deviceID);
- reason = kHandleIDSMessageNotReady;
- return;
- }
- else if(CFStringCompare(fromDeviceID, deviceID, 0) != 0){ //IDSids do not match, ghost
- secnotice("ids transport", "deviceIDMisMatch");
- reason = kHandleIDSmessageDeviceIDMismatch;
- CFReleaseNull(deviceID);
- return;
- }
- else if(CFStringCompare(deviceID, fromDeviceID, 0) == 0){
- *peerID = pID;
- *theirPeerInfo = peer;
- CFReleaseNull(deviceID);
- reason = kHandleIDSMessageSuccess;
- return;
- }
- else{
- secerror("?? deviceID:%@, pID: %@, fromPeerID: %@, fromDeviceID: %@", deviceID, pID, fromPeerID, fromDeviceID);
- }
- }
- }
- CFReleaseNull(deviceID);
- });
-
- return reason;
-}
-
--(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)acct m:(CFDictionaryRef) message err:(CFErrorRef *)error
-{
- secnotice("IDS Transport", "SOSTransportMessageIDSHandleMessage!");
-
- CFStringRef dataKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyIDSDataMessage, kCFStringEncodingASCII);
- CFStringRef deviceIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyDeviceID, kCFStringEncodingASCII);
- CFStringRef sendersPeerIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeySendersPeerID, kCFStringEncodingASCII);
- CFStringRef ourPeerIdKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyPeerID, kCFStringEncodingASCII);
- NSString *errMessage = nil;
-
- HandleIDSMessageReason result = kHandleIDSMessageSuccess;
-
- CFDataRef messageData = asData(CFDictionaryGetValue(message, dataKey), NULL);
- __block CFStringRef fromDeviceID = asString(CFDictionaryGetValue(message, deviceIDKey), NULL);
- __block CFStringRef fromPeerID = (CFStringRef)CFDictionaryGetValue(message, sendersPeerIDKey);
- CFStringRef ourPeerID = asString(CFDictionaryGetValue(message, ourPeerIdKey), NULL);
-
- CFStringRef peerID = NULL;
- SOSPeerInfoRef theirPeer = NULL;
-
- 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);
-
- if ([account.ids_message_transport SOSTransportMessageHandlePeerMessage:account.ids_message_transport id:peerID cm:messageData err:error]) {
- CFMutableDictionaryRef peersToSyncWith = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- CFMutableSetRef peerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(peerIDs, peerID);
- SOSAccountTrustClassic* trust = account.trust;
- //sync using fragmentation?
- if(SOSPeerInfoShouldUseIDSMessageFragmentation(trust.peerInfo, theirPeer)){
- //set useFragmentation bit
- [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanTrue];
- }
- else{
- [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanFalse];
- }
-
- if(![account.ids_message_transport SOSTransportMessageSyncWithPeers:account.ids_message_transport p:peerIDs err:error]){
- secerror("SOSTransportMessageIDSHandleMessage Could not sync with all peers: %@", *error);
- }else{
- secnotice("IDS Transport", "Synced with all peers!");
- }
-
- CFReleaseNull(peersToSyncWith);
- CFReleaseNull(peerIDs);
- }else{
- if(error && *error != NULL){
- CFStringRef errorMessage = CFErrorCopyDescription(*error);
- if (-25308 == CFErrorGetCode(*error)) { // tell KeychainSyncingOverIDSProxy to call us back when device unlocks
- result = kHandleIDSMessageLocked;
- }else{ //else drop it, couldn't handle the message
- result = kHandleIDSMessageDontHandle;
- }
- secerror("IDS Transport Could not handle message: %@, %@", messageData, *error);
- CFReleaseNull(errorMessage);
-
- }
- else{ //no error but failed? drop it, log message
- secerror("IDS Transport Could not handle message: %@", messageData);
- result = kHandleIDSMessageDontHandle;
-
- }
- }
-
-exit:
-
- if(errMessage != nil){
- secerror("%@", errMessage);
- }
- CFReleaseNull(ourPeerIdKey);
- CFReleaseNull(sendersPeerIDKey);
- CFReleaseNull(deviceIDKey);
- CFReleaseNull(dataKey);
- return result;
-}
-
-
-static bool sendToPeer(SOSMessageIDS* transport, bool shouldUseAckModel, CFStringRef circleName, CFStringRef deviceID, CFStringRef peerID,CFDictionaryRef message, CFErrorRef *error)
-{
- __block bool success = false;
- CFStringRef errorMessage = NULL;
- CFDictionaryRef userInfo;
- CFStringRef operation = NULL;
- CFDataRef operationData = NULL;
- CFMutableDataRef mutableData = NULL;
- SOSAccount* account = [transport SOSTransportMessageGetAccount];
- CFStringRef ourPeerID = SOSPeerInfoGetPeerID(account.peerInfo);
- CFStringRef operationToString = NULL;
-
- CFDictionaryRef messagetoSend = NULL;
-
- if(deviceID == NULL || CFStringGetLength(deviceID) == 0){
- errorMessage = CFSTR("Need an IDS Device ID to sync");
- userInfo = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kCFErrorLocalizedDescriptionKey, errorMessage, NULL);
- if(error != NULL){
- *error =CFErrorCreate(kCFAllocatorDefault, CFSTR("com.apple.security.ids.error"), kSecIDSErrorNoDeviceID, userInfo);
- secerror("%@", *error);
- }
- CFReleaseNull(messagetoSend);
- CFReleaseNull(operation);
- CFReleaseNull(operationData);
- CFReleaseNull(mutableData);
- CFReleaseNull(userInfo);
- CFReleaseNull(operationToString);
-
- return success;
- }
-
- if(CFDictionaryGetValue(message, kIDSOperationType) == NULL && [transport SOSTransportMessageIDSGetFragmentationPreference:transport] == kCFBooleanTrue){
- //handle a keychain data blob using fragmentation!
- secnotice("IDS Transport","sendToPeer: using fragmentation!");
-
- operationToString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), kIDSKeychainSyncIDSFragmentation);
- messagetoSend = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- kIDSOperationType, operationToString,
- kIDSMessageRecipientDeviceID, deviceID,
- kIDSMessageRecipientPeerID, peerID,
- kIDSMessageUsesAckModel, (shouldUseAckModel ? CFSTR("YES") : CFSTR("NO")),
- kIDSMessageToSendKey, message,
- NULL);
- }
- else{ //otherhandle handle the test message without fragmentation
- secnotice("IDS Transport","sendToPeer: not going to fragment message");
-
- CFMutableDictionaryRef annotatedMessage = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, message);
- CFDictionaryAddValue(annotatedMessage, kIDSMessageRecipientPeerID, peerID);
- CFDictionaryAddValue(annotatedMessage, kIDSMessageRecipientDeviceID, deviceID);
- CFDictionaryAddValue(annotatedMessage, kIDSMessageUsesAckModel, (shouldUseAckModel ? CFSTR("YES") : CFSTR("NO")));
- CFTransferRetained(messagetoSend, annotatedMessage);
- CFReleaseNull(annotatedMessage);
- }
-
- dispatch_semaphore_t wait_for = dispatch_semaphore_create(0);
-
- secnotice("IDS Transport", "Starting");
-
- SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.sendids"), 1);
-
- 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);
- }
-
- dispatch_semaphore_signal(wait_for);
- });
-
- if (dispatch_semaphore_wait(wait_for, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 2)) != 0) {
- secerror("IDS Transport: timed out waiting for message send to complete");
- }
-
- if(!success){
- if(error != NULL)
- secerror("IDS Transport: Failed to send message to peer! %@", *error);
- else
- secerror("IDS Transport: Failed to send message to peer");
- }
- else{
- secnotice("IDS Transport", "Sent message to peer!");
- }
- CFReleaseNull(myDeviceID);
- CFReleaseNull(messagetoSend);
- CFReleaseNull(operation);
- CFReleaseNull(operationData);
- CFReleaseNull(mutableData);
- CFReleaseNull(operationToString);
- return success;
-}
-
-
--(bool) SOSTransportMessageSyncWithPeers:(SOSMessageIDS*) transport p:(CFSetRef) peers err:(CFErrorRef *)error
-{
- // Each entry is keyed by circle name and contains a list of peerIDs
- __block bool result = true;
-
- CFSetForEach(peers, ^(const void *value) {
- CFStringRef peerID = asString(value, NULL);
-
- result &= [transport SOSTransportMessageSendMessageIfNeeded:transport id:(__bridge CFStringRef)(transport.circleName) pID:peerID err:error];
- });
-
- return result;
-}
-
--(bool) SOSTransportMessageSendMessages:(SOSMessageIDS*) transport pm:(CFDictionaryRef) peer_messages err:(CFErrorRef *)error
-{
- __block bool result = true;
-
- SOSPeerInfoRef myPeer = transport->account.peerInfo;
- CFStringRef myID = SOSPeerInfoGetPeerID(myPeer);
- if(!myPeer)
- return result;
-
- CFDictionaryForEach(peer_messages, ^(const void *key, const void *value) {
- CFErrorRef error = NULL;
-
- SOSPeerInfoRef peer = NULL;
- CFStringRef deviceID = NULL;
- CFDictionaryRef message = NULL;
-
- CFStringRef peerID = asString(key, &error);
- require_quiet(peerID, skip);
- require_quiet(!CFEqualSafe(myID, key), skip);
-
- message = CFRetainSafe(asDictionary(value, &error));
- if (message == NULL) {
- // If it's not a data, return the error
- CFDataRef messageData = asData(value, NULL);
- if (messageData) {
- CFReleaseNull(error);
- message = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, peerID, messageData, NULL);
- }
- }
- require_quiet(message, skip);
-
- peer = SOSAccountCopyPeerWithID(transport->account, peerID, &error);
- require_quiet(peer, skip);
-
- deviceID = SOSPeerInfoCopyDeviceID(peer);
- require_action_quiet(deviceID, skip, SOSErrorCreate(kSOSErrorSendFailure, &error, NULL, CFSTR("No IDS ID")));
-
- [transport SOSTransportMessageIDSSetFragmentationPreference:transport
- pref:SOSPeerInfoShouldUseIDSMessageFragmentation(myPeer, peer) ? kCFBooleanTrue : kCFBooleanFalse];
- bool shouldUseAckModel = SOSPeerInfoShouldUseACKModel(myPeer, peer);
-
- result &= sendToPeer(transport, shouldUseAckModel, (__bridge CFStringRef)(transport.circleName), deviceID, peerID, message, &error);
-
- skip:
- if (error) {
- secerror("Failed to sync to %@ over IDS: %@", peerID, error);
- }
-
- CFReleaseNull(peer);
- CFReleaseNull(deviceID);
- CFReleaseNull(message);
-
- CFReleaseNull(error);
- });
-
- return result;
-}
-
-
--(bool) SOSTransportMessageFlushChanges:(SOSMessageIDS*) transport err:(CFErrorRef *)error
-{
- return true;
-}
-
--(bool) SOSTransportMessageCleanupAfterPeerMessages:(SOSMessageIDS*) transport peers:(CFDictionaryRef) peers err:(CFErrorRef*) error
-{
- return true;
-}
-
--(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct
-{
- SOSAccountTrustClassic* trust = acct.trust;
- CFStringRef deviceID = SOSPeerInfoCopyDeviceID(trust.peerInfo);
- bool hasDeviceID = (deviceID != NULL && CFStringGetLength(deviceID) != 0) || account.deviceID;
- CFReleaseNull(deviceID);
-
- if(!hasDeviceID){
- SOSCloudKeychainGetIDSDeviceID(^(CFDictionaryRef returnedValues, CFErrorRef sync_error){
- bool success = (sync_error == NULL);
- if (!success) {
- secerror("Could not ask KeychainSyncingOverIDSProxy for Device ID: %@", sync_error);
- }
- else{
- secnotice("IDS Transport", "Successfully attempting to retrieve the IDS Device ID");
- }
- });
- }
-
- return hasDeviceID;
-}
-@end
return true;
}
-static bool SOSTransportMessageKVSSendPendingChanges(SOSMessageKVS* transport, CFErrorRef *error) {
- CFErrorRef changeError = NULL;
-
- if (transport->pending_changes == NULL || CFDictionaryGetCount(transport->pending_changes) == 0) {
- CFReleaseNull(transport->pending_changes);
- return true;
- }
- SOSAccount* acct = [transport SOSTransportMessageGetAccount];
- CFTypeRef dsid = SOSAccountGetValue(acct, kSOSDSIDKey, error);
-
- if(dsid == NULL)
- dsid = kCFNull;
-
- CFDictionaryAddValue(transport->pending_changes, kSOSKVSRequiredKey, dsid);
-
- bool success = SOSTransportMessageKVSUpdateKVS(transport, transport->pending_changes, &changeError);
- if (success) {
- CFDictionaryRemoveAllValues(transport->pending_changes);
- } else {
- SOSCreateErrorWithFormat(kSOSErrorSendFailure, changeError, error, NULL,
- CFSTR("Send changes block failed [%@]"), transport->pending_changes);
- }
-
- return success;
-}
-
static void SOSTransportMessageKVSAddToPendingChanges(SOSMessageKVS* transport, CFStringRef message_key, CFDataRef message_data){
if (transport.pending_changes == NULL) {
transport.pending_changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
return true;
}
--(bool) SOSTransportMssageFlushChanges:(SOSMessage*) transport err:(CFErrorRef *)error
-{
- return SOSTransportMessageKVSSendPendingChanges((SOSMessageKVS*) transport, error);
-}
-
@end
kSyncWithAllPeersLocked,
} SyncWithAllPeersReason;
-typedef enum HandleIDSMessageReason {
- kHandleIDSMessageDontHandle = 0,
- kHandleIDSMessageNotReady,
- kHandleIDSMessageSuccess,
- kHandleIDSMessageLocked,
- kHandleIDSmessageDeviceIDMismatch
-} HandleIDSMessageReason;
-
/*
* Piggy backing codes
*/
};
typedef int SOSViewActionCode;
-/*
- SecurityProperty Result Codes
- */
-enum {
- kSOSCCGeneralSecurityPropertyError = 0,
- kSOSCCSecurityPropertyValid = 1,
- kSOSCCSecurityPropertyNotValid = 2,
- kSOSCCSecurityPropertyNotQualified = 3,
- kSOSCCNoSuchSecurityProperty = 4,
- kSOSCCSecurityPropertyPending = 5,
-};
-typedef int SOSSecurityPropertyResultCode;
-
-
-/*
- SecurityProperty Action Codes
- */
-enum {
- kSOSCCSecurityPropertyEnable = 1,
- kSOSCCSecurityPropertyDisable = 2,
- kSOSCCSecurityPropertyQuery = 3,
-};
-typedef int SOSSecurityPropertyActionCode;
-
#if __OBJC__
#import <Foundation/Foundation.h>
@protocol SOSControlProtocol <NSObject>
- (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))complete;
- (void)kvsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply;
-- (void)idsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply;
- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary <NSString *, NSString *> *))reply;
- (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))complete;
CFSetRef SOSViewsGetAllCurrent(void);
void SOSViewsForEachDefaultEnabledViewName(void (^operation)(CFStringRef viewName));
+CFSetRef SOSViewCreateSetFromBitmask(uint64_t bitmask);
+
// Test constraints
void SOSViewsSetTestViewsSet(CFSetRef testViewNames);
return allViews;
}
+static CFDictionaryRef SOSViewsGetBitmasks(void) {
+ static dispatch_once_t once;
+ static CFMutableDictionaryRef masks = NULL;
+
+ dispatch_once(&once, ^{
+ CFSetRef views = SOSViewsGetAllCurrent();
+ CFMutableArrayRef viewArray = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+ CFSetForEach(views, ^(const void *value) {
+ CFStringRef viewName = (CFStringRef) value;
+ CFArrayAppendValue(viewArray, viewName);
+ });
+ CFIndex viewCount = CFArrayGetCount(viewArray);
+ if(viewCount > 32) {
+ secnotice("views", "Too many views defined, can't make bitmask (%d)", (int) viewCount);
+ } else {
+ __block uint32_t maskValue = 1;
+ CFRange all = CFRangeMake(0, viewCount);
+ CFArraySortValues(viewArray, all, (CFComparatorFunction)CFStringCompare, NULL);
+ masks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, NULL);
+ CFArrayForEach(viewArray, ^(const void *value) {
+ CFDictionaryAddValue(masks, value, (const void *) (uintptr_t) maskValue);
+ maskValue <<= 1;
+ });
+ }
+ CFReleaseNull(viewArray);
+ });
+ return masks;
+}
+
+static uint64_t SOSViewBitmaskFromSet(CFSetRef views) {
+ __block uint64_t retval = 0;
+ CFDictionaryRef masks = SOSViewsGetBitmasks();
+ if(masks) {
+ CFSetForEach(views, ^(const void *viewName) {
+ uint64_t viewMask = (uint64_t) CFDictionaryGetValue(masks, viewName);
+ retval |= viewMask;
+ });
+ }
+ return retval;
+}
+
+uint64_t SOSPeerInfoViewBitMask(SOSPeerInfoRef pi) {
+ __block uint64_t retval = 0;
+ CFSetRef views = SOSPeerInfoCopyEnabledViews(pi);
+ if(views) {
+ retval = SOSViewBitmaskFromSet(views);
+ CFReleaseNull(views);
+ }
+ return retval;
+}
+
+CFSetRef SOSViewCreateSetFromBitmask(uint64_t bitmask) {
+ CFMutableSetRef retval = NULL;
+ CFDictionaryRef masks = SOSViewsGetBitmasks();
+ if(masks) {
+ retval = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
+ CFDictionaryForEach(masks, ^(const void *key, const void *value) {
+ CFStringRef viewName = (CFStringRef) key;
+ uint64_t viewMask = (uint64_t) value;
+ if(bitmask & viewMask) {
+ CFSetAddValue(retval, viewName);
+ }
+ });
+ }
+ return retval;
+}
+
const char *SOSViewsXlateAction(SOSViewActionCode action) {
switch(action) {
case kSOSCCViewEnable: return "kSOSCCViewEnable";
DOVIEWMACRO(AutoUnlock, "AutoUnlock", "autounlock", CKKS, D, , A, , )
DOVIEWMACRO(Health, "Health", "health", CKKS, D, , A, , )
DOVIEWMACRO(ApplePay, "ApplePay", "applepay", CKKS, D, , A, , )
+DOVIEWMACRO(Home, "Home", "home", CKKS, D, , A, , )
#include <Security/SecItem.h>
-#include <CoreFoundation/CFNumber.h>
-#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFPriv.h>
#include <Security/SecureObjectSync/SOSCloudCircle.h>
#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
#include <Security/SecPasswordGenerate.h>
-/* Copied from CFPriv.h */
-// #include <CoreFoundation/CFPriv.h>
-
-CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
-CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
-CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
-CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
-
#define MAXKVSKEYTYPE kUnknownKey
#define DATE_LENGTH 18
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;
+ if(!peer) { return; }
CFIndex version = SOSPeerInfoGetVersion(peer);
CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
CFStringRef devtype = SOSPeerInfoGetPeerDeviceType(peer);
CFStringRef peerID = SOSPeerInfoGetPeerID(peer);
CFStringRef transportType = CFSTR("KVS");
CFStringRef deviceID = CFSTR("");
+ CFStringRef machineID = CFSTR("");
CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer);
- CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion"));
-
-
+ CFStringRef osVersion = CFSTR("Unknown");
+ if(gestalt) {
+ osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion"));
+ }
+
if(version >= 2){
CFDictionaryRef v2Dictionary = peer->v2Dictionary;
- transportType = CFDictionaryGetValue(v2Dictionary, sTransportType);
- deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID);
+ if(v2Dictionary) {
+ transportType = CFDictionaryGetValue(v2Dictionary, CFSTR("TransportType"));
+ deviceID = CFDictionaryGetValue(v2Dictionary, CFSTR("DeviceID"));
+ machineID = CFDictionaryGetValue(v2Dictionary, CFSTR("MachineIDKey"));
+ }
}
char *pname = CFStringToCString(peerName);
char *dname = CFStringToCString(devtype);
- char *tname = CFStringToCString(transportType);
+ char *tname = transportType ? CFStringToCString(transportType) : CFStringToCString(CFSTR("KVS"));
char *iname = CFStringToCString(deviceID);
+ char *mname = CFStringToCString(machineID);
const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " ";
-
-
- snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-36s", me, label, pname, dname, tname, iname);
-
+
+
+ snprintf(buf, 160, "%s %s: %-16s dev:%-16s trn:%-16s devid:%-36s mid: %-36s", me, label, pname, dname, tname, iname, mname);
+
free(pname);
free(dname);
free(tname);
free(iname);
+ free(mname);
// %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("%@ %@ V%d OS:%@\n"), bufstr, pid, vers, osVersion ?: CFSTR(""));
+ printmsg(CFSTR("%@ pid:%@ V%d OS:%@\n"), bufstr, pid, vers, osVersion ?: CFSTR(""));
CFRelease(bufstr);
CFReleaseNull(gestalt);
#include <Security/SecItem.h>
-#include <CoreFoundation/CFNumber.h>
-#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFPriv.h>
#include <Security/SecureObjectSync/SOSCloudCircle.h>
#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
return retval;
}
-// #include <CoreFoundation/CFPriv.h>
-
-CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
-CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
-CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
-CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
-
static char *CFDictionaryCopyCString(CFDictionaryRef dict, const void *key) {
CFStringRef val = CFDictionaryGetValue(dict, key);
char *retval = CFStringToCString(val);
" -4 delete engine state from the keychain\n"
" -5 cleanup old KVS keys in KVS\n"
" -6 [test]populate KVS with garbage KVS keys\n"
-
- "\n"
- "IDS\n"
- " -g set IDS device id\n"
- " -p retrieve IDS device id\n"
- " -x ping all devices in an IDS account\n"
- " -w check IDS availability\n"
- " -z retrieve IDS id through KeychainSyncingOverIDSProxy\n"
+ "\n"
+ "Circle Tools\n"
+ " --remove-peer SPID Remove a peer identified by the first 8 or more\n"
+ " characters of its spid. Specify multiple times to\n"
+ " remove more than one peer.\n"
"\n"
"Password\n"
" -P [label:]password set password (optionally for a given label) for sync\n"
" viewnames are: keychain|masterkey|iclouddrive|photos|cloudkit|escrow|fde|maildrop|icloudbackup|notes|imessage|appletv|homekit\n"
" wifi|passwords|creditcards|icloudidentity|othersyncable\n"
" -L list all known view and their status\n"
- " -S [enable|disable|propertyname] enable, disable, or query my PeerInfo's Security Property set\n"
- " propertynames are: hasentropy|screenlock|SEP|IOS\n"
" -U purge private key material cache\n"
" -V Report View Sync Status on all known clients.\n"
" -Y Report yet to initial sync views\n"
#include <sys/utsname.h>
#include <sys/stat.h>
#include <time.h>
+#include <getopt.h>
+#include <readpassphrase.h>
#include <Security/SecItem.h>
return returned;
}
+/*
+ * Prompt user, call SOSCCTryUserCredentials.
+ * Does not support optional label syntax like -T/-P.
+ * Returns true on success.
+ */
+static bool
+promptAndTryPassword(CFErrorRef *error)
+{
+ bool success = false;
+ char passbuf[1024];
+ CFDataRef password;
+
+ if (readpassphrase("iCloud password: ", passbuf, sizeof(passbuf), RPP_REQUIRE_TTY) != NULL) {
+ password = CFDataCreate(NULL, (const UInt8 *)passbuf, strlen(passbuf));
+ if (password != NULL) {
+ success = SOSCCTryUserCredentials(CFSTR("security command line tool"), password, error);
+ CFReleaseNull(password);
+ }
+ }
+
+ return success;
+}
+
static bool syncAndWait(CFErrorRef *err)
{
__block CFTypeRef objects = NULL;
return false;
}
-static CFStringRef convertStringToProperty(char *propertyname) {
- CFStringRef propertyspec = NULL;
-
- if(strcmp(propertyname, "hasentropy") == 0) {
- propertyspec = kSOSSecPropertyHasEntropy;
- } else if(strcmp(propertyname, "screenlock") == 0) {
- propertyspec = kSOSSecPropertyScreenLock;
- } else if(strcmp(propertyname, "SEP") == 0) {
- propertyspec = kSOSSecPropertySEP;
- } else if(strcmp(propertyname, "IOS") == 0) {
- propertyspec = kSOSSecPropertyIOS;
- }
- return propertyspec;
-}
-
-
-static CFStringRef convertPropertyReturnCodeToString(SOSSecurityPropertyResultCode ac) {
- CFStringRef retval = NULL;
- switch(ac) {
- case kSOSCCGeneralSecurityPropertyError:
- retval = CFSTR("General Error"); break;
- case kSOSCCSecurityPropertyValid:
- retval = CFSTR("Is Member of Security Property"); break;
- case kSOSCCSecurityPropertyNotValid:
- retval = CFSTR("Is Not Member of Security Property"); break;
- case kSOSCCSecurityPropertyNotQualified:
- retval = CFSTR("Is not qualified for Security Property"); break;
- case kSOSCCNoSuchSecurityProperty:
- retval = CFSTR("No Such Security Property"); break;
- }
- return retval;
-}
-
-
-static bool SecPropertycmd(char *itemName, CFErrorRef *err) {
- char *cmd, *propertyname;
- SOSSecurityPropertyActionCode ac = kSOSCCSecurityPropertyQuery;
- CFStringRef propertyspec;
-
- propertyname = strchr(itemName, ':');
- if(propertyname == NULL) return false;
- *propertyname = 0;
- propertyname++;
- cmd = itemName;
-
- if(strcmp(cmd, "enable") == 0) {
- ac = kSOSCCSecurityPropertyEnable;
- } else if(strcmp(cmd, "disable") == 0) {
- ac = kSOSCCSecurityPropertyDisable;
- } else if(strcmp(cmd, "query") == 0) {
- ac = kSOSCCSecurityPropertyQuery;
- } else {
- return false;
- }
-
- propertyspec = convertStringToProperty(propertyname);
- if(!propertyspec) return false;
-
- SOSSecurityPropertyResultCode rc = SOSCCSecurityProperty(propertyspec, ac, err);
- CFStringRef resultString = convertPropertyReturnCodeToString(rc);
-
- printmsg(CFSTR("Property Result: %@ : %@\n"), resultString, propertyspec);
- return true;
-}
-
-
static void dumpStringSet(CFStringRef label, CFSetRef s) {
if(!s || !label) return;
CFBooleanRef preferIDSACKModel = SOSPeerInfoV2DictionaryCopyBoolean(myPeer, sPreferIDSACKModel);
CFStringRef transportType = SOSPeerInfoV2DictionaryCopyString(myPeer, sTransportType);
CFStringRef idsDeviceID = SOSPeerInfoV2DictionaryCopyString(myPeer, sDeviceID);
- CFMutableSetRef properties = SOSPeerInfoV2DictionaryCopySet(myPeer, sSecurityPropertiesKey);
-
+
printmsg(CFSTR("Serial#: %@ PrefIDS#: %@ PrefFragmentation#: %@ PrefACK#: %@ transportType#: %@ idsDeviceID#: %@\n"),
serialNumber, preferIDS, preferIDSFragmentation, preferIDSACKModel, transportType, idsDeviceID);
+
+ printmsg(CFSTR("Serial#: %@\n"),
+ serialNumber);
dumpStringSet(CFSTR(" Views: "), views);
- dumpStringSet(CFSTR("SecurityProperties: "), properties);
-
+
+
CFReleaseSafe(serialNumber);
CFReleaseSafe(preferIDS);
CFReleaseSafe(preferIDSFragmentation);
CFReleaseSafe(views);
CFReleaseSafe(transportType);
CFReleaseSafe(idsDeviceID);
- CFReleaseSafe(properties);
-
}
bool ret = myPeer != NULL;
return !hadError;
}
+#pragma mark -
+#pragma mark --remove-peer
+
+static void
+add_matching_peerinfos(CFMutableArrayRef list, CFArrayRef spids, CFArrayRef (*copy_peer_func)(CFErrorRef *))
+{
+ CFErrorRef error;
+ CFArrayRef peers;
+ SOSPeerInfoRef pi;
+ CFStringRef spid;
+ CFIndex i, j;
+
+ peers = copy_peer_func(&error);
+ if (peers != NULL) {
+ for (i = 0; i < CFArrayGetCount(peers); i++) {
+ pi = (SOSPeerInfoRef)CFArrayGetValueAtIndex(peers, i);
+ for (j = 0; j < CFArrayGetCount(spids); j++) {
+ spid = (CFStringRef)CFArrayGetValueAtIndex(spids, j);
+ if (CFStringGetLength(spid) < 8) {
+ continue;
+ }
+ if (CFStringHasPrefix(SOSPeerInfoGetPeerID(pi), spid)) {
+ CFArrayAppendValue(list, pi);
+ }
+ }
+ }
+ CFRelease(peers);
+ } else {
+ // unlikely
+ CFShow(error);
+ CFRelease(error);
+ }
+}
+
+static CFArrayRef
+copy_peerinfos(CFArrayRef spids)
+{
+ CFMutableArrayRef matches;
+
+ matches = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ add_matching_peerinfos(matches, spids, SOSCCCopyValidPeerPeerInfo);
+ add_matching_peerinfos(matches, spids, SOSCCCopyNotValidPeerPeerInfo);
+ add_matching_peerinfos(matches, spids, SOSCCCopyRetirementPeerInfo);
+
+ return matches;
+}
+
+static bool
+doRemovePeers(CFArrayRef peerids, CFErrorRef *error)
+{
+ bool success = false;
+ CFArrayRef peers = NULL;
+ CFErrorRef localError = NULL;
+ CFIndex i;
+ char buf[16];
+
+ peers = copy_peerinfos(peerids);
+ if (peers == NULL || CFArrayGetCount(peers) == 0) {
+ fprintf(stdout, "No matching peers to remove.\n");
+ success = true;
+ goto done;
+ }
+
+ fprintf(stdout, "Matched the following devices:\n");
+ for (i = 0; i < CFArrayGetCount(peers); i++) {
+ // Ugly.
+ CFShow(CFArrayGetValueAtIndex(peers, i));
+ }
+
+ if (readpassphrase("Confirm removal (y/N): ", buf, sizeof(buf), RPP_ECHO_ON | RPP_FORCEUPPER) == NULL) {
+ goto done;
+ }
+
+ if (buf[0] != 'Y') {
+ success = true;
+ goto done;
+ }
+
+ success = SOSCCRemovePeersFromCircle(peers, &localError);
+ if (!success && isSOSErrorCoded(localError, kSOSErrorPrivateKeyAbsent)) {
+ CFReleaseNull(localError);
+
+ success = promptAndTryPassword(&localError);
+ if (success) {
+ success = SOSCCRemovePeersFromCircle(peers, &localError);
+ }
+ }
+
+done:
+ CFReleaseNull(peers);
+
+ if (!success && error != NULL) {
+ *error = localError;
+ } else {
+ CFReleaseNull(localError);
+ }
+
+ return success;
+}
+
+#pragma mark -
// enable, disable, accept, reject, status, Reset, Clear
int
" -4 delete engine state from the keychain"
" -5 cleanup old KVS keys in KVS"
" -6 [test]populate KVS with garbage KVS keys
- "
- "IDS"
- " -g set IDS device id"
- " -p retrieve IDS device id"
- " -x ping all devices in an IDS account"
- " -w check IDS availability"
- " -z retrieve IDS id through KeychainSyncingOverIDSProxy"
"
"Password"
" -P [label:]password set password (optionally for a given label) for sync"
" viewnames are: keychain|masterkey|iclouddrive|photos|cloudkit|escrow|fde|maildrop|icloudbackup|notes|imessage|appletv|homekit|"
" wifi|passwords|creditcards|icloudidentity|othersyncable"
" -L list all known view and their status"
- " -S [enable|disable|propertyname] enable, disable, or query my PeerInfo's Security Property set"
- " propertynames are: hasentropy|screenlock|SEP|IOS\n"
" -U purge private key material cache\n"
" -V Report View Sync Status on all known clients.\n"
" -H Set escrow record.\n"
" -J Get the escrow record.\n"
" -M Check peer availability.\n"
*/
- int ch, result = 0;
+ enum {
+ SYNC_REMOVE_PEER,
+ };
+ int action = -1;
+ const struct option longopts[] = {
+ { "remove-peer", required_argument, &action, SYNC_REMOVE_PEER, },
+ { NULL, 0, NULL, 0, },
+ };
+ int ch, result = 0;
CFErrorRef error = NULL;
bool hadError = false;
+ CFMutableArrayRef peers2remove = NULL;
SOSLogSetOutputTo(NULL, NULL);
- while ((ch = getopt(argc, argv, "ab:deg:hikl:mopq:rSv:w:x:zA:B:MNJCDEF:HG:ILOP:RT:UWX:VY0123456")) != -1)
+ while ((ch = getopt_long(argc, argv, "ab:deg:hikl:mopq:rSv:w:x:zA:B:MNJCDEF:HG:ILOP:RT:UWX:VY0123456", longopts, NULL)) != -1)
switch (ch) {
case 'l':
{
notify_post(kSOSCCCircleChangedNotification);
break;
}
-
- case 'p':
- {
- fprintf(outFile, "Grabbing DS ID\n");
- CFStringRef deviceID = SOSCCCopyDeviceID(&error);
- if (error) {
- hadError = true;
- break;
- }
- if (!isNull(deviceID)) {
- const char *id = CFStringGetCStringPtr(deviceID, kCFStringEncodingUTF8);
- if (id)
- fprintf(outFile, "IDS Device ID: %s\n", id);
- else
- fprintf(outFile, "IDS Device ID is null!\n");
- }
- CFReleaseNull(deviceID);
- break;
- }
-
- case 'g':
- {
- fprintf(outFile, "Setting DS ID: %s\n", optarg);
- CFStringRef deviceID = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
- hadError = SOSCCSetDeviceID(deviceID, &error);
- CFReleaseNull(deviceID);
- break;
- }
-
- case 'w':
- {
- fprintf(outFile, "Attempting to send this message over IDS: %s\n", optarg);
- CFStringRef message = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
- hadError = SOSCCIDSServiceRegistrationTest(message, &error);
- if (error) {
- printerr(CFSTR("IDS is not ready: %@\n"), error);
- CFRelease(error);
- }
- CFReleaseNull(message);
- break;
- }
-
- case 'x':
- {
- fprintf(outFile, "Starting ping test using this message: %s\n", optarg);
- CFStringRef message = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8);
- hadError = SOSCCIDSPingTest(message, &error);
- if (error) {
- printerr(CFSTR("Ping test failed to start: %@\n"), error);
- CFRelease(error);
- }
- CFReleaseNull(message);
- break;
- }
-
- case 'z':
- hadError = SOSCCIDSDeviceIDIsAvailableTest(&error);
- if (error) {
- printerr(CFSTR("Failed to retrieve IDS device ID: %@\n"), error);
- CFRelease(error);
- }
- break;
-
case 'e':
fprintf(outFile, "Turning ON keychain syncing\n");
hadError = requestToJoinCircle(&error);
CFReleaseNull(attempts);
hadError = false;
break;
- }
- case 'M':
- {
- bool success = SOSCCCheckPeerAvailability(&error);
- if(success)
- hadError = false;
- else
- hadError = true;
- break;
}
case 'I':
{
hadError = !listviewcmd(&error);
break;
- case 'S':
- hadError = !SecPropertycmd(optarg, &error);
- break;
-
case 'b':
hadError = setBag(optarg, &error);
break;
case 'Y':
hadError = dumpYetToSync(&error);
break;
+ case 0:
+ switch (action) {
+ case SYNC_REMOVE_PEER: {
+ CFStringRef optstr;
+ optstr = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8);
+ if (peers2remove == NULL) {
+ peers2remove = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
+ CFArrayAppendValue(peers2remove, optstr);
+ CFRelease(optstr);
+ break;
+ }
+ default:
+ return SHOW_USAGE_MESSAGE;
+ }
+ break;
case '?':
- default:
- return SHOW_USAGE_MESSAGE;
- }
+ default:
+ return SHOW_USAGE_MESSAGE;
+ }
- if (hadError)
+ if (peers2remove != NULL) {
+ hadError = !doRemovePeers(peers2remove, &error);
+ CFRelease(peers2remove);
+ }
+
+ if (hadError) {
printerr(CFSTR("Error: %@\n"), error);
+ }
- return result;
+ return result;
}
ONE_TEST(si_78_query_attrs)
ONE_TEST(si_80_empty_data)
ONE_TEST(si_82_token_ag)
-ONE_TEST(si_89_cms_hash_agility)
ONE_TEST(si_90_emcs)
ONE_TEST(si_95_cms_basic)
}
static
-void
-pbkdf2_hmac_sha1_deriviation(const uint8_t *passphrase, size_t passphrase_length,
+OSStatus
+pbkdf2_hmac_sha1_derivation(const uint8_t *passphrase, size_t passphrase_length,
const uint8_t *salt, size_t salt_length,
size_t iterations,
uint8_t *key_out, size_t key_length)
{
// MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20;
- uint8_t temp_data[3*20+salt_length];
+ uint8_t *temp_data = malloc(3*20+salt_length);
+
+ if (temp_data == NULL) {
+ return errSecMemoryError;
+ }
pbkdf2(hmac_sha1, 20, passphrase, passphrase_length,
salt, salt_length, iterations, key_out, key_length, temp_data);
+
+ free(temp_data);
+
+ return errSecSuccess;
}
}
#endif
-static int kTestTestCount = 4;
+static int kTestTestCount = 8;
static void tests(void)
{
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-1");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-1");
}
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-2");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-2");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-2");
}
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-4096");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-4096");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-4096");
}
SKIP: {
- skip("16777216 iterations is too slow", 1, 0);
+ skip("16777216 iterations is too slow", 2, 0);
const char *password = "password";
const char *salt = "salt";
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1_deriviation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1_derivation((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-16777216");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'Salt' I-16777216");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'Salt' I-16777216");
}
}
#include "Security_regressions.h"
-static int kTestTestCount = 8;
+static int kTestTestCount = 16;
static void tests(void)
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-1");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-1");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-1");
}
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-2");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-2");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-2");
}
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-4096");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096");
}
SKIP: {
uint8_t actual[resultSize];
- pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha1((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-16777216");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216");
}
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-1");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-1");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-1");
CFReleaseSafe(password);
CFReleaseSafe(salt);
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-2");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-2");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-2");
CFReleaseSafe(password);
CFReleaseSafe(salt);
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-4096");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-4096");
CFReleaseSafe(password);
CFReleaseSafe(salt);
}
SKIP: {
- skip("16777216 iterations is too slow", 1, 0);
+ skip("16777216 iterations is too slow", 2, 0);
CFStringRef password = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8);
CFStringRef salt = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8);
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA1(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-1: Failed Key Derivation I-16777216");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-1: P-'password' S-'salt' I-16777216");
CFReleaseSafe(password);
CFReleaseSafe(salt);
#include "Security_regressions.h"
-static int kTestTestCount = 8;
+static int kTestTestCount = 16;
static void tests(void)
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-1");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-1");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-1");
}
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-2");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-2");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-2");
}
{
uint8_t actual[resultSize];
- pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-4096");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096");
}
SKIP: {
uint8_t actual[resultSize];
- pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize);
+ is(pbkdf2_hmac_sha256((const uint8_t*) password, strlen(password), (const uint8_t*) salt, strlen(salt), iterations, actual, resultSize), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-16777216");
- ok(memcmp(expected, actual, resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216");
+ is(memcmp(expected, actual, resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216");
}
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-1");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-1");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-1");
CFReleaseSafe(password);
CFReleaseSafe(salt);
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-2");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-2");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-2");
CFReleaseSafe(password);
CFReleaseSafe(salt);
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess, "pbkdf-sha-256: Failed Key Derivation I-4096");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-4096");
CFReleaseSafe(password);
CFReleaseSafe(salt);
}
SKIP: {
- skip("16777216 iterations is too slow", 1, 0);
+ skip("16777216 iterations is too slow", 2, 0);
CFStringRef password = CFStringCreateWithCString(NULL, "password", kCFStringEncodingUTF8);
CFStringRef salt = CFStringCreateWithCString(NULL, "salt", kCFStringEncodingUTF8);
CFMutableDataRef resultData = CFDataCreateMutable(NULL, resultSize);
CFDataIncreaseLength(resultData, resultSize);
- SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData);
+ is(SecKeyFromPassphraseDataHMACSHA256(passwordData, saltData, iterations, resultData), errSecSuccess,
+ "pbkdf-sha-256: P-'password' S-'salt' I-16777216");
- ok(memcmp(expected, CFDataGetBytePtr(resultData), resultSize) == 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216");
+ is(memcmp(expected, CFDataGetBytePtr(resultData), resultSize), 0, "pbkdf-sha-256: P-'password' S-'salt' I-16777216");
CFReleaseSafe(password);
CFReleaseSafe(salt);
CFReleaseNull(query2);
query2 = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, results);
CFReleaseNull(results);
- CFDictionaryRemoveValue(query2, kSecAttrSHA1),
+ CFDictionaryRemoveValue(query2, kSecAttrSHA1);
CFDictionarySetValue(query2, kSecClass, kSecClassInternetPassword);
CFDictionarySetValue(query2, kSecReturnData, kCFBooleanTrue);
ok_status(SecItemCopyMatching(query2, &results), "find internet password using returned attributes");
SecKeyRef pubkey = NULL;
require_action(cert, blockOut,
fail("Failed to parse cert with SPKI error: %@", url));
-#if TARGET_OS_OSX
- pubkey = SecCertificateCopyPublicKey_ios(cert);
-#else
- pubkey = SecCertificateCopyPublicKey(cert);
-#endif
+ pubkey = SecCertificateCopyKey(cert);
is(pubkey, NULL, "Successfully parsed bad SPKI: %@", url);
blockOut:
{
SecTrustRef trust = NULL;
CFArrayRef _anchors = NULL, certs = NULL, anchors = NULL, replacementPolicies;
- SecCertificateRef cert0 = NULL, cert1 = NULL, _root = NULL, cert_xedge2 = NULL, garthc2 = NULL;
+ SecCertificateRef cert0 = NULL, cert1 = NULL, _anchor = NULL, cert_google = NULL, garthc2 = NULL;
SecPolicyRef policy = NULL, replacementPolicy = NULL, replacementPolicy2 = NULL;
CFDateRef date = NULL;
CFDataRef c0_serial = NULL, serial = NULL;
if (!cert0) { goto errOut; }
c0_serial = CFDataCreate(NULL, _c0_serial, sizeof(_c0_serial));
-#if TARGET_OS_IPHONE
- ok(serial = SecCertificateCopySerialNumber(cert0), "copy cert0 serial");
-#else
CFErrorRef error = NULL;
- ok(serial = SecCertificateCopySerialNumber(cert0, &error), "copy cert0 serial");
+ ok(serial = SecCertificateCopySerialNumberData(cert0, &error), "copy cert0 serial");
CFReleaseNull(error);
-#endif
ok(CFEqual(c0_serial, serial), "serial matches");
CFReleaseNull(serial);
CFReleaseNull(c0_serial);
"trust is kSecTrustResultUnspecified");
is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
- /* Set certs to be the xedge2 leaf. */
+ /* Set certs to be the www.google.com leaf. */
CFReleaseNull(certs);
- isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_certificate,
- sizeof(xedge2_certificate)), NULL, "create cert_xedge2");
- certs = CFArrayCreate(NULL, (const void **)&cert_xedge2, 1, &kCFTypeArrayCallBacks);
+ isnt(cert_google = SecCertificateCreateWithBytes(NULL, google_certificate,
+ sizeof(google_certificate)), NULL, "create cert_google");
+ certs = CFArrayCreate(NULL, (const void **)&cert_google, 1, &kCFTypeArrayCallBacks);
CFReleaseNull(trust);
CFReleaseNull(policy);
CFReleaseNull(date);
bool server = true;
- policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+ policy = SecPolicyCreateSSL(server, CFSTR("www.google.com"));
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
- "create trust for ssl server xedge2.apple.com");
+ "create trust for ssl server www.google.com");
- /* This test uses a cert whose root is no longer in our trust store,
- * so we need to explicitly set it as a trusted anchor
- */
- isnt(_root = SecCertificateCreateWithBytes(NULL, entrust1024RootCA, sizeof(entrust1024RootCA)),
+ isnt(_anchor = SecCertificateCreateWithBytes(NULL, googleInternetAuthoritySubCA, sizeof(googleInternetAuthoritySubCA)),
NULL, "create root");
- const void *v_roots[] = { _root };
- isnt(_anchors = CFArrayCreate(NULL, v_roots, array_size(v_roots), &kCFTypeArrayCallBacks),
+ const void *v_anchors[] = { _anchor };
+ isnt(_anchors = CFArrayCreate(NULL, v_anchors, array_size(v_anchors), &kCFTypeArrayCallBacks),
NULL, "create anchors");
if (!_anchors) { goto errOut; }
ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
- /* Jan 1st 2009. */
- date = CFDateCreate(NULL, 252288000.0);
- ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
- ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+ /* May 23, 2018. */
+ date = CFDateCreate(NULL, 548800000.0);
+ ok_status(SecTrustSetVerifyDate(trust, date), "set www.google.com trust date to May 23, 2018");
+ ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust");
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
CFReleaseNull(trust);
CFReleaseNull(policy);
server = false;
- policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+ policy = SecPolicyCreateSSL(server, CFSTR("www.google.com"));
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
- "create trust for ssl client xedge2.apple.com");
+ "create trust for ssl client www.google.com");
ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
- ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
- ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+ ok_status(SecTrustSetVerifyDate(trust, date), "set google trust date to May 23, 2018");
+ ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate google trust");
is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
"trust is kSecTrustResultRecoverableTrustFailure");
CFReleaseNull(trust);
CFReleaseNull(policy);
server = true;
- policy = SecPolicyCreateIPSec(server, CFSTR("xedge2.apple.com"));
+ policy = SecPolicyCreateIPSec(server, CFSTR("www.google.com"));
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
- "create trust for ip server xedge2.apple.com");
+ "create trust for ip server www.google.com");
ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
- ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
- ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+ ok_status(SecTrustSetVerifyDate(trust, date), "set www.apple.com trust date to May 23, 2018");
+ ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust");
#if 0
/* Although this shouldn't be a valid ipsec cert, since we no longer
check for ekus in the ipsec policy it is. */
policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
"create trust for ssl server nowhere.com");
- replacementPolicy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+ replacementPolicy = SecPolicyCreateSSL(server, CFSTR("www.google.com"));
SecTrustSetPolicies(trust, replacementPolicy);
CFReleaseNull(replacementPolicy);
ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
- ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
- ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+ ok_status(SecTrustSetVerifyDate(trust, date), "set www.google.com trust date to May 23, 2018");
+ ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust");
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
"create trust for ssl server nowhere.com");
- replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
+ replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("www.google.com"));
replacementPolicies = CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)&replacementPolicy2, 1, &kCFTypeArrayCallBacks);
SecTrustSetPolicies(trust, replacementPolicies);
CFReleaseNull(replacementPolicy2);
CFReleaseNull(replacementPolicies);
ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
- ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
- ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+ ok_status(SecTrustSetVerifyDate(trust, date), "set www.google.com trust date to May 23, 2018");
+ ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate www.google.com trust");
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
isnt(garthc2 = SecCertificateCreateWithBytes(NULL, garthc2_certificate,
sizeof(garthc2_certificate)), NULL, "create garthc2");
certs = CFArrayCreate(NULL, (const void **)&garthc2, 1, &kCFTypeArrayCallBacks);
- policy = SecPolicyCreateSSL(server, CFSTR("garthc2.apple.com"));
+ policy = SecPolicyCreateSSL(server, NULL);
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
"create trust for ip server garthc2.apple.com");
date = CFDateCreate(NULL, 269568000.0);
errOut:
CFReleaseSafe(garthc2);
- CFReleaseSafe(cert_xedge2);
+ CFReleaseSafe(cert_google);
CFReleaseSafe(anchors);
CFReleaseSafe(trust);
CFReleaseSafe(serial);
CFReleaseSafe(cert1);
CFReleaseSafe(date);
- CFReleaseSafe(_root);
+ CFReleaseSafe(_anchor);
CFReleaseSafe(_anchors);
}
CFArrayRef certs = NULL;
isnt(certs = CFArrayCreate(NULL, &prt_forest_fi, 1, &kCFTypeArrayCallBacks), NULL, "failed to create cert array");
SecPolicyRef policy = NULL;
- isnt(policy = SecPolicyCreateSSL(false, CFSTR("owa.prt-forest.fi")), NULL, "failed to create policy");
+ isnt(policy = SecPolicyCreateSSL(true, CFSTR("owa.prt-forest.fi")), NULL, "failed to create policy");
SecTrustRef trust = NULL;
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
"create trust for ip client owa.prt-forest.fi");
CFErrorRef error = NULL;
bool reported = SecTrustReportTLSAnalytics(CFSTR("TLSConnectionEvent"), metric, &error);
ok(reported, "Failed to report analytics with error %@", error);
+ xpc_release(metric);
+}
+
+static void test_weak_signature(void) {
+ SecCertificateRef md5_root = NULL, md5_leaf = NULL, sha256_root = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CFArrayRef certs = NULL, anchors = NULL;
+ CFDateRef verifyDate = NULL;
+ CFErrorRef error = NULL;
+
+ require_action(md5_root = SecCertificateCreateWithBytes(NULL, _md5_root, sizeof(_md5_root)), errOut,
+ fail("failed to create md5 root cert"));
+ require_action(md5_leaf = SecCertificateCreateWithBytes(NULL, _md5_leaf, sizeof(_md5_leaf)), errOut,
+ fail("failed to create md5 leaf cert"));
+ require_action(sha256_root = SecCertificateCreateWithBytes(NULL, _sha256_root, sizeof(_sha256_root)), errOut,
+ fail("failed to create sha256 root cert"));
+
+ require_action(certs = CFArrayCreate(NULL, (const void **)&md5_root, 1, &kCFTypeArrayCallBacks), errOut,
+ fail("failed to create certs array"));
+ require_action(anchors = CFArrayCreate(NULL, (const void **)&md5_root, 1, &kCFTypeArrayCallBacks), errOut,
+ fail("failed to create anchors array"));
+ require_action(policy = SecPolicyCreateBasicX509(), errOut, fail("failed to make policy"));
+ require_action(verifyDate = CFDateCreate(NULL, 550600000), errOut, fail("failed to make verification date")); // June 13, 2018
+
+ /* Test self-signed MD5 cert. Should work since cert is a trusted anchor - rdar://39152516 */
+ require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut,
+ fail("failed to create trust object"));
+ require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut,
+ fail("faild to set anchors"));
+ require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut,
+ fail("failed to set verify date"));
+ ok(SecTrustEvaluateWithError(trust, &error), "self-signed MD5 cert failed");
+ is(error, NULL, "got a trust error for self-signed MD5 cert: %@", error);
+
+ /* clean up and set up for next test */
+ CFReleaseNull(error);
+ CFReleaseNull(trust);
+ CFReleaseNull(anchors);
+ CFReleaseNull(certs);
+
+ require_action(certs = CFArrayCreate(NULL, (const void **)&md5_leaf, 1, &kCFTypeArrayCallBacks), errOut,
+ fail("failed to create certs array"));
+ require_action(anchors = CFArrayCreate(NULL, (const void **)&sha256_root, 1, &kCFTypeArrayCallBacks), errOut,
+ fail("failed to create anchors array"));
+
+
+ /* Test non-self-signed MD5 cert. Should fail. */
+ require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut,
+ fail("failed to create trust object"));
+ require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut,
+ fail("faild to set anchors"));
+ require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut,
+ fail("failed to set verify date"));
+ is(SecTrustEvaluateWithError(trust, &error), false, "non-self-signed MD5 cert succeeded");
+ if (error) {
+ is(CFErrorGetCode(error), errSecInvalidDigestAlgorithm, "got wrong error code for MD5 leaf cert, got %ld, expected %d",
+ (long)CFErrorGetCode(error), errSecInvalidDigestAlgorithm);
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
+ }
+
+errOut:
+ CFReleaseNull(md5_root);
+ CFReleaseNull(md5_leaf);
+ CFReleaseNull(sha256_root);
+ CFReleaseNull(certs);
+ CFReleaseNull(anchors);
+ CFReleaseNull(policy);
+ CFReleaseNull(verifyDate);
+ CFReleaseNull(trust);
+ CFReleaseNull(error);
}
int si_20_sectrust(int argc, char *const *argv)
{
#if TARGET_OS_IPHONE
- plan_tests(101+9+(8*13)+9+1+2+17+2+9+2);
+ plan_tests(101+9+(8*13)+9+1+2+17+2+9+2+4);
#else
- plan_tests(97+9+(8*13)+9+1+2+2+17+2+9+2);
+ plan_tests(97+9+(8*13)+9+1+2+2+17+2+9+2+4);
#endif
basic_tests();
test_optional_policy_check();
test_serialization();
test_tls_analytics_report();
+ test_weak_signature();
return 0;
}
};
-/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Operations/CN=xedge2.apple.com
- issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */
-const uint8_t xedge2_certificate[1385]={
- 0x30,0x82,0x05,0x65,0x30,0x82,0x04,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x46,
- 0x9C,0xDF,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
- 0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
- 0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
- 0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
- 0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,
- 0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,
- 0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,
- 0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,
- 0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38,
- 0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
- 0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
- 0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,
- 0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x31,
- 0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x32,
- 0x38,0x31,0x39,0x30,0x33,0x31,0x32,0x5A,0x30,0x81,0x83,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,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x41,0x70,0x70,0x6C,
- 0x65,0x20,0x49,0x6E,0x63,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x13,0x13,
- 0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x4F,0x70,0x65,0x72,0x61,0x74,0x69,
- 0x6F,0x6E,0x73,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x78,0x65,
- 0x64,0x67,0x65,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,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,0xC7,0xF3,0xA1,0x0E,0x0E,
- 0xA4,0xDF,0xC5,0x3F,0x24,0x87,0xC3,0x6E,0xE7,0xD0,0x7C,0x2B,0x5A,0x1C,0xF3,0x67,
- 0x6C,0x6B,0x56,0x0A,0x95,0xC9,0xE5,0x13,0x28,0x6E,0x16,0x9D,0x4F,0xB1,0x76,0xFB,
- 0x7D,0x42,0x5B,0x2A,0x7C,0xCC,0x97,0x75,0xAA,0xA6,0xA9,0xDE,0xB2,0xEC,0xEF,0xE2,
- 0xAB,0x40,0xAE,0x9A,0x23,0xF0,0x6A,0x10,0xB3,0x75,0x27,0xF0,0xF4,0x7D,0x08,0x67,
- 0x8F,0xCE,0x41,0x24,0x74,0xAA,0x37,0xB6,0xC1,0x32,0x61,0xCF,0x7D,0x1C,0x21,0xCD,
- 0xCF,0x7C,0x9E,0xE2,0x48,0x03,0x7E,0x78,0xB3,0x86,0x3D,0x06,0x6B,0x39,0xEC,0xC8,
- 0x73,0x68,0xDB,0xE7,0x5B,0x97,0xF4,0xF9,0xA3,0xE7,0xFB,0x81,0x2E,0x4D,0x0B,0x3F,
- 0xA9,0xCA,0xDE,0x32,0x26,0xF3,0xF0,0x97,0x72,0x65,0xAB,0x02,0x03,0x01,0x00,0x01,
- 0xA3,0x82,0x02,0xA2,0x30,0x82,0x02,0x9E,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,
- 0x04,0x03,0x02,0x05,0xA0,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22,
- 0x80,0x0F,0x32,0x30,0x30,0x38,0x30,0x31,0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,
- 0x5A,0x81,0x0F,0x32,0x30,0x31,0x30,0x30,0x31,0x32,0x38,0x31,0x39,0x30,0x33,0x31,
- 0x32,0x5A,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,
- 0x04,0x03,0x02,0x06,0x40,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,
- 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x82,0x01,0x68,0x06,0x03,
- 0x55,0x1D,0x20,0x04,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,0x82,0x01,0x57,0x06,
- 0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x4B,0x02,0x30,0x82,0x01,0x48,0x30,0x26,
- 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,
- 0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
- 0x65,0x74,0x2F,0x63,0x70,0x73,0x30,0x82,0x01,0x1C,0x06,0x08,0x2B,0x06,0x01,0x05,
- 0x05,0x07,0x02,0x02,0x30,0x82,0x01,0x0E,0x1A,0x82,0x01,0x0A,0x54,0x68,0x65,0x20,
- 0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x53,0x53,0x4C,0x20,0x57,0x65,0x62,0x20,
- 0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
- 0x74,0x69,0x6F,0x6E,0x20,0x50,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x53,0x74,
- 0x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x20,0x28,0x43,0x50,0x53,0x29,0x20,0x61,0x76,
- 0x61,0x69,0x6C,0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x77,0x77,0x77,0x2E,0x65,
- 0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x63,0x70,0x73,0x20,0x20,
- 0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x62,0x79,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,
- 0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x69,0x6E,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,
- 0x20,0x75,0x73,0x65,0x20,0x6F,0x72,0x20,0x72,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,
- 0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,
- 0x63,0x61,0x74,0x65,0x2E,0x20,0x20,0x54,0x68,0x69,0x73,0x20,0x43,0x50,0x53,0x20,
- 0x63,0x6F,0x6E,0x74,0x61,0x69,0x6E,0x73,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74,
- 0x69,0x6F,0x6E,0x73,0x20,0x6F,0x6E,0x20,0x77,0x61,0x72,0x72,0x61,0x6E,0x74,0x69,
- 0x65,0x73,0x20,0x61,0x6E,0x64,0x20,0x6C,0x69,0x61,0x62,0x69,0x6C,0x69,0x74,0x69,
- 0x65,0x73,0x2E,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,
- 0x29,0x20,0x32,0x30,0x30,0x32,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x4C,
- 0x69,0x6D,0x69,0x74,0x65,0x64,0x30,0x33,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2C,0x30,
- 0x2A,0x30,0x28,0xA0,0x26,0xA0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
- 0x63,0x72,0x6C,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,
- 0x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2E,0x63,0x72,0x6C,0x30,0x33,0x06,0x08,0x2B,
- 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x27,0x30,0x25,0x30,0x23,0x06,0x08,0x2B,
- 0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x17,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
- 0x6F,0x63,0x73,0x70,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,
- 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62,
- 0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,
- 0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2D,0xEF,0xD9,0xAF,
- 0x1A,0x89,0x40,0x53,0x75,0x48,0x26,0x59,0x2F,0xEC,0x11,0x18,0xC0,0xD1,0x7A,0x34,
- 0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x19,0x06,0x09,0x2A,
- 0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,0x04,0x56,0x37,
- 0x2E,0x31,0x03,0x02,0x03,0x28,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
- 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x77,0x33,0x2A,0x69,0x45,0x5A,0xB2,
- 0xF5,0x74,0xF7,0xDF,0xC7,0x08,0x85,0x86,0x88,0x98,0x41,0x7F,0x57,0x49,0x01,0xBA,
- 0x13,0x21,0x40,0xD0,0x0A,0x5C,0xA7,0x37,0xDF,0xB3,0x7E,0xF8,0xED,0x04,0x63,0xC3,
- 0xE8,0x0F,0xA0,0xE5,0xC4,0x4F,0x3A,0x90,0xE4,0x87,0x5F,0xEC,0xDB,0x65,0x8B,0x6E,
- 0x88,0x6E,0x6E,0xE4,0xBC,0x6A,0x7E,0x37,0x47,0x04,0xFF,0x09,0xC6,0x70,0xE1,0x65,
- 0x8F,0xE3,0xE9,0x60,0xEB,0xE8,0x8E,0x29,0xAE,0xF9,0x81,0xCA,0x9A,0x97,0x3C,0x6F,
- 0x7C,0xFA,0xA8,0x49,0xB4,0x33,0x76,0x9C,0x65,0x92,0x12,0xF6,0x7F,0x6A,0x62,0x84,
- 0x29,0x5F,0x14,0x26,0x6E,0x07,0x6F,0x5C,0xB5,0x7C,0x21,0x64,0x7C,0xD9,0x93,0xF4,
- 0x9C,0xC8,0xE7,0xEC,0xC6,0xAC,0x13,0xC4,0xF0
+/* subject:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com */
+/* issuer :/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */
+const uint8_t google_certificate[]={
+ 0x30,0x82,0x03,0xC7,0x30,0x82,0x02,0xAF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x55,
+ 0x81,0x47,0xC4,0x26,0x8C,0x3F,0xC2,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+ 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,
+ 0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,
+ 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x53,0x65,0x72,
+ 0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C,
+ 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,
+ 0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,
+ 0x31,0x38,0x30,0x35,0x30,0x38,0x31,0x34,0x34,0x37,0x34,0x33,0x5A,0x17,0x0D,0x31,
+ 0x38,0x30,0x37,0x33,0x31,0x31,0x33,0x32,0x37,0x30,0x30,0x5A,0x30,0x68,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,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,
+ 0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
+ 0x0A,0x0C,0x0A,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x4C,0x4C,0x43,0x31,0x17,0x30,
+ 0x15,0x06,0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x67,0x6F,0x6F,0x67,
+ 0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,
+ 0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,
+ 0x04,0xDD,0x10,0xCB,0x4F,0xB1,0x49,0xF9,0xE8,0xC2,0x8E,0xB5,0xB9,0xC3,0x7D,0xCC,
+ 0x9D,0x94,0x3A,0x91,0x19,0x7C,0xA9,0xB3,0x78,0x81,0x21,0x01,0xC0,0x76,0x12,0xA9,
+ 0x84,0x65,0xDF,0xD3,0xE2,0x51,0xFF,0x17,0x9F,0x69,0x0F,0x0B,0xFA,0x04,0x0D,0xBA,
+ 0x35,0xBB,0xE8,0x1F,0x14,0x66,0xB7,0xC7,0xD7,0xFC,0xEB,0x10,0xD6,0xCD,0x79,0x8A,
+ 0x22,0xA3,0x82,0x01,0x52,0x30,0x82,0x01,0x4E,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,
+ 0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x0E,
+ 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x19,
+ 0x06,0x03,0x55,0x1D,0x11,0x04,0x12,0x30,0x10,0x82,0x0E,0x77,0x77,0x77,0x2E,0x67,
+ 0x6F,0x6F,0x67,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x68,0x06,0x08,0x2B,0x06,0x01,
+ 0x05,0x05,0x07,0x01,0x01,0x04,0x5C,0x30,0x5A,0x30,0x2D,0x06,0x08,0x2B,0x06,0x01,
+ 0x05,0x05,0x07,0x30,0x02,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x70,0x6B,
+ 0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x2F,0x47,0x54,0x53,0x47,
+ 0x49,0x41,0x47,0x33,0x2E,0x63,0x72,0x74,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,
+ 0x05,0x07,0x30,0x01,0x86,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,
+ 0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49,
+ 0x41,0x47,0x33,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2B,0x53,
+ 0xE0,0x79,0xD4,0xFD,0xA4,0xD4,0xDF,0x18,0x6B,0xDD,0x80,0x4D,0x11,0x35,0xC7,0xB2,
+ 0x41,0xCC,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,
+ 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x77,0xC2,0xB8,
+ 0x50,0x9A,0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA,
+ 0x4B,0x30,0x21,0x06,0x03,0x55,0x1D,0x20,0x04,0x1A,0x30,0x18,0x30,0x0C,0x06,0x0A,
+ 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x05,0x03,0x30,0x08,0x06,0x06,0x67,0x81,
+ 0x0C,0x01,0x02,0x02,0x30,0x31,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2A,0x30,0x28,0x30,
+ 0x26,0xA0,0x24,0xA0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,
+ 0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49,
+ 0x41,0x47,0x33,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+ 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6E,0x85,0x02,0xC0,0xF0,
+ 0x15,0xBF,0xAF,0x4F,0x29,0x73,0x19,0x87,0x7F,0x30,0xB3,0x24,0xD1,0xEE,0xA7,0xDC,
+ 0x90,0x44,0x30,0xC1,0xA0,0x84,0x65,0x52,0x26,0xE6,0xAD,0x0D,0xCA,0x43,0xEE,0xB6,
+ 0x6B,0x37,0x9D,0xFF,0x97,0x80,0x09,0x85,0x58,0x46,0xEC,0xFF,0xF2,0x42,0x6A,0xBB,
+ 0xE6,0xA3,0xB4,0x9B,0x26,0x26,0xA8,0x53,0xA9,0xB9,0x95,0xB6,0x42,0x06,0x94,0xED,
+ 0x31,0xC5,0x33,0xF7,0x91,0x6A,0x90,0x4B,0xD2,0x8A,0x45,0xAE,0x3A,0xA0,0x10,0x27,
+ 0xAE,0xF4,0x9A,0xC9,0x5E,0x63,0x20,0xAD,0xF2,0xCB,0xDC,0x74,0xA8,0x83,0x32,0x56,
+ 0x6D,0xAA,0x6C,0xCA,0xBC,0xCC,0x71,0x23,0xD4,0xAC,0xA9,0xAE,0xEA,0x04,0xD6,0x75,
+ 0xE7,0xBF,0x18,0xC7,0x9C,0xCC,0x7B,0xE6,0x81,0x62,0xC6,0xFA,0x17,0xA8,0x82,0x2F,
+ 0xCC,0xE9,0xAC,0xEF,0x81,0xCC,0xAE,0x1A,0x1C,0x79,0x35,0x7B,0x54,0xFE,0x06,0x57,
+ 0x2F,0x58,0xD0,0x7C,0x4E,0x5A,0x75,0xAE,0xCC,0x31,0xD6,0x20,0xA6,0xB1,0xDA,0x39,
+ 0x9E,0x46,0x5B,0x15,0x76,0xF2,0x3E,0x2C,0xB1,0x5E,0xBF,0x7F,0x29,0xE3,0xBE,0xC6,
+ 0xF3,0xE5,0xEB,0xD5,0x91,0x48,0x84,0x41,0x7B,0xB6,0x3B,0x83,0xC6,0xCE,0x1B,0xE2,
+ 0x88,0x44,0x91,0x89,0x72,0x27,0xF9,0xD2,0x72,0x33,0xCF,0xC3,0xB2,0x52,0x38,0x65,
+ 0x17,0x14,0x00,0x4E,0x36,0x1C,0xC2,0xAD,0xBF,0x7F,0x3A,0x18,0xF7,0x52,0xFA,0x3B,
+ 0x86,0x18,0xF3,0x24,0x97,0xF7,0x35,0x58,0x48,0x0D,0x7D,0x93,0x18,0xA7,0x14,0x52,
+ 0x1A,0x19,0x9D,0xDB,0xD5,0xCC,0xA3,0xC5,0x48,0x6D,0x8A,
};
-const uint8_t entrust1024RootCA[1244]={
- 0x30,0x82,0x04,0xD8,0x30,0x82,0x04,0x41,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x37,
- 0x4A,0xD2,0x43,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
- 0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
- 0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
- 0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
- 0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,
- 0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,
- 0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,
- 0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,
- 0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38,
- 0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
- 0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
- 0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,
- 0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x35,
- 0x32,0x35,0x31,0x36,0x30,0x39,0x34,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x35,0x32,
- 0x35,0x31,0x36,0x33,0x39,0x34,0x30,0x5A,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,
- 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,
- 0x0A,0x13,0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,
- 0x30,0x39,0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,
- 0x6F,0x72,0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,
- 0x6D,0x69,0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,
- 0x03,0x55,0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,
- 0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,
- 0x65,0x64,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,
- 0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
- 0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x81,
- 0x9D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
- 0x03,0x81,0x8B,0x00,0x30,0x81,0x87,0x02,0x81,0x81,0x00,0xCD,0x28,0x83,0x34,0x54,
- 0x1B,0x89,0xF3,0x0F,0xAF,0x37,0x91,0x31,0xFF,0xAF,0x31,0x60,0xC9,0xA8,0xE8,0xB2,
- 0x10,0x68,0xED,0x9F,0xE7,0x93,0x36,0xF1,0x0A,0x64,0xBB,0x47,0xF5,0x04,0x17,0x3F,
- 0x23,0x47,0x4D,0xC5,0x27,0x19,0x81,0x26,0x0C,0x54,0x72,0x0D,0x88,0x2D,0xD9,0x1F,
- 0x9A,0x12,0x9F,0xBC,0xB3,0x71,0xD3,0x80,0x19,0x3F,0x47,0x66,0x7B,0x8C,0x35,0x28,
- 0xD2,0xB9,0x0A,0xDF,0x24,0xDA,0x9C,0xD6,0x50,0x79,0x81,0x7A,0x5A,0xD3,0x37,0xF7,
- 0xC2,0x4A,0xD8,0x29,0x92,0x26,0x64,0xD1,0xE4,0x98,0x6C,0x3A,0x00,0x8A,0xF5,0x34,
- 0x9B,0x65,0xF8,0xED,0xE3,0x10,0xFF,0xFD,0xB8,0x49,0x58,0xDC,0xA0,0xDE,0x82,0x39,
- 0x6B,0x81,0xB1,0x16,0x19,0x61,0xB9,0x54,0xB6,0xE6,0x43,0x02,0x01,0x03,0xA3,0x82,
- 0x01,0xD7,0x30,0x82,0x01,0xD3,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,
- 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x82,0x01,0x19,0x06,0x03,0x55,
- 0x1D,0x1F,0x04,0x82,0x01,0x10,0x30,0x82,0x01,0x0C,0x30,0x81,0xDE,0xA0,0x81,0xDB,
- 0xA0,0x81,0xD8,0xA4,0x81,0xD5,0x30,0x81,0xD2,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
- 0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,
- 0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,
- 0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,
- 0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,
- 0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,
- 0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,
- 0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,
- 0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,
- 0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,
- 0x72,0x76,0x65,0x72,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,0x0D,0x30,0x0B,
- 0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x29,0xA0,0x27,0xA0,
- 0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,
- 0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x52,0x4C,0x2F,0x6E,0x65,
- 0x74,0x31,0x2E,0x63,0x72,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,
- 0x22,0x80,0x0F,0x31,0x39,0x39,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,0x34,
- 0x30,0x5A,0x81,0x0F,0x32,0x30,0x31,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,
- 0x34,0x30,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06,
- 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62,
- 0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,
- 0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF0,0x17,0x62,0x13,
- 0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,0x1A,
- 0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x19,
- 0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,
- 0x04,0x56,0x34,0x2E,0x30,0x03,0x02,0x04,0x90,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
- 0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x90,0xDC,0x30,0x02,
- 0xFA,0x64,0x74,0xC2,0xA7,0x0A,0xA5,0x7C,0x21,0x8D,0x34,0x17,0xA8,0xFB,0x47,0x0E,
- 0xFF,0x25,0x7C,0x8D,0x13,0x0A,0xFB,0xE4,0x98,0xB5,0xEF,0x8C,0xF8,0xC5,0x10,0x0D,
- 0xF7,0x92,0xBE,0xF1,0xC3,0xD5,0xD5,0x95,0x6A,0x04,0xBB,0x2C,0xCE,0x26,0x36,0x65,
- 0xC8,0x31,0xC6,0xE7,0xEE,0x3F,0xE3,0x57,0x75,0x84,0x7A,0x11,0xEF,0x46,0x4F,0x18,
- 0xF4,0xD3,0x98,0xBB,0xA8,0x87,0x32,0xBA,0x72,0xF6,0x3C,0xE2,0x3D,0x9F,0xD7,0x1D,
- 0xD9,0xC3,0x60,0x43,0x8C,0x58,0x0E,0x22,0x96,0x2F,0x62,0xA3,0x2C,0x1F,0xBA,0xAD,
- 0x05,0xEF,0xAB,0x32,0x78,0x87,0xA0,0x54,0x73,0x19,0xB5,0x5C,0x05,0xF9,0x52,0x3E,
- 0x6D,0x2D,0x45,0x0B,0xF7,0x0A,0x93,0xEA,0xED,0x06,0xF9,0xB2,
+/* subject:/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */
+/* issuer :/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */
+const uint8_t googleInternetAuthoritySubCA[]={
+ 0x30,0x82,0x04,0x5C,0x30,0x82,0x03,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x01,
+ 0xE3,0xA9,0x30,0x1C,0xFC,0x72,0x06,0x38,0x3F,0x9A,0x53,0x1D,0x30,0x0D,0x06,0x09,
+ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4C,0x31,0x20,0x30,
+ 0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,
+ 0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31,
+ 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,
+ 0x53,0x69,0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,
+ 0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,
+ 0x36,0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x17,0x0D,0x32,0x31,0x31,0x32,
+ 0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,
+ 0x0A,0x13,0x15,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20,
+ 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,
+ 0x03,0x13,0x1C,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E,
+ 0x65,0x74,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,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,
+ 0xCA,0x52,0x4B,0xEA,0x1E,0xFF,0xCE,0x24,0x6B,0xA8,0xDA,0x72,0x18,0x68,0xD5,0x56,
+ 0x5D,0x0E,0x48,0x5A,0x2D,0x35,0x09,0x76,0x5A,0xCF,0xA4,0xC8,0x1C,0xB1,0xA9,0xFE,
+ 0x53,0x89,0xFB,0xAD,0x34,0xFF,0x88,0x5B,0x9F,0xBB,0xE7,0xE8,0x00,0x01,0xDC,0x35,
+ 0x73,0x75,0x03,0xAD,0xB3,0xB1,0xB9,0xA4,0x7D,0x2B,0x26,0x79,0xCE,0x15,0x40,0x0A,
+ 0xEF,0x51,0xB8,0x9F,0x32,0x8C,0x7C,0x70,0x86,0x52,0x4B,0x16,0xFE,0x6A,0x27,0x6B,
+ 0xE6,0x36,0x7A,0x62,0x50,0xD8,0xDF,0x9A,0x89,0xCC,0x09,0x29,0xEB,0x4F,0x29,0x14,
+ 0x88,0x80,0x0B,0x8F,0x38,0x1E,0x80,0x6A,0x18,0x7C,0x1D,0xBD,0x97,0x3B,0x78,0x7D,
+ 0x45,0x49,0x36,0x4F,0x41,0xCD,0xA2,0xE0,0x76,0x57,0x3C,0x68,0x31,0x79,0x64,0xC9,
+ 0x6E,0xD7,0x51,0x1E,0x66,0xC3,0xA2,0x64,0x2C,0x79,0xC0,0xE7,0x65,0xC3,0x56,0x84,
+ 0x53,0x5A,0x43,0x6D,0xCB,0x9A,0x02,0x20,0xD2,0xEF,0x1A,0x69,0xD1,0xB0,0x9D,0x73,
+ 0xA2,0xE0,0x2A,0x60,0x65,0x50,0x31,0xCF,0xFB,0xB3,0x2F,0xBF,0x11,0x88,0x40,0x2E,
+ 0xB5,0x49,0x10,0x0F,0x0A,0x6E,0xDC,0x97,0xFA,0xBF,0x2C,0x9F,0x05,0x39,0x0B,0x58,
+ 0x54,0xAF,0x06,0x96,0xE8,0xC5,0x8E,0x01,0x16,0xBC,0xA8,0x1A,0x4D,0x41,0xC5,0x93,
+ 0x91,0xA2,0x1E,0xA1,0x8B,0xF2,0xFE,0xC1,0x88,0x24,0x49,0xA3,0x47,0x4B,0xC5,0x13,
+ 0x01,0xDD,0xA7,0x57,0x12,0x69,0x62,0x2B,0xEB,0xFE,0x20,0xEF,0x69,0xFB,0x3A,0xA5,
+ 0xF0,0x7E,0x29,0xEE,0xED,0x96,0x16,0xF7,0xB1,0x1F,0xA0,0xE4,0x90,0x25,0xE0,0x33,
+ 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x33,0x30,0x82,0x01,0x2F,0x30,0x0E,0x06,
+ 0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,0x12,0x06,0x03,
+ 0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,
+ 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x77,0xC2,0xB8,0x50,0x9A,
+ 0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA,0x4B,0x30,
+ 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x9B,0xE2,0x07,0x57,
+ 0x67,0x1C,0x1E,0xC0,0x6A,0x06,0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86,0x2E,
+ 0x30,0x35,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x29,0x30,0x27,
+ 0x30,0x25,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x19,0x68,0x74,
+ 0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,
+ 0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x30,0x32,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2B,
+ 0x30,0x29,0x30,0x27,0xA0,0x25,0xA0,0x23,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,
+ 0x2F,0x63,0x72,0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73,
+ 0x72,0x32,0x2F,0x67,0x73,0x72,0x32,0x2E,0x63,0x72,0x6C,0x30,0x3F,0x06,0x03,0x55,
+ 0x1D,0x20,0x04,0x38,0x30,0x36,0x30,0x34,0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x02,
+ 0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,
+ 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,
+ 0x2F,0x72,0x65,0x70,0x6F,0x73,0x69,0x74,0x6F,0x72,0x79,0x2F,0x30,0x0D,0x06,0x09,
+ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
+ 0x1C,0xB7,0x89,0x96,0xE4,0x53,0xED,0xBB,0xEC,0xDB,0xA8,0x32,0x01,0x9F,0x2C,0xA3,
+ 0xCD,0x6D,0xAD,0x42,0x12,0x77,0xB3,0xB8,0xE6,0xC9,0x03,0x52,0x60,0x20,0x7B,0x57,
+ 0x27,0xC6,0x11,0xB5,0x3F,0x67,0x0D,0x99,0x2C,0x5B,0x5A,0xCA,0x22,0x0A,0xDD,0x9E,
+ 0xBB,0x1F,0x4B,0x48,0x3F,0x8F,0x02,0x3D,0x8B,0x21,0x84,0x45,0x1D,0x6D,0xF5,0xFF,
+ 0xAC,0x68,0x89,0xCD,0x64,0xE2,0xD6,0xD6,0x5E,0x40,0xC2,0x8E,0x2A,0xF7,0xEF,0x14,
+ 0xD3,0x36,0xA4,0x40,0x30,0xF5,0x32,0x15,0x15,0x92,0x76,0xFB,0x7E,0x9E,0x53,0xEA,
+ 0xC2,0x76,0xFC,0x39,0xAD,0x88,0xFE,0x66,0x92,0x26,0xE9,0x1C,0xC4,0x38,0xCD,0x49,
+ 0xFA,0x43,0x87,0xF0,0x5D,0xD6,0x56,0x4D,0x81,0xD7,0x7F,0xF1,0xC2,0xDD,0xB0,0x4D,
+ 0xFE,0xC3,0x2A,0x6E,0x7C,0x9F,0x6E,0x5C,0xED,0x62,0x42,0x99,0xE1,0xF7,0x36,0xEE,
+ 0x14,0x8C,0x2C,0x20,0xE3,0x46,0x97,0x5A,0x77,0x03,0xC0,0xA0,0xC6,0x4A,0x88,0xFD,
+ 0x40,0x22,0x87,0x72,0x5A,0x18,0xEA,0x9C,0xA5,0xC7,0x5A,0x08,0x8C,0xE4,0x05,0xA4,
+ 0x7D,0xB9,0x84,0x35,0x5F,0x89,0x36,0x56,0x0E,0x40,0x3D,0x12,0xE8,0xBB,0x35,0x72,
+ 0xED,0xAF,0x08,0x56,0x4E,0xB0,0xBB,0x2E,0xA9,0x9B,0xE4,0xFB,0x1D,0x3E,0x0B,0x63,
+ 0xC8,0x9B,0x4B,0x91,0x44,0x66,0x57,0xC0,0x14,0xB4,0x96,0xF0,0xDC,0x2C,0x57,0x3F,
+ 0x52,0x04,0xAD,0x95,0xAA,0x7D,0x4D,0xD0,0xF2,0x0C,0x9F,0x9C,0x40,0xE8,0xD6,0x55,
+ 0x73,0xBA,0x3C,0xDF,0x90,0xCB,0x00,0x5B,0x21,0x11,0x67,0xC2,0xED,0x32,0x1E,0xDE,
};
-
/* subject:/CN=garthc2.apple.com/O=Apple Inc./OU=DTS/ST=California/C=US/L=Cupertino/emailAddress=gcummings@apple.com
issuer :/CN=garthc2.apple.com/O=Apple Inc./OU=DTS/ST=California/C=US/L=Cupertino/emailAddress=gcummings@apple.com */
const uint8_t garthc2_certificate[730]={
0xB5,0x14,0x69,0x66,0x0E,0x82,0xE7,0xCD,0xCE,0xC8,0x2D,0xA6,0x51,0x7F,0x21,0xC1,
0x35,0x53,0x85,0x06,0x4A,0x5D,0x9F,0xAD,0xBB,0x1B,0x5F,0x74,
};
+
+/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test MD5 Root */
+/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test MD5 Root */
+uint8_t _md5_root[]={
+ 0x30,0x82,0x03,0xCE,0x30,0x82,0x02,0xB6,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00,
+ 0x89,0x96,0x98,0xE1,0x25,0xF9,0x94,0x1E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+ 0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30,0x81,0x82,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,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x0C,0x0D,0x54,
+ 0x65,0x73,0x74,0x20,0x4D,0x44,0x35,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,
+ 0x31,0x38,0x30,0x36,0x31,0x32,0x32,0x33,0x34,0x37,0x30,0x39,0x5A,0x17,0x0D,0x31,
+ 0x39,0x30,0x36,0x31,0x32,0x32,0x33,0x34,0x37,0x30,0x39,0x5A,0x30,0x81,0x82,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,0x16,0x30,0x14,0x06,0x03,0x55,
+ 0x04,0x03,0x0C,0x0D,0x54,0x65,0x73,0x74,0x20,0x4D,0x44,0x35,0x20,0x52,0x6F,0x6F,
+ 0x74,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,0xBA,0xAB,0xFB,0x22,0xB6,0x25,0x79,0x2A,0x84,0xDB,0x59,0xE9,0x48,0x7C,
+ 0x36,0x54,0xCC,0x6F,0x82,0xE6,0x0A,0x11,0x31,0x31,0x84,0xB4,0xB2,0x7F,0x97,0xFD,
+ 0xF9,0x3A,0xB2,0x49,0xB2,0x2C,0x36,0x39,0x9A,0x57,0x97,0x8F,0x92,0xB3,0xD2,0xE0,
+ 0x91,0x1A,0x06,0x19,0xD2,0xB4,0xE3,0xD9,0xFF,0x0C,0x25,0xFA,0x85,0x78,0x1D,0x40,
+ 0xD9,0xB8,0xD5,0xA7,0x62,0x84,0x8E,0x20,0xFF,0xBB,0xD0,0x83,0xF9,0x59,0xFC,0x68,
+ 0x06,0x76,0x0D,0x10,0x82,0xC3,0xEA,0x49,0xD7,0xBE,0x79,0x0C,0x8A,0x57,0xBC,0x5B,
+ 0xD7,0xD2,0xF0,0x33,0x79,0xC4,0xC7,0xA7,0x64,0x3C,0x82,0xFA,0x76,0x9E,0x04,0xB6,
+ 0x49,0xB8,0xE6,0xFE,0x1E,0x0C,0x56,0x84,0x8B,0x51,0x91,0x81,0x92,0x1C,0xBA,0xDB,
+ 0xA8,0xF4,0x60,0x36,0x8F,0xB6,0x3D,0xBF,0x7E,0xDD,0x0F,0x3B,0x1C,0x17,0xDC,0x4B,
+ 0x6C,0x32,0xCF,0xE9,0x9B,0xE7,0xBD,0x97,0x3C,0x31,0x15,0x27,0xB8,0xCA,0x7E,0xB9,
+ 0x63,0xB5,0xA3,0xB3,0x0C,0x3A,0x3D,0x83,0xE6,0xC2,0xAB,0xF7,0x9B,0x90,0x8D,0xD3,
+ 0xA1,0x3A,0x57,0xBE,0x95,0x75,0x51,0x40,0x3B,0xE9,0x86,0x52,0xD4,0x95,0xBF,0xE5,
+ 0xA7,0xD5,0x91,0x11,0x04,0x84,0x89,0x96,0xCB,0xC7,0x68,0xAE,0xEF,0x03,0xC7,0x08,
+ 0xE5,0x39,0x72,0x14,0xEB,0x85,0x31,0xE5,0x1C,0x7E,0xE6,0x8C,0x24,0x8A,0x6E,0xBD,
+ 0xE0,0x14,0xFA,0x54,0x41,0xE2,0x22,0x0C,0x77,0xE9,0x85,0x52,0xD2,0x57,0x8E,0x50,
+ 0xB5,0xBD,0xD9,0xBD,0xEB,0xA4,0xDE,0xE4,0x76,0x8C,0x18,0xAF,0xEB,0x73,0xFC,0xD6,
+ 0xB1,0x09,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,0x50,0xD0,0xF4,0xB0,0xFF,0x54,
+ 0x6F,0x98,0x26,0x0A,0x8A,0xA7,0x72,0x90,0xCC,0xD2,0x63,0xEF,0x1D,0x16,0x30,0x0D,
+ 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x03,0x82,0x01,
+ 0x01,0x00,0x48,0x03,0xF2,0xD6,0x05,0x9E,0x02,0x47,0xEF,0xDA,0xAE,0x6C,0xDF,0x1C,
+ 0xC4,0xE2,0xFB,0x62,0x89,0xE7,0xC7,0x55,0xE4,0x7B,0x20,0xC3,0xCE,0x7F,0x94,0x60,
+ 0x2D,0xE6,0x63,0x43,0xF1,0x03,0xC3,0x9D,0x79,0xA8,0x62,0x75,0x3D,0x41,0xAF,0xCE,
+ 0x3F,0x70,0xA7,0xF9,0xAC,0x8C,0xC7,0xBA,0x01,0xE4,0xAE,0xDF,0x15,0xBC,0x36,0xDE,
+ 0x27,0x63,0xBD,0x4C,0xE5,0x20,0x4E,0x8B,0x91,0x80,0x60,0xBF,0xF8,0x34,0xD5,0x89,
+ 0xE0,0x5D,0x0F,0x5E,0xF6,0x63,0xC0,0x26,0x7F,0x48,0xBA,0x38,0x80,0xEA,0x91,0xDF,
+ 0xC4,0x53,0xE0,0x7B,0x0D,0xF1,0x85,0x35,0x55,0xC3,0x0B,0xDD,0x35,0x82,0x75,0x7F,
+ 0x5A,0x23,0x2C,0x11,0xD6,0x2E,0xA1,0xB0,0x61,0x81,0x04,0x8A,0xD0,0x3E,0xFC,0x30,
+ 0xD4,0x46,0x4C,0x64,0x6C,0xF1,0x29,0xED,0x5F,0x49,0x54,0xB7,0x79,0xC7,0xC2,0x03,
+ 0x53,0x1A,0x7D,0xB9,0x17,0x10,0xFF,0x4F,0xD7,0x4E,0x0A,0x58,0x51,0xB3,0x77,0x50,
+ 0xA2,0x93,0x24,0x60,0x95,0x70,0x77,0xB4,0x18,0x72,0xBB,0x43,0x49,0x44,0xBE,0x11,
+ 0x1D,0xD9,0xCB,0x37,0xCE,0x6F,0x02,0xBC,0x7F,0xCE,0x52,0x06,0xFA,0x38,0x7D,0x75,
+ 0x60,0xDD,0xAF,0x0C,0x1F,0xAF,0xA9,0x2F,0x11,0xB8,0xC8,0xEF,0x12,0xE2,0xB2,0xC2,
+ 0x87,0xF3,0xAC,0x10,0x16,0x40,0x0D,0x9B,0xFA,0x7F,0xA3,0xDD,0xBE,0x31,0xA2,0x6B,
+ 0x5B,0xF4,0x50,0x6F,0xC6,0x6F,0xBB,0x2E,0xD3,0x34,0x16,0xBF,0xB3,0x61,0x5E,0xD3,
+ 0x5C,0x03,0x9E,0xE6,0xEB,0x6E,0xF7,0x11,0x1F,0xF8,0x90,0x34,0xC9,0x7B,0x21,0x14,
+ 0x4F,0x70,
+};
+
+/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test Root CA */
+/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test Root CA */
+uint8_t _sha256_root[] = {
+ 0x30,0x82,0x03,0xCC,0x30,0x82,0x02,0xB4,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00,
+ 0xF7,0xC7,0x8C,0x2F,0xE6,0xB8,0xCE,0xD2,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+ 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x81,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,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54,
+ 0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,
+ 0x38,0x30,0x34,0x32,0x38,0x32,0x30,0x32,0x31,0x32,0x30,0x5A,0x17,0x0D,0x32,0x38,
+ 0x30,0x34,0x32,0x35,0x32,0x30,0x32,0x31,0x32,0x30,0x5A,0x30,0x81,0x81,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,0x15,0x30,0x13,0x06,0x03,0x55,0x04,
+ 0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,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,
+ 0xDD,0xC7,0xD4,0xC4,0xC9,0x5B,0x62,0xEF,0x30,0x90,0x81,0x1A,0xA8,0x3C,0x5F,0x37,
+ 0xEC,0xEF,0x85,0xEF,0x54,0x77,0x67,0xD7,0xED,0x1A,0x97,0xF0,0x0A,0x3E,0x42,0x9C,
+ 0xFC,0x74,0xDD,0x27,0x40,0xF9,0xFA,0xA9,0x42,0xA7,0x71,0x05,0x18,0x4E,0xCC,0xC4,
+ 0x8C,0x27,0x4C,0x55,0x21,0xBF,0xCA,0xB8,0xAD,0xB4,0x2E,0x4E,0x0B,0x0C,0x43,0xCF,
+ 0x94,0x4E,0x52,0xBB,0x39,0xEB,0x69,0x6B,0x32,0xF0,0x88,0x16,0x33,0xE4,0x91,0x7A,
+ 0xF6,0xA7,0xBC,0x28,0x9F,0xAD,0x40,0x02,0xC7,0xA1,0x13,0x5E,0x94,0xCA,0xDF,0x0F,
+ 0xEB,0xC6,0xDB,0x2A,0xF9,0x3D,0x57,0x52,0x41,0x2E,0x0D,0x85,0xA2,0xD1,0x12,0x80,
+ 0x69,0x74,0x8C,0x4D,0xEC,0x8B,0x82,0xEA,0xA5,0xD7,0xDF,0x9F,0x1E,0xBA,0xC6,0x2D,
+ 0xAC,0x3F,0xFC,0x12,0xF4,0xB1,0x29,0x7C,0x05,0x40,0x68,0x3F,0xAC,0x80,0x5A,0xB0,
+ 0xD8,0xA3,0x17,0xB8,0x94,0x0F,0x40,0x7F,0x33,0xDC,0xAF,0x51,0xA9,0xEA,0x95,0x32,
+ 0xCA,0x8F,0x36,0xDA,0x93,0xC7,0x20,0xA2,0xC2,0xB2,0xDD,0x0B,0x6A,0xC1,0x4D,0x21,
+ 0x80,0x16,0x54,0x6C,0xFD,0xB0,0xCC,0x3C,0xF9,0x78,0x64,0x40,0x4E,0xB0,0x43,0xA6,
+ 0xF6,0xF9,0x8E,0xEE,0xBC,0x41,0x49,0xCB,0x20,0x9A,0x71,0x85,0xF4,0xA2,0xA2,0xE6,
+ 0x18,0xDD,0xA7,0x76,0xC1,0x86,0xB5,0x43,0xE3,0xE0,0x76,0x51,0x5E,0xD6,0x0A,0xA9,
+ 0x2E,0x31,0x95,0x2C,0x2F,0x3D,0x76,0x59,0x41,0x75,0x50,0xCD,0x96,0x63,0x34,0x62,
+ 0x4D,0xE4,0xA8,0xA3,0x08,0x3A,0xDF,0x28,0x36,0x58,0x72,0xBC,0x4B,0x4F,0x07,0xE3,
+ 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,0xB5,0xA9,0x53,0x08,0x10,0x38,0x1A,0xA5,
+ 0xB3,0x84,0xC9,0xEE,0xC4,0xAB,0x0F,0xB8,0x5F,0x68,0x10,0xA2,0x30,0x0D,0x06,0x09,
+ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
+ 0xDA,0xA8,0xB6,0x1B,0xA8,0x15,0x27,0xDA,0xA9,0xE9,0x2F,0xC2,0x87,0xB6,0x7E,0x0A,
+ 0xDE,0x88,0x65,0xB9,0x23,0x5F,0x7B,0x35,0xE1,0xDB,0xB2,0xBA,0x3B,0x1D,0xE5,0x3E,
+ 0x20,0x7E,0x2B,0x93,0xD0,0xB5,0xEC,0x9B,0x4E,0xB8,0x64,0xAE,0x7A,0x77,0xB6,0x7C,
+ 0x80,0x9D,0x35,0x42,0x23,0xAE,0x91,0x6A,0xAB,0x27,0xBE,0x46,0x80,0xE0,0x58,0xA9,
+ 0x8C,0x47,0xFF,0x7E,0x79,0x7F,0xFC,0xB0,0x71,0xFF,0x35,0x4A,0x5E,0x30,0xAC,0xF5,
+ 0xCB,0xC6,0x57,0xD2,0x93,0x4E,0x78,0xD4,0x14,0x7C,0x43,0x6A,0x5E,0x20,0x01,0xB6,
+ 0x30,0x41,0xC4,0xB0,0x3D,0x72,0x0C,0xD6,0x36,0x88,0x37,0x4A,0xE9,0xF3,0xBB,0x28,
+ 0x1D,0x53,0x62,0x6D,0x1B,0x79,0xAA,0xDC,0xF2,0x0A,0x9A,0xD6,0x00,0x9E,0x18,0x82,
+ 0x3E,0x7D,0xD1,0x9C,0x5A,0x16,0xA5,0xA7,0x73,0x68,0x61,0x63,0x99,0x26,0x8D,0xB9,
+ 0xAF,0x01,0x98,0xA4,0x94,0x1D,0x7F,0x12,0x51,0x0A,0xAC,0xCE,0x65,0xBA,0xBF,0x38,
+ 0xF9,0xDB,0xC9,0x82,0xA3,0x2C,0x5D,0x22,0x87,0xEA,0xD2,0x45,0xD3,0xEC,0x50,0xF1,
+ 0x29,0x7B,0x09,0x10,0x4D,0xE0,0x21,0x35,0x4F,0x3F,0x0F,0x29,0x5D,0x30,0x83,0xBD,
+ 0xD9,0x45,0x78,0x49,0xD7,0xAF,0xC6,0xF0,0x3E,0x2B,0xD6,0xC3,0x7B,0xF9,0x2F,0x3B,
+ 0xCB,0x3E,0xB9,0xC9,0x08,0xE7,0x19,0x9C,0xEA,0xFC,0x03,0xED,0x51,0xF7,0x3C,0x5E,
+ 0x09,0x67,0x91,0x5F,0x22,0x58,0x73,0x31,0xE7,0xA0,0x9F,0x9D,0xBF,0x48,0x2D,0x7C,
+ 0xFE,0xAA,0xFE,0x29,0x56,0x11,0xE8,0x0F,0xBE,0xE0,0x3A,0xA6,0x8D,0x82,0x34,0xFB,
+};
+
+/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test MD5 Leaf */
+/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Test Root CA */
+uint8_t _md5_leaf[] = {
+ 0x30,0x82,0x04,0x5D,0x30,0x82,0x03,0x45,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x7A,
+ 0x22,0xA1,0x88,0x18,0x9E,0x75,0x77,0xE6,0xEF,0x7E,0xC0,0x33,0x8E,0xE8,0x90,0xE8,
+ 0x7B,0xC5,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,
+ 0x00,0x30,0x81,0x81,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,0x15,
+ 0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,
+ 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x36,0x31,0x32,0x32,
+ 0x33,0x34,0x35,0x35,0x38,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x31,0x32,0x32,0x33,
+ 0x34,0x35,0x35,0x38,0x5A,0x30,0x81,0x82,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,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x0C,0x0D,0x54,0x65,0x73,
+ 0x74,0x20,0x4D,0x44,0x35,0x20,0x4C,0x65,0x61,0x66,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,0xAD,0xB6,0x0E,0xB4,0xE8,
+ 0xA1,0x87,0xDB,0x0A,0x67,0xA2,0xE0,0xAD,0xD3,0x22,0x30,0xBF,0x7A,0x17,0x94,0x95,
+ 0xE2,0xA3,0xC3,0xF3,0xA7,0xD1,0x31,0xAA,0xD4,0x6F,0x12,0x20,0x6A,0x28,0x31,0xA3,
+ 0x02,0x11,0xB7,0xCB,0xEF,0x49,0xE1,0x8D,0xAB,0x41,0x83,0x0A,0xBB,0xDE,0x44,0x93,
+ 0x73,0x13,0x4B,0xFD,0x36,0x8A,0x57,0x30,0x3D,0x86,0x62,0x96,0x2A,0x3B,0x59,0x7C,
+ 0x29,0x19,0x73,0xA6,0x9C,0xE3,0x5C,0x2E,0xB6,0x91,0x42,0x9A,0x52,0xC7,0x60,0xF0,
+ 0x05,0x99,0x46,0xC8,0x6B,0x3A,0xD9,0xB7,0x70,0xDB,0xCA,0x81,0x71,0x74,0xDF,0x20,
+ 0xD3,0x94,0xF9,0x70,0xBA,0xF3,0x69,0x0B,0x9D,0x40,0xC0,0xC2,0xBF,0x95,0xAD,0xFF,
+ 0x88,0xF5,0x12,0x41,0x80,0xB1,0x7E,0xAD,0x2F,0x80,0x88,0xC7,0x60,0x89,0xFE,0x3C,
+ 0x0C,0xCA,0x85,0x67,0xFD,0xD1,0x84,0x89,0x77,0x7E,0xA1,0x77,0x1D,0xCD,0x80,0xE1,
+ 0xFA,0x2A,0xF9,0x04,0x60,0xED,0x77,0xB7,0x05,0xF7,0xA0,0x08,0xCF,0xFE,0x7B,0x3D,
+ 0x75,0x84,0x8C,0x7A,0x6A,0x48,0x22,0x44,0xAE,0xA7,0x2F,0xC6,0xE6,0xC3,0x8C,0x1A,
+ 0xAD,0xEA,0x12,0x3F,0x06,0x6F,0x03,0x61,0xCE,0xAA,0x42,0x73,0x23,0x3D,0x41,0x08,
+ 0x33,0x6F,0x76,0xC6,0x39,0xBB,0x94,0xCF,0xBA,0x44,0x92,0x17,0x6D,0xD1,0x1D,0xAE,
+ 0xF2,0x47,0x61,0x6F,0xAE,0x67,0x23,0xCD,0x6A,0x9A,0x52,0xD9,0x0B,0x06,0x8A,0xA2,
+ 0x33,0x8F,0x35,0x14,0xBD,0x4F,0xE7,0x2E,0x09,0x7B,0xAB,0x4E,0x99,0xA9,0x28,0x2B,
+ 0xAD,0x8E,0xDA,0x21,0xD9,0xD3,0x73,0x5B,0x86,0x69,0xEF,0x02,0x03,0x01,0x00,0x01,
+ 0xA3,0x81,0xCA,0x30,0x81,0xC7,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,
+ 0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,
+ 0x03,0x02,0x07,0x80,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,
+ 0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x16,0x06,0x03,0x55,0x1D,0x11,
+ 0x04,0x0F,0x30,0x0D,0x82,0x0B,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F,
+ 0x6D,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2A,0x04,0x77,0xF2,
+ 0xC5,0xB3,0x51,0xA0,0x85,0x23,0x10,0x8D,0xEC,0x1F,0x01,0xCF,0x3C,0x94,0x87,0x44,
+ 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xB5,0xA9,0x53,
+ 0x08,0x10,0x38,0x1A,0xA5,0xB3,0x84,0xC9,0xEE,0xC4,0xAB,0x0F,0xB8,0x5F,0x68,0x10,
+ 0xA2,0x30,0x3A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x2E,0x30,
+ 0x2C,0x30,0x2A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x1E,0x68,
+ 0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,
+ 0x6F,0x6D,0x2F,0x74,0x65,0x73,0x74,0x43,0x41,0x2E,0x64,0x65,0x72,0x30,0x0D,0x06,
+ 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x03,0x82,0x01,0x01,
+ 0x00,0x9D,0x05,0xC0,0xB6,0xDE,0x11,0x00,0xDB,0x29,0xB2,0xAC,0xE6,0xFD,0x8C,0x2D,
+ 0x88,0x79,0x75,0x8F,0xFD,0x7C,0x65,0x6D,0xAE,0xF7,0x19,0xF4,0x52,0x79,0x14,0x8C,
+ 0x57,0x39,0x50,0x53,0xFA,0xB9,0xCC,0x5B,0xEE,0x9C,0x23,0xC2,0x15,0xBD,0xB4,0x9A,
+ 0x0A,0x6D,0xC4,0x8C,0x39,0xA3,0xAE,0xD4,0x1D,0x9D,0x1A,0xBD,0x3C,0x6C,0x70,0x95,
+ 0x0B,0xFA,0xE6,0x0B,0x4E,0xB8,0x35,0x10,0x49,0xCC,0x3A,0x7C,0xE0,0x57,0x85,0xE0,
+ 0xD5,0x4E,0xB0,0x6B,0xB8,0xE0,0x37,0xF1,0xF1,0x6C,0x32,0x8E,0x8A,0x55,0x81,0x71,
+ 0x4B,0xC3,0x75,0x8D,0xFF,0x11,0x9C,0x2B,0xE9,0x71,0xA7,0xBA,0x01,0xDA,0xA0,0x4A,
+ 0x46,0xEC,0x86,0xC8,0x44,0x67,0x44,0x78,0x99,0x6B,0xFA,0x3A,0x26,0x09,0xA9,0xA5,
+ 0xAF,0x29,0x3A,0x2A,0x0E,0xD0,0x44,0x69,0xD7,0x8E,0xB3,0xB0,0xCF,0x90,0xC3,0xB7,
+ 0x8B,0xB4,0xD8,0xB8,0xEB,0x27,0x42,0x2B,0x91,0xDF,0x4D,0x59,0x56,0xD4,0x9F,0x0A,
+ 0x58,0x16,0x24,0x4B,0x96,0xEE,0xDE,0xCA,0xD2,0x3F,0xB9,0xC7,0x9B,0x4A,0x65,0x51,
+ 0xBC,0x6E,0x39,0xEE,0x39,0x11,0x8F,0xBC,0xB3,0x6C,0x17,0xF5,0xAD,0x2F,0x46,0x86,
+ 0x5F,0x76,0x17,0x43,0x70,0x55,0xCD,0x08,0x5A,0x81,0x93,0x16,0xDD,0xC7,0x14,0x34,
+ 0x87,0xFF,0xE5,0x13,0xA3,0xC4,0x5A,0xFD,0xF8,0x40,0x77,0xDC,0xBE,0xEC,0xB1,0x31,
+ 0x05,0xA6,0xE1,0x6F,0x2C,0x32,0xD2,0xD7,0x6D,0x4D,0xF2,0xDF,0x2E,0x5D,0x6E,0x31,
+ 0x7E,0x06,0x20,0x11,0xF9,0x7C,0x72,0xE3,0x47,0xBA,0x33,0xA7,0x0A,0x74,0x92,0x7F,
+ 0x74,
+};
ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate");
is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified");
+ /* Test v3 certs fail iAP SW Auth policy */
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+ policy = SecPolicyCreateiAPSWAuth();
+ require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail);
+ require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail);
+ require_noerr(SecTrustSetVerifyDate(trust, date), trustFail);
+ require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail);
+ is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
+
trustFail:
CFReleaseSafe(policy);
CFReleaseSafe(trust);
CFReleaseSafe(v3CA);
}
+static void test_sw_auth_trust(void) {
+ SecCertificateRef sw_auth_test_CA = NULL, sw_auth_test_leaf = NULL;
+ isnt(sw_auth_test_CA = SecCertificateCreateWithBytes(NULL, _iAPSWAuthTestRoot, sizeof(_iAPSWAuthTestRoot)),
+ NULL, "create sw auth test ca");
+ isnt(sw_auth_test_leaf = SecCertificateCreateWithBytes(NULL, _iAPSWAuth_leaf, sizeof(_iAPSWAuth_leaf)),
+ NULL, "create sw auth leaf");
+
+ /* Test SW Auth certs meet iAP SW Auth policy */
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CFArrayRef certs = NULL, anchors = NULL;
+ CFDateRef date = NULL;
+ SecTrustResultType trustResult;
+
+ certs = CFArrayCreate(NULL, (const void **)&sw_auth_test_leaf, 1, &kCFTypeArrayCallBacks);
+ anchors = CFArrayCreate(NULL, (const void **)&sw_auth_test_CA, 1, &kCFTypeArrayCallBacks);
+ policy = SecPolicyCreateiAPSWAuth();
+ require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail);
+ require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail);
+ require(date = CFDateCreate(NULL, 530000000.0), trustFail); /* 17 Oct 2017, BEFORE issuance */
+ require_noerr(SecTrustSetVerifyDate(trust, date), trustFail);
+ require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail);
+ is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified");
+
+ /* Test SW Auth certs fail iAP policy */
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+ policy = SecPolicyCreateiAP();
+ require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail);
+ require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail);
+ require_noerr(SecTrustSetVerifyDate(trust, date), trustFail);
+ require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail);
+ is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
+
+ /* Test SW Auth certs fail when not-yet-valid with expiration check */
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+ policy = SecPolicyCreateiAPSWAuthWithExpiration(true);
+ require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail);
+ require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail);
+ require_noerr(SecTrustSetVerifyDate(trust, date), trustFail);
+ require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail);
+ is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
+
+trustFail:
+ CFReleaseSafe(policy);
+ CFReleaseSafe(trust);
+ CFReleaseSafe(certs);
+ CFReleaseSafe(anchors);
+ CFReleaseSafe(date);
+ CFReleaseSafe(sw_auth_test_CA);
+ CFReleaseSafe(sw_auth_test_leaf);
+}
+
+static void test_sw_auth_cert(void) {
+ SecCertificateRef good_leaf = NULL, bad_leaf = NULL;
+ isnt(good_leaf = SecCertificateCreateWithBytes(NULL, _iAPSWAuth_leaf, sizeof(_iAPSWAuth_leaf)),
+ NULL, "create good iAP SW Auth cert");
+ isnt(bad_leaf = SecCertificateCreateWithBytes(NULL, _malformed_iAPSWAuth_leaf, sizeof(_malformed_iAPSWAuth_leaf)),
+ NULL, "create bad iAP SW Auth cert");
+
+ /* Test Auth version interface */
+ ok(SecCertificateGetiAuthVersion(good_leaf) == kSeciAuthVersionSW, "Get version of well-formed SW Auth cert");
+ ok(SecCertificateGetiAuthVersion(bad_leaf) == kSeciAuthVersionSW, "Get version of malformed SW Auth cert");
+
+ /* Test extension copying with malformed extensions */
+ is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf, kSeciAPSWAuthGeneralCapabilities), NULL,
+ "Fail to get capabilities of malformed SW auth cert");
+ is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf, kSeciAPSWAuthAirPlayCapabilities), NULL,
+ "Fail to get AirPlay capabilities of malformed SW auth cert");
+ is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf, kSeciAPSWAuthHomeKitCapabilities), NULL,
+ "Fail to get HomeKit capabilities of malformed SW auth cert");
+
+ uint8_t byte0 = 0x00;
+ uint8_t byte1 = 0x01;
+ CFDataRef data0 = CFDataCreate(NULL, &byte0, 1);
+ CFDataRef data1 = CFDataCreate(NULL, &byte1, 1);
+
+ /* Test extension copying with well-formed extensions */
+ CFDataRef extensionValue = NULL;
+ isnt(extensionValue = SecCertificateCopyiAPSWAuthCapabilities(good_leaf, kSeciAPSWAuthGeneralCapabilities), NULL,
+ "Get capabilities of well-formed SW auth cert");
+ ok(CFEqual(extensionValue, data1), "Got correct general extension value");
+ CFReleaseNull(extensionValue);
+
+ isnt(extensionValue = SecCertificateCopyiAPSWAuthCapabilities(good_leaf, kSeciAPSWAuthAirPlayCapabilities), NULL,
+ "Get AirPlay capabilities of well-formed SW auth cert");
+ ok(CFEqual(extensionValue, data0), "Got correct AirPlay extension value");
+ CFReleaseNull(extensionValue);
+
+ isnt(extensionValue = SecCertificateCopyiAPSWAuthCapabilities(good_leaf, kSeciAPSWAuthHomeKitCapabilities), NULL,
+ "Get capabilities of well-formed SW auth cert");
+ ok(CFEqual(extensionValue, data1), "Got correct HomeKit extension value");
+ CFReleaseNull(extensionValue);
+
+ CFReleaseNull(good_leaf);
+ CFReleaseNull(bad_leaf);
+ CFReleaseNull(data0);
+ CFReleaseNull(data1);
+}
+
+
int si_22_sectrust_iap(int argc, char *const *argv)
{
- plan_tests(14+20);
+ plan_tests(14+21+5+13);
test_v1();
test_v3();
+ test_sw_auth_trust();
+ test_sw_auth_cert();
return 0;
}
0x0A,0xCB,0xCD,0x6C,0x03,0x8A,0x73,0x95,0x74,0xB1,0x57,0x03,0x09,0x55,0x8D,
};
+/* subject:/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */
+/* issuer :/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */
+uint8_t _iAPSWAuthTestRoot[584]={
+ 0x30,0x82,0x02,0x44,0x30,0x82,0x01,0xEA,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x59,
+ 0x29,0x18,0xB6,0x20,0x80,0x90,0x94,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,
+ 0x04,0x03,0x02,0x30,0x81,0x85,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x03,0x0C,
+ 0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F,0x72,0x69,0x65,
+ 0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x41,0x75,0x74,0x68,0x65,
+ 0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,
+ 0x41,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,
+ 0x37,0x31,0x31,0x30,0x39,0x30,0x30,0x31,0x35,0x31,0x32,0x5A,0x17,0x0D,0x33,0x37,
+ 0x31,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x81,0x85,0x31,0x39,
+ 0x30,0x37,0x06,0x03,0x55,0x04,0x03,0x0C,0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63,
+ 0x63,0x65,0x73,0x73,0x6F,0x72,0x69,0x65,0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61,
+ 0x72,0x65,0x20,0x41,0x75,0x74,0x68,0x65,0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,
+ 0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,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,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,
+ 0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x00,0x28,
+ 0x4C,0xD4,0xFA,0x57,0x5C,0xB5,0x62,0xE6,0x10,0x30,0x60,0xBB,0x4E,0x8E,0xE9,0x34,
+ 0x52,0xFC,0xAB,0x74,0x4C,0x62,0xDA,0xEE,0x66,0x47,0x5E,0x5D,0x0D,0x04,0x2A,0x22,
+ 0x49,0xC4,0xF0,0x2C,0x93,0xC6,0xA8,0x5E,0x26,0x69,0xAA,0x3C,0x43,0xF8,0x49,0xCC,
+ 0x89,0x03,0x98,0xB3,0x7A,0x90,0xC8,0x79,0xFD,0x5A,0x13,0xE7,0x26,0x8C,0xA3,0x42,
+ 0x30,0x40,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,0x6F,0x79,
+ 0x89,0xE2,0x11,0xB0,0x49,0xE2,0xC1,0x5C,0xC4,0xDC,0xC7,0xE0,0x62,0x9F,0x3B,0x0A,
+ 0xC6,0x8C,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,
+ 0x01,0x06,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x03,0x48,
+ 0x00,0x30,0x45,0x02,0x21,0x00,0x9A,0x4F,0xA8,0xC3,0xC2,0x06,0x7D,0x86,0x3D,0x6F,
+ 0x9B,0x02,0xD7,0xBC,0xD6,0x28,0xE2,0x22,0xAA,0x90,0x62,0x73,0xED,0x91,0x34,0xD7,
+ 0x62,0xF0,0x4D,0xD7,0xD4,0x38,0x02,0x20,0x23,0x7B,0x01,0x88,0xBB,0xB9,0xF2,0x00,
+ 0x04,0x20,0x9B,0xC7,0x69,0x97,0x4B,0xAE,0xC6,0xB0,0x2E,0x93,0xE3,0x9B,0x50,0x8B,
+ 0xC8,0x1E,0xA4,0x94,0xF6,0x97,0x78,0x78,
+};
+
+/* subject:/CN=0/O=TestPPID1234 */
+/* issuer :/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */
+uint8_t _malformed_iAPSWAuth_leaf[739]={
+ 0x30,0x82,0x02,0xDF,0x30,0x82,0x02,0x85,0xA0,0x03,0x02,0x01,0x02,0x02,0x0A,0x12,
+ 0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78,0x90,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,
+ 0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x85,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,
+ 0x03,0x0C,0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F,0x72,
+ 0x69,0x65,0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x41,0x75,0x74,
+ 0x68,0x65,0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x52,0x6F,0x6F,0x74,
+ 0x20,0x43,0x41,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,0x37,0x31,0x31,0x31,0x35,0x32,0x30,0x34,0x33,0x35,0x38,0x5A,0x17,0x0D,
+ 0x32,0x37,0x31,0x32,0x31,0x33,0x32,0x30,0x34,0x33,0x35,0x38,0x5A,0x30,0x23,0x31,
+ 0x0A,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x0C,0x01,0x30,0x31,0x15,0x30,0x13,0x06,
+ 0x03,0x55,0x04,0x0A,0x0C,0x0C,0x54,0x65,0x73,0x74,0x50,0x50,0x49,0x44,0x31,0x32,
+ 0x33,0x34,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,
+ 0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0xC1,0xBD,0x0B,
+ 0x4E,0xBA,0xD3,0xC6,0x8F,0x70,0x39,0x73,0xBF,0x58,0xB7,0x75,0x02,0x41,0x60,0x62,
+ 0x70,0x6A,0x4D,0xA6,0x5C,0xF6,0xE7,0x5B,0xA9,0xAF,0x50,0x60,0x35,0x90,0xED,0x7D,
+ 0x28,0xF1,0x3C,0xF5,0x1D,0x4B,0xF4,0x32,0x41,0x3E,0x05,0x79,0x0B,0xEB,0xDD,0x89,
+ 0xA0,0x30,0x11,0xC9,0xB0,0x3F,0x83,0x77,0xC4,0xB3,0x2B,0x0A,0xE4,0xA3,0x82,0x01,
+ 0x3C,0x30,0x82,0x01,0x38,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,
+ 0x02,0x30,0x00,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
+ 0x6F,0x79,0x89,0xE2,0x11,0xB0,0x49,0xE2,0xC1,0x5C,0xC4,0xDC,0xC7,0xE0,0x62,0x9F,
+ 0x3B,0x0A,0xC6,0x8C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
+ 0x04,0x4B,0x30,0x49,0x30,0x47,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,
+ 0x86,0x3B,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2D,0x75,0x61,
+ 0x74,0x2E,0x63,0x6F,0x72,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
+ 0x2F,0x6F,0x63,0x73,0x70,0x30,0x33,0x2D,0x74,0x65,0x73,0x74,0x61,0x63,0x63,0x73,
+ 0x77,0x61,0x75,0x74,0x68,0x72,0x6F,0x6F,0x74,0x63,0x61,0x30,0x31,0x30,0x46,0x06,
+ 0x03,0x55,0x1D,0x1F,0x04,0x3F,0x30,0x3D,0x30,0x3B,0xA0,0x39,0xA0,0x37,0x86,0x35,
+ 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2D,0x75,0x61,0x74,0x2E,0x63,
+ 0x6F,0x72,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x74,0x65,
+ 0x73,0x74,0x61,0x63,0x63,0x73,0x77,0x61,0x75,0x74,0x68,0x72,0x6F,0x6F,0x74,0x63,
+ 0x61,0x2E,0x63,0x72,0x6C,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,
+ 0x95,0x87,0xEF,0xFB,0xDF,0x1F,0x26,0x48,0x67,0x29,0xEC,0x94,0x70,0xD6,0x29,0x5D,
+ 0x9A,0x95,0xC8,0x88,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,
+ 0x03,0x02,0x07,0x80,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,
+ 0x3B,0x01,0x04,0x03,0x0C,0x01,0x30,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,
+ 0x63,0x64,0x06,0x3B,0x02,0x04,0x03,0x0C,0x01,0x30,0x30,0x11,0x06,0x0A,0x2A,0x86,
+ 0x48,0x86,0xF7,0x63,0x64,0x06,0x3B,0x03,0x04,0x03,0x0C,0x01,0x30,0x30,0x0A,0x06,
+ 0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x21,
+ 0x00,0x9B,0xF6,0xD2,0x7D,0x61,0x1F,0xFD,0x73,0x9C,0x1D,0x54,0x3F,0x3C,0x9A,0xDF,
+ 0xAA,0x1D,0xEA,0x35,0xF6,0x41,0xF8,0xB5,0xC5,0x0E,0x92,0x14,0xA3,0x87,0xED,0xE6,
+ 0xD2,0x02,0x20,0x60,0xDA,0x7A,0x30,0xC3,0xEB,0x24,0x58,0xE2,0xBF,0x83,0xFC,0x41,
+ 0x51,0xF3,0xFB,0x50,0xE1,0x0F,0x53,0x6A,0x41,0x7A,0x59,0xA9,0x04,0x01,0x84,0xF9,
+ 0x81,0x89,0x87,
+};
+
+/* subject:/CN=0/O=PPID1234 */
+/* issuer :/CN=Test Accessories Software Authentication Root CA/OU=Apple Certification Authority/O=Apple Inc./C=US */
+uint8_t _iAPSWAuth_leaf[735]={
+ 0x30,0x82,0x02,0xDB,0x30,0x82,0x02,0x82,0xA0,0x03,0x02,0x01,0x02,0x02,0x0B,0x00,
+ 0x8A,0x71,0xFE,0xCD,0xA2,0xF3,0x00,0x00,0x00,0x00,0x30,0x0A,0x06,0x08,0x2A,0x86,
+ 0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x85,0x31,0x39,0x30,0x37,0x06,0x03,0x55,
+ 0x04,0x03,0x0C,0x30,0x54,0x65,0x73,0x74,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F,
+ 0x72,0x69,0x65,0x73,0x20,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x41,0x75,
+ 0x74,0x68,0x65,0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x52,0x6F,0x6F,
+ 0x74,0x20,0x43,0x41,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,0x37,0x31,0x32,0x31,0x32,0x30,0x32,0x35,0x36,0x35,0x30,0x5A,0x17,
+ 0x0D,0x32,0x38,0x30,0x31,0x30,0x39,0x30,0x32,0x35,0x36,0x35,0x30,0x5A,0x30,0x1F,
+ 0x31,0x0A,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x0C,0x01,0x30,0x31,0x11,0x30,0x0F,
+ 0x06,0x03,0x55,0x04,0x0A,0x0C,0x08,0x50,0x50,0x49,0x44,0x31,0x32,0x33,0x34,0x30,
+ 0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,
+ 0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x64,0xFA,0xB0,0xFD,0xAF,0xD3,
+ 0xBF,0x9A,0xF6,0x48,0x03,0x9D,0x6B,0xBB,0x55,0x81,0x5E,0x6C,0x47,0x7D,0x2E,0xD4,
+ 0xF2,0xAE,0xA9,0xD3,0xA7,0x13,0xFA,0x69,0x16,0x16,0xC9,0x46,0x16,0xA2,0x38,0xB7,
+ 0x39,0xAC,0xFE,0x0B,0x9B,0x01,0x81,0x8A,0x94,0xA5,0x49,0x44,0x48,0x22,0x50,0x13,
+ 0x6B,0x06,0x28,0x6E,0x2D,0x09,0x1A,0x40,0x62,0x35,0xA3,0x82,0x01,0x3C,0x30,0x82,
+ 0x01,0x38,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,
+ 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x6F,0x79,0x89,
+ 0xE2,0x11,0xB0,0x49,0xE2,0xC1,0x5C,0xC4,0xDC,0xC7,0xE0,0x62,0x9F,0x3B,0x0A,0xC6,
+ 0x8C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x4B,0x30,
+ 0x49,0x30,0x47,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x3B,0x68,
+ 0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2D,0x75,0x61,0x74,0x2E,0x63,
+ 0x6F,0x72,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,
+ 0x73,0x70,0x30,0x33,0x2D,0x74,0x65,0x73,0x74,0x61,0x63,0x63,0x73,0x77,0x61,0x75,
+ 0x74,0x68,0x72,0x6F,0x6F,0x74,0x63,0x61,0x30,0x31,0x30,0x46,0x06,0x03,0x55,0x1D,
+ 0x1F,0x04,0x3F,0x30,0x3D,0x30,0x3B,0xA0,0x39,0xA0,0x37,0x86,0x35,0x68,0x74,0x74,
+ 0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2D,0x75,0x61,0x74,0x2E,0x63,0x6F,0x72,0x70,
+ 0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x74,0x65,0x73,0x74,0x61,
+ 0x63,0x63,0x73,0x77,0x61,0x75,0x74,0x68,0x72,0x6F,0x6F,0x74,0x63,0x61,0x2E,0x63,
+ 0x72,0x6C,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xE3,0xA0,0x9F,
+ 0x50,0x4D,0x31,0xB6,0xB3,0xED,0x16,0x5B,0xA3,0x91,0x68,0xB8,0xC2,0x65,0x40,0x73,
+ 0x4D,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,
+ 0x80,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x3B,0x01,0x04,
+ 0x03,0x04,0x01,0x01,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,
+ 0x3B,0x02,0x04,0x03,0x04,0x01,0x00,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,
+ 0x63,0x64,0x06,0x3B,0x03,0x04,0x03,0x04,0x01,0x01,0x30,0x0A,0x06,0x08,0x2A,0x86,
+ 0x48,0xCE,0x3D,0x04,0x03,0x02,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x39,0x57,0x87,
+ 0x0B,0x53,0xB3,0x24,0x14,0x96,0x26,0xD2,0xA5,0x06,0xC2,0xA8,0x4C,0x5C,0x40,0xD4,
+ 0xC4,0x8D,0xEC,0x2D,0x2F,0x80,0xFB,0x2B,0xAF,0x56,0xF1,0x10,0x32,0x02,0x20,0x6D,
+ 0xCC,0xA8,0x41,0x92,0x89,0xD4,0xB8,0xEF,0xE5,0xB3,0x30,0xF7,0x94,0xBE,0x85,0x52,
+ 0xFE,0x75,0x5E,0xB2,0xEF,0x34,0x2F,0x71,0x8B,0xCD,0xD2,0xF0,0x9F,0xF7,0x63,
+};
+
#endif /* _SECURITY_SI_22_SECTRUST_IAP_H_ */
#include "shared_regressions.h"
-/* subject:/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 */
-/* issuer :/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */
-static const uint8_t _c0[]={
- 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,
-};
-
-
-/* subject:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */
-/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */
-static const uint8_t _c1[]= {
- 0x30,0x82,0x05,0x2B,0x30,0x82,0x04,0x13,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x7E,
- 0xE1,0x4A,0x6F,0x6F,0xEF,0xF2,0xD3,0x7F,0x3F,0xAD,0x65,0x4D,0x3A,0xDA,0xB4,0x30,
- 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,
- 0xCA,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
- 0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
- 0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,
- 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,
- 0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,
- 0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69,
- 0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,
- 0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,
- 0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,
- 0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,
- 0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,
- 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,
- 0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x1E,0x17,0x0D,0x31,
- 0x33,0x31,0x30,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x33,
- 0x31,0x30,0x33,0x30,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,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,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,0xD8,0xA1,0x65,0x74,0x23,0xE8,0x2B,0x64,0xE2,0x32,0xD7,
- 0x33,0x37,0x3D,0x8E,0xF5,0x34,0x16,0x48,0xDD,0x4F,0x7F,0x87,0x1C,0xF8,0x44,0x23,
- 0x13,0x8E,0xFB,0x11,0xD8,0x44,0x5A,0x18,0x71,0x8E,0x60,0x16,0x26,0x92,0x9B,0xFD,
- 0x17,0x0B,0xE1,0x71,0x70,0x42,0xFE,0xBF,0xFA,0x1C,0xC0,0xAA,0xA3,0xA7,0xB5,0x71,
- 0xE8,0xFF,0x18,0x83,0xF6,0xDF,0x10,0x0A,0x13,0x62,0xC8,0x3D,0x9C,0xA7,0xDE,0x2E,
- 0x3F,0x0C,0xD9,0x1D,0xE7,0x2E,0xFB,0x2A,0xCE,0xC8,0x9A,0x7F,0x87,0xBF,0xD8,0x4C,
- 0x04,0x15,0x32,0xC9,0xD1,0xCC,0x95,0x71,0xA0,0x4E,0x28,0x4F,0x84,0xD9,0x35,0xFB,
- 0xE3,0x86,0x6F,0x94,0x53,0xE6,0x72,0x8A,0x63,0x67,0x2E,0xBE,0x69,0xF6,0xF7,0x6E,
- 0x8E,0x9C,0x60,0x04,0xEB,0x29,0xFA,0xC4,0x47,0x42,0xD2,0x78,0x98,0xE3,0xEC,0x0B,
- 0xA5,0x92,0xDC,0xB7,0x9A,0xBD,0x80,0x64,0x2B,0x38,0x7C,0x38,0x09,0x5B,0x66,0xF6,
- 0x2D,0x95,0x7A,0x86,0xB2,0x34,0x2E,0x85,0x9E,0x90,0x0E,0x5F,0xB7,0x5D,0xA4,0x51,
- 0x72,0x46,0x70,0x13,0xBF,0x67,0xF2,0xB6,0xA7,0x4D,0x14,0x1E,0x6C,0xB9,0x53,0xEE,
- 0x23,0x1A,0x4E,0x8D,0x48,0x55,0x43,0x41,0xB1,0x89,0x75,0x6A,0x40,0x28,0xC5,0x7D,
- 0xDD,0xD2,0x6E,0xD2,0x02,0x19,0x2F,0x7B,0x24,0x94,0x4B,0xEB,0xF1,0x1A,0xA9,0x9B,
- 0xE3,0x23,0x9A,0xEA,0xFA,0x33,0xAB,0x0A,0x2C,0xB7,0xF4,0x60,0x08,0xDD,0x9F,0x1C,
- 0xCD,0xDD,0x2D,0x01,0x66,0x80,0xAF,0xB3,0x2F,0x29,0x1D,0x23,0xB8,0x8A,0xE1,0xA1,
- 0x70,0x07,0x0C,0x34,0x0F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5D,0x30,0x82,
- 0x01,0x59,0x30,0x2F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x23,
- 0x30,0x21,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x13,
- 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x32,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,
- 0x63,0x6F,0x6D,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,
- 0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x65,0x06,0x03,0x55,0x1D,0x20,0x04,0x5E,
- 0x30,0x5C,0x30,0x5A,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x52,0x30,0x26,0x06,0x08,
- 0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,
- 0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,
- 0x2F,0x63,0x70,0x73,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
- 0x30,0x1C,0x1A,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,
- 0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x30,0x30,
- 0x06,0x03,0x55,0x1D,0x1F,0x04,0x29,0x30,0x27,0x30,0x25,0xA0,0x23,0xA0,0x21,0x86,
- 0x1F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x31,0x2E,0x73,0x79,0x6D,0x63,0x62,
- 0x2E,0x63,0x6F,0x6D,0x2F,0x70,0x63,0x61,0x33,0x2D,0x67,0x35,0x2E,0x63,0x72,0x6C,
- 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,
- 0x30,0x29,0x06,0x03,0x55,0x1D,0x11,0x04,0x22,0x30,0x20,0xA4,0x1E,0x30,0x1C,0x31,
- 0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x53,0x79,0x6D,0x61,0x6E,0x74,
- 0x65,0x63,0x50,0x4B,0x49,0x2D,0x31,0x2D,0x35,0x33,0x33,0x30,0x1D,0x06,0x03,0x55,
- 0x1D,0x0E,0x04,0x16,0x04,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59,0xA6,0x64,
- 0x63,0xD6,0xCF,0x20,0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x1F,0x06,0x03,0x55,0x1D,
- 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xD3,0x65,0xA7,0xC2,0xDD,0xEC,0xBB,0xF0,
- 0x30,0x09,0xF3,0x43,0x39,0xFA,0x02,0xAF,0x33,0x31,0x33,0x30,0x0D,0x06,0x09,0x2A,
- 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x42,
- 0x01,0x55,0x7B,0xD0,0x16,0x1A,0x5D,0x58,0xE8,0xBB,0x9B,0xA8,0x4D,0xD7,0xF3,0xD7,
- 0xEB,0x13,0x94,0x86,0xD6,0x7F,0x21,0x0B,0x47,0xBC,0x57,0x9B,0x92,0x5D,0x4F,0x05,
- 0x9F,0x38,0xA4,0x10,0x7C,0xCF,0x83,0xBE,0x06,0x43,0x46,0x8D,0x08,0xBC,0x6A,0xD7,
- 0x10,0xA6,0xFA,0xAB,0xAF,0x2F,0x61,0xA8,0x63,0xF2,0x65,0xDF,0x7F,0x4C,0x88,0x12,
- 0x88,0x4F,0xB3,0x69,0xD9,0xFF,0x27,0xC0,0x0A,0x97,0x91,0x8F,0x56,0xFB,0x89,0xC4,
- 0xA8,0xBB,0x92,0x2D,0x1B,0x73,0xB0,0xC6,0xAB,0x36,0xF4,0x96,0x6C,0x20,0x08,0xEF,
- 0x0A,0x1E,0x66,0x24,0x45,0x4F,0x67,0x00,0x40,0xC8,0x07,0x54,0x74,0x33,0x3B,0xA6,
- 0xAD,0xBB,0x23,0x9F,0x66,0xED,0xA2,0x44,0x70,0x34,0xFB,0x0E,0xEA,0x01,0xFD,0xCF,
- 0x78,0x74,0xDF,0xA7,0xAD,0x55,0xB7,0x5F,0x4D,0xF6,0xD6,0x3F,0xE0,0x86,0xCE,0x24,
- 0xC7,0x42,0xA9,0x13,0x14,0x44,0x35,0x4B,0xB6,0xDF,0xC9,0x60,0xAC,0x0C,0x7F,0xD9,
- 0x93,0x21,0x4B,0xEE,0x9C,0xE4,0x49,0x02,0x98,0xD3,0x60,0x7B,0x5C,0xBC,0xD5,0x30,
- 0x2F,0x07,0xCE,0x44,0x42,0xC4,0x0B,0x99,0xFE,0xE6,0x9F,0xFC,0xB0,0x78,0x86,0x51,
- 0x6D,0xD1,0x2C,0x9D,0xC6,0x96,0xFB,0x85,0x82,0xBB,0x04,0x2F,0xF7,0x62,0x80,0xEF,
- 0x62,0xDA,0x7F,0xF6,0x0E,0xAC,0x90,0xB8,0x56,0xBD,0x79,0x3F,0xF2,0x80,0x6E,0xA3,
- 0xD9,0xB9,0x0F,0x5D,0x3A,0x07,0x1D,0x91,0x93,0x86,0x4B,0x29,0x4C,0xE1,0xDC,0xB5,
- 0xE1,0xE0,0x33,0x9D,0xB3,0xCB,0x36,0x91,0x4B,0xFE,0xA1,0xB4,0xEE,0xF0,0xF9,
-};
-
-static const uint8_t _responderCert[]= {
- 0x30,0x82,0x04,0x58,0x30,0x82,0x03,0x40,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x03,
- 0x56,0x99,0xC9,0x07,0x45,0xC1,0xA9,0x4C,0x50,0x3A,0x24,0x28,0xD6,0x04,0x5D,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,0x37,0x31,
- 0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x37,0x31,0x30,0x31,0x36,
- 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,
- 0x04,0x03,0x13,0x2E,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,0x20,0x4F,0x43,0x53,0x50,0x20,0x52,0x65,0x73,0x70,0x6F,0x6E,0x64,
- 0x65,0x72,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,0xA1,0x49,0x87,0x17,0x74,0x89,0x30,0x97,0x77,0x0D,0x11,0x51,0x51,
- 0x3A,0x80,0x2D,0x7C,0xEC,0xB2,0x4C,0xB1,0xE5,0x46,0x51,0x1C,0xF5,0x7A,0x02,0xB3,
- 0x77,0x19,0x3B,0x7B,0x94,0x00,0x1A,0xA4,0xD1,0xB8,0xF0,0x07,0xF2,0x1B,0x8D,0x70,
- 0xC0,0x81,0x44,0xB5,0x58,0xD8,0x34,0xEC,0x62,0xF7,0x8B,0x4B,0x3C,0x44,0x7D,0xD0,
- 0x35,0xAE,0xEF,0x2B,0xFB,0x75,0xAF,0xB3,0x10,0x32,0xC8,0xF9,0x08,0x2C,0x5C,0x1B,
- 0x07,0x56,0x7C,0x88,0x6D,0xEE,0x4C,0xD5,0x8F,0xD4,0x48,0x41,0xBB,0x03,0xA8,0xBF,
- 0x20,0xE8,0x52,0xFB,0x24,0x5F,0x90,0x78,0xB8,0x87,0x0D,0xD5,0x17,0xAB,0xA8,0xF0,
- 0xDB,0xF8,0x61,0x9F,0xF8,0x09,0x88,0x79,0x19,0x6F,0x57,0xC6,0x69,0x01,0x08,0xAA,
- 0xC6,0xBF,0x8D,0x0C,0x2D,0xD3,0x54,0x89,0x03,0xC8,0xA8,0x55,0x00,0xC2,0x89,0xEC,
- 0x8E,0xD8,0xD8,0x12,0x15,0x26,0x67,0x8E,0x88,0x0F,0x94,0xFA,0x57,0x50,0xE7,0xE9,
- 0x7B,0x1B,0x94,0xF6,0xF1,0xE2,0x91,0x02,0x42,0x4F,0x3B,0x3E,0xB6,0xDD,0x3C,0x78,
- 0xE7,0xC8,0x45,0x4F,0x7B,0x7D,0x41,0xD5,0x95,0x3C,0xD6,0x16,0x84,0xF5,0x16,0xF2,
- 0x45,0x6C,0xBF,0x05,0x00,0x7E,0x92,0x70,0xB7,0x01,0x14,0x86,0x89,0x89,0x9D,0x6B,
- 0xDC,0x5D,0xDF,0x30,0x25,0x7F,0xAA,0x93,0xC0,0xC7,0xC7,0x80,0x12,0xEE,0x47,0xF7,
- 0x90,0x69,0x82,0x86,0xFA,0x22,0x11,0x45,0xAB,0xD1,0x50,0x4F,0xED,0x87,0xCA,0x99,
- 0x20,0xB5,0xC1,0x8D,0xAC,0x01,0x41,0x5C,0x70,0x3C,0x4D,0xD7,0x8E,0xD6,0x8F,0x51,
- 0x19,0x79,0xAB,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x1C,0x30,0x82,0x01,0x18,
- 0x30,0x0F,0x06,0x09,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,0x04,0x02,0x05,
- 0x00,0x30,0x22,0x06,0x03,0x55,0x1D,0x11,0x04,0x1B,0x30,0x19,0xA4,0x17,0x30,0x15,
- 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x54,0x47,0x56,0x2D,0x45,
- 0x2D,0x32,0x31,0x35,0x32,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,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,
- 0x14,0xE3,0x5E,0x00,0x73,0xB3,0x6F,0xFB,0x26,0x90,0x5A,0xE3,0xE5,0xF4,0xB5,0x99,
- 0x95,0xEA,0x80,0xFA,0x9F,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,
- 0x02,0x30,0x00,0x30,0x6E,0x06,0x03,0x55,0x1D,0x20,0x04,0x67,0x30,0x65,0x30,0x63,
- 0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x17,0x03,0x30,0x54,0x30,
- 0x26,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,
- 0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,
- 0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x2A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
- 0x07,0x02,0x02,0x30,0x1E,0x1A,0x1C,0x20,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
- 0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F,
- 0x72,0x70,0x61,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,
- 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,
- 0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
- 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x3B,0x57,0xAB,0x23,
- 0x8E,0x31,0x91,0x87,0x0E,0x02,0xC1,0x55,0xD4,0x53,0x58,0x16,0xEA,0x1B,0x77,0x61,
- 0x68,0x88,0x96,0xC6,0x8D,0x4F,0x57,0xD8,0x80,0x04,0xD2,0xCB,0x41,0x84,0xE9,0x78,
- 0xB1,0x21,0xD0,0xFD,0xB6,0x68,0x8C,0xB0,0xD5,0xED,0x28,0xB3,0xA9,0x9A,0x8A,0xBB,
- 0x88,0x09,0x30,0x04,0xB1,0x29,0xC6,0xC9,0x13,0x4F,0xDB,0xDA,0x52,0x00,0x3A,0x61,
- 0xEE,0xD5,0x6F,0xAB,0xDE,0x71,0x1B,0x8E,0xFA,0xE0,0x1F,0x09,0x9D,0x00,0xF1,0x1F,
- 0xAC,0x88,0x73,0x86,0x37,0xDA,0x7A,0x05,0x3F,0xDB,0xD2,0xEB,0x47,0x0B,0xC9,0x39,
- 0x74,0xA4,0x06,0xBD,0x50,0x63,0x52,0xEE,0x9F,0xE7,0x58,0x07,0x95,0x85,0x6D,0x43,
- 0xE8,0x3B,0x7E,0x0D,0x36,0x65,0x2A,0xB1,0x62,0xB5,0xDB,0x31,0x49,0x38,0x7F,0x6D,
- 0x4E,0xE0,0x9D,0x84,0x79,0x68,0xC3,0x1B,0xFB,0x89,0x54,0xFB,0x3C,0xEC,0xD1,0xF9,
- 0xF1,0xC2,0x57,0xD4,0xBF,0xBE,0xA6,0x22,0xD2,0x84,0xC3,0xC2,0x0E,0x9E,0x0E,0x54,
- 0x25,0x79,0x91,0x16,0x4E,0xBC,0x2B,0xD4,0x4F,0x63,0xB3,0x5B,0x7C,0x70,0x91,0xDE,
- 0xE2,0x70,0x34,0xB9,0x21,0xB4,0x89,0xF6,0x98,0x12,0x9E,0x38,0xF8,0x36,0x29,0x9D,
- 0x0A,0xEC,0xC6,0x69,0xD6,0xC6,0x2E,0xB8,0x38,0x07,0x3F,0xC5,0x52,0x8A,0xEE,0x6F,
- 0x20,0xDE,0x62,0xA7,0x85,0xEC,0x05,0x4A,0x15,0x1B,0x3D,0xA6,0x79,0x09,0x76,0xB0,
- 0x8B,0xDC,0x13,0xD1,0xD2,0x5E,0xAB,0x65,0x99,0x4D,0xA6,0x49,0x66,0xB8,0x2C,0x77,
- 0xAC,0x85,0x71,0xA4,0x69,0x59,0xA6,0xD4,0xAD,0x61,0xA1,0xCE,
-};
-
-/* subject:/serialNumber=424761419/1.3.6.1.4.1.311.60.2.1.3=FR/1.3.6.1.4.1.311.60.2.1.2=Nord/1.3.6.1.4.1.311.60.2.1.1=ROUBAIX/2.5.4.15=V1.0, Clause 5.(b)/C=FR/postalCode=59100/ST=Nord/L=ROUBAIX/streetAddress=140 quai du Sartel/O=OVH/OU=0002 424761419 */
-/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */
-static unsigned char ovh_certificate[1546]={
-0x30,0x82,0x06,0x06,0x30,0x82,0x04,0xEE,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x31,
-0xF0,0x42,0x6A,0x0B,0xBB,0xE7,0x45,0xD4,0x0E,0x51,0x9B,0xE0,0xE5,0xC1,0xB4,0x30,
-0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x73,
-0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,
-0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,
-0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,
-0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,
-0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41,
-0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,
-0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56,0x20,0x53,0x47,0x43,
-0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x38,0x31,0x32,0x30,0x32,0x30,0x30,0x30,
-0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,
-0x35,0x39,0x5A,0x30,0x82,0x01,0x48,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x05,
-0x13,0x09,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39,0x31,0x13,0x30,0x11,0x06,
-0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x46,0x52,
-0x31,0x15,0x30,0x13,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,
-0x02,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x18,0x30,0x16,0x06,0x0B,0x2B,0x06,0x01,
-0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,0x13,0x07,0x52,0x4F,0x55,0x42,0x41,0x49,
-0x58,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x0F,0x13,0x12,0x56,0x31,0x2E,0x30,
-0x2C,0x20,0x43,0x6C,0x61,0x75,0x73,0x65,0x20,0x35,0x2E,0x28,0x62,0x29,0x31,0x0B,
-0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x52,0x31,0x0E,0x30,0x0C,0x06,
-0x03,0x55,0x04,0x11,0x13,0x05,0x35,0x39,0x31,0x30,0x30,0x31,0x0D,0x30,0x0B,0x06,
-0x03,0x55,0x04,0x08,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x10,0x30,0x0E,0x06,0x03,
-0x55,0x04,0x07,0x13,0x07,0x52,0x4F,0x55,0x42,0x41,0x49,0x58,0x31,0x1B,0x30,0x19,
-0x06,0x03,0x55,0x04,0x09,0x13,0x12,0x31,0x34,0x30,0x20,0x71,0x75,0x61,0x69,0x20,
-0x64,0x75,0x20,0x53,0x61,0x72,0x74,0x65,0x6C,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,
-0x04,0x0A,0x13,0x03,0x4F,0x56,0x48,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0B,
-0x13,0x0E,0x30,0x30,0x30,0x32,0x20,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39,
-0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x48,0x6F,0x73,0x74,0x65,
-0x64,0x20,0x62,0x79,0x20,0x54,0x42,0x53,0x20,0x49,0x4E,0x54,0x45,0x52,0x4E,0x45,
-0x54,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0B,0x13,0x0D,0x43,0x6F,0x6D,0x6F,
-0x64,0x6F,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x31,0x14,0x30,0x12,0x06,0x03,0x55,
-0x04,0x03,0x13,0x0B,0x77,0x77,0x77,0x2E,0x6F,0x76,0x68,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,
-0xAF,0x7C,0x18,0x7E,0x00,0x52,0x8E,0x89,0x51,0x56,0x30,0xC8,0x83,0xED,0x53,0xAE,
-0x19,0xB3,0xA2,0x09,0x1A,0x17,0x41,0x6A,0x72,0x26,0xBC,0x77,0x47,0x0A,0xEA,0xA7,
-0x74,0x01,0x68,0x5D,0xC1,0x40,0x54,0x77,0xF2,0x03,0xAC,0xDA,0x1D,0x9F,0xAE,0xD0,
-0x0F,0x13,0x28,0xDD,0xF6,0x98,0xF5,0xAF,0x3D,0x69,0xDE,0xF0,0xE6,0x34,0xFD,0xB9,
-0x94,0x91,0x26,0x9D,0x56,0x9C,0xA5,0xD4,0xBA,0x04,0xFD,0xDA,0x5C,0x8D,0xCB,0x85,
-0x81,0x9D,0xD0,0x85,0x62,0x83,0x41,0xB6,0xAC,0x14,0xC3,0xAA,0xAE,0xA7,0x54,0x84,
-0xFD,0xED,0x9C,0xFC,0xB2,0x51,0xD1,0x43,0x5B,0xF3,0x6E,0xB9,0x6D,0xB1,0xE2,0x19,
-0xB1,0xB4,0xC6,0x15,0x10,0x78,0xBB,0x68,0x8D,0x4D,0x8D,0xE5,0xB2,0x97,0xFD,0x50,
-0xE1,0x07,0x14,0x0A,0xD3,0x28,0x0E,0x0A,0xFB,0xF3,0x18,0x65,0x2E,0xB1,0xD6,0xEE,
-0x00,0x4D,0xB8,0xB7,0xB9,0x86,0x90,0x97,0xC2,0x66,0xCC,0x09,0x11,0xFC,0xD7,0x4B,
-0xEF,0x4A,0x8B,0x9E,0x13,0xD0,0x5E,0x71,0x57,0xA9,0x39,0x91,0x6A,0xB2,0x60,0xC9,
-0x45,0xED,0xD9,0xFA,0x35,0xFF,0xF8,0x28,0xBB,0x87,0x90,0x99,0xBB,0x45,0x30,0x4A,
-0x15,0xC3,0x1D,0x6E,0xCD,0x02,0x1A,0x28,0x8E,0x89,0x1A,0x1A,0xC6,0x58,0xD8,0x78,
-0x1F,0xF0,0x24,0xFE,0x79,0x26,0xA8,0xCF,0x10,0x1E,0x31,0x58,0xF6,0x21,0xBA,0x05,
-0x31,0xF4,0x44,0x89,0x1B,0xC1,0x24,0x62,0x38,0xA8,0xCA,0x1A,0xCE,0x2F,0x2C,0xFA,
-0xB6,0x4F,0x12,0xD4,0x30,0xC6,0xDC,0xC5,0x5B,0x1B,0x8D,0xA2,0xAB,0xCE,0xC3,0x03,
-0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0xBD,0x30,0x82,0x01,0xB9,0x30,0x1F,0x06,
-0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,
-0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,0xF2,0x5B,0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x1D,
-0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xA4,0x72,0x61,0x0C,0x67,0xA4,0x90,
-0xCC,0x81,0x5A,0xDB,0xDF,0x7E,0xE8,0x08,0xF3,0xDA,0x3A,0x1E,0x55,0x30,0x0E,0x06,
-0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x0C,0x06,
-0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x34,0x06,0x03,0x55,
-0x1D,0x25,0x04,0x2D,0x30,0x2B,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,
-0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x0A,0x2B,0x06,0x01,0x04,
-0x01,0x82,0x37,0x0A,0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,
-0x01,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,
-0x03,0x02,0x06,0xC0,0x30,0x46,0x06,0x03,0x55,0x1D,0x20,0x04,0x3F,0x30,0x3D,0x30,
-0x3B,0x06,0x0C,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x01,0x05,0x01,0x30,
-0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,0x68,
-0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,0x6F,
-0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x3A,0x06,0x03,
-0x55,0x1D,0x1F,0x04,0x33,0x30,0x31,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,
-0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,
-0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x6F,0x6D,0x6F,0x64,0x6F,0x45,0x56,0x53,
-0x47,0x43,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x6B,0x06,0x08,0x2B,0x06,0x01,0x05,
-0x05,0x07,0x01,0x01,0x04,0x5F,0x30,0x5D,0x30,0x35,0x06,0x08,0x2B,0x06,0x01,0x05,
-0x05,0x07,0x30,0x02,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x74,
-0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x6F,
-0x6D,0x6F,0x64,0x6F,0x45,0x56,0x53,0x47,0x43,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,
-0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
-0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,
-0x61,0x2E,0x63,0x6F,0x6D,0x30,0x1F,0x06,0x03,0x55,0x1D,0x11,0x04,0x18,0x30,0x16,
-0x82,0x0B,0x77,0x77,0x77,0x2E,0x6F,0x76,0x68,0x2E,0x63,0x6F,0x6D,0x82,0x07,0x6F,
-0x76,0x68,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
-0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x85,0x1C,0xDD,0x46,0x8F,0x8A,
-0x37,0x7F,0xB7,0x13,0x67,0xE2,0x83,0x0A,0xEC,0x6F,0x29,0x02,0xD2,0x03,0xE0,0x84,
-0x66,0x28,0x37,0x0E,0xFF,0x61,0x14,0x0A,0xF5,0x62,0xBF,0x25,0x2B,0x01,0x3F,0xD2,
-0x27,0xCC,0x6B,0xB3,0x79,0xC2,0x93,0x9D,0xA4,0x56,0x6E,0x0C,0x8B,0x25,0x49,0xAA,
-0x8B,0xC9,0xDD,0x6A,0x68,0xFC,0x32,0xDC,0x83,0x17,0x10,0x87,0x90,0x06,0xC3,0xA7,
-0x16,0x77,0x05,0x7D,0x42,0xD7,0xBE,0xA5,0x5F,0x89,0x90,0xA8,0xF8,0x3A,0xFE,0x2E,
-0x95,0x7F,0x51,0x88,0x7D,0xFC,0xA3,0x8A,0x83,0xFF,0xD1,0x86,0xB2,0x30,0x3F,0x22,
-0x77,0xD4,0xE2,0xD8,0x61,0x78,0x50,0x16,0xE1,0x38,0xAD,0x75,0x7F,0x64,0x3D,0x4B,
-0x65,0x06,0x58,0x07,0xBF,0x1B,0x62,0xB2,0xE0,0xC9,0x55,0x08,0x6D,0x0D,0xF1,0x53,
-0x25,0x25,0x12,0x50,0x07,0x84,0xEA,0x43,0x95,0x7D,0xF1,0x1B,0x80,0xFE,0xE4,0x2D,
-0xA5,0x42,0x77,0x2F,0x9E,0x79,0x24,0x0A,0xB0,0xE5,0xCB,0xE7,0x9B,0xA6,0x09,0x7B,
-0xD0,0x5B,0x72,0x43,0x6C,0x91,0x31,0x48,0x35,0x6C,0xA2,0xB6,0xF4,0x64,0xAD,0x7B,
-0x7A,0x25,0x34,0xBA,0x2E,0xB4,0x52,0x2C,0x65,0x41,0xE5,0xCE,0xB2,0x53,0xEF,0xE7,
-0xFF,0x0C,0x39,0x72,0x61,0x91,0x21,0xBB,0x75,0x9A,0x11,0xD0,0xAB,0xB3,0x94,0x08,
-0x44,0xDA,0x78,0xF7,0x92,0x98,0x48,0xAD,0xE4,0xB6,0xBB,0x9F,0xFD,0x59,0x37,0xB6,
-0x42,0x8E,0xEE,0x99,0x90,0xB2,0xA0,0xB5,0xF3,0x68,0xA7,0x54,0x46,0xB6,0x6C,0x05,
-0x27,0x75,0x60,0x87,0x25,0x2E,0x2A,0x16,0xDA,0xA1,
-};
-
-/* This is the cert the ssl server returns to us. */
-/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */
-/* issuer :/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC */
-static unsigned char comodo_ev_certificate[1232]={
-0x30,0x82,0x04,0xCC,0x30,0x82,0x03,0xB4,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x3B,
-0x9F,0xB1,0xF2,0xC0,0x97,0x44,0x9D,0x61,0xA4,0x8F,0x5F,0xF9,0xA6,0xF5,0xE0,0x30,
-0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,
-0x93,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,
-0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x13,0x02,0x55,0x54,0x31,0x17,0x30,0x15,0x06,
-0x03,0x55,0x04,0x07,0x13,0x0E,0x53,0x61,0x6C,0x74,0x20,0x4C,0x61,0x6B,0x65,0x20,
-0x43,0x69,0x74,0x79,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,0x54,
-0x68,0x65,0x20,0x55,0x53,0x45,0x52,0x54,0x52,0x55,0x53,0x54,0x20,0x4E,0x65,0x74,
-0x77,0x6F,0x72,0x6B,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x68,
-0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x75,0x73,0x65,0x72,0x74,0x72,
-0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,
-0x13,0x12,0x55,0x54,0x4E,0x20,0x2D,0x20,0x44,0x41,0x54,0x41,0x43,0x6F,0x72,0x70,
-0x20,0x53,0x47,0x43,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30,
-0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32,0x34,0x31,0x39,0x30,
-0x36,0x33,0x30,0x5A,0x30,0x73,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
-0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,
-0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,
-0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,
-0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,
-0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,
-0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,
-0x45,0x56,0x20,0x53,0x47,0x43,0x20,0x43,0x41,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,0xE8,0xCE,0xAA,0xA9,0x25,0xAF,
-0x2E,0x8E,0xD1,0x79,0x95,0x5E,0xA4,0x88,0x24,0x4F,0xFD,0xB3,0x5C,0xAE,0x2A,0x9E,
-0x4A,0x7B,0x40,0xE0,0xCC,0x50,0xE9,0x81,0x58,0x15,0xD2,0x87,0xF7,0xAD,0x85,0x7A,
-0x69,0x52,0xA0,0x95,0x6E,0x8F,0x67,0x09,0x8E,0xF1,0xF3,0x5C,0x17,0xE3,0x49,0x42,
-0xC8,0x12,0x67,0xA6,0x05,0xF8,0x37,0xA0,0x0F,0x16,0x61,0x0F,0x8F,0x31,0x52,0xC6,
-0xE1,0x87,0xE1,0x4F,0xB9,0xDB,0xC9,0xFE,0x69,0x1B,0xD4,0xC9,0xF7,0x2D,0xAC,0x48,
-0xD7,0x73,0x4A,0x04,0x95,0xE3,0xA1,0x37,0x87,0x52,0x5A,0x88,0xB3,0xD6,0x01,0x2C,
-0xF1,0x03,0x70,0x2C,0x26,0x70,0x2B,0x47,0x3B,0x0A,0xAE,0x31,0x7A,0xD7,0xE5,0x14,
-0x4E,0xAC,0x2F,0x30,0xE1,0x7C,0x6D,0x36,0xDA,0xA0,0xF5,0x83,0x62,0x5D,0x88,0x26,
-0x0D,0x05,0x45,0x5E,0xCE,0xF7,0x8B,0xEB,0x95,0xB4,0xE0,0xEB,0x10,0x7A,0xD4,0xB9,
-0x59,0x75,0x46,0x52,0xDD,0x86,0x74,0x84,0xCB,0x5F,0xD3,0x1C,0x41,0xEA,0xF0,0x9A,
-0xDA,0x91,0x64,0x84,0xDF,0xDE,0x9F,0xF2,0xDD,0xD0,0xFA,0xA6,0x68,0x96,0xB7,0x3E,
-0x97,0x2D,0x7F,0xB1,0xFB,0x8C,0x6C,0xA7,0xFE,0x72,0x82,0xD0,0xE3,0x8A,0xD3,0xBB,
-0xE3,0xCE,0x01,0xB7,0x9D,0x67,0xE9,0xA9,0x13,0x9A,0x3B,0x21,0xED,0xF7,0x73,0x13,
-0xE3,0x33,0x5D,0x7A,0x01,0xA9,0xCA,0x49,0xD0,0x4E,0x63,0x87,0x57,0x81,0x3A,0x17,
-0x54,0x30,0xF6,0x02,0x5E,0x94,0xB6,0x60,0xD2,0x29,0xF9,0x4E,0xE7,0x29,0xA0,0xA0,
-0x9D,0x2A,0x5B,0xEB,0x3F,0x89,0x2E,0x45,0xA2,0xFD,0x02,0x03,0x01,0x00,0x01,0xA3,
-0x82,0x01,0x39,0x30,0x82,0x01,0x35,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,
-0x30,0x16,0x80,0x14,0x53,0x32,0xD1,0xB3,0xCF,0x7F,0xFA,0xE0,0xF1,0xA0,0x5D,0x85,
-0x4E,0x92,0xD2,0x9E,0x45,0x1D,0xB4,0x4F,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
-0x16,0x04,0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,
-0xF2,0x5B,0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,
-0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,
-0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x20,0x06,0x03,0x55,
-0x1D,0x25,0x04,0x19,0x30,0x17,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,
-0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x3E,0x06,
-0x03,0x55,0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00,
-0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,
-0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,
-0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x6D,0x06,
-0x03,0x55,0x1D,0x1F,0x04,0x66,0x30,0x64,0x30,0x31,0xA0,0x2F,0xA0,0x2D,0x86,0x2B,
-0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,
-0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x55,0x54,0x4E,0x2D,0x44,0x41,0x54,0x41,
-0x43,0x6F,0x72,0x70,0x53,0x47,0x43,0x2E,0x63,0x72,0x6C,0x30,0x2F,0xA0,0x2D,0xA0,
-0x2B,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,
-0x6D,0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x55,0x54,0x4E,0x2D,0x44,0x41,0x54,
-0x41,0x43,0x6F,0x72,0x70,0x53,0x47,0x43,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
-0x63,0xCD,0x05,0x7E,0x6F,0x81,0x18,0xF9,0x50,0x25,0x8E,0x91,0x75,0x1B,0x1F,0xF7,
-0x3E,0x02,0x54,0x5B,0xAF,0xD2,0xA3,0x15,0xFD,0xD6,0x1D,0x61,0x73,0x7A,0x9C,0x57,
-0xFA,0xCB,0xB7,0xF9,0xE8,0x32,0xA2,0x02,0x5D,0x36,0xFE,0x34,0x1F,0x6C,0x8A,0xB3,
-0x72,0x43,0x26,0x36,0x8F,0x4D,0x14,0x5E,0x34,0x8A,0xBB,0xFC,0x6B,0x69,0xC4,0x46,
-0x76,0x07,0x04,0x75,0xA4,0xF2,0xA5,0xF8,0x91,0x46,0x2D,0xD5,0x28,0x71,0xE3,0xCC,
-0xA6,0x2C,0x99,0x2F,0xD5,0xFD,0xA3,0x45,0xD8,0x1A,0x9A,0x04,0xFB,0x1D,0x90,0xEE,
-0x57,0x5E,0x08,0x73,0xC0,0x7A,0x02,0x36,0x11,0xEA,0x06,0x44,0x1E,0x39,0xA1,0x2A,
-0x3F,0x22,0x5C,0x91,0xF4,0x22,0x55,0xAF,0x9A,0x0B,0x07,0x56,0x2A,0x59,0x0B,0x71,
-0x5D,0x43,0x16,0xF4,0xE6,0x4F,0xD5,0x50,0xB0,0xCF,0xAD,0xA0,0xF8,0xE2,0x0B,0x00,
-0x3C,0x83,0xA9,0x4E,0x50,0x37,0xD9,0x9C,0x65,0x3E,0x8C,0xC5,0x3A,0xA9,0x51,0xF5,
-0xEB,0x7B,0x56,0xCD,0xF9,0xD5,0xBC,0xE4,0x6B,0x29,0xAC,0x3E,0x09,0x8E,0xB8,0x8D,
-0x76,0x24,0x11,0xA1,0x80,0x4A,0xF2,0xD9,0xEC,0x83,0xD0,0x91,0x03,0x2C,0x6B,0x2B,
-0x11,0xD5,0xD0,0x90,0x81,0xBB,0xE6,0x17,0xBD,0xD0,0xCD,0x85,0x73,0x2D,0x8D,0xDE,
-0x69,0x27,0xE7,0x7E,0xAF,0x39,0x5C,0x0F,0xF2,0xC5,0x7C,0x3D,0xFB,0xE4,0xB0,0xF7,
-0x81,0x1F,0x30,0x54,0x68,0x20,0x9C,0x8C,0xC5,0x2A,0x5A,0x39,0x17,0xCD,0x30,0x68,
-0x5D,0x45,0xD8,0xA7,0xB8,0x4B,0xFD,0xDC,0x2D,0x2D,0x04,0x01,0x8D,0x5D,0x78,0x28,
-};
-
-/* This is the cert we get when we get the url in the AIA extension of the ovh leaf. */
-/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO EV SGC CA */
-/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Certification Authority */
-static unsigned char comodo_aia_certificate[1178]={
-0x30,0x82,0x04,0x96,0x30,0x82,0x03,0x7E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x13,
-0x62,0xE8,0xEB,0x54,0x1A,0x10,0x8C,0xB8,0xA8,0x0E,0xE5,0x9F,0xB1,0xD4,0x51,0x30,
-0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,
-0x81,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,
-0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,
-0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,
-0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,
-0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,
-0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x27,0x30,0x25,0x06,0x03,0x55,
-0x04,0x03,0x13,0x1E,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x65,0x72,0x74,0x69,
-0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,
-0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x32,0x30,0x31,0x30,0x30,0x30,0x30,
-0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
-0x39,0x5A,0x30,0x73,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,
-0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,
-0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,
-0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,
-0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,
-0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x19,0x30,0x17,
-0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56,
-0x20,0x53,0x47,0x43,0x20,0x43,0x41,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,0xE8,0xCE,0xAA,0xA9,0x25,0xAF,0x2E,0x8E,
-0xD1,0x79,0x95,0x5E,0xA4,0x88,0x24,0x4F,0xFD,0xB3,0x5C,0xAE,0x2A,0x9E,0x4A,0x7B,
-0x40,0xE0,0xCC,0x50,0xE9,0x81,0x58,0x15,0xD2,0x87,0xF7,0xAD,0x85,0x7A,0x69,0x52,
-0xA0,0x95,0x6E,0x8F,0x67,0x09,0x8E,0xF1,0xF3,0x5C,0x17,0xE3,0x49,0x42,0xC8,0x12,
-0x67,0xA6,0x05,0xF8,0x37,0xA0,0x0F,0x16,0x61,0x0F,0x8F,0x31,0x52,0xC6,0xE1,0x87,
-0xE1,0x4F,0xB9,0xDB,0xC9,0xFE,0x69,0x1B,0xD4,0xC9,0xF7,0x2D,0xAC,0x48,0xD7,0x73,
-0x4A,0x04,0x95,0xE3,0xA1,0x37,0x87,0x52,0x5A,0x88,0xB3,0xD6,0x01,0x2C,0xF1,0x03,
-0x70,0x2C,0x26,0x70,0x2B,0x47,0x3B,0x0A,0xAE,0x31,0x7A,0xD7,0xE5,0x14,0x4E,0xAC,
-0x2F,0x30,0xE1,0x7C,0x6D,0x36,0xDA,0xA0,0xF5,0x83,0x62,0x5D,0x88,0x26,0x0D,0x05,
-0x45,0x5E,0xCE,0xF7,0x8B,0xEB,0x95,0xB4,0xE0,0xEB,0x10,0x7A,0xD4,0xB9,0x59,0x75,
-0x46,0x52,0xDD,0x86,0x74,0x84,0xCB,0x5F,0xD3,0x1C,0x41,0xEA,0xF0,0x9A,0xDA,0x91,
-0x64,0x84,0xDF,0xDE,0x9F,0xF2,0xDD,0xD0,0xFA,0xA6,0x68,0x96,0xB7,0x3E,0x97,0x2D,
-0x7F,0xB1,0xFB,0x8C,0x6C,0xA7,0xFE,0x72,0x82,0xD0,0xE3,0x8A,0xD3,0xBB,0xE3,0xCE,
-0x01,0xB7,0x9D,0x67,0xE9,0xA9,0x13,0x9A,0x3B,0x21,0xED,0xF7,0x73,0x13,0xE3,0x33,
-0x5D,0x7A,0x01,0xA9,0xCA,0x49,0xD0,0x4E,0x63,0x87,0x57,0x81,0x3A,0x17,0x54,0x30,
-0xF6,0x02,0x5E,0x94,0xB6,0x60,0xD2,0x29,0xF9,0x4E,0xE7,0x29,0xA0,0xA0,0x9D,0x2A,
-0x5B,0xEB,0x3F,0x89,0x2E,0x45,0xA2,0xFD,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,
-0x15,0x30,0x82,0x01,0x11,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,
-0x80,0x14,0x0B,0x58,0xE5,0x8B,0xC6,0x4C,0x15,0x37,0xA4,0x40,0xA9,0x30,0xA9,0x21,
-0xBE,0x47,0x36,0x5A,0x56,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,
-0x14,0x7F,0xF6,0x4C,0x36,0x28,0x14,0xAE,0xCD,0x1E,0x37,0xAF,0xDE,0x5A,0xF2,0x5B,
-0xC3,0xA0,0xAC,0x2B,0xFE,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,
-0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,
-0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x20,0x06,0x03,0x55,0x1D,0x25,
-0x04,0x19,0x30,0x17,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,
-0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x3E,0x06,0x03,0x55,
-0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x2B,
-0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,0x68,0x74,
-0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,0x6F,0x6D,
-0x6F,0x64,0x6F,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x30,0x49,0x06,0x03,0x55,
-0x1D,0x1F,0x04,0x42,0x30,0x40,0x30,0x3E,0xA0,0x3C,0xA0,0x3A,0x86,0x38,0x68,0x74,
-0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,
-0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x43,0x65,0x72,0x74,
-0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,
-0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
-0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x8C,0xD9,0xD9,0x52,0x33,0xEE,
-0x07,0xF6,0xE1,0xEC,0xAB,0x15,0xE0,0x9F,0x15,0xD8,0x99,0x25,0xDB,0x19,0x95,0x25,
-0x9B,0x43,0xBE,0x59,0x2B,0x81,0x29,0xC8,0xF8,0xF1,0x5F,0x8E,0x49,0x02,0x36,0x46,
-0x1C,0xEB,0xF2,0xA1,0xFE,0xD1,0x0A,0x45,0xBA,0xD0,0xDB,0x50,0x44,0x0C,0x50,0xA3,
-0x3C,0x6E,0x5F,0x84,0xD4,0x4F,0x1A,0xA8,0x69,0x8F,0x24,0x66,0x01,0xD2,0x0B,0xB4,
-0x08,0x19,0xBA,0xBD,0x34,0x09,0x90,0x09,0x62,0x71,0xAD,0x39,0x8E,0xB8,0x78,0x79,
-0xB1,0x24,0x78,0xB4,0xCD,0xA7,0x49,0xF9,0x6D,0x78,0x7F,0x70,0x87,0x82,0x91,0x35,
-0xAC,0xB1,0x00,0x86,0x21,0x51,0xD2,0xCD,0x46,0xCB,0x3A,0x82,0xC0,0x48,0x1A,0xD3,
-0x15,0x26,0xDB,0xF1,0x0F,0x82,0x71,0x66,0xE2,0x8B,0x77,0x54,0xA3,0x76,0x2F,0xD7,
-0x6D,0xF8,0x0D,0x0E,0xCE,0x3A,0x4E,0x65,0x57,0x3F,0x1C,0x77,0x50,0xCA,0xBB,0x7A,
-0x53,0xF7,0xFB,0x5F,0x3D,0x75,0x56,0xAA,0xD3,0xE3,0x1F,0x12,0xB5,0x1D,0xBF,0xC3,
-0xDC,0xE1,0xF9,0x39,0x67,0x81,0xF1,0x33,0x9C,0xC8,0x1E,0xC5,0xE6,0xEE,0x2B,0xB9,
-0xD9,0x58,0xC8,0xC7,0x2E,0xDF,0x48,0xD1,0xC9,0xE4,0xB3,0x1A,0x08,0x5F,0x9A,0x18,
-0x6D,0x61,0xD3,0xB0,0xAD,0x27,0x5E,0x08,0x35,0x34,0x25,0xA1,0x9F,0x42,0xC8,0x75,
-0x98,0xD3,0x02,0x64,0x55,0x94,0xE3,0xAF,0xD1,0xE7,0x4A,0xB9,0xE4,0xD9,0x06,0x6E,
-0x71,0x28,0xF8,0xDD,0xAC,0xE5,0x45,0xDF,0xD8,0xE7,0x28,0x05,0xA1,0x68,0xCE,0xC1,
-0x25,0x5B,0x85,0xFA,0x46,0x9D,0xFE,0xDB,0x64,0xF0,
-};
-
-static unsigned char revoked_ist_certificate[1515]={
-0x30,0x82,0x05,0xE7,0x30,0x82,0x04,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x7F,
-0x00,0xCE,0x8A,0xD6,0x3F,0x5B,0x34,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
-0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,
-0x03,0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20,
-0x32,0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,
-0x17,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,0x13,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,0x34,
-0x31,0x31,0x32,0x38,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x17,0x0D,0x31,0x36,0x31,
-0x32,0x32,0x37,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x30,0x81,0xAB,0x31,0x4B,0x30,
-0x49,0x06,0x03,0x55,0x04,0x03,0x0C,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,
-0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D,
-0x63,0x61,0x2E,0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65,
-0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72,
-0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x25,0x30,0x23,0x06,0x03,
-0x55,0x04,0x0B,0x0C,0x1C,0x6D,0x61,0x6E,0x61,0x67,0x65,0x6D,0x65,0x6E,0x74,0x3A,
-0x69,0x64,0x6D,0x73,0x2E,0x67,0x72,0x6F,0x75,0x70,0x2E,0x31,0x37,0x36,0x33,0x39,
-0x39,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,
-0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,
-0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x0B,0x30,0x09,0x06,
-0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,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,0xA9,0xD7,0xE0,0x65,0x48,0x36,0x8A,
-0x4B,0x6C,0xBB,0x16,0xAF,0xFD,0x09,0xA5,0x9C,0x30,0xDA,0xC5,0x9B,0x3D,0xD6,0xB4,
-0x8E,0x6B,0xC2,0xF4,0xBF,0x30,0xA7,0xCC,0xF7,0xA1,0x23,0x58,0xA0,0x16,0xE8,0x31,
-0x5F,0xE7,0xD2,0x21,0x3D,0x24,0x3D,0xF4,0x1E,0x82,0x46,0x45,0xA0,0xB8,0x2E,0xD7,
-0xB6,0x86,0xD3,0x2A,0xBC,0x93,0x74,0x44,0xAB,0x1C,0x9F,0x86,0xBF,0x19,0xCE,0xA4,
-0xD0,0xC9,0xB9,0x65,0x84,0x89,0x87,0xDE,0x77,0xDC,0xAE,0x85,0xA9,0xDE,0x5A,0xCF,
-0xAF,0x46,0x80,0x45,0x72,0x68,0x87,0x55,0x5B,0x4D,0x49,0xE2,0x7B,0x25,0x31,0x22,
-0x00,0x87,0xAB,0x72,0xEB,0x9A,0x2D,0x81,0x35,0x0E,0x76,0x82,0x5C,0x99,0x10,0xFB,
-0xD6,0x3F,0x29,0xE8,0xFD,0x2E,0xAD,0xF6,0xF8,0xCF,0xC1,0x99,0x5F,0xDA,0xC1,0xB3,
-0x90,0x70,0xA5,0x4B,0x23,0x4D,0xD6,0x1D,0xC9,0x73,0x27,0xD1,0xAE,0x38,0xA3,0xD0,
-0x71,0x92,0xFF,0x89,0xA8,0xE5,0x51,0x3E,0x2F,0xB6,0xB4,0x02,0x20,0x54,0x62,0xA0,
-0x69,0x6D,0xB6,0x10,0x8D,0xB7,0x13,0x2A,0x94,0x4E,0xED,0x73,0x8C,0x78,0x39,0xF6,
-0x04,0xC0,0xF8,0x7A,0x75,0x2D,0x1E,0x82,0x7E,0x55,0x7B,0xE7,0xA7,0xFA,0x6E,0xB1,
-0x53,0x81,0x75,0xB6,0x19,0xD8,0xD2,0xD3,0x8E,0x30,0x95,0x0D,0xD8,0xC9,0xBA,0x3F,
-0x70,0x23,0xC3,0x7B,0xE2,0x6E,0xA9,0xA8,0x91,0x69,0x89,0x8D,0xEA,0x64,0x5D,0x8E,
-0x49,0x43,0x30,0x99,0xBC,0x54,0x97,0xAC,0xEB,0x98,0x09,0x8C,0xE9,0xA7,0xE8,0xDC,
-0xFC,0xE4,0xBE,0x20,0xDA,0xA1,0x88,0xB6,0x99,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,
-0x02,0x55,0x30,0x82,0x02,0x51,0x30,0x48,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
-0x01,0x01,0x04,0x3C,0x30,0x3A,0x30,0x38,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
-0x30,0x01,0x86,0x2C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,
-0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,0x73,0x70,0x30,0x34,
-0x2D,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74,0x63,0x61,0x32,0x67,0x31,0x30,0x31,
-0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x75,0x81,0x7F,0xDF,0xDE,
-0x90,0xE2,0xFB,0x67,0xA8,0x04,0xC9,0x82,0xE1,0x2A,0x13,0x08,0x3D,0xCE,0x8E,0x30,
-0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x1F,0x06,
-0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xD8,0x7A,0x94,0x44,0x7C,0x90,
-0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C,0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,0x30,0x81,
-0xFF,0x06,0x03,0x55,0x1D,0x20,0x04,0x81,0xF7,0x30,0x81,0xF4,0x30,0x81,0xF1,0x06,
-0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x0B,0x04,0x30,0x81,0xE2,0x30,0x81,
-0xA4,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x81,0x97,0x0C,0x81,
-0x94,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,
-0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x62,0x79,
-0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,0x74,0x79,0x20,0x61,0x73,0x73,0x75,0x6D,
-0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,0x6E,0x63,0x65,0x20,0x6F,0x66,
-0x20,0x61,0x6E,0x79,0x20,0x61,0x70,0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20,
-0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x64,0x69,0x74,
-0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x6E,0x64,0x2F,
-0x6F,0x72,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
-0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,0x74,0x61,0x74,0x65,0x6D,
-0x65,0x6E,0x74,0x73,0x2E,0x30,0x39,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,
-0x01,0x16,0x2D,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,0x2F,0x72,0x70,0x61,
-0x30,0x37,0x06,0x03,0x55,0x1D,0x1F,0x04,0x30,0x30,0x2E,0x30,0x2C,0xA0,0x2A,0xA0,
-0x28,0x86,0x26,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x61,0x70,
-0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74,
-0x63,0x61,0x32,0x67,0x31,0x2E,0x63,0x72,0x6C,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,0x4D,0x06,0x03,0x55,0x1D,0x11,0x04,
-0x46,0x30,0x44,0x82,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x67,0x65,0x6F,
-0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D,0x63,0x61,0x2E,
-0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65,0x72,0x74,0x69,
-0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72,0x2E,0x61,0x70,
-0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
-0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC0,0x5B,0xA6,0xAF,0x2C,
-0x27,0xBA,0x49,0x8D,0x41,0xF6,0xC4,0x02,0xEE,0x9D,0xB1,0x48,0xC3,0x34,0x7B,0xF2,
-0xD2,0x82,0x49,0xA5,0x13,0x5A,0x66,0xAD,0xC9,0x73,0xBF,0x6B,0xC9,0x30,0x86,0xBA,
-0x7A,0xD2,0x9D,0x61,0xFE,0x04,0x07,0x15,0x66,0xC2,0x25,0xF7,0x6C,0x88,0xB1,0x0E,
-0x22,0x11,0xF9,0x26,0xA7,0x4E,0x88,0x96,0x20,0x99,0xA6,0x51,0xEE,0x02,0x96,0xC7,
-0xA4,0xCA,0xD4,0xAB,0xFC,0x5F,0x96,0x16,0x0D,0x8D,0xA0,0xA1,0x17,0x6E,0x77,0x92,
-0xC9,0x64,0xD9,0xA2,0x5A,0x00,0x08,0xA6,0x55,0x73,0x2C,0xDD,0xD3,0x0C,0xA5,0xCA,
-0x68,0x48,0xAE,0xCE,0x5F,0xF2,0x56,0x4A,0x66,0x57,0xB2,0x2D,0xB5,0xC6,0xFF,0x50,
-0xD8,0x36,0x9C,0x31,0x31,0xE8,0xB2,0x07,0xE2,0x7B,0xC0,0xCE,0x72,0xA4,0x60,0x91,
-0xBB,0x84,0xA7,0xA8,0xC0,0x1D,0x42,0xE8,0x1D,0xF5,0xD9,0x6B,0x85,0x67,0x23,0x20,
-0xA6,0xF8,0x0F,0xBA,0x83,0x63,0x49,0xE2,0x79,0x23,0x90,0xFF,0x6B,0xEF,0xFA,0xB4,
-0x04,0xA8,0x99,0x1E,0x5D,0x5A,0xCD,0x8C,0xBC,0x8E,0x30,0x41,0x7E,0xE7,0x4E,0xDB,
-0x6F,0x4E,0xB7,0xBA,0xE0,0x5B,0x31,0xC4,0xD2,0x2D,0xD3,0x5D,0x82,0x95,0x44,0x7D,
-0x11,0x60,0x75,0xCE,0x6D,0x12,0xDA,0x89,0x71,0x23,0x80,0x75,0xC0,0x13,0x67,0x27,
-0xE8,0xE8,0xCA,0xE0,0xE3,0xFC,0x72,0x23,0x98,0xFA,0xF0,0x96,0x05,0x23,0xC9,0x03,
-0xC8,0x29,0xA4,0xB1,0xE5,0x07,0xE6,0xE8,0x09,0x26,0xD1,0x8C,0xAF,0xE0,0x53,0xBB,
-0xB4,0x1E,0x4D,0x5E,0xEA,0x9A,0x1E,0xE9,0x42,0x87,0x9F,
-};
-
-static unsigned char ist_intermediate_certificate[1092]={
-0x30,0x82,0x04,0x40,0x30,0x82,0x03,0x28,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x02,
-0x3A,0x74,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,
-0x00,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
-0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,
-0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,
-0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62,
-0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x34,0x30,0x36,0x31,0x36,0x31,
-0x35,0x34,0x32,0x30,0x32,0x5A,0x17,0x0D,0x32,0x32,0x30,0x35,0x32,0x30,0x31,0x35,
-0x34,0x32,0x30,0x32,0x5A,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,
-0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20,0x32,
-0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17,
-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,
-0x13,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,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,0x93,0xA1,0x1D,0x47,0x43,
-0x20,0x16,0xB2,0x0B,0x6B,0xEB,0xC3,0xD5,0xB4,0xE8,0xC7,0x98,0xCD,0xF3,0xDE,0xBF,
-0xE8,0x4D,0xE9,0xE3,0x36,0x80,0x07,0xFC,0x45,0x1B,0x6A,0x7C,0x45,0x86,0xAE,0x56,
-0xD3,0xA4,0x09,0x7F,0x61,0x0D,0x6B,0x5D,0x7E,0x52,0x6B,0x7D,0xB4,0xC8,0x39,0xC4,
-0xF4,0x67,0x3A,0xF7,0x83,0xCE,0x19,0x6F,0x86,0x2F,0x7E,0x45,0x7E,0x47,0x1C,0x67,
-0x52,0xCA,0x95,0x05,0x5D,0xE2,0x36,0x51,0x85,0xC0,0xD4,0x67,0x80,0x35,0x6F,0x15,
-0xDD,0x3E,0xFD,0x1D,0xD2,0xFD,0x8F,0x34,0x50,0xD8,0xEC,0x76,0x2A,0xBE,0xE3,0xD3,
-0xDA,0xE4,0xFD,0xC8,0xEB,0x28,0x02,0x96,0x11,0x97,0x17,0x61,0x1C,0xE9,0xC4,0x59,
-0x3B,0x42,0xDC,0x32,0xD1,0x09,0x1D,0xDA,0xA6,0xD1,0x43,0x86,0xFF,0x5E,0xB2,0xBC,
-0x8C,0xCF,0x66,0xDB,0x01,0x8B,0x02,0xAE,0x94,0x48,0xF3,0x38,0x8F,0xFD,0xEA,0x32,
-0xA8,0x08,0xEC,0x86,0x97,0x51,0x94,0x24,0x3E,0x49,0x49,0x96,0x53,0xE8,0x79,0xA1,
-0x40,0x81,0xE9,0x05,0xBB,0x93,0x95,0x51,0xFC,0xE3,0xFD,0x7C,0x11,0x4B,0xF7,0x9E,
-0x08,0xB3,0x15,0x49,0x15,0x07,0xF9,0xD1,0x37,0xA0,0x9B,0x4B,0x32,0xF6,0xB5,0xC4,
-0xDC,0x6A,0xD1,0xFC,0x0A,0xED,0xF6,0xE0,0xC5,0x29,0xA0,0xA8,0x8B,0x71,0xFE,0x0D,
-0x92,0xBC,0xFE,0x54,0x70,0x18,0x0A,0x6D,0xC7,0xED,0x0C,0xFB,0xC9,0x2D,0x06,0xC3,
-0x8C,0x85,0xFC,0xCB,0x86,0x5C,0xD6,0x36,0x8E,0x12,0x8B,0x09,0x7F,0xFB,0x19,0x1A,
-0x38,0xD5,0xF0,0x94,0x30,0x7A,0x0F,0xA6,0x8C,0xF3,0x02,0x03,0x01,0x00,0x01,0xA3,
-0x82,0x01,0x1D,0x30,0x82,0x01,0x19,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,
-0x30,0x16,0x80,0x14,0xC0,0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11,
-0x7D,0xAA,0x7D,0x65,0xB8,0xCA,0xCC,0x4E,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
-0x16,0x04,0x14,0xD8,0x7A,0x94,0x44,0x7C,0x90,0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C,
-0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,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,0x35,0x06,0x03,0x55,
-0x1D,0x1F,0x04,0x2E,0x30,0x2C,0x30,0x2A,0xA0,0x28,0xA0,0x26,0x86,0x24,0x68,0x74,
-0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,
-0x2F,0x63,0x72,0x6C,0x73,0x2F,0x67,0x74,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2E,0x63,
-0x72,0x6C,0x30,0x2E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x22,
-0x30,0x20,0x30,0x1E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x12,
-0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E,0x63,
-0x6F,0x6D,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43,0x30,0x41,0x06,
-0x0A,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x36,0x30,0x33,0x30,0x31,0x06,
-0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25,0x68,0x74,0x74,0x70,0x3A,
-0x2F,0x2F,0x77,0x77,0x77,0x2E,0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,
-0x6F,0x6D,0x2F,0x72,0x65,0x73,0x6F,0x75,0x72,0x63,0x65,0x73,0x2F,0x63,0x70,0x73,
-0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,
-0x82,0x01,0x01,0x00,0x16,0x47,0x73,0x6F,0x85,0xA2,0x62,0xE1,0xE7,0x2A,0x76,0xBB,
-0x89,0x95,0x42,0x26,0x97,0xBC,0x4A,0xAC,0xAC,0x70,0x53,0x3A,0x3F,0x31,0x83,0x3D,
-0x3C,0x1C,0xAB,0x9A,0xE2,0xB1,0x5D,0x1C,0x76,0x1A,0xA0,0x3C,0x0C,0x72,0x57,0xBE,
-0xD3,0x9E,0x50,0xE0,0xC8,0x99,0xD6,0x58,0xD7,0x02,0xEA,0xCE,0x0D,0x29,0x54,0x7C,
-0xCD,0xF5,0xC2,0xC6,0x90,0x29,0x55,0xA3,0x6F,0x14,0xA8,0x0B,0x42,0x0D,0x3A,0x98,
-0x6D,0x06,0x78,0x9E,0xF0,0x6A,0xA3,0x1D,0x02,0x0A,0xA2,0x28,0xA4,0x8D,0xC2,0x81,
-0x46,0x3E,0x6D,0x67,0xDA,0xDE,0x3F,0xFE,0x85,0x0E,0x42,0x2A,0x12,0xDE,0xB5,0xB7,
-0xFB,0xB8,0x1B,0xA7,0x96,0xEC,0x77,0x9F,0xEC,0xD4,0x53,0x95,0x7A,0xFF,0x07,0xF4,
-0xF2,0x0A,0x14,0xC0,0x51,0x52,0xB1,0xD6,0x8E,0x50,0x0B,0x1A,0x99,0x5C,0xBC,0x0B,
-0xC9,0xBD,0xED,0xED,0xF8,0x5E,0xC1,0x56,0xDB,0x4D,0x7E,0x23,0xA4,0x11,0xA1,0x2C,
-0xD4,0x1B,0x05,0x9A,0xE4,0x1B,0x52,0xF6,0x7C,0x38,0x99,0x05,0x4B,0xBA,0x72,0x8D,
-0x42,0x89,0x60,0x04,0x66,0x2A,0xF4,0xFD,0x68,0xD7,0x6B,0xF7,0x99,0x41,0x28,0xD6,
-0x6C,0x24,0xAB,0xE6,0x25,0x53,0x2E,0xC8,0x82,0x99,0xE2,0xA2,0x8F,0x23,0xBE,0x30,
-0x83,0xB1,0x27,0x8B,0xFA,0x68,0x7F,0x01,0x49,0xE8,0xC6,0x98,0x6B,0x10,0x2E,0x98,
-0x5E,0x8A,0xD7,0xCA,0x4B,0xB1,0xC7,0xC9,0x58,0x9A,0xD0,0x36,0xDB,0x96,0x95,0xEC,
-0xB6,0x81,0xE4,0xF2,0xCD,0x6F,0x1B,0x79,0x87,0x4C,0x10,0x3C,0x89,0xE4,0x4D,0xFA,
-0x54,0xDC,0xAA,0xA6,
-};
-
-unsigned char smime_leaf_certificate[1338]={
- 0x30,0x82,0x05,0x36,0x30,0x82,0x04,0x1E,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x14,
- 0x00,0x01,0x00,0x02,0x9C,0xE1,0xB9,0xE0,0x7C,0xD1,0x7B,0xEC,0x30,0x0D,0x06,0x09,
- 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x7C,0x31,0x0B,0x30,
- 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,
- 0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,
- 0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,
- 0x0B,0x13,0x1C,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,
- 0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31,
- 0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75,
- 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,
- 0x20,0x4C,0x31,0x20,0x43,0x41,0x20,0x49,0x58,0x30,0x1E,0x17,0x0D,0x31,0x30,0x31,
- 0x31,0x31,0x32,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x17,0x0D,0x31,0x31,0x31,0x31,
- 0x31,0x33,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x30,0x24,0x31,0x0B,0x30,0x09,0x06,
- 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,
- 0x03,0x13,0x0C,0x51,0x75,0x69,0x6E,0x6E,0x20,0x54,0x61,0x79,0x6C,0x6F,0x72,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,
- 0xC1,0x11,0xAA,0x04,0xCF,0x04,0xA0,0x07,0xF3,0x43,0x2A,0xB2,0x27,0x1A,0x13,0x35,
- 0x97,0x9A,0xBA,0x34,0xE5,0x84,0xF3,0xD5,0xE5,0xD9,0xAB,0x23,0x8D,0xB4,0x7E,0x68,
- 0x5C,0xF2,0x9A,0xF1,0x08,0x9B,0x04,0x34,0xC1,0x09,0x14,0x68,0xD8,0x9C,0xC1,0x6C,
- 0x27,0xF5,0x92,0x54,0xAF,0x66,0x65,0xF1,0x50,0xAA,0x7E,0xE3,0xFC,0xC1,0xB0,0x3E,
- 0xEF,0xAA,0x86,0x58,0x4F,0xE7,0x86,0x0A,0x74,0xA6,0x97,0xBD,0x7D,0xF6,0xCE,0xA6,
- 0x8B,0xF7,0xC0,0x90,0x6E,0x50,0x69,0x36,0x65,0x82,0x0F,0x65,0xA7,0x2C,0x16,0xFA,
- 0x6C,0xCA,0x54,0x45,0x7C,0x06,0x20,0x72,0xF0,0x00,0x7B,0xD7,0x17,0xCD,0x94,0x64,
- 0x6A,0xB7,0x28,0xF3,0x62,0xB1,0x29,0xAE,0x0C,0x8A,0x2F,0x3C,0x06,0x89,0xE8,0x81,
- 0x77,0xAD,0x1F,0x65,0xED,0x6F,0x51,0x64,0x65,0x68,0x76,0xD8,0xEE,0xEC,0xA6,0x28,
- 0xA9,0x1C,0x4F,0x98,0x4A,0x6D,0xD0,0xC8,0x5C,0x59,0x17,0x9B,0xF8,0x6D,0xF5,0x93,
- 0xD3,0x4C,0x2A,0x37,0x80,0x65,0xB4,0x34,0xBA,0x64,0x2F,0xA1,0x8E,0x1C,0x6A,0x88,
- 0x7C,0xA3,0xDB,0xDD,0x00,0x9B,0x78,0x51,0x7B,0xA6,0x8D,0xDD,0x43,0x9B,0xB2,0x2E,
- 0x4B,0x1E,0xB3,0x34,0x37,0x3F,0x63,0x08,0x8C,0xC8,0xCF,0xD0,0xB0,0x8C,0xBF,0x8F,
- 0xA7,0x49,0xBD,0x48,0x1D,0xB5,0x1E,0x6A,0x42,0x48,0x16,0x9A,0x7C,0xD3,0x55,0x6B,
- 0xFF,0xD6,0xBA,0x70,0xF3,0x5F,0x1F,0x57,0x16,0xE0,0x1C,0xF1,0x73,0x22,0xD9,0x33,
- 0xA7,0x20,0xE8,0xED,0x52,0x2A,0xE9,0x6F,0xCF,0xFB,0x76,0xAC,0xB8,0x5D,0x9B,0xAB,
- 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x0D,0x30,0x82,0x02,0x09,0x30,0x81,0xA5,
- 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0x98,0x30,0x81,0x95,
- 0x30,0x51,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x45,0x68,0x74,
- 0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,
- 0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65,0x72,0x74,0x73,0x65,0x72,0x76,
- 0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72,0x74,0x73,0x2F,0x74,0x63,0x5F,
- 0x63,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E,
- 0x63,0x72,0x74,0x30,0x40,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,
- 0x34,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x69,0x78,0x2E,
- 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,
- 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
- 0x65,0x72,0x2E,0x64,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,
- 0x80,0x14,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5,0xEE,0x4B,
- 0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,
- 0x04,0x02,0x30,0x00,0x30,0x4A,0x06,0x03,0x55,0x1D,0x20,0x04,0x43,0x30,0x41,0x30,
- 0x3F,0x06,0x09,0x2A,0x82,0x14,0x00,0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30,
- 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70,
- 0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
- 0x65,0x72,0x2E,0x64,0x65,0x2F,0x67,0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73,
- 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x04,0xF0,
- 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF8,0x4D,0x7F,0xDE,0xFA,
- 0x21,0x2E,0xAF,0x96,0xBB,0xAA,0x9B,0x22,0x56,0x80,0xF0,0x8E,0xD4,0x6A,0x52,0x30,
- 0x62,0x06,0x03,0x55,0x1D,0x1F,0x04,0x5B,0x30,0x59,0x30,0x57,0xA0,0x55,0xA0,0x53,
- 0x86,0x51,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x69,0x78,0x2E,
- 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,
- 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
- 0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F,0x74,0x63,0x5F,
- 0x43,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E,
- 0x63,0x72,0x6C,0x30,0x33,0x06,0x03,0x55,0x1D,0x25,0x04,0x2C,0x30,0x2A,0x06,0x08,
- 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
- 0x03,0x04,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,0x06,0x0A,0x2B,0x06,
- 0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,0x30,0x1C,0x06,0x03,0x55,0x1D,0x11,0x04,
- 0x15,0x30,0x13,0x81,0x11,0x71,0x74,0x61,0x79,0x6C,0x6F,0x72,0x40,0x61,0x70,0x70,
- 0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
- 0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x0D,0xCF,0x33,0xAB,0x3D,0xD3,
- 0xD2,0x06,0x2C,0x20,0x3C,0xEC,0x0C,0xE4,0xA5,0x19,0x86,0xB3,0xA7,0xA9,0xA6,0xE9,
- 0xDC,0xB4,0x35,0xBB,0x0D,0x67,0xD5,0xBD,0x5F,0x93,0xD9,0x2E,0xA0,0x05,0x2A,0xED,
- 0xAE,0x41,0xD9,0xEE,0x30,0xA8,0x82,0x50,0xD0,0x4B,0x04,0x6B,0x37,0xAE,0xC0,0x10,
- 0x89,0x05,0x68,0x82,0x91,0x2B,0x5B,0xE2,0x7D,0xA6,0x87,0xF7,0x26,0x96,0xBA,0x2A,
- 0x52,0x03,0x97,0xF6,0x2E,0x0D,0x81,0x65,0x24,0x10,0xD5,0x8C,0xB3,0xCD,0x19,0x58,
- 0xAF,0x3A,0x3D,0x2F,0x10,0x30,0x79,0x6A,0xD6,0x08,0x8F,0x8B,0x9D,0x1D,0xF8,0x19,
- 0xE4,0x24,0x2B,0xE0,0x7F,0x73,0xE1,0x50,0x9C,0x53,0xE1,0x46,0xC7,0xA7,0xBD,0x71,
- 0xCD,0xFF,0x39,0xA0,0x50,0xA5,0xA8,0xD9,0x50,0x39,0x6C,0x36,0x1C,0x13,0x89,0x8A,
- 0x0D,0x9D,0x06,0x1B,0xAA,0x59,0x40,0xC1,0xAF,0xED,0x66,0x31,0xB8,0xA0,0x9F,0xCF,
- 0xA6,0x8A,0x2E,0xC2,0x1A,0x4B,0xDB,0x62,0x15,0x6E,0x10,0x2F,0x82,0x3C,0xF8,0xA2,
- 0x18,0x63,0xCC,0x67,0x13,0x42,0x07,0x43,0xDB,0x20,0x13,0xC7,0xAC,0xCE,0xCB,0xEA,
- 0x7E,0x53,0xA6,0x01,0x81,0xB2,0x6E,0x92,0x2B,0x0C,0xF9,0x01,0x2C,0x11,0xC9,0x00,
- 0x10,0x58,0x64,0x56,0x91,0xAC,0xAA,0xF6,0xE0,0x73,0xC7,0x59,0xEC,0xCE,0x51,0x7E,
- 0xAD,0x9F,0x04,0xA4,0x38,0x74,0x65,0xD0,0x23,0xBD,0x6E,0xDF,0x64,0x79,0xE2,0xA3,
- 0x37,0x19,0x2F,0x8C,0x41,0x8B,0x5F,0x6D,0x84,0x61,0x54,0xD1,0x26,0x18,0x70,0xAD,
- 0xE5,0xF4,0xCD,0x59,0xED,0x9E,0xE0,0xC9,0x9F,0xD3,
-};
-
-unsigned char smime_CA_certificate[1500]={
- 0x30,0x82,0x05,0xD8,0x30,0x82,0x04,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x06,
- 0xE8,0x00,0x01,0x00,0x02,0x4A,0x96,0x2D,0x24,0x0C,0xFE,0xC5,0xC9,0x30,0x0D,0x06,
- 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B,
- 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,
- 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,
- 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,
- 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,
- 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,
- 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,
- 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,
- 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x39,0x31,0x31,0x30,
- 0x33,0x31,0x34,0x30,0x38,0x31,0x39,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31,
- 0x32,0x31,0x35,0x39,0x35,0x39,0x5A,0x30,0x7C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
- 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,
- 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,
- 0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,0x54,
- 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,
- 0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31,0x28,0x30,0x26,0x06,
- 0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,
- 0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,
- 0x43,0x41,0x20,0x49,0x58,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,0xBB,0xE6,0x90,0x6E,0xCF,0x62,0xE9,0xE9,0x0B,0xAA,
- 0xB6,0x10,0xD5,0x47,0xE5,0x7C,0x5D,0x2B,0x27,0x71,0x9A,0x68,0xCD,0x55,0x6D,0xE4,
- 0xA2,0xEF,0xE4,0xFE,0xF2,0x7A,0x63,0x11,0xC2,0x57,0x8A,0xC8,0x7D,0xCF,0x8E,0x66,
- 0x1F,0x65,0x45,0x4B,0xEB,0x80,0x62,0x69,0xBD,0x46,0x8E,0x8B,0xC5,0x6E,0x5A,0x95,
- 0x18,0x2A,0xDE,0xA7,0xF1,0x1F,0x75,0x1A,0x27,0xAB,0x6D,0x32,0x53,0xE3,0xFB,0x4D,
- 0x58,0x62,0x2C,0xFF,0x19,0xE5,0xC7,0xA0,0x0D,0x9A,0x2D,0x21,0x88,0x59,0x84,0xCD,
- 0x1D,0xF1,0xC3,0xC8,0x8A,0x3E,0xB0,0xE5,0xDE,0x08,0x24,0xCF,0xFC,0x40,0x2C,0xBA,
- 0x41,0x23,0x94,0xBB,0x80,0x12,0x89,0x35,0x48,0xB6,0x86,0x04,0xE0,0x01,0x4F,0x8C,
- 0xBA,0xA9,0x98,0xFC,0x1C,0x89,0xED,0x1F,0x8A,0xA1,0xC7,0x86,0x98,0x26,0x1E,0x72,
- 0x65,0x6B,0xFE,0xCF,0x65,0xD9,0x0C,0x64,0x4B,0x1A,0x09,0xF5,0x43,0x11,0x60,0x66,
- 0x26,0xE3,0x33,0x56,0x9A,0xC9,0x3D,0x3E,0x34,0x6A,0x78,0xC6,0xE5,0x50,0x4B,0xC8,
- 0xCD,0x88,0xE4,0x39,0x6C,0x50,0x26,0x9E,0x40,0x2C,0xB6,0x3B,0x7C,0x37,0xB2,0xA7,
- 0xF5,0xDD,0xDC,0xB3,0x51,0xCB,0xF4,0xDC,0x82,0x02,0xB8,0xD7,0x3A,0xDE,0xDA,0x30,
- 0x5C,0x0D,0xF5,0x42,0xDD,0x13,0x69,0x53,0x54,0xE9,0x80,0x26,0x42,0x33,0x1E,0xA5,
- 0xD7,0xCC,0x6E,0xCA,0x66,0x09,0x9F,0x86,0xF0,0x3D,0xBE,0xC6,0x8A,0x61,0x10,0xF3,
- 0xD1,0xFF,0x5B,0xE4,0xB2,0xDB,0x2D,0xB2,0x65,0x0C,0xA9,0x7D,0x17,0xAC,0xBA,0x27,
- 0x4D,0x42,0x5C,0xCE,0x09,0x4F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x59,0x30,
- 0x82,0x02,0x55,0x30,0x81,0x9A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
- 0x04,0x81,0x8D,0x30,0x81,0x8A,0x30,0x52,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
- 0x30,0x02,0x86,0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,
- 0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65,
- 0x72,0x74,0x73,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72,
- 0x74,0x73,0x2F,0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F,
- 0x72,0x6F,0x6F,0x74,0x5F,0x49,0x2E,0x63,0x72,0x74,0x30,0x34,0x06,0x08,0x2B,0x06,
- 0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x28,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,
- 0x63,0x73,0x70,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D,
- 0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,
- 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75,
- 0x2C,0xA4,0x9E,0xBE,0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,
- 0x73,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,
- 0x01,0xFF,0x02,0x01,0x00,0x30,0x52,0x06,0x03,0x55,0x1D,0x20,0x04,0x4B,0x30,0x49,
- 0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x3F,0x06,0x09,0x2A,0x82,0x14,0x00,
- 0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
- 0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,
- 0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x67,
- 0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73,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,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5,
- 0xEE,0x4B,0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x81,0xFD,0x06,0x03,0x55,0x1D,0x1F,
- 0x04,0x81,0xF5,0x30,0x81,0xF2,0x30,0x81,0xEF,0xA0,0x81,0xEC,0xA0,0x81,0xE9,0x86,
- 0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x74,0x63,0x75,0x6E,
- 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D,0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,
- 0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F,
- 0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F,0x72,0x6F,0x6F,
- 0x74,0x5F,0x49,0x2E,0x63,0x72,0x6C,0x86,0x81,0x9E,0x6C,0x64,0x61,0x70,0x3A,0x2F,
- 0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,
- 0x2E,0x64,0x65,0x2F,0x43,0x4E,0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,
- 0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,0x32,0x30,0x55,0x6E,0x69,0x76,0x65,0x72,
- 0x73,0x61,0x6C,0x25,0x32,0x30,0x43,0x41,0x25,0x32,0x30,0x49,0x2C,0x4F,0x3D,0x54,
- 0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,
- 0x32,0x30,0x47,0x6D,0x62,0x48,0x2C,0x4F,0x55,0x3D,0x72,0x6F,0x6F,0x74,0x63,0x65,
- 0x72,0x74,0x73,0x2C,0x44,0x43,0x3D,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
- 0x65,0x72,0x2C,0x44,0x43,0x3D,0x64,0x65,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,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
- 0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x39,0xC8,0xC4,0x9B,
- 0xEE,0xBE,0x98,0xEE,0x48,0x72,0x6F,0x8D,0xE7,0x71,0xB6,0x0E,0x90,0x8C,0xD3,0xB2,
- 0xC1,0x15,0x21,0xA8,0x46,0x90,0x68,0x5F,0x4A,0x04,0xF1,0x3A,0xC9,0x68,0x84,0x21,
- 0xD8,0xA5,0xE6,0x04,0x75,0x5D,0x9F,0xD2,0xD4,0xF2,0x4B,0x77,0x43,0x32,0xDC,0x95,
- 0xCB,0x60,0xBF,0x02,0x55,0xD0,0xAC,0x1C,0xB0,0xC5,0x14,0x97,0x9B,0x65,0x0A,0xC3,
- 0x0F,0xA5,0x1D,0xEC,0xD8,0x49,0x39,0x95,0xB5,0xA9,0xBE,0xFA,0xF4,0x1E,0xAB,0x56,
- 0xE7,0xA6,0xE5,0x01,0x08,0x88,0x35,0x5F,0x67,0x05,0xDD,0x44,0x24,0x50,0x12,0x22,
- 0x44,0x63,0x79,0xF1,0x9B,0x57,0x69,0xCE,0xAB,0xD6,0x33,0x51,0x4F,0x8D,0xF0,0x70,
- 0x3B,0x8E,0xAD,0x51,0x3A,0x17,0x7F,0x35,0x96,0x6B,0x68,0x68,0x63,0xB6,0x1C,0x0A,
- 0xC9,0xF8,0xDF,0x1D,0x5E,0xCF,0x2B,0x11,0xA5,0x63,0xED,0xCC,0xD0,0xC6,0xD3,0x20,
- 0x6F,0xAA,0xFC,0x68,0x48,0x7E,0x6D,0x1E,0xB8,0x3A,0x45,0xAA,0x12,0x86,0xF3,0xC7,
- 0xBD,0x00,0xB5,0xEB,0xFE,0xEA,0x12,0x9F,0x73,0x33,0x78,0xE7,0x28,0x39,0x68,0xD3,
- 0xA5,0x6D,0xDA,0x76,0xD1,0x4E,0xE1,0x55,0x95,0x80,0xA6,0xE0,0x1B,0xB8,0xCD,0xAC,
- 0x56,0xEF,0x45,0x59,0x47,0x98,0x52,0xDB,0x3A,0x6E,0x26,0xB2,0x31,0x39,0x69,0x75,
- 0xB1,0x2E,0x24,0xF0,0xA4,0x9D,0x97,0x88,0x5E,0x33,0x29,0xC6,0xB5,0xBC,0x07,0x40,
- 0x3A,0x0C,0x3D,0xBA,0xCF,0x74,0x8C,0x4B,0x4E,0x7A,0x21,0xFA,0x1B,0x38,0xCD,0xC4,
- 0x43,0x2F,0x6F,0xB4,0xDF,0x78,0xEE,0x99,0x92,0xE7,0x3A,0x1C,
-};
-
-unsigned char smime_root_certificate[993]={
- 0x30,0x82,0x03,0xDD,0x30,0x82,0x02,0xC5,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x1D,
- 0xA2,0x00,0x01,0x00,0x02,0xEC,0xB7,0x60,0x80,0x78,0x8D,0xB6,0x06,0x30,0x0D,0x06,
- 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B,
- 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,
- 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,
- 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,
- 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,
- 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,
- 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,
- 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,
- 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x33,0x32,
- 0x32,0x31,0x35,0x35,0x34,0x32,0x38,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31,
- 0x32,0x32,0x35,0x39,0x35,0x39,0x5A,0x30,0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
- 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,
- 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,
- 0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x0B,0x13,0x1B,0x54,
- 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,
- 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,0x26,0x30,0x24,0x06,0x03,
- 0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,
- 0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,
- 0x20,0x49,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,0xA4,0x77,0x23,0x96,0x44,0xAF,0x90,0xF4,0x31,0xA7,0x10,0xF4,0x26,
- 0x87,0x9C,0xF3,0x38,0xD9,0x0F,0x5E,0xDE,0xCF,0x41,0xE8,0x31,0xAD,0xC6,0x74,0x91,
- 0x24,0x96,0x78,0x1E,0x09,0xA0,0x9B,0x9A,0x95,0x4A,0x4A,0xF5,0x62,0x7C,0x02,0xA8,
- 0xCA,0xAC,0xFB,0x5A,0x04,0x76,0x39,0xDE,0x5F,0xF1,0xF9,0xB3,0xBF,0xF3,0x03,0x58,
- 0x55,0xD2,0xAA,0xB7,0xE3,0x04,0x22,0xD1,0xF8,0x94,0xDA,0x22,0x08,0x00,0x8D,0xD3,
- 0x7C,0x26,0x5D,0xCC,0x77,0x79,0xE7,0x2C,0x78,0x39,0xA8,0x26,0x73,0x0E,0xA2,0x5D,
- 0x25,0x69,0x85,0x4F,0x55,0x0E,0x9A,0xEF,0xC6,0xB9,0x44,0xE1,0x57,0x3D,0xDF,0x1F,
- 0x54,0x22,0xE5,0x6F,0x65,0xAA,0x33,0x84,0x3A,0xF3,0xCE,0x7A,0xBE,0x55,0x97,0xAE,
- 0x8D,0x12,0x0F,0x14,0x33,0xE2,0x50,0x70,0xC3,0x49,0x87,0x13,0xBC,0x51,0xDE,0xD7,
- 0x98,0x12,0x5A,0xEF,0x3A,0x83,0x33,0x92,0x06,0x75,0x8B,0x92,0x7C,0x12,0x68,0x7B,
- 0x70,0x6A,0x0F,0xB5,0x9B,0xB6,0x77,0x5B,0x48,0x59,0x9D,0xE4,0xEF,0x5A,0xAD,0xF3,
- 0xC1,0x9E,0xD4,0xD7,0x45,0x4E,0xCA,0x56,0x34,0x21,0xBC,0x3E,0x17,0x5B,0x6F,0x77,
- 0x0C,0x48,0x01,0x43,0x29,0xB0,0xDD,0x3F,0x96,0x6E,0xE6,0x95,0xAA,0x0C,0xC0,0x20,
- 0xB6,0xFD,0x3E,0x36,0x27,0x9C,0xE3,0x5C,0xCF,0x4E,0x81,0xDC,0x19,0xBB,0x91,0x90,
- 0x7D,0xEC,0xE6,0x97,0x04,0x1E,0x93,0xCC,0x22,0x49,0xD7,0x97,0x86,0xB6,0x13,0x0A,
- 0x3C,0x43,0x23,0x77,0x7E,0xF0,0xDC,0xE6,0xCD,0x24,0x1F,0x3B,0x83,0x9B,0x34,0x3A,
- 0x83,0x34,0xE3,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x1F,0x06,0x03,
- 0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE,
- 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,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,0x1D,
- 0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE,
- 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,0x30,0x0D,0x06,
- 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,
- 0x00,0x28,0xD2,0xE0,0x86,0xD5,0xE6,0xF8,0x7B,0xF0,0x97,0xDC,0x22,0x6B,0x3B,0x95,
- 0x14,0x56,0x0F,0x11,0x30,0xA5,0x9A,0x4F,0x3A,0xB0,0x3A,0xE0,0x06,0xCB,0x65,0xF5,
- 0xED,0xC6,0x97,0x27,0xFE,0x25,0xF2,0x57,0xE6,0x5E,0x95,0x8C,0x3E,0x64,0x60,0x15,
- 0x5A,0x7F,0x2F,0x0D,0x01,0xC5,0xB1,0x60,0xFD,0x45,0x35,0xCF,0xF0,0xB2,0xBF,0x06,
- 0xD9,0xEF,0x5A,0xBE,0xB3,0x62,0x21,0xB4,0xD7,0xAB,0x35,0x7C,0x53,0x3E,0xA6,0x27,
- 0xF1,0xA1,0x2D,0xDA,0x1A,0x23,0x9D,0xCC,0xDD,0xEC,0x3C,0x2D,0x9E,0x27,0x34,0x5D,
- 0x0F,0xC2,0x36,0x79,0xBC,0xC9,0x4A,0x62,0x2D,0xED,0x6B,0xD9,0x7D,0x41,0x43,0x7C,
- 0xB6,0xAA,0xCA,0xED,0x61,0xB1,0x37,0x82,0x15,0x09,0x1A,0x8A,0x16,0x30,0xD8,0xEC,
- 0xC9,0xD6,0x47,0x72,0x78,0x4B,0x10,0x46,0x14,0x8E,0x5F,0x0E,0xAF,0xEC,0xC7,0x2F,
- 0xAB,0x10,0xD7,0xB6,0xF1,0x6E,0xEC,0x86,0xB2,0xC2,0xE8,0x0D,0x92,0x73,0xDC,0xA2,
- 0xF4,0x0F,0x3A,0xBF,0x61,0x23,0x10,0x89,0x9C,0x48,0x40,0x6E,0x70,0x00,0xB3,0xD3,
- 0xBA,0x37,0x44,0x58,0x11,0x7A,0x02,0x6A,0x88,0xF0,0x37,0x34,0xF0,0x19,0xE9,0xAC,
- 0xD4,0x65,0x73,0xF6,0x69,0x8C,0x64,0x94,0x3A,0x79,0x85,0x29,0xB0,0x16,0x2B,0x0C,
- 0x82,0x3F,0x06,0x9C,0xC7,0xFD,0x10,0x2B,0x9E,0x0F,0x2C,0xB6,0x9E,0xE3,0x15,0xBF,
- 0xD9,0x36,0x1C,0xBA,0x25,0x1A,0x52,0x3D,0x1A,0xEC,0x22,0x0C,0x1C,0xE0,0xA4,0xA2,
- 0x3D,0xF0,0xE8,0x39,0xCF,0x81,0xC0,0x7B,0xED,0x5D,0x1F,0x6F,0xC5,0xD0,0x0B,0xD7,
- 0x98,
-};
-
-/* subject:/C=US/ST=California/L=Walnut Creek/O=Lucas Garron/CN=revoked.badssl.com */
-/* issuer :/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */
-uint8_t _probablyRevokedLeaf[]={
- 0x30,0x82,0x06,0xA1,0x30,0x82,0x05,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01,
- 0xAF,0x1E,0xFB,0xDD,0x5E,0xAE,0x09,0x52,0x32,0x0B,0x24,0xFE,0x6B,0x55,0x68,0x30,
- 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4D,
- 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,
- 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,
- 0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03,0x13,0x1E,0x44,
- 0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x53,0x65,0x63,
- 0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,
- 0x0D,0x31,0x36,0x30,0x39,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,
- 0x31,0x39,0x30,0x39,0x31,0x31,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x6D,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,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x07,0x13,0x0C,0x57,0x61,0x6C,0x6E,
- 0x75,0x74,0x20,0x43,0x72,0x65,0x65,0x6B,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,
- 0x0A,0x13,0x0C,0x4C,0x75,0x63,0x61,0x73,0x20,0x47,0x61,0x72,0x72,0x6F,0x6E,0x31,
- 0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65,
- 0x64,0x2E,0x62,0x61,0x64,0x73,0x73,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,0xC7,0x31,0x65,
- 0xE4,0x55,0xCF,0x69,0x90,0x9F,0x6E,0x1F,0xD8,0x6A,0x13,0x7E,0x74,0xBF,0x13,0x3A,
- 0x54,0x64,0x0F,0x74,0x24,0x3D,0xDC,0x60,0xB8,0xA7,0x45,0x01,0xB7,0xC8,0x6A,0x03,
- 0xAC,0x64,0x4A,0x65,0xF0,0x7C,0x81,0x81,0x83,0x0A,0xD9,0xDD,0x31,0x20,0x82,0x48,
- 0xA6,0x33,0x63,0xEE,0x2B,0x74,0xEA,0xB4,0xE6,0xC7,0x1C,0xB2,0x5E,0xE4,0x28,0x3A,
- 0x7A,0x3D,0x20,0x19,0x03,0xB7,0x15,0x3F,0x4F,0xC9,0x26,0xEC,0xB7,0xCB,0xBF,0x48,
- 0x6E,0x5F,0x34,0x70,0x56,0xC4,0x86,0xC7,0xE3,0x52,0x9A,0x21,0x33,0x2F,0x10,0x13,
- 0xF3,0x25,0x0C,0x1E,0x94,0x35,0x2E,0xE8,0xD0,0xD1,0xB5,0xA0,0x77,0x40,0x91,0x2E,
- 0xE9,0xBA,0xF8,0xFF,0x4E,0xF5,0xFB,0xF2,0x7A,0x04,0xA7,0xE6,0xC6,0xCE,0x3F,0x0F,
- 0x10,0x18,0x32,0xC8,0x06,0xBC,0x15,0xB3,0xBE,0x69,0xAC,0x75,0x7D,0x42,0xA0,0x8C,
- 0x2E,0xC3,0xAC,0xE1,0x20,0x4F,0x1E,0x36,0x9C,0x9A,0x2E,0xA2,0xFD,0x79,0x80,0xB6,
- 0x62,0xF8,0xC0,0xB2,0x03,0xA9,0x29,0x50,0xCC,0xD5,0x25,0x8A,0x33,0x5E,0xE0,0x78,
- 0x13,0x18,0xC0,0x80,0x17,0x09,0x95,0xBD,0xA2,0xFE,0x92,0x15,0x07,0x20,0x7A,0x81,
- 0xCE,0xDB,0x0E,0x81,0x29,0x89,0xD4,0xC8,0xEC,0xB3,0xB3,0x79,0x0E,0xF2,0xCE,0x25,
- 0xE7,0xEE,0xBE,0x21,0x7D,0xAF,0x0C,0x13,0x94,0x29,0xDE,0x35,0x9A,0x1E,0xD8,0x84,
- 0x18,0x5A,0x5C,0x1A,0x94,0x82,0xCE,0x9A,0x61,0xD6,0x9D,0xEC,0xF8,0xEE,0xAD,0x3F,
- 0x09,0x5B,0x73,0xEC,0xA2,0x9B,0xFA,0xDC,0x62,0xF1,0x58,0x1F,0x7D,0x02,0x03,0x01,
- 0x00,0x01,0xA3,0x82,0x03,0x5B,0x30,0x82,0x03,0x57,0x30,0x1F,0x06,0x03,0x55,0x1D,
- 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x0F,0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F,
- 0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1,0xC6,0xD9,0xE2,0x30,0x1D,0x06,0x03,0x55,
- 0x1D,0x0E,0x04,0x16,0x04,0x14,0xF4,0x48,0x7D,0x07,0x45,0x1A,0x32,0x07,0x90,0x91,
- 0xAC,0x05,0xB8,0x9F,0xA9,0x11,0xF0,0x7E,0x11,0x36,0x30,0x1D,0x06,0x03,0x55,0x1D,
- 0x11,0x04,0x16,0x30,0x14,0x82,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x62,
- 0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,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,0x6B,0x06,0x03,0x55,0x1D,0x1F,0x04,
- 0x64,0x30,0x62,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,
- 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,
- 0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67,0x35,
- 0x2E,0x63,0x72,0x6C,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70,
- 0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,
- 0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67,
- 0x35,0x2E,0x63,0x72,0x6C,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43,
- 0x30,0x37,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xFD,0x6C,0x01,0x01,0x30,0x2A,0x30,
- 0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74,
- 0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,
- 0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x08,0x06,0x06,0x67,0x81,0x0C,
- 0x01,0x02,0x03,0x30,0x7C,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,
- 0x70,0x30,0x6E,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,
- 0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67,
- 0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x46,0x06,0x08,0x2B,0x06,0x01,
- 0x05,0x05,0x07,0x30,0x02,0x86,0x3A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x61,
- 0x63,0x65,0x72,0x74,0x73,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,
- 0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x53,0x48,0x41,0x32,0x53,
- 0x65,0x63,0x75,0x72,0x65,0x53,0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72,
- 0x74,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,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,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,0x56,
- 0xEC,0xA1,0x37,0xDA,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x3F,0x6C,
- 0xA8,0xF5,0xC4,0x7C,0x01,0x4C,0xC3,0x5A,0x28,0x27,0x50,0x47,0x63,0xD9,0xAC,0xE1,
- 0xBE,0x2D,0xBF,0x87,0x78,0xCB,0x3A,0x80,0x97,0x24,0x74,0xCD,0x16,0xF7,0x02,0x20,
- 0x71,0xFF,0x93,0xA2,0xB5,0x54,0x7E,0x7F,0x53,0x45,0x7F,0x59,0x5A,0x60,0x18,0x21,
- 0x5C,0xAB,0x7D,0x1F,0x08,0xB2,0x54,0xA0,0xB3,0xC4,0x88,0xA5,0x83,0xD2,0x63,0x55,
- 0x00,0x77,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,0x56,0xEC,0xA1,0x37,0xA1,0x00,0x00,0x04,0x03,0x00,
- 0x48,0x30,0x46,0x02,0x21,0x00,0xFE,0x59,0x97,0x22,0x4C,0x6C,0x0F,0x39,0x05,0xD9,
- 0xE4,0xCA,0x7E,0x3B,0xD3,0xB3,0x47,0x1B,0x61,0x72,0xB6,0x3A,0x4F,0xD6,0xF2,0xA3,
- 0x57,0x49,0x48,0x4F,0x6A,0x6D,0x02,0x21,0x00,0x8F,0x14,0x1B,0x3C,0x1B,0x89,0xA3,
- 0x1D,0x70,0xEC,0xD4,0xD7,0x11,0xBC,0xF9,0x0B,0x3C,0x60,0xAC,0x8C,0x84,0x73,0x24,
- 0x6B,0x0E,0x37,0x6E,0x53,0x7F,0x9D,0x7F,0x34,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,0x56,
- 0xEC,0xA1,0x38,0x7F,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x20,0x0E,0xBF,
- 0x53,0x59,0x17,0x0C,0xEC,0x66,0x0C,0x5E,0x87,0xBB,0x8F,0x5F,0xB6,0x76,0x86,0xF2,
- 0x5C,0xFC,0xBC,0xA8,0xB9,0xC0,0xDF,0xBC,0x1A,0x3B,0xEE,0x11,0xF2,0xD0,0x02,0x21,
- 0x00,0x87,0x25,0x39,0xE4,0x32,0x99,0x48,0xCA,0x20,0x1B,0x13,0x96,0x1D,0xC3,0x2C,
- 0x98,0x6B,0x1B,0xC0,0xCC,0xE5,0x67,0x22,0xBD,0x92,0x14,0xE9,0x68,0xCD,0x95,0x82,
- 0x32,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,
- 0x03,0x82,0x01,0x01,0x00,0x5A,0xA0,0x49,0x88,0xAD,0x60,0x1F,0x08,0x53,0x4C,0xD9,
- 0xB8,0xDC,0xF5,0x40,0x41,0xAD,0xEF,0xC8,0x7B,0x01,0x3B,0x13,0x70,0x44,0x99,0xF6,
- 0x5C,0x23,0x46,0xF7,0x3A,0xC8,0x7D,0xC9,0x21,0xAD,0x3A,0x49,0x45,0x82,0x1E,0x5D,
- 0x3B,0x1E,0x9B,0x6A,0x0A,0x3E,0x61,0x2D,0xF6,0xB1,0x99,0x74,0x2F,0x91,0xF9,0xD5,
- 0xF1,0x9F,0xAE,0x74,0x26,0x8B,0x3C,0xA7,0x8C,0xBE,0x28,0xFE,0xAC,0x3B,0x70,0xAE,
- 0x08,0x56,0x71,0xAC,0x55,0x7C,0x40,0x89,0x02,0x2D,0x61,0x2A,0xFD,0x54,0x72,0xBF,
- 0x1A,0x5C,0x70,0x19,0x90,0x15,0xA4,0x76,0xA0,0x7F,0x56,0x1C,0xC1,0xF0,0x8D,0x5E,
- 0x99,0x3D,0x83,0x41,0x54,0x68,0xE5,0x62,0xC1,0x5A,0xA2,0x64,0x8C,0x01,0x64,0x7A,
- 0x23,0xB9,0x3F,0xBF,0x22,0xCF,0x1F,0xC0,0x47,0x80,0x1F,0x94,0xD5,0xF2,0x30,0x84,
- 0xFB,0x07,0x02,0xFA,0x5B,0xA0,0xBA,0x09,0x04,0x98,0x4E,0xF3,0x25,0x56,0x4C,0xC4,
- 0x7E,0xE0,0x27,0xD8,0xE8,0x32,0x8F,0xB3,0x3C,0x5A,0x92,0x4B,0xC0,0x77,0x2D,0xB0,
- 0xE5,0xAE,0x1F,0xAF,0x1D,0x7F,0x21,0x9C,0x65,0x26,0xBE,0x0C,0xBA,0xE8,0x0D,0xC1,
- 0xD2,0x67,0xB4,0xB9,0x33,0xD1,0x4A,0xEE,0xFC,0xB8,0xAF,0x03,0x5B,0xC8,0x3E,0xBC,
- 0xFA,0x09,0x9D,0x04,0xCE,0x3E,0xA6,0xB5,0xC4,0x74,0x3B,0x31,0x7A,0xF3,0x2C,0x42,
- 0xB3,0xC7,0x73,0xDB,0xAA,0x75,0x2E,0x8D,0x8A,0x9E,0x79,0x33,0xBE,0xD7,0xB6,0x14,
- 0x9B,0x26,0xAB,0x7B,0x9E,0x14,0xB3,0x55,0xE6,0x4B,0xBB,0x86,0x94,0x11,0x74,0x02,
- 0x35,0xB4,0x52,0x70,0x9B,
-};
-
-/* subject:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */
-/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */
-uint8_t _digiCertSha2SubCA[] ={
- 0x30,0x82,0x04,0x94,0x30,0x82,0x03,0x7C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01,
- 0xFD,0xA3,0xEB,0x6E,0xCA,0x75,0xC8,0x88,0x43,0x8B,0x72,0x4B,0xCF,0xBC,0x91,0x30,
- 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x61,
- 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,
- 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,
- 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77,
- 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31,
- 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65,
- 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,
- 0x41,0x30,0x1E,0x17,0x0D,0x31,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30,
- 0x30,0x5A,0x17,0x0D,0x32,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30,0x30,
- 0x5A,0x30,0x4D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
- 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,
- 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03,
- 0x13,0x1E,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,
- 0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,
- 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,0xAE,0x58,0x90,0x4D,0xC1,0xC4,0x30,0x15,0x90,0x35,0x5B,0x6E,0x3C,0x82,
- 0x15,0xF5,0x2C,0x5C,0xBD,0xE3,0xDB,0xFF,0x71,0x43,0xFA,0x64,0x25,0x80,0xD4,0xEE,
- 0x18,0xA2,0x4D,0xF0,0x66,0xD0,0x0A,0x73,0x6E,0x11,0x98,0x36,0x17,0x64,0xAF,0x37,
- 0x9D,0xFD,0xFA,0x41,0x84,0xAF,0xC7,0xAF,0x8C,0xFE,0x1A,0x73,0x4D,0xCF,0x33,0x97,
- 0x90,0xA2,0x96,0x87,0x53,0x83,0x2B,0xB9,0xA6,0x75,0x48,0x2D,0x1D,0x56,0x37,0x7B,
- 0xDA,0x31,0x32,0x1A,0xD7,0xAC,0xAB,0x06,0xF4,0xAA,0x5D,0x4B,0xB7,0x47,0x46,0xDD,
- 0x2A,0x93,0xC3,0x90,0x2E,0x79,0x80,0x80,0xEF,0x13,0x04,0x6A,0x14,0x3B,0xB5,0x9B,
- 0x92,0xBE,0xC2,0x07,0x65,0x4E,0xFC,0xDA,0xFC,0xFF,0x7A,0xAE,0xDC,0x5C,0x7E,0x55,
- 0x31,0x0C,0xE8,0x39,0x07,0xA4,0xD7,0xBE,0x2F,0xD3,0x0B,0x6A,0xD2,0xB1,0xDF,0x5F,
- 0xFE,0x57,0x74,0x53,0x3B,0x35,0x80,0xDD,0xAE,0x8E,0x44,0x98,0xB3,0x9F,0x0E,0xD3,
- 0xDA,0xE0,0xD7,0xF4,0x6B,0x29,0xAB,0x44,0xA7,0x4B,0x58,0x84,0x6D,0x92,0x4B,0x81,
- 0xC3,0xDA,0x73,0x8B,0x12,0x97,0x48,0x90,0x04,0x45,0x75,0x1A,0xDD,0x37,0x31,0x97,
- 0x92,0xE8,0xCD,0x54,0x0D,0x3B,0xE4,0xC1,0x3F,0x39,0x5E,0x2E,0xB8,0xF3,0x5C,0x7E,
- 0x10,0x8E,0x86,0x41,0x00,0x8D,0x45,0x66,0x47,0xB0,0xA1,0x65,0xCE,0xA0,0xAA,0x29,
- 0x09,0x4E,0xF3,0x97,0xEB,0xE8,0x2E,0xAB,0x0F,0x72,0xA7,0x30,0x0E,0xFA,0xC7,0xF4,
- 0xFD,0x14,0x77,0xC3,0xA4,0x5B,0x28,0x57,0xC2,0xB3,0xF9,0x82,0xFD,0xB7,0x45,0x58,
- 0x9B,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5A,0x30,0x82,0x01,0x56,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,0x86,0x30,0x34,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,
- 0x30,0x26,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,
- 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67,0x69,
- 0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x7B,0x06,0x03,0x55,0x1D,0x1F,0x04,
- 0x74,0x30,0x72,0x30,0x37,0xA0,0x35,0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,
- 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,
- 0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62,
- 0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x37,0xA0,0x35,
- 0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E,
- 0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67,
- 0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43,
- 0x41,0x2E,0x63,0x72,0x6C,0x30,0x3D,0x06,0x03,0x55,0x1D,0x20,0x04,0x36,0x30,0x34,
- 0x30,0x32,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06,
- 0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,
- 0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,
- 0x2F,0x43,0x50,0x53,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x0F,
- 0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F,0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1,
- 0xC6,0xD9,0xE2,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
- 0x03,0xDE,0x50,0x35,0x56,0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,
- 0xB2,0x3D,0xD1,0x55,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,
- 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x23,0x3E,0xDF,0x4B,0xD2,0x31,0x42,0xA5,
- 0xB6,0x7E,0x42,0x5C,0x1A,0x44,0xCC,0x69,0xD1,0x68,0xB4,0x5D,0x4B,0xE0,0x04,0x21,
- 0x6C,0x4B,0xE2,0x6D,0xCC,0xB1,0xE0,0x97,0x8F,0xA6,0x53,0x09,0xCD,0xAA,0x2A,0x65,
- 0xE5,0x39,0x4F,0x1E,0x83,0xA5,0x6E,0x5C,0x98,0xA2,0x24,0x26,0xE6,0xFB,0xA1,0xED,
- 0x93,0xC7,0x2E,0x02,0xC6,0x4D,0x4A,0xBF,0xB0,0x42,0xDF,0x78,0xDA,0xB3,0xA8,0xF9,
- 0x6D,0xFF,0x21,0x85,0x53,0x36,0x60,0x4C,0x76,0xCE,0xEC,0x38,0xDC,0xD6,0x51,0x80,
- 0xF0,0xC5,0xD6,0xE5,0xD4,0x4D,0x27,0x64,0xAB,0x9B,0xC7,0x3E,0x71,0xFB,0x48,0x97,
- 0xB8,0x33,0x6D,0xC9,0x13,0x07,0xEE,0x96,0xA2,0x1B,0x18,0x15,0xF6,0x5C,0x4C,0x40,
- 0xED,0xB3,0xC2,0xEC,0xFF,0x71,0xC1,0xE3,0x47,0xFF,0xD4,0xB9,0x00,0xB4,0x37,0x42,
- 0xDA,0x20,0xC9,0xEA,0x6E,0x8A,0xEE,0x14,0x06,0xAE,0x7D,0xA2,0x59,0x98,0x88,0xA8,
- 0x1B,0x6F,0x2D,0xF4,0xF2,0xC9,0x14,0x5F,0x26,0xCF,0x2C,0x8D,0x7E,0xED,0x37,0xC0,
- 0xA9,0xD5,0x39,0xB9,0x82,0xBF,0x19,0x0C,0xEA,0x34,0xAF,0x00,0x21,0x68,0xF8,0xAD,
- 0x73,0xE2,0xC9,0x32,0xDA,0x38,0x25,0x0B,0x55,0xD3,0x9A,0x1D,0xF0,0x68,0x86,0xED,
- 0x2E,0x41,0x34,0xEF,0x7C,0xA5,0x50,0x1D,0xBF,0x3A,0xF9,0xD3,0xC1,0x08,0x0C,0xE6,
- 0xED,0x1E,0x8A,0x58,0x25,0xE4,0xB8,0x77,0xAD,0x2D,0x6E,0xF5,0x52,0xDD,0xB4,0x74,
- 0x8F,0xAB,0x49,0x2E,0x9D,0x3B,0x93,0x34,0x28,0x1F,0x78,0xCE,0x94,0xEA,0xC7,0xBD,
- 0xD3,0xC9,0x6D,0x1C,0xDE,0x5C,0x32,0xF3,
-};
-
-/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */
-/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */
-uint8_t _digiCertGlobalRoot[] ={
- 0x30,0x82,0x03,0xAF,0x30,0x82,0x02,0x97,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x08,
- 0x3B,0xE0,0x56,0x90,0x42,0x46,0xB1,0xA1,0x75,0x6A,0xC9,0x59,0x91,0xC7,0x4A,0x30,
- 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x61,
- 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,
- 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,
- 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77,
- 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31,
- 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65,
- 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,
- 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
- 0x30,0x5A,0x17,0x0D,0x33,0x31,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
- 0x5A,0x30,0x61,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
- 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,
- 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,
- 0x13,0x10,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,
- 0x6F,0x6D,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,
- 0x69,0x43,0x65,0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,
- 0x74,0x20,0x43,0x41,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,0xE2,0x3B,0xE1,0x11,0x72,0xDE,0xA8,0xA4,0xD3,0xA3,0x57,
- 0xAA,0x50,0xA2,0x8F,0x0B,0x77,0x90,0xC9,0xA2,0xA5,0xEE,0x12,0xCE,0x96,0x5B,0x01,
- 0x09,0x20,0xCC,0x01,0x93,0xA7,0x4E,0x30,0xB7,0x53,0xF7,0x43,0xC4,0x69,0x00,0x57,
- 0x9D,0xE2,0x8D,0x22,0xDD,0x87,0x06,0x40,0x00,0x81,0x09,0xCE,0xCE,0x1B,0x83,0xBF,
- 0xDF,0xCD,0x3B,0x71,0x46,0xE2,0xD6,0x66,0xC7,0x05,0xB3,0x76,0x27,0x16,0x8F,0x7B,
- 0x9E,0x1E,0x95,0x7D,0xEE,0xB7,0x48,0xA3,0x08,0xDA,0xD6,0xAF,0x7A,0x0C,0x39,0x06,
- 0x65,0x7F,0x4A,0x5D,0x1F,0xBC,0x17,0xF8,0xAB,0xBE,0xEE,0x28,0xD7,0x74,0x7F,0x7A,
- 0x78,0x99,0x59,0x85,0x68,0x6E,0x5C,0x23,0x32,0x4B,0xBF,0x4E,0xC0,0xE8,0x5A,0x6D,
- 0xE3,0x70,0xBF,0x77,0x10,0xBF,0xFC,0x01,0xF6,0x85,0xD9,0xA8,0x44,0x10,0x58,0x32,
- 0xA9,0x75,0x18,0xD5,0xD1,0xA2,0xBE,0x47,0xE2,0x27,0x6A,0xF4,0x9A,0x33,0xF8,0x49,
- 0x08,0x60,0x8B,0xD4,0x5F,0xB4,0x3A,0x84,0xBF,0xA1,0xAA,0x4A,0x4C,0x7D,0x3E,0xCF,
- 0x4F,0x5F,0x6C,0x76,0x5E,0xA0,0x4B,0x37,0x91,0x9E,0xDC,0x22,0xE6,0x6D,0xCE,0x14,
- 0x1A,0x8E,0x6A,0xCB,0xFE,0xCD,0xB3,0x14,0x64,0x17,0xC7,0x5B,0x29,0x9E,0x32,0xBF,
- 0xF2,0xEE,0xFA,0xD3,0x0B,0x42,0xD4,0xAB,0xB7,0x41,0x32,0xDA,0x0C,0xD4,0xEF,0xF8,
- 0x81,0xD5,0xBB,0x8D,0x58,0x3F,0xB5,0x1B,0xE8,0x49,0x28,0xA2,0x70,0xDA,0x31,0x04,
- 0xDD,0xF7,0xB2,0x16,0xF2,0x4C,0x0A,0x4E,0x07,0xA8,0xED,0x4A,0x3D,0x5E,0xB5,0x7F,
- 0xA3,0x90,0xC3,0xAF,0x27,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0E,
- 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,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,0x03,0xDE,0x50,0x35,0x56,0xD1,
- 0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30,0x1F,
- 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x03,0xDE,0x50,0x35,0x56,
- 0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30,
- 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,
- 0x01,0x01,0x00,0xCB,0x9C,0x37,0xAA,0x48,0x13,0x12,0x0A,0xFA,0xDD,0x44,0x9C,0x4F,
- 0x52,0xB0,0xF4,0xDF,0xAE,0x04,0xF5,0x79,0x79,0x08,0xA3,0x24,0x18,0xFC,0x4B,0x2B,
- 0x84,0xC0,0x2D,0xB9,0xD5,0xC7,0xFE,0xF4,0xC1,0x1F,0x58,0xCB,0xB8,0x6D,0x9C,0x7A,
- 0x74,0xE7,0x98,0x29,0xAB,0x11,0xB5,0xE3,0x70,0xA0,0xA1,0xCD,0x4C,0x88,0x99,0x93,
- 0x8C,0x91,0x70,0xE2,0xAB,0x0F,0x1C,0xBE,0x93,0xA9,0xFF,0x63,0xD5,0xE4,0x07,0x60,
- 0xD3,0xA3,0xBF,0x9D,0x5B,0x09,0xF1,0xD5,0x8E,0xE3,0x53,0xF4,0x8E,0x63,0xFA,0x3F,
- 0xA7,0xDB,0xB4,0x66,0xDF,0x62,0x66,0xD6,0xD1,0x6E,0x41,0x8D,0xF2,0x2D,0xB5,0xEA,
- 0x77,0x4A,0x9F,0x9D,0x58,0xE2,0x2B,0x59,0xC0,0x40,0x23,0xED,0x2D,0x28,0x82,0x45,
- 0x3E,0x79,0x54,0x92,0x26,0x98,0xE0,0x80,0x48,0xA8,0x37,0xEF,0xF0,0xD6,0x79,0x60,
- 0x16,0xDE,0xAC,0xE8,0x0E,0xCD,0x6E,0xAC,0x44,0x17,0x38,0x2F,0x49,0xDA,0xE1,0x45,
- 0x3E,0x2A,0xB9,0x36,0x53,0xCF,0x3A,0x50,0x06,0xF7,0x2E,0xE8,0xC4,0x57,0x49,0x6C,
- 0x61,0x21,0x18,0xD5,0x04,0xAD,0x78,0x3C,0x2C,0x3A,0x80,0x6B,0xA7,0xEB,0xAF,0x15,
- 0x14,0xE9,0xD8,0x89,0xC1,0xB9,0x38,0x6C,0xE2,0x91,0x6C,0x8A,0xFF,0x64,0xB9,0x77,
- 0x25,0x57,0x30,0xC0,0x1B,0x24,0xA3,0xE1,0xDC,0xE9,0xDF,0x47,0x7C,0xB5,0xB4,0x24,
- 0x08,0x05,0x30,0xEC,0x2D,0xBD,0x0B,0xBF,0x45,0xBF,0x50,0xB9,0xA9,0xF3,0xEB,0x98,
- 0x01,0x12,0xAD,0xC8,0x88,0xC6,0x98,0x34,0x5F,0x8D,0x0A,0x3C,0xC6,0xE9,0xD5,0x95,
- 0x95,0x6D,0xDE,
-};
+#include "si-23-sectrust-ocsp.h"
static void tests(void)
{
SecTrustRef trust;
SecCertificateRef cert0, cert1, responderCert;
- isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
+ isnt(cert0 = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0)),
NULL, "create cert0");
- isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
+ isnt(cert1 = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1)),
NULL, "create cert1");
CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeArrayCallBacks);
CFArrayAppendValue(certs, cert0);
CFArrayAppendValue(certs, cert1);
- SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, CFSTR("www.paypal.com"));
+ SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.paypal.com"));
SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
const void *v_policies[] = { sslPolicy, ocspPolicy };
CFArrayRef policies = CFArrayCreate(NULL, v_policies,
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
- /* Certificates are only EV if they are also CT. These aren't CT. */
+ /* Certificates are only EV if they are also CT. */
CFDictionaryRef info = SecTrustCopyInfo(trust);
CFBooleanRef ev = (CFBooleanRef)CFDictionaryGetValue(info,
kSecTrustInfoExtendedValidationKey);
- ok(!ev, "extended validation succeeded");
+ ok(ev, "extended validation succeeded");
SecPolicyRef ocspSignerPolicy;
ok(ocspSignerPolicy = SecPolicyCreateOCSPSigner(),
CFArrayAppendValue(rcerts, rcert0);
CFArrayAppendValue(rcerts, rcert1);
- SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, CFSTR("revoked.geotrust-global-ca.test-pages.certificatemanager.apple.com"));
+ SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("revoked.geotrust-global-ca.test-pages.certificatemanager.apple.com"));
SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
const void *v_policies[] = { sslPolicy, ocspPolicy };
CFArrayRef policies = CFArrayCreate(NULL, v_policies,
SecCertificateRef smime_root_cert;
// Import certificates from byte array above
- isnt(smime_leaf_cert = SecCertificateCreateWithBytes(NULL, smime_leaf_certificate, sizeof(smime_leaf_certificate)),
+ isnt(smime_leaf_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_leaf_certificate, sizeof(ocsp_smime_leaf_certificate)),
NULL, "SMIME Leaf Cert");
- isnt(smime_CA_cert = SecCertificateCreateWithBytes(NULL, smime_CA_certificate, sizeof(smime_CA_certificate)),
+ isnt(smime_CA_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_CA_certificate, sizeof(ocsp_smime_CA_certificate)),
NULL, "SMIME CA Cert");
- isnt(smime_root_cert = SecCertificateCreateWithBytes(NULL, smime_root_certificate, sizeof(smime_root_certificate)),
+ isnt(smime_root_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_root_certificate, sizeof(ocsp_smime_root_certificate)),
NULL, "SMIME Root Cert");
SecPolicyRef smimePolicy = SecPolicyCreateWithProperties(kSecPolicyAppleSMIME, NULL);
ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate");
// Check results
- // %%% 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.
+ // NOTE: We now expect a fatal error, since the "TC TrustCenter Class 1 L1 CA IX" CA
+ // is revoked. That CA is no longer present in Valid since the TC root was removed
+ // from the trust store, and as of May 2018, its OCSP server no longer resolves in DNS.
+ // However, the OCSP URI for the CA's issuer is still active and reports the CA as revoked.
+ //
is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure");
CFReleaseNull(trust);
ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate");
// Check results
- // %%% 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.
+ // NOTE: We now expect a fatal error, since the "TC TrustCenter Class 1 L1 CA IX" CA
+ // is revoked. That CA is no longer present in Valid since the TC root was removed
+ // from the trust store, and as of May 2018, its OCSP server no longer resolves in DNS.
+ // However, the OCSP URI for the CA's issuer is still active and reports the CA as revoked.
+ //
is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure");
CFReleaseNull(trust);
SecCertificateRef ovh = NULL, comodo_ev = NULL, comodo_aia = NULL;
CFMutableArrayRef certs = NULL, policies = NULL;
SecPolicyRef sslPolicy = NULL, revPolicy = NULL;
- CFDateRef jan1st2009 = NULL;
+ CFDateRef verifyDate = NULL;
CFDictionaryRef info = NULL;
SecTrustRef trust = NULL;
SecTrustResultType trustResult = kSecTrustResultInvalid;
&kCFTypeArrayCallBacks);
policies = CFArrayCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeArrayCallBacks);
- sslPolicy = SecPolicyCreateSSL(false, CFSTR("www.ovh.com"));
+ sslPolicy = SecPolicyCreateSSL(false, NULL); // For now, use SSL client policy to avoid SHA-1 deprecation
revPolicy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
CFArrayAppendValue(policies, sslPolicy);
CFArrayAppendValue(policies, revPolicy);
- /* Jan 1st 2009. */
- jan1st2009 = CFDateCreate(NULL, 252288000.0);
+ /* May 9th 2018. */
+ verifyDate = CFDateCreate(NULL, 547600500);
/* First run with no intermediate and disallow network fetching.
* Evaluation should fail because it couldn't get the intermediate. */
CFArrayAppendValue(certs, ovh);
ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
"create trust");
- ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date");
+ ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
ok_status(SecTrustSetNetworkFetchAllowed(trust, false), "set no network");
ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
CFArrayAppendValue(certs, comodo_ev);
ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
"create trust");
- ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date");
+ ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
info = SecTrustCopyInfo(trust);
ev = (CFBooleanRef)CFDictionaryGetValue(info,
kSecTrustInfoExtendedValidationKey);
- ok(!ev, "extended validation succeeded due to caissuers fetch");
+ ok(ev, "extended validation succeeded due to caissuers fetch");
//display_anchor_digest(trust);
CFReleaseSafe(info);
CFReleaseSafe(trust);
CFArrayAppendValue(certs, comodo_aia);
ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
"re-create trust with aia intermediate");
- ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date");
+ ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
info = SecTrustCopyInfo(trust);
ev = (CFBooleanRef)CFDictionaryGetValue(info,
kSecTrustInfoExtendedValidationKey);
- ok(!ev, "extended validation succeeded");
+ ok(ev, "extended validation succeeded");
//display_anchor_digest(trust);
CFReleaseSafe(info);
CFReleaseSafe(trust);
CFArrayRemoveValueAtIndex(certs, 1);
ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
"re-create trust with aia intermediate");
- ok_status(SecTrustSetVerifyDate(trust, jan1st2009), "set date");
+ ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
info = SecTrustCopyInfo(trust);
ev = (CFBooleanRef)CFDictionaryGetValue(info,
kSecTrustInfoExtendedValidationKey);
- ok(!ev, "extended validation succeeded");
+ ok(ev, "extended validation succeeded");
//display_anchor_digest(trust);
CFReleaseSafe(info);
CFReleaseSafe(trust);
CFReleaseSafe(comodo_aia);
CFReleaseSafe(comodo_ev);
CFReleaseSafe(ovh);
- CFReleaseSafe(jan1st2009);
+ CFReleaseSafe(verifyDate);
}
-static int ping_host(char *host_name){
-
- struct sockaddr_in pin;
- struct hostent *nlp_host;
- int sd;
- int port;
- int retries = 5;
-
- port=80;
-
- //tries 5 times then give up
- while ((nlp_host=gethostbyname(host_name))==0 && retries--){
- printf("Resolve Error! (%s) %d\n", host_name, h_errno);
- sleep(1);
- }
+static void test_aia_https(void) {
+ SecCertificateRef leaf = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CFArrayRef certs = NULL;
+ CFDateRef verifyDate = NULL;
+ CFErrorRef error = NULL;
- if(nlp_host==0)
- return 0;
+ leaf = SecCertificateCreateWithBytes(NULL, _caissuer_https, sizeof(_caissuer_https));
+ const void *v_certs[] = { leaf };
- bzero(&pin,sizeof(pin));
- pin.sin_family=AF_INET;
- pin.sin_addr.s_addr=htonl(INADDR_ANY);
- pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr;
- pin.sin_port=htons(port);
+ certs = CFArrayCreate(NULL, v_certs, 1, &kCFTypeArrayCallBacks);
+ policy = SecPolicyCreateSSL(true, CFSTR("example.com"));
+ require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
- sd=socket(AF_INET,SOCK_STREAM,0);
+ verifyDate = CFDateCreate(NULL, 546700000.0); // April 29, 2018 at 6:06:40 AM PDT
+ require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
- if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){
- printf("connect error! (%s) %d\n", host_name, errno);
- close(sd);
- return 0;
- }
- else{
- close(sd);
- return 1;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunguarded-availability-new"
+ /* Evaluate trust. This cert does not chain to anything trusted and we can't fetch an
+ * intermediate because the URI is https. */
+ is(SecTrustEvaluateWithError(trust, &error), false, "leaf with missing intermediate and https CAIssuer URI succeeded");
+ if (error) {
+ is(CFErrorGetCode(error), errSecCreateChainFailed, "got wrong error code for revoked cert, got %ld, expected %d",
+ (long)CFErrorGetCode(error), errSecCreateChainFailed);
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
}
+#pragma clang diagnostic pop
+
+errOut:
+ CFReleaseNull(leaf);
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+ CFReleaseNull(certs);
+ CFReleaseNull(verifyDate);
+ CFReleaseNull(error);
}
static void test_set_fetch_allowed(void) {
/* Evaluate trust. SetFetchAllowed should have reset the trust result, so now we should re-do the evaluation and get a revoked failure. */
is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
- is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
- (long)CFErrorGetCode(error), errSecCertificateRevoked);
+ if (error) {
+ is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
+ (long)CFErrorGetCode(error), errSecCertificateRevoked);
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
+ }
#pragma clang diagnostic pop
* due to the temporal validity failure, but not due to revocation since we couldn't check for this
* untrusted chain. */
is(SecTrustEvaluateWithError(trust, &error), false, "not yet valid cert succeeded trust evaluation");
- is(CFErrorGetCode(error), errSecCertificateExpired, "got wrong error code for expired cert");
+ if (error) {
+ is(CFErrorGetCode(error), errSecCertificateExpired, "got wrong error code for expired cert");
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
+ }
CFReleaseNull(error);
/* Set verify date within validity period */
/* Evaluate trust. Now that we trust the chain, we should do a revocation check and get a revocation failure. */
is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
- is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
- (long)CFErrorGetCode(error), errSecCertificateRevoked);
+ if (error) {
+ is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
+ (long)CFErrorGetCode(error), errSecCertificateRevoked);
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
+ }
#pragma clang diagnostic pop
errOut:
CFReleaseNull(error);
}
+static void test_cache(void) {
+ SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CFArrayRef certs = NULL, anchors = NULL;
+ CFDateRef verifyDate = NULL;
+ CFErrorRef error = NULL;
+
+ leaf = SecCertificateCreateWithBytes(NULL, _probablyRevokedLeaf, sizeof(_probablyRevokedLeaf));
+ subCA = SecCertificateCreateWithBytes(NULL, _digiCertSha2SubCA, sizeof(_digiCertSha2SubCA));
+ root = SecCertificateCreateWithBytes(NULL, _digiCertGlobalRoot, sizeof(_digiCertGlobalRoot));
+
+ const void *v_certs[] = { leaf, subCA };
+ const void *v_anchors[] = { root };
+
+ certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
+ policy = SecPolicyCreateSSL(true, CFSTR("revoked.badssl.com"));
+ require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
+
+ anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
+ require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
+
+ verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
+ require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
+
+ /* Clear the OCSP cache in case there are old responses for this cert. */
+ ok(SecTrustFlushResponseCache(&error), "OCSP cache flush failed");
+ CFReleaseNull(error);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunguarded-availability-new"
+ /* Evaluate trust. This cert is revoked, but is only listed as "probably revoked" by valid.apple.com.
+ * This cert should come back as revoked after a network-based fetch. */
+ is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
+ if (error) {
+ is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
+ (long)CFErrorGetCode(error), errSecCertificateRevoked);
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
+ }
+
+ /* Set no fetch allowed, so we're relying on the cached response from above */
+ require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
+
+ /* Evaluate trust. Cached response should tell us that it's revoked. */
+ is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with cached response succeeded");
+ if (error) {
+ is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
+ (long)CFErrorGetCode(error), errSecCertificateRevoked);
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
+ }
+
+#pragma clang diagnostic pop
+
+errOut:
+ CFReleaseNull(leaf);
+ CFReleaseNull(subCA);
+ CFReleaseNull(root);
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+ CFReleaseNull(certs);
+ CFReleaseNull(anchors);
+ CFReleaseNull(verifyDate);
+ CFReleaseNull(error);
+}
+
+static void test_stapled_revoked_response(void) {
+ SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CFArrayRef certs = NULL, anchors = NULL;
+ CFDateRef verifyDate = NULL;
+ CFErrorRef error = NULL;
+ CFDataRef ocspResponse = NULL;
+
+ leaf = SecCertificateCreateWithBytes(NULL, _probablyRevokedLeaf, sizeof(_probablyRevokedLeaf));
+ subCA = SecCertificateCreateWithBytes(NULL, _digiCertSha2SubCA, sizeof(_digiCertSha2SubCA));
+ root = SecCertificateCreateWithBytes(NULL, _digiCertGlobalRoot, sizeof(_digiCertGlobalRoot));
+
+ const void *v_certs[] = { leaf, subCA };
+ const void *v_anchors[] = { root };
+
+ certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
+ policy = SecPolicyCreateSSL(true, CFSTR("revoked.badssl.com"));
+ require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
+
+ anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
+ require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
+
+ verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
+ require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
+
+ /* Set the stapled response */
+ ocspResponse = CFDataCreate(NULL, _digicertOCSPResponse, sizeof(_digicertOCSPResponse));
+ ok_status(SecTrustSetOCSPResponse(trust, ocspResponse), "failed to set OCSP response");
+
+ /* Clear the OCSP cache in case there are old responses for this cert. */
+ ok(SecTrustFlushResponseCache(&error), "OCSP cache flush failed");
+ CFReleaseNull(error);
+
+ /* Set no fetch allowed, so we're relying on the stapled response from above */
+ require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunguarded-availability-new"
+ /* Evaluate trust. This cert is revoked, but is only listed as "probably revoked" by valid.apple.com.
+ * This cert should come back as revoked because of the stapled revoked response. */
+ is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with stapled response succeeded");
+ if (error) {
+ is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
+ (long)CFErrorGetCode(error), errSecCertificateRevoked);
+ } else {
+ fail("expected trust evaluation to fail and it did not.");
+ }
+
+#pragma clang diagnostic pop
+
+errOut:
+ CFReleaseNull(leaf);
+ CFReleaseNull(subCA);
+ CFReleaseNull(root);
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+ CFReleaseNull(certs);
+ CFReleaseNull(anchors);
+ CFReleaseNull(verifyDate);
+ CFReleaseNull(error);
+ CFReleaseNull(ocspResponse);
+}
+
+static int ping_host(char *host_name){
+
+ struct sockaddr_in pin;
+ struct hostent *nlp_host;
+ int sd;
+ int port;
+ int retries = 5;
+
+ port=80;
+
+ //tries 5 times then give up
+ while ((nlp_host=gethostbyname(host_name))==0 && retries--){
+ printf("Resolve Error! (%s) %d\n", host_name, h_errno);
+ sleep(1);
+ }
+
+ if(nlp_host==0)
+ return 0;
+
+ bzero(&pin,sizeof(pin));
+ pin.sin_family=AF_INET;
+ pin.sin_addr.s_addr=htonl(INADDR_ANY);
+ pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr;
+ pin.sin_port=htons(port);
+
+ sd=socket(AF_INET,SOCK_STREAM,0);
+
+ if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){
+ printf("connect error! (%s) %d\n", host_name, errno);
+ close(sd);
+ return 0;
+ }
+ else{
+ close(sd);
+ return 1;
+ }
+}
+
int si_23_sectrust_ocsp(int argc, char *const *argv)
{
char *hosts[] = {
unsigned host_cnt = 0;
- plan_tests(82);
+ plan_tests(93);
for (host_cnt = 0; host_cnt < sizeof(hosts)/sizeof(hosts[0]); host_cnt ++) {
if(!ping_host(hosts[host_cnt])) {
tests();
test_aia();
+ test_aia_https();
test_revocation();
test_forced_revocation();
test_set_fetch_allowed();
test_check_if_trusted();
+ test_cache();
+ test_stapled_revoked_response();
return 0;
}
--- /dev/null
+/*
+ * 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 _SECURITY_SI_23_SECTRUST_OCSP_H_
+#define _SECURITY_SI_23_SECTRUST_OCSP_H_
+
+/* subject:/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 */
+/* issuer :/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */
+static const uint8_t _ocsp_c0[]={
+ 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,
+};
+
+
+/* subject:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */
+/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */
+static const uint8_t _ocsp_c1[]= {
+ 0x30,0x82,0x05,0x2B,0x30,0x82,0x04,0x13,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x7E,
+ 0xE1,0x4A,0x6F,0x6F,0xEF,0xF2,0xD3,0x7F,0x3F,0xAD,0x65,0x4D,0x3A,0xDA,0xB4,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,
+ 0xCA,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
+ 0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
+ 0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,
+ 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,
+ 0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,
+ 0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69,
+ 0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,
+ 0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,
+ 0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,
+ 0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,
+ 0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,
+ 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,
+ 0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x1E,0x17,0x0D,0x31,
+ 0x33,0x31,0x30,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x33,
+ 0x31,0x30,0x33,0x30,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,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,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,0xD8,0xA1,0x65,0x74,0x23,0xE8,0x2B,0x64,0xE2,0x32,0xD7,
+ 0x33,0x37,0x3D,0x8E,0xF5,0x34,0x16,0x48,0xDD,0x4F,0x7F,0x87,0x1C,0xF8,0x44,0x23,
+ 0x13,0x8E,0xFB,0x11,0xD8,0x44,0x5A,0x18,0x71,0x8E,0x60,0x16,0x26,0x92,0x9B,0xFD,
+ 0x17,0x0B,0xE1,0x71,0x70,0x42,0xFE,0xBF,0xFA,0x1C,0xC0,0xAA,0xA3,0xA7,0xB5,0x71,
+ 0xE8,0xFF,0x18,0x83,0xF6,0xDF,0x10,0x0A,0x13,0x62,0xC8,0x3D,0x9C,0xA7,0xDE,0x2E,
+ 0x3F,0x0C,0xD9,0x1D,0xE7,0x2E,0xFB,0x2A,0xCE,0xC8,0x9A,0x7F,0x87,0xBF,0xD8,0x4C,
+ 0x04,0x15,0x32,0xC9,0xD1,0xCC,0x95,0x71,0xA0,0x4E,0x28,0x4F,0x84,0xD9,0x35,0xFB,
+ 0xE3,0x86,0x6F,0x94,0x53,0xE6,0x72,0x8A,0x63,0x67,0x2E,0xBE,0x69,0xF6,0xF7,0x6E,
+ 0x8E,0x9C,0x60,0x04,0xEB,0x29,0xFA,0xC4,0x47,0x42,0xD2,0x78,0x98,0xE3,0xEC,0x0B,
+ 0xA5,0x92,0xDC,0xB7,0x9A,0xBD,0x80,0x64,0x2B,0x38,0x7C,0x38,0x09,0x5B,0x66,0xF6,
+ 0x2D,0x95,0x7A,0x86,0xB2,0x34,0x2E,0x85,0x9E,0x90,0x0E,0x5F,0xB7,0x5D,0xA4,0x51,
+ 0x72,0x46,0x70,0x13,0xBF,0x67,0xF2,0xB6,0xA7,0x4D,0x14,0x1E,0x6C,0xB9,0x53,0xEE,
+ 0x23,0x1A,0x4E,0x8D,0x48,0x55,0x43,0x41,0xB1,0x89,0x75,0x6A,0x40,0x28,0xC5,0x7D,
+ 0xDD,0xD2,0x6E,0xD2,0x02,0x19,0x2F,0x7B,0x24,0x94,0x4B,0xEB,0xF1,0x1A,0xA9,0x9B,
+ 0xE3,0x23,0x9A,0xEA,0xFA,0x33,0xAB,0x0A,0x2C,0xB7,0xF4,0x60,0x08,0xDD,0x9F,0x1C,
+ 0xCD,0xDD,0x2D,0x01,0x66,0x80,0xAF,0xB3,0x2F,0x29,0x1D,0x23,0xB8,0x8A,0xE1,0xA1,
+ 0x70,0x07,0x0C,0x34,0x0F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5D,0x30,0x82,
+ 0x01,0x59,0x30,0x2F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x23,
+ 0x30,0x21,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x13,
+ 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x32,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,
+ 0x63,0x6F,0x6D,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,
+ 0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x65,0x06,0x03,0x55,0x1D,0x20,0x04,0x5E,
+ 0x30,0x5C,0x30,0x5A,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x52,0x30,0x26,0x06,0x08,
+ 0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,
+ 0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,
+ 0x2F,0x63,0x70,0x73,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
+ 0x30,0x1C,0x1A,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,
+ 0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x70,0x61,0x30,0x30,
+ 0x06,0x03,0x55,0x1D,0x1F,0x04,0x29,0x30,0x27,0x30,0x25,0xA0,0x23,0xA0,0x21,0x86,
+ 0x1F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x31,0x2E,0x73,0x79,0x6D,0x63,0x62,
+ 0x2E,0x63,0x6F,0x6D,0x2F,0x70,0x63,0x61,0x33,0x2D,0x67,0x35,0x2E,0x63,0x72,0x6C,
+ 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,
+ 0x30,0x29,0x06,0x03,0x55,0x1D,0x11,0x04,0x22,0x30,0x20,0xA4,0x1E,0x30,0x1C,0x31,
+ 0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x53,0x79,0x6D,0x61,0x6E,0x74,
+ 0x65,0x63,0x50,0x4B,0x49,0x2D,0x31,0x2D,0x35,0x33,0x33,0x30,0x1D,0x06,0x03,0x55,
+ 0x1D,0x0E,0x04,0x16,0x04,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59,0xA6,0x64,
+ 0x63,0xD6,0xCF,0x20,0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x1F,0x06,0x03,0x55,0x1D,
+ 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7F,0xD3,0x65,0xA7,0xC2,0xDD,0xEC,0xBB,0xF0,
+ 0x30,0x09,0xF3,0x43,0x39,0xFA,0x02,0xAF,0x33,0x31,0x33,0x30,0x0D,0x06,0x09,0x2A,
+ 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x42,
+ 0x01,0x55,0x7B,0xD0,0x16,0x1A,0x5D,0x58,0xE8,0xBB,0x9B,0xA8,0x4D,0xD7,0xF3,0xD7,
+ 0xEB,0x13,0x94,0x86,0xD6,0x7F,0x21,0x0B,0x47,0xBC,0x57,0x9B,0x92,0x5D,0x4F,0x05,
+ 0x9F,0x38,0xA4,0x10,0x7C,0xCF,0x83,0xBE,0x06,0x43,0x46,0x8D,0x08,0xBC,0x6A,0xD7,
+ 0x10,0xA6,0xFA,0xAB,0xAF,0x2F,0x61,0xA8,0x63,0xF2,0x65,0xDF,0x7F,0x4C,0x88,0x12,
+ 0x88,0x4F,0xB3,0x69,0xD9,0xFF,0x27,0xC0,0x0A,0x97,0x91,0x8F,0x56,0xFB,0x89,0xC4,
+ 0xA8,0xBB,0x92,0x2D,0x1B,0x73,0xB0,0xC6,0xAB,0x36,0xF4,0x96,0x6C,0x20,0x08,0xEF,
+ 0x0A,0x1E,0x66,0x24,0x45,0x4F,0x67,0x00,0x40,0xC8,0x07,0x54,0x74,0x33,0x3B,0xA6,
+ 0xAD,0xBB,0x23,0x9F,0x66,0xED,0xA2,0x44,0x70,0x34,0xFB,0x0E,0xEA,0x01,0xFD,0xCF,
+ 0x78,0x74,0xDF,0xA7,0xAD,0x55,0xB7,0x5F,0x4D,0xF6,0xD6,0x3F,0xE0,0x86,0xCE,0x24,
+ 0xC7,0x42,0xA9,0x13,0x14,0x44,0x35,0x4B,0xB6,0xDF,0xC9,0x60,0xAC,0x0C,0x7F,0xD9,
+ 0x93,0x21,0x4B,0xEE,0x9C,0xE4,0x49,0x02,0x98,0xD3,0x60,0x7B,0x5C,0xBC,0xD5,0x30,
+ 0x2F,0x07,0xCE,0x44,0x42,0xC4,0x0B,0x99,0xFE,0xE6,0x9F,0xFC,0xB0,0x78,0x86,0x51,
+ 0x6D,0xD1,0x2C,0x9D,0xC6,0x96,0xFB,0x85,0x82,0xBB,0x04,0x2F,0xF7,0x62,0x80,0xEF,
+ 0x62,0xDA,0x7F,0xF6,0x0E,0xAC,0x90,0xB8,0x56,0xBD,0x79,0x3F,0xF2,0x80,0x6E,0xA3,
+ 0xD9,0xB9,0x0F,0x5D,0x3A,0x07,0x1D,0x91,0x93,0x86,0x4B,0x29,0x4C,0xE1,0xDC,0xB5,
+ 0xE1,0xE0,0x33,0x9D,0xB3,0xCB,0x36,0x91,0x4B,0xFE,0xA1,0xB4,0xEE,0xF0,0xF9,
+};
+
+static const uint8_t _responderCert[]= {
+ 0x30,0x82,0x04,0x58,0x30,0x82,0x03,0x40,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x03,
+ 0x56,0x99,0xC9,0x07,0x45,0xC1,0xA9,0x4C,0x50,0x3A,0x24,0x28,0xD6,0x04,0x5D,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,0x37,0x31,
+ 0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x37,0x31,0x30,0x31,0x36,
+ 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,
+ 0x04,0x03,0x13,0x2E,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,0x20,0x4F,0x43,0x53,0x50,0x20,0x52,0x65,0x73,0x70,0x6F,0x6E,0x64,
+ 0x65,0x72,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,0xA1,0x49,0x87,0x17,0x74,0x89,0x30,0x97,0x77,0x0D,0x11,0x51,0x51,
+ 0x3A,0x80,0x2D,0x7C,0xEC,0xB2,0x4C,0xB1,0xE5,0x46,0x51,0x1C,0xF5,0x7A,0x02,0xB3,
+ 0x77,0x19,0x3B,0x7B,0x94,0x00,0x1A,0xA4,0xD1,0xB8,0xF0,0x07,0xF2,0x1B,0x8D,0x70,
+ 0xC0,0x81,0x44,0xB5,0x58,0xD8,0x34,0xEC,0x62,0xF7,0x8B,0x4B,0x3C,0x44,0x7D,0xD0,
+ 0x35,0xAE,0xEF,0x2B,0xFB,0x75,0xAF,0xB3,0x10,0x32,0xC8,0xF9,0x08,0x2C,0x5C,0x1B,
+ 0x07,0x56,0x7C,0x88,0x6D,0xEE,0x4C,0xD5,0x8F,0xD4,0x48,0x41,0xBB,0x03,0xA8,0xBF,
+ 0x20,0xE8,0x52,0xFB,0x24,0x5F,0x90,0x78,0xB8,0x87,0x0D,0xD5,0x17,0xAB,0xA8,0xF0,
+ 0xDB,0xF8,0x61,0x9F,0xF8,0x09,0x88,0x79,0x19,0x6F,0x57,0xC6,0x69,0x01,0x08,0xAA,
+ 0xC6,0xBF,0x8D,0x0C,0x2D,0xD3,0x54,0x89,0x03,0xC8,0xA8,0x55,0x00,0xC2,0x89,0xEC,
+ 0x8E,0xD8,0xD8,0x12,0x15,0x26,0x67,0x8E,0x88,0x0F,0x94,0xFA,0x57,0x50,0xE7,0xE9,
+ 0x7B,0x1B,0x94,0xF6,0xF1,0xE2,0x91,0x02,0x42,0x4F,0x3B,0x3E,0xB6,0xDD,0x3C,0x78,
+ 0xE7,0xC8,0x45,0x4F,0x7B,0x7D,0x41,0xD5,0x95,0x3C,0xD6,0x16,0x84,0xF5,0x16,0xF2,
+ 0x45,0x6C,0xBF,0x05,0x00,0x7E,0x92,0x70,0xB7,0x01,0x14,0x86,0x89,0x89,0x9D,0x6B,
+ 0xDC,0x5D,0xDF,0x30,0x25,0x7F,0xAA,0x93,0xC0,0xC7,0xC7,0x80,0x12,0xEE,0x47,0xF7,
+ 0x90,0x69,0x82,0x86,0xFA,0x22,0x11,0x45,0xAB,0xD1,0x50,0x4F,0xED,0x87,0xCA,0x99,
+ 0x20,0xB5,0xC1,0x8D,0xAC,0x01,0x41,0x5C,0x70,0x3C,0x4D,0xD7,0x8E,0xD6,0x8F,0x51,
+ 0x19,0x79,0xAB,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x1C,0x30,0x82,0x01,0x18,
+ 0x30,0x0F,0x06,0x09,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,0x04,0x02,0x05,
+ 0x00,0x30,0x22,0x06,0x03,0x55,0x1D,0x11,0x04,0x1B,0x30,0x19,0xA4,0x17,0x30,0x15,
+ 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x54,0x47,0x56,0x2D,0x45,
+ 0x2D,0x32,0x31,0x35,0x32,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,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,
+ 0x14,0xE3,0x5E,0x00,0x73,0xB3,0x6F,0xFB,0x26,0x90,0x5A,0xE3,0xE5,0xF4,0xB5,0x99,
+ 0x95,0xEA,0x80,0xFA,0x9F,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,
+ 0x02,0x30,0x00,0x30,0x6E,0x06,0x03,0x55,0x1D,0x20,0x04,0x67,0x30,0x65,0x30,0x63,
+ 0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x17,0x03,0x30,0x54,0x30,
+ 0x26,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,
+ 0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,
+ 0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x2A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
+ 0x07,0x02,0x02,0x30,0x1E,0x1A,0x1C,0x20,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+ 0x77,0x77,0x77,0x2E,0x73,0x79,0x6D,0x61,0x75,0x74,0x68,0x2E,0x63,0x6F,0x6D,0x2F,
+ 0x72,0x70,0x61,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,
+ 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,
+ 0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+ 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x3B,0x57,0xAB,0x23,
+ 0x8E,0x31,0x91,0x87,0x0E,0x02,0xC1,0x55,0xD4,0x53,0x58,0x16,0xEA,0x1B,0x77,0x61,
+ 0x68,0x88,0x96,0xC6,0x8D,0x4F,0x57,0xD8,0x80,0x04,0xD2,0xCB,0x41,0x84,0xE9,0x78,
+ 0xB1,0x21,0xD0,0xFD,0xB6,0x68,0x8C,0xB0,0xD5,0xED,0x28,0xB3,0xA9,0x9A,0x8A,0xBB,
+ 0x88,0x09,0x30,0x04,0xB1,0x29,0xC6,0xC9,0x13,0x4F,0xDB,0xDA,0x52,0x00,0x3A,0x61,
+ 0xEE,0xD5,0x6F,0xAB,0xDE,0x71,0x1B,0x8E,0xFA,0xE0,0x1F,0x09,0x9D,0x00,0xF1,0x1F,
+ 0xAC,0x88,0x73,0x86,0x37,0xDA,0x7A,0x05,0x3F,0xDB,0xD2,0xEB,0x47,0x0B,0xC9,0x39,
+ 0x74,0xA4,0x06,0xBD,0x50,0x63,0x52,0xEE,0x9F,0xE7,0x58,0x07,0x95,0x85,0x6D,0x43,
+ 0xE8,0x3B,0x7E,0x0D,0x36,0x65,0x2A,0xB1,0x62,0xB5,0xDB,0x31,0x49,0x38,0x7F,0x6D,
+ 0x4E,0xE0,0x9D,0x84,0x79,0x68,0xC3,0x1B,0xFB,0x89,0x54,0xFB,0x3C,0xEC,0xD1,0xF9,
+ 0xF1,0xC2,0x57,0xD4,0xBF,0xBE,0xA6,0x22,0xD2,0x84,0xC3,0xC2,0x0E,0x9E,0x0E,0x54,
+ 0x25,0x79,0x91,0x16,0x4E,0xBC,0x2B,0xD4,0x4F,0x63,0xB3,0x5B,0x7C,0x70,0x91,0xDE,
+ 0xE2,0x70,0x34,0xB9,0x21,0xB4,0x89,0xF6,0x98,0x12,0x9E,0x38,0xF8,0x36,0x29,0x9D,
+ 0x0A,0xEC,0xC6,0x69,0xD6,0xC6,0x2E,0xB8,0x38,0x07,0x3F,0xC5,0x52,0x8A,0xEE,0x6F,
+ 0x20,0xDE,0x62,0xA7,0x85,0xEC,0x05,0x4A,0x15,0x1B,0x3D,0xA6,0x79,0x09,0x76,0xB0,
+ 0x8B,0xDC,0x13,0xD1,0xD2,0x5E,0xAB,0x65,0x99,0x4D,0xA6,0x49,0x66,0xB8,0x2C,0x77,
+ 0xAC,0x85,0x71,0xA4,0x69,0x59,0xA6,0xD4,0xAD,0x61,0xA1,0xCE,
+};
+
+/* subject:/serialNumber=424761419/jurisdictionC=FR/businessCategory=Private Organization/C=FR/postalCode=59100/ST=Nord/L=Roubaix/street=2 rue Kellermann/O=OVH SAS/OU=IT/OU=COMODO EV SSL/CN=ovh.com */
+/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA */
+static unsigned char ovh_certificate[1884]={
+ 0x30,0x82,0x07,0x58,0x30,0x82,0x06,0x40,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x40,
+ 0x46,0x47,0xDC,0xC2,0x4B,0x04,0x42,0xD4,0x89,0x8D,0x08,0x4D,0x4B,0xC2,0x01,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,
+ 0x92,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,
+ 0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,
+ 0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,
+ 0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,
+ 0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,
+ 0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x38,0x30,0x36,0x06,0x03,0x55,
+ 0x04,0x03,0x13,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x45,
+ 0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,
+ 0x6F,0x6E,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
+ 0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x34,0x32,0x38,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x34,0x32,0x38,0x32,0x33,0x35,0x39,
+ 0x35,0x39,0x5A,0x30,0x81,0xEA,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x05,0x13,
+ 0x09,0x34,0x32,0x34,0x37,0x36,0x31,0x34,0x31,0x39,0x31,0x13,0x30,0x11,0x06,0x0B,
+ 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x46,0x52,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,0x0B,
+ 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x52,0x31,0x0E,0x30,0x0C,0x06,
+ 0x03,0x55,0x04,0x11,0x13,0x05,0x35,0x39,0x31,0x30,0x30,0x31,0x0D,0x30,0x0B,0x06,
+ 0x03,0x55,0x04,0x08,0x13,0x04,0x4E,0x6F,0x72,0x64,0x31,0x10,0x30,0x0E,0x06,0x03,
+ 0x55,0x04,0x07,0x13,0x07,0x52,0x6F,0x75,0x62,0x61,0x69,0x78,0x31,0x19,0x30,0x17,
+ 0x06,0x03,0x55,0x04,0x09,0x13,0x10,0x32,0x20,0x72,0x75,0x65,0x20,0x4B,0x65,0x6C,
+ 0x6C,0x65,0x72,0x6D,0x61,0x6E,0x6E,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,
+ 0x13,0x07,0x4F,0x56,0x48,0x20,0x53,0x41,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+ 0x04,0x0B,0x13,0x02,0x49,0x54,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0B,0x13,
+ 0x0D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x31,0x10,
+ 0x30,0x0E,0x06,0x03,0x55,0x04,0x03,0x13,0x07,0x6F,0x76,0x68,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,0x93,0xA1,0x5D,0x05,0x5F,0x1A,0x26,0x56,0x3D,0xDC,0xC2,0x7C,0x1B,0xA1,0x7A,
+ 0x63,0x16,0x4F,0xBD,0xE0,0x77,0x85,0x04,0xB0,0x9B,0x49,0xE9,0x2B,0x5C,0xB1,0x51,
+ 0xFD,0x8A,0x14,0x51,0xC7,0xD9,0x50,0xDE,0x64,0x2F,0xFE,0x8C,0x27,0xC3,0x01,0x48,
+ 0x64,0x7C,0x85,0x3F,0x93,0xD4,0x09,0xE6,0x42,0xDF,0xC1,0xE4,0xEB,0x6A,0xC0,0x87,
+ 0x90,0xA5,0xF6,0x9C,0xD4,0x6B,0x08,0x77,0xFB,0x56,0x44,0x2B,0x8A,0xE0,0x05,0x73,
+ 0x14,0x6B,0x02,0x7D,0x76,0x44,0x7B,0x3E,0xA6,0xE5,0x23,0xA9,0xE1,0x8F,0x99,0xDD,
+ 0x15,0xCD,0xD9,0xD9,0x6D,0xB9,0x95,0x5B,0xE8,0xB6,0xE2,0x52,0xDD,0xF0,0xB0,0x80,
+ 0x1B,0xC1,0x95,0x4B,0x2C,0x9D,0x5E,0x8D,0x02,0x6B,0x59,0x6C,0x26,0x8B,0xC3,0x19,
+ 0x0D,0x3E,0xA8,0x34,0xD0,0x43,0x81,0xD7,0xBD,0xB3,0xA7,0x04,0xE1,0x05,0x82,0xA6,
+ 0x1F,0x4D,0x70,0x67,0x05,0x96,0x88,0xE8,0xE9,0x2E,0x95,0xD2,0x36,0x75,0xD6,0xC8,
+ 0x0C,0x59,0xBF,0x9F,0x1F,0x9F,0xB4,0xFF,0xF0,0x10,0x8C,0xC3,0xE6,0x8B,0x9F,0xE2,
+ 0x8E,0x00,0x60,0x58,0xCB,0x6F,0xAD,0x84,0x7B,0xA5,0x36,0xDB,0xB2,0xA4,0xEB,0xC6,
+ 0xC8,0xD8,0x61,0x6E,0x4A,0xDC,0x5C,0x3E,0x2C,0x33,0xCB,0x1E,0x16,0x8B,0x8C,0xA3,
+ 0x5F,0x0F,0x30,0x4E,0x0A,0x5D,0xA0,0x53,0x7C,0xCE,0xAB,0x29,0x9A,0xC6,0x64,0xC5,
+ 0x5A,0xD7,0x94,0x3D,0x81,0xB1,0x05,0x3F,0x2A,0x6D,0xD7,0xB8,0x9D,0xF1,0x6D,0x13,
+ 0xFD,0x82,0xB4,0xF9,0x88,0x77,0xAB,0xB8,0x2C,0x7A,0x81,0x6E,0x68,0xFF,0x6E,0x04,
+ 0xC1,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x4E,0x30,0x82,0x03,0x4A,0x30,0x1F,
+ 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x39,0xDA,0xFF,0xCA,0x28,
+ 0x14,0x8A,0xA8,0x74,0x13,0x08,0xB9,0xE4,0x0E,0xA9,0xD2,0xFA,0x7E,0x9D,0x69,0x30,
+ 0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x0B,0x0F,0xAD,0xA6,0xC3,0xBF,
+ 0x98,0xA1,0xEC,0xCD,0x20,0xB3,0x2C,0x75,0x03,0x56,0x3A,0xA6,0xD3,0xE6,0x30,0x0E,
+ 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x0C,
+ 0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,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,0x46,0x06,0x03,0x55,
+ 0x1D,0x20,0x04,0x3F,0x30,0x3D,0x30,0x3B,0x06,0x0C,0x2B,0x06,0x01,0x04,0x01,0xB2,
+ 0x31,0x01,0x02,0x01,0x05,0x01,0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,
+ 0x05,0x07,0x02,0x01,0x16,0x1D,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,
+ 0x63,0x75,0x72,0x65,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x63,0x6F,0x6D,0x2F,
+ 0x43,0x50,0x53,0x30,0x56,0x06,0x03,0x55,0x1D,0x1F,0x04,0x4F,0x30,0x4D,0x30,0x4B,
+ 0xA0,0x49,0xA0,0x47,0x86,0x45,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,
+ 0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,
+ 0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x56,
+ 0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x53,0x65,0x63,0x75,0x72,0x65,0x53,
+ 0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x81,0x87,0x06,0x08,
+ 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x7B,0x30,0x79,0x30,0x51,0x06,0x08,
+ 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x45,0x68,0x74,0x74,0x70,0x3A,0x2F,
+ 0x2F,0x63,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,
+ 0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x45,0x78,0x74,0x65,0x6E,
+ 0x64,0x65,0x64,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x53,0x65,0x63,
+ 0x75,0x72,0x65,0x53,0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,
+ 0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
+ 0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,
+ 0x61,0x2E,0x63,0x6F,0x6D,0x30,0x1F,0x06,0x03,0x55,0x1D,0x11,0x04,0x18,0x30,0x16,
+ 0x82,0x07,0x6F,0x76,0x68,0x2E,0x63,0x6F,0x6D,0x82,0x0B,0x77,0x77,0x77,0x2E,0x6F,
+ 0x76,0x68,0x2E,0x63,0x6F,0x6D,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,0x5B,0xB5,0x7B,0xC8,0x2D,0x00,0x00,0x04,0x03,0x00,
+ 0x47,0x30,0x45,0x02,0x21,0x00,0xD5,0x1B,0x6C,0xAE,0x75,0x46,0x62,0x0C,0x8B,0x2E,
+ 0x14,0xB1,0xDE,0x7C,0xA5,0xFE,0x5C,0x4F,0x3E,0xB0,0xFF,0xFF,0x33,0xA2,0x84,0x58,
+ 0x51,0x57,0x97,0x09,0xAF,0x09,0x02,0x20,0x49,0xD7,0x12,0x12,0x6C,0x2A,0x00,0x21,
+ 0x5E,0x48,0xF8,0xD0,0xF2,0xA5,0x81,0x2A,0x4E,0xE9,0x22,0x0A,0x4E,0x46,0x8F,0xDB,
+ 0xA5,0x9C,0x4B,0x43,0x7E,0x51,0x24,0xE4,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,0x5B,0xB5,
+ 0x7B,0xC5,0xC8,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x20,0x36,0xA9,0x1D,
+ 0x52,0x63,0x04,0x11,0x1F,0x65,0xC6,0x97,0x7C,0x17,0xFC,0x17,0x8D,0xDB,0x9D,0xA7,
+ 0xB7,0x84,0x66,0x03,0x55,0x95,0x7D,0x42,0x39,0x98,0x60,0xDE,0x19,0x02,0x21,0x00,
+ 0x8B,0xB7,0x16,0xC0,0x20,0x17,0xBF,0x31,0x36,0xBD,0xBC,0x1C,0x12,0x61,0x42,0xC0,
+ 0x5C,0x19,0x97,0x0A,0xFA,0x85,0xDB,0x5D,0xC3,0x65,0xBE,0x18,0xBF,0x89,0x6F,0xB9,
+ 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,0x5B,0xB5,0x7B,0xC7,0xFA,0x00,0x00,0x04,0x03,0x00,
+ 0x47,0x30,0x45,0x02,0x21,0x00,0xF8,0xFE,0x02,0xC9,0xAF,0x02,0x18,0xF4,0x12,0x00,
+ 0x39,0x3C,0x15,0xE0,0x9C,0x78,0x04,0x19,0x55,0xAE,0x8F,0xB4,0x22,0xB9,0x08,0x66,
+ 0x9E,0x21,0x3E,0xF0,0x7D,0xC6,0x02,0x20,0x47,0x45,0x31,0xC7,0x2C,0xC3,0xBE,0xC7,
+ 0x5B,0xD8,0x31,0x0A,0xD6,0xAF,0x9D,0xAF,0x04,0x45,0xAA,0x51,0x7D,0x43,0xEF,0x35,
+ 0x4D,0x81,0xB3,0x0A,0x2F,0x8D,0xD8,0x61,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+ 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6C,0x8E,0xB5,0x58,
+ 0x8A,0xC5,0x66,0xAC,0x99,0x68,0xF9,0x80,0x68,0x8E,0xC5,0x10,0xF7,0xD7,0x37,0x5E,
+ 0x09,0x8C,0x6B,0xCF,0x30,0x2B,0x98,0x3F,0x76,0x4D,0x69,0xBA,0xE8,0x61,0x1D,0xDE,
+ 0x1A,0x14,0x4F,0x5A,0x0B,0x54,0x0F,0x66,0xEF,0xB9,0xB3,0x51,0x6C,0x9B,0x86,0x1D,
+ 0xB9,0x13,0xC8,0x54,0x24,0x6C,0x82,0x6E,0x4B,0x3C,0x53,0xC7,0x7D,0x0B,0x40,0x4A,
+ 0x7E,0x23,0xF2,0x79,0x6B,0xC3,0xFF,0x9D,0xDF,0xC0,0x16,0x7B,0xFF,0x7B,0x04,0xC9,
+ 0xE0,0xEB,0x3F,0x28,0xC6,0xD2,0x79,0xEE,0xAE,0x7E,0x38,0x5F,0x0D,0xDF,0x71,0xE7,
+ 0xAA,0x38,0x7E,0xF3,0x28,0xE8,0xB2,0xAC,0x69,0xB9,0x69,0xD4,0x05,0x8E,0xF1,0x00,
+ 0x71,0x77,0x97,0x7F,0x94,0x36,0x45,0xE5,0x9C,0x15,0xA3,0xF1,0x40,0xD7,0xB5,0xEA,
+ 0x95,0x56,0x75,0x60,0x86,0xFB,0xCD,0xB7,0x81,0x5A,0x34,0x1A,0x83,0x1E,0xC2,0x50,
+ 0xA2,0x57,0x16,0x13,0x53,0x95,0xFA,0x95,0xD0,0x64,0x1E,0x09,0x45,0x50,0x05,0x63,
+ 0x3A,0x86,0xB2,0x1D,0x9B,0x19,0x0E,0x89,0x7E,0x75,0x17,0xDA,0xC5,0x4D,0x4F,0x71,
+ 0x55,0x82,0x3E,0x5F,0x41,0x25,0x2F,0x86,0x9E,0x3D,0xF1,0x32,0xFA,0x77,0x7C,0x30,
+ 0x6C,0x50,0x2F,0xE7,0x11,0x7B,0xE1,0x3F,0xA8,0x2E,0xEF,0xAC,0x36,0x94,0x8F,0xF0,
+ 0x92,0xB4,0xCA,0x1A,0x53,0x8E,0x12,0x26,0x48,0xC4,0xA8,0x25,0x19,0x96,0x19,0x11,
+ 0xA2,0xA2,0x48,0xEB,0x8C,0x12,0x59,0x7F,0xCE,0xFC,0x4B,0xC9,0x19,0x10,0x61,0x2B,
+ 0xB3,0xA6,0x6B,0xB4,0xBA,0x68,0xB9,0x22,0x58,0xE4,0x82,0x27,
+};
+
+/* This is the cert the ssl server returns to us. */
+/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA */
+/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */
+static unsigned char comodo_ev_certificate[1554]={
+ 0x30,0x82,0x06,0x0E,0x30,0x82,0x03,0xF6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x06,
+ 0xA7,0x43,0x80,0xD4,0xEB,0xFE,0xD4,0x35,0xB5,0xA3,0xF7,0xE1,0x6A,0xBD,0xD8,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x30,0x81,
+ 0x85,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,
+ 0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,
+ 0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,
+ 0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,
+ 0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,
+ 0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x2B,0x30,0x29,0x06,0x03,0x55,
+ 0x04,0x03,0x13,0x22,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x43,
+ 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,
+ 0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x32,0x31,0x32,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x37,0x30,0x32,0x31,0x31,0x32,
+ 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x92,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+ 0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,
+ 0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,
+ 0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,
+ 0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,
+ 0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,
+ 0x64,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,0x43,0x4F,0x4D,0x4F,
+ 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,
+ 0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x63,0x75,0x72,
+ 0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,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,0x95,0x56,0xDE,0x54,
+ 0xB4,0xDF,0xD5,0x02,0x49,0x7B,0xD1,0x5B,0x5C,0xA2,0xB2,0x1E,0x8F,0x9C,0x2B,0x62,
+ 0x4C,0x2B,0x8D,0x12,0x28,0xF3,0x1A,0x95,0xA3,0xC6,0x10,0xFD,0x29,0xDE,0xE1,0x9F,
+ 0x0B,0x38,0x40,0x93,0xD1,0xEF,0x6E,0x95,0x10,0xFC,0xE1,0x90,0x17,0x77,0x2C,0xEE,
+ 0x75,0x3E,0x7B,0x63,0xEC,0x61,0x92,0x6E,0x4F,0x3B,0xAB,0x80,0x49,0x6B,0xDF,0x00,
+ 0xEA,0x03,0x00,0x7F,0x2F,0x75,0xD5,0x28,0x2F,0xEC,0x56,0x67,0x8F,0x80,0x83,0xA3,
+ 0xBD,0xDC,0x03,0x99,0x93,0x8B,0x94,0x91,0x56,0x5B,0xA1,0xB8,0x6A,0x3A,0x3F,0x06,
+ 0xBD,0x0E,0x92,0xCC,0x60,0x9C,0xFD,0xB5,0xE0,0x9F,0x66,0x30,0x5F,0xDB,0xE6,0x94,
+ 0xF0,0x95,0x6A,0xAF,0xC8,0x8A,0xAF,0x80,0xD9,0xE6,0x88,0x39,0x01,0x7C,0x1C,0xC0,
+ 0xC5,0x2A,0xF7,0x7B,0x95,0xA0,0xF2,0x76,0xAB,0x6D,0x9B,0x72,0x39,0x30,0xEB,0xD1,
+ 0x57,0x55,0x01,0x9D,0x58,0x11,0x9D,0x7C,0x6D,0x84,0x8F,0x49,0xE8,0x9D,0x09,0xFC,
+ 0x3C,0xFD,0x0A,0x4A,0x76,0x14,0x21,0x5C,0x16,0x73,0x40,0x23,0x19,0x74,0xC3,0xBA,
+ 0x58,0x0A,0xA6,0x96,0x2E,0xDE,0x36,0xE5,0x9F,0xD0,0xC2,0xF0,0xE1,0xE0,0xC1,0x62,
+ 0xE3,0xC2,0x18,0x45,0x19,0x51,0xAA,0x17,0x1E,0xE8,0x23,0x75,0xD4,0xC8,0xD0,0x96,
+ 0x13,0xFF,0xC7,0x24,0xD1,0x8C,0x0B,0x27,0xAE,0x9E,0x7A,0xDC,0x3A,0x61,0x63,0x60,
+ 0x88,0x97,0x2D,0x5D,0x05,0x0B,0xE5,0x3B,0xEB,0xAE,0xCE,0x3A,0x47,0x73,0x76,0xA8,
+ 0xFA,0x2C,0xDD,0xC0,0x87,0x17,0xE9,0xAC,0x30,0x99,0xF8,0x1F,0x02,0x03,0x01,0x00,
+ 0x01,0xA3,0x82,0x01,0x69,0x30,0x82,0x01,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,
+ 0x04,0x18,0x30,0x16,0x80,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84,
+ 0x8E,0xAD,0xEE,0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,0x30,0x1D,0x06,0x03,0x55,0x1D,
+ 0x0E,0x04,0x16,0x04,0x14,0x39,0xDA,0xFF,0xCA,0x28,0x14,0x8A,0xA8,0x74,0x13,0x08,
+ 0xB9,0xE4,0x0E,0xA9,0xD2,0xFA,0x7E,0x9D,0x69,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,
+ 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,
+ 0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x3E,0x06,
+ 0x03,0x55,0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00,
+ 0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,
+ 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,
+ 0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x4C,0x06,
+ 0x03,0x55,0x1D,0x1F,0x04,0x45,0x30,0x43,0x30,0x41,0xA0,0x3F,0xA0,0x3D,0x86,0x3B,
+ 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,
+ 0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,
+ 0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75,
+ 0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x71,0x06,0x08,0x2B,
+ 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x65,0x30,0x63,0x30,0x3B,0x06,0x08,0x2B,
+ 0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x2F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+ 0x63,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,
+ 0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x41,0x64,0x64,0x54,0x72,0x75,
+ 0x73,0x74,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,
+ 0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,
+ 0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x30,0x0D,
+ 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02,
+ 0x01,0x00,0x44,0x42,0x9D,0x41,0x51,0x2B,0x48,0x88,0x5D,0x97,0x9B,0x79,0x5E,0x11,
+ 0x01,0x4A,0x52,0x19,0x7B,0x41,0x2C,0xC7,0x89,0x3C,0xD0,0x72,0xDC,0x85,0xFA,0x58,
+ 0xAF,0xD5,0x25,0xE4,0x13,0xF8,0x58,0x65,0x67,0x9F,0x0D,0xFF,0x57,0x8B,0xA9,0x85,
+ 0x5E,0xCA,0xA6,0x4B,0xB0,0xA7,0xB2,0x2D,0xE0,0x8C,0x22,0xCD,0xFB,0xFF,0x79,0xA4,
+ 0x8C,0x2B,0x8D,0xFE,0x02,0x3D,0x24,0xDE,0xA9,0x5D,0x5F,0xE4,0x0F,0x47,0xD0,0xDB,
+ 0x66,0x25,0x3E,0x87,0x47,0x0C,0xAE,0x22,0xC5,0x50,0x22,0x84,0xD7,0xED,0x4A,0x59,
+ 0x1A,0xF6,0x93,0xA5,0x93,0xB0,0xE0,0x1B,0x81,0xF2,0x56,0xC4,0xC8,0x10,0x53,0xE4,
+ 0xD4,0x76,0xB1,0xD1,0x5B,0x69,0x4B,0x77,0xB2,0xE0,0x4F,0xC4,0x84,0xE7,0xD4,0xA0,
+ 0x50,0xEE,0x3C,0xFA,0x44,0xFC,0xD0,0x57,0xB9,0xE1,0x28,0x53,0xFD,0x53,0xCD,0xDC,
+ 0xB9,0x1F,0x7A,0x40,0xBD,0x30,0x3F,0xD8,0x6C,0xD2,0xF3,0xE7,0x07,0x9F,0x1F,0x22,
+ 0xB5,0xEA,0x22,0x71,0xCB,0x2A,0xF0,0x56,0x7C,0xFE,0xAC,0xA8,0xD1,0x06,0x0F,0x14,
+ 0x14,0x52,0x4C,0xFE,0x64,0x2B,0x0C,0x69,0x2A,0xB8,0x0D,0x50,0x6E,0x3E,0x04,0x07,
+ 0xBF,0x7A,0x20,0x8B,0xF8,0xEE,0x65,0x09,0xE1,0xC7,0x49,0x08,0x32,0x3D,0x0D,0x28,
+ 0x7E,0x49,0x1D,0xB7,0x4A,0xEF,0x02,0xE7,0x0D,0x80,0x17,0xC8,0x5C,0xE0,0x61,0x62,
+ 0xCB,0xEC,0xB3,0x60,0x79,0x25,0xDA,0x1A,0x65,0x73,0x9C,0x38,0x10,0xA0,0x26,0x3A,
+ 0xB0,0xC8,0x16,0x7D,0x93,0x31,0x22,0xEE,0x74,0x0B,0x88,0xC0,0x5C,0x89,0x41,0x00,
+ 0x28,0xA9,0x47,0x31,0xDF,0x7D,0x49,0x45,0x9A,0xF5,0xE6,0xA7,0x45,0x1A,0xD2,0x8E,
+ 0x13,0x10,0xDF,0x83,0xAF,0x9B,0x0D,0xAD,0x7E,0x7E,0x9D,0x35,0x50,0x34,0x04,0xCE,
+ 0xE9,0x20,0xD6,0x9E,0xDB,0x9D,0xD4,0xA8,0xDA,0x64,0xB4,0xD1,0x2F,0x59,0x2E,0x5E,
+ 0xA2,0x36,0x61,0xD4,0x24,0xA0,0x82,0x33,0x33,0x8A,0xA1,0xD1,0x6C,0xEF,0x61,0x68,
+ 0xA3,0xE5,0xD2,0x56,0xAD,0xC5,0xFD,0x5E,0x62,0xEB,0x15,0xA8,0x74,0x12,0x4C,0x2F,
+ 0x31,0x8C,0xE9,0xC1,0xDF,0x10,0x4B,0x01,0xEA,0xF6,0x54,0x1B,0xCD,0x7F,0x3B,0xBD,
+ 0x5C,0x9F,0xC1,0xDB,0xCF,0x01,0xCA,0xF2,0xBA,0x60,0x12,0x21,0x31,0xED,0xA9,0x64,
+ 0xB8,0xB2,0x49,0x58,0x17,0x6D,0x5A,0xD7,0xCD,0x8C,0x6D,0xBE,0x9E,0x7F,0xE2,0x02,
+ 0x58,0xA7,0xDB,0xC3,0x2D,0x58,0xF6,0x74,0x06,0x6A,0x9A,0xF6,0x61,0xF9,0xF6,0x00,
+ 0xB6,0x69,0xD8,0x3A,0x8B,0x31,0x59,0xDD,0x91,0xE6,0x7C,0x27,0x23,0x87,0xDD,0x03,
+ 0x0F,0x8F,0x2A,0x8C,0x1E,0x83,0x01,0x4E,0x01,0x61,0x0C,0x52,0x73,0x6D,0xFC,0x08,
+ 0xA2,0xB9,0x2A,0x66,0xE4,0x76,0x4D,0x31,0xA0,0x56,0x9B,0xD9,0x53,0x8D,0xA2,0xB6,
+ 0x8F,0x02,0xC8,0xE6,0x3A,0xA6,0x04,0xD1,0x48,0xFB,0xC3,0x4A,0x02,0x76,0xFD,0x2F,
+ 0xD2,0xBC,0x13,0xB6,0xE8,0x6D,0x34,0x24,0xFA,0x9D,0x29,0x8A,0xC7,0xA1,0x2B,0x14,
+ 0xF1,0x96,0x00,0x73,0xB9,0x13,0xE9,0xC0,0xB9,0x3A,0x47,0x56,0x02,0x71,0x80,0x27,
+ 0xA4,0xBC,0x25,0xB6,0xE9,0xBD,0xE4,0xE9,0x98,0x74,0x16,0xF1,0x37,0x84,0x81,0x07,
+ 0xB4,0x82,
+};
+
+/* This is the cert we get when we get the url in the AIA extension of the ovh leaf. */
+/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA */
+/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */
+static unsigned char comodo_aia_certificate[1554]={
+ 0x30,0x82,0x06,0x0E,0x30,0x82,0x03,0xF6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x06,
+ 0xA7,0x43,0x80,0xD4,0xEB,0xFE,0xD4,0x35,0xB5,0xA3,0xF7,0xE1,0x6A,0xBD,0xD8,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x30,0x81,
+ 0x85,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,
+ 0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,
+ 0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,
+ 0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,
+ 0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,
+ 0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x2B,0x30,0x29,0x06,0x03,0x55,
+ 0x04,0x03,0x13,0x22,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x43,
+ 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,
+ 0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x32,0x31,0x32,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x37,0x30,0x32,0x31,0x31,0x32,
+ 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x92,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+ 0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x08,0x13,
+ 0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,0x4D,0x61,0x6E,0x63,0x68,0x65,0x73,
+ 0x74,0x65,0x72,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53,0x61,
+ 0x6C,0x66,0x6F,0x72,0x64,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13,0x11,
+ 0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x43,0x41,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,
+ 0x64,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2F,0x43,0x4F,0x4D,0x4F,
+ 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,
+ 0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x63,0x75,0x72,
+ 0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,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,0x95,0x56,0xDE,0x54,
+ 0xB4,0xDF,0xD5,0x02,0x49,0x7B,0xD1,0x5B,0x5C,0xA2,0xB2,0x1E,0x8F,0x9C,0x2B,0x62,
+ 0x4C,0x2B,0x8D,0x12,0x28,0xF3,0x1A,0x95,0xA3,0xC6,0x10,0xFD,0x29,0xDE,0xE1,0x9F,
+ 0x0B,0x38,0x40,0x93,0xD1,0xEF,0x6E,0x95,0x10,0xFC,0xE1,0x90,0x17,0x77,0x2C,0xEE,
+ 0x75,0x3E,0x7B,0x63,0xEC,0x61,0x92,0x6E,0x4F,0x3B,0xAB,0x80,0x49,0x6B,0xDF,0x00,
+ 0xEA,0x03,0x00,0x7F,0x2F,0x75,0xD5,0x28,0x2F,0xEC,0x56,0x67,0x8F,0x80,0x83,0xA3,
+ 0xBD,0xDC,0x03,0x99,0x93,0x8B,0x94,0x91,0x56,0x5B,0xA1,0xB8,0x6A,0x3A,0x3F,0x06,
+ 0xBD,0x0E,0x92,0xCC,0x60,0x9C,0xFD,0xB5,0xE0,0x9F,0x66,0x30,0x5F,0xDB,0xE6,0x94,
+ 0xF0,0x95,0x6A,0xAF,0xC8,0x8A,0xAF,0x80,0xD9,0xE6,0x88,0x39,0x01,0x7C,0x1C,0xC0,
+ 0xC5,0x2A,0xF7,0x7B,0x95,0xA0,0xF2,0x76,0xAB,0x6D,0x9B,0x72,0x39,0x30,0xEB,0xD1,
+ 0x57,0x55,0x01,0x9D,0x58,0x11,0x9D,0x7C,0x6D,0x84,0x8F,0x49,0xE8,0x9D,0x09,0xFC,
+ 0x3C,0xFD,0x0A,0x4A,0x76,0x14,0x21,0x5C,0x16,0x73,0x40,0x23,0x19,0x74,0xC3,0xBA,
+ 0x58,0x0A,0xA6,0x96,0x2E,0xDE,0x36,0xE5,0x9F,0xD0,0xC2,0xF0,0xE1,0xE0,0xC1,0x62,
+ 0xE3,0xC2,0x18,0x45,0x19,0x51,0xAA,0x17,0x1E,0xE8,0x23,0x75,0xD4,0xC8,0xD0,0x96,
+ 0x13,0xFF,0xC7,0x24,0xD1,0x8C,0x0B,0x27,0xAE,0x9E,0x7A,0xDC,0x3A,0x61,0x63,0x60,
+ 0x88,0x97,0x2D,0x5D,0x05,0x0B,0xE5,0x3B,0xEB,0xAE,0xCE,0x3A,0x47,0x73,0x76,0xA8,
+ 0xFA,0x2C,0xDD,0xC0,0x87,0x17,0xE9,0xAC,0x30,0x99,0xF8,0x1F,0x02,0x03,0x01,0x00,
+ 0x01,0xA3,0x82,0x01,0x69,0x30,0x82,0x01,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,
+ 0x04,0x18,0x30,0x16,0x80,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84,
+ 0x8E,0xAD,0xEE,0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,0x30,0x1D,0x06,0x03,0x55,0x1D,
+ 0x0E,0x04,0x16,0x04,0x14,0x39,0xDA,0xFF,0xCA,0x28,0x14,0x8A,0xA8,0x74,0x13,0x08,
+ 0xB9,0xE4,0x0E,0xA9,0xD2,0xFA,0x7E,0x9D,0x69,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,
+ 0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,
+ 0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x3E,0x06,
+ 0x03,0x55,0x1D,0x20,0x04,0x37,0x30,0x35,0x30,0x33,0x06,0x04,0x55,0x1D,0x20,0x00,
+ 0x30,0x2B,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1D,
+ 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x73,0x65,0x63,0x75,0x72,0x65,0x2E,0x63,
+ 0x6F,0x6D,0x6F,0x64,0x6F,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x4C,0x06,
+ 0x03,0x55,0x1D,0x1F,0x04,0x45,0x30,0x43,0x30,0x41,0xA0,0x3F,0xA0,0x3D,0x86,0x3B,
+ 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x63,0x6F,0x6D,0x6F,0x64,
+ 0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,
+ 0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75,
+ 0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x2E,0x63,0x72,0x6C,0x30,0x71,0x06,0x08,0x2B,
+ 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x65,0x30,0x63,0x30,0x3B,0x06,0x08,0x2B,
+ 0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x2F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
+ 0x63,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,
+ 0x2F,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x52,0x53,0x41,0x41,0x64,0x64,0x54,0x72,0x75,
+ 0x73,0x74,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,
+ 0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,
+ 0x70,0x2E,0x63,0x6F,0x6D,0x6F,0x64,0x6F,0x63,0x61,0x2E,0x63,0x6F,0x6D,0x30,0x0D,
+ 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02,
+ 0x01,0x00,0x44,0x42,0x9D,0x41,0x51,0x2B,0x48,0x88,0x5D,0x97,0x9B,0x79,0x5E,0x11,
+ 0x01,0x4A,0x52,0x19,0x7B,0x41,0x2C,0xC7,0x89,0x3C,0xD0,0x72,0xDC,0x85,0xFA,0x58,
+ 0xAF,0xD5,0x25,0xE4,0x13,0xF8,0x58,0x65,0x67,0x9F,0x0D,0xFF,0x57,0x8B,0xA9,0x85,
+ 0x5E,0xCA,0xA6,0x4B,0xB0,0xA7,0xB2,0x2D,0xE0,0x8C,0x22,0xCD,0xFB,0xFF,0x79,0xA4,
+ 0x8C,0x2B,0x8D,0xFE,0x02,0x3D,0x24,0xDE,0xA9,0x5D,0x5F,0xE4,0x0F,0x47,0xD0,0xDB,
+ 0x66,0x25,0x3E,0x87,0x47,0x0C,0xAE,0x22,0xC5,0x50,0x22,0x84,0xD7,0xED,0x4A,0x59,
+ 0x1A,0xF6,0x93,0xA5,0x93,0xB0,0xE0,0x1B,0x81,0xF2,0x56,0xC4,0xC8,0x10,0x53,0xE4,
+ 0xD4,0x76,0xB1,0xD1,0x5B,0x69,0x4B,0x77,0xB2,0xE0,0x4F,0xC4,0x84,0xE7,0xD4,0xA0,
+ 0x50,0xEE,0x3C,0xFA,0x44,0xFC,0xD0,0x57,0xB9,0xE1,0x28,0x53,0xFD,0x53,0xCD,0xDC,
+ 0xB9,0x1F,0x7A,0x40,0xBD,0x30,0x3F,0xD8,0x6C,0xD2,0xF3,0xE7,0x07,0x9F,0x1F,0x22,
+ 0xB5,0xEA,0x22,0x71,0xCB,0x2A,0xF0,0x56,0x7C,0xFE,0xAC,0xA8,0xD1,0x06,0x0F,0x14,
+ 0x14,0x52,0x4C,0xFE,0x64,0x2B,0x0C,0x69,0x2A,0xB8,0x0D,0x50,0x6E,0x3E,0x04,0x07,
+ 0xBF,0x7A,0x20,0x8B,0xF8,0xEE,0x65,0x09,0xE1,0xC7,0x49,0x08,0x32,0x3D,0x0D,0x28,
+ 0x7E,0x49,0x1D,0xB7,0x4A,0xEF,0x02,0xE7,0x0D,0x80,0x17,0xC8,0x5C,0xE0,0x61,0x62,
+ 0xCB,0xEC,0xB3,0x60,0x79,0x25,0xDA,0x1A,0x65,0x73,0x9C,0x38,0x10,0xA0,0x26,0x3A,
+ 0xB0,0xC8,0x16,0x7D,0x93,0x31,0x22,0xEE,0x74,0x0B,0x88,0xC0,0x5C,0x89,0x41,0x00,
+ 0x28,0xA9,0x47,0x31,0xDF,0x7D,0x49,0x45,0x9A,0xF5,0xE6,0xA7,0x45,0x1A,0xD2,0x8E,
+ 0x13,0x10,0xDF,0x83,0xAF,0x9B,0x0D,0xAD,0x7E,0x7E,0x9D,0x35,0x50,0x34,0x04,0xCE,
+ 0xE9,0x20,0xD6,0x9E,0xDB,0x9D,0xD4,0xA8,0xDA,0x64,0xB4,0xD1,0x2F,0x59,0x2E,0x5E,
+ 0xA2,0x36,0x61,0xD4,0x24,0xA0,0x82,0x33,0x33,0x8A,0xA1,0xD1,0x6C,0xEF,0x61,0x68,
+ 0xA3,0xE5,0xD2,0x56,0xAD,0xC5,0xFD,0x5E,0x62,0xEB,0x15,0xA8,0x74,0x12,0x4C,0x2F,
+ 0x31,0x8C,0xE9,0xC1,0xDF,0x10,0x4B,0x01,0xEA,0xF6,0x54,0x1B,0xCD,0x7F,0x3B,0xBD,
+ 0x5C,0x9F,0xC1,0xDB,0xCF,0x01,0xCA,0xF2,0xBA,0x60,0x12,0x21,0x31,0xED,0xA9,0x64,
+ 0xB8,0xB2,0x49,0x58,0x17,0x6D,0x5A,0xD7,0xCD,0x8C,0x6D,0xBE,0x9E,0x7F,0xE2,0x02,
+ 0x58,0xA7,0xDB,0xC3,0x2D,0x58,0xF6,0x74,0x06,0x6A,0x9A,0xF6,0x61,0xF9,0xF6,0x00,
+ 0xB6,0x69,0xD8,0x3A,0x8B,0x31,0x59,0xDD,0x91,0xE6,0x7C,0x27,0x23,0x87,0xDD,0x03,
+ 0x0F,0x8F,0x2A,0x8C,0x1E,0x83,0x01,0x4E,0x01,0x61,0x0C,0x52,0x73,0x6D,0xFC,0x08,
+ 0xA2,0xB9,0x2A,0x66,0xE4,0x76,0x4D,0x31,0xA0,0x56,0x9B,0xD9,0x53,0x8D,0xA2,0xB6,
+ 0x8F,0x02,0xC8,0xE6,0x3A,0xA6,0x04,0xD1,0x48,0xFB,0xC3,0x4A,0x02,0x76,0xFD,0x2F,
+ 0xD2,0xBC,0x13,0xB6,0xE8,0x6D,0x34,0x24,0xFA,0x9D,0x29,0x8A,0xC7,0xA1,0x2B,0x14,
+ 0xF1,0x96,0x00,0x73,0xB9,0x13,0xE9,0xC0,0xB9,0x3A,0x47,0x56,0x02,0x71,0x80,0x27,
+ 0xA4,0xBC,0x25,0xB6,0xE9,0xBD,0xE4,0xE9,0x98,0x74,0x16,0xF1,0x37,0x84,0x81,0x07,
+ 0xB4,0x82,
+};
+
+static unsigned char revoked_ist_certificate[1515]={
+ 0x30,0x82,0x05,0xE7,0x30,0x82,0x04,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x7F,
+ 0x00,0xCE,0x8A,0xD6,0x3F,0x5B,0x34,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+ 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,
+ 0x03,0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20,
+ 0x32,0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,
+ 0x17,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,0x13,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,0x34,
+ 0x31,0x31,0x32,0x38,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x17,0x0D,0x31,0x36,0x31,
+ 0x32,0x32,0x37,0x31,0x35,0x30,0x36,0x31,0x34,0x5A,0x30,0x81,0xAB,0x31,0x4B,0x30,
+ 0x49,0x06,0x03,0x55,0x04,0x03,0x0C,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,
+ 0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D,
+ 0x63,0x61,0x2E,0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65,
+ 0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72,
+ 0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x25,0x30,0x23,0x06,0x03,
+ 0x55,0x04,0x0B,0x0C,0x1C,0x6D,0x61,0x6E,0x61,0x67,0x65,0x6D,0x65,0x6E,0x74,0x3A,
+ 0x69,0x64,0x6D,0x73,0x2E,0x67,0x72,0x6F,0x75,0x70,0x2E,0x31,0x37,0x36,0x33,0x39,
+ 0x39,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,
+ 0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,
+ 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x0B,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,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,0xA9,0xD7,0xE0,0x65,0x48,0x36,0x8A,
+ 0x4B,0x6C,0xBB,0x16,0xAF,0xFD,0x09,0xA5,0x9C,0x30,0xDA,0xC5,0x9B,0x3D,0xD6,0xB4,
+ 0x8E,0x6B,0xC2,0xF4,0xBF,0x30,0xA7,0xCC,0xF7,0xA1,0x23,0x58,0xA0,0x16,0xE8,0x31,
+ 0x5F,0xE7,0xD2,0x21,0x3D,0x24,0x3D,0xF4,0x1E,0x82,0x46,0x45,0xA0,0xB8,0x2E,0xD7,
+ 0xB6,0x86,0xD3,0x2A,0xBC,0x93,0x74,0x44,0xAB,0x1C,0x9F,0x86,0xBF,0x19,0xCE,0xA4,
+ 0xD0,0xC9,0xB9,0x65,0x84,0x89,0x87,0xDE,0x77,0xDC,0xAE,0x85,0xA9,0xDE,0x5A,0xCF,
+ 0xAF,0x46,0x80,0x45,0x72,0x68,0x87,0x55,0x5B,0x4D,0x49,0xE2,0x7B,0x25,0x31,0x22,
+ 0x00,0x87,0xAB,0x72,0xEB,0x9A,0x2D,0x81,0x35,0x0E,0x76,0x82,0x5C,0x99,0x10,0xFB,
+ 0xD6,0x3F,0x29,0xE8,0xFD,0x2E,0xAD,0xF6,0xF8,0xCF,0xC1,0x99,0x5F,0xDA,0xC1,0xB3,
+ 0x90,0x70,0xA5,0x4B,0x23,0x4D,0xD6,0x1D,0xC9,0x73,0x27,0xD1,0xAE,0x38,0xA3,0xD0,
+ 0x71,0x92,0xFF,0x89,0xA8,0xE5,0x51,0x3E,0x2F,0xB6,0xB4,0x02,0x20,0x54,0x62,0xA0,
+ 0x69,0x6D,0xB6,0x10,0x8D,0xB7,0x13,0x2A,0x94,0x4E,0xED,0x73,0x8C,0x78,0x39,0xF6,
+ 0x04,0xC0,0xF8,0x7A,0x75,0x2D,0x1E,0x82,0x7E,0x55,0x7B,0xE7,0xA7,0xFA,0x6E,0xB1,
+ 0x53,0x81,0x75,0xB6,0x19,0xD8,0xD2,0xD3,0x8E,0x30,0x95,0x0D,0xD8,0xC9,0xBA,0x3F,
+ 0x70,0x23,0xC3,0x7B,0xE2,0x6E,0xA9,0xA8,0x91,0x69,0x89,0x8D,0xEA,0x64,0x5D,0x8E,
+ 0x49,0x43,0x30,0x99,0xBC,0x54,0x97,0xAC,0xEB,0x98,0x09,0x8C,0xE9,0xA7,0xE8,0xDC,
+ 0xFC,0xE4,0xBE,0x20,0xDA,0xA1,0x88,0xB6,0x99,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,
+ 0x02,0x55,0x30,0x82,0x02,0x51,0x30,0x48,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
+ 0x01,0x01,0x04,0x3C,0x30,0x3A,0x30,0x38,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
+ 0x30,0x01,0x86,0x2C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,
+ 0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,0x73,0x70,0x30,0x34,
+ 0x2D,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74,0x63,0x61,0x32,0x67,0x31,0x30,0x31,
+ 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x75,0x81,0x7F,0xDF,0xDE,
+ 0x90,0xE2,0xFB,0x67,0xA8,0x04,0xC9,0x82,0xE1,0x2A,0x13,0x08,0x3D,0xCE,0x8E,0x30,
+ 0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,0x1F,0x06,
+ 0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xD8,0x7A,0x94,0x44,0x7C,0x90,
+ 0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C,0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,0x30,0x81,
+ 0xFF,0x06,0x03,0x55,0x1D,0x20,0x04,0x81,0xF7,0x30,0x81,0xF4,0x30,0x81,0xF1,0x06,
+ 0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x0B,0x04,0x30,0x81,0xE2,0x30,0x81,
+ 0xA4,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x81,0x97,0x0C,0x81,
+ 0x94,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,
+ 0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x62,0x79,
+ 0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,0x74,0x79,0x20,0x61,0x73,0x73,0x75,0x6D,
+ 0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74,0x61,0x6E,0x63,0x65,0x20,0x6F,0x66,
+ 0x20,0x61,0x6E,0x79,0x20,0x61,0x70,0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20,
+ 0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x64,0x69,0x74,
+ 0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x6E,0x64,0x2F,
+ 0x6F,0x72,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
+ 0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x73,0x74,0x61,0x74,0x65,0x6D,
+ 0x65,0x6E,0x74,0x73,0x2E,0x30,0x39,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,
+ 0x01,0x16,0x2D,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,0x2F,0x72,0x70,0x61,
+ 0x30,0x37,0x06,0x03,0x55,0x1D,0x1F,0x04,0x30,0x30,0x2E,0x30,0x2C,0xA0,0x2A,0xA0,
+ 0x28,0x86,0x26,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x61,0x70,
+ 0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70,0x6C,0x65,0x69,0x73,0x74,
+ 0x63,0x61,0x32,0x67,0x31,0x2E,0x63,0x72,0x6C,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,0x4D,0x06,0x03,0x55,0x1D,0x11,0x04,
+ 0x46,0x30,0x44,0x82,0x42,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x67,0x65,0x6F,
+ 0x74,0x72,0x75,0x73,0x74,0x2D,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2D,0x63,0x61,0x2E,
+ 0x74,0x65,0x73,0x74,0x2D,0x70,0x61,0x67,0x65,0x73,0x2E,0x63,0x65,0x72,0x74,0x69,
+ 0x66,0x69,0x63,0x61,0x74,0x65,0x6D,0x61,0x6E,0x61,0x67,0x65,0x72,0x2E,0x61,0x70,
+ 0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+ 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC0,0x5B,0xA6,0xAF,0x2C,
+ 0x27,0xBA,0x49,0x8D,0x41,0xF6,0xC4,0x02,0xEE,0x9D,0xB1,0x48,0xC3,0x34,0x7B,0xF2,
+ 0xD2,0x82,0x49,0xA5,0x13,0x5A,0x66,0xAD,0xC9,0x73,0xBF,0x6B,0xC9,0x30,0x86,0xBA,
+ 0x7A,0xD2,0x9D,0x61,0xFE,0x04,0x07,0x15,0x66,0xC2,0x25,0xF7,0x6C,0x88,0xB1,0x0E,
+ 0x22,0x11,0xF9,0x26,0xA7,0x4E,0x88,0x96,0x20,0x99,0xA6,0x51,0xEE,0x02,0x96,0xC7,
+ 0xA4,0xCA,0xD4,0xAB,0xFC,0x5F,0x96,0x16,0x0D,0x8D,0xA0,0xA1,0x17,0x6E,0x77,0x92,
+ 0xC9,0x64,0xD9,0xA2,0x5A,0x00,0x08,0xA6,0x55,0x73,0x2C,0xDD,0xD3,0x0C,0xA5,0xCA,
+ 0x68,0x48,0xAE,0xCE,0x5F,0xF2,0x56,0x4A,0x66,0x57,0xB2,0x2D,0xB5,0xC6,0xFF,0x50,
+ 0xD8,0x36,0x9C,0x31,0x31,0xE8,0xB2,0x07,0xE2,0x7B,0xC0,0xCE,0x72,0xA4,0x60,0x91,
+ 0xBB,0x84,0xA7,0xA8,0xC0,0x1D,0x42,0xE8,0x1D,0xF5,0xD9,0x6B,0x85,0x67,0x23,0x20,
+ 0xA6,0xF8,0x0F,0xBA,0x83,0x63,0x49,0xE2,0x79,0x23,0x90,0xFF,0x6B,0xEF,0xFA,0xB4,
+ 0x04,0xA8,0x99,0x1E,0x5D,0x5A,0xCD,0x8C,0xBC,0x8E,0x30,0x41,0x7E,0xE7,0x4E,0xDB,
+ 0x6F,0x4E,0xB7,0xBA,0xE0,0x5B,0x31,0xC4,0xD2,0x2D,0xD3,0x5D,0x82,0x95,0x44,0x7D,
+ 0x11,0x60,0x75,0xCE,0x6D,0x12,0xDA,0x89,0x71,0x23,0x80,0x75,0xC0,0x13,0x67,0x27,
+ 0xE8,0xE8,0xCA,0xE0,0xE3,0xFC,0x72,0x23,0x98,0xFA,0xF0,0x96,0x05,0x23,0xC9,0x03,
+ 0xC8,0x29,0xA4,0xB1,0xE5,0x07,0xE6,0xE8,0x09,0x26,0xD1,0x8C,0xAF,0xE0,0x53,0xBB,
+ 0xB4,0x1E,0x4D,0x5E,0xEA,0x9A,0x1E,0xE9,0x42,0x87,0x9F,
+};
+
+static unsigned char ist_intermediate_certificate[1092]={
+ 0x30,0x82,0x04,0x40,0x30,0x82,0x03,0x28,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x02,
+ 0x3A,0x74,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,
+ 0x00,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+ 0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,
+ 0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,
+ 0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62,
+ 0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x34,0x30,0x36,0x31,0x36,0x31,
+ 0x35,0x34,0x32,0x30,0x32,0x5A,0x17,0x0D,0x32,0x32,0x30,0x35,0x32,0x30,0x31,0x35,
+ 0x34,0x32,0x30,0x32,0x5A,0x30,0x62,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,
+ 0x13,0x13,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x53,0x54,0x20,0x43,0x41,0x20,0x32,
+ 0x20,0x2D,0x20,0x47,0x31,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17,
+ 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,
+ 0x13,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,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,0x93,0xA1,0x1D,0x47,0x43,
+ 0x20,0x16,0xB2,0x0B,0x6B,0xEB,0xC3,0xD5,0xB4,0xE8,0xC7,0x98,0xCD,0xF3,0xDE,0xBF,
+ 0xE8,0x4D,0xE9,0xE3,0x36,0x80,0x07,0xFC,0x45,0x1B,0x6A,0x7C,0x45,0x86,0xAE,0x56,
+ 0xD3,0xA4,0x09,0x7F,0x61,0x0D,0x6B,0x5D,0x7E,0x52,0x6B,0x7D,0xB4,0xC8,0x39,0xC4,
+ 0xF4,0x67,0x3A,0xF7,0x83,0xCE,0x19,0x6F,0x86,0x2F,0x7E,0x45,0x7E,0x47,0x1C,0x67,
+ 0x52,0xCA,0x95,0x05,0x5D,0xE2,0x36,0x51,0x85,0xC0,0xD4,0x67,0x80,0x35,0x6F,0x15,
+ 0xDD,0x3E,0xFD,0x1D,0xD2,0xFD,0x8F,0x34,0x50,0xD8,0xEC,0x76,0x2A,0xBE,0xE3,0xD3,
+ 0xDA,0xE4,0xFD,0xC8,0xEB,0x28,0x02,0x96,0x11,0x97,0x17,0x61,0x1C,0xE9,0xC4,0x59,
+ 0x3B,0x42,0xDC,0x32,0xD1,0x09,0x1D,0xDA,0xA6,0xD1,0x43,0x86,0xFF,0x5E,0xB2,0xBC,
+ 0x8C,0xCF,0x66,0xDB,0x01,0x8B,0x02,0xAE,0x94,0x48,0xF3,0x38,0x8F,0xFD,0xEA,0x32,
+ 0xA8,0x08,0xEC,0x86,0x97,0x51,0x94,0x24,0x3E,0x49,0x49,0x96,0x53,0xE8,0x79,0xA1,
+ 0x40,0x81,0xE9,0x05,0xBB,0x93,0x95,0x51,0xFC,0xE3,0xFD,0x7C,0x11,0x4B,0xF7,0x9E,
+ 0x08,0xB3,0x15,0x49,0x15,0x07,0xF9,0xD1,0x37,0xA0,0x9B,0x4B,0x32,0xF6,0xB5,0xC4,
+ 0xDC,0x6A,0xD1,0xFC,0x0A,0xED,0xF6,0xE0,0xC5,0x29,0xA0,0xA8,0x8B,0x71,0xFE,0x0D,
+ 0x92,0xBC,0xFE,0x54,0x70,0x18,0x0A,0x6D,0xC7,0xED,0x0C,0xFB,0xC9,0x2D,0x06,0xC3,
+ 0x8C,0x85,0xFC,0xCB,0x86,0x5C,0xD6,0x36,0x8E,0x12,0x8B,0x09,0x7F,0xFB,0x19,0x1A,
+ 0x38,0xD5,0xF0,0x94,0x30,0x7A,0x0F,0xA6,0x8C,0xF3,0x02,0x03,0x01,0x00,0x01,0xA3,
+ 0x82,0x01,0x1D,0x30,0x82,0x01,0x19,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,
+ 0x30,0x16,0x80,0x14,0xC0,0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11,
+ 0x7D,0xAA,0x7D,0x65,0xB8,0xCA,0xCC,0x4E,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
+ 0x16,0x04,0x14,0xD8,0x7A,0x94,0x44,0x7C,0x90,0x70,0x90,0x16,0x9E,0xDD,0x17,0x9C,
+ 0x01,0x44,0x03,0x86,0xD6,0x2A,0x29,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,0x35,0x06,0x03,0x55,
+ 0x1D,0x1F,0x04,0x2E,0x30,0x2C,0x30,0x2A,0xA0,0x28,0xA0,0x26,0x86,0x24,0x68,0x74,
+ 0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,
+ 0x2F,0x63,0x72,0x6C,0x73,0x2F,0x67,0x74,0x67,0x6C,0x6F,0x62,0x61,0x6C,0x2E,0x63,
+ 0x72,0x6C,0x30,0x2E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x22,
+ 0x30,0x20,0x30,0x1E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x12,
+ 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x67,0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E,0x63,
+ 0x6F,0x6D,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43,0x30,0x41,0x06,
+ 0x0A,0x60,0x86,0x48,0x01,0x86,0xF8,0x45,0x01,0x07,0x36,0x30,0x33,0x30,0x31,0x06,
+ 0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25,0x68,0x74,0x74,0x70,0x3A,
+ 0x2F,0x2F,0x77,0x77,0x77,0x2E,0x67,0x65,0x6F,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,
+ 0x6F,0x6D,0x2F,0x72,0x65,0x73,0x6F,0x75,0x72,0x63,0x65,0x73,0x2F,0x63,0x70,0x73,
+ 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,
+ 0x82,0x01,0x01,0x00,0x16,0x47,0x73,0x6F,0x85,0xA2,0x62,0xE1,0xE7,0x2A,0x76,0xBB,
+ 0x89,0x95,0x42,0x26,0x97,0xBC,0x4A,0xAC,0xAC,0x70,0x53,0x3A,0x3F,0x31,0x83,0x3D,
+ 0x3C,0x1C,0xAB,0x9A,0xE2,0xB1,0x5D,0x1C,0x76,0x1A,0xA0,0x3C,0x0C,0x72,0x57,0xBE,
+ 0xD3,0x9E,0x50,0xE0,0xC8,0x99,0xD6,0x58,0xD7,0x02,0xEA,0xCE,0x0D,0x29,0x54,0x7C,
+ 0xCD,0xF5,0xC2,0xC6,0x90,0x29,0x55,0xA3,0x6F,0x14,0xA8,0x0B,0x42,0x0D,0x3A,0x98,
+ 0x6D,0x06,0x78,0x9E,0xF0,0x6A,0xA3,0x1D,0x02,0x0A,0xA2,0x28,0xA4,0x8D,0xC2,0x81,
+ 0x46,0x3E,0x6D,0x67,0xDA,0xDE,0x3F,0xFE,0x85,0x0E,0x42,0x2A,0x12,0xDE,0xB5,0xB7,
+ 0xFB,0xB8,0x1B,0xA7,0x96,0xEC,0x77,0x9F,0xEC,0xD4,0x53,0x95,0x7A,0xFF,0x07,0xF4,
+ 0xF2,0x0A,0x14,0xC0,0x51,0x52,0xB1,0xD6,0x8E,0x50,0x0B,0x1A,0x99,0x5C,0xBC,0x0B,
+ 0xC9,0xBD,0xED,0xED,0xF8,0x5E,0xC1,0x56,0xDB,0x4D,0x7E,0x23,0xA4,0x11,0xA1,0x2C,
+ 0xD4,0x1B,0x05,0x9A,0xE4,0x1B,0x52,0xF6,0x7C,0x38,0x99,0x05,0x4B,0xBA,0x72,0x8D,
+ 0x42,0x89,0x60,0x04,0x66,0x2A,0xF4,0xFD,0x68,0xD7,0x6B,0xF7,0x99,0x41,0x28,0xD6,
+ 0x6C,0x24,0xAB,0xE6,0x25,0x53,0x2E,0xC8,0x82,0x99,0xE2,0xA2,0x8F,0x23,0xBE,0x30,
+ 0x83,0xB1,0x27,0x8B,0xFA,0x68,0x7F,0x01,0x49,0xE8,0xC6,0x98,0x6B,0x10,0x2E,0x98,
+ 0x5E,0x8A,0xD7,0xCA,0x4B,0xB1,0xC7,0xC9,0x58,0x9A,0xD0,0x36,0xDB,0x96,0x95,0xEC,
+ 0xB6,0x81,0xE4,0xF2,0xCD,0x6F,0x1B,0x79,0x87,0x4C,0x10,0x3C,0x89,0xE4,0x4D,0xFA,
+ 0x54,0xDC,0xAA,0xA6,
+};
+
+unsigned char ocsp_smime_leaf_certificate[1338]={
+ 0x30,0x82,0x05,0x36,0x30,0x82,0x04,0x1E,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x14,
+ 0x00,0x01,0x00,0x02,0x9C,0xE1,0xB9,0xE0,0x7C,0xD1,0x7B,0xEC,0x30,0x0D,0x06,0x09,
+ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x7C,0x31,0x0B,0x30,
+ 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,
+ 0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,
+ 0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,
+ 0x0B,0x13,0x1C,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,
+ 0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31,
+ 0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75,
+ 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,
+ 0x20,0x4C,0x31,0x20,0x43,0x41,0x20,0x49,0x58,0x30,0x1E,0x17,0x0D,0x31,0x30,0x31,
+ 0x31,0x31,0x32,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x17,0x0D,0x31,0x31,0x31,0x31,
+ 0x31,0x33,0x30,0x36,0x33,0x36,0x34,0x35,0x5A,0x30,0x24,0x31,0x0B,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,
+ 0x03,0x13,0x0C,0x51,0x75,0x69,0x6E,0x6E,0x20,0x54,0x61,0x79,0x6C,0x6F,0x72,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,
+ 0xC1,0x11,0xAA,0x04,0xCF,0x04,0xA0,0x07,0xF3,0x43,0x2A,0xB2,0x27,0x1A,0x13,0x35,
+ 0x97,0x9A,0xBA,0x34,0xE5,0x84,0xF3,0xD5,0xE5,0xD9,0xAB,0x23,0x8D,0xB4,0x7E,0x68,
+ 0x5C,0xF2,0x9A,0xF1,0x08,0x9B,0x04,0x34,0xC1,0x09,0x14,0x68,0xD8,0x9C,0xC1,0x6C,
+ 0x27,0xF5,0x92,0x54,0xAF,0x66,0x65,0xF1,0x50,0xAA,0x7E,0xE3,0xFC,0xC1,0xB0,0x3E,
+ 0xEF,0xAA,0x86,0x58,0x4F,0xE7,0x86,0x0A,0x74,0xA6,0x97,0xBD,0x7D,0xF6,0xCE,0xA6,
+ 0x8B,0xF7,0xC0,0x90,0x6E,0x50,0x69,0x36,0x65,0x82,0x0F,0x65,0xA7,0x2C,0x16,0xFA,
+ 0x6C,0xCA,0x54,0x45,0x7C,0x06,0x20,0x72,0xF0,0x00,0x7B,0xD7,0x17,0xCD,0x94,0x64,
+ 0x6A,0xB7,0x28,0xF3,0x62,0xB1,0x29,0xAE,0x0C,0x8A,0x2F,0x3C,0x06,0x89,0xE8,0x81,
+ 0x77,0xAD,0x1F,0x65,0xED,0x6F,0x51,0x64,0x65,0x68,0x76,0xD8,0xEE,0xEC,0xA6,0x28,
+ 0xA9,0x1C,0x4F,0x98,0x4A,0x6D,0xD0,0xC8,0x5C,0x59,0x17,0x9B,0xF8,0x6D,0xF5,0x93,
+ 0xD3,0x4C,0x2A,0x37,0x80,0x65,0xB4,0x34,0xBA,0x64,0x2F,0xA1,0x8E,0x1C,0x6A,0x88,
+ 0x7C,0xA3,0xDB,0xDD,0x00,0x9B,0x78,0x51,0x7B,0xA6,0x8D,0xDD,0x43,0x9B,0xB2,0x2E,
+ 0x4B,0x1E,0xB3,0x34,0x37,0x3F,0x63,0x08,0x8C,0xC8,0xCF,0xD0,0xB0,0x8C,0xBF,0x8F,
+ 0xA7,0x49,0xBD,0x48,0x1D,0xB5,0x1E,0x6A,0x42,0x48,0x16,0x9A,0x7C,0xD3,0x55,0x6B,
+ 0xFF,0xD6,0xBA,0x70,0xF3,0x5F,0x1F,0x57,0x16,0xE0,0x1C,0xF1,0x73,0x22,0xD9,0x33,
+ 0xA7,0x20,0xE8,0xED,0x52,0x2A,0xE9,0x6F,0xCF,0xFB,0x76,0xAC,0xB8,0x5D,0x9B,0xAB,
+ 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x0D,0x30,0x82,0x02,0x09,0x30,0x81,0xA5,
+ 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0x98,0x30,0x81,0x95,
+ 0x30,0x51,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x45,0x68,0x74,
+ 0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,
+ 0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65,0x72,0x74,0x73,0x65,0x72,0x76,
+ 0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72,0x74,0x73,0x2F,0x74,0x63,0x5F,
+ 0x63,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E,
+ 0x63,0x72,0x74,0x30,0x40,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,
+ 0x34,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x69,0x78,0x2E,
+ 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,
+ 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
+ 0x65,0x72,0x2E,0x64,0x65,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,
+ 0x80,0x14,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5,0xEE,0x4B,
+ 0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,
+ 0x04,0x02,0x30,0x00,0x30,0x4A,0x06,0x03,0x55,0x1D,0x20,0x04,0x43,0x30,0x41,0x30,
+ 0x3F,0x06,0x09,0x2A,0x82,0x14,0x00,0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30,
+ 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70,
+ 0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
+ 0x65,0x72,0x2E,0x64,0x65,0x2F,0x67,0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73,
+ 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x04,0xF0,
+ 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF8,0x4D,0x7F,0xDE,0xFA,
+ 0x21,0x2E,0xAF,0x96,0xBB,0xAA,0x9B,0x22,0x56,0x80,0xF0,0x8E,0xD4,0x6A,0x52,0x30,
+ 0x62,0x06,0x03,0x55,0x1D,0x1F,0x04,0x5B,0x30,0x59,0x30,0x57,0xA0,0x55,0xA0,0x53,
+ 0x86,0x51,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x69,0x78,0x2E,
+ 0x74,0x63,0x63,0x6C,0x61,0x73,0x73,0x31,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,
+ 0x72,0x73,0x61,0x6C,0x2D,0x69,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
+ 0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F,0x74,0x63,0x5F,
+ 0x43,0x6C,0x61,0x73,0x73,0x31,0x5F,0x4C,0x31,0x5F,0x43,0x41,0x5F,0x49,0x58,0x2E,
+ 0x63,0x72,0x6C,0x30,0x33,0x06,0x03,0x55,0x1D,0x25,0x04,0x2C,0x30,0x2A,0x06,0x08,
+ 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
+ 0x03,0x04,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,0x06,0x0A,0x2B,0x06,
+ 0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,0x30,0x1C,0x06,0x03,0x55,0x1D,0x11,0x04,
+ 0x15,0x30,0x13,0x81,0x11,0x71,0x74,0x61,0x79,0x6C,0x6F,0x72,0x40,0x61,0x70,0x70,
+ 0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
+ 0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x0D,0xCF,0x33,0xAB,0x3D,0xD3,
+ 0xD2,0x06,0x2C,0x20,0x3C,0xEC,0x0C,0xE4,0xA5,0x19,0x86,0xB3,0xA7,0xA9,0xA6,0xE9,
+ 0xDC,0xB4,0x35,0xBB,0x0D,0x67,0xD5,0xBD,0x5F,0x93,0xD9,0x2E,0xA0,0x05,0x2A,0xED,
+ 0xAE,0x41,0xD9,0xEE,0x30,0xA8,0x82,0x50,0xD0,0x4B,0x04,0x6B,0x37,0xAE,0xC0,0x10,
+ 0x89,0x05,0x68,0x82,0x91,0x2B,0x5B,0xE2,0x7D,0xA6,0x87,0xF7,0x26,0x96,0xBA,0x2A,
+ 0x52,0x03,0x97,0xF6,0x2E,0x0D,0x81,0x65,0x24,0x10,0xD5,0x8C,0xB3,0xCD,0x19,0x58,
+ 0xAF,0x3A,0x3D,0x2F,0x10,0x30,0x79,0x6A,0xD6,0x08,0x8F,0x8B,0x9D,0x1D,0xF8,0x19,
+ 0xE4,0x24,0x2B,0xE0,0x7F,0x73,0xE1,0x50,0x9C,0x53,0xE1,0x46,0xC7,0xA7,0xBD,0x71,
+ 0xCD,0xFF,0x39,0xA0,0x50,0xA5,0xA8,0xD9,0x50,0x39,0x6C,0x36,0x1C,0x13,0x89,0x8A,
+ 0x0D,0x9D,0x06,0x1B,0xAA,0x59,0x40,0xC1,0xAF,0xED,0x66,0x31,0xB8,0xA0,0x9F,0xCF,
+ 0xA6,0x8A,0x2E,0xC2,0x1A,0x4B,0xDB,0x62,0x15,0x6E,0x10,0x2F,0x82,0x3C,0xF8,0xA2,
+ 0x18,0x63,0xCC,0x67,0x13,0x42,0x07,0x43,0xDB,0x20,0x13,0xC7,0xAC,0xCE,0xCB,0xEA,
+ 0x7E,0x53,0xA6,0x01,0x81,0xB2,0x6E,0x92,0x2B,0x0C,0xF9,0x01,0x2C,0x11,0xC9,0x00,
+ 0x10,0x58,0x64,0x56,0x91,0xAC,0xAA,0xF6,0xE0,0x73,0xC7,0x59,0xEC,0xCE,0x51,0x7E,
+ 0xAD,0x9F,0x04,0xA4,0x38,0x74,0x65,0xD0,0x23,0xBD,0x6E,0xDF,0x64,0x79,0xE2,0xA3,
+ 0x37,0x19,0x2F,0x8C,0x41,0x8B,0x5F,0x6D,0x84,0x61,0x54,0xD1,0x26,0x18,0x70,0xAD,
+ 0xE5,0xF4,0xCD,0x59,0xED,0x9E,0xE0,0xC9,0x9F,0xD3,
+};
+
+unsigned char ocsp_smime_CA_certificate[1500]={
+ 0x30,0x82,0x05,0xD8,0x30,0x82,0x04,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x06,
+ 0xE8,0x00,0x01,0x00,0x02,0x4A,0x96,0x2D,0x24,0x0C,0xFE,0xC5,0xC9,0x30,0x0D,0x06,
+ 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B,
+ 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,
+ 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,
+ 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,
+ 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,
+ 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,
+ 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,
+ 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,
+ 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x39,0x31,0x31,0x30,
+ 0x33,0x31,0x34,0x30,0x38,0x31,0x39,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31,
+ 0x32,0x31,0x35,0x39,0x35,0x39,0x5A,0x30,0x7C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+ 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,
+ 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,
+ 0x47,0x6D,0x62,0x48,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,0x54,
+ 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,
+ 0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,0x43,0x41,0x31,0x28,0x30,0x26,0x06,
+ 0x03,0x55,0x04,0x03,0x13,0x1F,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,
+ 0x6E,0x74,0x65,0x72,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x31,0x20,0x4C,0x31,0x20,
+ 0x43,0x41,0x20,0x49,0x58,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,0xBB,0xE6,0x90,0x6E,0xCF,0x62,0xE9,0xE9,0x0B,0xAA,
+ 0xB6,0x10,0xD5,0x47,0xE5,0x7C,0x5D,0x2B,0x27,0x71,0x9A,0x68,0xCD,0x55,0x6D,0xE4,
+ 0xA2,0xEF,0xE4,0xFE,0xF2,0x7A,0x63,0x11,0xC2,0x57,0x8A,0xC8,0x7D,0xCF,0x8E,0x66,
+ 0x1F,0x65,0x45,0x4B,0xEB,0x80,0x62,0x69,0xBD,0x46,0x8E,0x8B,0xC5,0x6E,0x5A,0x95,
+ 0x18,0x2A,0xDE,0xA7,0xF1,0x1F,0x75,0x1A,0x27,0xAB,0x6D,0x32,0x53,0xE3,0xFB,0x4D,
+ 0x58,0x62,0x2C,0xFF,0x19,0xE5,0xC7,0xA0,0x0D,0x9A,0x2D,0x21,0x88,0x59,0x84,0xCD,
+ 0x1D,0xF1,0xC3,0xC8,0x8A,0x3E,0xB0,0xE5,0xDE,0x08,0x24,0xCF,0xFC,0x40,0x2C,0xBA,
+ 0x41,0x23,0x94,0xBB,0x80,0x12,0x89,0x35,0x48,0xB6,0x86,0x04,0xE0,0x01,0x4F,0x8C,
+ 0xBA,0xA9,0x98,0xFC,0x1C,0x89,0xED,0x1F,0x8A,0xA1,0xC7,0x86,0x98,0x26,0x1E,0x72,
+ 0x65,0x6B,0xFE,0xCF,0x65,0xD9,0x0C,0x64,0x4B,0x1A,0x09,0xF5,0x43,0x11,0x60,0x66,
+ 0x26,0xE3,0x33,0x56,0x9A,0xC9,0x3D,0x3E,0x34,0x6A,0x78,0xC6,0xE5,0x50,0x4B,0xC8,
+ 0xCD,0x88,0xE4,0x39,0x6C,0x50,0x26,0x9E,0x40,0x2C,0xB6,0x3B,0x7C,0x37,0xB2,0xA7,
+ 0xF5,0xDD,0xDC,0xB3,0x51,0xCB,0xF4,0xDC,0x82,0x02,0xB8,0xD7,0x3A,0xDE,0xDA,0x30,
+ 0x5C,0x0D,0xF5,0x42,0xDD,0x13,0x69,0x53,0x54,0xE9,0x80,0x26,0x42,0x33,0x1E,0xA5,
+ 0xD7,0xCC,0x6E,0xCA,0x66,0x09,0x9F,0x86,0xF0,0x3D,0xBE,0xC6,0x8A,0x61,0x10,0xF3,
+ 0xD1,0xFF,0x5B,0xE4,0xB2,0xDB,0x2D,0xB2,0x65,0x0C,0xA9,0x7D,0x17,0xAC,0xBA,0x27,
+ 0x4D,0x42,0x5C,0xCE,0x09,0x4F,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0x59,0x30,
+ 0x82,0x02,0x55,0x30,0x81,0x9A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
+ 0x04,0x81,0x8D,0x30,0x81,0x8A,0x30,0x52,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,
+ 0x30,0x02,0x86,0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,
+ 0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x65,
+ 0x72,0x74,0x73,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2F,0x63,0x61,0x63,0x65,0x72,
+ 0x74,0x73,0x2F,0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F,
+ 0x72,0x6F,0x6F,0x74,0x5F,0x49,0x2E,0x63,0x72,0x74,0x30,0x34,0x06,0x08,0x2B,0x06,
+ 0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x28,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,
+ 0x63,0x73,0x70,0x2E,0x74,0x63,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D,
+ 0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,
+ 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75,
+ 0x2C,0xA4,0x9E,0xBE,0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,
+ 0x73,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,
+ 0x01,0xFF,0x02,0x01,0x00,0x30,0x52,0x06,0x03,0x55,0x1D,0x20,0x04,0x4B,0x30,0x49,
+ 0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x3F,0x06,0x09,0x2A,0x82,0x14,0x00,
+ 0x2C,0x01,0x01,0x01,0x01,0x30,0x32,0x30,0x30,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
+ 0x07,0x02,0x01,0x16,0x24,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,
+ 0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x67,
+ 0x75,0x69,0x64,0x65,0x6C,0x69,0x6E,0x65,0x73,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,0xE9,0xB8,0x28,0x1D,0x46,0xCF,0xFC,0xCD,0xF8,0x4E,0x9B,0xC5,
+ 0xEE,0x4B,0x60,0xEB,0xD8,0x3B,0x3F,0xD1,0x30,0x81,0xFD,0x06,0x03,0x55,0x1D,0x1F,
+ 0x04,0x81,0xF5,0x30,0x81,0xF2,0x30,0x81,0xEF,0xA0,0x81,0xEC,0xA0,0x81,0xE9,0x86,
+ 0x46,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x74,0x63,0x75,0x6E,
+ 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x2D,0x49,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,
+ 0x65,0x6E,0x74,0x65,0x72,0x2E,0x64,0x65,0x2F,0x63,0x72,0x6C,0x2F,0x76,0x32,0x2F,
+ 0x74,0x63,0x5F,0x75,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x5F,0x72,0x6F,0x6F,
+ 0x74,0x5F,0x49,0x2E,0x63,0x72,0x6C,0x86,0x81,0x9E,0x6C,0x64,0x61,0x70,0x3A,0x2F,
+ 0x2F,0x77,0x77,0x77,0x2E,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,0x65,0x72,
+ 0x2E,0x64,0x65,0x2F,0x43,0x4E,0x3D,0x54,0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,
+ 0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,0x32,0x30,0x55,0x6E,0x69,0x76,0x65,0x72,
+ 0x73,0x61,0x6C,0x25,0x32,0x30,0x43,0x41,0x25,0x32,0x30,0x49,0x2C,0x4F,0x3D,0x54,
+ 0x43,0x25,0x32,0x30,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x25,
+ 0x32,0x30,0x47,0x6D,0x62,0x48,0x2C,0x4F,0x55,0x3D,0x72,0x6F,0x6F,0x74,0x63,0x65,
+ 0x72,0x74,0x73,0x2C,0x44,0x43,0x3D,0x74,0x72,0x75,0x73,0x74,0x63,0x65,0x6E,0x74,
+ 0x65,0x72,0x2C,0x44,0x43,0x3D,0x64,0x65,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,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+ 0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x39,0xC8,0xC4,0x9B,
+ 0xEE,0xBE,0x98,0xEE,0x48,0x72,0x6F,0x8D,0xE7,0x71,0xB6,0x0E,0x90,0x8C,0xD3,0xB2,
+ 0xC1,0x15,0x21,0xA8,0x46,0x90,0x68,0x5F,0x4A,0x04,0xF1,0x3A,0xC9,0x68,0x84,0x21,
+ 0xD8,0xA5,0xE6,0x04,0x75,0x5D,0x9F,0xD2,0xD4,0xF2,0x4B,0x77,0x43,0x32,0xDC,0x95,
+ 0xCB,0x60,0xBF,0x02,0x55,0xD0,0xAC,0x1C,0xB0,0xC5,0x14,0x97,0x9B,0x65,0x0A,0xC3,
+ 0x0F,0xA5,0x1D,0xEC,0xD8,0x49,0x39,0x95,0xB5,0xA9,0xBE,0xFA,0xF4,0x1E,0xAB,0x56,
+ 0xE7,0xA6,0xE5,0x01,0x08,0x88,0x35,0x5F,0x67,0x05,0xDD,0x44,0x24,0x50,0x12,0x22,
+ 0x44,0x63,0x79,0xF1,0x9B,0x57,0x69,0xCE,0xAB,0xD6,0x33,0x51,0x4F,0x8D,0xF0,0x70,
+ 0x3B,0x8E,0xAD,0x51,0x3A,0x17,0x7F,0x35,0x96,0x6B,0x68,0x68,0x63,0xB6,0x1C,0x0A,
+ 0xC9,0xF8,0xDF,0x1D,0x5E,0xCF,0x2B,0x11,0xA5,0x63,0xED,0xCC,0xD0,0xC6,0xD3,0x20,
+ 0x6F,0xAA,0xFC,0x68,0x48,0x7E,0x6D,0x1E,0xB8,0x3A,0x45,0xAA,0x12,0x86,0xF3,0xC7,
+ 0xBD,0x00,0xB5,0xEB,0xFE,0xEA,0x12,0x9F,0x73,0x33,0x78,0xE7,0x28,0x39,0x68,0xD3,
+ 0xA5,0x6D,0xDA,0x76,0xD1,0x4E,0xE1,0x55,0x95,0x80,0xA6,0xE0,0x1B,0xB8,0xCD,0xAC,
+ 0x56,0xEF,0x45,0x59,0x47,0x98,0x52,0xDB,0x3A,0x6E,0x26,0xB2,0x31,0x39,0x69,0x75,
+ 0xB1,0x2E,0x24,0xF0,0xA4,0x9D,0x97,0x88,0x5E,0x33,0x29,0xC6,0xB5,0xBC,0x07,0x40,
+ 0x3A,0x0C,0x3D,0xBA,0xCF,0x74,0x8C,0x4B,0x4E,0x7A,0x21,0xFA,0x1B,0x38,0xCD,0xC4,
+ 0x43,0x2F,0x6F,0xB4,0xDF,0x78,0xEE,0x99,0x92,0xE7,0x3A,0x1C,
+};
+
+unsigned char ocsp_smime_root_certificate[993]={
+ 0x30,0x82,0x03,0xDD,0x30,0x82,0x02,0xC5,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x1D,
+ 0xA2,0x00,0x01,0x00,0x02,0xEC,0xB7,0x60,0x80,0x78,0x8D,0xB6,0x06,0x30,0x0D,0x06,
+ 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x79,0x31,0x0B,
+ 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,
+ 0x03,0x55,0x04,0x0A,0x13,0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,
+ 0x6E,0x74,0x65,0x72,0x20,0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,
+ 0x04,0x0B,0x13,0x1B,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,
+ 0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,
+ 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,
+ 0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,
+ 0x61,0x6C,0x20,0x43,0x41,0x20,0x49,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x33,0x32,
+ 0x32,0x31,0x35,0x35,0x34,0x32,0x38,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x33,0x31,
+ 0x32,0x32,0x35,0x39,0x35,0x39,0x5A,0x30,0x79,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
+ 0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,
+ 0x13,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,
+ 0x47,0x6D,0x62,0x48,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x0B,0x13,0x1B,0x54,
+ 0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,0x74,0x65,0x72,0x20,0x55,0x6E,
+ 0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x31,0x26,0x30,0x24,0x06,0x03,
+ 0x55,0x04,0x03,0x13,0x1D,0x54,0x43,0x20,0x54,0x72,0x75,0x73,0x74,0x43,0x65,0x6E,
+ 0x74,0x65,0x72,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,
+ 0x20,0x49,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,0xA4,0x77,0x23,0x96,0x44,0xAF,0x90,0xF4,0x31,0xA7,0x10,0xF4,0x26,
+ 0x87,0x9C,0xF3,0x38,0xD9,0x0F,0x5E,0xDE,0xCF,0x41,0xE8,0x31,0xAD,0xC6,0x74,0x91,
+ 0x24,0x96,0x78,0x1E,0x09,0xA0,0x9B,0x9A,0x95,0x4A,0x4A,0xF5,0x62,0x7C,0x02,0xA8,
+ 0xCA,0xAC,0xFB,0x5A,0x04,0x76,0x39,0xDE,0x5F,0xF1,0xF9,0xB3,0xBF,0xF3,0x03,0x58,
+ 0x55,0xD2,0xAA,0xB7,0xE3,0x04,0x22,0xD1,0xF8,0x94,0xDA,0x22,0x08,0x00,0x8D,0xD3,
+ 0x7C,0x26,0x5D,0xCC,0x77,0x79,0xE7,0x2C,0x78,0x39,0xA8,0x26,0x73,0x0E,0xA2,0x5D,
+ 0x25,0x69,0x85,0x4F,0x55,0x0E,0x9A,0xEF,0xC6,0xB9,0x44,0xE1,0x57,0x3D,0xDF,0x1F,
+ 0x54,0x22,0xE5,0x6F,0x65,0xAA,0x33,0x84,0x3A,0xF3,0xCE,0x7A,0xBE,0x55,0x97,0xAE,
+ 0x8D,0x12,0x0F,0x14,0x33,0xE2,0x50,0x70,0xC3,0x49,0x87,0x13,0xBC,0x51,0xDE,0xD7,
+ 0x98,0x12,0x5A,0xEF,0x3A,0x83,0x33,0x92,0x06,0x75,0x8B,0x92,0x7C,0x12,0x68,0x7B,
+ 0x70,0x6A,0x0F,0xB5,0x9B,0xB6,0x77,0x5B,0x48,0x59,0x9D,0xE4,0xEF,0x5A,0xAD,0xF3,
+ 0xC1,0x9E,0xD4,0xD7,0x45,0x4E,0xCA,0x56,0x34,0x21,0xBC,0x3E,0x17,0x5B,0x6F,0x77,
+ 0x0C,0x48,0x01,0x43,0x29,0xB0,0xDD,0x3F,0x96,0x6E,0xE6,0x95,0xAA,0x0C,0xC0,0x20,
+ 0xB6,0xFD,0x3E,0x36,0x27,0x9C,0xE3,0x5C,0xCF,0x4E,0x81,0xDC,0x19,0xBB,0x91,0x90,
+ 0x7D,0xEC,0xE6,0x97,0x04,0x1E,0x93,0xCC,0x22,0x49,0xD7,0x97,0x86,0xB6,0x13,0x0A,
+ 0x3C,0x43,0x23,0x77,0x7E,0xF0,0xDC,0xE6,0xCD,0x24,0x1F,0x3B,0x83,0x9B,0x34,0x3A,
+ 0x83,0x34,0xE3,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x1F,0x06,0x03,
+ 0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE,
+ 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,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,0x1D,
+ 0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x92,0xA4,0x75,0x2C,0xA4,0x9E,0xBE,
+ 0x81,0x44,0xEB,0x79,0xFC,0x8A,0xC5,0x95,0xA5,0xEB,0x10,0x75,0x73,0x30,0x0D,0x06,
+ 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,
+ 0x00,0x28,0xD2,0xE0,0x86,0xD5,0xE6,0xF8,0x7B,0xF0,0x97,0xDC,0x22,0x6B,0x3B,0x95,
+ 0x14,0x56,0x0F,0x11,0x30,0xA5,0x9A,0x4F,0x3A,0xB0,0x3A,0xE0,0x06,0xCB,0x65,0xF5,
+ 0xED,0xC6,0x97,0x27,0xFE,0x25,0xF2,0x57,0xE6,0x5E,0x95,0x8C,0x3E,0x64,0x60,0x15,
+ 0x5A,0x7F,0x2F,0x0D,0x01,0xC5,0xB1,0x60,0xFD,0x45,0x35,0xCF,0xF0,0xB2,0xBF,0x06,
+ 0xD9,0xEF,0x5A,0xBE,0xB3,0x62,0x21,0xB4,0xD7,0xAB,0x35,0x7C,0x53,0x3E,0xA6,0x27,
+ 0xF1,0xA1,0x2D,0xDA,0x1A,0x23,0x9D,0xCC,0xDD,0xEC,0x3C,0x2D,0x9E,0x27,0x34,0x5D,
+ 0x0F,0xC2,0x36,0x79,0xBC,0xC9,0x4A,0x62,0x2D,0xED,0x6B,0xD9,0x7D,0x41,0x43,0x7C,
+ 0xB6,0xAA,0xCA,0xED,0x61,0xB1,0x37,0x82,0x15,0x09,0x1A,0x8A,0x16,0x30,0xD8,0xEC,
+ 0xC9,0xD6,0x47,0x72,0x78,0x4B,0x10,0x46,0x14,0x8E,0x5F,0x0E,0xAF,0xEC,0xC7,0x2F,
+ 0xAB,0x10,0xD7,0xB6,0xF1,0x6E,0xEC,0x86,0xB2,0xC2,0xE8,0x0D,0x92,0x73,0xDC,0xA2,
+ 0xF4,0x0F,0x3A,0xBF,0x61,0x23,0x10,0x89,0x9C,0x48,0x40,0x6E,0x70,0x00,0xB3,0xD3,
+ 0xBA,0x37,0x44,0x58,0x11,0x7A,0x02,0x6A,0x88,0xF0,0x37,0x34,0xF0,0x19,0xE9,0xAC,
+ 0xD4,0x65,0x73,0xF6,0x69,0x8C,0x64,0x94,0x3A,0x79,0x85,0x29,0xB0,0x16,0x2B,0x0C,
+ 0x82,0x3F,0x06,0x9C,0xC7,0xFD,0x10,0x2B,0x9E,0x0F,0x2C,0xB6,0x9E,0xE3,0x15,0xBF,
+ 0xD9,0x36,0x1C,0xBA,0x25,0x1A,0x52,0x3D,0x1A,0xEC,0x22,0x0C,0x1C,0xE0,0xA4,0xA2,
+ 0x3D,0xF0,0xE8,0x39,0xCF,0x81,0xC0,0x7B,0xED,0x5D,0x1F,0x6F,0xC5,0xD0,0x0B,0xD7,
+ 0x98,
+};
+
+/* subject:/C=US/ST=California/L=Walnut Creek/O=Lucas Garron/CN=revoked.badssl.com */
+/* issuer :/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */
+uint8_t _probablyRevokedLeaf[]={
+ 0x30,0x82,0x06,0xA1,0x30,0x82,0x05,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01,
+ 0xAF,0x1E,0xFB,0xDD,0x5E,0xAE,0x09,0x52,0x32,0x0B,0x24,0xFE,0x6B,0x55,0x68,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4D,
+ 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,
+ 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,
+ 0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03,0x13,0x1E,0x44,
+ 0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x53,0x65,0x63,
+ 0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,
+ 0x0D,0x31,0x36,0x30,0x39,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,
+ 0x31,0x39,0x30,0x39,0x31,0x31,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x6D,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,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x07,0x13,0x0C,0x57,0x61,0x6C,0x6E,
+ 0x75,0x74,0x20,0x43,0x72,0x65,0x65,0x6B,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,
+ 0x0A,0x13,0x0C,0x4C,0x75,0x63,0x61,0x73,0x20,0x47,0x61,0x72,0x72,0x6F,0x6E,0x31,
+ 0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65,
+ 0x64,0x2E,0x62,0x61,0x64,0x73,0x73,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,0xC7,0x31,0x65,
+ 0xE4,0x55,0xCF,0x69,0x90,0x9F,0x6E,0x1F,0xD8,0x6A,0x13,0x7E,0x74,0xBF,0x13,0x3A,
+ 0x54,0x64,0x0F,0x74,0x24,0x3D,0xDC,0x60,0xB8,0xA7,0x45,0x01,0xB7,0xC8,0x6A,0x03,
+ 0xAC,0x64,0x4A,0x65,0xF0,0x7C,0x81,0x81,0x83,0x0A,0xD9,0xDD,0x31,0x20,0x82,0x48,
+ 0xA6,0x33,0x63,0xEE,0x2B,0x74,0xEA,0xB4,0xE6,0xC7,0x1C,0xB2,0x5E,0xE4,0x28,0x3A,
+ 0x7A,0x3D,0x20,0x19,0x03,0xB7,0x15,0x3F,0x4F,0xC9,0x26,0xEC,0xB7,0xCB,0xBF,0x48,
+ 0x6E,0x5F,0x34,0x70,0x56,0xC4,0x86,0xC7,0xE3,0x52,0x9A,0x21,0x33,0x2F,0x10,0x13,
+ 0xF3,0x25,0x0C,0x1E,0x94,0x35,0x2E,0xE8,0xD0,0xD1,0xB5,0xA0,0x77,0x40,0x91,0x2E,
+ 0xE9,0xBA,0xF8,0xFF,0x4E,0xF5,0xFB,0xF2,0x7A,0x04,0xA7,0xE6,0xC6,0xCE,0x3F,0x0F,
+ 0x10,0x18,0x32,0xC8,0x06,0xBC,0x15,0xB3,0xBE,0x69,0xAC,0x75,0x7D,0x42,0xA0,0x8C,
+ 0x2E,0xC3,0xAC,0xE1,0x20,0x4F,0x1E,0x36,0x9C,0x9A,0x2E,0xA2,0xFD,0x79,0x80,0xB6,
+ 0x62,0xF8,0xC0,0xB2,0x03,0xA9,0x29,0x50,0xCC,0xD5,0x25,0x8A,0x33,0x5E,0xE0,0x78,
+ 0x13,0x18,0xC0,0x80,0x17,0x09,0x95,0xBD,0xA2,0xFE,0x92,0x15,0x07,0x20,0x7A,0x81,
+ 0xCE,0xDB,0x0E,0x81,0x29,0x89,0xD4,0xC8,0xEC,0xB3,0xB3,0x79,0x0E,0xF2,0xCE,0x25,
+ 0xE7,0xEE,0xBE,0x21,0x7D,0xAF,0x0C,0x13,0x94,0x29,0xDE,0x35,0x9A,0x1E,0xD8,0x84,
+ 0x18,0x5A,0x5C,0x1A,0x94,0x82,0xCE,0x9A,0x61,0xD6,0x9D,0xEC,0xF8,0xEE,0xAD,0x3F,
+ 0x09,0x5B,0x73,0xEC,0xA2,0x9B,0xFA,0xDC,0x62,0xF1,0x58,0x1F,0x7D,0x02,0x03,0x01,
+ 0x00,0x01,0xA3,0x82,0x03,0x5B,0x30,0x82,0x03,0x57,0x30,0x1F,0x06,0x03,0x55,0x1D,
+ 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x0F,0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F,
+ 0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1,0xC6,0xD9,0xE2,0x30,0x1D,0x06,0x03,0x55,
+ 0x1D,0x0E,0x04,0x16,0x04,0x14,0xF4,0x48,0x7D,0x07,0x45,0x1A,0x32,0x07,0x90,0x91,
+ 0xAC,0x05,0xB8,0x9F,0xA9,0x11,0xF0,0x7E,0x11,0x36,0x30,0x1D,0x06,0x03,0x55,0x1D,
+ 0x11,0x04,0x16,0x30,0x14,0x82,0x12,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E,0x62,
+ 0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,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,0x6B,0x06,0x03,0x55,0x1D,0x1F,0x04,
+ 0x64,0x30,0x62,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70,0x3A,
+ 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,
+ 0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67,0x35,
+ 0x2E,0x63,0x72,0x6C,0x30,0x2F,0xA0,0x2D,0xA0,0x2B,0x86,0x29,0x68,0x74,0x74,0x70,
+ 0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,
+ 0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x73,0x63,0x61,0x2D,0x73,0x68,0x61,0x32,0x2D,0x67,
+ 0x35,0x2E,0x63,0x72,0x6C,0x30,0x4C,0x06,0x03,0x55,0x1D,0x20,0x04,0x45,0x30,0x43,
+ 0x30,0x37,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xFD,0x6C,0x01,0x01,0x30,0x2A,0x30,
+ 0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74,
+ 0x70,0x73,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,
+ 0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x43,0x50,0x53,0x30,0x08,0x06,0x06,0x67,0x81,0x0C,
+ 0x01,0x02,0x03,0x30,0x7C,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,
+ 0x70,0x30,0x6E,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,
+ 0x18,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67,
+ 0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x46,0x06,0x08,0x2B,0x06,0x01,
+ 0x05,0x05,0x07,0x30,0x02,0x86,0x3A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x61,
+ 0x63,0x65,0x72,0x74,0x73,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,
+ 0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x53,0x48,0x41,0x32,0x53,
+ 0x65,0x63,0x75,0x72,0x65,0x53,0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72,
+ 0x74,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,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,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,0x56,
+ 0xEC,0xA1,0x37,0xDA,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x3F,0x6C,
+ 0xA8,0xF5,0xC4,0x7C,0x01,0x4C,0xC3,0x5A,0x28,0x27,0x50,0x47,0x63,0xD9,0xAC,0xE1,
+ 0xBE,0x2D,0xBF,0x87,0x78,0xCB,0x3A,0x80,0x97,0x24,0x74,0xCD,0x16,0xF7,0x02,0x20,
+ 0x71,0xFF,0x93,0xA2,0xB5,0x54,0x7E,0x7F,0x53,0x45,0x7F,0x59,0x5A,0x60,0x18,0x21,
+ 0x5C,0xAB,0x7D,0x1F,0x08,0xB2,0x54,0xA0,0xB3,0xC4,0x88,0xA5,0x83,0xD2,0x63,0x55,
+ 0x00,0x77,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,0x56,0xEC,0xA1,0x37,0xA1,0x00,0x00,0x04,0x03,0x00,
+ 0x48,0x30,0x46,0x02,0x21,0x00,0xFE,0x59,0x97,0x22,0x4C,0x6C,0x0F,0x39,0x05,0xD9,
+ 0xE4,0xCA,0x7E,0x3B,0xD3,0xB3,0x47,0x1B,0x61,0x72,0xB6,0x3A,0x4F,0xD6,0xF2,0xA3,
+ 0x57,0x49,0x48,0x4F,0x6A,0x6D,0x02,0x21,0x00,0x8F,0x14,0x1B,0x3C,0x1B,0x89,0xA3,
+ 0x1D,0x70,0xEC,0xD4,0xD7,0x11,0xBC,0xF9,0x0B,0x3C,0x60,0xAC,0x8C,0x84,0x73,0x24,
+ 0x6B,0x0E,0x37,0x6E,0x53,0x7F,0x9D,0x7F,0x34,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,0x56,
+ 0xEC,0xA1,0x38,0x7F,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x20,0x0E,0xBF,
+ 0x53,0x59,0x17,0x0C,0xEC,0x66,0x0C,0x5E,0x87,0xBB,0x8F,0x5F,0xB6,0x76,0x86,0xF2,
+ 0x5C,0xFC,0xBC,0xA8,0xB9,0xC0,0xDF,0xBC,0x1A,0x3B,0xEE,0x11,0xF2,0xD0,0x02,0x21,
+ 0x00,0x87,0x25,0x39,0xE4,0x32,0x99,0x48,0xCA,0x20,0x1B,0x13,0x96,0x1D,0xC3,0x2C,
+ 0x98,0x6B,0x1B,0xC0,0xCC,0xE5,0x67,0x22,0xBD,0x92,0x14,0xE9,0x68,0xCD,0x95,0x82,
+ 0x32,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,
+ 0x03,0x82,0x01,0x01,0x00,0x5A,0xA0,0x49,0x88,0xAD,0x60,0x1F,0x08,0x53,0x4C,0xD9,
+ 0xB8,0xDC,0xF5,0x40,0x41,0xAD,0xEF,0xC8,0x7B,0x01,0x3B,0x13,0x70,0x44,0x99,0xF6,
+ 0x5C,0x23,0x46,0xF7,0x3A,0xC8,0x7D,0xC9,0x21,0xAD,0x3A,0x49,0x45,0x82,0x1E,0x5D,
+ 0x3B,0x1E,0x9B,0x6A,0x0A,0x3E,0x61,0x2D,0xF6,0xB1,0x99,0x74,0x2F,0x91,0xF9,0xD5,
+ 0xF1,0x9F,0xAE,0x74,0x26,0x8B,0x3C,0xA7,0x8C,0xBE,0x28,0xFE,0xAC,0x3B,0x70,0xAE,
+ 0x08,0x56,0x71,0xAC,0x55,0x7C,0x40,0x89,0x02,0x2D,0x61,0x2A,0xFD,0x54,0x72,0xBF,
+ 0x1A,0x5C,0x70,0x19,0x90,0x15,0xA4,0x76,0xA0,0x7F,0x56,0x1C,0xC1,0xF0,0x8D,0x5E,
+ 0x99,0x3D,0x83,0x41,0x54,0x68,0xE5,0x62,0xC1,0x5A,0xA2,0x64,0x8C,0x01,0x64,0x7A,
+ 0x23,0xB9,0x3F,0xBF,0x22,0xCF,0x1F,0xC0,0x47,0x80,0x1F,0x94,0xD5,0xF2,0x30,0x84,
+ 0xFB,0x07,0x02,0xFA,0x5B,0xA0,0xBA,0x09,0x04,0x98,0x4E,0xF3,0x25,0x56,0x4C,0xC4,
+ 0x7E,0xE0,0x27,0xD8,0xE8,0x32,0x8F,0xB3,0x3C,0x5A,0x92,0x4B,0xC0,0x77,0x2D,0xB0,
+ 0xE5,0xAE,0x1F,0xAF,0x1D,0x7F,0x21,0x9C,0x65,0x26,0xBE,0x0C,0xBA,0xE8,0x0D,0xC1,
+ 0xD2,0x67,0xB4,0xB9,0x33,0xD1,0x4A,0xEE,0xFC,0xB8,0xAF,0x03,0x5B,0xC8,0x3E,0xBC,
+ 0xFA,0x09,0x9D,0x04,0xCE,0x3E,0xA6,0xB5,0xC4,0x74,0x3B,0x31,0x7A,0xF3,0x2C,0x42,
+ 0xB3,0xC7,0x73,0xDB,0xAA,0x75,0x2E,0x8D,0x8A,0x9E,0x79,0x33,0xBE,0xD7,0xB6,0x14,
+ 0x9B,0x26,0xAB,0x7B,0x9E,0x14,0xB3,0x55,0xE6,0x4B,0xBB,0x86,0x94,0x11,0x74,0x02,
+ 0x35,0xB4,0x52,0x70,0x9B,
+};
+
+/* subject:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA */
+/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */
+uint8_t _digiCertSha2SubCA[] ={
+ 0x30,0x82,0x04,0x94,0x30,0x82,0x03,0x7C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01,
+ 0xFD,0xA3,0xEB,0x6E,0xCA,0x75,0xC8,0x88,0x43,0x8B,0x72,0x4B,0xCF,0xBC,0x91,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x61,
+ 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,
+ 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,
+ 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77,
+ 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31,
+ 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65,
+ 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,
+ 0x41,0x30,0x1E,0x17,0x0D,0x31,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30,
+ 0x30,0x5A,0x17,0x0D,0x32,0x33,0x30,0x33,0x30,0x38,0x31,0x32,0x30,0x30,0x30,0x30,
+ 0x5A,0x30,0x4D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+ 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,
+ 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03,
+ 0x13,0x1E,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,
+ 0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,
+ 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,0xAE,0x58,0x90,0x4D,0xC1,0xC4,0x30,0x15,0x90,0x35,0x5B,0x6E,0x3C,0x82,
+ 0x15,0xF5,0x2C,0x5C,0xBD,0xE3,0xDB,0xFF,0x71,0x43,0xFA,0x64,0x25,0x80,0xD4,0xEE,
+ 0x18,0xA2,0x4D,0xF0,0x66,0xD0,0x0A,0x73,0x6E,0x11,0x98,0x36,0x17,0x64,0xAF,0x37,
+ 0x9D,0xFD,0xFA,0x41,0x84,0xAF,0xC7,0xAF,0x8C,0xFE,0x1A,0x73,0x4D,0xCF,0x33,0x97,
+ 0x90,0xA2,0x96,0x87,0x53,0x83,0x2B,0xB9,0xA6,0x75,0x48,0x2D,0x1D,0x56,0x37,0x7B,
+ 0xDA,0x31,0x32,0x1A,0xD7,0xAC,0xAB,0x06,0xF4,0xAA,0x5D,0x4B,0xB7,0x47,0x46,0xDD,
+ 0x2A,0x93,0xC3,0x90,0x2E,0x79,0x80,0x80,0xEF,0x13,0x04,0x6A,0x14,0x3B,0xB5,0x9B,
+ 0x92,0xBE,0xC2,0x07,0x65,0x4E,0xFC,0xDA,0xFC,0xFF,0x7A,0xAE,0xDC,0x5C,0x7E,0x55,
+ 0x31,0x0C,0xE8,0x39,0x07,0xA4,0xD7,0xBE,0x2F,0xD3,0x0B,0x6A,0xD2,0xB1,0xDF,0x5F,
+ 0xFE,0x57,0x74,0x53,0x3B,0x35,0x80,0xDD,0xAE,0x8E,0x44,0x98,0xB3,0x9F,0x0E,0xD3,
+ 0xDA,0xE0,0xD7,0xF4,0x6B,0x29,0xAB,0x44,0xA7,0x4B,0x58,0x84,0x6D,0x92,0x4B,0x81,
+ 0xC3,0xDA,0x73,0x8B,0x12,0x97,0x48,0x90,0x04,0x45,0x75,0x1A,0xDD,0x37,0x31,0x97,
+ 0x92,0xE8,0xCD,0x54,0x0D,0x3B,0xE4,0xC1,0x3F,0x39,0x5E,0x2E,0xB8,0xF3,0x5C,0x7E,
+ 0x10,0x8E,0x86,0x41,0x00,0x8D,0x45,0x66,0x47,0xB0,0xA1,0x65,0xCE,0xA0,0xAA,0x29,
+ 0x09,0x4E,0xF3,0x97,0xEB,0xE8,0x2E,0xAB,0x0F,0x72,0xA7,0x30,0x0E,0xFA,0xC7,0xF4,
+ 0xFD,0x14,0x77,0xC3,0xA4,0x5B,0x28,0x57,0xC2,0xB3,0xF9,0x82,0xFD,0xB7,0x45,0x58,
+ 0x9B,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x5A,0x30,0x82,0x01,0x56,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,0x86,0x30,0x34,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,
+ 0x30,0x26,0x30,0x24,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,
+ 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x64,0x69,0x67,0x69,
+ 0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x7B,0x06,0x03,0x55,0x1D,0x1F,0x04,
+ 0x74,0x30,0x72,0x30,0x37,0xA0,0x35,0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,
+ 0x2F,0x2F,0x63,0x72,0x6C,0x33,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,
+ 0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62,
+ 0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x37,0xA0,0x35,
+ 0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x34,0x2E,
+ 0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67,
+ 0x69,0x43,0x65,0x72,0x74,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x52,0x6F,0x6F,0x74,0x43,
+ 0x41,0x2E,0x63,0x72,0x6C,0x30,0x3D,0x06,0x03,0x55,0x1D,0x20,0x04,0x36,0x30,0x34,
+ 0x30,0x32,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06,
+ 0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,
+ 0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,
+ 0x2F,0x43,0x50,0x53,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x0F,
+ 0x80,0x61,0x1C,0x82,0x31,0x61,0xD5,0x2F,0x28,0xE7,0x8D,0x46,0x38,0xB4,0x2C,0xE1,
+ 0xC6,0xD9,0xE2,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
+ 0x03,0xDE,0x50,0x35,0x56,0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,
+ 0xB2,0x3D,0xD1,0x55,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,
+ 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x23,0x3E,0xDF,0x4B,0xD2,0x31,0x42,0xA5,
+ 0xB6,0x7E,0x42,0x5C,0x1A,0x44,0xCC,0x69,0xD1,0x68,0xB4,0x5D,0x4B,0xE0,0x04,0x21,
+ 0x6C,0x4B,0xE2,0x6D,0xCC,0xB1,0xE0,0x97,0x8F,0xA6,0x53,0x09,0xCD,0xAA,0x2A,0x65,
+ 0xE5,0x39,0x4F,0x1E,0x83,0xA5,0x6E,0x5C,0x98,0xA2,0x24,0x26,0xE6,0xFB,0xA1,0xED,
+ 0x93,0xC7,0x2E,0x02,0xC6,0x4D,0x4A,0xBF,0xB0,0x42,0xDF,0x78,0xDA,0xB3,0xA8,0xF9,
+ 0x6D,0xFF,0x21,0x85,0x53,0x36,0x60,0x4C,0x76,0xCE,0xEC,0x38,0xDC,0xD6,0x51,0x80,
+ 0xF0,0xC5,0xD6,0xE5,0xD4,0x4D,0x27,0x64,0xAB,0x9B,0xC7,0x3E,0x71,0xFB,0x48,0x97,
+ 0xB8,0x33,0x6D,0xC9,0x13,0x07,0xEE,0x96,0xA2,0x1B,0x18,0x15,0xF6,0x5C,0x4C,0x40,
+ 0xED,0xB3,0xC2,0xEC,0xFF,0x71,0xC1,0xE3,0x47,0xFF,0xD4,0xB9,0x00,0xB4,0x37,0x42,
+ 0xDA,0x20,0xC9,0xEA,0x6E,0x8A,0xEE,0x14,0x06,0xAE,0x7D,0xA2,0x59,0x98,0x88,0xA8,
+ 0x1B,0x6F,0x2D,0xF4,0xF2,0xC9,0x14,0x5F,0x26,0xCF,0x2C,0x8D,0x7E,0xED,0x37,0xC0,
+ 0xA9,0xD5,0x39,0xB9,0x82,0xBF,0x19,0x0C,0xEA,0x34,0xAF,0x00,0x21,0x68,0xF8,0xAD,
+ 0x73,0xE2,0xC9,0x32,0xDA,0x38,0x25,0x0B,0x55,0xD3,0x9A,0x1D,0xF0,0x68,0x86,0xED,
+ 0x2E,0x41,0x34,0xEF,0x7C,0xA5,0x50,0x1D,0xBF,0x3A,0xF9,0xD3,0xC1,0x08,0x0C,0xE6,
+ 0xED,0x1E,0x8A,0x58,0x25,0xE4,0xB8,0x77,0xAD,0x2D,0x6E,0xF5,0x52,0xDD,0xB4,0x74,
+ 0x8F,0xAB,0x49,0x2E,0x9D,0x3B,0x93,0x34,0x28,0x1F,0x78,0xCE,0x94,0xEA,0xC7,0xBD,
+ 0xD3,0xC9,0x6D,0x1C,0xDE,0x5C,0x32,0xF3,
+};
+
+/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */
+/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */
+uint8_t _digiCertGlobalRoot[] ={
+ 0x30,0x82,0x03,0xAF,0x30,0x82,0x02,0x97,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x08,
+ 0x3B,0xE0,0x56,0x90,0x42,0x46,0xB1,0xA1,0x75,0x6A,0xC9,0x59,0x91,0xC7,0x4A,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x61,
+ 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,
+ 0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,
+ 0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,0x13,0x10,0x77,
+ 0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x31,
+ 0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,0x69,0x43,0x65,
+ 0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,
+ 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x5A,0x17,0x0D,0x33,0x31,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x5A,0x30,0x61,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
+ 0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x44,0x69,0x67,0x69,0x43,
+ 0x65,0x72,0x74,0x20,0x49,0x6E,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0B,
+ 0x13,0x10,0x77,0x77,0x77,0x2E,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2E,0x63,
+ 0x6F,0x6D,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x44,0x69,0x67,
+ 0x69,0x43,0x65,0x72,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x52,0x6F,0x6F,
+ 0x74,0x20,0x43,0x41,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,0xE2,0x3B,0xE1,0x11,0x72,0xDE,0xA8,0xA4,0xD3,0xA3,0x57,
+ 0xAA,0x50,0xA2,0x8F,0x0B,0x77,0x90,0xC9,0xA2,0xA5,0xEE,0x12,0xCE,0x96,0x5B,0x01,
+ 0x09,0x20,0xCC,0x01,0x93,0xA7,0x4E,0x30,0xB7,0x53,0xF7,0x43,0xC4,0x69,0x00,0x57,
+ 0x9D,0xE2,0x8D,0x22,0xDD,0x87,0x06,0x40,0x00,0x81,0x09,0xCE,0xCE,0x1B,0x83,0xBF,
+ 0xDF,0xCD,0x3B,0x71,0x46,0xE2,0xD6,0x66,0xC7,0x05,0xB3,0x76,0x27,0x16,0x8F,0x7B,
+ 0x9E,0x1E,0x95,0x7D,0xEE,0xB7,0x48,0xA3,0x08,0xDA,0xD6,0xAF,0x7A,0x0C,0x39,0x06,
+ 0x65,0x7F,0x4A,0x5D,0x1F,0xBC,0x17,0xF8,0xAB,0xBE,0xEE,0x28,0xD7,0x74,0x7F,0x7A,
+ 0x78,0x99,0x59,0x85,0x68,0x6E,0x5C,0x23,0x32,0x4B,0xBF,0x4E,0xC0,0xE8,0x5A,0x6D,
+ 0xE3,0x70,0xBF,0x77,0x10,0xBF,0xFC,0x01,0xF6,0x85,0xD9,0xA8,0x44,0x10,0x58,0x32,
+ 0xA9,0x75,0x18,0xD5,0xD1,0xA2,0xBE,0x47,0xE2,0x27,0x6A,0xF4,0x9A,0x33,0xF8,0x49,
+ 0x08,0x60,0x8B,0xD4,0x5F,0xB4,0x3A,0x84,0xBF,0xA1,0xAA,0x4A,0x4C,0x7D,0x3E,0xCF,
+ 0x4F,0x5F,0x6C,0x76,0x5E,0xA0,0x4B,0x37,0x91,0x9E,0xDC,0x22,0xE6,0x6D,0xCE,0x14,
+ 0x1A,0x8E,0x6A,0xCB,0xFE,0xCD,0xB3,0x14,0x64,0x17,0xC7,0x5B,0x29,0x9E,0x32,0xBF,
+ 0xF2,0xEE,0xFA,0xD3,0x0B,0x42,0xD4,0xAB,0xB7,0x41,0x32,0xDA,0x0C,0xD4,0xEF,0xF8,
+ 0x81,0xD5,0xBB,0x8D,0x58,0x3F,0xB5,0x1B,0xE8,0x49,0x28,0xA2,0x70,0xDA,0x31,0x04,
+ 0xDD,0xF7,0xB2,0x16,0xF2,0x4C,0x0A,0x4E,0x07,0xA8,0xED,0x4A,0x3D,0x5E,0xB5,0x7F,
+ 0xA3,0x90,0xC3,0xAF,0x27,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0E,
+ 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,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,0x03,0xDE,0x50,0x35,0x56,0xD1,
+ 0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30,0x1F,
+ 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x03,0xDE,0x50,0x35,0x56,
+ 0xD1,0x4C,0xBB,0x66,0xF0,0xA3,0xE2,0x1B,0x1B,0xC3,0x97,0xB2,0x3D,0xD1,0x55,0x30,
+ 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,
+ 0x01,0x01,0x00,0xCB,0x9C,0x37,0xAA,0x48,0x13,0x12,0x0A,0xFA,0xDD,0x44,0x9C,0x4F,
+ 0x52,0xB0,0xF4,0xDF,0xAE,0x04,0xF5,0x79,0x79,0x08,0xA3,0x24,0x18,0xFC,0x4B,0x2B,
+ 0x84,0xC0,0x2D,0xB9,0xD5,0xC7,0xFE,0xF4,0xC1,0x1F,0x58,0xCB,0xB8,0x6D,0x9C,0x7A,
+ 0x74,0xE7,0x98,0x29,0xAB,0x11,0xB5,0xE3,0x70,0xA0,0xA1,0xCD,0x4C,0x88,0x99,0x93,
+ 0x8C,0x91,0x70,0xE2,0xAB,0x0F,0x1C,0xBE,0x93,0xA9,0xFF,0x63,0xD5,0xE4,0x07,0x60,
+ 0xD3,0xA3,0xBF,0x9D,0x5B,0x09,0xF1,0xD5,0x8E,0xE3,0x53,0xF4,0x8E,0x63,0xFA,0x3F,
+ 0xA7,0xDB,0xB4,0x66,0xDF,0x62,0x66,0xD6,0xD1,0x6E,0x41,0x8D,0xF2,0x2D,0xB5,0xEA,
+ 0x77,0x4A,0x9F,0x9D,0x58,0xE2,0x2B,0x59,0xC0,0x40,0x23,0xED,0x2D,0x28,0x82,0x45,
+ 0x3E,0x79,0x54,0x92,0x26,0x98,0xE0,0x80,0x48,0xA8,0x37,0xEF,0xF0,0xD6,0x79,0x60,
+ 0x16,0xDE,0xAC,0xE8,0x0E,0xCD,0x6E,0xAC,0x44,0x17,0x38,0x2F,0x49,0xDA,0xE1,0x45,
+ 0x3E,0x2A,0xB9,0x36,0x53,0xCF,0x3A,0x50,0x06,0xF7,0x2E,0xE8,0xC4,0x57,0x49,0x6C,
+ 0x61,0x21,0x18,0xD5,0x04,0xAD,0x78,0x3C,0x2C,0x3A,0x80,0x6B,0xA7,0xEB,0xAF,0x15,
+ 0x14,0xE9,0xD8,0x89,0xC1,0xB9,0x38,0x6C,0xE2,0x91,0x6C,0x8A,0xFF,0x64,0xB9,0x77,
+ 0x25,0x57,0x30,0xC0,0x1B,0x24,0xA3,0xE1,0xDC,0xE9,0xDF,0x47,0x7C,0xB5,0xB4,0x24,
+ 0x08,0x05,0x30,0xEC,0x2D,0xBD,0x0B,0xBF,0x45,0xBF,0x50,0xB9,0xA9,0xF3,0xEB,0x98,
+ 0x01,0x12,0xAD,0xC8,0x88,0xC6,0x98,0x34,0x5F,0x8D,0x0A,0x3C,0xC6,0xE9,0xD5,0x95,
+ 0x95,0x6D,0xDE,
+};
+
+uint8_t _digicertOCSPResponse[] = {
+ 0x30,0x82,0x01,0xe6,0x0a,0x01,0x00,0xa0,0x82,0x01,0xdf,0x30,0x82,0x01,0xdb,0x06,0x09,0x2b,0x06,0x01,
+ 0x05,0x05,0x07,0x30,0x01,0x01,0x04,0x82,0x01,0xcc,0x30,0x82,0x01,0xc8,0x30,0x81,0xb1,0xa2,0x16,0x04,
+ 0x14,0x0f,0x80,0x61,0x1c,0x82,0x31,0x61,0xd5,0x2f,0x28,0xe7,0x8d,0x46,0x38,0xb4,0x2c,0xe1,0xc6,0xd9,
+ 0xe2,0x18,0x0f,0x32,0x30,0x31,0x38,0x30,0x34,0x32,0x35,0x31,0x37,0x34,0x37,0x34,0x33,0x5a,0x30,0x81,
+ 0x85,0x30,0x81,0x82,0x30,0x49,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14,0x10,
+ 0x5f,0xa6,0x7a,0x80,0x08,0x9d,0xb5,0x27,0x9f,0x35,0xce,0x83,0x0b,0x43,0x88,0x9e,0xa3,0xc7,0x0d,0x04,
+ 0x14,0x0f,0x80,0x61,0x1c,0x82,0x31,0x61,0xd5,0x2f,0x28,0xe7,0x8d,0x46,0x38,0xb4,0x2c,0xe1,0xc6,0xd9,
+ 0xe2,0x02,0x10,0x01,0xaf,0x1e,0xfb,0xdd,0x5e,0xae,0x09,0x52,0x32,0x0b,0x24,0xfe,0x6b,0x55,0x68,0xa1,
+ 0x11,0x18,0x0f,0x32,0x30,0x31,0x36,0x30,0x39,0x30,0x32,0x32,0x31,0x32,0x38,0x34,0x38,0x5a,0x18,0x0f,
+ 0x32,0x30,0x31,0x38,0x30,0x34,0x32,0x35,0x31,0x37,0x34,0x37,0x34,0x33,0x5a,0xa0,0x11,0x18,0x0f,0x32,
+ 0x30,0x31,0x38,0x30,0x35,0x30,0x32,0x31,0x37,0x30,0x32,0x34,0x33,0x5a,0x30,0x0d,0x06,0x09,0x2a,0x86,
+ 0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x9c,0x3d,0xb9,0xc6,0xfd,0x97,
+ 0x21,0xb0,0x04,0xc1,0x62,0x4b,0xc7,0x74,0x7a,0x37,0x01,0xa6,0x22,0xb2,0xd2,0xce,0xbb,0xd4,0x67,0xcd,
+ 0xda,0x66,0xb6,0x53,0xbc,0x81,0xd4,0x09,0x9c,0xa0,0x3e,0x95,0x6d,0x90,0x0a,0xe6,0x39,0x24,0xb0,0x42,
+ 0x17,0xc1,0x02,0x62,0x57,0xc8,0x04,0x07,0x66,0x1f,0xc4,0x75,0x75,0xe6,0x82,0x7e,0xd3,0x28,0x46,0xde,
+ 0xaa,0xb8,0xd7,0x2d,0xd5,0x17,0x70,0xb7,0xbf,0xd6,0xcc,0xa3,0x14,0xe9,0x5f,0x9d,0x40,0xf2,0x5f,0x29,
+ 0xb2,0xde,0x8a,0x9f,0x02,0x79,0x2a,0xe9,0xa0,0xc0,0x0f,0xb1,0xc3,0xf8,0xaa,0xb1,0x9d,0xaf,0x15,0x78,
+ 0xf1,0x98,0x6c,0xd2,0xf2,0x1f,0x8d,0x75,0xd4,0xb6,0x91,0xc4,0xb8,0x13,0x18,0xd2,0x30,0xa1,0xb1,0x1e,
+ 0x81,0x1a,0xef,0x2a,0x42,0x52,0x2a,0xd4,0xec,0xc5,0x8a,0x87,0x9c,0x7b,0x38,0x81,0xf9,0x6e,0xfe,0x60,
+ 0x3d,0xc7,0xfe,0x77,0x64,0x99,0x3d,0x1c,0xf5,0x92,0xe9,0xe5,0x45,0xf3,0x7e,0x98,0x74,0xfa,0x5a,0xd9,
+ 0xf4,0x79,0xf3,0xf7,0x6c,0x99,0xce,0x52,0x47,0xc0,0x4a,0x87,0x20,0xed,0x3b,0x76,0x2a,0x58,0x3f,0x8b,
+ 0xb3,0xcb,0x9f,0xd4,0x11,0x26,0xc4,0x43,0xce,0xd1,0x6f,0x48,0xe4,0xd0,0x2f,0xa1,0x95,0x5a,0xb9,0x93,
+ 0x25,0xf9,0xd4,0x1a,0xe9,0x75,0x7d,0xcf,0xfb,0xc5,0xa5,0x78,0x98,0x68,0xfb,0x12,0xbd,0x53,0xdc,0x98,
+ 0x1d,0xd6,0xc7,0xa1,0x28,0x3f,0x5b,0x82,0x39,0x18,0x85,0xfd,0x91,0x8f,0x80,0xa2,0x30,0xd9,0xee,0xc4,
+ 0x23,0x48,0x3c,0x50,0x18,0x7e,0xc7,0x1d,0xc1,0x5a
+};
+
+uint8_t _caissuer_https[] = {
+ 0x30,0x82,0x04,0x68,0x30,0x82,0x03,0x50,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x7A,
+ 0x22,0xA1,0x88,0x18,0x9E,0x75,0x77,0xE6,0xEF,0x7E,0xC0,0x33,0x8E,0xE8,0x90,0xE8,
+ 0x7B,0xC4,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,
+ 0x00,0x30,0x81,0x81,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,0x15,
+ 0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,
+ 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x34,0x32,0x38,0x32,
+ 0x30,0x32,0x31,0x34,0x31,0x5A,0x17,0x0D,0x31,0x39,0x30,0x34,0x32,0x38,0x32,0x30,
+ 0x32,0x31,0x34,0x31,0x5A,0x30,0x81,0x8D,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,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x0C,0x18,0x48,0x54,0x54,
+ 0x50,0x53,0x20,0x43,0x41,0x49,0x73,0x73,0x75,0x65,0x72,0x20,0x54,0x65,0x73,0x74,
+ 0x20,0x43,0x65,0x72,0x74,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,0xC1,0x68,0xC2,0x47,0x1E,0x07,0x82,0x66,0x47,0xC9,
+ 0x5C,0x22,0xDD,0x8B,0x93,0x6A,0xA7,0x22,0x00,0xB8,0xDA,0x8C,0x3C,0x52,0xA7,0x47,
+ 0x73,0xBB,0x7A,0xD7,0x8C,0x1E,0xAE,0xDA,0x34,0x25,0x4E,0xEB,0x1F,0x33,0x0B,0x8A,
+ 0xC7,0x6D,0x2A,0x93,0xDB,0x0D,0xD0,0x47,0x85,0x9C,0x14,0xD5,0x23,0xE3,0xE4,0x94,
+ 0xE0,0x17,0x9F,0x56,0x64,0x8E,0xE0,0x08,0xE9,0x1B,0x4C,0x7C,0x77,0xF9,0x35,0x74,
+ 0x52,0x43,0x90,0x13,0xFA,0x51,0x9A,0xA2,0x93,0x47,0x94,0xE7,0xBD,0x07,0xE5,0xFB,
+ 0x67,0x8B,0xF0,0xE2,0x0C,0x97,0xFD,0x29,0x51,0xBD,0x85,0x6C,0xBE,0x36,0xFD,0xDD,
+ 0xCC,0x99,0x4D,0x68,0x37,0x96,0xB2,0x20,0x85,0x55,0xA5,0x99,0xA4,0x7E,0xD7,0x19,
+ 0x06,0x15,0x20,0x10,0x50,0x51,0x2E,0x74,0x5C,0x43,0x49,0x94,0x6B,0x0E,0x9E,0xFB,
+ 0xDF,0xB2,0xEB,0xD9,0x28,0xA8,0xF1,0x25,0x49,0xC8,0xFE,0x3B,0xE1,0x45,0x95,0x47,
+ 0xD1,0x53,0xCD,0x34,0x9A,0x6F,0xC4,0x3F,0x63,0xC2,0x60,0xC6,0x40,0xBB,0xF7,0x20,
+ 0x8A,0xB8,0xB7,0xD7,0xC2,0xBB,0x48,0x24,0x64,0xA2,0x4A,0xE4,0x2A,0x17,0x68,0xE2,
+ 0xAC,0x47,0x2D,0xCC,0xBD,0xB7,0xCE,0x73,0xDF,0x96,0x8C,0x12,0x56,0xE3,0x29,0xE3,
+ 0x4D,0xB4,0x55,0x28,0xAB,0x28,0x24,0x45,0x7F,0x55,0x66,0xCD,0x46,0x29,0x89,0x58,
+ 0xFF,0xA6,0xD1,0x67,0xAC,0x50,0xEE,0x55,0x6D,0x6A,0x2A,0xCF,0xD6,0x09,0xE9,0xDA,
+ 0x22,0xB0,0xAF,0x90,0xD7,0x02,0xB2,0xCE,0x5F,0x09,0x96,0x5E,0x88,0xAE,0xB5,0xB6,
+ 0xA1,0xC3,0x9D,0x1A,0x2F,0x2D,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xCA,0x30,0x81,
+ 0xC7,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,0x30,
+ 0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,
+ 0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,
+ 0x05,0x07,0x03,0x01,0x30,0x16,0x06,0x03,0x55,0x1D,0x11,0x04,0x0F,0x30,0x0D,0x82,
+ 0x0B,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1D,0x06,0x03,
+ 0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xDF,0xC7,0x68,0x26,0x64,0x95,0x5D,0x73,0x36,
+ 0x84,0xE8,0xE3,0x1D,0xC8,0x28,0x5E,0xA8,0x27,0x73,0x8C,0x30,0x1F,0x06,0x03,0x55,
+ 0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xB5,0xA9,0x53,0x08,0x10,0x38,0x1A,0xA5,
+ 0xB3,0x84,0xC9,0xEE,0xC4,0xAB,0x0F,0xB8,0x5F,0x68,0x10,0xA2,0x30,0x3A,0x06,0x08,
+ 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x2E,0x30,0x2C,0x30,0x2A,0x06,0x08,
+ 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x1E,0x68,0x74,0x74,0x70,0x73,0x3A,
+ 0x2F,0x2F,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x74,0x65,
+ 0x73,0x74,0x43,0x41,0x2E,0x64,0x65,0x72,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+ 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC4,0x48,0xDF,0x5E,
+ 0x73,0xD1,0x43,0x28,0x7D,0x69,0x71,0x32,0x1F,0xCC,0x1A,0xEB,0x5B,0x98,0x9D,0xCE,
+ 0xFF,0xCA,0x16,0xA9,0x96,0xE7,0x4D,0xC4,0xAE,0x53,0xE2,0x5D,0xDB,0xDA,0x40,0x80,
+ 0xE5,0xFB,0xF3,0xD7,0x21,0x9A,0x77,0x1D,0x67,0xFC,0x04,0x62,0x18,0xFF,0x10,0x59,
+ 0xF4,0xDD,0xF4,0xC6,0x8F,0xB4,0xEF,0x9F,0x05,0xA6,0xF1,0xCB,0x44,0x24,0x02,0x19,
+ 0x75,0xF9,0x3C,0x28,0x8A,0xAA,0x57,0x6B,0xFF,0x64,0xFF,0xD7,0xE2,0x62,0x67,0x70,
+ 0x20,0x4D,0xAE,0xD2,0x67,0xED,0x92,0xA4,0xFA,0x8A,0xC3,0x24,0x9C,0x2F,0x4D,0x2C,
+ 0xA9,0xA5,0x92,0x5E,0x5C,0x6F,0xDB,0xAB,0x96,0xA6,0xB1,0x5B,0xF1,0x8D,0x97,0x08,
+ 0xBC,0x5B,0x27,0xD5,0x9E,0x2D,0xF0,0x49,0x68,0xA6,0x92,0x00,0x13,0xAD,0x60,0x9E,
+ 0x78,0x72,0xC2,0x18,0xB8,0xE5,0x9D,0x72,0xA5,0x87,0x61,0xA8,0x95,0x8A,0x2B,0xB2,
+ 0xCC,0xCA,0x7F,0x1E,0x1E,0xC5,0xFB,0x5A,0x0C,0x77,0x17,0xB0,0xBE,0x7B,0x5A,0x50,
+ 0x05,0x32,0x40,0x98,0x3A,0x8B,0x22,0x3F,0x3B,0xA5,0xA8,0xA9,0x59,0x3B,0x55,0x92,
+ 0xD1,0x8A,0x34,0x73,0xA6,0xD6,0x5D,0x5E,0x85,0x59,0x00,0xD5,0x55,0x94,0x80,0xC1,
+ 0xB9,0xF1,0xCA,0x2B,0xC5,0x96,0xEE,0x49,0x6A,0x2C,0xDD,0x62,0x98,0xB3,0x74,0x09,
+ 0x09,0xDE,0x3D,0x59,0x5B,0x21,0x76,0x6E,0x27,0x66,0xED,0x7B,0x74,0x7F,0xE7,0xA9,
+ 0xAE,0xEB,0x40,0x83,0xB9,0xBC,0xE6,0x0C,0x1E,0x53,0xB2,0xEA,0x79,0xC4,0xA9,0x30,
+ 0x2B,0x1F,0xC4,0x34,0x82,0x3E,0xFC,0x1E,0x2D,0x66,0x75,0xD0,
+};
+
+#endif /* _SECURITY_SI_23_SECTRUST_OCSP_H_ */
cert0,
cert1
};
- SecPolicyRef policy = SecPolicyCreateSSL(false, CFSTR("store.apple.com"));
+ SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("store.apple.com"));
CFArrayRef certs = CFArrayCreate(NULL, v_certs,
array_size(v_certs), NULL);
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
CFReleaseNull(trust);
CFReleaseNull(policy);
- policy = SecPolicyCreateSSL(false, CFSTR("badstore.apple.com"));
+ policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust with hostname mismatch");
ok_status(SecTrustSetVerifyDate(trust, date), "set date");
ok(SecTrustSetExceptions(trust, exceptions), "set old exceptions");
CFReleaseNull(trust);
CFReleaseNull(policy);
- policy = SecPolicyCreateSSL(false, CFSTR("self-signed.ssltest.apple.com"));
+ policy = SecPolicyCreateSSL(true, CFSTR("self-signed.ssltest.apple.com"));
ok_status(SecTrustCreateWithCertificates(sscert0, policy, &trust), "create trust");
ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
/* Of course, the interface is different for OS X and iOS. */
/* each call is 1 test */
+#define kNumberSetTSTests 1
#if TARGET_OS_IPHONE
#define setTS(cert, settings) \
{ \
#endif
/* each call is 1 test */
+#define kNumberRemoveTSTests 1
#if TARGET_OS_IPHONE
#define removeTS(cert) \
{ \
#endif
/* each call is 4 tests */
+#define kNumberCheckTrustTests 4
#define check_trust(certs, policy, valid_date, expected) \
{ \
SecTrustRef trust = NULL; \
}
-#define kNumberPolicyNamePinnningConstraintsTests (1 + 1 + 5)
+#define kNumberChangeConstraintsTests (2*kNumberSetTSTests + kNumberRemoveTSTests + 4*kNumberCheckTrustTests)
+static void test_change_constraints(void) {
+ /* allow all but */
+ NSArray *allowAllBut = @[
+ @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
+ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
+ @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
+ ];
+ setTS(cert0, (__bridge CFArrayRef)allowAllBut);
+ check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
+ check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
+
+ /* Don't clear trust settings. Just change them. */
+
+ /* root with the default TrustRoot result succeeds */
+ setTS(cert0, NULL);
+ check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
+ check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
+ removeTS(cert0);
+}
+
+#define kNumberPolicyNamePinnningConstraintsTests (kNumberSetTSTests + kNumberRemoveTSTests + 5)
static void test_policy_name_pinning_constraints(void) {
/* allow all but */
NSArray *allowAllBut = @[
+ kNumberKeyUsageConstraintsTests
+ kNumberAllowedErrorsTests
+ kNumberMultipleConstraintsTests
+ + kNumberChangeConstraintsTests
+ kNumberPolicyNamePinnningConstraintsTests
);
test_key_usage_constraints();
test_allowed_errors();
test_multiple_constraints();
+ test_change_constraints();
test_policy_name_pinning_constraints();
cleanup_globals();
}
is(trustResult, kSecTrustResultUnspecified, "accept test: app-trusted SHA-1 SSL server");
/* SHA1 cert from system root passes SSL client */
- clientPolicy = SecPolicyCreateSSL(false, CFSTR("www.badssl.com"));
+ clientPolicy = SecPolicyCreateSSL(false, NULL);
setTrust(&trust, sha1_certs, clientPolicy);
require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust");
is(trustResult, kSecTrustResultUnspecified, "accept test: system-trusted SHA-1 SSL client");
--- /dev/null
+/*
+ * Copyright (c) 2018 Apple Inc. All Rights Reserved.
+ */
+
+#ifndef si_34_cms_timestamp_h
+#define si_34_cms_timestamp_h
+
+/* MARK: Mismatched timestamp
+ * The MessageImprint in the timestamp of this CMS blob does not match the countersigned SignerInfo
+ * that contains the timestamp.
+ */
+uint8_t _mismatched_content[] = {
+ 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x0a
+};
+
+uint8_t _mismatched_timestamp[] = {
+ 0x30, 0x82, 0x21, 0x6c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x21, 0x5d, 0x30,
+ 0x82, 0x21, 0x59, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
+ 0x01, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x0e, 0xc1, 0x30, 0x82,
+ 0x05, 0x69, 0x30, 0x82, 0x04, 0x51, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x00, 0xe3, 0xd3, 0xe8, 0xe4, 0xcc, 0xd6,
+ 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x71, 0x31, 0x2b,
+ 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+ 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d,
+ 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 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, 0x38, 0x30, 0x31, 0x32,
+ 0x39, 0x32, 0x32, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x31, 0x32, 0x37, 0x32, 0x32, 0x33, 0x35,
+ 0x35, 0x32, 0x5a, 0x30, 0x3c, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x63, 0x73, 0x73, 0x73,
+ 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x30, 0x30, 0x33, 0x74, 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, 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, 0xe9, 0xad,
+ 0x73, 0xbc, 0xa2, 0x60, 0x1a, 0x44, 0x1d, 0x16, 0x2b, 0x21, 0x23, 0xdf, 0xe8, 0x1e, 0x74, 0xc2, 0xe8, 0x14, 0xb3, 0x60,
+ 0x17, 0x02, 0x8a, 0x54, 0xbf, 0xfd, 0x3e, 0x77, 0x7b, 0xdc, 0x55, 0x49, 0xd7, 0x05, 0x33, 0x6a, 0xd8, 0x4d, 0xa8, 0x2b,
+ 0xa1, 0xfd, 0xeb, 0xdf, 0xb6, 0xd5, 0x7b, 0x1a, 0x15, 0x02, 0xa3, 0x41, 0xc0, 0x71, 0x12, 0x13, 0x72, 0xe1, 0x8f, 0x23,
+ 0x65, 0x18, 0xde, 0x7f, 0x66, 0x7c, 0x49, 0x5d, 0x78, 0x75, 0xd7, 0xf6, 0xe2, 0x7c, 0x8c, 0x8d, 0xf6, 0xc7, 0x6d, 0x83,
+ 0x9e, 0xd9, 0x8b, 0xef, 0xd3, 0xb2, 0xab, 0x31, 0x19, 0x7f, 0xd1, 0x95, 0x0e, 0xaf, 0xe6, 0x16, 0xb8, 0x43, 0x23, 0xa5,
+ 0x93, 0xc4, 0x0f, 0x8f, 0xde, 0xf3, 0x38, 0xf6, 0x53, 0xbc, 0xdd, 0x5c, 0x3a, 0x5b, 0x06, 0x5e, 0xf1, 0x68, 0x82, 0x2e,
+ 0xee, 0x29, 0x5d, 0xfa, 0x3f, 0x0f, 0x06, 0xfa, 0xef, 0x8b, 0x54, 0x26, 0xc9, 0xd7, 0xff, 0x92, 0x4f, 0x13, 0x19, 0x6e,
+ 0x5b, 0x6f, 0x73, 0x58, 0x8e, 0x5d, 0xc1, 0xdf, 0x23, 0xe1, 0x27, 0xb9, 0x16, 0xd2, 0xe5, 0x67, 0x07, 0xc5, 0xcc, 0xe4,
+ 0xbe, 0xa6, 0xda, 0xfa, 0x37, 0xe6, 0xe1, 0xe1, 0xba, 0x05, 0x68, 0x84, 0xe3, 0xa2, 0xd9, 0xa9, 0x43, 0x93, 0x8b, 0xaa,
+ 0xd7, 0xc6, 0x98, 0x75, 0xde, 0xb2, 0xfe, 0x2c, 0x28, 0xbf, 0x58, 0x92, 0x60, 0xe5, 0xbc, 0xda, 0x0b, 0xc4, 0x5b, 0x8c,
+ 0x87, 0x45, 0xad, 0x62, 0x8c, 0x10, 0x6a, 0x31, 0x77, 0x4e, 0x48, 0xc0, 0x76, 0x79, 0x29, 0x91, 0xb3, 0x66, 0x82, 0xeb,
+ 0xb2, 0x35, 0xd1, 0xc3, 0x5a, 0x2b, 0x13, 0xda, 0x24, 0xf7, 0xa8, 0xad, 0xb7, 0xd2, 0xaf, 0x98, 0xa1, 0x93, 0x43, 0x9a,
+ 0x07, 0xf8, 0xb5, 0xce, 0xe5, 0x1c, 0xc9, 0x46, 0x63, 0x50, 0x79, 0xa5, 0x1e, 0x1f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+ 0x82, 0x02, 0x38, 0x30, 0x82, 0x02, 0x34, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+ 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d,
+ 0x92, 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 0x30, 0x56, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x4a, 0x30, 0x48, 0x30, 0x46, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x01, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x75, 0x61, 0x74, 0x2e,
+ 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30,
+ 0x33, 0x2d, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67, 0x32,
+ 0x30, 0x31, 0x30, 0x82, 0x01, 0x03, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x81, 0xfb, 0x30, 0x81, 0xf8, 0x30, 0x81, 0xf5,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xe7, 0x30, 0x81, 0xac, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0x9f, 0x0c, 0x81, 0x9c, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63,
+ 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, 0x73, 0x75,
+ 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x65, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73,
+ 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61,
+ 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x30, 0x36, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+ 0x01, 0x16, 0x2a, 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, 0x2f, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0d, 0x30, 0x0b, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x42, 0x30,
+ 0x40, 0x30, 0x3e, 0xa0, 0x3c, 0xa0, 0x3a, 0x86, 0x38, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2d,
+ 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74,
+ 0x65, 0x73, 0x74, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67,
+ 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3,
+ 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b, 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x11, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x63, 0x64, 0x06, 0x01, 0x1d, 0x02, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0xbe, 0xc8, 0x17, 0x96, 0xe9, 0x50, 0x1e, 0xfa,
+ 0xfb, 0xa8, 0x99, 0x83, 0xc4, 0x68, 0x3a, 0xc5, 0xb7, 0x80, 0x7a, 0xb0, 0x59, 0x6c, 0xb6, 0x0c, 0xb1, 0xee, 0x40, 0x9a,
+ 0x18, 0x11, 0x45, 0x16, 0x97, 0xad, 0xd7, 0xe5, 0x10, 0xa2, 0x1f, 0x3c, 0xdd, 0x63, 0xcb, 0xc9, 0x72, 0xd3, 0x6e, 0x72,
+ 0x4d, 0x90, 0xc4, 0xb2, 0x16, 0x95, 0x16, 0x1c, 0x12, 0x2a, 0xd0, 0xb6, 0x65, 0x4c, 0x54, 0x7e, 0xe0, 0xa6, 0xb7, 0x06,
+ 0x85, 0x07, 0xac, 0x3f, 0x05, 0x51, 0xcb, 0xd5, 0x20, 0x6a, 0x47, 0x16, 0xb9, 0x6e, 0xd3, 0x93, 0xa1, 0xd6, 0xbc, 0xe2,
+ 0x15, 0x25, 0x0b, 0x7c, 0xc1, 0x72, 0xcd, 0xee, 0x64, 0xbe, 0x5f, 0x4e, 0xb4, 0xf5, 0x1d, 0x6d, 0x6c, 0xc5, 0x37, 0xf6,
+ 0xb8, 0xb3, 0xfc, 0xc2, 0x41, 0x01, 0x79, 0x0c, 0x68, 0x2b, 0x24, 0x86, 0xe8, 0x6f, 0x55, 0x19, 0x59, 0x69, 0xa2, 0x36,
+ 0x01, 0x80, 0x22, 0x78, 0xad, 0xe6, 0xd8, 0xe9, 0xa8, 0x98, 0x75, 0xc7, 0xe8, 0x10, 0x37, 0x7c, 0x8a, 0x80, 0x06, 0xbf,
+ 0x24, 0xfb, 0xd6, 0xc0, 0x9f, 0xa3, 0x26, 0x7a, 0xee, 0x92, 0xbe, 0xea, 0x7a, 0x18, 0x88, 0x2a, 0xdf, 0xc5, 0x85, 0x1d,
+ 0x8a, 0x18, 0x66, 0xa9, 0xd5, 0xe5, 0x76, 0x23, 0xc0, 0x47, 0x4f, 0xc2, 0xb9, 0x6a, 0x46, 0x21, 0x8c, 0x6a, 0xd6, 0x95,
+ 0x04, 0x7d, 0x06, 0xa1, 0x91, 0xf5, 0x0c, 0x77, 0x9b, 0xb4, 0xbb, 0x21, 0xc6, 0xc0, 0x63, 0x5b, 0xe3, 0x47, 0x65, 0x71,
+ 0xe5, 0x55, 0x89, 0x17, 0xa9, 0x73, 0x70, 0xd0, 0xdf, 0x43, 0x9d, 0xfc, 0x1d, 0xb1, 0x6f, 0x73, 0x83, 0xd5, 0x89, 0x34,
+ 0xf6, 0x00, 0xa7, 0x87, 0x7d, 0x7b, 0x91, 0xc2, 0x15, 0x18, 0x38, 0x97, 0x7f, 0x81, 0x63, 0x34, 0x64, 0xaa, 0xa4, 0x00,
+ 0x40, 0x29, 0xbe, 0xfd, 0x96, 0x14, 0xfa, 0x30, 0x82, 0x04, 0x80, 0x30, 0x82, 0x03, 0x68, 0xa0, 0x03, 0x02, 0x01, 0x02,
+ 0x02, 0x08, 0x30, 0x0c, 0x95, 0xe4, 0x78, 0x4f, 0xf3, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70,
+ 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, 0x30, 0x39,
+ 0x32, 0x32, 0x30, 0x36, 0x31, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x5a, 0x30, 0x71, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20,
+ 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17,
+ 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, 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, 0xd9, 0xdc, 0x8b, 0xf5, 0x7a, 0x4e, 0xb8, 0xcb, 0xee, 0x25,
+ 0xb2, 0xd6, 0x6a, 0x36, 0x16, 0xd6, 0xf6, 0xdf, 0x9d, 0xd6, 0xcc, 0x65, 0xf3, 0xf4, 0x89, 0xb2, 0x06, 0x3e, 0x41, 0xfd,
+ 0xc2, 0xf8, 0x5a, 0x7b, 0x16, 0x90, 0x03, 0x9a, 0x60, 0x7c, 0xb0, 0x93, 0x1e, 0x20, 0xc0, 0x8a, 0xce, 0x13, 0x08, 0xd5,
+ 0x2e, 0x4d, 0x88, 0xd1, 0x10, 0xdc, 0xef, 0xc1, 0x62, 0x50, 0x5a, 0x8b, 0x77, 0x2e, 0x4f, 0x53, 0xa1, 0x0a, 0x0f, 0xb3,
+ 0xb1, 0xd2, 0x00, 0xd6, 0x6b, 0x6f, 0xa0, 0x20, 0x52, 0xe7, 0x91, 0x4e, 0x9e, 0xd0, 0x85, 0xa6, 0xcd, 0x76, 0x1a, 0xd0,
+ 0x58, 0x2a, 0x1d, 0xa2, 0x9b, 0xd4, 0xf7, 0xae, 0x05, 0xe7, 0x0a, 0xab, 0xd6, 0x0f, 0x74, 0x29, 0x5b, 0x88, 0x46, 0xc4,
+ 0x6b, 0x73, 0x4d, 0x56, 0x9d, 0x91, 0xb6, 0x11, 0xc5, 0xab, 0xc0, 0xc7, 0x19, 0x1d, 0x78, 0xe4, 0xa9, 0x2f, 0x8e, 0x0b,
+ 0x7f, 0x97, 0x85, 0x3a, 0x61, 0x32, 0x1d, 0x94, 0x59, 0x59, 0x30, 0xe6, 0xf7, 0xbc, 0x33, 0x74, 0x74, 0x54, 0x6e, 0xe8,
+ 0x90, 0xc9, 0xb4, 0xc6, 0x9a, 0xb7, 0x44, 0x02, 0xd7, 0x95, 0x60, 0x72, 0x4c, 0xe2, 0x8f, 0xe9, 0xf8, 0x53, 0x44, 0xd2,
+ 0x1a, 0x15, 0xac, 0x14, 0xe8, 0x93, 0x9c, 0xe6, 0xd8, 0xf1, 0xa3, 0xc1, 0x59, 0x29, 0x6f, 0x92, 0xb4, 0x53, 0xf4, 0x68,
+ 0x47, 0x9b, 0x81, 0xcf, 0xfc, 0x7c, 0xe8, 0x65, 0x6c, 0xcd, 0x54, 0x44, 0x80, 0x87, 0xef, 0x45, 0x07, 0x98, 0x82, 0x1d,
+ 0x07, 0x9b, 0xf2, 0x1f, 0xcc, 0x22, 0x81, 0x98, 0x18, 0xbf, 0x4c, 0x14, 0xb3, 0x2c, 0xa7, 0xae, 0x00, 0x9a, 0x7a, 0x3c,
+ 0x1e, 0xd1, 0x0d, 0xef, 0xeb, 0x95, 0xba, 0xd4, 0xd4, 0x8d, 0x75, 0x0f, 0xa0, 0x00, 0x01, 0x64, 0x98, 0x49, 0x17, 0x2b,
+ 0xe3, 0xfb, 0xeb, 0x3e, 0x4d, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x24, 0x30, 0x82, 0x01, 0x20, 0x30,
+ 0x51, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x35, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
+ 0x2d, 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x30, 0x33, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f, 0x6f, 0x74,
+ 0x63, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d, 0x92,
+ 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 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, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59,
+ 0xc3, 0x54, 0x98, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33,
+ 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2d, 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72,
+ 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c,
+ 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0d, 0x30, 0x0b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
+ 0x06, 0x02, 0x13, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0x1b, 0x61, 0x6c, 0x35, 0xb9, 0x13, 0xb9, 0xb9, 0xac, 0xdc, 0x31, 0x8a,
+ 0x9c, 0x09, 0xb0, 0x5a, 0xe4, 0x63, 0x07, 0x0e, 0x74, 0xeb, 0xe8, 0x37, 0x28, 0x62, 0x39, 0xdb, 0x25, 0xbe, 0x6c, 0xff,
+ 0xea, 0x1b, 0xd4, 0x3f, 0x50, 0x23, 0xbd, 0xa6, 0x91, 0x1c, 0xfe, 0x9c, 0x2f, 0x52, 0xb6, 0x67, 0x2b, 0xf1, 0x7a, 0x9c,
+ 0xd8, 0x66, 0x6c, 0x07, 0xeb, 0x11, 0x88, 0x68, 0x66, 0x2b, 0xb6, 0xd0, 0x72, 0xdb, 0xcc, 0x3a, 0xa8, 0xb8, 0xb8, 0x1f,
+ 0xd0, 0x05, 0xaa, 0xb3, 0xb2, 0x7b, 0xc1, 0xa9, 0xfe, 0x5e, 0xd3, 0x1b, 0xfb, 0x88, 0xba, 0x60, 0xbe, 0x1e, 0xb1, 0x63,
+ 0x8a, 0xae, 0x21, 0x35, 0xc6, 0xc0, 0x42, 0xe0, 0xa3, 0x1a, 0xc3, 0x37, 0x25, 0x5c, 0xc5, 0xca, 0x35, 0x65, 0x4d, 0x6d,
+ 0x9c, 0x13, 0x69, 0xb5, 0xde, 0x07, 0x4c, 0xf8, 0x54, 0x96, 0x9a, 0x60, 0x94, 0xca, 0x1d, 0xa3, 0xb7, 0xf6, 0x49, 0x86,
+ 0x26, 0x06, 0xa8, 0x6a, 0x70, 0x22, 0x54, 0x4a, 0xd4, 0xfd, 0xd8, 0x2d, 0xae, 0xc1, 0x35, 0x42, 0xac, 0x50, 0x03, 0xe3,
+ 0x34, 0xd7, 0x52, 0xb5, 0x9e, 0xeb, 0xb6, 0x41, 0x98, 0x0b, 0xdd, 0xec, 0xf9, 0x7e, 0x5a, 0x55, 0xd2, 0xf5, 0x4c, 0xb5,
+ 0x78, 0x1a, 0xd8, 0x23, 0x31, 0xff, 0x67, 0x7e, 0x7f, 0x05, 0xd6, 0x20, 0x7f, 0xe4, 0x34, 0xd4, 0xd3, 0x8e, 0x8d, 0x75,
+ 0xe1, 0x8c, 0xf1, 0x60, 0x26, 0x4b, 0x88, 0x87, 0x6b, 0xbd, 0x88, 0x1d, 0xe2, 0xa6, 0x9b, 0xbf, 0x4d, 0xed, 0xd7, 0x31,
+ 0x13, 0x8f, 0xa0, 0x64, 0x63, 0x27, 0xbc, 0x06, 0xce, 0x9d, 0x91, 0xa4, 0x8d, 0xd3, 0x10, 0x25, 0x0c, 0xe7, 0xac, 0xef,
+ 0x7f, 0x21, 0xf1, 0xfb, 0xca, 0x80, 0x28, 0x0c, 0x4a, 0xd4, 0x52, 0x61, 0xbc, 0x7c, 0x3b, 0x88, 0x54, 0x16, 0x0e, 0x5f,
+ 0x14, 0x99, 0x4f, 0x30, 0x82, 0x04, 0xcc, 0x30, 0x82, 0x03, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x3d, 0x00,
+ 0x4b, 0x90, 0x3e, 0xde, 0xe0, 0xd0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+ 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30,
+ 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52,
+ 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x32, 0x30, 0x32, 0x31, 0x35,
+ 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x67,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+ 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+ 0x20, 0x43, 0x41, 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, 0xc7, 0xd1, 0x43, 0x53,
+ 0x7f, 0x0d, 0x88, 0x6b, 0xe6, 0xb1, 0x67, 0x9d, 0xee, 0x67, 0xb6, 0xe7, 0x77, 0x12, 0x81, 0xc4, 0xdf, 0x24, 0x6b, 0x7a,
+ 0x75, 0x24, 0xf7, 0x01, 0x09, 0xce, 0x34, 0x92, 0xf5, 0x38, 0x08, 0x42, 0x7e, 0xec, 0x9d, 0xf2, 0x5d, 0x38, 0x91, 0xb4,
+ 0x93, 0x98, 0x35, 0x11, 0x3c, 0x98, 0x00, 0x77, 0xd9, 0xd7, 0xf3, 0x4a, 0xf8, 0xf0, 0xbc, 0xeb, 0x97, 0x5d, 0x4b, 0x61,
+ 0x2e, 0xfb, 0xc5, 0xcc, 0x68, 0xb7, 0x6d, 0x69, 0x10, 0xcc, 0xa5, 0x61, 0x78, 0xa8, 0x81, 0x02, 0x9e, 0xe7, 0x63, 0xc5,
+ 0xff, 0x29, 0x22, 0x82, 0x68, 0xaa, 0xaa, 0x0e, 0xfb, 0xa9, 0xd8, 0x16, 0x73, 0x25, 0xbf, 0x9d, 0x08, 0x62, 0x2f, 0x78,
+ 0x04, 0xf6, 0xf6, 0x44, 0x07, 0x37, 0x6e, 0x99, 0x1b, 0x93, 0xd8, 0x7f, 0xee, 0x72, 0xde, 0xe8, 0x32, 0xf6, 0x6d, 0x78,
+ 0x04, 0xa0, 0xa8, 0x21, 0x26, 0x8a, 0x32, 0xe3, 0xb1, 0x65, 0x85, 0xa1, 0x7b, 0x1a, 0xa9, 0x02, 0xb2, 0xbb, 0xee, 0xdd,
+ 0xdd, 0x8f, 0x41, 0x49, 0xc8, 0x3f, 0xdc, 0x1e, 0xdf, 0x21, 0xa3, 0x95, 0x99, 0xbb, 0xfc, 0x29, 0xba, 0x40, 0x43, 0xb9,
+ 0x1c, 0xcd, 0xc9, 0x21, 0x45, 0x73, 0xad, 0xff, 0xfd, 0xa2, 0x6c, 0x5c, 0x3b, 0x1c, 0x37, 0x91, 0x34, 0x8e, 0x5c, 0xd3,
+ 0xd5, 0x03, 0x58, 0x28, 0xc7, 0xf2, 0x76, 0x6f, 0x11, 0xc0, 0xb5, 0xbd, 0x7e, 0xef, 0x23, 0xb3, 0x3d, 0xb8, 0xbd, 0x38,
+ 0x66, 0x8c, 0xf2, 0x78, 0x95, 0xc1, 0x8b, 0x32, 0x65, 0x3a, 0x9b, 0x49, 0x1a, 0x5c, 0x41, 0x3c, 0xc6, 0x85, 0x50, 0xec,
+ 0x85, 0xf0, 0x59, 0x17, 0x81, 0xe8, 0x96, 0xe8, 0x6a, 0xcc, 0xb3, 0xc7, 0x46, 0xbf, 0x81, 0x48, 0xd1, 0x09, 0x1b, 0xbc,
+ 0x73, 0x1e, 0xd7, 0xe8, 0x27, 0xa8, 0x49, 0x48, 0xa2, 0x1c, 0x41, 0x1d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+ 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x59, 0xb8, 0x2b, 0x94,
+ 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 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, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23,
+ 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30,
+ 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81,
+ 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73,
+ 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+ 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81,
+ 0xb6, 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73,
+ 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20,
+ 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74,
+ 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72,
+ 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66,
+ 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f,
+ 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x73, 0x2e, 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, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x10,
+ 0x5e, 0x6c, 0x69, 0xfc, 0xa6, 0x0f, 0xe2, 0x09, 0xd5, 0x94, 0x90, 0xa6, 0x7c, 0x22, 0xdc, 0xee, 0xb0, 0x8f, 0x24, 0x22,
+ 0x4f, 0xb3, 0x67, 0xdb, 0x32, 0xb0, 0xd6, 0x24, 0x87, 0xe6, 0xf3, 0xea, 0x9e, 0xd0, 0x95, 0x75, 0xaa, 0xa7, 0x08, 0xff,
+ 0xb0, 0x35, 0xd7, 0x1f, 0xa3, 0xbf, 0x89, 0x55, 0x0c, 0x1c, 0xa4, 0xd0, 0xf8, 0x00, 0x17, 0x44, 0x94, 0x36, 0x63, 0x3b,
+ 0x83, 0xfe, 0x4e, 0xe5, 0xb3, 0xec, 0x7b, 0x7d, 0xce, 0xfe, 0xa9, 0x54, 0xed, 0xbb, 0x12, 0xa6, 0x72, 0x2b, 0xb3, 0x48,
+ 0x00, 0xc7, 0x8e, 0xf5, 0x5b, 0x68, 0xc9, 0x24, 0x22, 0x7f, 0xa1, 0x4d, 0xfc, 0x54, 0xd9, 0xd0, 0x5d, 0x82, 0x53, 0x71,
+ 0x29, 0x66, 0xcf, 0x0f, 0x6d, 0x32, 0xa6, 0x3f, 0xae, 0x54, 0x27, 0xc2, 0x8c, 0x12, 0x4c, 0xf0, 0xd6, 0xc1, 0x80, 0x75,
+ 0xc3, 0x33, 0x19, 0xd1, 0x8b, 0x58, 0xe6, 0x00, 0x69, 0x76, 0xe7, 0xe5, 0x3d, 0x47, 0xf9, 0xc0, 0x9c, 0xe7, 0x19, 0x1e,
+ 0x95, 0xbc, 0x52, 0x15, 0xce, 0x94, 0xf8, 0x30, 0x14, 0x0b, 0x39, 0x0e, 0x8b, 0xaf, 0x29, 0x30, 0x56, 0xaf, 0x5a, 0x28,
+ 0xac, 0xe1, 0x0f, 0x51, 0x76, 0x76, 0x9a, 0xe7, 0xb9, 0x7d, 0xa3, 0x30, 0xe8, 0xe3, 0x71, 0x15, 0xe8, 0xbf, 0x0d, 0x4f,
+ 0x12, 0x9b, 0x65, 0xab, 0xef, 0xa4, 0xe9, 0x42, 0xf0, 0xd2, 0x4d, 0x20, 0x55, 0x29, 0x88, 0x58, 0x5c, 0x82, 0x67, 0x63,
+ 0x20, 0x50, 0xc6, 0xca, 0x04, 0xe8, 0xbc, 0x3d, 0x93, 0x06, 0x21, 0xb2, 0xc0, 0xbf, 0x53, 0x1e, 0xe1, 0x8b, 0x48, 0xa9,
+ 0xb9, 0xd7, 0xe6, 0x5f, 0x4e, 0x5a, 0x2f, 0x43, 0xac, 0x35, 0xbd, 0x26, 0x60, 0x2f, 0x01, 0xd5, 0x86, 0x6b, 0x64, 0xfa,
+ 0x67, 0x05, 0x44, 0x55, 0x83, 0x5b, 0x93, 0x9c, 0x7c, 0xa7, 0x26, 0x4e, 0x02, 0x2b, 0x48, 0x31, 0x82, 0x12, 0x71, 0x30,
+ 0x82, 0x12, 0x6d, 0x02, 0x01, 0x03, 0xa0, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3, 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b,
+ 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x01, 0xa0, 0x69, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x51, 0xc4, 0xbf, 0xb0, 0x32, 0xf1, 0x05, 0x0d, 0xd1, 0x16, 0x4f, 0x18,
+ 0x9f, 0x54, 0x93, 0x36, 0x1c, 0x86, 0xad, 0x78, 0xcc, 0x14, 0x3f, 0xc1, 0xa5, 0x90, 0x1e, 0x78, 0x47, 0x05, 0xb4, 0x4d,
+ 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x03, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x39, 0x31,
+ 0x32, 0x33, 0x31, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x6d, 0xb7, 0x63, 0x59, 0x7a, 0xbb, 0x28, 0xdf, 0xd2, 0x41, 0x3c,
+ 0x6c, 0x39, 0xbb, 0x42, 0x49, 0x82, 0xa9, 0x21, 0x09, 0xb1, 0x83, 0x54, 0x17, 0xf4, 0x7d, 0x91, 0x92, 0x36, 0xce, 0x2d,
+ 0x86, 0xf2, 0xbb, 0x1d, 0x7a, 0xb7, 0x90, 0x13, 0x95, 0xd3, 0x42, 0x94, 0x92, 0x12, 0xd3, 0xec, 0xd2, 0xdb, 0x6a, 0xcb,
+ 0x3f, 0x63, 0x5a, 0x02, 0x8f, 0xe8, 0x8e, 0x34, 0x67, 0xfa, 0xa0, 0x6d, 0x49, 0xa0, 0xfe, 0xd9, 0xd2, 0x1f, 0x38, 0xdd,
+ 0x54, 0x45, 0xa3, 0xd1, 0x15, 0xc0, 0xdb, 0x3e, 0xb8, 0x0a, 0xa9, 0xce, 0x5c, 0x46, 0x7b, 0x76, 0xa5, 0x34, 0x4f, 0xe6,
+ 0x33, 0x27, 0x41, 0x3c, 0xff, 0x8d, 0x8d, 0x7b, 0xec, 0x5c, 0xa8, 0xa9, 0x6b, 0x79, 0x30, 0xde, 0xe2, 0x50, 0x80, 0x92,
+ 0xb2, 0x0d, 0x69, 0xca, 0x60, 0x72, 0x04, 0xd7, 0x40, 0x80, 0xb6, 0xc9, 0xcb, 0x97, 0x89, 0x0b, 0x9a, 0xa6, 0x20, 0x7e,
+ 0xc2, 0xef, 0xc6, 0xc3, 0x72, 0x6e, 0x08, 0x7b, 0x38, 0x2d, 0x08, 0xc4, 0x97, 0xdd, 0x61, 0x76, 0x0e, 0xe7, 0xae, 0x28,
+ 0x61, 0xbf, 0x41, 0xa6, 0x06, 0x9f, 0x7a, 0x00, 0xd9, 0x38, 0x42, 0xdc, 0x7e, 0xba, 0xfd, 0xa9, 0x11, 0xa5, 0x81, 0x80,
+ 0xa8, 0x9c, 0x18, 0xba, 0xda, 0xef, 0x16, 0x29, 0x70, 0xbf, 0x76, 0xe5, 0x95, 0x85, 0x2f, 0xf6, 0xa2, 0xa5, 0x7b, 0x82,
+ 0x84, 0x37, 0xd2, 0xf5, 0xc4, 0x9b, 0x45, 0xd0, 0x64, 0x22, 0xf1, 0xdd, 0xd0, 0x60, 0x57, 0xb2, 0xfb, 0xb2, 0x5f, 0xa1,
+ 0x40, 0xf9, 0x3b, 0xf5, 0x06, 0x36, 0x49, 0x8f, 0x58, 0x1e, 0x48, 0x96, 0xff, 0xec, 0x57, 0xbd, 0x17, 0xf8, 0x4b, 0xf3,
+ 0xb4, 0x5d, 0x06, 0x9f, 0xe8, 0x94, 0x6d, 0x27, 0xe4, 0x78, 0x3a, 0x73, 0x47, 0xc3, 0x52, 0xd1, 0x74, 0x41, 0x74, 0x32,
+ 0xa6, 0x98, 0x3c, 0xc4, 0x65, 0xa1, 0x82, 0x10, 0xc3, 0x30, 0x82, 0x10, 0xbf, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, 0x31, 0x82, 0x10, 0xae, 0x30, 0x82, 0x10, 0xaa, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x9b, 0x30, 0x82, 0x10, 0x97, 0x02, 0x01, 0x03, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x6d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x09, 0x10, 0x01, 0x04, 0xa0, 0x5e, 0x04, 0x5c, 0x30, 0x5a, 0x02, 0x01, 0x01, 0x06, 0x02, 0x2a, 0x03, 0x30, 0x31, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0x51, 0xc4, 0xbf, 0xb0,
+ 0x32, 0xf1, 0x05, 0x0d, 0xd1, 0x16, 0x4f, 0x18, 0x9f, 0x54, 0x93, 0x36, 0x1c, 0x86, 0xad, 0x78, 0xcc, 0x14, 0x3f, 0xc1,
+ 0xa5, 0x90, 0x1e, 0x78, 0x47, 0x05, 0xb4, 0x4d, 0x02, 0x08, 0x3b, 0x16, 0xc3, 0xcb, 0x4d, 0x17, 0xe8, 0xc1, 0x18, 0x0f,
+ 0x32, 0x30, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x31, 0x39, 0x31, 0x34, 0x35, 0x30, 0x5a, 0x30, 0x03, 0x02, 0x01, 0x01,
+ 0xa0, 0x82, 0x0d, 0xd1, 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x55,
+ 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65,
+ 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x38, 0x30, 0x33, 0x30, 0x36, 0x30, 0x31,
+ 0x33, 0x30, 0x30, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x34, 0x31, 0x37, 0x30, 0x31, 0x33, 0x30, 0x30, 0x33, 0x5a,
+ 0x30, 0x42, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+ 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x4e, 0x57, 0x4b, 0x32, 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, 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, 0xbc, 0x9b, 0x45, 0x28, 0x53, 0xe1, 0x51, 0xbf, 0xef, 0x09, 0x31, 0x1d, 0x75, 0x65, 0x97, 0x05, 0x46, 0x6e, 0x59,
+ 0x18, 0xc2, 0x6d, 0x3a, 0x85, 0x1d, 0x0d, 0x2e, 0x78, 0x7c, 0x50, 0xdf, 0x57, 0x02, 0x32, 0x4f, 0x6b, 0x13, 0xb6, 0x33,
+ 0xdd, 0xff, 0x44, 0x4a, 0xed, 0xdf, 0x6b, 0xcb, 0xd5, 0x21, 0xd2, 0x96, 0x40, 0x43, 0xde, 0x0f, 0x90, 0x8f, 0x29, 0x6a,
+ 0x09, 0xf4, 0xac, 0x43, 0xd6, 0xbc, 0x61, 0xbb, 0x47, 0xd7, 0xde, 0xba, 0x4e, 0x68, 0x3a, 0x42, 0x4b, 0x45, 0xcc, 0x76,
+ 0x15, 0xdb, 0x17, 0x3b, 0x51, 0xbf, 0x73, 0x85, 0x7e, 0x00, 0x2c, 0xa4, 0x0a, 0x94, 0x1e, 0x5c, 0x1b, 0x3b, 0x26, 0xe4,
+ 0x56, 0x52, 0xb5, 0xc2, 0x78, 0x56, 0xbf, 0x43, 0xb9, 0xab, 0xa2, 0x7a, 0x52, 0xbd, 0x3b, 0x3f, 0x7c, 0x11, 0x88, 0x5f,
+ 0x8c, 0xf3, 0x36, 0x00, 0xb1, 0xe6, 0x43, 0xdb, 0x84, 0xa4, 0x3e, 0x9e, 0x87, 0xcb, 0x09, 0x25, 0x71, 0x8a, 0x45, 0x9e,
+ 0xbb, 0x0a, 0x62, 0x4c, 0xfa, 0xcc, 0xaa, 0x97, 0xba, 0x6d, 0x90, 0x9e, 0x0d, 0x0c, 0xac, 0x60, 0xe7, 0x5e, 0x61, 0xa2,
+ 0xc5, 0x29, 0x5c, 0x64, 0x5f, 0xc3, 0xd8, 0x2c, 0xe7, 0x1b, 0x57, 0x32, 0x79, 0x97, 0xae, 0x97, 0x3f, 0x19, 0x1b, 0xe9,
+ 0xb9, 0x2a, 0x53, 0x23, 0xfc, 0x9b, 0x3c, 0x88, 0x90, 0xaa, 0x58, 0xde, 0x0b, 0x91, 0x45, 0xb1, 0x26, 0xb9, 0xc0, 0x6d,
+ 0x9e, 0x3b, 0x1e, 0x56, 0x19, 0x7a, 0xf2, 0x5f, 0xa9, 0x82, 0x9d, 0x88, 0xbe, 0x53, 0x10, 0x02, 0x7f, 0x80, 0x79, 0x15,
+ 0xc1, 0x60, 0xc7, 0xe0, 0xbf, 0xe9, 0x0c, 0x5c, 0x16, 0xb3, 0x6d, 0xda, 0x61, 0xb2, 0xe8, 0x6d, 0x26, 0xf1, 0xe2, 0xb1,
+ 0xea, 0x1d, 0x66, 0x42, 0xe7, 0x6c, 0x4a, 0xf2, 0xa4, 0xaa, 0x49, 0xfe, 0xfb, 0x7e, 0xbf, 0x5f, 0xbb, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc1, 0x30, 0x82, 0x01, 0xbd, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0x60, 0xd9, 0x78, 0x59, 0xea, 0xb0, 0x24, 0x26, 0x69, 0xac, 0xd9, 0xc1, 0xa3, 0xac, 0xb0, 0x50, 0xaa, 0x37, 0xcb,
+ 0x97, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55,
+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26,
+ 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01,
+ 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30,
+ 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+ 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6,
+ 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
+ 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70,
+ 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61,
+ 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c,
+ 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d,
+ 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20,
+ 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c,
+ 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x73, 0x2e, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
+ 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01,
+ 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x34, 0xf6, 0x34, 0x61, 0x30,
+ 0x1c, 0x0a, 0xa4, 0xf1, 0x2a, 0x4e, 0x47, 0xf2, 0xb3, 0x5a, 0x6b, 0xfe, 0x9e, 0x33, 0x8f, 0xa6, 0x44, 0x8b, 0xd0, 0x37,
+ 0x2c, 0xff, 0x00, 0xb3, 0x83, 0xaf, 0x42, 0x2e, 0xa5, 0x98, 0x77, 0x5d, 0x1c, 0x75, 0xbd, 0xaa, 0x68, 0x62, 0x5b, 0xbe,
+ 0x59, 0x91, 0x9e, 0x58, 0xfd, 0xe4, 0x74, 0xe2, 0x7c, 0x5c, 0xb8, 0xb3, 0xb5, 0x66, 0xda, 0x78, 0xda, 0xf7, 0x58, 0x6f,
+ 0xcd, 0x50, 0x77, 0x01, 0xe3, 0x99, 0x84, 0xf2, 0x77, 0x66, 0xba, 0x7c, 0xbe, 0x97, 0xe9, 0x2d, 0x2e, 0x83, 0x2d, 0xcc,
+ 0x73, 0x3a, 0x6a, 0x42, 0xed, 0x58, 0xb0, 0x34, 0x7d, 0xe0, 0xa7, 0x48, 0x6b, 0xe9, 0x39, 0x92, 0xdf, 0x67, 0x05, 0xe5,
+ 0x01, 0x5e, 0xeb, 0x63, 0xc1, 0x35, 0x3a, 0x58, 0xdc, 0x44, 0x35, 0x39, 0x5c, 0xe5, 0xe0, 0x4d, 0x9b, 0x72, 0xb7, 0x0b,
+ 0x59, 0x5a, 0x4a, 0x0d, 0x07, 0x61, 0x5d, 0x0f, 0xf8, 0x19, 0x42, 0x10, 0xd9, 0x77, 0xaf, 0xdf, 0x3d, 0xac, 0x86, 0xf0,
+ 0x5f, 0x66, 0x11, 0x4d, 0x94, 0x38, 0x3f, 0xca, 0xb9, 0x0c, 0xbf, 0xbf, 0x7d, 0x00, 0x51, 0x74, 0x61, 0xd2, 0xc7, 0x75,
+ 0xab, 0xe4, 0x99, 0x0f, 0x18, 0xd2, 0x5e, 0x6d, 0xa0, 0x2a, 0x96, 0x52, 0x36, 0xa9, 0xa3, 0xbb, 0x20, 0xde, 0x0c, 0x6e,
+ 0xfa, 0x86, 0x25, 0xee, 0x05, 0x80, 0x7f, 0x56, 0x6a, 0xd7, 0xc8, 0xaa, 0xbc, 0x4b, 0x85, 0x94, 0xe8, 0x38, 0xc5, 0x45,
+ 0xd8, 0x15, 0x97, 0xde, 0x69, 0x1a, 0x14, 0x04, 0xa4, 0xfc, 0x84, 0x8c, 0xef, 0xe3, 0x23, 0x0d, 0xe1, 0x6b, 0x23, 0x5f,
+ 0xdf, 0x47, 0x93, 0x22, 0x24, 0xe8, 0x12, 0x2b, 0xbd, 0xd1, 0x6f, 0xcb, 0xb5, 0x65, 0x89, 0xa0, 0x9f, 0x78, 0xb3, 0xdb,
+ 0x55, 0xf5, 0x34, 0x41, 0x99, 0x00, 0xd8, 0x31, 0x49, 0x00, 0xb9, 0x30, 0x82, 0x04, 0x07, 0x30, 0x82, 0x02, 0xef, 0xa0,
+ 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7d, 0x4c, 0x57, 0x63, 0x9f, 0xf3, 0xf0, 0xb7, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c,
+ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x35, 0x31,
+ 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x34, 0x30, 0x35, 0x31, 0x32, 0x30, 0x32, 0x34, 0x34,
+ 0x5a, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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,
+ 0xd3, 0x77, 0x18, 0xa1, 0xf7, 0x99, 0x10, 0x67, 0x5c, 0xd2, 0x2e, 0x9e, 0xb8, 0x8f, 0x23, 0x67, 0x3e, 0xfc, 0x42, 0xe2,
+ 0x09, 0x7d, 0x0a, 0x8a, 0xb8, 0x18, 0xfc, 0x73, 0x40, 0x2f, 0xbd, 0xc4, 0xd8, 0x50, 0xc5, 0x27, 0xc8, 0xfe, 0xb8, 0x34,
+ 0x70, 0xa0, 0x0d, 0x13, 0x3c, 0xbd, 0x08, 0x4e, 0x9a, 0x93, 0x6f, 0x39, 0x37, 0xda, 0x9e, 0x65, 0xf5, 0xb4, 0x63, 0xf4,
+ 0x90, 0xc8, 0x49, 0x6d, 0x5d, 0x20, 0xd3, 0x39, 0xfd, 0x09, 0xba, 0xf4, 0x3a, 0xf3, 0xce, 0x4a, 0x69, 0x64, 0x05, 0x99,
+ 0x46, 0xe0, 0xda, 0x35, 0xc4, 0x65, 0x18, 0x1e, 0xc6, 0x16, 0xa3, 0x12, 0x61, 0xb4, 0x2e, 0xf5, 0xf0, 0x89, 0x0d, 0x8c,
+ 0xdc, 0x3d, 0xf6, 0x06, 0xcf, 0x6f, 0x86, 0x25, 0x4c, 0x09, 0xc2, 0x1b, 0xc8, 0x0e, 0x78, 0x88, 0x8d, 0xc1, 0x22, 0xb8,
+ 0xba, 0x21, 0x13, 0x9b, 0xca, 0xee, 0x8a, 0x9e, 0xdd, 0x7b, 0x5b, 0xff, 0xa3, 0xe9, 0xd1, 0xa3, 0x81, 0x7e, 0xfe, 0xff,
+ 0xe6, 0x8c, 0x49, 0xe4, 0x3b, 0x0a, 0xf9, 0x10, 0xa6, 0x72, 0x33, 0xbb, 0x2c, 0xc4, 0x4a, 0x5a, 0x72, 0x0a, 0x39, 0x50,
+ 0x74, 0xdd, 0x28, 0x6e, 0x79, 0x5f, 0x7e, 0xa7, 0xa8, 0x14, 0xcf, 0x56, 0xb3, 0x56, 0x6c, 0xa5, 0xe9, 0xf0, 0xc4, 0xae,
+ 0xf9, 0xea, 0x20, 0x8e, 0x18, 0xc7, 0x28, 0x74, 0xe2, 0x08, 0x4d, 0x89, 0x26, 0x42, 0x79, 0x5e, 0xf6, 0x60, 0xe3, 0x45,
+ 0x58, 0xa1, 0xfb, 0x51, 0x49, 0x5e, 0x92, 0x4a, 0x4d, 0xb9, 0xef, 0xd4, 0x73, 0xb5, 0xda, 0x04, 0x7b, 0xe3, 0x52, 0x9f,
+ 0xcb, 0xa3, 0x19, 0x5d, 0xac, 0x6b, 0x98, 0x6c, 0x9e, 0xe2, 0xec, 0x74, 0x2d, 0x44, 0x3e, 0xe0, 0x61, 0x3e, 0x07, 0x45,
+ 0x7e, 0x34, 0x75, 0x26, 0x98, 0x40, 0x9b, 0x75, 0x9e, 0xc8, 0x30, 0xed, 0x4b, 0xbf, 0x77, 0x8f, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x34, 0xcd,
+ 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 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, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e,
+ 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30,
+ 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70,
+ 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x63, 0x64, 0x06, 0x02, 0x09, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x36, 0xd2, 0xf5, 0xde, 0x71, 0x53, 0x07, 0xc9, 0x23, 0xd8,
+ 0x78, 0x9b, 0x65, 0xbc, 0xf3, 0xd5, 0x5b, 0xe9, 0xb8, 0x7f, 0x1b, 0x23, 0xc7, 0xa2, 0xcf, 0xb4, 0xa9, 0x28, 0xe9, 0xf8,
+ 0xdd, 0x70, 0x88, 0x21, 0x39, 0xf3, 0xdb, 0x33, 0x9c, 0xc3, 0x72, 0x43, 0xd6, 0x3d, 0x42, 0x51, 0x97, 0xba, 0xad, 0x1d,
+ 0x8e, 0x92, 0xd2, 0x75, 0x8b, 0xc3, 0x5d, 0x9c, 0xf5, 0xcb, 0x8c, 0xdc, 0x6a, 0x6a, 0x3a, 0xdd, 0xeb, 0x54, 0x7d, 0xed,
+ 0x14, 0x6b, 0xf3, 0xd6, 0x3e, 0x93, 0xc8, 0x6d, 0x7a, 0x54, 0x5f, 0xf2, 0x43, 0x8e, 0x10, 0xd0, 0x76, 0x5c, 0x9b, 0x00,
+ 0x0c, 0x1d, 0x4e, 0xca, 0x3c, 0xcd, 0xfa, 0xe6, 0xf7, 0xc2, 0x3e, 0x72, 0xb7, 0xb8, 0xde, 0xe8, 0x34, 0xaa, 0x15, 0xa0,
+ 0xae, 0x5c, 0x67, 0xa8, 0x0c, 0xac, 0x9b, 0x1e, 0x65, 0xb3, 0xe3, 0x0f, 0x30, 0x42, 0x34, 0xe9, 0xae, 0xd3, 0x01, 0xd3,
+ 0xa7, 0xdd, 0x42, 0x73, 0x75, 0x7c, 0x51, 0x43, 0x85, 0x9a, 0x60, 0x10, 0xdc, 0xae, 0x27, 0xd2, 0x6b, 0x67, 0xc9, 0x33,
+ 0x45, 0x6f, 0xc9, 0x98, 0x1e, 0xa0, 0x9a, 0x7f, 0x4d, 0x11, 0x93, 0xe1, 0x69, 0xff, 0xec, 0x4b, 0x45, 0xf3, 0x4e, 0xca,
+ 0x22, 0x0e, 0x57, 0xd7, 0x22, 0x07, 0xe5, 0x22, 0xb4, 0x87, 0xe9, 0x9c, 0xd3, 0x45, 0xcb, 0x6e, 0x3f, 0xe5, 0x8e, 0xb8,
+ 0xfc, 0x46, 0xd5, 0x5c, 0xc9, 0xb0, 0xab, 0x05, 0x3a, 0x6d, 0x37, 0x28, 0xa3, 0xa8, 0x46, 0x65, 0x6f, 0x55, 0xa1, 0x68,
+ 0x88, 0xea, 0x52, 0x3e, 0xc9, 0xf4, 0xd4, 0xe6, 0xfa, 0x3f, 0xa4, 0xe4, 0x26, 0x80, 0xb5, 0x3a, 0x6b, 0xd6, 0xc3, 0xe5,
+ 0xf9, 0x32, 0x81, 0xc8, 0x32, 0xa2, 0x48, 0xe1, 0x8e, 0x06, 0xa3, 0x19, 0xe4, 0xb3, 0xcb, 0x3b, 0x4b, 0xdf, 0xe0, 0xcc,
+ 0x0e, 0xb2, 0xaf, 0x98, 0xd1, 0x83, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+ 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17,
+ 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32,
+ 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c,
+ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb,
+ 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8,
+ 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3,
+ 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4,
+ 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba,
+ 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e,
+ 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f,
+ 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e,
+ 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74,
+ 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb,
+ 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10,
+ 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65,
+ 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 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, 0x2b, 0xd0, 0x69, 0x47, 0x94,
+ 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55,
+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e,
+ 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01,
+ 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01,
+ 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02,
+ 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
+ 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e,
+ 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65,
+ 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61,
+ 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74,
+ 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
+ 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
+ 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2,
+ 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e,
+ 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2,
+ 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a,
+ 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b,
+ 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d,
+ 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2,
+ 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48,
+ 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3,
+ 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e,
+ 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8,
+ 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c,
+ 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37, 0xb0, 0x75, 0x75,
+ 0x21, 0x31, 0x82, 0x02, 0x3f, 0x30, 0x82, 0x02, 0x3b, 0x02, 0x01, 0x01, 0x30, 0x81, 0x88, 0x30, 0x7c, 0x31, 0x30, 0x30,
+ 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
+ 0x61, 0x6d, 0x70, 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, 0x02, 0x08, 0x55, 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+ 0x05, 0x00, 0xa0, 0x81, 0x8c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0d,
+ 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x31, 0x39, 0x31, 0x34,
+ 0x35, 0x30, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14,
+ 0x0e, 0xf0, 0xad, 0x61, 0xed, 0x39, 0xbe, 0xbc, 0x79, 0xf7, 0xad, 0x2b, 0x19, 0x8d, 0xb1, 0xb1, 0xc3, 0x9d, 0x27, 0xa1,
+ 0x30, 0x2b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0c, 0x31, 0x1c, 0x30, 0x1a, 0x30,
+ 0x18, 0x30, 0x16, 0x04, 0x14, 0xc5, 0xe5, 0x93, 0x54, 0xe1, 0x09, 0x59, 0x31, 0x49, 0x9b, 0x0e, 0xde, 0xbb, 0xda, 0x5c,
+ 0xc9, 0x20, 0x94, 0x1c, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x04, 0x82, 0x01, 0x00, 0x73, 0x96, 0x28, 0x77, 0xa2, 0x30, 0x0a, 0x61, 0xee, 0x07, 0x0c, 0x85, 0x7c, 0xaa, 0x37, 0xa4,
+ 0xda, 0x0f, 0xd2, 0xca, 0x0d, 0xa3, 0xf7, 0xc8, 0x1c, 0x20, 0x8d, 0xd1, 0x82, 0xda, 0xa0, 0x7d, 0xf5, 0x72, 0x49, 0x2d,
+ 0x11, 0x28, 0xe4, 0xb4, 0x71, 0x3e, 0xf7, 0x7b, 0x50, 0x74, 0x28, 0x0d, 0xee, 0x05, 0x5d, 0xc2, 0x5b, 0xe9, 0xfc, 0xee,
+ 0x48, 0x40, 0x1d, 0x84, 0x31, 0x8e, 0x78, 0x08, 0xb5, 0xa0, 0xaf, 0xf0, 0x29, 0xe9, 0xd4, 0x39, 0xd2, 0xff, 0xfb, 0x62,
+ 0xda, 0x5e, 0x4f, 0xa5, 0xe4, 0x32, 0x1e, 0xdd, 0xce, 0xf7, 0x1f, 0xf3, 0x79, 0x0c, 0xf2, 0x67, 0x8d, 0xc9, 0x5d, 0x68,
+ 0xe6, 0xe5, 0x8d, 0x15, 0x1a, 0x94, 0x98, 0x28, 0x38, 0xa6, 0x34, 0xe4, 0x90, 0x18, 0x4b, 0xea, 0x78, 0xa0, 0xc3, 0x04,
+ 0x2e, 0x2d, 0x54, 0x41, 0xd5, 0x9c, 0x6d, 0xbf, 0xc9, 0xa5, 0x65, 0xe1, 0xd5, 0xe3, 0xf2, 0xcd, 0xc0, 0x52, 0x40, 0x35,
+ 0xa1, 0xdd, 0x56, 0xff, 0x96, 0x6c, 0xa8, 0x81, 0x8a, 0x40, 0x61, 0x05, 0x8c, 0xa1, 0xd0, 0xf7, 0xce, 0x9b, 0xe1, 0x05,
+ 0x83, 0xc1, 0xf5, 0x6e, 0x5e, 0x33, 0xd2, 0x7d, 0xd1, 0x96, 0x31, 0x68, 0xd3, 0xdb, 0x63, 0x4c, 0xa5, 0xf7, 0xac, 0x9d,
+ 0xe5, 0x1c, 0x93, 0x23, 0x5a, 0x1e, 0x7c, 0x13, 0x58, 0xf7, 0x3a, 0xff, 0x92, 0x46, 0xee, 0xec, 0xf5, 0x9b, 0x54, 0x27,
+ 0x3e, 0xa7, 0x22, 0x26, 0xe4, 0x24, 0xd1, 0x07, 0x51, 0xfc, 0xa1, 0x50, 0x7d, 0xa7, 0xf9, 0x44, 0x82, 0x84, 0x23, 0x13,
+ 0x40, 0x19, 0xfd, 0x1d, 0x9f, 0x1f, 0x65, 0x24, 0x17, 0x96, 0x56, 0xa8, 0xcf, 0x85, 0xc3, 0xe5, 0x2a, 0x68, 0x56, 0xd1,
+ 0x6f, 0x6d, 0x15, 0x87, 0xaa, 0x64, 0x9e, 0xf1, 0xaf, 0x74, 0x95, 0x71, 0xd0, 0x4a, 0x8f, 0x73, 0x9a, 0x7f, 0x31, 0xdd
+};
+
+/* MARK: Developer ID Signature
+ * This timestamp has a matching MessageImprint */
+uint8_t _developer_id_data[] = {
+ 0xfa, 0xde, 0x0c, 0x02, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
+ 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x7e, 0x00, 0x14, 0x01, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6b, 0x37, 0x32,
+ 0x2e, 0x43, 0x68, 0x61, 0x72, 0x6c, 0x65, 0x73, 0x00, 0x39, 0x41, 0x35, 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x00,
+ 0x0a, 0x91, 0x11, 0xba, 0x5e, 0xbb, 0xcb, 0x30, 0xbc, 0xf0, 0x20, 0x12, 0xc4, 0x12, 0x87, 0xa6, 0x38, 0x7f, 0x94, 0x85,
+ 0x19, 0xa0, 0x1f, 0x76, 0x50, 0xfb, 0xd9, 0x8e, 0x42, 0xe8, 0x5c, 0x37, 0xd8, 0x91, 0xb2, 0xdd, 0xee, 0x43, 0xb4, 0xc7,
+ 0x65, 0x23, 0x39, 0xb8, 0x34, 0xec, 0x43, 0x13, 0xe2, 0xf4, 0x87, 0xf8, 0x53, 0x8b, 0x9a, 0x45, 0x1a, 0x3b, 0x3c, 0x6b,
+ 0x45, 0xe3, 0xec, 0x96, 0xcb, 0x55, 0x5a, 0xbe, 0x6d, 0x39, 0x63, 0x11, 0x74, 0x28, 0x6b, 0x74, 0x9f, 0xb2, 0x39, 0x04,
+ 0x60, 0xd4, 0x71, 0x64, 0xe5, 0xf2, 0xe1, 0xae, 0x3f, 0xb0, 0x20, 0xa1, 0xee, 0x3a, 0x54, 0x0b, 0x2d, 0x50, 0x47, 0x6c,
+ 0x10, 0x94, 0x66, 0x5a, 0x03, 0xaa, 0x49, 0xe4, 0x9c, 0xf4, 0xbd, 0x0b, 0xeb, 0xe1, 0xaf, 0xf8, 0x7e, 0x8a, 0x53, 0x05,
+ 0xf5, 0x0e, 0xa4, 0x2a, 0x45, 0x4a, 0x8e, 0xd1, 0x1e, 0xed, 0x98, 0x10, 0x0b, 0x66, 0x4b, 0xc4, 0x31, 0x4b, 0xed, 0x80,
+ 0x6c, 0x80, 0x34, 0xf5, 0xe3, 0x91, 0x9d, 0x46, 0xea, 0x6f, 0x94, 0x59, 0x84, 0x38, 0x8f, 0x1e, 0x3d, 0xcc, 0x4a, 0x29,
+ 0xaf, 0xe2, 0x52, 0x65, 0x92, 0xa9, 0x9e, 0xc0, 0xfd, 0x26, 0xb7, 0xed, 0xb6, 0x65, 0x9e, 0xcf, 0xe9, 0x6c, 0xf7, 0x4b,
+ 0x5f, 0x24, 0x87, 0x95, 0xc4, 0x8f, 0xd8, 0x6c, 0x6c, 0x06, 0x5d, 0x96, 0x06, 0xa7, 0x9d, 0xf4, 0x97, 0xf5, 0xc3, 0x0c,
+ 0xea, 0x8f, 0x54, 0xf4, 0xe3, 0x3e, 0x08, 0xe5, 0x9a, 0x64, 0xbd, 0xe3, 0x79, 0xc0, 0xc0, 0xe0, 0xf8, 0x7f, 0xfc, 0xe3
+};
+
+uint8_t _developer_id_sig[] = {
+ 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, 0x0e, 0x3d, 0x30, 0x82, 0x04, 0x04,
+ 0x30, 0x82, 0x02, 0xec, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x18, 0x7a, 0xa9, 0xa8, 0xc2, 0x96, 0x21, 0x0c, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a,
+ 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32,
+ 0x30, 0x32, 0x30, 0x31, 0x32, 0x32, 0x31, 0x32, 0x31, 0x35, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x32, 0x30, 0x31, 0x32,
+ 0x32, 0x31, 0x32, 0x31, 0x35, 0x5a, 0x30, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x44,
+ 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x49, 0x44, 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, 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, 0x89, 0x76, 0x4f, 0x06, 0x5b, 0x9a, 0x41, 0xee, 0xa5, 0x23, 0x2b, 0x02, 0xa3, 0x5f, 0xd7, 0x73, 0x3f, 0xc0,
+ 0x35, 0xb0, 0x8b, 0x84, 0x0a, 0x3f, 0x06, 0x24, 0x7f, 0xa7, 0x95, 0x3f, 0xeb, 0x4f, 0x0e, 0x93, 0xaf, 0xb4, 0x0e, 0xd0,
+ 0xc8, 0x3e, 0xe5, 0x6d, 0x18, 0xb3, 0x1f, 0xe8, 0x89, 0x47, 0xbf, 0xd7, 0x09, 0x08, 0xe4, 0xff, 0x56, 0x98, 0x29, 0x15,
+ 0xe7, 0x94, 0x9d, 0xb9, 0x35, 0xa3, 0x0a, 0xcd, 0xb4, 0xc0, 0xe1, 0xe2, 0x60, 0xf4, 0xca, 0xec, 0x29, 0x78, 0x45, 0x69,
+ 0x69, 0x60, 0x6b, 0x5f, 0x8a, 0x92, 0xfc, 0x9e, 0x23, 0xe6, 0x3a, 0xc2, 0x22, 0xb3, 0x31, 0x4f, 0x1c, 0xba, 0xf2, 0xb6,
+ 0x34, 0x59, 0x42, 0xee, 0xb0, 0xa9, 0x02, 0x03, 0x18, 0x91, 0x04, 0xb6, 0xb3, 0x78, 0x2e, 0x33, 0x1f, 0x80, 0x45, 0x0d,
+ 0x45, 0x6f, 0xbb, 0x0e, 0x5a, 0x5b, 0x7f, 0x3a, 0xe7, 0xd8, 0x08, 0xd7, 0x0b, 0x0e, 0x32, 0x6d, 0xfb, 0x86, 0x36, 0xe4,
+ 0x6c, 0xab, 0xc4, 0x11, 0x8a, 0x70, 0x84, 0x26, 0xaa, 0x9f, 0x44, 0xd1, 0xf1, 0xb8, 0xc6, 0x7b, 0x94, 0x17, 0x9b, 0x48,
+ 0xf7, 0x0b, 0x58, 0x16, 0xba, 0x23, 0xc5, 0x9f, 0x15, 0x39, 0x7e, 0xca, 0x5d, 0xc3, 0x32, 0x5f, 0x0f, 0xe0, 0x52, 0x7f,
+ 0x40, 0xea, 0xbe, 0xac, 0x08, 0x64, 0x95, 0x5b, 0xc9, 0x1a, 0x9c, 0xe5, 0x80, 0xca, 0x1f, 0x6a, 0x44, 0x1c, 0x6c, 0x3e,
+ 0xc4, 0xb0, 0x26, 0x1f, 0x1d, 0xec, 0x7b, 0xaf, 0x5e, 0xa0, 0x6a, 0x3d, 0x47, 0xa9, 0x58, 0x12, 0x31, 0x3f, 0x20, 0x76,
+ 0x28, 0x6d, 0x1d, 0x1c, 0xb0, 0xc2, 0x4e, 0x11, 0x69, 0x26, 0x8b, 0xcb, 0xd6, 0xd0, 0x11, 0x82, 0xc9, 0x4e, 0x0f, 0xf1,
+ 0x56, 0x74, 0xd0, 0xd9, 0x08, 0x4b, 0x66, 0x78, 0xa2, 0xab, 0xac, 0xa7, 0xe2, 0xd2, 0x4c, 0x87, 0x59, 0xc9, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x57, 0x17, 0xed, 0xa2, 0xcf, 0xdc, 0x7c, 0x98, 0xa1, 0x10, 0xe0, 0xfc, 0xbe, 0x87, 0x2d, 0x2c, 0xf2, 0xe3, 0x17, 0x54,
+ 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, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b,
+ 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30,
+ 0x25, 0x30, 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
+ 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x06, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x42, 0x39, 0x74, 0x6b, 0xa1, 0xdc, 0xc6, 0xa4,
+ 0x8f, 0x37, 0x2a, 0x8c, 0xb3, 0x1d, 0x0a, 0x44, 0xbc, 0x95, 0x2c, 0x7f, 0xbc, 0x59, 0xb8, 0xac, 0x61, 0xfb, 0x07, 0x90,
+ 0x92, 0x32, 0xb9, 0xd4, 0xbf, 0x3b, 0xc1, 0x50, 0x39, 0x6a, 0x44, 0x74, 0xa2, 0xec, 0x5b, 0x1f, 0x70, 0xe5, 0xaa, 0xdd,
+ 0x4b, 0x6c, 0x1c, 0x23, 0x71, 0x2d, 0x5f, 0xd1, 0xc5, 0x93, 0xbe, 0xee, 0x9b, 0x8a, 0x70, 0x65, 0x82, 0x9d, 0x16, 0xe3,
+ 0x1a, 0x10, 0x17, 0x89, 0x2d, 0xa8, 0xcd, 0xfd, 0x0c, 0x78, 0x58, 0x49, 0x0c, 0x28, 0x7f, 0x33, 0xee, 0x00, 0x7a, 0x1b,
+ 0xb4, 0x76, 0xac, 0xb6, 0xb5, 0xbb, 0x4f, 0xdf, 0xa8, 0x1b, 0x9d, 0xc8, 0x19, 0x97, 0x4a, 0x0b, 0x56, 0x67, 0x2f, 0xc2,
+ 0x3e, 0xb6, 0xb3, 0xc4, 0x83, 0x3a, 0xf0, 0x77, 0x6d, 0x74, 0xc4, 0x2e, 0x23, 0x51, 0xee, 0x9a, 0xa5, 0x03, 0x6f, 0x60,
+ 0xf4, 0xa5, 0x48, 0xa7, 0x06, 0xc2, 0xbb, 0x5a, 0xe2, 0x1f, 0x1f, 0x46, 0x45, 0x7e, 0xe4, 0x97, 0xf5, 0x27, 0x10, 0xb7,
+ 0x20, 0x22, 0x72, 0x6f, 0x72, 0xda, 0xc6, 0x50, 0x75, 0xc5, 0x3d, 0x25, 0x8f, 0x5d, 0xa3, 0x00, 0xe9, 0x9f, 0x36, 0x8c,
+ 0x48, 0x39, 0x8f, 0xb3, 0x3b, 0xea, 0x90, 0x80, 0x2e, 0x95, 0x9a, 0x60, 0xf4, 0x78, 0xce, 0xf4, 0x0e, 0x0a, 0x53, 0x3e,
+ 0xa2, 0xfa, 0x4f, 0xd8, 0x1e, 0xae, 0x84, 0x95, 0x8d, 0x32, 0xbc, 0x56, 0x4d, 0x89, 0xe9, 0x78, 0x18, 0xe0, 0xac, 0x9a,
+ 0x42, 0xba, 0x7a, 0x46, 0x1b, 0x84, 0xa2, 0x89, 0xce, 0x14, 0xe8, 0x88, 0xd1, 0x58, 0x8b, 0xf6, 0xae, 0x56, 0xc4, 0x2c,
+ 0x05, 0x2a, 0x45, 0xaf, 0x0b, 0xd9, 0x4b, 0xa9, 0x02, 0x0f, 0x34, 0xac, 0x88, 0xc7, 0x61, 0x55, 0x89, 0x44, 0xc9, 0x27,
+ 0x73, 0x07, 0xee, 0x82, 0xe5, 0x4e, 0xf5, 0x70, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+ 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+ 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30,
+ 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35,
+ 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
+ 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70,
+ 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84,
+ 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30,
+ 0x02, 0xe8, 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11,
+ 0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33,
+ 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25,
+ 0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6,
+ 0x9c, 0x9e, 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70,
+ 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5,
+ 0xb9, 0x0e, 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16,
+ 0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41, 0xb3,
+ 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62,
+ 0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d,
+ 0xde, 0x65, 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+ 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 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, 0x2b, 0xd0, 0x69,
+ 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b,
+ 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
+ 0x05, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68,
+ 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20,
+ 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20,
+ 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63,
+ 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e,
+ 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
+ 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3, 0x77,
+ 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b,
+ 0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34,
+ 0xd8, 0xa2, 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1,
+ 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3,
+ 0xb7, 0x8b, 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca,
+ 0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b,
+ 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8,
+ 0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde,
+ 0xeb, 0xa3, 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f,
+ 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42,
+ 0xfb, 0xd8, 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6,
+ 0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37, 0xb0,
+ 0x75, 0x75, 0x21, 0x30, 0x82, 0x05, 0x72, 0x30, 0x82, 0x04, 0x5a, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x60, 0x97,
+ 0xa2, 0xe8, 0x89, 0x7f, 0x15, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x30, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f,
+ 0x70, 0x65, 0x72, 0x20, 0x49, 0x44, 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, 0x37, 0x30, 0x36, 0x32, 0x38, 0x30, 0x34, 0x31, 0x38, 0x33, 0x31,
+ 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x36, 0x32, 0x39, 0x30, 0x34, 0x31, 0x38, 0x33, 0x31, 0x5a, 0x30, 0x81, 0x93, 0x31,
+ 0x1a, 0x30, 0x18, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x01, 0x0c, 0x0a, 0x39, 0x41, 0x35,
+ 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x33, 0x44, 0x65,
+ 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x49, 0x44, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x3a, 0x20, 0x58, 0x4b, 0x37, 0x32, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x28, 0x39, 0x41,
+ 0x35, 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x29, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0a,
+ 0x39, 0x41, 0x35, 0x50, 0x43, 0x55, 0x34, 0x46, 0x53, 0x44, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
+ 0x0c, 0x58, 0x4b, 0x37, 0x32, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 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, 0xc9,
+ 0x97, 0x5a, 0x0c, 0x4c, 0x30, 0x37, 0xb1, 0xf0, 0x25, 0x28, 0xba, 0x16, 0x41, 0x3b, 0x44, 0xdc, 0x50, 0xc6, 0xf0, 0x20,
+ 0xf5, 0xe1, 0x17, 0x79, 0x8a, 0xdf, 0xd8, 0x87, 0x12, 0x04, 0x08, 0x6a, 0xb1, 0x2e, 0xa0, 0x7f, 0x1c, 0x8b, 0x61, 0x51,
+ 0x7d, 0x30, 0xef, 0x30, 0xbe, 0x8d, 0x91, 0x33, 0x9f, 0x2f, 0x42, 0xce, 0x85, 0x03, 0xaf, 0x05, 0x59, 0x72, 0xf3, 0xf1,
+ 0x5b, 0x77, 0xb0, 0x94, 0x31, 0xc9, 0xd5, 0x99, 0x0a, 0x0c, 0x6f, 0x56, 0x0e, 0xf9, 0x0a, 0x54, 0x40, 0x22, 0x1e, 0x96,
+ 0x9e, 0xcb, 0xf1, 0x43, 0xa1, 0x6c, 0x61, 0x28, 0x92, 0x6f, 0x1b, 0x2b, 0x29, 0x19, 0x1f, 0xe0, 0xa1, 0x18, 0xcd, 0x80,
+ 0xcc, 0xd5, 0x66, 0xc9, 0xe4, 0x0c, 0x12, 0x95, 0x4f, 0x21, 0x64, 0x81, 0x33, 0x19, 0x2c, 0x1e, 0xa6, 0x78, 0x3f, 0x56,
+ 0x6a, 0x4b, 0xc7, 0xb7, 0x38, 0xec, 0x38, 0xce, 0x60, 0x75, 0x8e, 0x67, 0xc5, 0x93, 0x00, 0xb3, 0x2c, 0x98, 0xb0, 0x56,
+ 0xef, 0x16, 0xbe, 0x4c, 0xe0, 0x2c, 0x4c, 0xa4, 0x67, 0x27, 0xcb, 0xa9, 0xbf, 0x67, 0xf4, 0x60, 0xe1, 0x9f, 0x56, 0x4a,
+ 0x38, 0xeb, 0xd7, 0x86, 0x21, 0xd6, 0xa5, 0xd3, 0x20, 0x41, 0x55, 0xcb, 0x8c, 0xbd, 0xaa, 0x80, 0x90, 0x17, 0xde, 0xbb,
+ 0x0d, 0x55, 0xac, 0x4e, 0x93, 0xa1, 0x7f, 0x75, 0xcc, 0xc6, 0xe7, 0x22, 0x3d, 0xed, 0xff, 0x34, 0x96, 0xd0, 0x41, 0x63,
+ 0x2a, 0x00, 0x1b, 0x72, 0xe3, 0x37, 0xb6, 0xf1, 0xfc, 0x28, 0x12, 0x8c, 0x13, 0xd3, 0xe5, 0x3e, 0xad, 0xc0, 0xb7, 0x59,
+ 0x9e, 0x79, 0x9a, 0x26, 0x13, 0xa2, 0x36, 0x19, 0xd8, 0xdb, 0x82, 0x78, 0x4d, 0x61, 0xc0, 0xc8, 0x56, 0x04, 0x29, 0xc8,
+ 0xc7, 0x95, 0x93, 0x69, 0xfb, 0x19, 0xe9, 0xe4, 0x2d, 0xd8, 0xc3, 0x95, 0xb3, 0x43, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x82, 0x01, 0xe1, 0x30, 0x82, 0x01, 0xdd, 0x30, 0x3e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+ 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x22, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x69, 0x64, 0x30, 0x31, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0x64, 0xca, 0x4d, 0xf4, 0x2c, 0x19, 0xf5, 0x2a, 0x21, 0xd1, 0xf9, 0x9e, 0x38, 0xeb, 0xbd, 0x79, 0x12,
+ 0x86, 0xc1, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x57, 0x17, 0xed, 0xa2, 0xcf, 0xdc, 0x7c, 0x98, 0xa1, 0x10,
+ 0xe0, 0xfc, 0xbe, 0x87, 0x2d, 0x2c, 0xf2, 0xe3, 0x17, 0x54, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x82, 0x01, 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05,
+ 0x01, 0x30, 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30,
+ 0x81, 0xb6, 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69,
+ 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79,
+ 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70,
+ 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70,
+ 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65,
+ 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f,
+ 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70,
+ 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65,
+ 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
+ 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x03, 0x30, 0x13, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x0d, 0x01, 0x01,
+ 0xff, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0x7a, 0x4b, 0xa3, 0x42, 0x22, 0x42, 0xa3, 0x8f, 0xc1, 0xbb, 0x60, 0x8a, 0xb6, 0x3e, 0xf5,
+ 0x2e, 0x76, 0x68, 0x59, 0x97, 0x2e, 0x91, 0xc9, 0xb0, 0x7f, 0x3d, 0xba, 0xf1, 0x7b, 0x19, 0x84, 0x68, 0xad, 0x69, 0x8c,
+ 0xe2, 0x08, 0x35, 0x4f, 0x8a, 0xf2, 0xf8, 0x04, 0xe8, 0xe9, 0x46, 0x3e, 0x64, 0xf9, 0x2d, 0xef, 0x5f, 0x34, 0x77, 0x43,
+ 0xd1, 0x1d, 0x6f, 0xeb, 0x7d, 0x58, 0xb0, 0x85, 0xf5, 0x34, 0x4c, 0x20, 0x84, 0x27, 0xc5, 0x02, 0x77, 0x93, 0x01, 0x18,
+ 0x5a, 0x98, 0xd1, 0xf2, 0x53, 0x44, 0x9b, 0x2f, 0xd6, 0xf3, 0xa2, 0xb8, 0x31, 0x0b, 0x31, 0x7e, 0xf2, 0x7f, 0x83, 0x76,
+ 0xf0, 0xff, 0x91, 0x2c, 0x39, 0xff, 0x5b, 0x9b, 0xbd, 0x30, 0xc6, 0xf5, 0xe8, 0x4d, 0xff, 0x16, 0xf0, 0xd1, 0xa9, 0x7c,
+ 0x03, 0x4d, 0x2a, 0x45, 0xd9, 0x64, 0x96, 0x6a, 0x84, 0x10, 0x06, 0x3a, 0x1c, 0x0b, 0x96, 0x04, 0xe7, 0x0f, 0xd7, 0x99,
+ 0x8f, 0x82, 0x9f, 0x29, 0xff, 0xcf, 0x7f, 0x0d, 0x40, 0xf5, 0xa2, 0xd6, 0x38, 0x3e, 0xca, 0x76, 0xa4, 0x69, 0xad, 0x07,
+ 0x6b, 0xd1, 0x76, 0xde, 0xb7, 0x52, 0xc6, 0x81, 0x7b, 0x0b, 0xce, 0x8a, 0xa2, 0x53, 0xe8, 0xf7, 0x6d, 0x6c, 0x91, 0xae,
+ 0xa5, 0xad, 0xb4, 0xd9, 0xb8, 0x86, 0xcf, 0xa4, 0x50, 0xce, 0x9a, 0x89, 0x79, 0x2f, 0x0b, 0xec, 0xce, 0x1b, 0x70, 0x5a,
+ 0x31, 0xf8, 0x5e, 0xc5, 0xd2, 0x7f, 0x4b, 0x19, 0xc2, 0x8b, 0xc9, 0xcf, 0xc1, 0x0e, 0x7d, 0x54, 0x35, 0xa5, 0xa7, 0xf5,
+ 0xb5, 0xa3, 0x76, 0xb8, 0x76, 0xed, 0x77, 0xf4, 0x67, 0x29, 0x39, 0x28, 0x3f, 0x4d, 0xa3, 0xb8, 0xd5, 0xb4, 0x9e, 0x49,
+ 0xb3, 0xad, 0x48, 0xa5, 0xf1, 0x30, 0xb6, 0xd9, 0x67, 0x93, 0x24, 0x12, 0xaf, 0xb1, 0x75, 0x4e, 0x08, 0x7a, 0x73, 0xde,
+ 0x21, 0x31, 0x82, 0x14, 0x51, 0x30, 0x82, 0x14, 0x4d, 0x02, 0x01, 0x01, 0x30, 0x81, 0x85, 0x30, 0x79, 0x31, 0x2d, 0x30,
+ 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x49, 0x44,
+ 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, 0x02, 0x08,
+ 0x60, 0x97, 0xa2, 0xe8, 0x89, 0x7f, 0x15, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
+ 0x01, 0x05, 0x00, 0xa0, 0x82, 0x01, 0xc8, 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, 0x30, 0x37, 0x31, 0x30, 0x31, 0x30, 0x33, 0x32,
+ 0x33, 0x33, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20,
+ 0xef, 0x70, 0xcf, 0x83, 0x01, 0xb4, 0x57, 0x33, 0xca, 0x1f, 0xec, 0x9c, 0x7c, 0xe4, 0xfa, 0xc3, 0x24, 0x62, 0xcd, 0xf7,
+ 0x62, 0x97, 0x3d, 0xd3, 0x2e, 0xfa, 0x6b, 0x7a, 0xca, 0x06, 0x98, 0x4a, 0x30, 0x82, 0x01, 0x5b, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x82, 0x01, 0x4c, 0x04, 0x82, 0x01, 0x48, 0x3c, 0x3f, 0x78, 0x6d, 0x6c,
+ 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64,
+ 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54,
+ 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d, 0x2f,
+ 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, 0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e,
+ 0x30, 0x2f, 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
+ 0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c,
+ 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x3c,
+ 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x64, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73,
+ 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64,
+ 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x54, 0x35, 0x52, 0x77, 0x70, 0x55, 0x51, 0x58, 0x2f, 0x30, 0x64, 0x74, 0x6e,
+ 0x79, 0x4b, 0x51, 0x31, 0x6f, 0x4a, 0x6a, 0x4e, 0x33, 0x47, 0x44, 0x4e, 0x57, 0x6f, 0x3d, 0x0a, 0x09, 0x09, 0x3c, 0x2f,
+ 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x57, 0x79, 0x77,
+ 0x6b, 0x4c, 0x62, 0x65, 0x66, 0x5a, 0x52, 0x61, 0x68, 0x51, 0x69, 0x43, 0x74, 0x35, 0x6e, 0x55, 0x36, 0x62, 0x53, 0x4c,
+ 0x45, 0x43, 0x72, 0x63, 0x3d, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x61,
+ 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73,
+ 0x74, 0x3e, 0x0a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+ 0x01, 0x00, 0x16, 0xb5, 0x73, 0xd6, 0x0e, 0x26, 0x56, 0xd7, 0x72, 0x6b, 0x2a, 0xd9, 0xe7, 0xac, 0x53, 0x8c, 0x05, 0x4a,
+ 0x83, 0x8b, 0x38, 0x56, 0xf8, 0xec, 0xbc, 0x72, 0xf0, 0xfb, 0x2a, 0xba, 0x7b, 0x4c, 0x67, 0x3f, 0x42, 0x47, 0x58, 0xf2,
+ 0xb4, 0x94, 0x8e, 0x07, 0x01, 0x08, 0x3b, 0xeb, 0xd0, 0x90, 0x9f, 0xad, 0xa9, 0xb5, 0x5b, 0x12, 0x88, 0x73, 0x1b, 0xf1,
+ 0x6e, 0x1e, 0xc2, 0x0a, 0x15, 0xbd, 0x2a, 0xe9, 0xf9, 0xf2, 0x32, 0x92, 0x82, 0x71, 0x49, 0x11, 0xa8, 0x00, 0x51, 0x2e,
+ 0xa4, 0xcb, 0xff, 0x50, 0xdb, 0x50, 0x7e, 0x63, 0x1a, 0xcd, 0x26, 0xb7, 0xb4, 0x84, 0x3a, 0x27, 0x17, 0xe1, 0x55, 0xa5,
+ 0xeb, 0xa7, 0xe0, 0x5c, 0x03, 0x4d, 0x16, 0xe7, 0xbc, 0xd1, 0xf9, 0x12, 0x9a, 0xf8, 0xb0, 0xc9, 0x23, 0xb8, 0xcf, 0x5e,
+ 0xbb, 0x2d, 0xee, 0x5d, 0xfa, 0xa6, 0xfb, 0x0b, 0x0a, 0x62, 0xf5, 0x2e, 0x3e, 0x52, 0x44, 0x80, 0x54, 0x12, 0x34, 0xdf,
+ 0xae, 0x86, 0x68, 0xf4, 0x7c, 0x70, 0xd5, 0x55, 0x35, 0x3e, 0x9c, 0x78, 0x92, 0x17, 0x9e, 0xe9, 0x11, 0xa8, 0x52, 0x0b,
+ 0x47, 0xd9, 0x98, 0xdb, 0xd9, 0xa2, 0xb7, 0x25, 0x2d, 0xfa, 0x51, 0x6d, 0x3a, 0x8e, 0x32, 0xe7, 0xfa, 0x8b, 0xfb, 0x5a,
+ 0x2e, 0xd7, 0x7f, 0xdf, 0x54, 0xfb, 0x76, 0xb9, 0x0d, 0x2a, 0x7d, 0xb4, 0x98, 0x58, 0x23, 0x10, 0x85, 0x42, 0xc3, 0x67,
+ 0xb5, 0xd5, 0x90, 0xc9, 0xeb, 0x2c, 0x4e, 0xeb, 0x29, 0xac, 0x92, 0x1e, 0xc4, 0x8c, 0xd6, 0x21, 0x4a, 0xf0, 0x56, 0x77,
+ 0x5f, 0x4f, 0x43, 0xaf, 0x9a, 0xbd, 0x36, 0x74, 0xb8, 0xf3, 0xdb, 0xd3, 0x54, 0xfe, 0x5a, 0x7f, 0x03, 0x54, 0x8c, 0x06,
+ 0xa6, 0xf0, 0x70, 0xa6, 0x32, 0x39, 0x1e, 0xed, 0xd7, 0x51, 0x9a, 0x2e, 0xd0, 0x1c, 0xec, 0xe1, 0x91, 0xf7, 0xa1, 0x82,
+ 0x10, 0xd0, 0x30, 0x82, 0x10, 0xcc, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, 0x31,
+ 0x82, 0x10, 0xbb, 0x30, 0x82, 0x10, 0xb7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82,
+ 0x10, 0xa8, 0x30, 0x82, 0x10, 0xa4, 0x02, 0x01, 0x03, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+ 0x05, 0x00, 0x30, 0x7b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0xa0, 0x6c, 0x04,
+ 0x6a, 0x30, 0x68, 0x02, 0x01, 0x01, 0x06, 0x05, 0x2a, 0x03, 0x04, 0x05, 0x06, 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0xd3, 0x4c, 0x00, 0xe3, 0x42, 0xf2, 0x47, 0x6d,
+ 0xb2, 0xb4, 0x81, 0xa9, 0x1e, 0x24, 0x5e, 0x94, 0x18, 0x2f, 0xc3, 0x6e, 0x31, 0x63, 0xb2, 0xf5, 0xc8, 0x5d, 0x6d, 0xbb,
+ 0x11, 0x6b, 0xb1, 0xb7, 0x02, 0x08, 0x45, 0x46, 0x80, 0x73, 0xbe, 0xbb, 0xd4, 0x86, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37,
+ 0x30, 0x37, 0x31, 0x30, 0x31, 0x30, 0x33, 0x32, 0x33, 0x33, 0x5a, 0x30, 0x03, 0x02, 0x01, 0x01, 0x02, 0x09, 0x00, 0xae,
+ 0x6c, 0xb5, 0x96, 0x2d, 0x6c, 0x0c, 0x95, 0xa0, 0x82, 0x0d, 0xd0, 0x30, 0x82, 0x05, 0x02, 0x30, 0x82, 0x03, 0xea, 0xa0,
+ 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x1e, 0x66, 0x56, 0xac, 0xcd, 0x48, 0x6e, 0xe8, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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,
+ 0x37, 0x30, 0x36, 0x32, 0x38, 0x31, 0x39, 0x32, 0x32, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x38, 0x30, 0x39,
+ 0x31, 0x39, 0x32, 0x32, 0x33, 0x38, 0x5a, 0x30, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x14,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x4c, 0x54, 0x4e,
+ 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, 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, 0xdd, 0xea, 0xf8, 0x32, 0xf9, 0x08, 0x78, 0xa6, 0x16, 0xa5, 0x81, 0xab, 0xb9,
+ 0x18, 0x71, 0xf5, 0xe5, 0xee, 0x2f, 0x29, 0xf4, 0x8c, 0xcc, 0xd4, 0x3e, 0xf8, 0xe7, 0x87, 0xa1, 0xa6, 0xb2, 0x3e, 0x68,
+ 0x84, 0x78, 0x51, 0x8b, 0x58, 0xd5, 0xe9, 0x94, 0x4b, 0xf7, 0x84, 0x83, 0x8a, 0xa8, 0x84, 0xaf, 0xef, 0xa3, 0xa5, 0x09,
+ 0xbd, 0xf8, 0xbf, 0xe7, 0xbb, 0xe0, 0x2f, 0x81, 0x43, 0x48, 0x85, 0x0a, 0x69, 0xe6, 0x2b, 0x3f, 0xeb, 0x4b, 0x56, 0x2d,
+ 0xf4, 0xca, 0xeb, 0x7b, 0xe8, 0x81, 0x76, 0xef, 0xf9, 0xe5, 0x6d, 0xfb, 0xd6, 0xf9, 0x5f, 0x70, 0xd4, 0xb8, 0x5c, 0x3c,
+ 0xcf, 0x04, 0xdc, 0xbc, 0x2d, 0xe6, 0x64, 0xf8, 0xd4, 0x59, 0x85, 0xd3, 0x91, 0x31, 0x33, 0x4b, 0x0d, 0x13, 0x27, 0x56,
+ 0x2a, 0x8a, 0x77, 0x5e, 0x31, 0x9d, 0x82, 0x19, 0xab, 0xf5, 0xe7, 0x07, 0xe2, 0x71, 0x6f, 0xd6, 0x17, 0x22, 0x8e, 0xe8,
+ 0x0c, 0xbb, 0x2f, 0xdb, 0x72, 0x9a, 0xb5, 0xa9, 0x0d, 0x45, 0x1e, 0x83, 0x62, 0xaf, 0x72, 0x90, 0x80, 0x20, 0x72, 0x88,
+ 0xaf, 0x8d, 0x03, 0x79, 0x16, 0x4c, 0x71, 0xf2, 0x5b, 0x9e, 0xb2, 0xab, 0x08, 0xaf, 0x69, 0x1f, 0xa7, 0x1a, 0xf9, 0xf3,
+ 0xdb, 0x00, 0xfe, 0x7a, 0xd8, 0x41, 0x63, 0x32, 0x8c, 0x8e, 0xba, 0x96, 0x49, 0x08, 0xd8, 0x71, 0x68, 0xec, 0x42, 0x6a,
+ 0x2d, 0x60, 0x6d, 0xf3, 0x5b, 0x1f, 0xae, 0x5a, 0x36, 0xaa, 0x58, 0xad, 0x72, 0x9d, 0x30, 0x82, 0xec, 0xdd, 0x67, 0x6d,
+ 0xbe, 0xd9, 0xcb, 0xd6, 0x66, 0x54, 0x76, 0xc2, 0x89, 0xa0, 0xba, 0x86, 0xd5, 0xd8, 0x2f, 0x2b, 0x8d, 0x4d, 0xa7, 0xe9,
+ 0x46, 0x18, 0xb2, 0xa3, 0x61, 0x20, 0x3a, 0x30, 0x83, 0xb2, 0xea, 0x42, 0x8c, 0x18, 0xc8, 0x75, 0x36, 0x81, 0xeb, 0xb0,
+ 0x05, 0x9b, 0xd7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc1, 0x30, 0x82, 0x01, 0xbd, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x28, 0xe1, 0x58, 0x8c, 0x9b, 0x4e, 0xba, 0x68, 0xda, 0x07, 0x78, 0x0e, 0x6f,
+ 0x25, 0x89, 0x5e, 0xb1, 0x17, 0x49, 0xd9, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+ 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde,
+ 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
+ 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6, 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e,
+ 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79,
+ 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61,
+ 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65,
+ 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
+ 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30,
+ 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70,
+ 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x63, 0x72,
+ 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06,
+ 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+ 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+ 0x00, 0x1f, 0x6f, 0x37, 0x73, 0xdf, 0x84, 0x8f, 0xbb, 0xe9, 0x1b, 0xda, 0xa2, 0x67, 0x5f, 0xcf, 0x2a, 0x0c, 0x06, 0x88,
+ 0x2f, 0x47, 0x9c, 0xb8, 0x37, 0xa2, 0x4e, 0x14, 0x6d, 0xb2, 0x24, 0x8e, 0x41, 0x81, 0x24, 0xa0, 0x94, 0x28, 0xea, 0xed,
+ 0xda, 0x87, 0x63, 0x5d, 0xb6, 0x88, 0xf6, 0xa6, 0xc5, 0x86, 0xda, 0x6d, 0xf0, 0x46, 0x23, 0x4a, 0xb1, 0xf5, 0xbc, 0x89,
+ 0xf5, 0xbd, 0x30, 0xed, 0xa3, 0xb8, 0x18, 0x4e, 0x12, 0x4d, 0x95, 0xfc, 0xbc, 0xad, 0xbf, 0xb2, 0x2f, 0x82, 0x9a, 0xf1,
+ 0x04, 0xb7, 0xda, 0xbc, 0xd9, 0x35, 0x14, 0x59, 0x98, 0xc3, 0x57, 0x50, 0x5e, 0x74, 0x81, 0xc8, 0x6e, 0x8d, 0x44, 0x17,
+ 0xe3, 0x1c, 0x8a, 0xed, 0x36, 0x1e, 0x87, 0x16, 0xb1, 0x12, 0x65, 0x95, 0x33, 0x56, 0x86, 0xf5, 0xec, 0x58, 0xe9, 0x82,
+ 0x48, 0x56, 0x18, 0x6e, 0x5e, 0xb8, 0xec, 0x15, 0x06, 0x4c, 0x64, 0xeb, 0xcc, 0x69, 0xb4, 0x5d, 0xc7, 0x56, 0x26, 0x02,
+ 0xb3, 0xf9, 0x38, 0x68, 0x1b, 0x0e, 0x71, 0x86, 0x5d, 0x81, 0xcc, 0x1c, 0xae, 0x64, 0xee, 0x22, 0xf2, 0xe0, 0x8f, 0xfc,
+ 0xc0, 0x88, 0x85, 0x6b, 0x8d, 0x69, 0x67, 0xd8, 0x00, 0xf5, 0x3b, 0x81, 0x5b, 0xbe, 0x35, 0x14, 0x2a, 0x9e, 0x10, 0xd5,
+ 0xcc, 0xa0, 0xdc, 0x8f, 0x44, 0xb2, 0xb1, 0xea, 0xbf, 0x02, 0x97, 0x31, 0x43, 0xa1, 0x1a, 0xe1, 0xfa, 0x09, 0xf1, 0x1f,
+ 0xef, 0x35, 0x82, 0x6b, 0x86, 0x98, 0x1c, 0xca, 0xee, 0x8e, 0x3c, 0x08, 0xa1, 0xbc, 0x69, 0xbf, 0xb9, 0x72, 0xe7, 0x97,
+ 0x81, 0x45, 0x7a, 0x74, 0xa6, 0x2c, 0xd9, 0x3a, 0xd0, 0xe6, 0x56, 0xe8, 0x5b, 0x7c, 0x63, 0x46, 0x1c, 0xaf, 0xa6, 0x25,
+ 0x4d, 0x19, 0x3c, 0x18, 0x63, 0x55, 0xb1, 0x0b, 0x8c, 0x3d, 0x89, 0xa2, 0xd4, 0x36, 0x08, 0xc7, 0x20, 0x30, 0x82, 0x04,
+ 0x07, 0x30, 0x82, 0x02, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7d, 0x4c, 0x57, 0x63, 0x9f, 0xf3, 0xf0, 0xb7,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+ 0x32, 0x30, 0x34, 0x30, 0x35, 0x31, 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x34, 0x30, 0x35,
+ 0x31, 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27,
+ 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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, 0xd3, 0x77, 0x18, 0xa1, 0xf7, 0x99, 0x10, 0x67, 0x5c, 0xd2, 0x2e, 0x9e, 0xb8, 0x8f,
+ 0x23, 0x67, 0x3e, 0xfc, 0x42, 0xe2, 0x09, 0x7d, 0x0a, 0x8a, 0xb8, 0x18, 0xfc, 0x73, 0x40, 0x2f, 0xbd, 0xc4, 0xd8, 0x50,
+ 0xc5, 0x27, 0xc8, 0xfe, 0xb8, 0x34, 0x70, 0xa0, 0x0d, 0x13, 0x3c, 0xbd, 0x08, 0x4e, 0x9a, 0x93, 0x6f, 0x39, 0x37, 0xda,
+ 0x9e, 0x65, 0xf5, 0xb4, 0x63, 0xf4, 0x90, 0xc8, 0x49, 0x6d, 0x5d, 0x20, 0xd3, 0x39, 0xfd, 0x09, 0xba, 0xf4, 0x3a, 0xf3,
+ 0xce, 0x4a, 0x69, 0x64, 0x05, 0x99, 0x46, 0xe0, 0xda, 0x35, 0xc4, 0x65, 0x18, 0x1e, 0xc6, 0x16, 0xa3, 0x12, 0x61, 0xb4,
+ 0x2e, 0xf5, 0xf0, 0x89, 0x0d, 0x8c, 0xdc, 0x3d, 0xf6, 0x06, 0xcf, 0x6f, 0x86, 0x25, 0x4c, 0x09, 0xc2, 0x1b, 0xc8, 0x0e,
+ 0x78, 0x88, 0x8d, 0xc1, 0x22, 0xb8, 0xba, 0x21, 0x13, 0x9b, 0xca, 0xee, 0x8a, 0x9e, 0xdd, 0x7b, 0x5b, 0xff, 0xa3, 0xe9,
+ 0xd1, 0xa3, 0x81, 0x7e, 0xfe, 0xff, 0xe6, 0x8c, 0x49, 0xe4, 0x3b, 0x0a, 0xf9, 0x10, 0xa6, 0x72, 0x33, 0xbb, 0x2c, 0xc4,
+ 0x4a, 0x5a, 0x72, 0x0a, 0x39, 0x50, 0x74, 0xdd, 0x28, 0x6e, 0x79, 0x5f, 0x7e, 0xa7, 0xa8, 0x14, 0xcf, 0x56, 0xb3, 0x56,
+ 0x6c, 0xa5, 0xe9, 0xf0, 0xc4, 0xae, 0xf9, 0xea, 0x20, 0x8e, 0x18, 0xc7, 0x28, 0x74, 0xe2, 0x08, 0x4d, 0x89, 0x26, 0x42,
+ 0x79, 0x5e, 0xf6, 0x60, 0xe3, 0x45, 0x58, 0xa1, 0xfb, 0x51, 0x49, 0x5e, 0x92, 0x4a, 0x4d, 0xb9, 0xef, 0xd4, 0x73, 0xb5,
+ 0xda, 0x04, 0x7b, 0xe3, 0x52, 0x9f, 0xcb, 0xa3, 0x19, 0x5d, 0xac, 0x6b, 0x98, 0x6c, 0x9e, 0xe2, 0xec, 0x74, 0x2d, 0x44,
+ 0x3e, 0xe0, 0x61, 0x3e, 0x07, 0x45, 0x7e, 0x34, 0x75, 0x26, 0x98, 0x40, 0x9b, 0x75, 0x9e, 0xc8, 0x30, 0xed, 0x4b, 0xbf,
+ 0x77, 0x8f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+ 0x04, 0x16, 0x04, 0x14, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29,
+ 0xde, 0xf2, 0x1c, 0x93, 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, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76,
+ 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d,
+ 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63,
+ 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10,
+ 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x09, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x36, 0xd2, 0xf5, 0xde,
+ 0x71, 0x53, 0x07, 0xc9, 0x23, 0xd8, 0x78, 0x9b, 0x65, 0xbc, 0xf3, 0xd5, 0x5b, 0xe9, 0xb8, 0x7f, 0x1b, 0x23, 0xc7, 0xa2,
+ 0xcf, 0xb4, 0xa9, 0x28, 0xe9, 0xf8, 0xdd, 0x70, 0x88, 0x21, 0x39, 0xf3, 0xdb, 0x33, 0x9c, 0xc3, 0x72, 0x43, 0xd6, 0x3d,
+ 0x42, 0x51, 0x97, 0xba, 0xad, 0x1d, 0x8e, 0x92, 0xd2, 0x75, 0x8b, 0xc3, 0x5d, 0x9c, 0xf5, 0xcb, 0x8c, 0xdc, 0x6a, 0x6a,
+ 0x3a, 0xdd, 0xeb, 0x54, 0x7d, 0xed, 0x14, 0x6b, 0xf3, 0xd6, 0x3e, 0x93, 0xc8, 0x6d, 0x7a, 0x54, 0x5f, 0xf2, 0x43, 0x8e,
+ 0x10, 0xd0, 0x76, 0x5c, 0x9b, 0x00, 0x0c, 0x1d, 0x4e, 0xca, 0x3c, 0xcd, 0xfa, 0xe6, 0xf7, 0xc2, 0x3e, 0x72, 0xb7, 0xb8,
+ 0xde, 0xe8, 0x34, 0xaa, 0x15, 0xa0, 0xae, 0x5c, 0x67, 0xa8, 0x0c, 0xac, 0x9b, 0x1e, 0x65, 0xb3, 0xe3, 0x0f, 0x30, 0x42,
+ 0x34, 0xe9, 0xae, 0xd3, 0x01, 0xd3, 0xa7, 0xdd, 0x42, 0x73, 0x75, 0x7c, 0x51, 0x43, 0x85, 0x9a, 0x60, 0x10, 0xdc, 0xae,
+ 0x27, 0xd2, 0x6b, 0x67, 0xc9, 0x33, 0x45, 0x6f, 0xc9, 0x98, 0x1e, 0xa0, 0x9a, 0x7f, 0x4d, 0x11, 0x93, 0xe1, 0x69, 0xff,
+ 0xec, 0x4b, 0x45, 0xf3, 0x4e, 0xca, 0x22, 0x0e, 0x57, 0xd7, 0x22, 0x07, 0xe5, 0x22, 0xb4, 0x87, 0xe9, 0x9c, 0xd3, 0x45,
+ 0xcb, 0x6e, 0x3f, 0xe5, 0x8e, 0xb8, 0xfc, 0x46, 0xd5, 0x5c, 0xc9, 0xb0, 0xab, 0x05, 0x3a, 0x6d, 0x37, 0x28, 0xa3, 0xa8,
+ 0x46, 0x65, 0x6f, 0x55, 0xa1, 0x68, 0x88, 0xea, 0x52, 0x3e, 0xc9, 0xf4, 0xd4, 0xe6, 0xfa, 0x3f, 0xa4, 0xe4, 0x26, 0x80,
+ 0xb5, 0x3a, 0x6b, 0xd6, 0xc3, 0xe5, 0xf9, 0x32, 0x81, 0xc8, 0x32, 0xa2, 0x48, 0xe1, 0x8e, 0x06, 0xa3, 0x19, 0xe4, 0xb3,
+ 0xcb, 0x3b, 0x4b, 0xdf, 0xe0, 0xcc, 0x0e, 0xb2, 0xaf, 0x98, 0xd1, 0x83, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3,
+ 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x05, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
+ 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+ 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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,
+ 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+ 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a,
+ 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05,
+ 0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5,
+ 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66,
+ 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b,
+ 0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f,
+ 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d,
+ 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac,
+ 0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a,
+ 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92,
+ 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1,
+ 0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41,
+ 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c,
+ 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1,
+ 0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 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, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08,
+ 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76,
+ 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03,
+ 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+ 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65,
+ 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+ 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65,
+ 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
+ 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e,
+ 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+ 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c,
+ 0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47,
+ 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f,
+ 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20,
+ 0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56,
+ 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f,
+ 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5,
+ 0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09,
+ 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7,
+ 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c,
+ 0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7,
+ 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a,
+ 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0,
+ 0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, 0x21, 0x31, 0x82, 0x02, 0x3f, 0x30, 0x82, 0x02, 0x3b, 0x02, 0x01, 0x01, 0x30, 0x81,
+ 0x88, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x02, 0x08, 0x1e, 0x66, 0x56, 0xac, 0xcd, 0x48, 0x6e, 0xe8, 0x30, 0x09, 0x06,
+ 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0xa0, 0x81, 0x8c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0x30,
+ 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x37,
+ 0x31, 0x30, 0x31, 0x30, 0x33, 0x32, 0x33, 0x33, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0xac, 0xa5, 0xf2, 0x94, 0xd6, 0x0b, 0x65, 0x54, 0x09, 0xf8, 0xad, 0x9d, 0x40, 0x93,
+ 0xda, 0x9f, 0x82, 0xef, 0xb6, 0x86, 0x30, 0x2b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02,
+ 0x0c, 0x31, 0x1c, 0x30, 0x1a, 0x30, 0x18, 0x30, 0x16, 0x04, 0x14, 0x64, 0x2b, 0x13, 0x96, 0x1d, 0x64, 0x33, 0xd4, 0xdf,
+ 0x33, 0xb3, 0x04, 0x94, 0xd1, 0x70, 0xbe, 0x43, 0x2c, 0xfb, 0xdf, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x90, 0x6d, 0x04, 0x4c, 0x96, 0x25, 0x41, 0xaa, 0x66, 0x0a,
+ 0x17, 0x90, 0xdb, 0x28, 0x99, 0xe4, 0x40, 0x81, 0x25, 0xca, 0xd7, 0x47, 0xa6, 0x95, 0x71, 0x95, 0x68, 0x20, 0xb4, 0xfb,
+ 0xbd, 0x13, 0x17, 0x54, 0x2e, 0x56, 0x0f, 0x7b, 0xa3, 0x65, 0x17, 0xda, 0x94, 0x48, 0x7e, 0xc9, 0xc7, 0xf2, 0xb9, 0x96,
+ 0xbd, 0xd7, 0xf5, 0xbd, 0xc3, 0x63, 0xe0, 0x95, 0x0b, 0x2d, 0xfc, 0xb2, 0x37, 0xeb, 0xe0, 0xc5, 0x0f, 0xfd, 0xc7, 0x61,
+ 0x70, 0xcf, 0x5f, 0x35, 0xca, 0x48, 0xf1, 0xb0, 0x20, 0x27, 0xb3, 0x8e, 0x8b, 0x1a, 0xda, 0xeb, 0x0b, 0x55, 0xa6, 0xd5,
+ 0x2f, 0x9d, 0x7b, 0x53, 0xbd, 0x24, 0x19, 0x06, 0xf8, 0x5e, 0xb5, 0x12, 0x55, 0x0c, 0x49, 0x4b, 0x96, 0xfb, 0x00, 0x2c,
+ 0xe1, 0xc9, 0xe6, 0x0a, 0x6b, 0x5a, 0x17, 0x29, 0xfb, 0x4d, 0xf1, 0xc5, 0xac, 0x14, 0xb0, 0xe5, 0xc1, 0xa0, 0xd7, 0x89,
+ 0x3e, 0xbf, 0x1b, 0xa3, 0x69, 0x70, 0xe2, 0x37, 0x17, 0x1d, 0xd5, 0x4a, 0x8b, 0xfe, 0x99, 0x9a, 0x43, 0xba, 0x9f, 0xc3,
+ 0xc9, 0x37, 0x7d, 0x4d, 0x6d, 0xb9, 0xb3, 0x46, 0x22, 0xc9, 0xc7, 0x5f, 0x59, 0x57, 0x19, 0xac, 0x7d, 0x8d, 0xad, 0x2a,
+ 0xad, 0xc8, 0x77, 0x8a, 0xcb, 0x44, 0xde, 0x2b, 0xdf, 0x95, 0xac, 0x9d, 0x10, 0x9e, 0x2a, 0xdb, 0x21, 0x9b, 0x21, 0x6f,
+ 0x72, 0x61, 0x13, 0xad, 0x49, 0x70, 0x52, 0xbf, 0xc6, 0xa2, 0x75, 0x97, 0xf5, 0xef, 0x2d, 0x86, 0x36, 0x2e, 0x07, 0x10,
+ 0x75, 0x41, 0xf8, 0x21, 0xc6, 0x2d, 0x5e, 0x34, 0x3a, 0xfb, 0x31, 0x1c, 0xf7, 0x13, 0x61, 0x42, 0x12, 0x53, 0xa2, 0x62,
+ 0x3c, 0x5b, 0x9f, 0x43, 0xb7, 0xae, 0xc5, 0x89, 0xa3, 0x85, 0xdb, 0xd9, 0x42, 0x0d, 0xda, 0x04, 0x0d, 0x9b, 0xd9, 0xe0,
+ 0xae, 0xa1, 0xa3, 0x90, 0xd0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#endif /* si_34_cms_timestamp_h */
--- /dev/null
+/*
+ * 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@
+ */
+
+#include "shared_regressions.h"
+
+#import <AssertMacros.h>
+#import <Foundation/Foundation.h>
+
+#import <Security/CMSDecoder.h>
+#import <Security/CMSEncoder.h>
+#import <Security/SecTrust.h>
+#include <utilities/SecCFRelease.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#if TARGET_OS_OSX
+#include <Security/CMSPrivate.h>
+#include <Security/tsaSupport.h>
+#endif
+
+#import "si-34-cms-timestamp.h"
+#import "si-cms-hash-agility-data.h" // for signing_identity_p12, hash agility attribute data
+
+static CMSSignerStatus test_verify_timestamp(NSData *content, NSData *message) {
+ CMSDecoderRef decoder = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CMSSignerStatus signerStatus = kCMSSignerUnsigned;
+
+ /* Create decoder and decode */
+ require_noerr_action(CMSDecoderCreate(&decoder), fail, fail("Failed to create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, [message bytes], [message length]), fail,
+ fail("Failed to update decoder with CMS message"));
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)content), fail,
+ fail("Failed to set detached content"));
+ require_noerr_action(CMSDecoderFinalizeMessage(decoder), fail, fail("Failed to finalize decoder"));
+
+ /* Get signer status */
+ require_action(policy = SecPolicyCreateBasicX509(), fail, fail("Failed to Create policy"));
+ require_noerr_action(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
+ fail, fail("Failed to copy Signer status"));
+
+fail:
+ CFReleaseNull(decoder);
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+ return signerStatus;
+}
+
+static void test_matching_messageImprint(void) {
+ /* If the timestamp is invalid, SecCmsSignerInfoVerifyUnAuthAttrs will fail, so the signer status will be
+ * kCMSSignerInvalidSignature. */
+ CMSSignerStatus expected_mismatch_result = kCMSSignerInvalidSignature;
+#if !TIMESTAMPING_SUPPORTED
+ expected_mismatch_result = kCMSSignerValid;
+#endif
+
+ is(test_verify_timestamp([NSData dataWithBytes:_developer_id_data length:sizeof(_developer_id_data)],
+ [NSData dataWithBytes:_developer_id_sig length:sizeof(_developer_id_sig)]),
+ kCMSSignerValid, "failed to verify good timestamped signature");
+ is(test_verify_timestamp([NSData dataWithBytes:_mismatched_content length:sizeof(_mismatched_content)],
+ [NSData dataWithBytes:_mismatched_timestamp length:sizeof(_mismatched_timestamp)]),
+ expected_mismatch_result, "successful verification of bad timestamped signature");
+}
+
+static void test_create_timestamp(void) {
+ CFArrayRef tmp_imported_items = NULL;
+ NSArray *imported_items = nil;
+ SecIdentityRef identity = nil;
+ CMSEncoderRef encoder = NULL;
+ CMSDecoderRef decoder = NULL;
+ CFDataRef message = NULL;
+ NSDictionary *attrValues = nil;
+
+ /* Import identity */
+ NSDictionary *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" };
+ NSData *p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)];
+ require_noerr_action(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options,
+ &tmp_imported_items), exit,
+ fail("Failed to import identity"));
+ imported_items = CFBridgingRelease(tmp_imported_items);
+ require_noerr_action([imported_items count] == 0 &&
+ [imported_items[0] isKindOfClass:[NSDictionary class]], exit,
+ fail("Wrong imported items output"));
+ identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]);
+ require_action(identity, exit, fail("Failed to get identity"));
+
+ /* Create encoder */
+ require_noerr_action(CMSEncoderCreate(&encoder), exit, fail("Failed to create CMS encoder"));
+ require_noerr_action(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit,
+ fail("Failed to set digest algorithm to SHA256"));
+
+ /* Set identity as signer */
+ require_noerr_action(CMSEncoderAddSigners(encoder, identity), exit, fail("Failed to add signer identity"));
+
+ /* Add hash agility attribute */
+ require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility), exit,
+ fail("Set hash agility flag"));
+ require_noerr_action(CMSEncoderSetAppleCodesigningHashAgility(encoder, (__bridge CFDataRef)[NSData dataWithBytes:attribute
+ length:sizeof(attribute)]),
+ exit, fail("Set hash agility data"));
+
+ /* Add hash agility v2 attribute */
+ attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20],
+ @(SEC_OID_SHA256) : [NSData dataWithBytes:(_attributev2 + 32) length:32],
+ };
+ require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgilityV2), exit,
+ fail("Set hash agility flag"));
+ require_noerr_action(CMSEncoderSetAppleCodesigningHashAgilityV2(encoder, (__bridge CFDictionaryRef)attrValues), exit,
+ fail("Set hash agility data"));
+
+#if TIMESTAMPING_SUPPORTED
+ /* Set timestamp context */
+ CmsMessageSetTSAContext(encoder, SecCmsTSAGetDefaultContext(NULL));
+#endif
+
+ /* Load content */
+ require_noerr_action(CMSEncoderSetHasDetachedContent(encoder, true), exit, fail("Failed to set detached content"));
+ require_noerr_action(CMSEncoderUpdateContent(encoder, content, sizeof(content)), exit, fail("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_action(CMSDecoderCreate(&decoder), exit, fail("Create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message),
+ CFDataGetLength(message)), exit,
+ fail("Update decoder with CMS message"));
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content
+ length:sizeof(content)]),
+ exit, fail("Set detached content"));
+ ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
+
+exit:
+ CFReleaseNull(encoder);
+ CFReleaseNull(decoder);
+ CFReleaseNull(message);
+#if TARGET_OS_OSX
+ // SecPKCS12Import adds the items to the keychain on macOS
+ NSDictionary *query = @{ (__bridge NSString*)kSecValueRef : (__bridge id)identity };
+ ok_status(SecItemDelete((__bridge CFDictionaryRef)query), "failed to remove identity from keychain");
+#else
+ pass("skip test on iOS");
+#endif
+ CFReleaseNull(identity);
+}
+
+static int ping_host(char *host_name){
+
+ struct sockaddr_in pin;
+ struct hostent *nlp_host;
+ int sd;
+ int port;
+ int retries = 5;
+
+ port=80;
+
+ //tries 5 times then give up
+ while ((nlp_host=gethostbyname(host_name))==0 && retries--){
+ printf("Resolve Error! (%s) %d\n", host_name, h_errno);
+ sleep(1);
+ }
+
+ if(nlp_host==0)
+ return 0;
+
+ bzero(&pin,sizeof(pin));
+ pin.sin_family=AF_INET;
+ pin.sin_addr.s_addr=htonl(INADDR_ANY);
+ pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr;
+ pin.sin_port=htons(port);
+
+ sd=socket(AF_INET,SOCK_STREAM,0);
+
+ if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){
+ printf("connect error! (%s) %d\n", host_name, errno);
+ close(sd);
+ return 0;
+ }
+ else{
+ close(sd);
+ return 1;
+ }
+}
+
+int si_34_cms_timestamp(int argc, char * const *argv) {
+ plan_tests(6);
+
+ test_matching_messageImprint();
+
+ if (!ping_host("timestamp.apple.com")) {
+ printf("Accessing timestamp.apple.com failed, check the network!\n");
+ return 0;
+ }
+ test_create_timestamp();
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Apple Inc. All Rights Reserved.
+ */
+
+#ifndef si_35_cms_expiration_time_h
+#define si_35_cms_expiration_time_h
+
+
+#endif /* si_35_cms_expiration_time_h */
+
+#include "si-cms-signing-identity-p12.h"
+
+uint8_t _css_content[] = {
+ 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x0a
+};
+
+uint8_t _css_gen_expiration_time[] = {
+ 0x30, 0x82, 0x21, 0x6c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x21, 0x5d, 0x30,
+ 0x82, 0x21, 0x59, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
+ 0x01, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x0e, 0xc1, 0x30, 0x82,
+ 0x05, 0x69, 0x30, 0x82, 0x04, 0x51, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x00, 0xe3, 0xd3, 0xe8, 0xe4, 0xcc, 0xd6,
+ 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x71, 0x31, 0x2b,
+ 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+ 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d,
+ 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 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, 0x38, 0x30, 0x31, 0x32,
+ 0x39, 0x32, 0x32, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x31, 0x32, 0x37, 0x32, 0x32, 0x33, 0x35,
+ 0x35, 0x32, 0x5a, 0x30, 0x3c, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x63, 0x73, 0x73, 0x73,
+ 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x30, 0x30, 0x33, 0x74, 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, 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, 0xe9, 0xad,
+ 0x73, 0xbc, 0xa2, 0x60, 0x1a, 0x44, 0x1d, 0x16, 0x2b, 0x21, 0x23, 0xdf, 0xe8, 0x1e, 0x74, 0xc2, 0xe8, 0x14, 0xb3, 0x60,
+ 0x17, 0x02, 0x8a, 0x54, 0xbf, 0xfd, 0x3e, 0x77, 0x7b, 0xdc, 0x55, 0x49, 0xd7, 0x05, 0x33, 0x6a, 0xd8, 0x4d, 0xa8, 0x2b,
+ 0xa1, 0xfd, 0xeb, 0xdf, 0xb6, 0xd5, 0x7b, 0x1a, 0x15, 0x02, 0xa3, 0x41, 0xc0, 0x71, 0x12, 0x13, 0x72, 0xe1, 0x8f, 0x23,
+ 0x65, 0x18, 0xde, 0x7f, 0x66, 0x7c, 0x49, 0x5d, 0x78, 0x75, 0xd7, 0xf6, 0xe2, 0x7c, 0x8c, 0x8d, 0xf6, 0xc7, 0x6d, 0x83,
+ 0x9e, 0xd9, 0x8b, 0xef, 0xd3, 0xb2, 0xab, 0x31, 0x19, 0x7f, 0xd1, 0x95, 0x0e, 0xaf, 0xe6, 0x16, 0xb8, 0x43, 0x23, 0xa5,
+ 0x93, 0xc4, 0x0f, 0x8f, 0xde, 0xf3, 0x38, 0xf6, 0x53, 0xbc, 0xdd, 0x5c, 0x3a, 0x5b, 0x06, 0x5e, 0xf1, 0x68, 0x82, 0x2e,
+ 0xee, 0x29, 0x5d, 0xfa, 0x3f, 0x0f, 0x06, 0xfa, 0xef, 0x8b, 0x54, 0x26, 0xc9, 0xd7, 0xff, 0x92, 0x4f, 0x13, 0x19, 0x6e,
+ 0x5b, 0x6f, 0x73, 0x58, 0x8e, 0x5d, 0xc1, 0xdf, 0x23, 0xe1, 0x27, 0xb9, 0x16, 0xd2, 0xe5, 0x67, 0x07, 0xc5, 0xcc, 0xe4,
+ 0xbe, 0xa6, 0xda, 0xfa, 0x37, 0xe6, 0xe1, 0xe1, 0xba, 0x05, 0x68, 0x84, 0xe3, 0xa2, 0xd9, 0xa9, 0x43, 0x93, 0x8b, 0xaa,
+ 0xd7, 0xc6, 0x98, 0x75, 0xde, 0xb2, 0xfe, 0x2c, 0x28, 0xbf, 0x58, 0x92, 0x60, 0xe5, 0xbc, 0xda, 0x0b, 0xc4, 0x5b, 0x8c,
+ 0x87, 0x45, 0xad, 0x62, 0x8c, 0x10, 0x6a, 0x31, 0x77, 0x4e, 0x48, 0xc0, 0x76, 0x79, 0x29, 0x91, 0xb3, 0x66, 0x82, 0xeb,
+ 0xb2, 0x35, 0xd1, 0xc3, 0x5a, 0x2b, 0x13, 0xda, 0x24, 0xf7, 0xa8, 0xad, 0xb7, 0xd2, 0xaf, 0x98, 0xa1, 0x93, 0x43, 0x9a,
+ 0x07, 0xf8, 0xb5, 0xce, 0xe5, 0x1c, 0xc9, 0x46, 0x63, 0x50, 0x79, 0xa5, 0x1e, 0x1f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+ 0x82, 0x02, 0x38, 0x30, 0x82, 0x02, 0x34, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+ 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d,
+ 0x92, 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 0x30, 0x56, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x4a, 0x30, 0x48, 0x30, 0x46, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x01, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x75, 0x61, 0x74, 0x2e,
+ 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30,
+ 0x33, 0x2d, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67, 0x32,
+ 0x30, 0x31, 0x30, 0x82, 0x01, 0x03, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x81, 0xfb, 0x30, 0x81, 0xf8, 0x30, 0x81, 0xf5,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xe7, 0x30, 0x81, 0xac, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0x9f, 0x0c, 0x81, 0x9c, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63,
+ 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, 0x73, 0x75,
+ 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x65, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73,
+ 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61,
+ 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x30, 0x36, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+ 0x01, 0x16, 0x2a, 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, 0x2f, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0d, 0x30, 0x0b, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x42, 0x30,
+ 0x40, 0x30, 0x3e, 0xa0, 0x3c, 0xa0, 0x3a, 0x86, 0x38, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2d,
+ 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74,
+ 0x65, 0x73, 0x74, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x63, 0x61, 0x67,
+ 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3,
+ 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b, 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x11, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x63, 0x64, 0x06, 0x01, 0x1d, 0x02, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0xbe, 0xc8, 0x17, 0x96, 0xe9, 0x50, 0x1e, 0xfa,
+ 0xfb, 0xa8, 0x99, 0x83, 0xc4, 0x68, 0x3a, 0xc5, 0xb7, 0x80, 0x7a, 0xb0, 0x59, 0x6c, 0xb6, 0x0c, 0xb1, 0xee, 0x40, 0x9a,
+ 0x18, 0x11, 0x45, 0x16, 0x97, 0xad, 0xd7, 0xe5, 0x10, 0xa2, 0x1f, 0x3c, 0xdd, 0x63, 0xcb, 0xc9, 0x72, 0xd3, 0x6e, 0x72,
+ 0x4d, 0x90, 0xc4, 0xb2, 0x16, 0x95, 0x16, 0x1c, 0x12, 0x2a, 0xd0, 0xb6, 0x65, 0x4c, 0x54, 0x7e, 0xe0, 0xa6, 0xb7, 0x06,
+ 0x85, 0x07, 0xac, 0x3f, 0x05, 0x51, 0xcb, 0xd5, 0x20, 0x6a, 0x47, 0x16, 0xb9, 0x6e, 0xd3, 0x93, 0xa1, 0xd6, 0xbc, 0xe2,
+ 0x15, 0x25, 0x0b, 0x7c, 0xc1, 0x72, 0xcd, 0xee, 0x64, 0xbe, 0x5f, 0x4e, 0xb4, 0xf5, 0x1d, 0x6d, 0x6c, 0xc5, 0x37, 0xf6,
+ 0xb8, 0xb3, 0xfc, 0xc2, 0x41, 0x01, 0x79, 0x0c, 0x68, 0x2b, 0x24, 0x86, 0xe8, 0x6f, 0x55, 0x19, 0x59, 0x69, 0xa2, 0x36,
+ 0x01, 0x80, 0x22, 0x78, 0xad, 0xe6, 0xd8, 0xe9, 0xa8, 0x98, 0x75, 0xc7, 0xe8, 0x10, 0x37, 0x7c, 0x8a, 0x80, 0x06, 0xbf,
+ 0x24, 0xfb, 0xd6, 0xc0, 0x9f, 0xa3, 0x26, 0x7a, 0xee, 0x92, 0xbe, 0xea, 0x7a, 0x18, 0x88, 0x2a, 0xdf, 0xc5, 0x85, 0x1d,
+ 0x8a, 0x18, 0x66, 0xa9, 0xd5, 0xe5, 0x76, 0x23, 0xc0, 0x47, 0x4f, 0xc2, 0xb9, 0x6a, 0x46, 0x21, 0x8c, 0x6a, 0xd6, 0x95,
+ 0x04, 0x7d, 0x06, 0xa1, 0x91, 0xf5, 0x0c, 0x77, 0x9b, 0xb4, 0xbb, 0x21, 0xc6, 0xc0, 0x63, 0x5b, 0xe3, 0x47, 0x65, 0x71,
+ 0xe5, 0x55, 0x89, 0x17, 0xa9, 0x73, 0x70, 0xd0, 0xdf, 0x43, 0x9d, 0xfc, 0x1d, 0xb1, 0x6f, 0x73, 0x83, 0xd5, 0x89, 0x34,
+ 0xf6, 0x00, 0xa7, 0x87, 0x7d, 0x7b, 0x91, 0xc2, 0x15, 0x18, 0x38, 0x97, 0x7f, 0x81, 0x63, 0x34, 0x64, 0xaa, 0xa4, 0x00,
+ 0x40, 0x29, 0xbe, 0xfd, 0x96, 0x14, 0xfa, 0x30, 0x82, 0x04, 0x80, 0x30, 0x82, 0x03, 0x68, 0xa0, 0x03, 0x02, 0x01, 0x02,
+ 0x02, 0x08, 0x30, 0x0c, 0x95, 0xe4, 0x78, 0x4f, 0xf3, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70,
+ 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, 0x30, 0x39,
+ 0x32, 0x32, 0x30, 0x36, 0x31, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x5a, 0x30, 0x71, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x22, 0x54, 0x65, 0x73, 0x74, 0x20,
+ 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17,
+ 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, 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, 0xd9, 0xdc, 0x8b, 0xf5, 0x7a, 0x4e, 0xb8, 0xcb, 0xee, 0x25,
+ 0xb2, 0xd6, 0x6a, 0x36, 0x16, 0xd6, 0xf6, 0xdf, 0x9d, 0xd6, 0xcc, 0x65, 0xf3, 0xf4, 0x89, 0xb2, 0x06, 0x3e, 0x41, 0xfd,
+ 0xc2, 0xf8, 0x5a, 0x7b, 0x16, 0x90, 0x03, 0x9a, 0x60, 0x7c, 0xb0, 0x93, 0x1e, 0x20, 0xc0, 0x8a, 0xce, 0x13, 0x08, 0xd5,
+ 0x2e, 0x4d, 0x88, 0xd1, 0x10, 0xdc, 0xef, 0xc1, 0x62, 0x50, 0x5a, 0x8b, 0x77, 0x2e, 0x4f, 0x53, 0xa1, 0x0a, 0x0f, 0xb3,
+ 0xb1, 0xd2, 0x00, 0xd6, 0x6b, 0x6f, 0xa0, 0x20, 0x52, 0xe7, 0x91, 0x4e, 0x9e, 0xd0, 0x85, 0xa6, 0xcd, 0x76, 0x1a, 0xd0,
+ 0x58, 0x2a, 0x1d, 0xa2, 0x9b, 0xd4, 0xf7, 0xae, 0x05, 0xe7, 0x0a, 0xab, 0xd6, 0x0f, 0x74, 0x29, 0x5b, 0x88, 0x46, 0xc4,
+ 0x6b, 0x73, 0x4d, 0x56, 0x9d, 0x91, 0xb6, 0x11, 0xc5, 0xab, 0xc0, 0xc7, 0x19, 0x1d, 0x78, 0xe4, 0xa9, 0x2f, 0x8e, 0x0b,
+ 0x7f, 0x97, 0x85, 0x3a, 0x61, 0x32, 0x1d, 0x94, 0x59, 0x59, 0x30, 0xe6, 0xf7, 0xbc, 0x33, 0x74, 0x74, 0x54, 0x6e, 0xe8,
+ 0x90, 0xc9, 0xb4, 0xc6, 0x9a, 0xb7, 0x44, 0x02, 0xd7, 0x95, 0x60, 0x72, 0x4c, 0xe2, 0x8f, 0xe9, 0xf8, 0x53, 0x44, 0xd2,
+ 0x1a, 0x15, 0xac, 0x14, 0xe8, 0x93, 0x9c, 0xe6, 0xd8, 0xf1, 0xa3, 0xc1, 0x59, 0x29, 0x6f, 0x92, 0xb4, 0x53, 0xf4, 0x68,
+ 0x47, 0x9b, 0x81, 0xcf, 0xfc, 0x7c, 0xe8, 0x65, 0x6c, 0xcd, 0x54, 0x44, 0x80, 0x87, 0xef, 0x45, 0x07, 0x98, 0x82, 0x1d,
+ 0x07, 0x9b, 0xf2, 0x1f, 0xcc, 0x22, 0x81, 0x98, 0x18, 0xbf, 0x4c, 0x14, 0xb3, 0x2c, 0xa7, 0xae, 0x00, 0x9a, 0x7a, 0x3c,
+ 0x1e, 0xd1, 0x0d, 0xef, 0xeb, 0x95, 0xba, 0xd4, 0xd4, 0x8d, 0x75, 0x0f, 0xa0, 0x00, 0x01, 0x64, 0x98, 0x49, 0x17, 0x2b,
+ 0xe3, 0xfb, 0xeb, 0x3e, 0x4d, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x24, 0x30, 0x82, 0x01, 0x20, 0x30,
+ 0x51, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x35, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
+ 0x2d, 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x30, 0x33, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f, 0x6f, 0x74,
+ 0x63, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xbe, 0x46, 0x64, 0xc6, 0xc9, 0x6d, 0x92,
+ 0x89, 0x11, 0x41, 0x60, 0x91, 0x87, 0xf1, 0x64, 0x7c, 0x78, 0xd2, 0x7c, 0x94, 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, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59,
+ 0xc3, 0x54, 0x98, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33,
+ 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2d, 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72,
+ 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c,
+ 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0d, 0x30, 0x0b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x04, 0x01, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
+ 0x06, 0x02, 0x13, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0x1b, 0x61, 0x6c, 0x35, 0xb9, 0x13, 0xb9, 0xb9, 0xac, 0xdc, 0x31, 0x8a,
+ 0x9c, 0x09, 0xb0, 0x5a, 0xe4, 0x63, 0x07, 0x0e, 0x74, 0xeb, 0xe8, 0x37, 0x28, 0x62, 0x39, 0xdb, 0x25, 0xbe, 0x6c, 0xff,
+ 0xea, 0x1b, 0xd4, 0x3f, 0x50, 0x23, 0xbd, 0xa6, 0x91, 0x1c, 0xfe, 0x9c, 0x2f, 0x52, 0xb6, 0x67, 0x2b, 0xf1, 0x7a, 0x9c,
+ 0xd8, 0x66, 0x6c, 0x07, 0xeb, 0x11, 0x88, 0x68, 0x66, 0x2b, 0xb6, 0xd0, 0x72, 0xdb, 0xcc, 0x3a, 0xa8, 0xb8, 0xb8, 0x1f,
+ 0xd0, 0x05, 0xaa, 0xb3, 0xb2, 0x7b, 0xc1, 0xa9, 0xfe, 0x5e, 0xd3, 0x1b, 0xfb, 0x88, 0xba, 0x60, 0xbe, 0x1e, 0xb1, 0x63,
+ 0x8a, 0xae, 0x21, 0x35, 0xc6, 0xc0, 0x42, 0xe0, 0xa3, 0x1a, 0xc3, 0x37, 0x25, 0x5c, 0xc5, 0xca, 0x35, 0x65, 0x4d, 0x6d,
+ 0x9c, 0x13, 0x69, 0xb5, 0xde, 0x07, 0x4c, 0xf8, 0x54, 0x96, 0x9a, 0x60, 0x94, 0xca, 0x1d, 0xa3, 0xb7, 0xf6, 0x49, 0x86,
+ 0x26, 0x06, 0xa8, 0x6a, 0x70, 0x22, 0x54, 0x4a, 0xd4, 0xfd, 0xd8, 0x2d, 0xae, 0xc1, 0x35, 0x42, 0xac, 0x50, 0x03, 0xe3,
+ 0x34, 0xd7, 0x52, 0xb5, 0x9e, 0xeb, 0xb6, 0x41, 0x98, 0x0b, 0xdd, 0xec, 0xf9, 0x7e, 0x5a, 0x55, 0xd2, 0xf5, 0x4c, 0xb5,
+ 0x78, 0x1a, 0xd8, 0x23, 0x31, 0xff, 0x67, 0x7e, 0x7f, 0x05, 0xd6, 0x20, 0x7f, 0xe4, 0x34, 0xd4, 0xd3, 0x8e, 0x8d, 0x75,
+ 0xe1, 0x8c, 0xf1, 0x60, 0x26, 0x4b, 0x88, 0x87, 0x6b, 0xbd, 0x88, 0x1d, 0xe2, 0xa6, 0x9b, 0xbf, 0x4d, 0xed, 0xd7, 0x31,
+ 0x13, 0x8f, 0xa0, 0x64, 0x63, 0x27, 0xbc, 0x06, 0xce, 0x9d, 0x91, 0xa4, 0x8d, 0xd3, 0x10, 0x25, 0x0c, 0xe7, 0xac, 0xef,
+ 0x7f, 0x21, 0xf1, 0xfb, 0xca, 0x80, 0x28, 0x0c, 0x4a, 0xd4, 0x52, 0x61, 0xbc, 0x7c, 0x3b, 0x88, 0x54, 0x16, 0x0e, 0x5f,
+ 0x14, 0x99, 0x4f, 0x30, 0x82, 0x04, 0xcc, 0x30, 0x82, 0x03, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x3d, 0x00,
+ 0x4b, 0x90, 0x3e, 0xde, 0xe0, 0xd0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+ 0x00, 0x30, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30,
+ 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52,
+ 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x32, 0x30, 0x32, 0x31, 0x35,
+ 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x67,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+ 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 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, 0x1b, 0x30, 0x19, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x0c, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+ 0x20, 0x43, 0x41, 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, 0xc7, 0xd1, 0x43, 0x53,
+ 0x7f, 0x0d, 0x88, 0x6b, 0xe6, 0xb1, 0x67, 0x9d, 0xee, 0x67, 0xb6, 0xe7, 0x77, 0x12, 0x81, 0xc4, 0xdf, 0x24, 0x6b, 0x7a,
+ 0x75, 0x24, 0xf7, 0x01, 0x09, 0xce, 0x34, 0x92, 0xf5, 0x38, 0x08, 0x42, 0x7e, 0xec, 0x9d, 0xf2, 0x5d, 0x38, 0x91, 0xb4,
+ 0x93, 0x98, 0x35, 0x11, 0x3c, 0x98, 0x00, 0x77, 0xd9, 0xd7, 0xf3, 0x4a, 0xf8, 0xf0, 0xbc, 0xeb, 0x97, 0x5d, 0x4b, 0x61,
+ 0x2e, 0xfb, 0xc5, 0xcc, 0x68, 0xb7, 0x6d, 0x69, 0x10, 0xcc, 0xa5, 0x61, 0x78, 0xa8, 0x81, 0x02, 0x9e, 0xe7, 0x63, 0xc5,
+ 0xff, 0x29, 0x22, 0x82, 0x68, 0xaa, 0xaa, 0x0e, 0xfb, 0xa9, 0xd8, 0x16, 0x73, 0x25, 0xbf, 0x9d, 0x08, 0x62, 0x2f, 0x78,
+ 0x04, 0xf6, 0xf6, 0x44, 0x07, 0x37, 0x6e, 0x99, 0x1b, 0x93, 0xd8, 0x7f, 0xee, 0x72, 0xde, 0xe8, 0x32, 0xf6, 0x6d, 0x78,
+ 0x04, 0xa0, 0xa8, 0x21, 0x26, 0x8a, 0x32, 0xe3, 0xb1, 0x65, 0x85, 0xa1, 0x7b, 0x1a, 0xa9, 0x02, 0xb2, 0xbb, 0xee, 0xdd,
+ 0xdd, 0x8f, 0x41, 0x49, 0xc8, 0x3f, 0xdc, 0x1e, 0xdf, 0x21, 0xa3, 0x95, 0x99, 0xbb, 0xfc, 0x29, 0xba, 0x40, 0x43, 0xb9,
+ 0x1c, 0xcd, 0xc9, 0x21, 0x45, 0x73, 0xad, 0xff, 0xfd, 0xa2, 0x6c, 0x5c, 0x3b, 0x1c, 0x37, 0x91, 0x34, 0x8e, 0x5c, 0xd3,
+ 0xd5, 0x03, 0x58, 0x28, 0xc7, 0xf2, 0x76, 0x6f, 0x11, 0xc0, 0xb5, 0xbd, 0x7e, 0xef, 0x23, 0xb3, 0x3d, 0xb8, 0xbd, 0x38,
+ 0x66, 0x8c, 0xf2, 0x78, 0x95, 0xc1, 0x8b, 0x32, 0x65, 0x3a, 0x9b, 0x49, 0x1a, 0x5c, 0x41, 0x3c, 0xc6, 0x85, 0x50, 0xec,
+ 0x85, 0xf0, 0x59, 0x17, 0x81, 0xe8, 0x96, 0xe8, 0x6a, 0xcc, 0xb3, 0xc7, 0x46, 0xbf, 0x81, 0x48, 0xd1, 0x09, 0x1b, 0xbc,
+ 0x73, 0x1e, 0xd7, 0xe8, 0x27, 0xa8, 0x49, 0x48, 0xa2, 0x1c, 0x41, 0x1d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+ 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x59, 0xb8, 0x2b, 0x94,
+ 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23, 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 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, 0x59, 0xb8, 0x2b, 0x94, 0x3a, 0x1b, 0xba, 0xf1, 0x00, 0xae, 0xee, 0x50, 0x52, 0x23,
+ 0x33, 0xc9, 0x59, 0xc3, 0x54, 0x98, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30,
+ 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81,
+ 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73,
+ 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+ 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81,
+ 0xb6, 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73,
+ 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20,
+ 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74,
+ 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72,
+ 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66,
+ 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f,
+ 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x73, 0x2e, 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, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x10,
+ 0x5e, 0x6c, 0x69, 0xfc, 0xa6, 0x0f, 0xe2, 0x09, 0xd5, 0x94, 0x90, 0xa6, 0x7c, 0x22, 0xdc, 0xee, 0xb0, 0x8f, 0x24, 0x22,
+ 0x4f, 0xb3, 0x67, 0xdb, 0x32, 0xb0, 0xd6, 0x24, 0x87, 0xe6, 0xf3, 0xea, 0x9e, 0xd0, 0x95, 0x75, 0xaa, 0xa7, 0x08, 0xff,
+ 0xb0, 0x35, 0xd7, 0x1f, 0xa3, 0xbf, 0x89, 0x55, 0x0c, 0x1c, 0xa4, 0xd0, 0xf8, 0x00, 0x17, 0x44, 0x94, 0x36, 0x63, 0x3b,
+ 0x83, 0xfe, 0x4e, 0xe5, 0xb3, 0xec, 0x7b, 0x7d, 0xce, 0xfe, 0xa9, 0x54, 0xed, 0xbb, 0x12, 0xa6, 0x72, 0x2b, 0xb3, 0x48,
+ 0x00, 0xc7, 0x8e, 0xf5, 0x5b, 0x68, 0xc9, 0x24, 0x22, 0x7f, 0xa1, 0x4d, 0xfc, 0x54, 0xd9, 0xd0, 0x5d, 0x82, 0x53, 0x71,
+ 0x29, 0x66, 0xcf, 0x0f, 0x6d, 0x32, 0xa6, 0x3f, 0xae, 0x54, 0x27, 0xc2, 0x8c, 0x12, 0x4c, 0xf0, 0xd6, 0xc1, 0x80, 0x75,
+ 0xc3, 0x33, 0x19, 0xd1, 0x8b, 0x58, 0xe6, 0x00, 0x69, 0x76, 0xe7, 0xe5, 0x3d, 0x47, 0xf9, 0xc0, 0x9c, 0xe7, 0x19, 0x1e,
+ 0x95, 0xbc, 0x52, 0x15, 0xce, 0x94, 0xf8, 0x30, 0x14, 0x0b, 0x39, 0x0e, 0x8b, 0xaf, 0x29, 0x30, 0x56, 0xaf, 0x5a, 0x28,
+ 0xac, 0xe1, 0x0f, 0x51, 0x76, 0x76, 0x9a, 0xe7, 0xb9, 0x7d, 0xa3, 0x30, 0xe8, 0xe3, 0x71, 0x15, 0xe8, 0xbf, 0x0d, 0x4f,
+ 0x12, 0x9b, 0x65, 0xab, 0xef, 0xa4, 0xe9, 0x42, 0xf0, 0xd2, 0x4d, 0x20, 0x55, 0x29, 0x88, 0x58, 0x5c, 0x82, 0x67, 0x63,
+ 0x20, 0x50, 0xc6, 0xca, 0x04, 0xe8, 0xbc, 0x3d, 0x93, 0x06, 0x21, 0xb2, 0xc0, 0xbf, 0x53, 0x1e, 0xe1, 0x8b, 0x48, 0xa9,
+ 0xb9, 0xd7, 0xe6, 0x5f, 0x4e, 0x5a, 0x2f, 0x43, 0xac, 0x35, 0xbd, 0x26, 0x60, 0x2f, 0x01, 0xd5, 0x86, 0x6b, 0x64, 0xfa,
+ 0x67, 0x05, 0x44, 0x55, 0x83, 0x5b, 0x93, 0x9c, 0x7c, 0xa7, 0x26, 0x4e, 0x02, 0x2b, 0x48, 0x31, 0x82, 0x12, 0x71, 0x30,
+ 0x82, 0x12, 0x6d, 0x02, 0x01, 0x03, 0xa0, 0x16, 0x04, 0x14, 0x4e, 0xe9, 0xa9, 0xc3, 0x2e, 0x25, 0xd2, 0xa2, 0x7a, 0x8b,
+ 0x52, 0x3d, 0x16, 0x3c, 0xaf, 0xee, 0x41, 0xef, 0x79, 0x01, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x01, 0xa0, 0x69, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x51, 0xc4, 0xbf, 0xb0, 0x32, 0xf1, 0x05, 0x0d, 0xd1, 0x16, 0x4f, 0x18,
+ 0x9f, 0x54, 0x93, 0x36, 0x1c, 0x86, 0xad, 0x78, 0xcc, 0x14, 0x3f, 0xc1, 0xa5, 0x90, 0x1e, 0x78, 0x47, 0x05, 0xb4, 0x4d,
+ 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x03, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x39, 0x31,
+ 0x32, 0x33, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x31, 0xad, 0x1c, 0x21, 0x85, 0x6d, 0xc8, 0x51, 0x8e, 0x2f, 0x3d,
+ 0x61, 0x54, 0x81, 0x55, 0xf3, 0x2d, 0x36, 0xea, 0x73, 0x63, 0xdb, 0x3d, 0x32, 0x2b, 0xe8, 0x2b, 0xd0, 0xcc, 0x6d, 0xd3,
+ 0xcf, 0x00, 0xf7, 0xf0, 0x9a, 0x3b, 0x09, 0xe8, 0x00, 0xaa, 0x94, 0xd4, 0x6a, 0x0d, 0x94, 0xbf, 0x01, 0xe9, 0x45, 0x06,
+ 0x54, 0xa0, 0xa1, 0xce, 0xa0, 0x4e, 0x2d, 0x41, 0xc4, 0xd4, 0xb9, 0xe0, 0xdd, 0xc7, 0x48, 0x2f, 0x5f, 0x48, 0x65, 0xbc,
+ 0x4e, 0x91, 0x6c, 0x15, 0x98, 0x91, 0xaa, 0xf6, 0xc1, 0x2b, 0x97, 0xd2, 0x2d, 0xbf, 0x3b, 0x30, 0x4b, 0xb3, 0x7b, 0x3c,
+ 0x80, 0xb7, 0xcc, 0x67, 0x4f, 0x79, 0xb5, 0x6d, 0x6e, 0xe6, 0x43, 0x86, 0x17, 0x92, 0x88, 0x2d, 0x1e, 0x55, 0x03, 0xcc,
+ 0x67, 0x7a, 0xe7, 0xdb, 0xa3, 0x99, 0xd9, 0x51, 0x7d, 0xbf, 0x03, 0x53, 0xf4, 0x89, 0x70, 0xbb, 0x8d, 0xaf, 0x61, 0x84,
+ 0x88, 0x1b, 0xc2, 0xd8, 0x62, 0x55, 0x1d, 0x50, 0x9c, 0x48, 0xd2, 0xc6, 0x90, 0x22, 0x82, 0x01, 0xa0, 0x03, 0xab, 0x63,
+ 0x9a, 0xab, 0x94, 0xa2, 0x75, 0xf9, 0x97, 0x4a, 0x22, 0x3f, 0xd8, 0xfb, 0xb4, 0x62, 0x1e, 0x83, 0x2a, 0x86, 0x62, 0x15,
+ 0xbf, 0x4a, 0x8c, 0xf5, 0xa1, 0xc3, 0x8a, 0x8a, 0xa5, 0x1b, 0x00, 0x77, 0x6b, 0x04, 0x85, 0x11, 0x4d, 0x47, 0x11, 0xe0,
+ 0x8e, 0xaa, 0x86, 0x23, 0x1c, 0xef, 0x74, 0xdf, 0x90, 0x2b, 0xfb, 0xba, 0x61, 0x03, 0xc9, 0xd9, 0x59, 0x9b, 0xb1, 0x01,
+ 0x77, 0xba, 0x7e, 0x89, 0x1c, 0x3b, 0x65, 0xdf, 0x01, 0xd2, 0x61, 0xfe, 0x51, 0x87, 0x36, 0x4b, 0x91, 0x2a, 0x69, 0xad,
+ 0xa2, 0xcd, 0x0c, 0xee, 0xb7, 0xe5, 0xb0, 0xbf, 0x8b, 0xc4, 0x0b, 0xeb, 0xbf, 0x11, 0xaa, 0x26, 0x47, 0x9a, 0xc3, 0xfc,
+ 0x7d, 0x61, 0xeb, 0xed, 0x50, 0xa1, 0x82, 0x10, 0xc3, 0x30, 0x82, 0x10, 0xbf, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, 0x31, 0x82, 0x10, 0xae, 0x30, 0x82, 0x10, 0xaa, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x9b, 0x30, 0x82, 0x10, 0x97, 0x02, 0x01, 0x03, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x6d, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x09, 0x10, 0x01, 0x04, 0xa0, 0x5e, 0x04, 0x5c, 0x30, 0x5a, 0x02, 0x01, 0x01, 0x06, 0x02, 0x2a, 0x03, 0x30, 0x31, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0x7e, 0xbb, 0x6f, 0xa9,
+ 0x87, 0xe1, 0x0b, 0xa5, 0x7e, 0x3b, 0xef, 0x40, 0x89, 0x6a, 0x2b, 0x64, 0x42, 0x29, 0x71, 0x0f, 0x81, 0x1d, 0x26, 0x9b,
+ 0x0a, 0x84, 0x07, 0xbf, 0x63, 0x61, 0xde, 0x0a, 0x02, 0x08, 0x4a, 0x30, 0x03, 0xb3, 0xaf, 0xe2, 0xb0, 0x10, 0x18, 0x0f,
+ 0x32, 0x30, 0x31, 0x38, 0x30, 0x33, 0x32, 0x37, 0x32, 0x33, 0x34, 0x30, 0x35, 0x35, 0x5a, 0x30, 0x03, 0x02, 0x01, 0x01,
+ 0xa0, 0x82, 0x0d, 0xd1, 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x55,
+ 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65,
+ 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x38, 0x30, 0x33, 0x30, 0x36, 0x30, 0x31,
+ 0x33, 0x30, 0x30, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x34, 0x31, 0x37, 0x30, 0x31, 0x33, 0x30, 0x30, 0x33, 0x5a,
+ 0x30, 0x42, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+ 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x4e, 0x57, 0x4b, 0x32, 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, 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, 0xbc, 0x9b, 0x45, 0x28, 0x53, 0xe1, 0x51, 0xbf, 0xef, 0x09, 0x31, 0x1d, 0x75, 0x65, 0x97, 0x05, 0x46, 0x6e, 0x59,
+ 0x18, 0xc2, 0x6d, 0x3a, 0x85, 0x1d, 0x0d, 0x2e, 0x78, 0x7c, 0x50, 0xdf, 0x57, 0x02, 0x32, 0x4f, 0x6b, 0x13, 0xb6, 0x33,
+ 0xdd, 0xff, 0x44, 0x4a, 0xed, 0xdf, 0x6b, 0xcb, 0xd5, 0x21, 0xd2, 0x96, 0x40, 0x43, 0xde, 0x0f, 0x90, 0x8f, 0x29, 0x6a,
+ 0x09, 0xf4, 0xac, 0x43, 0xd6, 0xbc, 0x61, 0xbb, 0x47, 0xd7, 0xde, 0xba, 0x4e, 0x68, 0x3a, 0x42, 0x4b, 0x45, 0xcc, 0x76,
+ 0x15, 0xdb, 0x17, 0x3b, 0x51, 0xbf, 0x73, 0x85, 0x7e, 0x00, 0x2c, 0xa4, 0x0a, 0x94, 0x1e, 0x5c, 0x1b, 0x3b, 0x26, 0xe4,
+ 0x56, 0x52, 0xb5, 0xc2, 0x78, 0x56, 0xbf, 0x43, 0xb9, 0xab, 0xa2, 0x7a, 0x52, 0xbd, 0x3b, 0x3f, 0x7c, 0x11, 0x88, 0x5f,
+ 0x8c, 0xf3, 0x36, 0x00, 0xb1, 0xe6, 0x43, 0xdb, 0x84, 0xa4, 0x3e, 0x9e, 0x87, 0xcb, 0x09, 0x25, 0x71, 0x8a, 0x45, 0x9e,
+ 0xbb, 0x0a, 0x62, 0x4c, 0xfa, 0xcc, 0xaa, 0x97, 0xba, 0x6d, 0x90, 0x9e, 0x0d, 0x0c, 0xac, 0x60, 0xe7, 0x5e, 0x61, 0xa2,
+ 0xc5, 0x29, 0x5c, 0x64, 0x5f, 0xc3, 0xd8, 0x2c, 0xe7, 0x1b, 0x57, 0x32, 0x79, 0x97, 0xae, 0x97, 0x3f, 0x19, 0x1b, 0xe9,
+ 0xb9, 0x2a, 0x53, 0x23, 0xfc, 0x9b, 0x3c, 0x88, 0x90, 0xaa, 0x58, 0xde, 0x0b, 0x91, 0x45, 0xb1, 0x26, 0xb9, 0xc0, 0x6d,
+ 0x9e, 0x3b, 0x1e, 0x56, 0x19, 0x7a, 0xf2, 0x5f, 0xa9, 0x82, 0x9d, 0x88, 0xbe, 0x53, 0x10, 0x02, 0x7f, 0x80, 0x79, 0x15,
+ 0xc1, 0x60, 0xc7, 0xe0, 0xbf, 0xe9, 0x0c, 0x5c, 0x16, 0xb3, 0x6d, 0xda, 0x61, 0xb2, 0xe8, 0x6d, 0x26, 0xf1, 0xe2, 0xb1,
+ 0xea, 0x1d, 0x66, 0x42, 0xe7, 0x6c, 0x4a, 0xf2, 0xa4, 0xaa, 0x49, 0xfe, 0xfb, 0x7e, 0xbf, 0x5f, 0xbb, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc1, 0x30, 0x82, 0x01, 0xbd, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0x60, 0xd9, 0x78, 0x59, 0xea, 0xb0, 0x24, 0x26, 0x69, 0xac, 0xd9, 0xc1, 0xa3, 0xac, 0xb0, 0x50, 0xaa, 0x37, 0xcb,
+ 0x97, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55,
+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x34, 0xcd, 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26,
+ 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 0x30, 0x82, 0x01, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01,
+ 0x05, 0x30, 0x82, 0x01, 0x01, 0x30, 0x81, 0xfe, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30,
+ 0x81, 0xf0, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70,
+ 0x6c, 0x65, 0x63, 0x61, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6,
+ 0x0c, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
+ 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70,
+ 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61,
+ 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c,
+ 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d,
+ 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20,
+ 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c,
+ 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x73, 0x2e, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
+ 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01,
+ 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x34, 0xf6, 0x34, 0x61, 0x30,
+ 0x1c, 0x0a, 0xa4, 0xf1, 0x2a, 0x4e, 0x47, 0xf2, 0xb3, 0x5a, 0x6b, 0xfe, 0x9e, 0x33, 0x8f, 0xa6, 0x44, 0x8b, 0xd0, 0x37,
+ 0x2c, 0xff, 0x00, 0xb3, 0x83, 0xaf, 0x42, 0x2e, 0xa5, 0x98, 0x77, 0x5d, 0x1c, 0x75, 0xbd, 0xaa, 0x68, 0x62, 0x5b, 0xbe,
+ 0x59, 0x91, 0x9e, 0x58, 0xfd, 0xe4, 0x74, 0xe2, 0x7c, 0x5c, 0xb8, 0xb3, 0xb5, 0x66, 0xda, 0x78, 0xda, 0xf7, 0x58, 0x6f,
+ 0xcd, 0x50, 0x77, 0x01, 0xe3, 0x99, 0x84, 0xf2, 0x77, 0x66, 0xba, 0x7c, 0xbe, 0x97, 0xe9, 0x2d, 0x2e, 0x83, 0x2d, 0xcc,
+ 0x73, 0x3a, 0x6a, 0x42, 0xed, 0x58, 0xb0, 0x34, 0x7d, 0xe0, 0xa7, 0x48, 0x6b, 0xe9, 0x39, 0x92, 0xdf, 0x67, 0x05, 0xe5,
+ 0x01, 0x5e, 0xeb, 0x63, 0xc1, 0x35, 0x3a, 0x58, 0xdc, 0x44, 0x35, 0x39, 0x5c, 0xe5, 0xe0, 0x4d, 0x9b, 0x72, 0xb7, 0x0b,
+ 0x59, 0x5a, 0x4a, 0x0d, 0x07, 0x61, 0x5d, 0x0f, 0xf8, 0x19, 0x42, 0x10, 0xd9, 0x77, 0xaf, 0xdf, 0x3d, 0xac, 0x86, 0xf0,
+ 0x5f, 0x66, 0x11, 0x4d, 0x94, 0x38, 0x3f, 0xca, 0xb9, 0x0c, 0xbf, 0xbf, 0x7d, 0x00, 0x51, 0x74, 0x61, 0xd2, 0xc7, 0x75,
+ 0xab, 0xe4, 0x99, 0x0f, 0x18, 0xd2, 0x5e, 0x6d, 0xa0, 0x2a, 0x96, 0x52, 0x36, 0xa9, 0xa3, 0xbb, 0x20, 0xde, 0x0c, 0x6e,
+ 0xfa, 0x86, 0x25, 0xee, 0x05, 0x80, 0x7f, 0x56, 0x6a, 0xd7, 0xc8, 0xaa, 0xbc, 0x4b, 0x85, 0x94, 0xe8, 0x38, 0xc5, 0x45,
+ 0xd8, 0x15, 0x97, 0xde, 0x69, 0x1a, 0x14, 0x04, 0xa4, 0xfc, 0x84, 0x8c, 0xef, 0xe3, 0x23, 0x0d, 0xe1, 0x6b, 0x23, 0x5f,
+ 0xdf, 0x47, 0x93, 0x22, 0x24, 0xe8, 0x12, 0x2b, 0xbd, 0xd1, 0x6f, 0xcb, 0xb5, 0x65, 0x89, 0xa0, 0x9f, 0x78, 0xb3, 0xdb,
+ 0x55, 0xf5, 0x34, 0x41, 0x99, 0x00, 0xd8, 0x31, 0x49, 0x00, 0xb9, 0x30, 0x82, 0x04, 0x07, 0x30, 0x82, 0x02, 0xef, 0xa0,
+ 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7d, 0x4c, 0x57, 0x63, 0x9f, 0xf3, 0xf0, 0xb7, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c,
+ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x35, 0x31,
+ 0x32, 0x30, 0x32, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x34, 0x30, 0x35, 0x31, 0x32, 0x30, 0x32, 0x34, 0x34,
+ 0x5a, 0x30, 0x7c, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 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,
+ 0xd3, 0x77, 0x18, 0xa1, 0xf7, 0x99, 0x10, 0x67, 0x5c, 0xd2, 0x2e, 0x9e, 0xb8, 0x8f, 0x23, 0x67, 0x3e, 0xfc, 0x42, 0xe2,
+ 0x09, 0x7d, 0x0a, 0x8a, 0xb8, 0x18, 0xfc, 0x73, 0x40, 0x2f, 0xbd, 0xc4, 0xd8, 0x50, 0xc5, 0x27, 0xc8, 0xfe, 0xb8, 0x34,
+ 0x70, 0xa0, 0x0d, 0x13, 0x3c, 0xbd, 0x08, 0x4e, 0x9a, 0x93, 0x6f, 0x39, 0x37, 0xda, 0x9e, 0x65, 0xf5, 0xb4, 0x63, 0xf4,
+ 0x90, 0xc8, 0x49, 0x6d, 0x5d, 0x20, 0xd3, 0x39, 0xfd, 0x09, 0xba, 0xf4, 0x3a, 0xf3, 0xce, 0x4a, 0x69, 0x64, 0x05, 0x99,
+ 0x46, 0xe0, 0xda, 0x35, 0xc4, 0x65, 0x18, 0x1e, 0xc6, 0x16, 0xa3, 0x12, 0x61, 0xb4, 0x2e, 0xf5, 0xf0, 0x89, 0x0d, 0x8c,
+ 0xdc, 0x3d, 0xf6, 0x06, 0xcf, 0x6f, 0x86, 0x25, 0x4c, 0x09, 0xc2, 0x1b, 0xc8, 0x0e, 0x78, 0x88, 0x8d, 0xc1, 0x22, 0xb8,
+ 0xba, 0x21, 0x13, 0x9b, 0xca, 0xee, 0x8a, 0x9e, 0xdd, 0x7b, 0x5b, 0xff, 0xa3, 0xe9, 0xd1, 0xa3, 0x81, 0x7e, 0xfe, 0xff,
+ 0xe6, 0x8c, 0x49, 0xe4, 0x3b, 0x0a, 0xf9, 0x10, 0xa6, 0x72, 0x33, 0xbb, 0x2c, 0xc4, 0x4a, 0x5a, 0x72, 0x0a, 0x39, 0x50,
+ 0x74, 0xdd, 0x28, 0x6e, 0x79, 0x5f, 0x7e, 0xa7, 0xa8, 0x14, 0xcf, 0x56, 0xb3, 0x56, 0x6c, 0xa5, 0xe9, 0xf0, 0xc4, 0xae,
+ 0xf9, 0xea, 0x20, 0x8e, 0x18, 0xc7, 0x28, 0x74, 0xe2, 0x08, 0x4d, 0x89, 0x26, 0x42, 0x79, 0x5e, 0xf6, 0x60, 0xe3, 0x45,
+ 0x58, 0xa1, 0xfb, 0x51, 0x49, 0x5e, 0x92, 0x4a, 0x4d, 0xb9, 0xef, 0xd4, 0x73, 0xb5, 0xda, 0x04, 0x7b, 0xe3, 0x52, 0x9f,
+ 0xcb, 0xa3, 0x19, 0x5d, 0xac, 0x6b, 0x98, 0x6c, 0x9e, 0xe2, 0xec, 0x74, 0x2d, 0x44, 0x3e, 0xe0, 0x61, 0x3e, 0x07, 0x45,
+ 0x7e, 0x34, 0x75, 0x26, 0x98, 0x40, 0x9b, 0x75, 0x9e, 0xc8, 0x30, 0xed, 0x4b, 0xbf, 0x77, 0x8f, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x34, 0xcd,
+ 0x25, 0x4e, 0xcd, 0xde, 0x37, 0x85, 0x38, 0xa1, 0x58, 0x26, 0xf8, 0xf9, 0xe2, 0x29, 0xde, 0xf2, 0x1c, 0x93, 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, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e,
+ 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30,
+ 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70,
+ 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x63, 0x64, 0x06, 0x02, 0x09, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x36, 0xd2, 0xf5, 0xde, 0x71, 0x53, 0x07, 0xc9, 0x23, 0xd8,
+ 0x78, 0x9b, 0x65, 0xbc, 0xf3, 0xd5, 0x5b, 0xe9, 0xb8, 0x7f, 0x1b, 0x23, 0xc7, 0xa2, 0xcf, 0xb4, 0xa9, 0x28, 0xe9, 0xf8,
+ 0xdd, 0x70, 0x88, 0x21, 0x39, 0xf3, 0xdb, 0x33, 0x9c, 0xc3, 0x72, 0x43, 0xd6, 0x3d, 0x42, 0x51, 0x97, 0xba, 0xad, 0x1d,
+ 0x8e, 0x92, 0xd2, 0x75, 0x8b, 0xc3, 0x5d, 0x9c, 0xf5, 0xcb, 0x8c, 0xdc, 0x6a, 0x6a, 0x3a, 0xdd, 0xeb, 0x54, 0x7d, 0xed,
+ 0x14, 0x6b, 0xf3, 0xd6, 0x3e, 0x93, 0xc8, 0x6d, 0x7a, 0x54, 0x5f, 0xf2, 0x43, 0x8e, 0x10, 0xd0, 0x76, 0x5c, 0x9b, 0x00,
+ 0x0c, 0x1d, 0x4e, 0xca, 0x3c, 0xcd, 0xfa, 0xe6, 0xf7, 0xc2, 0x3e, 0x72, 0xb7, 0xb8, 0xde, 0xe8, 0x34, 0xaa, 0x15, 0xa0,
+ 0xae, 0x5c, 0x67, 0xa8, 0x0c, 0xac, 0x9b, 0x1e, 0x65, 0xb3, 0xe3, 0x0f, 0x30, 0x42, 0x34, 0xe9, 0xae, 0xd3, 0x01, 0xd3,
+ 0xa7, 0xdd, 0x42, 0x73, 0x75, 0x7c, 0x51, 0x43, 0x85, 0x9a, 0x60, 0x10, 0xdc, 0xae, 0x27, 0xd2, 0x6b, 0x67, 0xc9, 0x33,
+ 0x45, 0x6f, 0xc9, 0x98, 0x1e, 0xa0, 0x9a, 0x7f, 0x4d, 0x11, 0x93, 0xe1, 0x69, 0xff, 0xec, 0x4b, 0x45, 0xf3, 0x4e, 0xca,
+ 0x22, 0x0e, 0x57, 0xd7, 0x22, 0x07, 0xe5, 0x22, 0xb4, 0x87, 0xe9, 0x9c, 0xd3, 0x45, 0xcb, 0x6e, 0x3f, 0xe5, 0x8e, 0xb8,
+ 0xfc, 0x46, 0xd5, 0x5c, 0xc9, 0xb0, 0xab, 0x05, 0x3a, 0x6d, 0x37, 0x28, 0xa3, 0xa8, 0x46, 0x65, 0x6f, 0x55, 0xa1, 0x68,
+ 0x88, 0xea, 0x52, 0x3e, 0xc9, 0xf4, 0xd4, 0xe6, 0xfa, 0x3f, 0xa4, 0xe4, 0x26, 0x80, 0xb5, 0x3a, 0x6b, 0xd6, 0xc3, 0xe5,
+ 0xf9, 0x32, 0x81, 0xc8, 0x32, 0xa2, 0x48, 0xe1, 0x8e, 0x06, 0xa3, 0x19, 0xe4, 0xb3, 0xcb, 0x3b, 0x4b, 0xdf, 0xe0, 0xcc,
+ 0x0e, 0xb2, 0xaf, 0x98, 0xd1, 0x83, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+ 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17,
+ 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32,
+ 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c,
+ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 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, 0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb,
+ 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8,
+ 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3,
+ 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4,
+ 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba,
+ 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e,
+ 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f,
+ 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e,
+ 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74,
+ 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb,
+ 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10,
+ 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65,
+ 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 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, 0x2b, 0xd0, 0x69, 0x47, 0x94,
+ 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55,
+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e,
+ 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01,
+ 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01,
+ 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02,
+ 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
+ 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e,
+ 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65,
+ 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61,
+ 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74,
+ 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
+ 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
+ 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2,
+ 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e,
+ 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2,
+ 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a,
+ 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b,
+ 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d,
+ 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2,
+ 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48,
+ 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3,
+ 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e,
+ 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8,
+ 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c,
+ 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37, 0xb0, 0x75, 0x75,
+ 0x21, 0x31, 0x82, 0x02, 0x3f, 0x30, 0x82, 0x02, 0x3b, 0x02, 0x01, 0x01, 0x30, 0x81, 0x88, 0x30, 0x7c, 0x31, 0x30, 0x30,
+ 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
+ 0x61, 0x6d, 0x70, 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, 0x02, 0x08, 0x55, 0xbd, 0xb7, 0x92, 0xdb, 0x54, 0x05, 0xfd, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+ 0x05, 0x00, 0xa0, 0x81, 0x8c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0d,
+ 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x37, 0x32, 0x33, 0x34, 0x30,
+ 0x35, 0x35, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14,
+ 0xc4, 0xbb, 0xb7, 0xc5, 0x0e, 0x2a, 0x51, 0x27, 0x41, 0x95, 0x46, 0x04, 0x67, 0x08, 0xc6, 0x3e, 0xf3, 0xb7, 0x57, 0x21,
+ 0x30, 0x2b, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0c, 0x31, 0x1c, 0x30, 0x1a, 0x30,
+ 0x18, 0x30, 0x16, 0x04, 0x14, 0xc5, 0xe5, 0x93, 0x54, 0xe1, 0x09, 0x59, 0x31, 0x49, 0x9b, 0x0e, 0xde, 0xbb, 0xda, 0x5c,
+ 0xc9, 0x20, 0x94, 0x1c, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x04, 0x82, 0x01, 0x00, 0x01, 0x3c, 0x74, 0x68, 0x64, 0x90, 0x55, 0xb1, 0x78, 0x2b, 0xa4, 0xd6, 0x4a, 0x79, 0xe6, 0x25,
+ 0x38, 0xe6, 0x2c, 0xc7, 0xe4, 0xa2, 0x59, 0xab, 0xc5, 0x54, 0x62, 0x05, 0xf3, 0xb0, 0x9a, 0xf8, 0x04, 0xf6, 0x73, 0x25,
+ 0x91, 0x9c, 0x0e, 0xc4, 0xe4, 0xf9, 0x75, 0xbd, 0xdb, 0xcc, 0xfc, 0x2d, 0x36, 0xa1, 0x1b, 0x86, 0x0e, 0xef, 0x56, 0x12,
+ 0x60, 0xc4, 0x48, 0xd9, 0x13, 0x80, 0x95, 0x8f, 0x74, 0x77, 0xae, 0x0c, 0x0d, 0x84, 0x71, 0x90, 0x2f, 0x31, 0x2f, 0x23,
+ 0x05, 0xe9, 0xbb, 0x80, 0x77, 0xc5, 0x5f, 0x4d, 0x56, 0x26, 0x68, 0xa1, 0xc4, 0x9e, 0x3c, 0xe8, 0x61, 0x49, 0xb2, 0x79,
+ 0x6c, 0x03, 0x04, 0x41, 0x2b, 0x12, 0x3d, 0x28, 0x10, 0xac, 0xc4, 0x2f, 0xca, 0x66, 0x59, 0xd1, 0xaa, 0x3c, 0xaa, 0x8d,
+ 0x08, 0xdd, 0x85, 0x3e, 0x09, 0xe5, 0xfd, 0x72, 0xed, 0xe5, 0x01, 0xd9, 0xc9, 0x25, 0xc9, 0xa5, 0x47, 0x04, 0xa0, 0xe8,
+ 0x13, 0xa2, 0x7b, 0xf1, 0x6d, 0xe2, 0x15, 0x74, 0xf9, 0x37, 0x86, 0x8b, 0x6c, 0x5f, 0x24, 0xbc, 0x13, 0x02, 0xdd, 0x95,
+ 0x73, 0x69, 0xb0, 0xc1, 0xdb, 0x92, 0xea, 0xbf, 0x4c, 0xe1, 0xd7, 0xca, 0x3c, 0x58, 0x1b, 0xa1, 0x61, 0x8b, 0x0a, 0x3d,
+ 0x22, 0x11, 0xad, 0xd3, 0xa2, 0x4c, 0xfd, 0x5f, 0x38, 0x58, 0xdf, 0x24, 0x9b, 0xbf, 0xb8, 0x0e, 0xb4, 0x8e, 0xd9, 0xe7,
+ 0x10, 0x43, 0xa6, 0x2e, 0x49, 0x4d, 0x4c, 0xdf, 0xee, 0xb4, 0x96, 0x49, 0x27, 0x00, 0x6c, 0xd3, 0x15, 0xbf, 0xf4, 0x7b,
+ 0x70, 0x1b, 0x94, 0xad, 0xd7, 0x68, 0x24, 0x3a, 0x14, 0x84, 0x45, 0x52, 0xe9, 0x31, 0x66, 0xea, 0x28, 0x9c, 0xd4, 0x44,
+ 0x78, 0xea, 0x0a, 0x8e, 0x26, 0xde, 0xa7, 0xb1, 0xe9, 0x1a, 0xff, 0x21, 0x3d, 0xc7, 0x21, 0xea, 0xbb, 0x08, 0x3d, 0xee
+};
+
+uint8_t _no_expiration_attr[] = {
+ 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, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x29, 0x54, 0x68, 0x69, 0x73,
+ 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x20,
+ 0x41, 0x69, 0x6e, 0x27, 0x74, 0x20, 0x69, 0x74, 0x20, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x82, 0x03, 0xe5, 0x30, 0x82, 0x03, 0xe1, 0x30, 0x82, 0x02, 0xc9, 0xa0, 0x03, 0x02, 0x01, 0x02,
+ 0x02, 0x04, 0x74, 0x3f, 0x1d, 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x30, 0x81, 0xa7, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20, 0x52,
+ 0x53, 0x41, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+ 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c,
+ 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 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, 0x13, 0x30, 0x11, 0x06,
+ 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
+ 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31,
+ 0x34, 0x30, 0x30, 0x31, 0x38, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x33, 0x30, 0x30, 0x31, 0x38,
+ 0x32, 0x39, 0x5a, 0x30, 0x81, 0xa7, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53,
+ 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70,
+ 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 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, 0x13, 0x30,
+ 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21,
+ 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e,
+ 0x61, 0x6d, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 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, 0xe2, 0x9b, 0xcb, 0x6c, 0x77, 0xb7, 0xd1, 0x05, 0xa0, 0xae, 0x86, 0x20, 0x45, 0xd3,
+ 0xf4, 0x24, 0x8d, 0x25, 0x34, 0x31, 0xa9, 0xe2, 0x10, 0x36, 0xf5, 0x0a, 0x0b, 0x90, 0x4a, 0xa5, 0x6b, 0x5c, 0x16, 0xcd,
+ 0xb0, 0x72, 0xe9, 0xa9, 0x80, 0x5f, 0x6d, 0xb2, 0x4d, 0xd9, 0x58, 0x16, 0x9f, 0x68, 0x81, 0x9a, 0x6b, 0xeb, 0xd5, 0x4b,
+ 0xf7, 0x7d, 0x59, 0xe9, 0x46, 0x2b, 0x5b, 0x8f, 0xe4, 0xec, 0xab, 0x5c, 0x07, 0x74, 0xa2, 0x0e, 0x59, 0xbb, 0xfc, 0xd3,
+ 0xcf, 0xf7, 0x21, 0x88, 0x6c, 0x88, 0xd9, 0x6b, 0xa3, 0xa3, 0x4e, 0x5b, 0xd1, 0x1c, 0xfb, 0x04, 0xf5, 0xb2, 0x12, 0x0e,
+ 0x54, 0x59, 0x4d, 0xce, 0x0a, 0xe0, 0x26, 0x24, 0x06, 0xeb, 0xc8, 0xa2, 0xc6, 0x41, 0x28, 0xf9, 0x79, 0xe4, 0xb1, 0x4e,
+ 0x00, 0x6f, 0x6e, 0xf8, 0x96, 0x9e, 0x45, 0x28, 0x70, 0xec, 0xc7, 0xdc, 0xa2, 0xdd, 0x92, 0xab, 0xdd, 0x6f, 0xd8, 0x57,
+ 0xba, 0xcc, 0x29, 0xbe, 0xb7, 0x00, 0x1e, 0x8d, 0x13, 0x3f, 0x47, 0x34, 0x3c, 0xd0, 0xc6, 0xc8, 0x17, 0xdf, 0x74, 0x8a,
+ 0xb1, 0xc3, 0x68, 0xd5, 0xba, 0x76, 0x60, 0x55, 0x5f, 0x8d, 0xfa, 0xbd, 0xe7, 0x11, 0x9e, 0x59, 0x96, 0xe5, 0x93, 0x70,
+ 0xad, 0x41, 0xfb, 0x61, 0x46, 0x70, 0xc4, 0x05, 0x12, 0x23, 0x23, 0xc0, 0x9d, 0xc8, 0xc5, 0xf5, 0x96, 0xe5, 0x48, 0x10,
+ 0x86, 0x8a, 0x1e, 0x3b, 0x83, 0xd1, 0x47, 0x3a, 0x27, 0x00, 0x71, 0x10, 0xa3, 0x52, 0xba, 0xae, 0x01, 0x43, 0x87, 0x9c,
+ 0x6a, 0x1b, 0xea, 0x1a, 0x44, 0x4f, 0x4a, 0xac, 0xd4, 0x82, 0x55, 0xee, 0x1f, 0x25, 0x9c, 0x55, 0xca, 0xd2, 0xd0, 0x3a,
+ 0x0b, 0x70, 0x90, 0x60, 0x49, 0x47, 0x02, 0xfd, 0x89, 0x2c, 0x9a, 0x26, 0x36, 0x34, 0x8f, 0x24, 0x39, 0x8c, 0xe9, 0xa2,
+ 0x52, 0x8f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x13, 0x30, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4c, 0xed, 0x5b, 0xaf, 0x13, 0x16, 0x5d, 0xe2, 0xdd, 0x5c, 0x48, 0x1c,
+ 0xd5, 0x6e, 0x8b, 0x04, 0x51, 0xd6, 0x38, 0x80, 0xfd, 0x52, 0x4a, 0x34, 0xdc, 0x13, 0x35, 0x6e, 0x64, 0x39, 0x39, 0x39,
+ 0x09, 0xa7, 0x6c, 0x2d, 0x39, 0xf2, 0x04, 0x21, 0xe3, 0xea, 0x8f, 0xf8, 0xbe, 0x46, 0x0e, 0x20, 0x82, 0xd0, 0xc5, 0x60,
+ 0xbf, 0x57, 0x6f, 0xd8, 0x29, 0xb4, 0x66, 0xdb, 0xbf, 0x92, 0xc9, 0xdc, 0x90, 0x97, 0x0f, 0x2f, 0x59, 0xa0, 0x13, 0xf3,
+ 0xa4, 0xca, 0xde, 0x3f, 0x80, 0x2a, 0x99, 0xb4, 0xee, 0x71, 0xc3, 0x56, 0x71, 0x51, 0x37, 0x55, 0xa1, 0x60, 0x89, 0xab,
+ 0x94, 0x0e, 0xb9, 0x70, 0xa5, 0x55, 0xf3, 0x1a, 0x87, 0xa4, 0x41, 0x4c, 0x45, 0xba, 0xb6, 0x56, 0xd6, 0x45, 0x56, 0x12,
+ 0x60, 0xe5, 0x91, 0xec, 0xf7, 0xbe, 0x39, 0xa4, 0x80, 0x08, 0x9f, 0xea, 0x17, 0x12, 0x0e, 0xa6, 0xe6, 0xef, 0x09, 0xf7,
+ 0x61, 0x51, 0x57, 0x73, 0xe3, 0x57, 0x88, 0xd7, 0xf8, 0x5f, 0xaf, 0x5d, 0xaf, 0x88, 0x32, 0xb4, 0x09, 0x3e, 0x7c, 0x25,
+ 0x77, 0x35, 0xe9, 0x3e, 0x6e, 0x0a, 0xb9, 0xb4, 0xa3, 0x06, 0x07, 0x0f, 0x7e, 0x93, 0x26, 0x16, 0x38, 0x1e, 0x4e, 0x72,
+ 0xaf, 0x06, 0x44, 0x1e, 0x8d, 0x96, 0xa6, 0x15, 0x9c, 0x82, 0x6d, 0x71, 0x99, 0x84, 0x8d, 0x12, 0x46, 0xf2, 0xbb, 0xa7,
+ 0x63, 0x7a, 0x32, 0xda, 0xa9, 0xde, 0xb6, 0x34, 0x14, 0xfb, 0x07, 0x0c, 0xab, 0x3b, 0x0a, 0xa1, 0x8b, 0xda, 0x15, 0xb3,
+ 0x63, 0xf3, 0x5c, 0x45, 0x2f, 0x0b, 0x6e, 0xc7, 0x27, 0x72, 0xc1, 0x37, 0x56, 0x30, 0xe3, 0x26, 0xbb, 0x19, 0x4f, 0x91,
+ 0xa1, 0xd0, 0x30, 0x29, 0x5b, 0x79, 0x79, 0x5c, 0xe6, 0x4f, 0xed, 0xcf, 0x81, 0xb2, 0x50, 0x35, 0x96, 0x23, 0xb2, 0x9f,
+ 0xca, 0x3f, 0xb5, 0x54, 0x31, 0x82, 0x02, 0x47, 0x30, 0x82, 0x02, 0x43, 0x02, 0x01, 0x01, 0x30, 0x81, 0xb0, 0x30, 0x81,
+ 0xa7, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20,
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 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, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61,
+ 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x02, 0x04, 0x74, 0x3f, 0x1d, 0x98, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x69, 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, 0x36, 0x30, 0x33, 0x31, 0x38,
+ 0x31, 0x33, 0x32, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04,
+ 0x31, 0x22, 0x04, 0x20, 0x33, 0x1f, 0x3a, 0xc4, 0x95, 0x97, 0x64, 0x1c, 0x99, 0x9b, 0x37, 0xc8, 0xf2, 0xba, 0xd0, 0xb4,
+ 0x38, 0xa5, 0x9c, 0x3a, 0xa3, 0x78, 0xf9, 0xfb, 0x66, 0x28, 0x4e, 0x6a, 0x90, 0xcc, 0x0e, 0x4c, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xae, 0x6d, 0xa9, 0xa7, 0xee,
+ 0x0c, 0x94, 0x1b, 0xf3, 0x93, 0x40, 0x43, 0x11, 0x41, 0x20, 0x11, 0x60, 0xd9, 0x4e, 0xb6, 0x2d, 0x3e, 0x98, 0xfe, 0x06,
+ 0xd2, 0xc4, 0xe4, 0x0a, 0x66, 0xdc, 0xbb, 0xbd, 0x4d, 0x8e, 0xcb, 0xe1, 0x87, 0x39, 0x3f, 0xb3, 0x4b, 0xf8, 0xe7, 0x18,
+ 0x6f, 0x39, 0xad, 0x01, 0xd4, 0xe8, 0x85, 0x8c, 0x84, 0x96, 0x2c, 0x3a, 0xd4, 0xcf, 0x3c, 0xe5, 0x05, 0xdd, 0xc7, 0xc0,
+ 0xb7, 0x72, 0x7b, 0x32, 0xa1, 0xff, 0x69, 0x51, 0xd4, 0xc9, 0x3e, 0x1f, 0x89, 0x71, 0x39, 0xd9, 0x99, 0x1e, 0xa9, 0x33,
+ 0x83, 0xc1, 0x37, 0x3e, 0xf2, 0xbd, 0xad, 0x8f, 0xa9, 0x24, 0x82, 0xad, 0x7d, 0x54, 0x8f, 0x6f, 0x8a, 0xdb, 0xbf, 0xd4,
+ 0xd4, 0x9c, 0x0a, 0x11, 0x8a, 0xb2, 0x0c, 0xd9, 0x32, 0xf1, 0xe6, 0x76, 0x4a, 0x09, 0x1a, 0x6a, 0xdf, 0x48, 0x2f, 0xf4,
+ 0x89, 0x73, 0xc8, 0x37, 0xb0, 0x14, 0xa9, 0x59, 0xc3, 0x94, 0x63, 0x6c, 0xfd, 0x90, 0x2c, 0x3a, 0x58, 0xa4, 0x5e, 0xbb,
+ 0x2f, 0x5e, 0x1d, 0xdc, 0x57, 0x47, 0x09, 0x77, 0xbc, 0x2b, 0x76, 0xfa, 0x97, 0x85, 0x63, 0x4b, 0xd6, 0x32, 0xac, 0x7e,
+ 0xa0, 0x41, 0xd1, 0xc7, 0x1a, 0x59, 0x3f, 0x39, 0xd1, 0xa7, 0x3f, 0xa7, 0x3f, 0x23, 0x11, 0x3e, 0x19, 0x6d, 0x63, 0xa1,
+ 0x4c, 0xcd, 0x03, 0x22, 0x07, 0x72, 0x4c, 0x44, 0x07, 0xd9, 0x85, 0x18, 0x63, 0x8c, 0x96, 0x29, 0x20, 0xc4, 0x1b, 0xac,
+ 0x6e, 0x4f, 0x95, 0x7d, 0x97, 0x9f, 0xcc, 0x94, 0xf4, 0xfe, 0x8b, 0x08, 0x1c, 0x8a, 0x9d, 0x19, 0x6d, 0x42, 0x92, 0x73,
+ 0xa9, 0xd0, 0xb3, 0x4c, 0x46, 0x40, 0x88, 0xcb, 0x51, 0x2f, 0x73, 0xec, 0x43, 0x4c, 0x09, 0xa7, 0xb5, 0x89, 0x4b, 0xe4,
+ 0xbc, 0xdc, 0x1d, 0x17, 0xf9, 0x55, 0xe5, 0x59, 0xea, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
--- /dev/null
+/*
+ * 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@
+ */
+
+#include <AssertMacros.h>
+#import <Foundation/Foundation.h>
+
+#include <Security/SecIdentity.h>
+#include <Security/SecCMS.h>
+#include <Security/CMSEncoder.h>
+#include <Security/CMSDecoder.h>
+
+#include <utilities/SecCFWrappers.h>
+
+#if TARGET_OS_OSX
+#include <Security/SecKeychain.h>
+#include <Security/SecImportExport.h>
+#include <Security/CMSPrivate.h>
+#endif
+
+#include "shared_regressions.h"
+
+#include "si-35-cms-expiration-time.h"
+
+/* MARK: SecCMS tests */
+static void SecCMS_positive_tests(void) {
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CFDictionaryRef tmpAttrs = NULL;
+ NSDictionary* attrs = nil;
+ NSData *expirationDateOid = nil, *unparsedExpirationDate = nil;
+ NSArray *attrValues = nil;
+ NSDate *expirationDate = nil, *expectedDate = [NSDate dateWithTimeIntervalSinceReferenceDate: 599400000.0];
+
+ NSData *message = [NSData dataWithBytes:_css_gen_expiration_time length:sizeof(_css_gen_expiration_time)];
+ NSData *content = [NSData dataWithBytes:_css_content length:sizeof(_css_content)];
+ policy = SecPolicyCreateBasicX509();
+
+ /* verify a valid message and copy out attributes */
+ ok_status(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)content, policy, &trust, NULL, &tmpAttrs),
+ "Failed to verify valid CMS message and get out attributes");
+ require_action(attrs = CFBridgingRelease(tmpAttrs), exit, fail("Failed to copy attributes"));
+
+ /* verify we can get the parsed expiration date attribute out */
+ uint8_t appleExpirationDateOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x3 };
+ expirationDateOid = [NSData dataWithBytes:appleExpirationDateOid length:sizeof(appleExpirationDateOid)];
+ attrValues = attrs[expirationDateOid];
+ is([attrValues count], (size_t)1, "Wrong number of attribute values");
+ require_action(unparsedExpirationDate = attrValues[0], exit, fail("Failed to get expiration date attribute value"));
+ uint8_t expectedUTCData[] = { 0x31, 0x39, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a };
+ is([unparsedExpirationDate isEqualToData:[NSData dataWithBytes:expectedUTCData length:sizeof(expectedUTCData)]], true, "Failed to get correct expiration date");
+
+ /* verify we can get the "cooked" expiration data out */
+ ok(expirationDate = attrs[(__bridge NSString*)kSecCMSExpirationDate], "Failed to get pre-parsed expiration date from attributes");
+ is([expirationDate isEqualToDate:expectedDate], true, "Failed to get correct expiration date");
+
+exit:
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+}
+
+static void SecCMS_negative_date_changed(void) {
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+
+ NSMutableData *invalid_message = [NSMutableData dataWithBytes:_css_gen_expiration_time length:sizeof(_css_gen_expiration_time)];
+ [invalid_message resetBytesInRange:NSMakeRange(3980, 1)]; // reset byte in expiration date attribute of _css_gen_expiration_time
+ NSData *content = [NSData dataWithBytes:_css_content length:sizeof(_css_content)];
+ policy = SecPolicyCreateBasicX509();
+
+ /* Verify message with expiration date changed fails*/
+ is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)invalid_message, (__bridge CFDataRef)content, policy, &trust, NULL, NULL),
+ errSecAuthFailed, "Failed to verify valid CMS message and get out attributes");
+
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+}
+
+static void SecCMS_negative_missing_date(void) {
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CFDictionaryRef tmpAttrs = NULL;
+ NSDictionary *attrs = nil;
+ NSData *expirationDateOid = nil;
+
+ NSData *message = [NSData dataWithBytes:_no_expiration_attr length:sizeof(_no_expiration_attr)];
+ policy = SecPolicyCreateBasicX509();
+
+ /* verify a message with no expiration date */
+ ok_status(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, NULL, policy, &trust, NULL, &tmpAttrs),
+ "Failed to verify valid CMS message and get out attributes");
+ require_action(attrs = CFBridgingRelease(tmpAttrs), exit, fail("Failed to copy attributes"));
+
+ /* verify we can't get the expiration date out */
+ uint8_t appleExpirationDateOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x3 };
+ expirationDateOid = [NSData dataWithBytes:appleExpirationDateOid length:sizeof(appleExpirationDateOid)];
+ is(attrs[expirationDateOid], NULL, "Got an expiration date attribute from message with no expiration date");
+ is(attrs[(__bridge NSString*)kSecCMSExpirationDate], NULL, "Got an expiration date attribute from message with no expiration date");
+
+exit:
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+}
+
+static void SecCMS_tests(void) {
+ SecCMS_positive_tests();
+ SecCMS_negative_date_changed();
+ SecCMS_negative_missing_date();
+}
+
+/* MARK: CMSEncoder tests */
+static void CMSEncoder_tests(SecIdentityRef identity) {
+ CMSEncoderRef encoder = NULL;
+ CMSDecoderRef decoder = NULL;
+ CFDataRef message = NULL;
+
+ /* Create encoder */
+ require_noerr_action(CMSEncoderCreate(&encoder), exit, fail("Failed to create CMS encoder"));
+ require_noerr_action(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit,
+ fail("Failed to set digest algorithm to SHA256"));
+
+ /* Set identity as signer */
+ require_noerr_action(CMSEncoderAddSigners(encoder, identity), exit, fail("Failed to add signer identity"));
+
+ /* Add signing time attribute for 6 June 2018 */
+ require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit,
+ fail("Failed to set signing time flag"));
+ require_noerr_action(CMSEncoderSetSigningTime(encoder, 550000000.0), exit, fail("Failed to set signing time"));
+
+ /* Add expiration date attribute for 30 September 2018 */
+ ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleExpirationTime),
+ "Set expiration date flag");
+ ok_status(CMSEncoderSetAppleExpirationTime(encoder, 560000000.0), "Set Expiration time");
+
+ /* Load content */
+ require_noerr_action(CMSEncoderSetHasDetachedContent(encoder, true), exit, fail("Failed to set detached content"));
+ require_noerr_action(CMSEncoderUpdateContent(encoder, _css_content, sizeof(_css_content)), exit, fail("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_action(CMSDecoderCreate(&decoder), exit, fail("Create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message),
+ CFDataGetLength(message)), exit,
+ fail("Update decoder with CMS message"));
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:_css_content
+ length:sizeof(_css_content)]),
+ exit, fail("Set detached content"));
+ ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
+
+exit:
+ CFReleaseNull(encoder);
+ CFReleaseNull(message);
+ CFReleaseNull(decoder);
+}
+
+/* MARK: CMSDecoder tests */
+static void CMSDecoder_positive_tests(void) {
+ CMSDecoderRef decoder = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CMSSignerStatus signerStatus;
+ NSData *_css_contentData = nil;
+ CFAbsoluteTime expirationTime = 0;
+ NSDate *expirationDate = nil, *expectedDate = [NSDate dateWithTimeIntervalSinceReferenceDate: 599400000.0];
+
+ /* Create decoder and decode */
+ require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, _css_gen_expiration_time, sizeof(_css_gen_expiration_time)), exit,
+ fail("Failed to update decoder with CMS message"));
+ _css_contentData = [NSData dataWithBytes:_css_content length:sizeof(_css_content)];
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)_css_contentData), exit,
+ fail("Failed to set detached _css_content"));
+ ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
+
+ /* Get signer status */
+ require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy"));
+ ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
+ "Copy Signer status");
+ is(signerStatus, kCMSSignerValid, "Valid signature");
+
+ /* Get Expiration Time Attribute value */
+ ok_status(CMSDecoderCopySignerAppleExpirationTime(decoder, 0, &expirationTime),
+ "Got expiration time from message with no expiration attribute");
+ expirationDate = [NSDate dateWithTimeIntervalSinceReferenceDate:expirationTime];
+ is([expirationDate isEqualToDate:expectedDate], true, "Got wrong expiration time"); // 31 December 2019 12:00:00 Zulu
+
+exit:
+ CFReleaseNull(decoder);
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+}
+
+static void CMSDecoder_negative_date_changed(void) {
+ CMSDecoderRef decoder = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CMSSignerStatus signerStatus;
+ NSData *_css_contentData = nil;
+ NSMutableData *invalid_message = nil;
+
+ /* Create decoder and decode */
+ invalid_message = [NSMutableData dataWithBytes:_css_gen_expiration_time length:sizeof(_css_gen_expiration_time)];
+ [invalid_message resetBytesInRange:NSMakeRange(3980, 1)]; // reset byte in expiration date attribute of _css_gen_expiration_time
+ require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit,
+ fail("Failed to update decoder with CMS message"));
+ _css_contentData = [NSData dataWithBytes:_css_content length:sizeof(_css_content)];
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)_css_contentData), exit,
+ fail("Failed to set detached _css_content"));
+ ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
+
+ /* Get signer status */
+ require_action(policy = SecPolicyCreateBasicX509(), exit, fail("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);
+}
+
+static void CMSDecoder_negative_missing_date(void) {
+ CMSDecoderRef decoder = NULL;
+ SecPolicyRef policy = NULL;
+ SecTrustRef trust = NULL;
+ CMSSignerStatus signerStatus;
+ CFAbsoluteTime expirationTime = 0.0;
+
+ /* Create decoder and decode */
+ require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, _no_expiration_attr, sizeof(_no_expiration_attr)), exit,
+ fail("Failed to update decoder with CMS message"));
+ ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
+
+ /* Get signer status */
+ require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy"));
+ ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
+ "Copy Signer status");
+ is(signerStatus, kCMSSignerValid, "Valid signature");
+
+ /* Get Expiration Time Attribute value */
+ is(CMSDecoderCopySignerAppleExpirationTime(decoder, 0, &expirationTime), -1,
+ "Got expiration time from message with no expiration attribute");
+
+exit:
+ CFReleaseNull(decoder);
+ CFReleaseNull(policy);
+ CFReleaseNull(trust);
+}
+
+static void CMSDecoder_tests(void) {
+ CMSDecoder_positive_tests();
+ CMSDecoder_negative_date_changed();
+ CMSDecoder_negative_missing_date();
+}
+
+static bool setup_keychain(const uint8_t *p12, size_t p12_len, SecIdentityRef *identity) {
+ CFArrayRef tmp_imported_items = NULL;
+ NSArray *imported_items = nil;
+
+ NSDictionary *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" };
+ NSData *p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)];
+ require_noerr_action(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options,
+ &tmp_imported_items), exit,
+ fail("Failed to import identity"));
+ imported_items = CFBridgingRelease(tmp_imported_items);
+ require_noerr_action([imported_items count] == 0 &&
+ [imported_items[0] isKindOfClass:[NSDictionary class]], exit,
+ fail("Wrong imported items output"));
+ *identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]);
+ require_action(*identity, exit, fail("Failed to get identity"));
+
+ return true;
+
+exit:
+ return false;
+}
+
+static void cleanup_keychain(SecIdentityRef identity) {
+#if TARGET_OS_OSX
+ // SecPKCS12Import adds the items to the keychain on macOS
+ NSDictionary *query = @{ (__bridge NSString*)kSecValueRef : (__bridge id)identity };
+ ok_status(SecItemDelete((__bridge CFDictionaryRef)query), "failed to remove identity from keychain");
+#else
+ pass("skip test on iOS");
+#endif
+ CFReleaseNull(identity);
+}
+
+int si_35_cms_expiration_time(int argc, char *const *argv) {
+ plan_tests(5+1+3+5+5+3+4+1);
+
+ SecIdentityRef identity = NULL;
+
+ if (setup_keychain(signing_identity_p12 , sizeof(signing_identity_p12), &identity)) {
+ SecCMS_tests();
+ CMSEncoder_tests(identity);
+ CMSDecoder_tests();
+ }
+
+ cleanup_keychain(identity);
+
+ return 0;
+}
#include "Security_regressions.h"
+static int dummy;
+static SecRandomRef kSecRandomNotDefault = (SecRandomRef)&dummy;
+
/* Test basic add delete update copy matching stuff. */
static void tests(void)
{
CFIndex size = 42;
UInt8 *p = bytes + 23;
ok_status(SecRandomCopyBytes(kSecRandomDefault, size, p), "generate some random bytes");
+ ok_status(SecRandomCopyBytes(kSecRandomNotDefault, size, p), "ignore random implementation specifier");
}
int si_50_secrandom(int argc, char *const *argv)
{
- plan_tests(1);
+ plan_tests(2);
tests();
SecKeyRef pubkey = NULL;
#if TARGET_OS_OSX
- ok_status(SecCertificateCopyPublicKey(cert, &pubkey), "get public key from cert");
+ ok(pubkey = SecCertificateCopyKey(cert), "get public key from cert");
#else
ok(pubkey = SecKeyCopyPublicKey(pkey), "get public key from private key");
#endif
CFRelease(anchor_array);
ok_status(SecTrustEvaluate(trust, &result), "evaluate trust");
- ok(result == kSecTrustResultRecoverableTrustFailure, "private root");
+ // the root of this chain has a MD2 signature; a weak digest algorithm error is now considered fatal.
+ ok(result == kSecTrustResultFatalTrustFailure, "private root");
#if DUMP_CERTS
// debug code to save a cert chain retrieved from a SecTrustRef (written to /tmp/c[0-9].cer)
//OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData)
-/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Operations/CN=xedge2.apple.com
- issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */
-const uint8_t xedge2_cert[1385]={
-0x30,0x82,0x05,0x65,0x30,0x82,0x04,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x46,
-0x9C,0xDF,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
-0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
-0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,
-0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
-0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
-0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,
-0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,
-0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,
-0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,
-0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38,
-0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
-0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
-0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,
-0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x31,
-0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x32,
-0x38,0x31,0x39,0x30,0x33,0x31,0x32,0x5A,0x30,0x81,0x83,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,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x41,0x70,0x70,0x6C,
-0x65,0x20,0x49,0x6E,0x63,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x13,0x13,
-0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x4F,0x70,0x65,0x72,0x61,0x74,0x69,
-0x6F,0x6E,0x73,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x78,0x65,
-0x64,0x67,0x65,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,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,0xC7,0xF3,0xA1,0x0E,0x0E,
-0xA4,0xDF,0xC5,0x3F,0x24,0x87,0xC3,0x6E,0xE7,0xD0,0x7C,0x2B,0x5A,0x1C,0xF3,0x67,
-0x6C,0x6B,0x56,0x0A,0x95,0xC9,0xE5,0x13,0x28,0x6E,0x16,0x9D,0x4F,0xB1,0x76,0xFB,
-0x7D,0x42,0x5B,0x2A,0x7C,0xCC,0x97,0x75,0xAA,0xA6,0xA9,0xDE,0xB2,0xEC,0xEF,0xE2,
-0xAB,0x40,0xAE,0x9A,0x23,0xF0,0x6A,0x10,0xB3,0x75,0x27,0xF0,0xF4,0x7D,0x08,0x67,
-0x8F,0xCE,0x41,0x24,0x74,0xAA,0x37,0xB6,0xC1,0x32,0x61,0xCF,0x7D,0x1C,0x21,0xCD,
-0xCF,0x7C,0x9E,0xE2,0x48,0x03,0x7E,0x78,0xB3,0x86,0x3D,0x06,0x6B,0x39,0xEC,0xC8,
-0x73,0x68,0xDB,0xE7,0x5B,0x97,0xF4,0xF9,0xA3,0xE7,0xFB,0x81,0x2E,0x4D,0x0B,0x3F,
-0xA9,0xCA,0xDE,0x32,0x26,0xF3,0xF0,0x97,0x72,0x65,0xAB,0x02,0x03,0x01,0x00,0x01,
-0xA3,0x82,0x02,0xA2,0x30,0x82,0x02,0x9E,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,
-0x04,0x03,0x02,0x05,0xA0,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22,
-0x80,0x0F,0x32,0x30,0x30,0x38,0x30,0x31,0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,
-0x5A,0x81,0x0F,0x32,0x30,0x31,0x30,0x30,0x31,0x32,0x38,0x31,0x39,0x30,0x33,0x31,
-0x32,0x5A,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,
-0x04,0x03,0x02,0x06,0x40,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,
-0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x82,0x01,0x68,0x06,0x03,
-0x55,0x1D,0x20,0x04,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,0x82,0x01,0x57,0x06,
-0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x4B,0x02,0x30,0x82,0x01,0x48,0x30,0x26,
-0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,
-0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
-0x65,0x74,0x2F,0x63,0x70,0x73,0x30,0x82,0x01,0x1C,0x06,0x08,0x2B,0x06,0x01,0x05,
-0x05,0x07,0x02,0x02,0x30,0x82,0x01,0x0E,0x1A,0x82,0x01,0x0A,0x54,0x68,0x65,0x20,
-0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x53,0x53,0x4C,0x20,0x57,0x65,0x62,0x20,
-0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
-0x74,0x69,0x6F,0x6E,0x20,0x50,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x53,0x74,
-0x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x20,0x28,0x43,0x50,0x53,0x29,0x20,0x61,0x76,
-0x61,0x69,0x6C,0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x77,0x77,0x77,0x2E,0x65,
-0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x63,0x70,0x73,0x20,0x20,
-0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x62,0x79,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,
-0x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x69,0x6E,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,
-0x20,0x75,0x73,0x65,0x20,0x6F,0x72,0x20,0x72,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,
-0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,
-0x63,0x61,0x74,0x65,0x2E,0x20,0x20,0x54,0x68,0x69,0x73,0x20,0x43,0x50,0x53,0x20,
-0x63,0x6F,0x6E,0x74,0x61,0x69,0x6E,0x73,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74,
-0x69,0x6F,0x6E,0x73,0x20,0x6F,0x6E,0x20,0x77,0x61,0x72,0x72,0x61,0x6E,0x74,0x69,
-0x65,0x73,0x20,0x61,0x6E,0x64,0x20,0x6C,0x69,0x61,0x62,0x69,0x6C,0x69,0x74,0x69,
-0x65,0x73,0x2E,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,
-0x29,0x20,0x32,0x30,0x30,0x32,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x4C,
-0x69,0x6D,0x69,0x74,0x65,0x64,0x30,0x33,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2C,0x30,
-0x2A,0x30,0x28,0xA0,0x26,0xA0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
-0x63,0x72,0x6C,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,
-0x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2E,0x63,0x72,0x6C,0x30,0x33,0x06,0x08,0x2B,
-0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x27,0x30,0x25,0x30,0x23,0x06,0x08,0x2B,
-0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x17,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
-0x6F,0x63,0x73,0x70,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,
-0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62,
-0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,
-0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2D,0xEF,0xD9,0xAF,
-0x1A,0x89,0x40,0x53,0x75,0x48,0x26,0x59,0x2F,0xEC,0x11,0x18,0xC0,0xD1,0x7A,0x34,
-0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x19,0x06,0x09,0x2A,
-0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,0x04,0x56,0x37,
-0x2E,0x31,0x03,0x02,0x03,0x28,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
-0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x77,0x33,0x2A,0x69,0x45,0x5A,0xB2,
-0xF5,0x74,0xF7,0xDF,0xC7,0x08,0x85,0x86,0x88,0x98,0x41,0x7F,0x57,0x49,0x01,0xBA,
-0x13,0x21,0x40,0xD0,0x0A,0x5C,0xA7,0x37,0xDF,0xB3,0x7E,0xF8,0xED,0x04,0x63,0xC3,
-0xE8,0x0F,0xA0,0xE5,0xC4,0x4F,0x3A,0x90,0xE4,0x87,0x5F,0xEC,0xDB,0x65,0x8B,0x6E,
-0x88,0x6E,0x6E,0xE4,0xBC,0x6A,0x7E,0x37,0x47,0x04,0xFF,0x09,0xC6,0x70,0xE1,0x65,
-0x8F,0xE3,0xE9,0x60,0xEB,0xE8,0x8E,0x29,0xAE,0xF9,0x81,0xCA,0x9A,0x97,0x3C,0x6F,
-0x7C,0xFA,0xA8,0x49,0xB4,0x33,0x76,0x9C,0x65,0x92,0x12,0xF6,0x7F,0x6A,0x62,0x84,
-0x29,0x5F,0x14,0x26,0x6E,0x07,0x6F,0x5C,0xB5,0x7C,0x21,0x64,0x7C,0xD9,0x93,0xF4,
-0x9C,0xC8,0xE7,0xEC,0xC6,0xAC,0x13,0xC4,0xF0
+/* subject:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com */
+/* issuer :/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */
+const uint8_t google_cert[]={
+ 0x30,0x82,0x03,0xC7,0x30,0x82,0x02,0xAF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x55,
+ 0x81,0x47,0xC4,0x26,0x8C,0x3F,0xC2,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+ 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,
+ 0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x0A,0x13,0x15,
+ 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x53,0x65,0x72,
+ 0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1C,
+ 0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,
+ 0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,
+ 0x31,0x38,0x30,0x35,0x30,0x38,0x31,0x34,0x34,0x37,0x34,0x33,0x5A,0x17,0x0D,0x31,
+ 0x38,0x30,0x37,0x33,0x31,0x31,0x33,0x32,0x37,0x30,0x30,0x5A,0x30,0x68,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,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x0C,0x0D,0x4D,0x6F,0x75,0x6E,0x74,
+ 0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
+ 0x0A,0x0C,0x0A,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x4C,0x4C,0x43,0x31,0x17,0x30,
+ 0x15,0x06,0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x67,0x6F,0x6F,0x67,
+ 0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,
+ 0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,
+ 0x04,0xDD,0x10,0xCB,0x4F,0xB1,0x49,0xF9,0xE8,0xC2,0x8E,0xB5,0xB9,0xC3,0x7D,0xCC,
+ 0x9D,0x94,0x3A,0x91,0x19,0x7C,0xA9,0xB3,0x78,0x81,0x21,0x01,0xC0,0x76,0x12,0xA9,
+ 0x84,0x65,0xDF,0xD3,0xE2,0x51,0xFF,0x17,0x9F,0x69,0x0F,0x0B,0xFA,0x04,0x0D,0xBA,
+ 0x35,0xBB,0xE8,0x1F,0x14,0x66,0xB7,0xC7,0xD7,0xFC,0xEB,0x10,0xD6,0xCD,0x79,0x8A,
+ 0x22,0xA3,0x82,0x01,0x52,0x30,0x82,0x01,0x4E,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,
+ 0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x0E,
+ 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x19,
+ 0x06,0x03,0x55,0x1D,0x11,0x04,0x12,0x30,0x10,0x82,0x0E,0x77,0x77,0x77,0x2E,0x67,
+ 0x6F,0x6F,0x67,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x68,0x06,0x08,0x2B,0x06,0x01,
+ 0x05,0x05,0x07,0x01,0x01,0x04,0x5C,0x30,0x5A,0x30,0x2D,0x06,0x08,0x2B,0x06,0x01,
+ 0x05,0x05,0x07,0x30,0x02,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x70,0x6B,
+ 0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x2F,0x47,0x54,0x53,0x47,
+ 0x49,0x41,0x47,0x33,0x2E,0x63,0x72,0x74,0x30,0x29,0x06,0x08,0x2B,0x06,0x01,0x05,
+ 0x05,0x07,0x30,0x01,0x86,0x1D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,
+ 0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49,
+ 0x41,0x47,0x33,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2B,0x53,
+ 0xE0,0x79,0xD4,0xFD,0xA4,0xD4,0xDF,0x18,0x6B,0xDD,0x80,0x4D,0x11,0x35,0xC7,0xB2,
+ 0x41,0xCC,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,
+ 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x77,0xC2,0xB8,
+ 0x50,0x9A,0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA,
+ 0x4B,0x30,0x21,0x06,0x03,0x55,0x1D,0x20,0x04,0x1A,0x30,0x18,0x30,0x0C,0x06,0x0A,
+ 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x05,0x03,0x30,0x08,0x06,0x06,0x67,0x81,
+ 0x0C,0x01,0x02,0x02,0x30,0x31,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2A,0x30,0x28,0x30,
+ 0x26,0xA0,0x24,0xA0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,
+ 0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x47,0x54,0x53,0x47,0x49,
+ 0x41,0x47,0x33,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+ 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6E,0x85,0x02,0xC0,0xF0,
+ 0x15,0xBF,0xAF,0x4F,0x29,0x73,0x19,0x87,0x7F,0x30,0xB3,0x24,0xD1,0xEE,0xA7,0xDC,
+ 0x90,0x44,0x30,0xC1,0xA0,0x84,0x65,0x52,0x26,0xE6,0xAD,0x0D,0xCA,0x43,0xEE,0xB6,
+ 0x6B,0x37,0x9D,0xFF,0x97,0x80,0x09,0x85,0x58,0x46,0xEC,0xFF,0xF2,0x42,0x6A,0xBB,
+ 0xE6,0xA3,0xB4,0x9B,0x26,0x26,0xA8,0x53,0xA9,0xB9,0x95,0xB6,0x42,0x06,0x94,0xED,
+ 0x31,0xC5,0x33,0xF7,0x91,0x6A,0x90,0x4B,0xD2,0x8A,0x45,0xAE,0x3A,0xA0,0x10,0x27,
+ 0xAE,0xF4,0x9A,0xC9,0x5E,0x63,0x20,0xAD,0xF2,0xCB,0xDC,0x74,0xA8,0x83,0x32,0x56,
+ 0x6D,0xAA,0x6C,0xCA,0xBC,0xCC,0x71,0x23,0xD4,0xAC,0xA9,0xAE,0xEA,0x04,0xD6,0x75,
+ 0xE7,0xBF,0x18,0xC7,0x9C,0xCC,0x7B,0xE6,0x81,0x62,0xC6,0xFA,0x17,0xA8,0x82,0x2F,
+ 0xCC,0xE9,0xAC,0xEF,0x81,0xCC,0xAE,0x1A,0x1C,0x79,0x35,0x7B,0x54,0xFE,0x06,0x57,
+ 0x2F,0x58,0xD0,0x7C,0x4E,0x5A,0x75,0xAE,0xCC,0x31,0xD6,0x20,0xA6,0xB1,0xDA,0x39,
+ 0x9E,0x46,0x5B,0x15,0x76,0xF2,0x3E,0x2C,0xB1,0x5E,0xBF,0x7F,0x29,0xE3,0xBE,0xC6,
+ 0xF3,0xE5,0xEB,0xD5,0x91,0x48,0x84,0x41,0x7B,0xB6,0x3B,0x83,0xC6,0xCE,0x1B,0xE2,
+ 0x88,0x44,0x91,0x89,0x72,0x27,0xF9,0xD2,0x72,0x33,0xCF,0xC3,0xB2,0x52,0x38,0x65,
+ 0x17,0x14,0x00,0x4E,0x36,0x1C,0xC2,0xAD,0xBF,0x7F,0x3A,0x18,0xF7,0x52,0xFA,0x3B,
+ 0x86,0x18,0xF3,0x24,0x97,0xF7,0x35,0x58,0x48,0x0D,0x7D,0x93,0x18,0xA7,0x14,0x52,
+ 0x1A,0x19,0x9D,0xDB,0xD5,0xCC,0xA3,0xC5,0x48,0x6D,0x8A,
};
-const uint8_t _entrust1024RootCA[1244]={
- 0x30,0x82,0x04,0xD8,0x30,0x82,0x04,0x41,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x37,
- 0x4A,0xD2,0x43,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
- 0x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
- 0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
- 0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
- 0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,
- 0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,
- 0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,
- 0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,
- 0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38,
- 0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
- 0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
- 0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,
- 0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x35,
- 0x32,0x35,0x31,0x36,0x30,0x39,0x34,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x35,0x32,
- 0x35,0x31,0x36,0x33,0x39,0x34,0x30,0x5A,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,
- 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,
- 0x0A,0x13,0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,
- 0x30,0x39,0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,
- 0x6F,0x72,0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,
- 0x6D,0x69,0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,
- 0x03,0x55,0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,
- 0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,
- 0x65,0x64,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,
- 0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
- 0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x81,
- 0x9D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
- 0x03,0x81,0x8B,0x00,0x30,0x81,0x87,0x02,0x81,0x81,0x00,0xCD,0x28,0x83,0x34,0x54,
- 0x1B,0x89,0xF3,0x0F,0xAF,0x37,0x91,0x31,0xFF,0xAF,0x31,0x60,0xC9,0xA8,0xE8,0xB2,
- 0x10,0x68,0xED,0x9F,0xE7,0x93,0x36,0xF1,0x0A,0x64,0xBB,0x47,0xF5,0x04,0x17,0x3F,
- 0x23,0x47,0x4D,0xC5,0x27,0x19,0x81,0x26,0x0C,0x54,0x72,0x0D,0x88,0x2D,0xD9,0x1F,
- 0x9A,0x12,0x9F,0xBC,0xB3,0x71,0xD3,0x80,0x19,0x3F,0x47,0x66,0x7B,0x8C,0x35,0x28,
- 0xD2,0xB9,0x0A,0xDF,0x24,0xDA,0x9C,0xD6,0x50,0x79,0x81,0x7A,0x5A,0xD3,0x37,0xF7,
- 0xC2,0x4A,0xD8,0x29,0x92,0x26,0x64,0xD1,0xE4,0x98,0x6C,0x3A,0x00,0x8A,0xF5,0x34,
- 0x9B,0x65,0xF8,0xED,0xE3,0x10,0xFF,0xFD,0xB8,0x49,0x58,0xDC,0xA0,0xDE,0x82,0x39,
- 0x6B,0x81,0xB1,0x16,0x19,0x61,0xB9,0x54,0xB6,0xE6,0x43,0x02,0x01,0x03,0xA3,0x82,
- 0x01,0xD7,0x30,0x82,0x01,0xD3,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,
- 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x82,0x01,0x19,0x06,0x03,0x55,
- 0x1D,0x1F,0x04,0x82,0x01,0x10,0x30,0x82,0x01,0x0C,0x30,0x81,0xDE,0xA0,0x81,0xDB,
- 0xA0,0x81,0xD8,0xA4,0x81,0xD5,0x30,0x81,0xD2,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,
- 0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,
- 0x0B,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,
- 0x06,0x03,0x55,0x04,0x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,
- 0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,
- 0x70,0x2E,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,
- 0x74,0x73,0x20,0x6C,0x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,
- 0x04,0x0B,0x13,0x1C,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,
- 0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,
- 0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,
- 0x73,0x74,0x2E,0x6E,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,
- 0x72,0x76,0x65,0x72,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,0x0D,0x30,0x0B,
- 0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x29,0xA0,0x27,0xA0,
- 0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,
- 0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x43,0x52,0x4C,0x2F,0x6E,0x65,
- 0x74,0x31,0x2E,0x63,0x72,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,
- 0x22,0x80,0x0F,0x31,0x39,0x39,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,0x34,
- 0x30,0x5A,0x81,0x0F,0x32,0x30,0x31,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,
- 0x34,0x30,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06,
- 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62,
- 0x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,
- 0x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xF0,0x17,0x62,0x13,
- 0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,0x1A,
- 0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x19,
- 0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,
- 0x04,0x56,0x34,0x2E,0x30,0x03,0x02,0x04,0x90,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
- 0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x90,0xDC,0x30,0x02,
- 0xFA,0x64,0x74,0xC2,0xA7,0x0A,0xA5,0x7C,0x21,0x8D,0x34,0x17,0xA8,0xFB,0x47,0x0E,
- 0xFF,0x25,0x7C,0x8D,0x13,0x0A,0xFB,0xE4,0x98,0xB5,0xEF,0x8C,0xF8,0xC5,0x10,0x0D,
- 0xF7,0x92,0xBE,0xF1,0xC3,0xD5,0xD5,0x95,0x6A,0x04,0xBB,0x2C,0xCE,0x26,0x36,0x65,
- 0xC8,0x31,0xC6,0xE7,0xEE,0x3F,0xE3,0x57,0x75,0x84,0x7A,0x11,0xEF,0x46,0x4F,0x18,
- 0xF4,0xD3,0x98,0xBB,0xA8,0x87,0x32,0xBA,0x72,0xF6,0x3C,0xE2,0x3D,0x9F,0xD7,0x1D,
- 0xD9,0xC3,0x60,0x43,0x8C,0x58,0x0E,0x22,0x96,0x2F,0x62,0xA3,0x2C,0x1F,0xBA,0xAD,
- 0x05,0xEF,0xAB,0x32,0x78,0x87,0xA0,0x54,0x73,0x19,0xB5,0x5C,0x05,0xF9,0x52,0x3E,
- 0x6D,0x2D,0x45,0x0B,0xF7,0x0A,0x93,0xEA,0xED,0x06,0xF9,0xB2,
+/* subject:/C=US/O=Google Trust Services/CN=Google Internet Authority G3 */
+/* issuer :/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign */
+const uint8_t _GIAG3[]={
+ 0x30,0x82,0x04,0x5C,0x30,0x82,0x03,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x0D,0x01,
+ 0xE3,0xA9,0x30,0x1C,0xFC,0x72,0x06,0x38,0x3F,0x9A,0x53,0x1D,0x30,0x0D,0x06,0x09,
+ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x4C,0x31,0x20,0x30,
+ 0x1E,0x06,0x03,0x55,0x04,0x0B,0x13,0x17,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,
+ 0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x52,0x32,0x31,
+ 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x47,0x6C,0x6F,0x62,0x61,0x6C,
+ 0x53,0x69,0x67,0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0A,0x47,
+ 0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,
+ 0x36,0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x17,0x0D,0x32,0x31,0x31,0x32,
+ 0x31,0x35,0x30,0x30,0x30,0x30,0x34,0x32,0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,
+ 0x0A,0x13,0x15,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20,
+ 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,
+ 0x03,0x13,0x1C,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x74,0x65,0x72,0x6E,
+ 0x65,0x74,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x47,0x33,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,
+ 0xCA,0x52,0x4B,0xEA,0x1E,0xFF,0xCE,0x24,0x6B,0xA8,0xDA,0x72,0x18,0x68,0xD5,0x56,
+ 0x5D,0x0E,0x48,0x5A,0x2D,0x35,0x09,0x76,0x5A,0xCF,0xA4,0xC8,0x1C,0xB1,0xA9,0xFE,
+ 0x53,0x89,0xFB,0xAD,0x34,0xFF,0x88,0x5B,0x9F,0xBB,0xE7,0xE8,0x00,0x01,0xDC,0x35,
+ 0x73,0x75,0x03,0xAD,0xB3,0xB1,0xB9,0xA4,0x7D,0x2B,0x26,0x79,0xCE,0x15,0x40,0x0A,
+ 0xEF,0x51,0xB8,0x9F,0x32,0x8C,0x7C,0x70,0x86,0x52,0x4B,0x16,0xFE,0x6A,0x27,0x6B,
+ 0xE6,0x36,0x7A,0x62,0x50,0xD8,0xDF,0x9A,0x89,0xCC,0x09,0x29,0xEB,0x4F,0x29,0x14,
+ 0x88,0x80,0x0B,0x8F,0x38,0x1E,0x80,0x6A,0x18,0x7C,0x1D,0xBD,0x97,0x3B,0x78,0x7D,
+ 0x45,0x49,0x36,0x4F,0x41,0xCD,0xA2,0xE0,0x76,0x57,0x3C,0x68,0x31,0x79,0x64,0xC9,
+ 0x6E,0xD7,0x51,0x1E,0x66,0xC3,0xA2,0x64,0x2C,0x79,0xC0,0xE7,0x65,0xC3,0x56,0x84,
+ 0x53,0x5A,0x43,0x6D,0xCB,0x9A,0x02,0x20,0xD2,0xEF,0x1A,0x69,0xD1,0xB0,0x9D,0x73,
+ 0xA2,0xE0,0x2A,0x60,0x65,0x50,0x31,0xCF,0xFB,0xB3,0x2F,0xBF,0x11,0x88,0x40,0x2E,
+ 0xB5,0x49,0x10,0x0F,0x0A,0x6E,0xDC,0x97,0xFA,0xBF,0x2C,0x9F,0x05,0x39,0x0B,0x58,
+ 0x54,0xAF,0x06,0x96,0xE8,0xC5,0x8E,0x01,0x16,0xBC,0xA8,0x1A,0x4D,0x41,0xC5,0x93,
+ 0x91,0xA2,0x1E,0xA1,0x8B,0xF2,0xFE,0xC1,0x88,0x24,0x49,0xA3,0x47,0x4B,0xC5,0x13,
+ 0x01,0xDD,0xA7,0x57,0x12,0x69,0x62,0x2B,0xEB,0xFE,0x20,0xEF,0x69,0xFB,0x3A,0xA5,
+ 0xF0,0x7E,0x29,0xEE,0xED,0x96,0x16,0xF7,0xB1,0x1F,0xA0,0xE4,0x90,0x25,0xE0,0x33,
+ 0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x33,0x30,0x82,0x01,0x2F,0x30,0x0E,0x06,
+ 0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,0x12,0x06,0x03,
+ 0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,
+ 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x77,0xC2,0xB8,0x50,0x9A,
+ 0x67,0x76,0x76,0xB1,0x2D,0xC2,0x86,0xD0,0x83,0xA0,0x7E,0xA6,0x7E,0xBA,0x4B,0x30,
+ 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x9B,0xE2,0x07,0x57,
+ 0x67,0x1C,0x1E,0xC0,0x6A,0x06,0xDE,0x59,0xB4,0x9A,0x2D,0xDF,0xDC,0x19,0x86,0x2E,
+ 0x30,0x35,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x29,0x30,0x27,
+ 0x30,0x25,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x19,0x68,0x74,
+ 0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,
+ 0x6F,0x67,0x2F,0x67,0x73,0x72,0x32,0x30,0x32,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2B,
+ 0x30,0x29,0x30,0x27,0xA0,0x25,0xA0,0x23,0x86,0x21,0x68,0x74,0x74,0x70,0x3A,0x2F,
+ 0x2F,0x63,0x72,0x6C,0x2E,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,0x2F,0x67,0x73,
+ 0x72,0x32,0x2F,0x67,0x73,0x72,0x32,0x2E,0x63,0x72,0x6C,0x30,0x3F,0x06,0x03,0x55,
+ 0x1D,0x20,0x04,0x38,0x30,0x36,0x30,0x34,0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x02,
+ 0x30,0x2A,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1C,
+ 0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x70,0x6B,0x69,0x2E,0x67,0x6F,0x6F,0x67,
+ 0x2F,0x72,0x65,0x70,0x6F,0x73,0x69,0x74,0x6F,0x72,0x79,0x2F,0x30,0x0D,0x06,0x09,
+ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,
+ 0x1C,0xB7,0x89,0x96,0xE4,0x53,0xED,0xBB,0xEC,0xDB,0xA8,0x32,0x01,0x9F,0x2C,0xA3,
+ 0xCD,0x6D,0xAD,0x42,0x12,0x77,0xB3,0xB8,0xE6,0xC9,0x03,0x52,0x60,0x20,0x7B,0x57,
+ 0x27,0xC6,0x11,0xB5,0x3F,0x67,0x0D,0x99,0x2C,0x5B,0x5A,0xCA,0x22,0x0A,0xDD,0x9E,
+ 0xBB,0x1F,0x4B,0x48,0x3F,0x8F,0x02,0x3D,0x8B,0x21,0x84,0x45,0x1D,0x6D,0xF5,0xFF,
+ 0xAC,0x68,0x89,0xCD,0x64,0xE2,0xD6,0xD6,0x5E,0x40,0xC2,0x8E,0x2A,0xF7,0xEF,0x14,
+ 0xD3,0x36,0xA4,0x40,0x30,0xF5,0x32,0x15,0x15,0x92,0x76,0xFB,0x7E,0x9E,0x53,0xEA,
+ 0xC2,0x76,0xFC,0x39,0xAD,0x88,0xFE,0x66,0x92,0x26,0xE9,0x1C,0xC4,0x38,0xCD,0x49,
+ 0xFA,0x43,0x87,0xF0,0x5D,0xD6,0x56,0x4D,0x81,0xD7,0x7F,0xF1,0xC2,0xDD,0xB0,0x4D,
+ 0xFE,0xC3,0x2A,0x6E,0x7C,0x9F,0x6E,0x5C,0xED,0x62,0x42,0x99,0xE1,0xF7,0x36,0xEE,
+ 0x14,0x8C,0x2C,0x20,0xE3,0x46,0x97,0x5A,0x77,0x03,0xC0,0xA0,0xC6,0x4A,0x88,0xFD,
+ 0x40,0x22,0x87,0x72,0x5A,0x18,0xEA,0x9C,0xA5,0xC7,0x5A,0x08,0x8C,0xE4,0x05,0xA4,
+ 0x7D,0xB9,0x84,0x35,0x5F,0x89,0x36,0x56,0x0E,0x40,0x3D,0x12,0xE8,0xBB,0x35,0x72,
+ 0xED,0xAF,0x08,0x56,0x4E,0xB0,0xBB,0x2E,0xA9,0x9B,0xE4,0xFB,0x1D,0x3E,0x0B,0x63,
+ 0xC8,0x9B,0x4B,0x91,0x44,0x66,0x57,0xC0,0x14,0xB4,0x96,0xF0,0xDC,0x2C,0x57,0x3F,
+ 0x52,0x04,0xAD,0x95,0xAA,0x7D,0x4D,0xD0,0xF2,0x0C,0x9F,0x9C,0x40,0xE8,0xD6,0x55,
+ 0x73,0xBA,0x3C,0xDF,0x90,0xCB,0x00,0x5B,0x21,0x11,0x67,0xC2,0xED,0x32,0x1E,0xDE,
};
CFArrayRef certs = NULL;
CFDateRef date = NULL;
- const void *cert_xedge2;
- isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_cert,
- sizeof(xedge2_cert)), NULL, "create cert_xedge2");
- certs = CFArrayCreate(NULL, &cert_xedge2, 1, NULL);
+ const void *cert_google;
+ isnt(cert_google = SecCertificateCreateWithBytes(NULL, google_cert,
+ sizeof(google_cert)), NULL, "create cert_google");
+ certs = CFArrayCreate(NULL, &cert_google, 1, NULL);
bool server = true;
- policy = SecPolicyCreateSSL(server, CFSTR("xedge.apple.com")); // deliberate hostname mismatch
+ policy = SecPolicyCreateSSL(server, CFSTR("www2.google.com")); // deliberate hostname mismatch
ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
- "create trust for ssl server xedge.apple.com");
+ "create trust for ssl server www2.google.com");
CFReleaseSafe(certs);
- date = CFDateCreate(NULL, 252288000.0); /* Jan 1st 2009 */
- ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to Jan 1st 2009");
+ date = CFDateCreate(NULL, 548800000.0); /* May 23, 2018" */
+ ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to May 23, 2018");
/* This test uses a root which is no longer in our trust store,
* so we need explicitly set it as a trusted anchor
*/
- SecCertificateRef _root;
- isnt(_root = SecCertificateCreateWithBytes(NULL, _entrust1024RootCA, sizeof(_entrust1024RootCA)),
+ SecCertificateRef _anchor;
+ isnt(_anchor = SecCertificateCreateWithBytes(NULL, _GIAG3, sizeof(_GIAG3)),
NULL, "create root");
- const void *v_roots[] = { _root };
+ const void *v_roots[] = { _anchor };
CFArrayRef _anchors;
isnt(_anchors = CFArrayCreate(NULL, v_roots, array_size(v_roots), NULL),
NULL, "create anchors");
SecTrustSetAnchorCertificates(trust, _anchors);
- ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge trust");
+ ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate google trust");
is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
"trust is kSecTrustResultRecoverableTrustFailure (hostname mismatch)");
CFReleaseNull(policy);
{
const void *keys[] = { kSecPolicyName, kSecPolicyClient };
- const void *values[] = { CFSTR("xedge2.apple.com"), kCFBooleanFalse };
+ const void *values[] = { CFSTR("www.google.com"), kCFBooleanFalse };
CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values,
array_size(keys),
&kCFTypeDictionaryKeyCallBacks,
isnt(properties = SecPolicyCopyProperties(policy), NULL, "copy policy properties");
CFTypeRef value = NULL;
is(CFDictionaryGetValueIfPresent(properties, kSecPolicyName, (const void **)&value) &&
- kCFCompareEqualTo == CFStringCompare((CFStringRef)value, CFSTR("xedge2.apple.com"), 0),
+ kCFCompareEqualTo == CFStringCompare((CFStringRef)value, CFSTR("www.google.com"), 0),
true, "has policy name");
is(CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value) &&
CFEqual(value, kSecPolicyAppleSSL) , true, "has SSL policy");
/* Test setting new policy on a trust via SecTrustSetPolicies */
ok_status(SecTrustSetPolicies(trust, policy));
/* Evaluation should now succeed, since our new policy has the correct hostname */
- ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
+ ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate google trust");
is_status(trustResult, kSecTrustResultUnspecified,
"trust is kSecTrustResultUnspecified");
CFReleaseSafe(trust);
CFReleaseSafe(policy);
CFReleaseSafe(date);
- CFReleaseSafe(cert_xedge2);
+ CFReleaseSafe(cert_google);
- CFReleaseSafe(_root);
+ CFReleaseSafe(_anchor);
CFReleaseSafe(_anchors);
}
CFDictionaryAddValue(dict, kSecAttrService, CFSTR("test"));
CFDictionaryAddValue(dict, kSecAttrAccessGroup, kSecAttrAccessGroupToken);
- is_status(SecItemAdd(dict, NULL), errSecParam);
+ is_status(SecItemAdd(dict, NULL), errSecMissingEntitlement);
is_status(SecItemCopyMatching(dict, NULL), errSecItemNotFound);
CFRelease(dict);
0x65,0xE6,0x30,0xFD,0xED,0x1F,0x0A,0x9E,0x27,0x8D,0x56,0x59,0x7A,0xFB,0xBF,0x52,
0x99,0x50,0xCE,
};
+
+/* subject:/C=US/O=Apple Inc./OU=Security Engineering/CN=JAPPLESEED/emailAddress=jony.appleseed@apple.com */
+/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Sub-CA */
+/* X509v3 Subject Alternative Name:
+ email:jony.appleseed@apple.com
+ */
+uint8_t _test_leaf3[] = {
+ 0x30,0x82,0x04,0x3A,0x30,0x82,0x03,0x22,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x63,
+ 0x82,0xBA,0x4B,0x18,0xB2,0x48,0xF9,0x10,0x06,0xFA,0x70,0x00,0x5D,0x3B,0xF9,0x9E,
+ 0xE3,0x13,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,
+ 0x00,0x30,0x81,0x91,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,0x25,
+ 0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x0C,0x1C,0x4E,0x61,0x6D,0x65,0x20,0x43,0x6F,
+ 0x6E,0x73,0x74,0x72,0x61,0x69,0x6E,0x74,0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x53,
+ 0x75,0x62,0x2D,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x35,0x32,0x33,0x31,
+ 0x37,0x32,0x32,0x32,0x34,0x5A,0x17,0x0D,0x31,0x39,0x30,0x35,0x32,0x33,0x31,0x37,
+ 0x32,0x32,0x32,0x34,0x5A,0x30,0x7F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
+ 0x13,0x02,0x55,0x53,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
+ 0x03,0x0C,0x0A,0x4A,0x41,0x50,0x50,0x4C,0x45,0x53,0x45,0x45,0x44,0x31,0x27,0x30,
+ 0x25,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x18,0x6A,0x6F,
+ 0x6E,0x79,0x2E,0x61,0x70,0x70,0x6C,0x65,0x73,0x65,0x65,0x64,0x40,0x61,0x70,0x70,
+ 0x6C,0x65,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,0x9C,0xD4,0x41,0x24,0x71,0x19,0x8B,0xBB,0x06,
+ 0x26,0xD1,0xE0,0x2D,0x81,0xF2,0x82,0x7D,0x87,0x01,0x59,0x65,0x3E,0xC0,0xC5,0xDD,
+ 0xA5,0x18,0xD8,0x42,0x9F,0x0E,0xFD,0xF6,0x12,0x34,0x16,0x27,0xA0,0x60,0x1F,0x1E,
+ 0x7C,0xA7,0xA6,0x64,0xDF,0x74,0xC3,0x23,0x28,0x14,0x7C,0x3C,0xF7,0xE0,0x1A,0x3C,
+ 0xB2,0x6B,0x41,0x48,0x11,0x5D,0xEA,0xCF,0x9C,0xAE,0xBB,0x03,0x56,0x2E,0x43,0xF2,
+ 0xAF,0x34,0x74,0x19,0xE3,0x4F,0x9C,0x0F,0x0A,0xA0,0xF7,0x7B,0xC9,0xD7,0x47,0xEE,
+ 0xD5,0xED,0x0C,0xAC,0x62,0x65,0xC9,0x27,0xE7,0x9A,0xA2,0xD7,0x8A,0x8D,0xAE,0x67,
+ 0x94,0x58,0x1D,0xC4,0x2E,0x3F,0x3F,0x1A,0x65,0xD8,0x74,0x2D,0x5D,0xFD,0x24,0xAA,
+ 0xA7,0x94,0xDB,0x8C,0xB0,0x2E,0x3F,0x98,0xD9,0x51,0x01,0xFE,0x0E,0xED,0x28,0xC4,
+ 0x26,0x5B,0x11,0x2E,0xDA,0x14,0xA7,0xC9,0x72,0x41,0x4D,0x21,0xA3,0x9A,0xBF,0xA8,
+ 0xE0,0xEA,0x1E,0x24,0x02,0x14,0x50,0x12,0x7D,0x22,0x5F,0x5E,0xC0,0x6B,0x45,0x68,
+ 0xD2,0x7C,0x81,0xE3,0xF0,0x26,0xEE,0x04,0xC5,0x61,0xCF,0x60,0x56,0x32,0x87,0xB3,
+ 0x46,0xE1,0xC1,0xFD,0x42,0x17,0x22,0xBE,0x38,0xA3,0xF3,0xA9,0x99,0x95,0x08,0x14,
+ 0xA8,0xA0,0xB3,0x81,0xD6,0x7F,0xEC,0xD6,0xAB,0xA6,0xCC,0x33,0xB1,0x55,0x6F,0xC9,
+ 0xF1,0x80,0x0F,0xFB,0xD7,0xB3,0x7A,0xF2,0xD9,0x51,0xC1,0x48,0xAC,0x58,0xB9,0x8A,
+ 0x3A,0xDB,0x6D,0x3F,0x64,0x06,0x5A,0xE9,0x32,0xF9,0x1B,0x40,0xD0,0xF2,0x65,0xA3,
+ 0xC7,0x21,0xE0,0xA4,0xB2,0x89,0xAD,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x9B,0x30,
+ 0x81,0x98,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,0x30,0x00,
+ 0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,
+ 0x05,0x05,0x07,0x03,0x04,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,
+ 0x04,0x03,0x02,0x05,0xA0,0x30,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30,0x1A,
+ 0x81,0x18,0x6A,0x6F,0x6E,0x79,0x2E,0x61,0x70,0x70,0x6C,0x65,0x73,0x65,0x65,0x64,
+ 0x40,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1D,0x06,0x03,0x55,0x1D,
+ 0x0E,0x04,0x16,0x04,0x14,0xD7,0xA6,0x4F,0x23,0xDF,0x52,0x4E,0xAB,0x30,0xD6,0x02,
+ 0x54,0x10,0xD9,0x4A,0x95,0x9C,0xF7,0x8E,0x2F,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,
+ 0x04,0x18,0x30,0x16,0x80,0x14,0x43,0xD7,0xC9,0x6E,0x6E,0x28,0x69,0x32,0xB9,0xB7,
+ 0x4F,0x36,0x5A,0xD3,0x51,0x80,0x23,0x41,0x9A,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,
+ 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x84,0xFD,
+ 0x54,0x30,0x53,0xC8,0x24,0xCB,0x13,0x6F,0xDA,0xE5,0x51,0xDC,0xAC,0x28,0x0D,0xEB,
+ 0xD4,0x69,0x1D,0x4B,0x23,0x78,0x52,0xF3,0x1D,0xE8,0xBD,0xB4,0xF4,0xB8,0x2F,0x6D,
+ 0x53,0x03,0x21,0xC0,0x68,0x44,0x6F,0x85,0xF1,0x7D,0xC6,0xBD,0xC6,0x86,0xEC,0xF5,
+ 0xAA,0x7A,0xCF,0x0F,0xCB,0x11,0xB4,0xC7,0x81,0xAF,0xE1,0x88,0xAD,0x90,0x42,0x3F,
+ 0x88,0xD0,0x26,0x85,0xA9,0xA5,0x47,0x37,0xE3,0xC8,0x83,0x88,0xF6,0x52,0x93,0xFD,
+ 0xE7,0x37,0x83,0xC0,0xE6,0xFC,0x4C,0xCC,0x9F,0x9D,0x90,0x6D,0x2A,0x10,0x62,0x2C,
+ 0xA5,0x1A,0xD3,0xD4,0x69,0x5C,0x3E,0x81,0x2E,0x65,0x8C,0x68,0x7A,0x83,0xF4,0x61,
+ 0x3C,0xEC,0xCE,0xE6,0x90,0x76,0xF0,0x11,0xE8,0x2C,0xCE,0xA8,0x1E,0xC9,0x03,0xF6,
+ 0xC5,0x2D,0x9D,0x50,0xB9,0x37,0xE2,0x5C,0x1B,0x17,0x5D,0xA7,0x41,0xA1,0x1F,0xE3,
+ 0x11,0xA0,0x35,0xE1,0xB3,0xA1,0x17,0x2E,0x1A,0x40,0xD3,0x32,0x5B,0xF4,0xCF,0x58,
+ 0xDB,0x9B,0xB7,0x0C,0xB7,0x97,0x70,0xAE,0x3A,0x60,0x9F,0xC1,0xD1,0xEF,0x0C,0x95,
+ 0xF5,0x4D,0xD3,0x61,0xC3,0xBF,0x28,0xBA,0x6D,0x04,0xB5,0x2B,0x7A,0xEC,0x8B,0x30,
+ 0x69,0xA9,0xA8,0x22,0xD1,0x60,0xDE,0x8C,0x3C,0xC2,0x46,0x13,0x3D,0xFF,0x1A,0x4F,
+ 0xDF,0xE9,0x99,0x88,0x2E,0x93,0xE9,0x0F,0x8D,0xD1,0xF4,0xBF,0xEC,0x8A,0xF2,0x79,
+ 0xFA,0xA8,0xDE,0xD4,0x7C,0xE7,0xB5,0x7F,0xD1,0x6D,0x4F,0x48,0xF6,0x37,0x77,0x3B,
+ 0x78,0x8A,0x01,0xC4,0x68,0x5B,0x37,0x31,0x71,0x99,0xDF,0x28,0xF4,0x1F,
+};
static void tests(void) {
- SecCertificateRef root = NULL, subca = NULL, leaf1 = NULL, leaf2 = NULL;
- NSArray *certs1 = nil, *certs2, *anchors = nil;
+ SecCertificateRef root = NULL, subca = NULL, leaf1 = NULL, leaf2 = NULL, leaf3 = NULL;
+ NSArray *certs1 = nil, *certs2 = nil, *certs3 = nil, *anchors = nil;
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust = NULL;
SecTrustResultType trustResult = kSecTrustResultInvalid;
fail("Failed to create leaf cert 1"));
require_action(leaf2 = SecCertificateCreateWithBytes(NULL, _test_leaf2, sizeof(_test_leaf2)), errOut,
fail("Failed to create leaf cert 2"));
+ require_action(leaf3 = SecCertificateCreateWithBytes(NULL, _test_leaf3, sizeof(_test_leaf3)), errOut,
+ fail("Failed to create leaf cert 3"));;
certs1 = @[(__bridge id)leaf1, (__bridge id)subca];
certs2 = @[(__bridge id)leaf2, (__bridge id)subca];
+ certs3 = @[(__bridge id)leaf3, (__bridge id)subca];
anchors = @[(__bridge id)root];
+ /* Test multiple pre-pended labels and intersecting name constraints in the subCA */
require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1,
policy, &trust), errOut,
fail("Failed to create trust for leaf 1"));
CFReleaseNull(trust);
trustResult = kSecTrustResultInvalid;
+ /* Test no pre-pended labels */
require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs2,
policy, &trust), errOut,
- fail("Failed to create trust for leaf 1"));
+ fail("Failed to create trust for leaf 2"));
require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
fail("Failed to set verify date"));
require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut,
fail("Failed to set anchors"));
require_noerr_action(SecTrustEvaluate(trust, &trustResult), errOut,
fail("Failed to evaluate trust"));
- is(trustResult, kSecTrustResultUnspecified, "Got wrong trust result for leaf 1");
+ is(trustResult, kSecTrustResultUnspecified, "Got wrong trust result for leaf 2");
+
+ CFReleaseNull(trust);
+ trustResult = kSecTrustResultInvalid;
+
+ /* Test DNS-looking Common Name */
+ date = [NSDate dateWithTimeIntervalSinceReferenceDate:548800000.0]; // 23 May 2018
+ require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs3,
+ policy, &trust), errOut,
+ fail("Failed to create trust for leaf 3"));
+ require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
+ fail("Failed to set verify date"));
+ require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut,
+ fail("Failed to set anchors"));
+ require_noerr_action(SecTrustEvaluate(trust, &trustResult), errOut,
+ fail("Failed to evaluate trust"));
+ is(trustResult, kSecTrustResultUnspecified, "Got wrong trust result for leaf 3");
errOut:
CFReleaseNull(root);
int si_87_sectrust_name_constraints(int argc, char *const *argv)
{
NSArray *testsArray = getTestsArray();
- plan_tests(2 + (int)(2 * [testsArray count]));
+ plan_tests(3 + (int)(2 * [testsArray count]));
tests();
if(untar_test_certs()) {
+++ /dev/null
-/*
- * 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@
- */
-
-#ifndef si_89_cms_hash_agility_h
-#define si_89_cms_hash_agility_h
-
-#include <stdio.h>
-
-/* Random data for content */
-unsigned char content[1024] = {
- 0x2a, 0xb1, 0x8c, 0xf1, 0x66, 0x52, 0xd5, 0x3c, 0xdd, 0x53, 0xc0, 0x07, 0x6a, 0x13, 0xda, 0x25, 0x9c, 0x04, 0x64, 0x5c,
- 0x97, 0xb8, 0xb3, 0xb5, 0xcf, 0xf8, 0xe1, 0x8f, 0xdd, 0x49, 0x64, 0x55, 0x97, 0xad, 0xbc, 0xad, 0xff, 0xd1, 0xd9, 0xdf,
- 0x0f, 0x26, 0x96, 0x27, 0x78, 0x1b, 0x13, 0xf6, 0x2e, 0x75, 0xb2, 0x6a, 0xf1, 0x04, 0x71, 0xa3, 0x51, 0x8d, 0x9c, 0xe8,
- 0xab, 0xee, 0xf4, 0xf4, 0xfa, 0x75, 0x16, 0xbe, 0x08, 0xaf, 0xdf, 0x23, 0xc2, 0x17, 0x75, 0x80, 0xad, 0x0e, 0x68, 0xc1,
- 0x37, 0xd9, 0x49, 0x0b, 0xea, 0x8a, 0x29, 0x3a, 0x2d, 0xff, 0x45, 0xe9, 0x13, 0x93, 0xac, 0x2e, 0x25, 0x3d, 0x5f, 0xd1,
- 0x36, 0x66, 0x61, 0x14, 0xa9, 0xf1, 0xae, 0x83, 0x3a, 0x96, 0xe3, 0xcd, 0xe1, 0xdd, 0xb8, 0x8b, 0x85, 0xe7, 0xd9, 0x1b,
- 0x76, 0xf9, 0x55, 0xf7, 0xd8, 0xb6, 0xca, 0x5b, 0x0f, 0xb8, 0x40, 0x1b, 0x69, 0x54, 0x07, 0xde, 0xd5, 0x26, 0x85, 0x9b,
- 0xd1, 0x4a, 0xce, 0x2b, 0xe1, 0xd8, 0xe7, 0x6a, 0x06, 0x28, 0x4b, 0x05, 0xa9, 0x0b, 0x65, 0x07, 0x3d, 0xf5, 0xca, 0x31,
- 0xd0, 0xfb, 0x5b, 0xf8, 0x1e, 0x19, 0x5f, 0x69, 0x64, 0x1b, 0xe1, 0x6d, 0x15, 0x88, 0x9c, 0xd1, 0x25, 0x4d, 0xf2, 0xa5,
- 0x74, 0x82, 0xa4, 0xd3, 0x21, 0xc2, 0x4f, 0x78, 0xcf, 0x37, 0xdd, 0x3c, 0xe5, 0x69, 0x27, 0x82, 0xf1, 0xc8, 0xe9, 0x2f,
- 0x7a, 0x7d, 0xd4, 0x65, 0x78, 0xad, 0x4c, 0xfc, 0xa5, 0x29, 0x51, 0xe2, 0x67, 0xac, 0x29, 0xa4, 0x23, 0x46, 0xe0, 0x10,
- 0x55, 0x2a, 0x7e, 0xef, 0x04, 0xd4, 0x9f, 0xe3, 0x65, 0x09, 0x2d, 0x33, 0x07, 0xa5, 0x6c, 0x3d, 0x6e, 0xf5, 0x3e, 0xda,
- 0x92, 0xb3, 0x47, 0x89, 0xa8, 0xda, 0x04, 0xe0, 0xa6, 0xcd, 0xd5, 0x84, 0xd6, 0xd5, 0x6f, 0xa5, 0x30, 0x3f, 0xcc, 0x9e,
- 0xfe, 0xd5, 0xd6, 0xb8, 0x61, 0xf6, 0xb0, 0x10, 0x9d, 0x4d, 0x5c, 0x90, 0xc8, 0x05, 0x4d, 0xba, 0x99, 0x8e, 0xa7, 0xc8,
- 0x53, 0xe7, 0x5d, 0xd7, 0x37, 0xf3, 0x0b, 0xc9, 0x0f, 0x97, 0x2d, 0x3e, 0x22, 0xed, 0xdc, 0x28, 0x22, 0x32, 0x04, 0xc0,
- 0x6a, 0x38, 0xd8, 0xc8, 0x85, 0xef, 0x57, 0x9c, 0xa1, 0xe0, 0x0b, 0x7e, 0x6a, 0xb4, 0x5a, 0x76, 0x7c, 0xaf, 0x6f, 0x5d,
- 0xcc, 0x56, 0xef, 0x60, 0x3c, 0xce, 0x0f, 0x0a, 0x5e, 0xfa, 0xbb, 0xb6, 0xd8, 0xba, 0xda, 0x9d, 0xf5, 0x86, 0x55, 0xc2,
- 0x84, 0x9b, 0x3d, 0xc2, 0x54, 0x5b, 0xa9, 0x23, 0x57, 0xe1, 0x0a, 0x84, 0x7e, 0x3c, 0x52, 0x9c, 0x3d, 0x02, 0x9b, 0xb5,
- 0x9c, 0x50, 0xfb, 0xfc, 0x43, 0xf9, 0x07, 0x34, 0xd9, 0xad, 0x3f, 0x59, 0x44, 0x6b, 0x47, 0xa0, 0xb9, 0x29, 0x63, 0xfb,
- 0xd9, 0xd7, 0xfc, 0x62, 0xda, 0x23, 0x7e, 0x2b, 0xb6, 0x09, 0xfc, 0x52, 0x70, 0x77, 0xb9, 0x4d, 0x92, 0xdd, 0xf2, 0x82,
- 0x8c, 0xa3, 0xf5, 0x79, 0xf9, 0x21, 0xe8, 0x36, 0xea, 0xf5, 0xa7, 0x8c, 0x3c, 0x46, 0xab, 0x29, 0xdc, 0x91, 0xa8, 0x8e,
- 0xc5, 0xe7, 0xe5, 0x95, 0xd5, 0xca, 0xed, 0xad, 0x54, 0x24, 0xf2, 0xee, 0x40, 0x9c, 0x06, 0x08, 0x03, 0x36, 0x0a, 0x73,
- 0xa4, 0xcb, 0xbb, 0x28, 0x83, 0x28, 0x66, 0xc3, 0x79, 0xba, 0x7a, 0x76, 0x90, 0x10, 0x88, 0x04, 0x3f, 0x0f, 0x67, 0xd2,
- 0x53, 0xab, 0x63, 0xc7, 0x83, 0xc9, 0x2b, 0xdd, 0x9c, 0x61, 0x99, 0xe4, 0x12, 0x18, 0xc6, 0x9a, 0x9d, 0x3c, 0xea, 0x13,
- 0x87, 0x32, 0x57, 0x8d, 0x01, 0x11, 0x39, 0x56, 0x94, 0xb2, 0x4d, 0x73, 0xc0, 0xdc, 0x2d, 0x4c, 0xb3, 0xd1, 0x90, 0x36,
- 0xd8, 0xae, 0xd3, 0x06, 0xd7, 0x70, 0xa5, 0xd6, 0x0e, 0x64, 0xf8, 0x80, 0xb6, 0x36, 0x0c, 0x31, 0xd3, 0xcc, 0x46, 0xba,
- 0xb4, 0x14, 0xb4, 0xcb, 0x43, 0x68, 0x0f, 0x8d, 0xf7, 0x2c, 0x61, 0xf4, 0xfb, 0xce, 0xf1, 0xaf, 0xe9, 0x2e, 0x52, 0x02,
- 0x29, 0x5e, 0xd7, 0xc6, 0xed, 0xf6, 0x22, 0xb9, 0x7b, 0xe8, 0x1a, 0xe6, 0x59, 0xdb, 0x43, 0xdd, 0x58, 0xe2, 0x50, 0xab,
- 0x57, 0x01, 0xf0, 0x61, 0xb0, 0x83, 0xa9, 0x40, 0x0c, 0x24, 0x08, 0x6e, 0x95, 0x45, 0xba, 0xb3, 0x02, 0xa9, 0x41, 0xde,
- 0xaf, 0xc2, 0x4c, 0xc2, 0x71, 0x1e, 0x86, 0xe4, 0xe9, 0x81, 0x9e, 0xdf, 0xea, 0x11, 0x66, 0x91, 0x02, 0x8c, 0xf5, 0xa3,
- 0x05, 0xe3, 0xe9, 0x6e, 0x7f, 0x34, 0xb5, 0x0a, 0x3f, 0xc3, 0x70, 0x18, 0x33, 0x33, 0x7e, 0x85, 0x81, 0x04, 0x1f, 0xaa,
- 0x14, 0x0c, 0x57, 0xca, 0x41, 0x97, 0x79, 0x62, 0x2e, 0x99, 0xbc, 0x6f, 0xce, 0x21, 0xad, 0xde, 0x7d, 0x74, 0x73, 0x3f,
- 0x75, 0x00, 0x65, 0xc2, 0x40, 0x5e, 0xda, 0xce, 0x41, 0x4e, 0x8b, 0xd0, 0x32, 0x4f, 0x7f, 0xee, 0xbe, 0xc9, 0x41, 0xb2,
- 0x42, 0xe9, 0x5a, 0xe5, 0xee, 0x18, 0x0c, 0x70, 0x93, 0xec, 0xb2, 0x46, 0xcd, 0x11, 0x16, 0x31, 0x81, 0x33, 0x5e, 0x82,
- 0x20, 0x85, 0x1b, 0x02, 0x76, 0xeb, 0x13, 0xb9, 0xd4, 0xbd, 0xf9, 0xe7, 0xb5, 0x5e, 0x5e, 0x05, 0x48, 0x74, 0x27, 0xf2,
- 0xdc, 0x3e, 0x87, 0x8b, 0x33, 0x3f, 0x50, 0xb6, 0xc6, 0x52, 0xf8, 0x61, 0x69, 0x7e, 0x6b, 0x30, 0xef, 0x2c, 0x6c, 0x5e,
- 0x69, 0xc8, 0xba, 0x1e, 0x3d, 0x2a, 0x0c, 0x74, 0xbd, 0x93, 0xc9, 0x36, 0xcc, 0x72, 0x15, 0xe6, 0xbb, 0xd0, 0xc0, 0xe3,
- 0xaf, 0x60, 0xcd, 0x83, 0x54, 0x50, 0x67, 0xbb, 0x70, 0x2a, 0xa1, 0x51, 0x87, 0x9b, 0xc5, 0xe0, 0xbb, 0xa3, 0xb1, 0x6f,
- 0x3a, 0x1a, 0x62, 0x72, 0x6f, 0x89, 0x8a, 0x1d, 0xc4, 0x09, 0x55, 0xac, 0x67, 0x7b, 0xa3, 0xe6, 0xed, 0x4e, 0xbb, 0xf2,
- 0x5f, 0x42, 0x95, 0x7b, 0x95, 0x7a, 0xbe, 0x3e, 0xf5, 0x2f, 0xee, 0x5f, 0x30, 0x57, 0x51, 0x94, 0x7d, 0x45, 0xd5, 0xd7,
- 0x6e, 0xcc, 0xf6, 0x4d, 0xac, 0x7b, 0x51, 0x70, 0x32, 0x07, 0x1c, 0xaf, 0x97, 0xdd, 0x92, 0x0d, 0x9d, 0xba, 0x53, 0xf5,
- 0x49, 0xc7, 0xa5, 0x6a, 0x7a, 0x3b, 0xb0, 0x3f, 0x0c, 0x01, 0xa5, 0x00, 0x4a, 0x33, 0x90, 0xf7, 0xee, 0x0a, 0x12, 0x5d,
- 0xc0, 0x5d, 0xb1, 0x85, 0x63, 0xed, 0xcf, 0xb8, 0x84, 0xde, 0x51, 0x8f, 0xd9, 0xf4, 0x15, 0x76, 0x43, 0xc4, 0xfe, 0x89,
- 0x16, 0xfe, 0x13, 0x92, 0xbd, 0x25, 0x66, 0xb9, 0x56, 0x60, 0x1f, 0x85, 0x3d, 0xc6, 0x9a, 0x02, 0xc4, 0x2a, 0xbf, 0x8b,
- 0x1b, 0xf1, 0x41, 0xbb, 0x37, 0x77, 0xe1, 0x18, 0xa7, 0x5f, 0x2a, 0x30, 0x37, 0xf6, 0xf4, 0x2a, 0x4b, 0x77, 0xf8, 0x15,
- 0xc5, 0xb9, 0xb5, 0xdd, 0x93, 0x4f, 0x59, 0x97, 0x6b, 0xf2, 0xe8, 0x6e, 0xf5, 0x7e, 0x21, 0x20, 0x64, 0xac, 0xe8, 0x8d,
- 0x60, 0xcb, 0xd2, 0xdc, 0xa7, 0xc8, 0x16, 0xb2, 0x7c, 0xf3, 0xbe, 0x88, 0x5b, 0x75, 0xcb, 0xf7, 0x38, 0x79, 0xa5, 0x32,
- 0x5f, 0xa7, 0xf2, 0xfd, 0x6a, 0x21, 0x71, 0x16, 0x1b, 0xe9, 0xde, 0xd9, 0x88, 0xf2, 0x89, 0xef, 0x4f, 0x9a, 0xc4, 0x9b,
- 0x04, 0xa0, 0x16, 0xab, 0x39, 0x62, 0x3f, 0x1f, 0x06, 0x2a, 0x88, 0x04, 0x68, 0x63, 0xb1, 0x21, 0x87, 0x25, 0xfb, 0xc3,
- 0xb5, 0xe0, 0xc8, 0x48, 0x42, 0x4e, 0x3a, 0xc9, 0x90, 0x4c, 0xc1, 0xa5, 0x69, 0x62, 0xd6, 0x25, 0xdc, 0xc9, 0x51, 0xeb,
- 0x6f, 0x00, 0x70, 0x91, 0x86, 0x57, 0x36, 0x23, 0x1f, 0x29, 0x8b, 0x52, 0xb2, 0x31, 0xd5, 0x8d, 0xc5, 0xa3, 0x5f, 0xd3,
- 0x7a, 0xe4, 0x2e, 0x3a
-};
-
-/* Random data for hash agility attribute */
-unsigned char attribute[32] = {
- 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab, 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3,
- 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,
- 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, 0x6d,
- 0x30, 0x82, 0x03, 0x69, 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, 0x9a,
- 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, 0x35, 0x31, 0x31, 0x30,
- 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab,
- 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0,
- 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00,
- 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d,
- 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb,
- 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d,
- 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b,
- 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab,
- 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a,
- 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88,
- 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57,
- 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac,
- 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5,
- 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55,
- 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d,
- 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1,
- 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35,
- 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab,
- 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6,
- 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83,
- 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36,
- 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78,
- 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad,
- 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88,
- 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93,
- 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d,
- 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59,
- 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0,
- 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d,
- 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c,
- 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4,
- 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05,
- 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c,
- 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69,
- 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
-};
-
-/*
- * Invalid CMS message on content with hash agility attribute.
- * Only the hash agility attribute value has been changed from the valid message.
- */
-uint8_t invalid_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, 0x6d,
- 0x30, 0x82, 0x03, 0x69, 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, 0x9a,
- 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, 0x35, 0x31, 0x31, 0x30,
- 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd0, 0x8f, 0xfd, 0xab,
- 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0,
- 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00,
- 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d,
- 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb,
- 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d,
- 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b,
- 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab,
- 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a,
- 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88,
- 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57,
- 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac,
- 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5,
- 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55,
- 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d,
- 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1,
- 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35,
- 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab,
- 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6,
- 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83,
- 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36,
- 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78,
- 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad,
- 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88,
- 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93,
- 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d,
- 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59,
- 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0,
- 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d,
- 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c,
- 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4,
- 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05,
- 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c,
- 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69,
- 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
-};
-
-/* Valid CMS message with no hash agility attribute */
-unsigned char valid_no_attr[] = {
- 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, 0x3b,
- 0x30, 0x82, 0x03, 0x37, 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, 0x69, 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, 0x35, 0x31, 0x31, 0x30, 0x34,
- 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xbc, 0x5a, 0x74, 0xac, 0x24,
- 0x13, 0xa5, 0xa3, 0xfb, 0x61, 0xfb, 0x19, 0x7a, 0x3f, 0x7b, 0x46, 0x5a, 0xcd, 0x8a, 0x92, 0x23,
- 0xeb, 0xd0, 0xdf, 0xf2, 0x05, 0xbe, 0x02, 0xf9, 0xd5, 0x81, 0xca, 0x16, 0xf9, 0xd9, 0x63, 0x9e,
- 0x19, 0xb8, 0xea, 0x1d, 0x51, 0x2c, 0xfc, 0x65, 0x0c, 0x67, 0x31, 0x5d, 0xa2, 0x87, 0x40, 0xa2,
- 0x58, 0x57, 0x35, 0xe1, 0xa2, 0xc8, 0x25, 0xe4, 0x79, 0xd1, 0xc2, 0x76, 0x26, 0x20, 0x11, 0x76,
- 0x38, 0xc8, 0xa1, 0x08, 0x98, 0x7c, 0x28, 0x8a, 0x14, 0x23, 0x89, 0xfa, 0xe6, 0x55, 0xaf, 0x47,
- 0x1f, 0xe8, 0x5c, 0xc4, 0x0b, 0x88, 0x27, 0x75, 0xf5, 0x2d, 0x2c, 0x63, 0x63, 0x7b, 0xd3, 0x2b,
- 0xd2, 0xb1, 0x4d, 0xf5, 0xd3, 0xa9, 0xdc, 0xc1, 0x34, 0x9d, 0xb8, 0x44, 0xae, 0xa3, 0x41, 0xd7,
- 0x1e, 0x02, 0xff, 0x06, 0x3d, 0x8b, 0x3b, 0x01, 0xc6, 0xa9, 0x0f, 0x7a, 0x59, 0x03, 0x05, 0x2a,
- 0xcf, 0x19, 0xc1, 0xd2, 0xea, 0x30, 0x3f, 0xbd, 0x83, 0x80, 0x26, 0xd7, 0x73, 0x32, 0x00, 0x8d,
- 0x4f, 0x69, 0xaa, 0xf0, 0x39, 0x3f, 0xae, 0x46, 0xfc, 0x19, 0x7e, 0x62, 0xd2, 0xc8, 0x59, 0xa2,
- 0xd1, 0x23, 0xa2, 0xab, 0xdd, 0x5b, 0xbc, 0xa9, 0x4d, 0x8c, 0x3a, 0xa4, 0x9d, 0x8e, 0x80, 0x0c,
- 0x2b, 0x2d, 0x26, 0x27, 0xb7, 0xf2, 0xb9, 0x19, 0xc5, 0x8e, 0x17, 0x44, 0xb2, 0x19, 0x29, 0x3b,
- 0x25, 0x7e, 0x76, 0xf8, 0x97, 0x85, 0xbc, 0x78, 0xa4, 0x41, 0xcb, 0x10, 0xed, 0xd7, 0x8c, 0x4c,
- 0x56, 0x44, 0xfc, 0x7c, 0xa8, 0x98, 0xff, 0xa5, 0xef, 0x21, 0xe4, 0xc2, 0x2b, 0xaf, 0xfb, 0xb2,
- 0xcb, 0x4c, 0x63, 0x19, 0x53, 0xae, 0xc4, 0xbc, 0x44, 0x31, 0xcb, 0x06, 0x2f, 0x01, 0x2b, 0x6b,
- 0x7e, 0xd8, 0x24, 0x76, 0x16, 0x74, 0xa5, 0xb2, 0x46, 0xff, 0x14, 0xde, 0xc8, 0xe5, 0xfc, 0xeb,
- 0xfa, 0xb8, 0xc2, 0x39, 0x9d, 0xf6, 0xdd, 0xbb, 0xba, 0x7d, 0x2d, 0x49, 0x4c, 0x7d, 0x87, 0xe2,
- 0x0a, 0xb7, 0x52, 0xb5, 0x3d, 0x9d, 0x02, 0xf2, 0x04, 0x3d, 0x9b, 0x8b, 0x04, 0xe8, 0x84, 0x50,
- 0x19, 0xb7, 0xfa, 0x4f, 0x9f, 0xa6, 0x00, 0x06, 0x2a, 0x44, 0xb2, 0x58, 0x91, 0x2f, 0xde, 0xd6,
- 0x25, 0xcc, 0xd5, 0x68, 0x04, 0x51, 0xb1, 0x0f, 0x08, 0x41, 0xdd, 0xea, 0x16, 0x70, 0xbd, 0x5a,
- 0xbc, 0x05, 0x60, 0xbc, 0xd4, 0x67, 0x62, 0xe2, 0xc3, 0xc0, 0x79, 0xdf, 0x49, 0xd7, 0x52, 0x62,
- 0xde, 0xce, 0x68, 0x5c, 0x32, 0x9b, 0xd3, 0xb8, 0xef, 0x62, 0x7b, 0x4b, 0x0e, 0x15, 0xae, 0x92,
- 0xfb, 0x06, 0x36, 0xb9, 0x05, 0x72, 0x2f, 0x01, 0x55, 0x70, 0x2b, 0x09, 0x54, 0xe1, 0x70, 0x15,
- 0xab, 0x24, 0xcb, 0x07, 0x4c, 0x7e, 0xde, 0x38, 0xb2, 0x03, 0x56, 0xdb, 0x2f, 0x8c, 0x3b, 0xe5,
- 0x5e, 0x1a, 0xbb, 0x90, 0x08, 0x55, 0xb2, 0x3d, 0xd9, 0x6f, 0xe8, 0x81, 0x08, 0x04, 0x5e, 0x82,
- 0x84, 0x7e, 0x9c, 0x3f, 0x5a, 0x66, 0x6f, 0x6c, 0xc6, 0x98, 0x82, 0x27, 0xb6, 0x49, 0x7b, 0x14,
- 0x07, 0x9d, 0x20, 0x61, 0x9d, 0xd9, 0x3d, 0xd0, 0x71, 0x0c, 0x72, 0x82, 0x50, 0xac, 0x61, 0xcd,
- 0xc5, 0xc6, 0xc9, 0x90, 0xe2, 0x92, 0x5b, 0x02, 0x73, 0xda, 0x98, 0x2e, 0x21, 0x1e, 0x66, 0x79,
- 0x83, 0x2e, 0x1d, 0x66, 0x0e, 0x2b, 0x6d, 0x42, 0x7d, 0xf4, 0x0a, 0xd3, 0xa1, 0x9b, 0x7f, 0x61,
- 0xa7, 0x13, 0x3a, 0xa4, 0x6e, 0x0d, 0x0b, 0xbf, 0x42, 0x32, 0xf7, 0xca, 0x0e, 0x96, 0x0a, 0xcb,
- 0x9a, 0x0a, 0x6a, 0x24, 0x8c, 0x43, 0x76, 0x0e, 0xa8, 0x71, 0xcd, 0x3f, 0xc4, 0x85, 0x46, 0x50,
- 0xb9, 0x65, 0x43, 0x49, 0xae, 0x31, 0x25, 0x76, 0x4b, 0xfb, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00
-};
-
-/*
- * password: "password"
- * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08
- * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
- * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
- */
-unsigned char signing_identity_p12[4477] = {
- 0x30, 0x82, 0x11, 0x79, 0x02, 0x01, 0x03, 0x30, 0x82, 0x11, 0x3f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x07, 0x01, 0xa0, 0x82, 0x11, 0x30, 0x04, 0x82, 0x11, 0x2c, 0x30, 0x82, 0x11, 0x28, 0x30, 0x82, 0x07, 0x57, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x07, 0x48, 0x30, 0x82, 0x07, 0x44, 0x02, 0x01, 0x00,
- 0x30, 0x82, 0x07, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xed, 0xd8, 0x65, 0x57, 0xbb, 0xca, 0x25,
- 0x46, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x07, 0x10, 0xc0, 0x1d, 0x0d, 0x5c, 0x7f, 0x3b, 0xbe, 0x20, 0xd4, 0x9a, 0x0d,
- 0xaf, 0xb6, 0x4b, 0xc7, 0x7f, 0xa8, 0xa8, 0x3f, 0x6c, 0x96, 0x1c, 0xea, 0x90, 0xd2, 0x79, 0x9f, 0x56, 0x3a, 0x5a, 0x29,
- 0x93, 0xff, 0x72, 0x39, 0x9e, 0x41, 0xd9, 0x5a, 0xfc, 0xb5, 0x54, 0x2d, 0x89, 0x60, 0x18, 0xf2, 0xea, 0x8c, 0xeb, 0x7f,
- 0xba, 0x87, 0xc6, 0x70, 0x42, 0x25, 0x55, 0x24, 0xc5, 0x4f, 0x26, 0x66, 0x8d, 0x78, 0x44, 0x47, 0x85, 0x36, 0x53, 0x86,
- 0xc9, 0x18, 0x83, 0x33, 0x4b, 0x4b, 0x08, 0x2d, 0x7b, 0x68, 0x37, 0x29, 0x4c, 0x20, 0x74, 0xd4, 0x4f, 0xbb, 0x6e, 0x97,
- 0x7a, 0xf4, 0xbf, 0xcb, 0x40, 0x26, 0x2d, 0xac, 0x95, 0x82, 0xe0, 0x88, 0xfe, 0x54, 0x80, 0xe9, 0xf5, 0xda, 0x8e, 0x6e,
- 0x3a, 0x47, 0x2d, 0xc8, 0xd4, 0xe7, 0x2e, 0xff, 0xec, 0xfa, 0xa5, 0x70, 0xcd, 0x2e, 0x99, 0x26, 0x32, 0xc8, 0x1d, 0x53,
- 0x60, 0x1e, 0x6f, 0x68, 0xcb, 0x49, 0xd0, 0xa2, 0xf8, 0x47, 0x70, 0x1b, 0x9e, 0x85, 0xbe, 0x4e, 0x56, 0xb5, 0x8b, 0x66,
- 0x45, 0x57, 0xe3, 0xbd, 0x57, 0xed, 0x94, 0x53, 0xf6, 0x72, 0xd7, 0xb7, 0xc6, 0x9f, 0x05, 0xf5, 0x98, 0xb4, 0x13, 0x35,
- 0x69, 0x24, 0x94, 0xd9, 0x3d, 0x80, 0xbc, 0xa8, 0xea, 0x78, 0x0c, 0xe0, 0xa2, 0xfe, 0x1b, 0xd2, 0x82, 0x3d, 0x83, 0x34,
- 0x76, 0xb4, 0x45, 0xf8, 0x14, 0x09, 0x66, 0x02, 0x68, 0xc3, 0x1b, 0xcb, 0x6c, 0x91, 0x6b, 0x3e, 0xdc, 0x35, 0x68, 0xab,
- 0x49, 0x47, 0x6c, 0x60, 0xea, 0xe3, 0xd5, 0x59, 0x82, 0x9c, 0x18, 0xb0, 0x6d, 0x45, 0xc0, 0x2f, 0x58, 0xf1, 0x44, 0x79,
- 0xe3, 0xd2, 0xd6, 0x16, 0xbc, 0xde, 0x17, 0xae, 0xf7, 0xea, 0x3c, 0xe4, 0xb4, 0x7b, 0xdf, 0xba, 0x9b, 0xf1, 0xb8, 0xa8,
- 0xb0, 0x51, 0xeb, 0xe8, 0xc3, 0xe9, 0x9c, 0x1b, 0x06, 0xdd, 0x89, 0x07, 0x98, 0xf8, 0x01, 0x7f, 0xde, 0x7e, 0x05, 0xa6,
- 0x72, 0x0b, 0x3f, 0xf4, 0x7d, 0xca, 0x74, 0x7b, 0xc9, 0x87, 0x0d, 0x35, 0x8b, 0x05, 0x3a, 0x73, 0x04, 0x08, 0x7a, 0x51,
- 0x34, 0x29, 0x5b, 0xd8, 0x90, 0x0f, 0xa7, 0xf0, 0x48, 0xfc, 0x9c, 0x74, 0xca, 0xe9, 0x34, 0x75, 0x1c, 0xd1, 0xa6, 0xd1,
- 0xfb, 0x9f, 0xc7, 0x82, 0x40, 0x75, 0x87, 0xdd, 0xa2, 0x22, 0xeb, 0x91, 0xd7, 0x85, 0x1a, 0x2c, 0xa7, 0x3d, 0xd5, 0xe4,
- 0xca, 0x85, 0x00, 0x33, 0x11, 0x6d, 0x62, 0xa8, 0xb7, 0xd3, 0x45, 0x46, 0xdc, 0xb4, 0xa3, 0xeb, 0xae, 0x5e, 0x8c, 0xc2,
- 0x7a, 0x0b, 0x83, 0x98, 0x5a, 0x94, 0x0f, 0x68, 0x61, 0x36, 0x57, 0x6e, 0x94, 0xe0, 0x6d, 0x93, 0x76, 0xa0, 0x5d, 0x3f,
- 0x25, 0x8b, 0x3b, 0x46, 0x1e, 0x0c, 0x15, 0x6b, 0x9f, 0x1d, 0xc3, 0x5f, 0x61, 0x42, 0xd5, 0xf8, 0x79, 0xcd, 0xd1, 0x0a,
- 0x96, 0xce, 0x49, 0x8a, 0xff, 0x54, 0x46, 0x77, 0x65, 0x37, 0x70, 0xcd, 0x65, 0x6f, 0x3d, 0x49, 0xc1, 0x29, 0x8d, 0x16,
- 0xbd, 0x36, 0x47, 0x54, 0xa5, 0x4d, 0x06, 0xfb, 0x33, 0x00, 0x29, 0xd8, 0x31, 0x09, 0x58, 0x12, 0x4c, 0xfe, 0xef, 0x8e,
- 0xf9, 0x1e, 0x30, 0xf7, 0x05, 0xb2, 0xd8, 0xd4, 0x7d, 0xae, 0xab, 0x57, 0xb7, 0x46, 0x09, 0xff, 0xca, 0xc7, 0x7b, 0xca,
- 0x73, 0xfa, 0xf9, 0x50, 0xa0, 0xb8, 0x09, 0xc2, 0x80, 0x43, 0x0d, 0x99, 0x7f, 0x4e, 0xdf, 0xd5, 0x6c, 0xc4, 0x42, 0x1a,
- 0x05, 0xbd, 0x65, 0xf4, 0x57, 0x2a, 0xe5, 0xc4, 0xcb, 0x79, 0x3f, 0x8f, 0x74, 0x93, 0x66, 0x8d, 0x93, 0xda, 0xba, 0x23,
- 0x77, 0x3f, 0xad, 0xd3, 0x8b, 0xae, 0xf5, 0xf1, 0x5c, 0xc1, 0xd2, 0x00, 0x3a, 0x60, 0x8e, 0xc3, 0x32, 0xd6, 0x8e, 0xce,
- 0x95, 0x24, 0x03, 0x79, 0x03, 0xf2, 0xb8, 0x2a, 0x94, 0xeb, 0x15, 0x97, 0xdc, 0x18, 0x8d, 0xc7, 0xd9, 0xc2, 0x63, 0x69,
- 0xfb, 0xf9, 0x8f, 0x05, 0xd3, 0x7c, 0x60, 0x5a, 0x57, 0xe4, 0xa5, 0xc1, 0xdf, 0x1d, 0x11, 0x84, 0x69, 0xba, 0x20, 0xd8,
- 0x79, 0xc3, 0x34, 0x3a, 0xb1, 0x63, 0x4c, 0xd2, 0x91, 0x2d, 0x87, 0x1e, 0xec, 0x06, 0xea, 0x35, 0x97, 0x0e, 0x59, 0x54,
- 0x83, 0x50, 0x3e, 0xac, 0xf2, 0xea, 0x6c, 0x0c, 0xa0, 0x57, 0xfb, 0xe8, 0x6b, 0xf9, 0xd1, 0x25, 0xc0, 0xa2, 0xb0, 0xa2,
- 0xcd, 0xde, 0x2b, 0xa7, 0xb3, 0x40, 0x75, 0x36, 0xf7, 0x20, 0xbe, 0xd7, 0xd1, 0x2e, 0x66, 0xc5, 0x3c, 0xf8, 0x6e, 0xce,
- 0xcb, 0x76, 0x7f, 0x1d, 0x32, 0x3b, 0x14, 0x27, 0x9c, 0x9e, 0xa3, 0xeb, 0x0c, 0x2f, 0x71, 0xba, 0x0d, 0xca, 0x27, 0x90,
- 0x42, 0xfd, 0xd4, 0x34, 0xb9, 0x96, 0xae, 0xcb, 0xd8, 0xfe, 0x31, 0x62, 0xe8, 0x4c, 0x07, 0x71, 0xb9, 0x0c, 0x9f, 0xe2,
- 0x8e, 0x66, 0xc2, 0x39, 0xc5, 0xc3, 0x1c, 0xfd, 0x5e, 0x18, 0x0b, 0xd4, 0x93, 0x3d, 0x98, 0x33, 0xaf, 0x6d, 0xb4, 0x6f,
- 0xe6, 0x75, 0x67, 0x62, 0xe7, 0x42, 0xee, 0xc6, 0xf2, 0x2e, 0x21, 0xa9, 0x75, 0xde, 0x0a, 0x8c, 0x39, 0xb7, 0x4b, 0x54,
- 0x01, 0xa7, 0xeb, 0x5a, 0x88, 0x79, 0xa8, 0xb3, 0x3f, 0x31, 0x8c, 0x47, 0x08, 0x94, 0x47, 0x52, 0xcf, 0x3c, 0xac, 0xd9,
- 0x32, 0x57, 0x4a, 0x18, 0x55, 0x5b, 0x66, 0xdc, 0x89, 0xd2, 0xc6, 0xa1, 0x11, 0x40, 0x19, 0x9c, 0x46, 0x88, 0x21, 0x77,
- 0xc1, 0x7f, 0x09, 0xc7, 0xfb, 0x52, 0x92, 0xec, 0x1a, 0xe0, 0xdd, 0x76, 0xb9, 0xfd, 0xa7, 0x8f, 0x61, 0xe3, 0xf0, 0x1b,
- 0x4e, 0xdb, 0xa0, 0xde, 0x90, 0xd6, 0x49, 0xea, 0xe9, 0x86, 0xc6, 0x5d, 0xac, 0xd0, 0xc2, 0xc5, 0x01, 0xcb, 0x3f, 0xcb,
- 0xf0, 0x62, 0x90, 0xa1, 0x17, 0x4b, 0x72, 0x5c, 0xc8, 0xe9, 0x24, 0x93, 0xda, 0x5c, 0x75, 0x24, 0x96, 0x35, 0x54, 0xf4,
- 0xfa, 0xc8, 0x27, 0xe1, 0xdd, 0x32, 0xda, 0x2f, 0x2b, 0x7d, 0xf6, 0xd8, 0x0b, 0xf2, 0xca, 0xb5, 0xee, 0x8a, 0xcf, 0xb6,
- 0x26, 0x71, 0x65, 0x85, 0xfe, 0x8c, 0x37, 0xf1, 0x17, 0x6b, 0x5e, 0x8a, 0xee, 0xb4, 0xc7, 0x0a, 0xff, 0xb2, 0x9a, 0x72,
- 0xe5, 0x85, 0xf3, 0xc0, 0xf9, 0x84, 0xbc, 0xe0, 0x18, 0x3c, 0x12, 0x0c, 0xa1, 0xe9, 0x10, 0xd4, 0x3b, 0x1a, 0x21, 0x35,
- 0xc6, 0x06, 0x93, 0xa0, 0xdf, 0x0d, 0x68, 0xa3, 0xf1, 0x06, 0xd9, 0xed, 0xb7, 0xa7, 0xba, 0xb0, 0x22, 0xc2, 0x0b, 0x6b,
- 0x70, 0x50, 0xf5, 0x49, 0x9a, 0x4f, 0x99, 0xaa, 0x1e, 0x9c, 0xa6, 0xf3, 0x99, 0x3a, 0xfd, 0x3b, 0xd2, 0xeb, 0xce, 0x1e,
- 0x72, 0x62, 0x99, 0xc0, 0x1e, 0x2b, 0x09, 0x75, 0x4a, 0xfb, 0xc8, 0x26, 0xcf, 0x76, 0xa2, 0x0e, 0xef, 0xf4, 0xa8, 0x70,
- 0x31, 0xd8, 0xa1, 0x22, 0x62, 0xcc, 0x9f, 0xd5, 0xa3, 0x55, 0xc2, 0x78, 0xd7, 0x27, 0xfc, 0x3c, 0x53, 0xe8, 0xeb, 0x7e,
- 0x7a, 0x27, 0xcf, 0x6d, 0x52, 0xb5, 0x9a, 0x2b, 0x49, 0x8d, 0x3f, 0x89, 0x80, 0x1a, 0x5c, 0x39, 0xe7, 0x53, 0xb3, 0xf3,
- 0x33, 0x97, 0xcf, 0x7d, 0xfb, 0x8e, 0x19, 0xf4, 0x72, 0xeb, 0xe7, 0xdf, 0xb1, 0xe3, 0xc1, 0x6c, 0x7f, 0x17, 0x89, 0x34,
- 0x4f, 0x45, 0x0f, 0xc5, 0xfc, 0x15, 0xb3, 0x3f, 0xc6, 0xdc, 0x25, 0xa6, 0xda, 0x28, 0x85, 0x5d, 0x25, 0x02, 0x78, 0x74,
- 0xd9, 0x74, 0xb8, 0x65, 0x48, 0x3a, 0x8a, 0x2a, 0xd5, 0xa9, 0xb8, 0x7f, 0xaa, 0x9d, 0xe7, 0xaf, 0xbd, 0xdf, 0xfd, 0x00,
- 0x67, 0xab, 0x39, 0xe1, 0x2c, 0x3d, 0xd1, 0x5c, 0x9b, 0x61, 0x2b, 0x51, 0xdc, 0x87, 0x19, 0x6c, 0xa0, 0x12, 0xd4, 0x60,
- 0xed, 0x94, 0xe9, 0xeb, 0x4e, 0x51, 0xd8, 0x50, 0xcb, 0x97, 0x8a, 0x20, 0x21, 0xdf, 0xe9, 0x2c, 0xd2, 0xe2, 0x04, 0x14,
- 0xaf, 0x7b, 0x7e, 0xd6, 0xeb, 0x1d, 0x25, 0x09, 0x98, 0x8e, 0x9e, 0x56, 0xf8, 0x7d, 0xfc, 0x0f, 0xbf, 0xd2, 0x6b, 0xbc,
- 0xab, 0xed, 0xca, 0x43, 0x6d, 0x28, 0xbe, 0xd5, 0x20, 0x44, 0xcb, 0x6b, 0xbc, 0x80, 0x5a, 0x82, 0x13, 0x50, 0xbd, 0xda,
- 0x18, 0x10, 0xac, 0xae, 0x56, 0xb9, 0x46, 0xc5, 0xa2, 0xca, 0xb2, 0x03, 0xf0, 0x57, 0xfe, 0xcd, 0x9a, 0x1b, 0x81, 0x6a,
- 0x10, 0x51, 0x2e, 0x88, 0x30, 0x57, 0x3c, 0xfe, 0x7c, 0x56, 0x0c, 0x00, 0x89, 0x5c, 0x21, 0x57, 0x19, 0x96, 0x85, 0x98,
- 0xeb, 0x43, 0x71, 0x0d, 0x8a, 0x35, 0xc3, 0xae, 0x36, 0x59, 0x72, 0x97, 0x12, 0x6d, 0xcd, 0x28, 0x64, 0x17, 0x9e, 0xe7,
- 0x2c, 0x28, 0xfd, 0x32, 0xa8, 0x10, 0x67, 0x4e, 0xc0, 0x14, 0x21, 0x7c, 0x36, 0x20, 0xe9, 0x46, 0x68, 0x62, 0xc1, 0xff,
- 0xb0, 0xdf, 0xaa, 0x87, 0xff, 0x94, 0xa4, 0xf3, 0xb3, 0xc8, 0x53, 0x57, 0x18, 0x92, 0x15, 0xc7, 0x78, 0x2d, 0x91, 0xba,
- 0xb3, 0x1f, 0x06, 0x13, 0x79, 0x21, 0x86, 0x1d, 0xa2, 0x38, 0x2c, 0xda, 0x35, 0x31, 0xbb, 0x04, 0x65, 0xa3, 0x01, 0xa6,
- 0x63, 0xa4, 0x4a, 0xa2, 0xc1, 0xad, 0x04, 0xc1, 0xfa, 0x78, 0xe1, 0xb6, 0x50, 0x46, 0xab, 0xad, 0x1c, 0xcf, 0xf4, 0xe5,
- 0xba, 0xa5, 0xe2, 0x91, 0x29, 0x4b, 0xa1, 0xc6, 0x4b, 0x30, 0xa5, 0x31, 0x02, 0xe9, 0xd0, 0x50, 0x72, 0x2c, 0x8e, 0xbd,
- 0xb2, 0x12, 0xd9, 0x4f, 0x7c, 0x87, 0x4b, 0xa0, 0x45, 0x71, 0x0c, 0x23, 0x37, 0x6b, 0x60, 0xd7, 0x9f, 0x19, 0xe8, 0x0b,
- 0x85, 0x57, 0x72, 0xb6, 0xbb, 0x20, 0x23, 0xd3, 0x7d, 0x9a, 0x9b, 0x9a, 0x05, 0x46, 0x5c, 0xf5, 0x02, 0xf1, 0x56, 0x00,
- 0xc2, 0x05, 0x85, 0x48, 0xd3, 0x8d, 0x8e, 0xe1, 0xcb, 0xc5, 0x83, 0x1f, 0x78, 0xd0, 0xc5, 0xb1, 0xdf, 0x80, 0x9d, 0x04,
- 0xe7, 0xac, 0xd1, 0x68, 0x1a, 0x19, 0x18, 0x16, 0xfa, 0x3a, 0xe2, 0xd2, 0x30, 0x08, 0x17, 0x4d, 0x50, 0x2b, 0xd4, 0xa3,
- 0xbe, 0x98, 0x5f, 0xe0, 0xcf, 0xed, 0x7d, 0x74, 0x94, 0xd1, 0xb2, 0x77, 0xbc, 0x72, 0xbc, 0xf5, 0xc7, 0x82, 0x26, 0x53,
- 0x14, 0xcc, 0xf9, 0xf7, 0x71, 0xea, 0x97, 0xaa, 0xbf, 0x21, 0x46, 0x59, 0x2c, 0x9a, 0xc4, 0xeb, 0xa3, 0x4a, 0x97, 0x91,
- 0x11, 0xf1, 0x01, 0x19, 0x7e, 0xb1, 0xb2, 0x63, 0x0d, 0xf0, 0x5d, 0xaf, 0x53, 0xdf, 0x4d, 0xa1, 0x90, 0xe5, 0x12, 0x82,
- 0x33, 0x6f, 0x1d, 0x73, 0xdf, 0xdb, 0x1f, 0x18, 0xa0, 0x72, 0xc1, 0xd6, 0xa7, 0x4d, 0xb2, 0x3e, 0x24, 0xb7, 0xa7, 0x76,
- 0x15, 0x46, 0x22, 0x48, 0x49, 0x55, 0xd1, 0xfb, 0x66, 0x32, 0x02, 0xa9, 0xfc, 0xbe, 0x7e, 0x16, 0xcf, 0xac, 0x32, 0xbc,
- 0xdb, 0xd5, 0xd8, 0xa3, 0x23, 0x6a, 0x10, 0xa6, 0x37, 0x03, 0xf6, 0x2a, 0xde, 0xba, 0xde, 0x2d, 0x7d, 0xef, 0x1d, 0xb9,
- 0xf3, 0x93, 0xd4, 0xf2, 0x13, 0xf4, 0x9c, 0x5a, 0x32, 0xba, 0x5f, 0xef, 0x7b, 0xd0, 0x6b, 0xd7, 0x91, 0x6d, 0x7b, 0xe1,
- 0x4d, 0xf2, 0x8c, 0xe7, 0xf1, 0x66, 0xb9, 0xad, 0xc6, 0x30, 0x08, 0x9e, 0x51, 0xd4, 0x39, 0x87, 0x09, 0xfa, 0x6b, 0x7a,
- 0xa7, 0x5f, 0x1a, 0x9c, 0x98, 0xc5, 0x76, 0xb0, 0x71, 0x76, 0xf5, 0xfc, 0x56, 0x88, 0x1c, 0xca, 0xee, 0x76, 0xd4, 0x2c,
- 0xa6, 0x64, 0x80, 0x59, 0x12, 0x8c, 0x08, 0xce, 0x83, 0xb3, 0xd9, 0x68, 0x59, 0xc1, 0x26, 0x86, 0xa7, 0x80, 0x10, 0xbc,
- 0x41, 0x28, 0x6c, 0x45, 0xd4, 0x6d, 0x15, 0xd0, 0x76, 0x44, 0x0e, 0xcf, 0xc1, 0xde, 0xef, 0x7a, 0x97, 0x36, 0x8f, 0x0d,
- 0x8a, 0xf5, 0x45, 0xde, 0xae, 0x61, 0xd0, 0x55, 0xe9, 0x8d, 0x62, 0xfd, 0xa3, 0x0d, 0x44, 0x0f, 0x49, 0xb6, 0x5a, 0xa4,
- 0xaa, 0x03, 0x4e, 0x60, 0x35, 0x53, 0x86, 0x9e, 0xec, 0x75, 0xd9, 0x0a, 0xca, 0x14, 0xe3, 0x1b, 0x06, 0x05, 0xd6, 0x8f,
- 0x4f, 0x11, 0xb3, 0x13, 0xdd, 0x26, 0x35, 0xbd, 0x56, 0x55, 0xf1, 0x43, 0x89, 0x5e, 0x5b, 0x25, 0x4d, 0xa8, 0x09, 0xdd,
- 0xf2, 0x6d, 0x9e, 0x8c, 0xcd, 0xa2, 0xde, 0x84, 0x00, 0x6a, 0x0a, 0xc6, 0x92, 0x30, 0x82, 0xcf, 0xa4, 0x31, 0x67, 0xbd,
- 0xd4, 0x36, 0x6a, 0x8b, 0xc6, 0x33, 0xdf, 0x8b, 0xde, 0x33, 0x01, 0x7b, 0x9d, 0xbf, 0xe9, 0x12, 0x35, 0x8a, 0x97, 0x07,
- 0x72, 0x0b, 0x6b, 0x60, 0xe6, 0x1e, 0x7d, 0x78, 0x22, 0x9f, 0xbf, 0x66, 0x8e, 0x02, 0xf4, 0xdc, 0xa1, 0xb0, 0x42, 0x73,
- 0x86, 0xca, 0x34, 0xf0, 0xa7, 0x2e, 0x15, 0x84, 0xa4, 0x60, 0xa8, 0x47, 0x05, 0x80, 0x03, 0x27, 0xa8, 0x04, 0x03, 0xfe,
- 0x47, 0xd4, 0xeb, 0x33, 0x27, 0xbf, 0x89, 0xff, 0x4c, 0xd9, 0x27, 0x0e, 0xd0, 0xa9, 0x41, 0x8b, 0xd5, 0x7c, 0xc4, 0x14,
- 0x7a, 0x9c, 0xb3, 0xaa, 0x13, 0x32, 0xa4, 0x67, 0xd5, 0x95, 0xdc, 0x4a, 0x3d, 0xf2, 0x54, 0xd7, 0x02, 0xf8, 0x06, 0x7b,
- 0x1d, 0x9a, 0xa4, 0x53, 0xa0, 0x9c, 0x76, 0x7d, 0xf4, 0x01, 0xa3, 0x4b, 0xb2, 0x8b, 0x44, 0x85, 0xf6, 0x80, 0x99, 0x2f,
- 0x77, 0x08, 0x20, 0xea, 0x08, 0xf8, 0x14, 0x76, 0xfe, 0xa0, 0x5a, 0xf9, 0x1f, 0x87, 0x03, 0xff, 0x8d, 0x1f, 0x5d, 0x02,
- 0x64, 0x8a, 0xf4, 0xa5, 0x8c, 0xb7, 0x0a, 0x34, 0x68, 0xaa, 0xca, 0xc8, 0xe1, 0x78, 0x9b, 0xd3, 0x6c, 0x5c, 0x07, 0x99,
- 0xc1, 0x10, 0x3f, 0x77, 0x0c, 0x45, 0xa2, 0xda, 0xda, 0xab, 0x7c, 0xf0, 0x90, 0x12, 0xa2, 0x7c, 0x84, 0x30, 0x82, 0x09,
- 0xc9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0xba, 0x04, 0x82, 0x09, 0xb6,
- 0x30, 0x82, 0x09, 0xb2, 0x30, 0x82, 0x09, 0xae, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
- 0x02, 0xa0, 0x82, 0x09, 0x76, 0x30, 0x82, 0x09, 0x72, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd3, 0x5d, 0xa8, 0x14, 0xbc, 0x7a, 0xaa, 0x5f, 0x02, 0x02, 0x08, 0x00, 0x04,
- 0x82, 0x09, 0x50, 0xaf, 0xe9, 0x63, 0xb6, 0x05, 0x8b, 0x48, 0xe1, 0x11, 0xd0, 0x37, 0x1d, 0x48, 0x71, 0x22, 0x70, 0xdc,
- 0xbd, 0xca, 0x98, 0x5d, 0x72, 0xca, 0x38, 0xdc, 0x2e, 0x4f, 0xd4, 0x71, 0xd3, 0xac, 0xf3, 0x0c, 0xcf, 0x78, 0x4e, 0x5c,
- 0x63, 0x35, 0xaa, 0xac, 0x5a, 0xf0, 0xef, 0x6c, 0xc0, 0x89, 0x28, 0xc4, 0x64, 0xec, 0x5c, 0x92, 0x72, 0xbc, 0xe5, 0x30,
- 0xe9, 0x5c, 0x35, 0xff, 0xe0, 0xb1, 0x1f, 0xc6, 0x37, 0x50, 0xb7, 0x3d, 0x94, 0x28, 0xbd, 0x3b, 0xf0, 0xd9, 0x5c, 0xb1,
- 0x45, 0x93, 0xde, 0x41, 0x5b, 0x12, 0xba, 0xfa, 0x27, 0x49, 0x6b, 0xb7, 0x9a, 0xa6, 0x46, 0x8e, 0xe3, 0x15, 0x1b, 0x7f,
- 0x2c, 0x91, 0x2e, 0x33, 0xf3, 0xef, 0x7a, 0x9b, 0x9d, 0xa8, 0x82, 0x95, 0xa0, 0x7e, 0x43, 0xd6, 0x9d, 0xe2, 0xfb, 0xb1,
- 0xb0, 0xcf, 0xbd, 0xb6, 0x9b, 0x55, 0x4c, 0xc8, 0x4a, 0xc7, 0x82, 0xeb, 0x3d, 0x09, 0x8d, 0x85, 0x6f, 0x8c, 0x42, 0x6d,
- 0x10, 0x7d, 0x77, 0x57, 0x29, 0x00, 0xe2, 0xd8, 0x2f, 0xed, 0x7c, 0x10, 0x5b, 0x03, 0xfa, 0x60, 0x34, 0xc9, 0x63, 0x25,
- 0x4d, 0x02, 0x77, 0x8f, 0x7f, 0x4b, 0x53, 0xe4, 0x8d, 0x1e, 0x4e, 0x2c, 0x0c, 0x7f, 0x0e, 0x48, 0x4b, 0xcd, 0xc8, 0x6a,
- 0xfa, 0xd3, 0x9f, 0x6f, 0x20, 0x4e, 0x2c, 0x77, 0x2a, 0x84, 0x5e, 0x6c, 0xc3, 0x57, 0xba, 0x97, 0xa7, 0xa8, 0xcb, 0x6f,
- 0x22, 0xc1, 0xa7, 0x61, 0xf7, 0x7e, 0x7a, 0xae, 0xda, 0xbd, 0x3a, 0xea, 0xb3, 0x46, 0x54, 0x8d, 0x46, 0x48, 0x1f, 0xf3,
- 0x5c, 0xaa, 0x2e, 0x44, 0xe1, 0x83, 0x69, 0x45, 0x30, 0x02, 0x49, 0x63, 0xa6, 0xdd, 0xf0, 0x25, 0xce, 0x81, 0xab, 0x66,
- 0x20, 0x04, 0x12, 0x2f, 0x94, 0x2f, 0x8f, 0xf9, 0x88, 0xea, 0x5b, 0xba, 0x87, 0xd7, 0xbe, 0x63, 0x2e, 0xb4, 0xa4, 0x15,
- 0xe8, 0x56, 0x9e, 0xb5, 0x7b, 0x27, 0xf8, 0x06, 0xfd, 0xf5, 0x21, 0x93, 0x2b, 0x64, 0xb0, 0xe2, 0x31, 0xb3, 0x19, 0xe0,
- 0x6b, 0x10, 0x8c, 0xa5, 0xa5, 0x38, 0x27, 0x78, 0xc9, 0x9c, 0x01, 0xa7, 0x42, 0x22, 0x3d, 0xf8, 0x8c, 0x23, 0x46, 0xc5,
- 0x4e, 0x47, 0xa5, 0x9e, 0xd7, 0xa5, 0x50, 0x24, 0x02, 0x30, 0xe9, 0x15, 0x3e, 0x17, 0xba, 0x2c, 0xf2, 0x5e, 0xc7, 0x01,
- 0x25, 0x9a, 0x74, 0x73, 0x5c, 0x5e, 0xca, 0x01, 0xe2, 0x58, 0x96, 0x47, 0x3e, 0x4c, 0xb9, 0x0f, 0x95, 0xbf, 0xf3, 0xc4,
- 0x24, 0x98, 0x6c, 0xc5, 0x40, 0xd2, 0xf3, 0x88, 0x62, 0xb0, 0x25, 0x54, 0xb5, 0xf6, 0x2b, 0xfd, 0xf5, 0x6a, 0x6d, 0x15,
- 0xb2, 0x18, 0x7d, 0xef, 0x3e, 0x66, 0x7d, 0x38, 0x4c, 0xda, 0xc9, 0x1a, 0xcd, 0x40, 0x2a, 0xc6, 0x7b, 0x2e, 0x8a, 0x15,
- 0xa7, 0xae, 0x99, 0xf5, 0x93, 0x39, 0x20, 0xd2, 0xd8, 0xfd, 0x1f, 0x87, 0x2e, 0xa0, 0xcd, 0x95, 0xa2, 0xd7, 0xd0, 0x48,
- 0xf7, 0x6e, 0x81, 0x91, 0x1c, 0x37, 0x8a, 0x28, 0x6f, 0x22, 0x7b, 0x37, 0x69, 0x30, 0x3a, 0x64, 0x6e, 0x4a, 0x5f, 0x0a,
- 0xa6, 0xd7, 0x53, 0xce, 0x1d, 0x60, 0x88, 0xa5, 0x0b, 0xde, 0xf5, 0x01, 0x3a, 0x20, 0xfa, 0xd6, 0x08, 0xdf, 0x83, 0x39,
- 0x2e, 0xb8, 0x3a, 0x91, 0xec, 0x39, 0x47, 0xaa, 0x66, 0x8a, 0xb4, 0x35, 0x70, 0xaf, 0x88, 0x24, 0xb2, 0xc3, 0xdc, 0x7c,
- 0xd0, 0x8f, 0x93, 0x0d, 0xa4, 0x53, 0xf1, 0x55, 0x92, 0xae, 0xd9, 0xeb, 0x31, 0xa0, 0x68, 0x29, 0xf5, 0xdb, 0x2f, 0xd1,
- 0xa3, 0xfe, 0x34, 0x2f, 0xcd, 0x64, 0x0c, 0x11, 0x13, 0x14, 0x50, 0xeb, 0x27, 0x56, 0xda, 0xc0, 0x30, 0x3a, 0x8c, 0x92,
- 0xb3, 0xb8, 0xc8, 0xb7, 0x19, 0xea, 0x4c, 0x74, 0xb9, 0x95, 0x46, 0x9f, 0xc0, 0x63, 0xfd, 0x72, 0x35, 0x0b, 0xb9, 0x1d,
- 0x1e, 0x85, 0xf8, 0xf9, 0x23, 0xf7, 0x42, 0xe2, 0xf4, 0x67, 0xbf, 0x3d, 0x30, 0x4b, 0x6a, 0xf2, 0x44, 0x2f, 0xcb, 0x6f,
- 0xe9, 0x73, 0x4b, 0x8f, 0x09, 0x29, 0x69, 0xcd, 0x8d, 0xcd, 0xc7, 0xd4, 0xa2, 0x0c, 0x6a, 0xc4, 0x9a, 0x33, 0xe2, 0x64,
- 0x5f, 0x07, 0xf2, 0xb6, 0xf8, 0x86, 0x7f, 0x05, 0x04, 0xf1, 0x1d, 0x9d, 0xd1, 0xc8, 0x3c, 0x16, 0x6e, 0x18, 0x96, 0x15,
- 0x33, 0xda, 0x84, 0xb6, 0xfd, 0x13, 0x29, 0x2f, 0x5e, 0xa0, 0x0e, 0xaa, 0xf6, 0x24, 0xb4, 0xa5, 0x48, 0x01, 0x02, 0x07,
- 0x31, 0x98, 0x0d, 0x9c, 0x65, 0x59, 0x68, 0x61, 0x22, 0xdb, 0x64, 0x16, 0x05, 0xae, 0xd8, 0x64, 0x5f, 0xba, 0x51, 0xab,
- 0x5e, 0xe0, 0xbe, 0x3d, 0x29, 0x67, 0x20, 0x94, 0x63, 0xfe, 0xc7, 0x90, 0x30, 0xc9, 0x43, 0xf1, 0xce, 0x9c, 0x53, 0x01,
- 0x2c, 0x64, 0x56, 0x85, 0xb7, 0x3b, 0xa4, 0x05, 0x5d, 0x88, 0xdf, 0x44, 0xda, 0x18, 0xf3, 0x8c, 0xdb, 0xae, 0xd2, 0x9f,
- 0xee, 0x4e, 0x08, 0x17, 0xf9, 0xd8, 0xe0, 0xc9, 0x7d, 0xa5, 0xad, 0x79, 0x06, 0x1b, 0x8c, 0x92, 0xe7, 0x53, 0xdf, 0xde,
- 0xa3, 0xa5, 0x84, 0x1d, 0xd8, 0x75, 0x35, 0x78, 0x32, 0x55, 0x6f, 0x4f, 0x29, 0x34, 0x4e, 0x6f, 0x32, 0x16, 0xe4, 0xfd,
- 0xbc, 0xf5, 0x76, 0x99, 0xf3, 0x48, 0x5b, 0xa0, 0x65, 0xb2, 0xef, 0xeb, 0x58, 0x6c, 0xf4, 0x1e, 0x97, 0x34, 0xee, 0xf9,
- 0x74, 0xe2, 0x94, 0xc0, 0xf2, 0xf5, 0x0b, 0x97, 0x40, 0xce, 0x25, 0xd6, 0xe5, 0xdf, 0x0b, 0x3b, 0x6b, 0xf3, 0x38, 0x28,
- 0xc3, 0xa6, 0x30, 0xa5, 0x22, 0x3c, 0xb0, 0xbd, 0x4d, 0xd5, 0x79, 0x25, 0xb9, 0xb2, 0xb4, 0xc4, 0x31, 0x62, 0x0b, 0xe7,
- 0x73, 0x4e, 0xf9, 0xa7, 0x57, 0xdf, 0x33, 0x0e, 0xf0, 0xb9, 0x3b, 0x6d, 0xff, 0x6b, 0x11, 0xb0, 0x90, 0x10, 0x2a, 0x7b,
- 0xb5, 0x0b, 0x41, 0x17, 0x0b, 0x12, 0xc7, 0x61, 0xef, 0xb1, 0x9b, 0x57, 0x3a, 0x01, 0x55, 0x91, 0xe3, 0xd5, 0xc8, 0xd5,
- 0xeb, 0x26, 0x90, 0x2b, 0x67, 0x5b, 0xc2, 0x0b, 0xad, 0x6f, 0x26, 0x3a, 0xf5, 0x45, 0xb2, 0xd7, 0x6a, 0x78, 0xaa, 0x43,
- 0xd0, 0xdb, 0x53, 0x6f, 0x1a, 0x7a, 0x5c, 0x92, 0xe1, 0xb7, 0xe5, 0xad, 0xda, 0xac, 0x3b, 0x5a, 0x20, 0x06, 0xe1, 0x56,
- 0xf0, 0x55, 0x66, 0x64, 0x42, 0xd4, 0xe4, 0x77, 0x3b, 0xa5, 0x60, 0x8d, 0x5b, 0x24, 0x7a, 0x2a, 0xb9, 0xe2, 0x2f, 0xc6,
- 0x02, 0xd1, 0x21, 0xf3, 0x08, 0xbd, 0x7b, 0xf4, 0x44, 0x47, 0x00, 0xd2, 0xca, 0x3c, 0x80, 0x37, 0xb0, 0xf2, 0x3d, 0x07,
- 0x87, 0xbd, 0xe8, 0x59, 0x01, 0x17, 0x7b, 0xb3, 0x1b, 0xc3, 0xce, 0x45, 0x77, 0x3c, 0x0e, 0xdd, 0xac, 0x38, 0xf1, 0x5e,
- 0xde, 0x5e, 0xdd, 0xad, 0xf2, 0xc9, 0x0f, 0xed, 0xec, 0xe5, 0x00, 0x8b, 0x61, 0xf4, 0x62, 0xd5, 0x58, 0x37, 0xec, 0xbf,
- 0x36, 0xcf, 0x7a, 0x6a, 0x55, 0x1f, 0x25, 0x53, 0xba, 0xcd, 0x76, 0xc3, 0x07, 0x5e, 0x12, 0xf0, 0xc3, 0x82, 0x52, 0x5f,
- 0xc6, 0x24, 0x54, 0x76, 0x49, 0xa3, 0xf1, 0xdd, 0x67, 0x29, 0x81, 0x19, 0x5f, 0x7b, 0xcd, 0xc6, 0x60, 0x3e, 0x80, 0x02,
- 0xb3, 0xd9, 0xb6, 0x9d, 0x29, 0x59, 0xdc, 0x79, 0x90, 0xab, 0x53, 0xf4, 0xe6, 0x23, 0xb4, 0x77, 0x0f, 0xc8, 0xf2, 0x88,
- 0xb3, 0x1c, 0x70, 0xb4, 0xeb, 0xa8, 0xdf, 0x25, 0x5b, 0x94, 0xa6, 0xce, 0x80, 0xbd, 0x46, 0xe6, 0x26, 0x8c, 0x4f, 0xee,
- 0x37, 0x81, 0x84, 0xc6, 0xff, 0x0a, 0x37, 0x2e, 0xa4, 0xcb, 0xdf, 0x62, 0x81, 0x79, 0x3b, 0xa2, 0xdb, 0x07, 0x14, 0x0c,
- 0xf7, 0x44, 0x1e, 0xda, 0xe0, 0x6c, 0x1a, 0xb6, 0x52, 0x7f, 0xd8, 0xce, 0xe7, 0x29, 0x98, 0xc1, 0x69, 0x40, 0xb9, 0x2a,
- 0xe7, 0xb4, 0xee, 0x04, 0x67, 0xf7, 0x54, 0xac, 0x94, 0x12, 0x5c, 0x67, 0xb4, 0x51, 0x9c, 0xf6, 0xfa, 0x9b, 0x10, 0xd3,
- 0x7e, 0xce, 0x78, 0xd5, 0x88, 0x80, 0xd7, 0x88, 0xea, 0x16, 0x51, 0x0c, 0xc9, 0xf2, 0x55, 0xda, 0xbd, 0x22, 0x34, 0x1a,
- 0x65, 0x8f, 0xd7, 0x52, 0x00, 0x98, 0xc3, 0x76, 0xff, 0x3e, 0xfc, 0x44, 0x4b, 0x7e, 0xc2, 0x40, 0x00, 0x94, 0xf3, 0xc6,
- 0xd5, 0xa3, 0x0f, 0x95, 0x9a, 0x96, 0xbb, 0x50, 0xcd, 0xd0, 0x6f, 0x75, 0xd7, 0xcc, 0x89, 0xb4, 0xc2, 0x85, 0x7f, 0x5f,
- 0x06, 0xc1, 0xdf, 0x3c, 0xdd, 0x32, 0xdb, 0x44, 0xae, 0x1e, 0xd8, 0x56, 0xde, 0x93, 0xb0, 0xbd, 0xed, 0x8c, 0xb6, 0xcc,
- 0x15, 0xe7, 0x81, 0x98, 0x36, 0x36, 0xd6, 0x91, 0x61, 0xd8, 0x65, 0x57, 0x5d, 0xcd, 0xbf, 0xf1, 0x3b, 0x31, 0xb6, 0xdd,
- 0x6e, 0xc6, 0xd3, 0x1b, 0xc9, 0x47, 0x8c, 0x09, 0x03, 0x81, 0x7d, 0xbd, 0x64, 0xa9, 0x09, 0x66, 0x81, 0x2d, 0x56, 0x43,
- 0xe8, 0x3c, 0x3e, 0xaa, 0xf8, 0x28, 0x92, 0x13, 0xea, 0x1f, 0xc1, 0x81, 0x4f, 0xb1, 0x1e, 0x88, 0xd2, 0x47, 0xdb, 0xb4,
- 0x7e, 0xcb, 0xac, 0xc4, 0xbc, 0x07, 0x68, 0x83, 0x7d, 0xd2, 0x90, 0x90, 0x01, 0xa7, 0x0b, 0xac, 0x60, 0x67, 0x0f, 0xf4,
- 0x1b, 0x2c, 0x1e, 0x93, 0x93, 0x6a, 0x16, 0x63, 0x78, 0x36, 0x7d, 0xc5, 0xa5, 0x04, 0xf4, 0x96, 0x1d, 0xae, 0x1a, 0xdf,
- 0x1d, 0xba, 0xfc, 0x00, 0x21, 0x07, 0x8c, 0xa7, 0x9d, 0x00, 0x60, 0xb7, 0xa4, 0x05, 0xdd, 0xcd, 0x05, 0xee, 0x70, 0x5e,
- 0xc5, 0x79, 0x6c, 0xc1, 0x22, 0x57, 0xfb, 0x5a, 0x25, 0x3e, 0xb9, 0x37, 0x76, 0x61, 0xc2, 0x7d, 0x14, 0x3c, 0xd3, 0x3a,
- 0x13, 0xb9, 0x33, 0x07, 0xf6, 0x53, 0xc9, 0x5b, 0xb9, 0x97, 0x03, 0xd0, 0x76, 0xb8, 0xd1, 0xf1, 0x43, 0x9d, 0x7f, 0x37,
- 0x46, 0x1a, 0xda, 0xdf, 0xd7, 0x4a, 0xb7, 0x79, 0x84, 0x9e, 0x47, 0x73, 0xac, 0x26, 0xf7, 0xd7, 0x54, 0x16, 0xad, 0x49,
- 0x5e, 0x5d, 0x77, 0x61, 0x79, 0xdd, 0x52, 0x13, 0x2f, 0x20, 0xce, 0x26, 0x35, 0xa3, 0x60, 0x28, 0x3f, 0xc5, 0x67, 0xce,
- 0x43, 0xa0, 0x86, 0x28, 0xf7, 0xa6, 0xf9, 0x6a, 0xbf, 0x25, 0x41, 0xb7, 0x7d, 0xbc, 0x04, 0x02, 0xd1, 0xe5, 0xed, 0x74,
- 0xf5, 0xf5, 0x39, 0xf5, 0x18, 0x42, 0x9f, 0xdc, 0xaf, 0x46, 0xb6, 0x55, 0x48, 0x72, 0xa6, 0x66, 0x94, 0xef, 0x4a, 0x45,
- 0x92, 0xf8, 0x31, 0x7a, 0x19, 0x69, 0xcb, 0xcf, 0xf3, 0x10, 0x4a, 0x65, 0x53, 0x18, 0xf4, 0x7f, 0x47, 0xe8, 0xe5, 0x07,
- 0xb1, 0x8b, 0x3c, 0x3b, 0xb1, 0x1f, 0xdb, 0xb8, 0x5d, 0x53, 0xcb, 0xad, 0xf7, 0x38, 0x91, 0x8a, 0x1e, 0xa6, 0x76, 0x05,
- 0x48, 0x89, 0xcc, 0xff, 0x51, 0x59, 0x53, 0xe9, 0xd7, 0x6e, 0x1a, 0x6e, 0xad, 0xf2, 0xcb, 0xf5, 0xfd, 0x48, 0xbe, 0xa8,
- 0x70, 0xae, 0x5e, 0xc1, 0x7e, 0x1e, 0x07, 0x8e, 0x64, 0x0d, 0x70, 0xb7, 0x92, 0xda, 0x6f, 0x45, 0xb0, 0xe3, 0x8a, 0x30,
- 0xbc, 0x45, 0xd1, 0x65, 0xf2, 0xb7, 0xab, 0x4e, 0x16, 0x5c, 0xa2, 0xb2, 0x9a, 0x4d, 0x2f, 0x76, 0x26, 0x62, 0x92, 0x7a,
- 0x3c, 0x47, 0xf6, 0x87, 0x04, 0x0f, 0x7b, 0xda, 0x4b, 0x02, 0x6b, 0xd6, 0x16, 0x79, 0xbd, 0x16, 0x24, 0x42, 0x7a, 0xf4,
- 0x44, 0x58, 0xb4, 0x68, 0x71, 0xce, 0xb3, 0x28, 0xba, 0x84, 0x6c, 0x26, 0x82, 0x1e, 0xba, 0x19, 0x83, 0xb7, 0x75, 0x1b,
- 0xde, 0x09, 0xf6, 0x1b, 0x4f, 0x31, 0x65, 0xae, 0xb6, 0x45, 0xc2, 0xa7, 0x35, 0x2d, 0x9f, 0x14, 0x10, 0xe0, 0x3e, 0x43,
- 0xa7, 0x82, 0x01, 0x06, 0x95, 0x2c, 0x19, 0x43, 0x8c, 0x94, 0xd4, 0x8c, 0x85, 0x6d, 0x88, 0x33, 0xff, 0x19, 0x51, 0xd3,
- 0x7c, 0xf2, 0xa7, 0x5b, 0x05, 0xd1, 0x2b, 0x56, 0x18, 0x5e, 0xa6, 0xb9, 0x66, 0x3c, 0xf7, 0x4d, 0xbd, 0xa9, 0x95, 0x75,
- 0xa9, 0xa1, 0x87, 0x24, 0x87, 0xf0, 0x60, 0xbb, 0x39, 0xec, 0xd1, 0xe5, 0x67, 0x51, 0x76, 0x99, 0xbc, 0x64, 0x7b, 0x5a,
- 0xd5, 0xa6, 0x54, 0x4f, 0x16, 0x10, 0xb2, 0xe9, 0x43, 0x1c, 0x3a, 0x4c, 0x88, 0x51, 0xf4, 0xc2, 0x95, 0x16, 0x8e, 0xbf,
- 0x79, 0x19, 0x22, 0x95, 0xd1, 0x76, 0x99, 0xb8, 0x68, 0xf3, 0x6a, 0x1a, 0x4e, 0x43, 0xf8, 0x9c, 0x6b, 0x75, 0x8c, 0xa5,
- 0xbd, 0x65, 0x3a, 0x83, 0x0b, 0x47, 0xcf, 0x08, 0xf7, 0x22, 0x86, 0xad, 0xd5, 0x89, 0xd0, 0x6f, 0x4e, 0xbe, 0x2a, 0x81,
- 0x1d, 0x1c, 0xf1, 0xc8, 0xf3, 0x18, 0x44, 0x40, 0xf3, 0x99, 0xfd, 0x18, 0xe3, 0x1a, 0xc9, 0x7f, 0x3b, 0x93, 0x68, 0x84,
- 0xe2, 0x49, 0xb9, 0xcf, 0x00, 0x5c, 0x76, 0xc4, 0xcc, 0x4b, 0x7e, 0x86, 0x7e, 0x3f, 0x4b, 0x23, 0x61, 0x92, 0x7c, 0xcb,
- 0x0c, 0x0c, 0x3e, 0x97, 0x34, 0xcc, 0xfd, 0x34, 0xa9, 0xcc, 0xf0, 0x83, 0xb1, 0xbc, 0x50, 0x4c, 0x84, 0x6f, 0xba, 0x68,
- 0x01, 0x4f, 0x71, 0x57, 0x05, 0x7f, 0x01, 0xe2, 0x18, 0x23, 0xe9, 0x44, 0xa8, 0x4d, 0x93, 0x11, 0xee, 0xc0, 0x79, 0x5a,
- 0x94, 0x13, 0x81, 0xf4, 0x67, 0xa0, 0x50, 0x79, 0x83, 0xa1, 0x13, 0x5f, 0x0e, 0x82, 0x9a, 0x72, 0x90, 0xba, 0x43, 0x21,
- 0x28, 0xa9, 0x65, 0x1c, 0x16, 0x97, 0x6f, 0xdb, 0xc3, 0x1e, 0x23, 0xc5, 0x4a, 0xdb, 0x3b, 0x3c, 0x42, 0x4a, 0xc4, 0xb5,
- 0x7f, 0x6b, 0x5d, 0xfc, 0x09, 0x08, 0x43, 0x2f, 0xf8, 0x11, 0x27, 0x6f, 0x1d, 0xc0, 0x12, 0x59, 0x04, 0xa4, 0x5b, 0xe9,
- 0x9f, 0x25, 0xd1, 0x58, 0x3a, 0x1f, 0xac, 0x05, 0x15, 0x18, 0xea, 0xbd, 0x4b, 0xd2, 0xba, 0x67, 0xf3, 0x1d, 0x89, 0x09,
- 0x52, 0xe5, 0x0e, 0x15, 0xd6, 0x5b, 0x87, 0xf5, 0xc3, 0x3c, 0x98, 0xbc, 0x46, 0x4e, 0x19, 0x8d, 0xbb, 0x3e, 0xe0, 0xde,
- 0x19, 0x59, 0x53, 0x32, 0x62, 0x31, 0x16, 0xd4, 0xea, 0x63, 0xda, 0xf4, 0xcc, 0x94, 0xd0, 0x18, 0x98, 0xbc, 0x00, 0xd3,
- 0x6c, 0xe2, 0xa5, 0xac, 0x30, 0x08, 0x9d, 0x68, 0x82, 0x8e, 0xbb, 0xdf, 0x9a, 0xa1, 0x13, 0xa5, 0x98, 0x18, 0xa9, 0x11,
- 0xde, 0x49, 0x18, 0x88, 0xab, 0xff, 0xc6, 0x2c, 0xa8, 0xe1, 0xf7, 0x49, 0xba, 0x17, 0x93, 0x1c, 0x6c, 0x7f, 0x2c, 0xa9,
- 0x3a, 0xee, 0x77, 0x9d, 0x46, 0x0c, 0xf9, 0x1c, 0x24, 0x33, 0x6f, 0x9b, 0xf8, 0x47, 0x9d, 0xc9, 0x7f, 0x9c, 0x80, 0xa0,
- 0x2c, 0x96, 0x63, 0xe1, 0x97, 0x75, 0x75, 0x1f, 0xb3, 0xc6, 0x0d, 0xa9, 0x49, 0x82, 0x66, 0x86, 0x13, 0xa4, 0x62, 0x4c,
- 0x56, 0x89, 0x73, 0x03, 0x1b, 0x61, 0xff, 0xfa, 0x0f, 0xf4, 0x84, 0xe3, 0xad, 0x89, 0xc0, 0x8e, 0x03, 0x91, 0x1c, 0x99,
- 0x9f, 0x99, 0x92, 0x7e, 0xb5, 0xd8, 0xe3, 0xee, 0x6c, 0x21, 0x27, 0x5d, 0xa2, 0xa5, 0x90, 0xf2, 0x67, 0xed, 0xf3, 0xca,
- 0x51, 0x56, 0x28, 0x7d, 0xa9, 0xd0, 0x4a, 0x4b, 0x76, 0x2b, 0xa8, 0x95, 0x8a, 0x37, 0xb4, 0x72, 0x96, 0xb2, 0xa0, 0xbe,
- 0x90, 0x4f, 0x4e, 0x37, 0xbb, 0x14, 0xf8, 0xd2, 0x76, 0x7c, 0x79, 0xf3, 0xd2, 0xbf, 0x35, 0xad, 0x64, 0xbc, 0x98, 0x73,
- 0xe5, 0xb9, 0xb3, 0xa2, 0x9b, 0x54, 0x17, 0x9b, 0x99, 0xa1, 0xeb, 0xfd, 0xc2, 0x8b, 0xbd, 0xac, 0x6d, 0x14, 0x35, 0xc2,
- 0x3b, 0xc9, 0x88, 0x57, 0x64, 0xaa, 0x52, 0x3d, 0xf1, 0x80, 0x9c, 0xb2, 0xfc, 0xe9, 0x53, 0x7c, 0x12, 0x81, 0xe6, 0x07,
- 0xa1, 0x0b, 0x2b, 0xb3, 0x88, 0xa6, 0x07, 0xb8, 0x10, 0x7e, 0xc4, 0x55, 0x14, 0xa2, 0x66, 0xf1, 0xcc, 0xff, 0x49, 0x84,
- 0xbc, 0x54, 0x15, 0x41, 0x26, 0x15, 0x44, 0xf1, 0xe4, 0x4e, 0x8a, 0xf4, 0x02, 0xb1, 0x87, 0x51, 0xa7, 0xa4, 0xe6, 0x4f,
- 0xbb, 0xff, 0xfe, 0x94, 0x51, 0x54, 0x20, 0x7e, 0x16, 0x60, 0x23, 0xfe, 0x05, 0x8c, 0x1a, 0xe1, 0x12, 0x7c, 0xd4, 0xc0,
- 0xae, 0x3a, 0x96, 0x13, 0x5d, 0x83, 0x89, 0x49, 0x99, 0x2c, 0x3e, 0x19, 0x8b, 0xa8, 0xf0, 0x0d, 0x65, 0x5d, 0x35, 0x37,
- 0xa1, 0x2d, 0xdd, 0xe2, 0x6b, 0x0d, 0xa9, 0x47, 0x9e, 0xf0, 0x22, 0xb5, 0x8e, 0xab, 0xc1, 0x34, 0x93, 0x4c, 0xff, 0x89,
- 0x9b, 0x24, 0xd4, 0x01, 0x24, 0xbc, 0xf5, 0x42, 0xd8, 0xee, 0xc2, 0xbc, 0x78, 0x03, 0xc1, 0x24, 0xa8, 0x88, 0xba, 0x3f,
- 0x71, 0x58, 0x3d, 0xdd, 0xef, 0xa8, 0xf8, 0x15, 0x4c, 0xb0, 0x68, 0x7c, 0xbc, 0x41, 0x66, 0x72, 0xc4, 0x4d, 0x9f, 0xd0,
- 0xdb, 0x9a, 0xd0, 0x65, 0xde, 0xf1, 0x25, 0x02, 0x35, 0xff, 0x49, 0x4a, 0xd8, 0xa4, 0x19, 0x49, 0xb4, 0x51, 0xda, 0x4b,
- 0x75, 0x81, 0x17, 0xa7, 0x84, 0x80, 0x70, 0x3f, 0xc7, 0x0d, 0xb2, 0x79, 0x24, 0x25, 0x7c, 0xe2, 0x30, 0x67, 0x15, 0x00,
- 0x80, 0x68, 0x1e, 0xde, 0xf0, 0x3e, 0xda, 0xc6, 0x31, 0x4d, 0xa7, 0xf0, 0x53, 0x0d, 0x88, 0x08, 0xe1, 0xd8, 0xe2, 0x8b,
- 0x01, 0xdb, 0x9f, 0x5b, 0x7c, 0xd4, 0x68, 0x89, 0xb1, 0xeb, 0xdb, 0x4e, 0x6f, 0xac, 0x21, 0xad, 0xf2, 0xed, 0x6f, 0x61,
- 0x4d, 0x1f, 0x2f, 0x64, 0x0b, 0xdb, 0x07, 0x54, 0x65, 0xd7, 0xf0, 0xf8, 0x40, 0xdb, 0xd9, 0x5e, 0x2d, 0xaf, 0x4f, 0x14,
- 0x9f, 0x5b, 0x0b, 0x74, 0x4e, 0xad, 0x07, 0x60, 0xac, 0x24, 0x04, 0x5b, 0xc8, 0xf4, 0xc9, 0x6f, 0x28, 0xb0, 0x2b, 0xb3,
- 0xd9, 0x43, 0xf1, 0x55, 0xc9, 0x25, 0x01, 0xb7, 0xab, 0x8f, 0xd8, 0x0f, 0x78, 0x6a, 0xbf, 0xa0, 0x4e, 0x80, 0x22, 0xc6,
- 0x8a, 0x42, 0x37, 0x6d, 0x3a, 0xbd, 0xf3, 0x66, 0xbe, 0x84, 0x87, 0xf6, 0xa1, 0xa0, 0x99, 0x7f, 0x13, 0x66, 0x40, 0x39,
- 0xce, 0x43, 0x8f, 0xe5, 0x83, 0x48, 0x94, 0xc6, 0x59, 0xc2, 0xce, 0x55, 0x35, 0x44, 0x74, 0xa6, 0x37, 0x0c, 0x3c, 0x69,
- 0xdc, 0xdb, 0x2b, 0x3a, 0xd8, 0x32, 0x4d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x01, 0xae, 0x1a, 0x61, 0x75, 0xae, 0x23, 0xd9, 0x11, 0x5c, 0x28, 0x93, 0xa9, 0xe2,
- 0x49, 0x5e, 0x74, 0x28, 0x4c, 0x08, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
- 0x00, 0x04, 0x14, 0x3d, 0xc6, 0xb0, 0x07, 0xf5, 0xd4, 0xa7, 0x42, 0x90, 0xa1, 0x2f, 0x4d, 0x1e, 0x43, 0x09, 0x7d, 0xd5,
- 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 */
/*
- * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2015-2018 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <Security/Security.h>
#include <Security/SecCMS.h>
#include <Security/SecCmsBase.h>
+#include <Security/CMSEncoder.h>
+#include <Security/CMSDecoder.h>
#include <utilities/SecCFRelease.h>
-#include "Security_regressions.h"
+#if TARGET_OS_OSX
+#include <Security/CMSPrivate.h>
+#endif
+
+#include "shared_regressions.h"
-#include "si-89-cms-hash-agility.h"
+#include "si-cms-hash-agility-data.h"
static void ios_shim_tests(void)
{
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(message = CFDataCreate(NULL, valid_message, valid_message_size), "Create valid message");
+ ok(contentData = CFDataCreate(NULL, content, content_size), "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");
+ CFReleaseNull(trust);
/* verify we can get the parsed attribute */
uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x1 };
CFReleaseNull(message);
/* verify the invalid message */
- ok(message = CFDataCreate(NULL, invalid_message, sizeof(invalid_message)), "Create invalid message");
+ ok(message = CFDataCreate(NULL, invalid_message, invalid_message_size), "Create invalid message");
is(SecCMSVerify(message, contentData, policy, &trust, NULL), errSecAuthFailed,
"Verify invalid CMS message");
CFReleaseNull(message);
+ CFReleaseNull(trust);
+ CFReleaseNull(attrs);
/* verify the valid message with no hash agility attribute */
- ok(message = CFDataCreate(NULL, valid_no_attr, sizeof(valid_no_attr)),
+ ok(message = CFDataCreate(NULL, valid_no_attr, valid_no_attr_size),
"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");
}
/* MARK: macOS Shim tests */
-#include <Security/CMSEncoder.h>
-#include <Security/CMSDecoder.h>
-
/* encode test */
-static void encode_test(void)
+static void encode_test(SecIdentityRef identity)
{
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;
-
+ CFDataRef attributeData = NULL, message = 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");
+ /* Set identity as signer */
ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity");
/* Add signing time attribute for 3 November 2015 */
/* Load content */
ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content");
- ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content");
+ ok_status(CMSEncoderUpdateContent(encoder, content, content_size), "Set content");
/* output cms message */
ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message");
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(contentData = CFDataCreate(NULL, content, content_size), "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);
/* Create decoder and decode */
ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder");
- ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)),
+ ok_status(CMSDecoderUpdateMessage(decoder, valid_message, valid_message_size),
"Update decoder with CMS message");
- ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
+ ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content");
ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content");
ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
/* Create decoder and decode */
ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder");
- ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)),
+ ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, invalid_message_size),
"Update decoder with CMS message");
- ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
+ ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content");
ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content");
ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
/* Create decoder and decode */
ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder");
- ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)),
+ ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, valid_no_attr_size),
"Update decoder with CMS message");
- ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
+ ok(contentData = CFDataCreate(NULL, content, content_size), "Create detached content");
ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content");
ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
CFReleaseNull(attrValue);
}
-static void macos_shim_tests(void) {
- encode_test();
+static void macos_shim_tests(SecIdentityRef identity) {
+ encode_test(identity);
decode_positive_test();
decode_negative_test();
decode_no_attr_test();
NSArray *attrValues = nil;
NSDate *signingTime = nil;
- message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)];
- contentData = [NSData dataWithBytes:content length:sizeof(content)];
+ message = [NSMutableData dataWithBytes:_V2_valid_message length:_V2_valid_message_size];
+ contentData = [NSData dataWithBytes:content length:content_size];
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");
+ require_action(attrs, exit, fail("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");
+ is([attrValues count], (size_t)2, "Two attribute values");
/* verify we can get the "cooked" parsed attribute */
- require_string(hashAgilityValue = (NSDictionary *)attrs[(__bridge NSString*)kSecCMSHashAgilityV2], exit,
- "Get cooked hash agility value");
+ require_action(hashAgilityValue = (NSDictionary *)attrs[(__bridge NSString*)kSecCMSHashAgilityV2], exit,
+ fail("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]],
attrValues = NULL;
/*verify we can get the signing time attribute */
- require_string(signingTime = attrs[(__bridge NSString*)kSecCMSSignDate], exit, "Failed to get signing time");
+ require_action(signingTime = attrs[(__bridge NSString*)kSecCMSSignDate], exit, fail("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 */
+ message = [NSMutableData dataWithBytes:_V2_valid_message length:_V2_valid_message_size];
+ [message resetBytesInRange:NSMakeRange(2110, 1)]; /* 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)];
+ message = [NSMutableData dataWithBytes:valid_no_attr length:valid_no_attr_size];
is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL, &tmpAttrs),
errSecSuccess, "Verify 2nd valid CMS message and get attributes");
attrs = CFBridgingRelease(tmpAttrs);
}
/* macOS shim test - encode */
-static void encode_V2_test(void) {
+static void encode_V2_test(SecIdentityRef identity) {
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" };
+ NSDictionary *attrValues = nil;
/* 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");
+ require_noerr_action(CMSEncoderCreate(&encoder), exit, fail("Failed to create CMS encoder"));
+ require_noerr_action(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit,
+ fail("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");
+ /* Set identity as signer */
+ require_noerr_action(CMSEncoderAddSigners(encoder, identity), exit, fail("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");
+ require_noerr_action(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit,
+ fail("Failed to set signing time flag"));
+ require_noerr_action(CMSEncoderSetSigningTime(encoder, 530700000.0), exit, fail("Failed to set signing time"));
/* Add hash agility attribute */
attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20],
"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");
+ require_noerr_action(CMSEncoderSetHasDetachedContent(encoder, true), exit, fail("Failed to set detached content"));
+ require_noerr_action(CMSEncoderUpdateContent(encoder, content, content_size), exit, fail("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),
+ require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Create CMS decoder"));
+ require_noerr_action(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");
+ fail("Update decoder with CMS message"));
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content
+ length:content_size]),
+ exit, fail("Set detached content"));
ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
exit:
CFReleaseNull(encoder);
- CFReleaseNull(identity);
CFReleaseNull(message);
CFReleaseNull(decoder);
}
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");
+ require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, _V2_valid_message, _V2_valid_message_size), exit,
+ fail("Failed to update decoder with CMS message"));
+ contentData = [NSData dataWithBytes:content length:content_size];
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit,
+ fail("Failed to set detached content"));
ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
/* Get signer status */
- require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy");
+ require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy"));
ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
"Copy Signer status");
is(signerStatus, kCMSSignerValid, "Valid signature");
NSMutableData *invalid_message = nil;
/* Create decoder and decode */
- invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)];
+ invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:_V2_valid_message_size];
[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");
+ require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit,
+ fail("Failed to update decoder with CMS message"));
+ contentData = [NSData dataWithBytes:content length:content_size];
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit,
+ fail("Failed to set detached content"));
ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
/* Get signer status */
- require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy");
+ require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy"));
ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
"Copy Signer status");
is(signerStatus, kCMSSignerInvalidSignature, "Valid signature");
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");
+ require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder"));
+ require_noerr_action(CMSDecoderUpdateMessage(decoder, valid_message, valid_message_size), exit,
+ fail("Failed to update decoder with CMS message"));
+ contentData = [NSData dataWithBytes:content length:content_size];
+ require_noerr_action(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit,
+ fail("Failed to set detached content"));
ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
/* Get signer status */
- require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy");
+ require_action(policy = SecPolicyCreateBasicX509(), exit, fail("Failed to Create policy"));
ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
"Copy Signer status");
is(signerStatus, kCMSSignerValid, "Valid signature");
CFReleaseNull(attrValue);
}
-static void macOS_shim_V2_tests(void) {
- encode_V2_test();
+static void macOS_shim_V2_tests(SecIdentityRef identity) {
+ encode_V2_test(identity);
decode_V2_positive_test();
decode_V2_negative_test();
decodeV2_no_attr_test();
}
+static bool setup_keychain(const uint8_t *p12, size_t p12_len, SecIdentityRef *identity) {
+ CFArrayRef tmp_imported_items = NULL;
+ NSArray *imported_items = nil;
+
+ NSDictionary *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" };
+ NSData *p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)];
+ require_noerr_action(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options,
+ &tmp_imported_items), exit,
+ fail("Failed to import identity"));
+ imported_items = CFBridgingRelease(tmp_imported_items);
+ require_noerr_action([imported_items count] == 0 &&
+ [imported_items[0] isKindOfClass:[NSDictionary class]], exit,
+ fail("Wrong imported items output"));
+ *identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]);
+ require_action(*identity, exit, fail("Failed to get identity"));
+
+ return true;
+
+exit:
+ return false;
+}
+
+static void cleanup_keychain(SecIdentityRef identity) {
+#if TARGET_OS_OSX
+ // SecPKCS12Import adds the items to the keychain on macOS
+ NSDictionary *query = @{ (__bridge NSString*)kSecValueRef : (__bridge id)identity };
+ ok_status(SecItemDelete((__bridge CFDictionaryRef)query), "failed to remove identity from keychain");
+#else
+ pass("skip test on iOS");
+#endif
+ CFReleaseNull(identity);
+}
+
int si_89_cms_hash_agility(int argc, char *const *argv)
{
- plan_tests(99);
+ plan_tests(102);
+
+ SecIdentityRef identity = NULL;
+
+ if (setup_keychain(signing_identity_p12 , sizeof(signing_identity_p12), &identity)) {
+ ios_shim_tests();
+ macos_shim_tests(identity);
+ ios_shim_V2_tests();
+ macOS_shim_V2_tests(identity);
+ }
- ios_shim_tests();
- macos_shim_tests();
- ios_shim_V2_tests();
- macOS_shim_V2_tests();
+ cleanup_keychain(identity);
return 0;
}
--- /dev/null
+#include "si-cms-hash-agility-data.h"
+
+/* Random data for content */
+unsigned char content[1024] = {
+ 0x2a, 0xb1, 0x8c, 0xf1, 0x66, 0x52, 0xd5, 0x3c, 0xdd, 0x53, 0xc0, 0x07, 0x6a, 0x13, 0xda, 0x25, 0x9c, 0x04, 0x64, 0x5c,
+ 0x97, 0xb8, 0xb3, 0xb5, 0xcf, 0xf8, 0xe1, 0x8f, 0xdd, 0x49, 0x64, 0x55, 0x97, 0xad, 0xbc, 0xad, 0xff, 0xd1, 0xd9, 0xdf,
+ 0x0f, 0x26, 0x96, 0x27, 0x78, 0x1b, 0x13, 0xf6, 0x2e, 0x75, 0xb2, 0x6a, 0xf1, 0x04, 0x71, 0xa3, 0x51, 0x8d, 0x9c, 0xe8,
+ 0xab, 0xee, 0xf4, 0xf4, 0xfa, 0x75, 0x16, 0xbe, 0x08, 0xaf, 0xdf, 0x23, 0xc2, 0x17, 0x75, 0x80, 0xad, 0x0e, 0x68, 0xc1,
+ 0x37, 0xd9, 0x49, 0x0b, 0xea, 0x8a, 0x29, 0x3a, 0x2d, 0xff, 0x45, 0xe9, 0x13, 0x93, 0xac, 0x2e, 0x25, 0x3d, 0x5f, 0xd1,
+ 0x36, 0x66, 0x61, 0x14, 0xa9, 0xf1, 0xae, 0x83, 0x3a, 0x96, 0xe3, 0xcd, 0xe1, 0xdd, 0xb8, 0x8b, 0x85, 0xe7, 0xd9, 0x1b,
+ 0x76, 0xf9, 0x55, 0xf7, 0xd8, 0xb6, 0xca, 0x5b, 0x0f, 0xb8, 0x40, 0x1b, 0x69, 0x54, 0x07, 0xde, 0xd5, 0x26, 0x85, 0x9b,
+ 0xd1, 0x4a, 0xce, 0x2b, 0xe1, 0xd8, 0xe7, 0x6a, 0x06, 0x28, 0x4b, 0x05, 0xa9, 0x0b, 0x65, 0x07, 0x3d, 0xf5, 0xca, 0x31,
+ 0xd0, 0xfb, 0x5b, 0xf8, 0x1e, 0x19, 0x5f, 0x69, 0x64, 0x1b, 0xe1, 0x6d, 0x15, 0x88, 0x9c, 0xd1, 0x25, 0x4d, 0xf2, 0xa5,
+ 0x74, 0x82, 0xa4, 0xd3, 0x21, 0xc2, 0x4f, 0x78, 0xcf, 0x37, 0xdd, 0x3c, 0xe5, 0x69, 0x27, 0x82, 0xf1, 0xc8, 0xe9, 0x2f,
+ 0x7a, 0x7d, 0xd4, 0x65, 0x78, 0xad, 0x4c, 0xfc, 0xa5, 0x29, 0x51, 0xe2, 0x67, 0xac, 0x29, 0xa4, 0x23, 0x46, 0xe0, 0x10,
+ 0x55, 0x2a, 0x7e, 0xef, 0x04, 0xd4, 0x9f, 0xe3, 0x65, 0x09, 0x2d, 0x33, 0x07, 0xa5, 0x6c, 0x3d, 0x6e, 0xf5, 0x3e, 0xda,
+ 0x92, 0xb3, 0x47, 0x89, 0xa8, 0xda, 0x04, 0xe0, 0xa6, 0xcd, 0xd5, 0x84, 0xd6, 0xd5, 0x6f, 0xa5, 0x30, 0x3f, 0xcc, 0x9e,
+ 0xfe, 0xd5, 0xd6, 0xb8, 0x61, 0xf6, 0xb0, 0x10, 0x9d, 0x4d, 0x5c, 0x90, 0xc8, 0x05, 0x4d, 0xba, 0x99, 0x8e, 0xa7, 0xc8,
+ 0x53, 0xe7, 0x5d, 0xd7, 0x37, 0xf3, 0x0b, 0xc9, 0x0f, 0x97, 0x2d, 0x3e, 0x22, 0xed, 0xdc, 0x28, 0x22, 0x32, 0x04, 0xc0,
+ 0x6a, 0x38, 0xd8, 0xc8, 0x85, 0xef, 0x57, 0x9c, 0xa1, 0xe0, 0x0b, 0x7e, 0x6a, 0xb4, 0x5a, 0x76, 0x7c, 0xaf, 0x6f, 0x5d,
+ 0xcc, 0x56, 0xef, 0x60, 0x3c, 0xce, 0x0f, 0x0a, 0x5e, 0xfa, 0xbb, 0xb6, 0xd8, 0xba, 0xda, 0x9d, 0xf5, 0x86, 0x55, 0xc2,
+ 0x84, 0x9b, 0x3d, 0xc2, 0x54, 0x5b, 0xa9, 0x23, 0x57, 0xe1, 0x0a, 0x84, 0x7e, 0x3c, 0x52, 0x9c, 0x3d, 0x02, 0x9b, 0xb5,
+ 0x9c, 0x50, 0xfb, 0xfc, 0x43, 0xf9, 0x07, 0x34, 0xd9, 0xad, 0x3f, 0x59, 0x44, 0x6b, 0x47, 0xa0, 0xb9, 0x29, 0x63, 0xfb,
+ 0xd9, 0xd7, 0xfc, 0x62, 0xda, 0x23, 0x7e, 0x2b, 0xb6, 0x09, 0xfc, 0x52, 0x70, 0x77, 0xb9, 0x4d, 0x92, 0xdd, 0xf2, 0x82,
+ 0x8c, 0xa3, 0xf5, 0x79, 0xf9, 0x21, 0xe8, 0x36, 0xea, 0xf5, 0xa7, 0x8c, 0x3c, 0x46, 0xab, 0x29, 0xdc, 0x91, 0xa8, 0x8e,
+ 0xc5, 0xe7, 0xe5, 0x95, 0xd5, 0xca, 0xed, 0xad, 0x54, 0x24, 0xf2, 0xee, 0x40, 0x9c, 0x06, 0x08, 0x03, 0x36, 0x0a, 0x73,
+ 0xa4, 0xcb, 0xbb, 0x28, 0x83, 0x28, 0x66, 0xc3, 0x79, 0xba, 0x7a, 0x76, 0x90, 0x10, 0x88, 0x04, 0x3f, 0x0f, 0x67, 0xd2,
+ 0x53, 0xab, 0x63, 0xc7, 0x83, 0xc9, 0x2b, 0xdd, 0x9c, 0x61, 0x99, 0xe4, 0x12, 0x18, 0xc6, 0x9a, 0x9d, 0x3c, 0xea, 0x13,
+ 0x87, 0x32, 0x57, 0x8d, 0x01, 0x11, 0x39, 0x56, 0x94, 0xb2, 0x4d, 0x73, 0xc0, 0xdc, 0x2d, 0x4c, 0xb3, 0xd1, 0x90, 0x36,
+ 0xd8, 0xae, 0xd3, 0x06, 0xd7, 0x70, 0xa5, 0xd6, 0x0e, 0x64, 0xf8, 0x80, 0xb6, 0x36, 0x0c, 0x31, 0xd3, 0xcc, 0x46, 0xba,
+ 0xb4, 0x14, 0xb4, 0xcb, 0x43, 0x68, 0x0f, 0x8d, 0xf7, 0x2c, 0x61, 0xf4, 0xfb, 0xce, 0xf1, 0xaf, 0xe9, 0x2e, 0x52, 0x02,
+ 0x29, 0x5e, 0xd7, 0xc6, 0xed, 0xf6, 0x22, 0xb9, 0x7b, 0xe8, 0x1a, 0xe6, 0x59, 0xdb, 0x43, 0xdd, 0x58, 0xe2, 0x50, 0xab,
+ 0x57, 0x01, 0xf0, 0x61, 0xb0, 0x83, 0xa9, 0x40, 0x0c, 0x24, 0x08, 0x6e, 0x95, 0x45, 0xba, 0xb3, 0x02, 0xa9, 0x41, 0xde,
+ 0xaf, 0xc2, 0x4c, 0xc2, 0x71, 0x1e, 0x86, 0xe4, 0xe9, 0x81, 0x9e, 0xdf, 0xea, 0x11, 0x66, 0x91, 0x02, 0x8c, 0xf5, 0xa3,
+ 0x05, 0xe3, 0xe9, 0x6e, 0x7f, 0x34, 0xb5, 0x0a, 0x3f, 0xc3, 0x70, 0x18, 0x33, 0x33, 0x7e, 0x85, 0x81, 0x04, 0x1f, 0xaa,
+ 0x14, 0x0c, 0x57, 0xca, 0x41, 0x97, 0x79, 0x62, 0x2e, 0x99, 0xbc, 0x6f, 0xce, 0x21, 0xad, 0xde, 0x7d, 0x74, 0x73, 0x3f,
+ 0x75, 0x00, 0x65, 0xc2, 0x40, 0x5e, 0xda, 0xce, 0x41, 0x4e, 0x8b, 0xd0, 0x32, 0x4f, 0x7f, 0xee, 0xbe, 0xc9, 0x41, 0xb2,
+ 0x42, 0xe9, 0x5a, 0xe5, 0xee, 0x18, 0x0c, 0x70, 0x93, 0xec, 0xb2, 0x46, 0xcd, 0x11, 0x16, 0x31, 0x81, 0x33, 0x5e, 0x82,
+ 0x20, 0x85, 0x1b, 0x02, 0x76, 0xeb, 0x13, 0xb9, 0xd4, 0xbd, 0xf9, 0xe7, 0xb5, 0x5e, 0x5e, 0x05, 0x48, 0x74, 0x27, 0xf2,
+ 0xdc, 0x3e, 0x87, 0x8b, 0x33, 0x3f, 0x50, 0xb6, 0xc6, 0x52, 0xf8, 0x61, 0x69, 0x7e, 0x6b, 0x30, 0xef, 0x2c, 0x6c, 0x5e,
+ 0x69, 0xc8, 0xba, 0x1e, 0x3d, 0x2a, 0x0c, 0x74, 0xbd, 0x93, 0xc9, 0x36, 0xcc, 0x72, 0x15, 0xe6, 0xbb, 0xd0, 0xc0, 0xe3,
+ 0xaf, 0x60, 0xcd, 0x83, 0x54, 0x50, 0x67, 0xbb, 0x70, 0x2a, 0xa1, 0x51, 0x87, 0x9b, 0xc5, 0xe0, 0xbb, 0xa3, 0xb1, 0x6f,
+ 0x3a, 0x1a, 0x62, 0x72, 0x6f, 0x89, 0x8a, 0x1d, 0xc4, 0x09, 0x55, 0xac, 0x67, 0x7b, 0xa3, 0xe6, 0xed, 0x4e, 0xbb, 0xf2,
+ 0x5f, 0x42, 0x95, 0x7b, 0x95, 0x7a, 0xbe, 0x3e, 0xf5, 0x2f, 0xee, 0x5f, 0x30, 0x57, 0x51, 0x94, 0x7d, 0x45, 0xd5, 0xd7,
+ 0x6e, 0xcc, 0xf6, 0x4d, 0xac, 0x7b, 0x51, 0x70, 0x32, 0x07, 0x1c, 0xaf, 0x97, 0xdd, 0x92, 0x0d, 0x9d, 0xba, 0x53, 0xf5,
+ 0x49, 0xc7, 0xa5, 0x6a, 0x7a, 0x3b, 0xb0, 0x3f, 0x0c, 0x01, 0xa5, 0x00, 0x4a, 0x33, 0x90, 0xf7, 0xee, 0x0a, 0x12, 0x5d,
+ 0xc0, 0x5d, 0xb1, 0x85, 0x63, 0xed, 0xcf, 0xb8, 0x84, 0xde, 0x51, 0x8f, 0xd9, 0xf4, 0x15, 0x76, 0x43, 0xc4, 0xfe, 0x89,
+ 0x16, 0xfe, 0x13, 0x92, 0xbd, 0x25, 0x66, 0xb9, 0x56, 0x60, 0x1f, 0x85, 0x3d, 0xc6, 0x9a, 0x02, 0xc4, 0x2a, 0xbf, 0x8b,
+ 0x1b, 0xf1, 0x41, 0xbb, 0x37, 0x77, 0xe1, 0x18, 0xa7, 0x5f, 0x2a, 0x30, 0x37, 0xf6, 0xf4, 0x2a, 0x4b, 0x77, 0xf8, 0x15,
+ 0xc5, 0xb9, 0xb5, 0xdd, 0x93, 0x4f, 0x59, 0x97, 0x6b, 0xf2, 0xe8, 0x6e, 0xf5, 0x7e, 0x21, 0x20, 0x64, 0xac, 0xe8, 0x8d,
+ 0x60, 0xcb, 0xd2, 0xdc, 0xa7, 0xc8, 0x16, 0xb2, 0x7c, 0xf3, 0xbe, 0x88, 0x5b, 0x75, 0xcb, 0xf7, 0x38, 0x79, 0xa5, 0x32,
+ 0x5f, 0xa7, 0xf2, 0xfd, 0x6a, 0x21, 0x71, 0x16, 0x1b, 0xe9, 0xde, 0xd9, 0x88, 0xf2, 0x89, 0xef, 0x4f, 0x9a, 0xc4, 0x9b,
+ 0x04, 0xa0, 0x16, 0xab, 0x39, 0x62, 0x3f, 0x1f, 0x06, 0x2a, 0x88, 0x04, 0x68, 0x63, 0xb1, 0x21, 0x87, 0x25, 0xfb, 0xc3,
+ 0xb5, 0xe0, 0xc8, 0x48, 0x42, 0x4e, 0x3a, 0xc9, 0x90, 0x4c, 0xc1, 0xa5, 0x69, 0x62, 0xd6, 0x25, 0xdc, 0xc9, 0x51, 0xeb,
+ 0x6f, 0x00, 0x70, 0x91, 0x86, 0x57, 0x36, 0x23, 0x1f, 0x29, 0x8b, 0x52, 0xb2, 0x31, 0xd5, 0x8d, 0xc5, 0xa3, 0x5f, 0xd3,
+ 0x7a, 0xe4, 0x2e, 0x3a
+};
+size_t content_size = sizeof(content);
+
+/* Random data for hash agility attribute */
+unsigned char attribute[32] = {
+ 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab, 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3,
+ 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,
+ 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, 0x6d,
+ 0x30, 0x82, 0x03, 0x69, 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, 0x9a,
+ 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, 0x35, 0x31, 0x31, 0x30,
+ 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd3, 0x8f, 0xfd, 0xab,
+ 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0,
+ 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00,
+ 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d,
+ 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb,
+ 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d,
+ 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b,
+ 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab,
+ 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a,
+ 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88,
+ 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57,
+ 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac,
+ 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5,
+ 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55,
+ 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d,
+ 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1,
+ 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35,
+ 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab,
+ 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6,
+ 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83,
+ 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36,
+ 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78,
+ 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad,
+ 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88,
+ 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93,
+ 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d,
+ 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59,
+ 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0,
+ 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d,
+ 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c,
+ 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4,
+ 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05,
+ 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c,
+ 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69,
+ 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+};
+size_t valid_message_size = sizeof(valid_message);
+
+/*
+ * Invalid CMS message on content with hash agility attribute.
+ * Only the hash agility attribute value has been changed from the valid message.
+ */
+uint8_t invalid_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, 0x6d,
+ 0x30, 0x82, 0x03, 0x69, 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, 0x9a,
+ 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, 0x35, 0x31, 0x31, 0x30,
+ 0x34, 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31, 0x22, 0x04, 0x20, 0x2e, 0xd0, 0xd0, 0x8f, 0xfd, 0xab,
+ 0xc6, 0x13, 0xc8, 0x7c, 0x7b, 0x3c, 0x05, 0x16, 0xfb, 0x44, 0x66, 0x40, 0xaf, 0xe3, 0x87, 0xa0,
+ 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x89, 0xd3, 0x00,
+ 0x9b, 0xd0, 0x99, 0x21, 0x21, 0x47, 0xff, 0xa3, 0x4c, 0xef, 0xa7, 0x6e, 0x03, 0x1e, 0xbf, 0x6d,
+ 0x10, 0x3e, 0xf7, 0x36, 0x7e, 0x98, 0xb4, 0xb6, 0x74, 0xa0, 0xa6, 0x2c, 0x83, 0x33, 0xec, 0xeb,
+ 0xb5, 0x69, 0x3b, 0x10, 0x80, 0x60, 0x2b, 0xf4, 0x71, 0x84, 0x2a, 0x22, 0xfa, 0xbe, 0x51, 0x3d,
+ 0x69, 0xdc, 0x2b, 0x94, 0xf6, 0x8a, 0x82, 0xee, 0x88, 0xa3, 0xa4, 0x8a, 0x4d, 0x13, 0xee, 0x4b,
+ 0xf2, 0xd0, 0xef, 0x3a, 0x2d, 0xe0, 0x3e, 0x52, 0xe9, 0x75, 0xf3, 0xf1, 0x8a, 0xc6, 0x68, 0xab,
+ 0x5f, 0x97, 0x7c, 0xef, 0x2e, 0x06, 0xe4, 0x53, 0x2e, 0xa5, 0x20, 0x8b, 0x8a, 0x1f, 0x0b, 0x8a,
+ 0xb2, 0x0e, 0xe0, 0x77, 0xbf, 0x4d, 0x0f, 0x45, 0x15, 0x7f, 0x03, 0xdc, 0x0a, 0x5c, 0xcc, 0x88,
+ 0x49, 0x0b, 0x19, 0xde, 0xd8, 0xdd, 0x62, 0xc6, 0xad, 0x77, 0xaa, 0x37, 0x19, 0x31, 0x6d, 0x57,
+ 0x7f, 0x29, 0xc1, 0xe2, 0x7a, 0x15, 0xf9, 0xb9, 0xa5, 0xe2, 0xf3, 0xeb, 0x3f, 0x27, 0x5d, 0xac,
+ 0x02, 0xb8, 0xf7, 0x6d, 0xfe, 0x0f, 0x22, 0x89, 0xe3, 0x5d, 0xcc, 0xf3, 0x6a, 0x8f, 0x1a, 0xe5,
+ 0x94, 0xfd, 0xad, 0x9a, 0xc2, 0x5d, 0xb5, 0x1b, 0x48, 0xd8, 0x0b, 0x77, 0x9c, 0x27, 0x24, 0x55,
+ 0xf3, 0x8f, 0x5b, 0x7e, 0x0a, 0x73, 0x35, 0xb4, 0x6c, 0xc7, 0x84, 0xc3, 0x0b, 0x22, 0x57, 0x4d,
+ 0xff, 0x45, 0x4d, 0x78, 0xa7, 0xd0, 0x7d, 0xcf, 0x74, 0x5c, 0xe8, 0xa6, 0x26, 0x76, 0xda, 0xf1,
+ 0x4f, 0x75, 0x89, 0xd1, 0x6c, 0x7e, 0x52, 0x8c, 0x6e, 0xa8, 0x6e, 0x4c, 0x5b, 0x54, 0x94, 0x35,
+ 0x92, 0xec, 0x22, 0x5c, 0xdd, 0x97, 0x41, 0xef, 0x9f, 0x6d, 0xa2, 0x63, 0xaa, 0x22, 0x81, 0xab,
+ 0xfa, 0x0d, 0x2d, 0xed, 0xe6, 0x45, 0xe4, 0x2a, 0x51, 0x1d, 0xa6, 0x8d, 0x24, 0x99, 0xda, 0xb6,
+ 0xe3, 0xeb, 0x56, 0xf8, 0x6d, 0xe7, 0xbf, 0x14, 0xfa, 0x41, 0x82, 0x93, 0x28, 0xb0, 0x3f, 0x83,
+ 0x3a, 0x10, 0x79, 0x18, 0x4f, 0x21, 0xc7, 0xd1, 0x5f, 0x80, 0x77, 0x98, 0x0e, 0x26, 0xdd, 0x36,
+ 0xc7, 0xc6, 0x6b, 0xd2, 0x42, 0xd8, 0xa1, 0xfc, 0x69, 0x90, 0xa6, 0xea, 0xe6, 0xf2, 0x5b, 0x78,
+ 0xb7, 0x27, 0xe2, 0x13, 0xc2, 0xe7, 0xdf, 0x37, 0x30, 0x94, 0xaf, 0xbf, 0x88, 0x63, 0x3d, 0xad,
+ 0xfc, 0xdb, 0xf4, 0x5f, 0x5c, 0x4b, 0x07, 0x36, 0xc2, 0xc2, 0xca, 0xe3, 0x3d, 0xd9, 0x51, 0x88,
+ 0x37, 0xb5, 0xd6, 0x36, 0x63, 0x42, 0x8b, 0xd3, 0x86, 0xc3, 0xc0, 0x1c, 0x08, 0x2c, 0x5c, 0x93,
+ 0x21, 0x3e, 0x7a, 0x54, 0x21, 0xa4, 0xbc, 0x78, 0xdc, 0x41, 0x78, 0x18, 0x83, 0xf6, 0x4d, 0x2d,
+ 0x3a, 0xa1, 0xf3, 0xd2, 0x3e, 0x31, 0x91, 0x6f, 0xf9, 0xd3, 0xd6, 0xe1, 0xef, 0x83, 0xd7, 0x59,
+ 0xc9, 0xa3, 0x36, 0xcc, 0x26, 0xfd, 0x7c, 0x93, 0x0a, 0x4e, 0xae, 0x45, 0x4b, 0xb0, 0x58, 0xd0,
+ 0xb0, 0xca, 0x70, 0x35, 0x2f, 0x63, 0x28, 0x9d, 0x5a, 0xc8, 0x02, 0xf9, 0x8b, 0xaa, 0xcf, 0x6d,
+ 0x8b, 0xbb, 0xb5, 0xf6, 0x44, 0xe4, 0xcb, 0x3d, 0xbe, 0xd2, 0x70, 0x2d, 0xb3, 0xe9, 0x05, 0x6c,
+ 0xfe, 0x41, 0xa3, 0x05, 0xec, 0xe4, 0xf1, 0x9e, 0x37, 0x04, 0xd1, 0x9a, 0x60, 0xf9, 0x95, 0xc4,
+ 0x11, 0xb3, 0xbf, 0x17, 0xa4, 0x72, 0x2a, 0x03, 0x2d, 0x9a, 0x2b, 0xed, 0x97, 0xc9, 0x29, 0x05,
+ 0x23, 0xbb, 0xd2, 0xfe, 0x0b, 0x91, 0x5b, 0x93, 0x3f, 0x93, 0x10, 0x69, 0xcb, 0x92, 0x14, 0x8c,
+ 0xd4, 0xf3, 0x4f, 0x51, 0xc4, 0x78, 0x52, 0xc1, 0xea, 0x20, 0xa9, 0x16, 0x9b, 0x51, 0xb3, 0x69,
+ 0xf7, 0x92, 0xea, 0x6e, 0x94, 0x53, 0xc8, 0xf0, 0xd1, 0x24, 0x38, 0x3a, 0x1d, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+};
+size_t invalid_message_size = sizeof(invalid_message);
+
+/* Valid CMS message with no hash agility attribute */
+unsigned char valid_no_attr[] = {
+ 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, 0x3b,
+ 0x30, 0x82, 0x03, 0x37, 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, 0x69, 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, 0x35, 0x31, 0x31, 0x30, 0x34,
+ 0x30, 0x31, 0x35, 0x36, 0x34, 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, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xbc, 0x5a, 0x74, 0xac, 0x24,
+ 0x13, 0xa5, 0xa3, 0xfb, 0x61, 0xfb, 0x19, 0x7a, 0x3f, 0x7b, 0x46, 0x5a, 0xcd, 0x8a, 0x92, 0x23,
+ 0xeb, 0xd0, 0xdf, 0xf2, 0x05, 0xbe, 0x02, 0xf9, 0xd5, 0x81, 0xca, 0x16, 0xf9, 0xd9, 0x63, 0x9e,
+ 0x19, 0xb8, 0xea, 0x1d, 0x51, 0x2c, 0xfc, 0x65, 0x0c, 0x67, 0x31, 0x5d, 0xa2, 0x87, 0x40, 0xa2,
+ 0x58, 0x57, 0x35, 0xe1, 0xa2, 0xc8, 0x25, 0xe4, 0x79, 0xd1, 0xc2, 0x76, 0x26, 0x20, 0x11, 0x76,
+ 0x38, 0xc8, 0xa1, 0x08, 0x98, 0x7c, 0x28, 0x8a, 0x14, 0x23, 0x89, 0xfa, 0xe6, 0x55, 0xaf, 0x47,
+ 0x1f, 0xe8, 0x5c, 0xc4, 0x0b, 0x88, 0x27, 0x75, 0xf5, 0x2d, 0x2c, 0x63, 0x63, 0x7b, 0xd3, 0x2b,
+ 0xd2, 0xb1, 0x4d, 0xf5, 0xd3, 0xa9, 0xdc, 0xc1, 0x34, 0x9d, 0xb8, 0x44, 0xae, 0xa3, 0x41, 0xd7,
+ 0x1e, 0x02, 0xff, 0x06, 0x3d, 0x8b, 0x3b, 0x01, 0xc6, 0xa9, 0x0f, 0x7a, 0x59, 0x03, 0x05, 0x2a,
+ 0xcf, 0x19, 0xc1, 0xd2, 0xea, 0x30, 0x3f, 0xbd, 0x83, 0x80, 0x26, 0xd7, 0x73, 0x32, 0x00, 0x8d,
+ 0x4f, 0x69, 0xaa, 0xf0, 0x39, 0x3f, 0xae, 0x46, 0xfc, 0x19, 0x7e, 0x62, 0xd2, 0xc8, 0x59, 0xa2,
+ 0xd1, 0x23, 0xa2, 0xab, 0xdd, 0x5b, 0xbc, 0xa9, 0x4d, 0x8c, 0x3a, 0xa4, 0x9d, 0x8e, 0x80, 0x0c,
+ 0x2b, 0x2d, 0x26, 0x27, 0xb7, 0xf2, 0xb9, 0x19, 0xc5, 0x8e, 0x17, 0x44, 0xb2, 0x19, 0x29, 0x3b,
+ 0x25, 0x7e, 0x76, 0xf8, 0x97, 0x85, 0xbc, 0x78, 0xa4, 0x41, 0xcb, 0x10, 0xed, 0xd7, 0x8c, 0x4c,
+ 0x56, 0x44, 0xfc, 0x7c, 0xa8, 0x98, 0xff, 0xa5, 0xef, 0x21, 0xe4, 0xc2, 0x2b, 0xaf, 0xfb, 0xb2,
+ 0xcb, 0x4c, 0x63, 0x19, 0x53, 0xae, 0xc4, 0xbc, 0x44, 0x31, 0xcb, 0x06, 0x2f, 0x01, 0x2b, 0x6b,
+ 0x7e, 0xd8, 0x24, 0x76, 0x16, 0x74, 0xa5, 0xb2, 0x46, 0xff, 0x14, 0xde, 0xc8, 0xe5, 0xfc, 0xeb,
+ 0xfa, 0xb8, 0xc2, 0x39, 0x9d, 0xf6, 0xdd, 0xbb, 0xba, 0x7d, 0x2d, 0x49, 0x4c, 0x7d, 0x87, 0xe2,
+ 0x0a, 0xb7, 0x52, 0xb5, 0x3d, 0x9d, 0x02, 0xf2, 0x04, 0x3d, 0x9b, 0x8b, 0x04, 0xe8, 0x84, 0x50,
+ 0x19, 0xb7, 0xfa, 0x4f, 0x9f, 0xa6, 0x00, 0x06, 0x2a, 0x44, 0xb2, 0x58, 0x91, 0x2f, 0xde, 0xd6,
+ 0x25, 0xcc, 0xd5, 0x68, 0x04, 0x51, 0xb1, 0x0f, 0x08, 0x41, 0xdd, 0xea, 0x16, 0x70, 0xbd, 0x5a,
+ 0xbc, 0x05, 0x60, 0xbc, 0xd4, 0x67, 0x62, 0xe2, 0xc3, 0xc0, 0x79, 0xdf, 0x49, 0xd7, 0x52, 0x62,
+ 0xde, 0xce, 0x68, 0x5c, 0x32, 0x9b, 0xd3, 0xb8, 0xef, 0x62, 0x7b, 0x4b, 0x0e, 0x15, 0xae, 0x92,
+ 0xfb, 0x06, 0x36, 0xb9, 0x05, 0x72, 0x2f, 0x01, 0x55, 0x70, 0x2b, 0x09, 0x54, 0xe1, 0x70, 0x15,
+ 0xab, 0x24, 0xcb, 0x07, 0x4c, 0x7e, 0xde, 0x38, 0xb2, 0x03, 0x56, 0xdb, 0x2f, 0x8c, 0x3b, 0xe5,
+ 0x5e, 0x1a, 0xbb, 0x90, 0x08, 0x55, 0xb2, 0x3d, 0xd9, 0x6f, 0xe8, 0x81, 0x08, 0x04, 0x5e, 0x82,
+ 0x84, 0x7e, 0x9c, 0x3f, 0x5a, 0x66, 0x6f, 0x6c, 0xc6, 0x98, 0x82, 0x27, 0xb6, 0x49, 0x7b, 0x14,
+ 0x07, 0x9d, 0x20, 0x61, 0x9d, 0xd9, 0x3d, 0xd0, 0x71, 0x0c, 0x72, 0x82, 0x50, 0xac, 0x61, 0xcd,
+ 0xc5, 0xc6, 0xc9, 0x90, 0xe2, 0x92, 0x5b, 0x02, 0x73, 0xda, 0x98, 0x2e, 0x21, 0x1e, 0x66, 0x79,
+ 0x83, 0x2e, 0x1d, 0x66, 0x0e, 0x2b, 0x6d, 0x42, 0x7d, 0xf4, 0x0a, 0xd3, 0xa1, 0x9b, 0x7f, 0x61,
+ 0xa7, 0x13, 0x3a, 0xa4, 0x6e, 0x0d, 0x0b, 0xbf, 0x42, 0x32, 0xf7, 0xca, 0x0e, 0x96, 0x0a, 0xcb,
+ 0x9a, 0x0a, 0x6a, 0x24, 0x8c, 0x43, 0x76, 0x0e, 0xa8, 0x71, 0xcd, 0x3f, 0xc4, 0x85, 0x46, 0x50,
+ 0xb9, 0x65, 0x43, 0x49, 0xae, 0x31, 0x25, 0x76, 0x4b, 0xfb, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00
+};
+size_t valid_no_attr_size = sizeof(valid_no_attr);
+
+#include "si-cms-signing-identity-p12.h"
+
+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
+};
+size_t _V2_valid_message_size = sizeof(_V2_valid_message);
--- /dev/null
+#ifndef si_cms_hash_agility_data_h
+#define si_cms_hash_agility_data_h
+
+#include <stdio.h>
+#include <stdint.h>
+
+/* Random data for content */
+extern unsigned char content[1024];
+extern size_t content_size;
+
+/* Random data for hash agility attribute */
+extern unsigned char attribute[32];
+
+/* Random data for hash agility V2 attribute */
+extern unsigned char _attributev2[64];
+
+/* Valid CMS message on content with hash agility attribute */
+extern uint8_t valid_message[];
+extern size_t valid_message_size;
+/*
+ * Invalid CMS message on content with hash agility attribute.
+ * Only the hash agility attribute value has been changed from the valid message.
+ */
+extern uint8_t invalid_message[];
+extern size_t invalid_message_size;
+
+/* Valid CMS message with no hash agility attribute */
+extern unsigned char valid_no_attr[];
+extern size_t valid_no_attr_size;
+
+#include "si-cms-signing-identity-p12.h"
+
+extern unsigned char _V2_valid_message[];
+extern size_t _V2_valid_message_size;
+
+#endif /* si_cms_hash_agility_data_h */
--- /dev/null
+#include "si-cms-signing-identity-p12.h"
+
+/*
+ * password: "password"
+ * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08
+ * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
+ * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
+ */
+unsigned char signing_identity_p12[4477] = {
+ 0x30, 0x82, 0x11, 0x79, 0x02, 0x01, 0x03, 0x30, 0x82, 0x11, 0x3f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x07, 0x01, 0xa0, 0x82, 0x11, 0x30, 0x04, 0x82, 0x11, 0x2c, 0x30, 0x82, 0x11, 0x28, 0x30, 0x82, 0x07, 0x57, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, 0xa0, 0x82, 0x07, 0x48, 0x30, 0x82, 0x07, 0x44, 0x02, 0x01, 0x00,
+ 0x30, 0x82, 0x07, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xed, 0xd8, 0x65, 0x57, 0xbb, 0xca, 0x25,
+ 0x46, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x07, 0x10, 0xc0, 0x1d, 0x0d, 0x5c, 0x7f, 0x3b, 0xbe, 0x20, 0xd4, 0x9a, 0x0d,
+ 0xaf, 0xb6, 0x4b, 0xc7, 0x7f, 0xa8, 0xa8, 0x3f, 0x6c, 0x96, 0x1c, 0xea, 0x90, 0xd2, 0x79, 0x9f, 0x56, 0x3a, 0x5a, 0x29,
+ 0x93, 0xff, 0x72, 0x39, 0x9e, 0x41, 0xd9, 0x5a, 0xfc, 0xb5, 0x54, 0x2d, 0x89, 0x60, 0x18, 0xf2, 0xea, 0x8c, 0xeb, 0x7f,
+ 0xba, 0x87, 0xc6, 0x70, 0x42, 0x25, 0x55, 0x24, 0xc5, 0x4f, 0x26, 0x66, 0x8d, 0x78, 0x44, 0x47, 0x85, 0x36, 0x53, 0x86,
+ 0xc9, 0x18, 0x83, 0x33, 0x4b, 0x4b, 0x08, 0x2d, 0x7b, 0x68, 0x37, 0x29, 0x4c, 0x20, 0x74, 0xd4, 0x4f, 0xbb, 0x6e, 0x97,
+ 0x7a, 0xf4, 0xbf, 0xcb, 0x40, 0x26, 0x2d, 0xac, 0x95, 0x82, 0xe0, 0x88, 0xfe, 0x54, 0x80, 0xe9, 0xf5, 0xda, 0x8e, 0x6e,
+ 0x3a, 0x47, 0x2d, 0xc8, 0xd4, 0xe7, 0x2e, 0xff, 0xec, 0xfa, 0xa5, 0x70, 0xcd, 0x2e, 0x99, 0x26, 0x32, 0xc8, 0x1d, 0x53,
+ 0x60, 0x1e, 0x6f, 0x68, 0xcb, 0x49, 0xd0, 0xa2, 0xf8, 0x47, 0x70, 0x1b, 0x9e, 0x85, 0xbe, 0x4e, 0x56, 0xb5, 0x8b, 0x66,
+ 0x45, 0x57, 0xe3, 0xbd, 0x57, 0xed, 0x94, 0x53, 0xf6, 0x72, 0xd7, 0xb7, 0xc6, 0x9f, 0x05, 0xf5, 0x98, 0xb4, 0x13, 0x35,
+ 0x69, 0x24, 0x94, 0xd9, 0x3d, 0x80, 0xbc, 0xa8, 0xea, 0x78, 0x0c, 0xe0, 0xa2, 0xfe, 0x1b, 0xd2, 0x82, 0x3d, 0x83, 0x34,
+ 0x76, 0xb4, 0x45, 0xf8, 0x14, 0x09, 0x66, 0x02, 0x68, 0xc3, 0x1b, 0xcb, 0x6c, 0x91, 0x6b, 0x3e, 0xdc, 0x35, 0x68, 0xab,
+ 0x49, 0x47, 0x6c, 0x60, 0xea, 0xe3, 0xd5, 0x59, 0x82, 0x9c, 0x18, 0xb0, 0x6d, 0x45, 0xc0, 0x2f, 0x58, 0xf1, 0x44, 0x79,
+ 0xe3, 0xd2, 0xd6, 0x16, 0xbc, 0xde, 0x17, 0xae, 0xf7, 0xea, 0x3c, 0xe4, 0xb4, 0x7b, 0xdf, 0xba, 0x9b, 0xf1, 0xb8, 0xa8,
+ 0xb0, 0x51, 0xeb, 0xe8, 0xc3, 0xe9, 0x9c, 0x1b, 0x06, 0xdd, 0x89, 0x07, 0x98, 0xf8, 0x01, 0x7f, 0xde, 0x7e, 0x05, 0xa6,
+ 0x72, 0x0b, 0x3f, 0xf4, 0x7d, 0xca, 0x74, 0x7b, 0xc9, 0x87, 0x0d, 0x35, 0x8b, 0x05, 0x3a, 0x73, 0x04, 0x08, 0x7a, 0x51,
+ 0x34, 0x29, 0x5b, 0xd8, 0x90, 0x0f, 0xa7, 0xf0, 0x48, 0xfc, 0x9c, 0x74, 0xca, 0xe9, 0x34, 0x75, 0x1c, 0xd1, 0xa6, 0xd1,
+ 0xfb, 0x9f, 0xc7, 0x82, 0x40, 0x75, 0x87, 0xdd, 0xa2, 0x22, 0xeb, 0x91, 0xd7, 0x85, 0x1a, 0x2c, 0xa7, 0x3d, 0xd5, 0xe4,
+ 0xca, 0x85, 0x00, 0x33, 0x11, 0x6d, 0x62, 0xa8, 0xb7, 0xd3, 0x45, 0x46, 0xdc, 0xb4, 0xa3, 0xeb, 0xae, 0x5e, 0x8c, 0xc2,
+ 0x7a, 0x0b, 0x83, 0x98, 0x5a, 0x94, 0x0f, 0x68, 0x61, 0x36, 0x57, 0x6e, 0x94, 0xe0, 0x6d, 0x93, 0x76, 0xa0, 0x5d, 0x3f,
+ 0x25, 0x8b, 0x3b, 0x46, 0x1e, 0x0c, 0x15, 0x6b, 0x9f, 0x1d, 0xc3, 0x5f, 0x61, 0x42, 0xd5, 0xf8, 0x79, 0xcd, 0xd1, 0x0a,
+ 0x96, 0xce, 0x49, 0x8a, 0xff, 0x54, 0x46, 0x77, 0x65, 0x37, 0x70, 0xcd, 0x65, 0x6f, 0x3d, 0x49, 0xc1, 0x29, 0x8d, 0x16,
+ 0xbd, 0x36, 0x47, 0x54, 0xa5, 0x4d, 0x06, 0xfb, 0x33, 0x00, 0x29, 0xd8, 0x31, 0x09, 0x58, 0x12, 0x4c, 0xfe, 0xef, 0x8e,
+ 0xf9, 0x1e, 0x30, 0xf7, 0x05, 0xb2, 0xd8, 0xd4, 0x7d, 0xae, 0xab, 0x57, 0xb7, 0x46, 0x09, 0xff, 0xca, 0xc7, 0x7b, 0xca,
+ 0x73, 0xfa, 0xf9, 0x50, 0xa0, 0xb8, 0x09, 0xc2, 0x80, 0x43, 0x0d, 0x99, 0x7f, 0x4e, 0xdf, 0xd5, 0x6c, 0xc4, 0x42, 0x1a,
+ 0x05, 0xbd, 0x65, 0xf4, 0x57, 0x2a, 0xe5, 0xc4, 0xcb, 0x79, 0x3f, 0x8f, 0x74, 0x93, 0x66, 0x8d, 0x93, 0xda, 0xba, 0x23,
+ 0x77, 0x3f, 0xad, 0xd3, 0x8b, 0xae, 0xf5, 0xf1, 0x5c, 0xc1, 0xd2, 0x00, 0x3a, 0x60, 0x8e, 0xc3, 0x32, 0xd6, 0x8e, 0xce,
+ 0x95, 0x24, 0x03, 0x79, 0x03, 0xf2, 0xb8, 0x2a, 0x94, 0xeb, 0x15, 0x97, 0xdc, 0x18, 0x8d, 0xc7, 0xd9, 0xc2, 0x63, 0x69,
+ 0xfb, 0xf9, 0x8f, 0x05, 0xd3, 0x7c, 0x60, 0x5a, 0x57, 0xe4, 0xa5, 0xc1, 0xdf, 0x1d, 0x11, 0x84, 0x69, 0xba, 0x20, 0xd8,
+ 0x79, 0xc3, 0x34, 0x3a, 0xb1, 0x63, 0x4c, 0xd2, 0x91, 0x2d, 0x87, 0x1e, 0xec, 0x06, 0xea, 0x35, 0x97, 0x0e, 0x59, 0x54,
+ 0x83, 0x50, 0x3e, 0xac, 0xf2, 0xea, 0x6c, 0x0c, 0xa0, 0x57, 0xfb, 0xe8, 0x6b, 0xf9, 0xd1, 0x25, 0xc0, 0xa2, 0xb0, 0xa2,
+ 0xcd, 0xde, 0x2b, 0xa7, 0xb3, 0x40, 0x75, 0x36, 0xf7, 0x20, 0xbe, 0xd7, 0xd1, 0x2e, 0x66, 0xc5, 0x3c, 0xf8, 0x6e, 0xce,
+ 0xcb, 0x76, 0x7f, 0x1d, 0x32, 0x3b, 0x14, 0x27, 0x9c, 0x9e, 0xa3, 0xeb, 0x0c, 0x2f, 0x71, 0xba, 0x0d, 0xca, 0x27, 0x90,
+ 0x42, 0xfd, 0xd4, 0x34, 0xb9, 0x96, 0xae, 0xcb, 0xd8, 0xfe, 0x31, 0x62, 0xe8, 0x4c, 0x07, 0x71, 0xb9, 0x0c, 0x9f, 0xe2,
+ 0x8e, 0x66, 0xc2, 0x39, 0xc5, 0xc3, 0x1c, 0xfd, 0x5e, 0x18, 0x0b, 0xd4, 0x93, 0x3d, 0x98, 0x33, 0xaf, 0x6d, 0xb4, 0x6f,
+ 0xe6, 0x75, 0x67, 0x62, 0xe7, 0x42, 0xee, 0xc6, 0xf2, 0x2e, 0x21, 0xa9, 0x75, 0xde, 0x0a, 0x8c, 0x39, 0xb7, 0x4b, 0x54,
+ 0x01, 0xa7, 0xeb, 0x5a, 0x88, 0x79, 0xa8, 0xb3, 0x3f, 0x31, 0x8c, 0x47, 0x08, 0x94, 0x47, 0x52, 0xcf, 0x3c, 0xac, 0xd9,
+ 0x32, 0x57, 0x4a, 0x18, 0x55, 0x5b, 0x66, 0xdc, 0x89, 0xd2, 0xc6, 0xa1, 0x11, 0x40, 0x19, 0x9c, 0x46, 0x88, 0x21, 0x77,
+ 0xc1, 0x7f, 0x09, 0xc7, 0xfb, 0x52, 0x92, 0xec, 0x1a, 0xe0, 0xdd, 0x76, 0xb9, 0xfd, 0xa7, 0x8f, 0x61, 0xe3, 0xf0, 0x1b,
+ 0x4e, 0xdb, 0xa0, 0xde, 0x90, 0xd6, 0x49, 0xea, 0xe9, 0x86, 0xc6, 0x5d, 0xac, 0xd0, 0xc2, 0xc5, 0x01, 0xcb, 0x3f, 0xcb,
+ 0xf0, 0x62, 0x90, 0xa1, 0x17, 0x4b, 0x72, 0x5c, 0xc8, 0xe9, 0x24, 0x93, 0xda, 0x5c, 0x75, 0x24, 0x96, 0x35, 0x54, 0xf4,
+ 0xfa, 0xc8, 0x27, 0xe1, 0xdd, 0x32, 0xda, 0x2f, 0x2b, 0x7d, 0xf6, 0xd8, 0x0b, 0xf2, 0xca, 0xb5, 0xee, 0x8a, 0xcf, 0xb6,
+ 0x26, 0x71, 0x65, 0x85, 0xfe, 0x8c, 0x37, 0xf1, 0x17, 0x6b, 0x5e, 0x8a, 0xee, 0xb4, 0xc7, 0x0a, 0xff, 0xb2, 0x9a, 0x72,
+ 0xe5, 0x85, 0xf3, 0xc0, 0xf9, 0x84, 0xbc, 0xe0, 0x18, 0x3c, 0x12, 0x0c, 0xa1, 0xe9, 0x10, 0xd4, 0x3b, 0x1a, 0x21, 0x35,
+ 0xc6, 0x06, 0x93, 0xa0, 0xdf, 0x0d, 0x68, 0xa3, 0xf1, 0x06, 0xd9, 0xed, 0xb7, 0xa7, 0xba, 0xb0, 0x22, 0xc2, 0x0b, 0x6b,
+ 0x70, 0x50, 0xf5, 0x49, 0x9a, 0x4f, 0x99, 0xaa, 0x1e, 0x9c, 0xa6, 0xf3, 0x99, 0x3a, 0xfd, 0x3b, 0xd2, 0xeb, 0xce, 0x1e,
+ 0x72, 0x62, 0x99, 0xc0, 0x1e, 0x2b, 0x09, 0x75, 0x4a, 0xfb, 0xc8, 0x26, 0xcf, 0x76, 0xa2, 0x0e, 0xef, 0xf4, 0xa8, 0x70,
+ 0x31, 0xd8, 0xa1, 0x22, 0x62, 0xcc, 0x9f, 0xd5, 0xa3, 0x55, 0xc2, 0x78, 0xd7, 0x27, 0xfc, 0x3c, 0x53, 0xe8, 0xeb, 0x7e,
+ 0x7a, 0x27, 0xcf, 0x6d, 0x52, 0xb5, 0x9a, 0x2b, 0x49, 0x8d, 0x3f, 0x89, 0x80, 0x1a, 0x5c, 0x39, 0xe7, 0x53, 0xb3, 0xf3,
+ 0x33, 0x97, 0xcf, 0x7d, 0xfb, 0x8e, 0x19, 0xf4, 0x72, 0xeb, 0xe7, 0xdf, 0xb1, 0xe3, 0xc1, 0x6c, 0x7f, 0x17, 0x89, 0x34,
+ 0x4f, 0x45, 0x0f, 0xc5, 0xfc, 0x15, 0xb3, 0x3f, 0xc6, 0xdc, 0x25, 0xa6, 0xda, 0x28, 0x85, 0x5d, 0x25, 0x02, 0x78, 0x74,
+ 0xd9, 0x74, 0xb8, 0x65, 0x48, 0x3a, 0x8a, 0x2a, 0xd5, 0xa9, 0xb8, 0x7f, 0xaa, 0x9d, 0xe7, 0xaf, 0xbd, 0xdf, 0xfd, 0x00,
+ 0x67, 0xab, 0x39, 0xe1, 0x2c, 0x3d, 0xd1, 0x5c, 0x9b, 0x61, 0x2b, 0x51, 0xdc, 0x87, 0x19, 0x6c, 0xa0, 0x12, 0xd4, 0x60,
+ 0xed, 0x94, 0xe9, 0xeb, 0x4e, 0x51, 0xd8, 0x50, 0xcb, 0x97, 0x8a, 0x20, 0x21, 0xdf, 0xe9, 0x2c, 0xd2, 0xe2, 0x04, 0x14,
+ 0xaf, 0x7b, 0x7e, 0xd6, 0xeb, 0x1d, 0x25, 0x09, 0x98, 0x8e, 0x9e, 0x56, 0xf8, 0x7d, 0xfc, 0x0f, 0xbf, 0xd2, 0x6b, 0xbc,
+ 0xab, 0xed, 0xca, 0x43, 0x6d, 0x28, 0xbe, 0xd5, 0x20, 0x44, 0xcb, 0x6b, 0xbc, 0x80, 0x5a, 0x82, 0x13, 0x50, 0xbd, 0xda,
+ 0x18, 0x10, 0xac, 0xae, 0x56, 0xb9, 0x46, 0xc5, 0xa2, 0xca, 0xb2, 0x03, 0xf0, 0x57, 0xfe, 0xcd, 0x9a, 0x1b, 0x81, 0x6a,
+ 0x10, 0x51, 0x2e, 0x88, 0x30, 0x57, 0x3c, 0xfe, 0x7c, 0x56, 0x0c, 0x00, 0x89, 0x5c, 0x21, 0x57, 0x19, 0x96, 0x85, 0x98,
+ 0xeb, 0x43, 0x71, 0x0d, 0x8a, 0x35, 0xc3, 0xae, 0x36, 0x59, 0x72, 0x97, 0x12, 0x6d, 0xcd, 0x28, 0x64, 0x17, 0x9e, 0xe7,
+ 0x2c, 0x28, 0xfd, 0x32, 0xa8, 0x10, 0x67, 0x4e, 0xc0, 0x14, 0x21, 0x7c, 0x36, 0x20, 0xe9, 0x46, 0x68, 0x62, 0xc1, 0xff,
+ 0xb0, 0xdf, 0xaa, 0x87, 0xff, 0x94, 0xa4, 0xf3, 0xb3, 0xc8, 0x53, 0x57, 0x18, 0x92, 0x15, 0xc7, 0x78, 0x2d, 0x91, 0xba,
+ 0xb3, 0x1f, 0x06, 0x13, 0x79, 0x21, 0x86, 0x1d, 0xa2, 0x38, 0x2c, 0xda, 0x35, 0x31, 0xbb, 0x04, 0x65, 0xa3, 0x01, 0xa6,
+ 0x63, 0xa4, 0x4a, 0xa2, 0xc1, 0xad, 0x04, 0xc1, 0xfa, 0x78, 0xe1, 0xb6, 0x50, 0x46, 0xab, 0xad, 0x1c, 0xcf, 0xf4, 0xe5,
+ 0xba, 0xa5, 0xe2, 0x91, 0x29, 0x4b, 0xa1, 0xc6, 0x4b, 0x30, 0xa5, 0x31, 0x02, 0xe9, 0xd0, 0x50, 0x72, 0x2c, 0x8e, 0xbd,
+ 0xb2, 0x12, 0xd9, 0x4f, 0x7c, 0x87, 0x4b, 0xa0, 0x45, 0x71, 0x0c, 0x23, 0x37, 0x6b, 0x60, 0xd7, 0x9f, 0x19, 0xe8, 0x0b,
+ 0x85, 0x57, 0x72, 0xb6, 0xbb, 0x20, 0x23, 0xd3, 0x7d, 0x9a, 0x9b, 0x9a, 0x05, 0x46, 0x5c, 0xf5, 0x02, 0xf1, 0x56, 0x00,
+ 0xc2, 0x05, 0x85, 0x48, 0xd3, 0x8d, 0x8e, 0xe1, 0xcb, 0xc5, 0x83, 0x1f, 0x78, 0xd0, 0xc5, 0xb1, 0xdf, 0x80, 0x9d, 0x04,
+ 0xe7, 0xac, 0xd1, 0x68, 0x1a, 0x19, 0x18, 0x16, 0xfa, 0x3a, 0xe2, 0xd2, 0x30, 0x08, 0x17, 0x4d, 0x50, 0x2b, 0xd4, 0xa3,
+ 0xbe, 0x98, 0x5f, 0xe0, 0xcf, 0xed, 0x7d, 0x74, 0x94, 0xd1, 0xb2, 0x77, 0xbc, 0x72, 0xbc, 0xf5, 0xc7, 0x82, 0x26, 0x53,
+ 0x14, 0xcc, 0xf9, 0xf7, 0x71, 0xea, 0x97, 0xaa, 0xbf, 0x21, 0x46, 0x59, 0x2c, 0x9a, 0xc4, 0xeb, 0xa3, 0x4a, 0x97, 0x91,
+ 0x11, 0xf1, 0x01, 0x19, 0x7e, 0xb1, 0xb2, 0x63, 0x0d, 0xf0, 0x5d, 0xaf, 0x53, 0xdf, 0x4d, 0xa1, 0x90, 0xe5, 0x12, 0x82,
+ 0x33, 0x6f, 0x1d, 0x73, 0xdf, 0xdb, 0x1f, 0x18, 0xa0, 0x72, 0xc1, 0xd6, 0xa7, 0x4d, 0xb2, 0x3e, 0x24, 0xb7, 0xa7, 0x76,
+ 0x15, 0x46, 0x22, 0x48, 0x49, 0x55, 0xd1, 0xfb, 0x66, 0x32, 0x02, 0xa9, 0xfc, 0xbe, 0x7e, 0x16, 0xcf, 0xac, 0x32, 0xbc,
+ 0xdb, 0xd5, 0xd8, 0xa3, 0x23, 0x6a, 0x10, 0xa6, 0x37, 0x03, 0xf6, 0x2a, 0xde, 0xba, 0xde, 0x2d, 0x7d, 0xef, 0x1d, 0xb9,
+ 0xf3, 0x93, 0xd4, 0xf2, 0x13, 0xf4, 0x9c, 0x5a, 0x32, 0xba, 0x5f, 0xef, 0x7b, 0xd0, 0x6b, 0xd7, 0x91, 0x6d, 0x7b, 0xe1,
+ 0x4d, 0xf2, 0x8c, 0xe7, 0xf1, 0x66, 0xb9, 0xad, 0xc6, 0x30, 0x08, 0x9e, 0x51, 0xd4, 0x39, 0x87, 0x09, 0xfa, 0x6b, 0x7a,
+ 0xa7, 0x5f, 0x1a, 0x9c, 0x98, 0xc5, 0x76, 0xb0, 0x71, 0x76, 0xf5, 0xfc, 0x56, 0x88, 0x1c, 0xca, 0xee, 0x76, 0xd4, 0x2c,
+ 0xa6, 0x64, 0x80, 0x59, 0x12, 0x8c, 0x08, 0xce, 0x83, 0xb3, 0xd9, 0x68, 0x59, 0xc1, 0x26, 0x86, 0xa7, 0x80, 0x10, 0xbc,
+ 0x41, 0x28, 0x6c, 0x45, 0xd4, 0x6d, 0x15, 0xd0, 0x76, 0x44, 0x0e, 0xcf, 0xc1, 0xde, 0xef, 0x7a, 0x97, 0x36, 0x8f, 0x0d,
+ 0x8a, 0xf5, 0x45, 0xde, 0xae, 0x61, 0xd0, 0x55, 0xe9, 0x8d, 0x62, 0xfd, 0xa3, 0x0d, 0x44, 0x0f, 0x49, 0xb6, 0x5a, 0xa4,
+ 0xaa, 0x03, 0x4e, 0x60, 0x35, 0x53, 0x86, 0x9e, 0xec, 0x75, 0xd9, 0x0a, 0xca, 0x14, 0xe3, 0x1b, 0x06, 0x05, 0xd6, 0x8f,
+ 0x4f, 0x11, 0xb3, 0x13, 0xdd, 0x26, 0x35, 0xbd, 0x56, 0x55, 0xf1, 0x43, 0x89, 0x5e, 0x5b, 0x25, 0x4d, 0xa8, 0x09, 0xdd,
+ 0xf2, 0x6d, 0x9e, 0x8c, 0xcd, 0xa2, 0xde, 0x84, 0x00, 0x6a, 0x0a, 0xc6, 0x92, 0x30, 0x82, 0xcf, 0xa4, 0x31, 0x67, 0xbd,
+ 0xd4, 0x36, 0x6a, 0x8b, 0xc6, 0x33, 0xdf, 0x8b, 0xde, 0x33, 0x01, 0x7b, 0x9d, 0xbf, 0xe9, 0x12, 0x35, 0x8a, 0x97, 0x07,
+ 0x72, 0x0b, 0x6b, 0x60, 0xe6, 0x1e, 0x7d, 0x78, 0x22, 0x9f, 0xbf, 0x66, 0x8e, 0x02, 0xf4, 0xdc, 0xa1, 0xb0, 0x42, 0x73,
+ 0x86, 0xca, 0x34, 0xf0, 0xa7, 0x2e, 0x15, 0x84, 0xa4, 0x60, 0xa8, 0x47, 0x05, 0x80, 0x03, 0x27, 0xa8, 0x04, 0x03, 0xfe,
+ 0x47, 0xd4, 0xeb, 0x33, 0x27, 0xbf, 0x89, 0xff, 0x4c, 0xd9, 0x27, 0x0e, 0xd0, 0xa9, 0x41, 0x8b, 0xd5, 0x7c, 0xc4, 0x14,
+ 0x7a, 0x9c, 0xb3, 0xaa, 0x13, 0x32, 0xa4, 0x67, 0xd5, 0x95, 0xdc, 0x4a, 0x3d, 0xf2, 0x54, 0xd7, 0x02, 0xf8, 0x06, 0x7b,
+ 0x1d, 0x9a, 0xa4, 0x53, 0xa0, 0x9c, 0x76, 0x7d, 0xf4, 0x01, 0xa3, 0x4b, 0xb2, 0x8b, 0x44, 0x85, 0xf6, 0x80, 0x99, 0x2f,
+ 0x77, 0x08, 0x20, 0xea, 0x08, 0xf8, 0x14, 0x76, 0xfe, 0xa0, 0x5a, 0xf9, 0x1f, 0x87, 0x03, 0xff, 0x8d, 0x1f, 0x5d, 0x02,
+ 0x64, 0x8a, 0xf4, 0xa5, 0x8c, 0xb7, 0x0a, 0x34, 0x68, 0xaa, 0xca, 0xc8, 0xe1, 0x78, 0x9b, 0xd3, 0x6c, 0x5c, 0x07, 0x99,
+ 0xc1, 0x10, 0x3f, 0x77, 0x0c, 0x45, 0xa2, 0xda, 0xda, 0xab, 0x7c, 0xf0, 0x90, 0x12, 0xa2, 0x7c, 0x84, 0x30, 0x82, 0x09,
+ 0xc9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0xba, 0x04, 0x82, 0x09, 0xb6,
+ 0x30, 0x82, 0x09, 0xb2, 0x30, 0x82, 0x09, 0xae, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
+ 0x02, 0xa0, 0x82, 0x09, 0x76, 0x30, 0x82, 0x09, 0x72, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0xd3, 0x5d, 0xa8, 0x14, 0xbc, 0x7a, 0xaa, 0x5f, 0x02, 0x02, 0x08, 0x00, 0x04,
+ 0x82, 0x09, 0x50, 0xaf, 0xe9, 0x63, 0xb6, 0x05, 0x8b, 0x48, 0xe1, 0x11, 0xd0, 0x37, 0x1d, 0x48, 0x71, 0x22, 0x70, 0xdc,
+ 0xbd, 0xca, 0x98, 0x5d, 0x72, 0xca, 0x38, 0xdc, 0x2e, 0x4f, 0xd4, 0x71, 0xd3, 0xac, 0xf3, 0x0c, 0xcf, 0x78, 0x4e, 0x5c,
+ 0x63, 0x35, 0xaa, 0xac, 0x5a, 0xf0, 0xef, 0x6c, 0xc0, 0x89, 0x28, 0xc4, 0x64, 0xec, 0x5c, 0x92, 0x72, 0xbc, 0xe5, 0x30,
+ 0xe9, 0x5c, 0x35, 0xff, 0xe0, 0xb1, 0x1f, 0xc6, 0x37, 0x50, 0xb7, 0x3d, 0x94, 0x28, 0xbd, 0x3b, 0xf0, 0xd9, 0x5c, 0xb1,
+ 0x45, 0x93, 0xde, 0x41, 0x5b, 0x12, 0xba, 0xfa, 0x27, 0x49, 0x6b, 0xb7, 0x9a, 0xa6, 0x46, 0x8e, 0xe3, 0x15, 0x1b, 0x7f,
+ 0x2c, 0x91, 0x2e, 0x33, 0xf3, 0xef, 0x7a, 0x9b, 0x9d, 0xa8, 0x82, 0x95, 0xa0, 0x7e, 0x43, 0xd6, 0x9d, 0xe2, 0xfb, 0xb1,
+ 0xb0, 0xcf, 0xbd, 0xb6, 0x9b, 0x55, 0x4c, 0xc8, 0x4a, 0xc7, 0x82, 0xeb, 0x3d, 0x09, 0x8d, 0x85, 0x6f, 0x8c, 0x42, 0x6d,
+ 0x10, 0x7d, 0x77, 0x57, 0x29, 0x00, 0xe2, 0xd8, 0x2f, 0xed, 0x7c, 0x10, 0x5b, 0x03, 0xfa, 0x60, 0x34, 0xc9, 0x63, 0x25,
+ 0x4d, 0x02, 0x77, 0x8f, 0x7f, 0x4b, 0x53, 0xe4, 0x8d, 0x1e, 0x4e, 0x2c, 0x0c, 0x7f, 0x0e, 0x48, 0x4b, 0xcd, 0xc8, 0x6a,
+ 0xfa, 0xd3, 0x9f, 0x6f, 0x20, 0x4e, 0x2c, 0x77, 0x2a, 0x84, 0x5e, 0x6c, 0xc3, 0x57, 0xba, 0x97, 0xa7, 0xa8, 0xcb, 0x6f,
+ 0x22, 0xc1, 0xa7, 0x61, 0xf7, 0x7e, 0x7a, 0xae, 0xda, 0xbd, 0x3a, 0xea, 0xb3, 0x46, 0x54, 0x8d, 0x46, 0x48, 0x1f, 0xf3,
+ 0x5c, 0xaa, 0x2e, 0x44, 0xe1, 0x83, 0x69, 0x45, 0x30, 0x02, 0x49, 0x63, 0xa6, 0xdd, 0xf0, 0x25, 0xce, 0x81, 0xab, 0x66,
+ 0x20, 0x04, 0x12, 0x2f, 0x94, 0x2f, 0x8f, 0xf9, 0x88, 0xea, 0x5b, 0xba, 0x87, 0xd7, 0xbe, 0x63, 0x2e, 0xb4, 0xa4, 0x15,
+ 0xe8, 0x56, 0x9e, 0xb5, 0x7b, 0x27, 0xf8, 0x06, 0xfd, 0xf5, 0x21, 0x93, 0x2b, 0x64, 0xb0, 0xe2, 0x31, 0xb3, 0x19, 0xe0,
+ 0x6b, 0x10, 0x8c, 0xa5, 0xa5, 0x38, 0x27, 0x78, 0xc9, 0x9c, 0x01, 0xa7, 0x42, 0x22, 0x3d, 0xf8, 0x8c, 0x23, 0x46, 0xc5,
+ 0x4e, 0x47, 0xa5, 0x9e, 0xd7, 0xa5, 0x50, 0x24, 0x02, 0x30, 0xe9, 0x15, 0x3e, 0x17, 0xba, 0x2c, 0xf2, 0x5e, 0xc7, 0x01,
+ 0x25, 0x9a, 0x74, 0x73, 0x5c, 0x5e, 0xca, 0x01, 0xe2, 0x58, 0x96, 0x47, 0x3e, 0x4c, 0xb9, 0x0f, 0x95, 0xbf, 0xf3, 0xc4,
+ 0x24, 0x98, 0x6c, 0xc5, 0x40, 0xd2, 0xf3, 0x88, 0x62, 0xb0, 0x25, 0x54, 0xb5, 0xf6, 0x2b, 0xfd, 0xf5, 0x6a, 0x6d, 0x15,
+ 0xb2, 0x18, 0x7d, 0xef, 0x3e, 0x66, 0x7d, 0x38, 0x4c, 0xda, 0xc9, 0x1a, 0xcd, 0x40, 0x2a, 0xc6, 0x7b, 0x2e, 0x8a, 0x15,
+ 0xa7, 0xae, 0x99, 0xf5, 0x93, 0x39, 0x20, 0xd2, 0xd8, 0xfd, 0x1f, 0x87, 0x2e, 0xa0, 0xcd, 0x95, 0xa2, 0xd7, 0xd0, 0x48,
+ 0xf7, 0x6e, 0x81, 0x91, 0x1c, 0x37, 0x8a, 0x28, 0x6f, 0x22, 0x7b, 0x37, 0x69, 0x30, 0x3a, 0x64, 0x6e, 0x4a, 0x5f, 0x0a,
+ 0xa6, 0xd7, 0x53, 0xce, 0x1d, 0x60, 0x88, 0xa5, 0x0b, 0xde, 0xf5, 0x01, 0x3a, 0x20, 0xfa, 0xd6, 0x08, 0xdf, 0x83, 0x39,
+ 0x2e, 0xb8, 0x3a, 0x91, 0xec, 0x39, 0x47, 0xaa, 0x66, 0x8a, 0xb4, 0x35, 0x70, 0xaf, 0x88, 0x24, 0xb2, 0xc3, 0xdc, 0x7c,
+ 0xd0, 0x8f, 0x93, 0x0d, 0xa4, 0x53, 0xf1, 0x55, 0x92, 0xae, 0xd9, 0xeb, 0x31, 0xa0, 0x68, 0x29, 0xf5, 0xdb, 0x2f, 0xd1,
+ 0xa3, 0xfe, 0x34, 0x2f, 0xcd, 0x64, 0x0c, 0x11, 0x13, 0x14, 0x50, 0xeb, 0x27, 0x56, 0xda, 0xc0, 0x30, 0x3a, 0x8c, 0x92,
+ 0xb3, 0xb8, 0xc8, 0xb7, 0x19, 0xea, 0x4c, 0x74, 0xb9, 0x95, 0x46, 0x9f, 0xc0, 0x63, 0xfd, 0x72, 0x35, 0x0b, 0xb9, 0x1d,
+ 0x1e, 0x85, 0xf8, 0xf9, 0x23, 0xf7, 0x42, 0xe2, 0xf4, 0x67, 0xbf, 0x3d, 0x30, 0x4b, 0x6a, 0xf2, 0x44, 0x2f, 0xcb, 0x6f,
+ 0xe9, 0x73, 0x4b, 0x8f, 0x09, 0x29, 0x69, 0xcd, 0x8d, 0xcd, 0xc7, 0xd4, 0xa2, 0x0c, 0x6a, 0xc4, 0x9a, 0x33, 0xe2, 0x64,
+ 0x5f, 0x07, 0xf2, 0xb6, 0xf8, 0x86, 0x7f, 0x05, 0x04, 0xf1, 0x1d, 0x9d, 0xd1, 0xc8, 0x3c, 0x16, 0x6e, 0x18, 0x96, 0x15,
+ 0x33, 0xda, 0x84, 0xb6, 0xfd, 0x13, 0x29, 0x2f, 0x5e, 0xa0, 0x0e, 0xaa, 0xf6, 0x24, 0xb4, 0xa5, 0x48, 0x01, 0x02, 0x07,
+ 0x31, 0x98, 0x0d, 0x9c, 0x65, 0x59, 0x68, 0x61, 0x22, 0xdb, 0x64, 0x16, 0x05, 0xae, 0xd8, 0x64, 0x5f, 0xba, 0x51, 0xab,
+ 0x5e, 0xe0, 0xbe, 0x3d, 0x29, 0x67, 0x20, 0x94, 0x63, 0xfe, 0xc7, 0x90, 0x30, 0xc9, 0x43, 0xf1, 0xce, 0x9c, 0x53, 0x01,
+ 0x2c, 0x64, 0x56, 0x85, 0xb7, 0x3b, 0xa4, 0x05, 0x5d, 0x88, 0xdf, 0x44, 0xda, 0x18, 0xf3, 0x8c, 0xdb, 0xae, 0xd2, 0x9f,
+ 0xee, 0x4e, 0x08, 0x17, 0xf9, 0xd8, 0xe0, 0xc9, 0x7d, 0xa5, 0xad, 0x79, 0x06, 0x1b, 0x8c, 0x92, 0xe7, 0x53, 0xdf, 0xde,
+ 0xa3, 0xa5, 0x84, 0x1d, 0xd8, 0x75, 0x35, 0x78, 0x32, 0x55, 0x6f, 0x4f, 0x29, 0x34, 0x4e, 0x6f, 0x32, 0x16, 0xe4, 0xfd,
+ 0xbc, 0xf5, 0x76, 0x99, 0xf3, 0x48, 0x5b, 0xa0, 0x65, 0xb2, 0xef, 0xeb, 0x58, 0x6c, 0xf4, 0x1e, 0x97, 0x34, 0xee, 0xf9,
+ 0x74, 0xe2, 0x94, 0xc0, 0xf2, 0xf5, 0x0b, 0x97, 0x40, 0xce, 0x25, 0xd6, 0xe5, 0xdf, 0x0b, 0x3b, 0x6b, 0xf3, 0x38, 0x28,
+ 0xc3, 0xa6, 0x30, 0xa5, 0x22, 0x3c, 0xb0, 0xbd, 0x4d, 0xd5, 0x79, 0x25, 0xb9, 0xb2, 0xb4, 0xc4, 0x31, 0x62, 0x0b, 0xe7,
+ 0x73, 0x4e, 0xf9, 0xa7, 0x57, 0xdf, 0x33, 0x0e, 0xf0, 0xb9, 0x3b, 0x6d, 0xff, 0x6b, 0x11, 0xb0, 0x90, 0x10, 0x2a, 0x7b,
+ 0xb5, 0x0b, 0x41, 0x17, 0x0b, 0x12, 0xc7, 0x61, 0xef, 0xb1, 0x9b, 0x57, 0x3a, 0x01, 0x55, 0x91, 0xe3, 0xd5, 0xc8, 0xd5,
+ 0xeb, 0x26, 0x90, 0x2b, 0x67, 0x5b, 0xc2, 0x0b, 0xad, 0x6f, 0x26, 0x3a, 0xf5, 0x45, 0xb2, 0xd7, 0x6a, 0x78, 0xaa, 0x43,
+ 0xd0, 0xdb, 0x53, 0x6f, 0x1a, 0x7a, 0x5c, 0x92, 0xe1, 0xb7, 0xe5, 0xad, 0xda, 0xac, 0x3b, 0x5a, 0x20, 0x06, 0xe1, 0x56,
+ 0xf0, 0x55, 0x66, 0x64, 0x42, 0xd4, 0xe4, 0x77, 0x3b, 0xa5, 0x60, 0x8d, 0x5b, 0x24, 0x7a, 0x2a, 0xb9, 0xe2, 0x2f, 0xc6,
+ 0x02, 0xd1, 0x21, 0xf3, 0x08, 0xbd, 0x7b, 0xf4, 0x44, 0x47, 0x00, 0xd2, 0xca, 0x3c, 0x80, 0x37, 0xb0, 0xf2, 0x3d, 0x07,
+ 0x87, 0xbd, 0xe8, 0x59, 0x01, 0x17, 0x7b, 0xb3, 0x1b, 0xc3, 0xce, 0x45, 0x77, 0x3c, 0x0e, 0xdd, 0xac, 0x38, 0xf1, 0x5e,
+ 0xde, 0x5e, 0xdd, 0xad, 0xf2, 0xc9, 0x0f, 0xed, 0xec, 0xe5, 0x00, 0x8b, 0x61, 0xf4, 0x62, 0xd5, 0x58, 0x37, 0xec, 0xbf,
+ 0x36, 0xcf, 0x7a, 0x6a, 0x55, 0x1f, 0x25, 0x53, 0xba, 0xcd, 0x76, 0xc3, 0x07, 0x5e, 0x12, 0xf0, 0xc3, 0x82, 0x52, 0x5f,
+ 0xc6, 0x24, 0x54, 0x76, 0x49, 0xa3, 0xf1, 0xdd, 0x67, 0x29, 0x81, 0x19, 0x5f, 0x7b, 0xcd, 0xc6, 0x60, 0x3e, 0x80, 0x02,
+ 0xb3, 0xd9, 0xb6, 0x9d, 0x29, 0x59, 0xdc, 0x79, 0x90, 0xab, 0x53, 0xf4, 0xe6, 0x23, 0xb4, 0x77, 0x0f, 0xc8, 0xf2, 0x88,
+ 0xb3, 0x1c, 0x70, 0xb4, 0xeb, 0xa8, 0xdf, 0x25, 0x5b, 0x94, 0xa6, 0xce, 0x80, 0xbd, 0x46, 0xe6, 0x26, 0x8c, 0x4f, 0xee,
+ 0x37, 0x81, 0x84, 0xc6, 0xff, 0x0a, 0x37, 0x2e, 0xa4, 0xcb, 0xdf, 0x62, 0x81, 0x79, 0x3b, 0xa2, 0xdb, 0x07, 0x14, 0x0c,
+ 0xf7, 0x44, 0x1e, 0xda, 0xe0, 0x6c, 0x1a, 0xb6, 0x52, 0x7f, 0xd8, 0xce, 0xe7, 0x29, 0x98, 0xc1, 0x69, 0x40, 0xb9, 0x2a,
+ 0xe7, 0xb4, 0xee, 0x04, 0x67, 0xf7, 0x54, 0xac, 0x94, 0x12, 0x5c, 0x67, 0xb4, 0x51, 0x9c, 0xf6, 0xfa, 0x9b, 0x10, 0xd3,
+ 0x7e, 0xce, 0x78, 0xd5, 0x88, 0x80, 0xd7, 0x88, 0xea, 0x16, 0x51, 0x0c, 0xc9, 0xf2, 0x55, 0xda, 0xbd, 0x22, 0x34, 0x1a,
+ 0x65, 0x8f, 0xd7, 0x52, 0x00, 0x98, 0xc3, 0x76, 0xff, 0x3e, 0xfc, 0x44, 0x4b, 0x7e, 0xc2, 0x40, 0x00, 0x94, 0xf3, 0xc6,
+ 0xd5, 0xa3, 0x0f, 0x95, 0x9a, 0x96, 0xbb, 0x50, 0xcd, 0xd0, 0x6f, 0x75, 0xd7, 0xcc, 0x89, 0xb4, 0xc2, 0x85, 0x7f, 0x5f,
+ 0x06, 0xc1, 0xdf, 0x3c, 0xdd, 0x32, 0xdb, 0x44, 0xae, 0x1e, 0xd8, 0x56, 0xde, 0x93, 0xb0, 0xbd, 0xed, 0x8c, 0xb6, 0xcc,
+ 0x15, 0xe7, 0x81, 0x98, 0x36, 0x36, 0xd6, 0x91, 0x61, 0xd8, 0x65, 0x57, 0x5d, 0xcd, 0xbf, 0xf1, 0x3b, 0x31, 0xb6, 0xdd,
+ 0x6e, 0xc6, 0xd3, 0x1b, 0xc9, 0x47, 0x8c, 0x09, 0x03, 0x81, 0x7d, 0xbd, 0x64, 0xa9, 0x09, 0x66, 0x81, 0x2d, 0x56, 0x43,
+ 0xe8, 0x3c, 0x3e, 0xaa, 0xf8, 0x28, 0x92, 0x13, 0xea, 0x1f, 0xc1, 0x81, 0x4f, 0xb1, 0x1e, 0x88, 0xd2, 0x47, 0xdb, 0xb4,
+ 0x7e, 0xcb, 0xac, 0xc4, 0xbc, 0x07, 0x68, 0x83, 0x7d, 0xd2, 0x90, 0x90, 0x01, 0xa7, 0x0b, 0xac, 0x60, 0x67, 0x0f, 0xf4,
+ 0x1b, 0x2c, 0x1e, 0x93, 0x93, 0x6a, 0x16, 0x63, 0x78, 0x36, 0x7d, 0xc5, 0xa5, 0x04, 0xf4, 0x96, 0x1d, 0xae, 0x1a, 0xdf,
+ 0x1d, 0xba, 0xfc, 0x00, 0x21, 0x07, 0x8c, 0xa7, 0x9d, 0x00, 0x60, 0xb7, 0xa4, 0x05, 0xdd, 0xcd, 0x05, 0xee, 0x70, 0x5e,
+ 0xc5, 0x79, 0x6c, 0xc1, 0x22, 0x57, 0xfb, 0x5a, 0x25, 0x3e, 0xb9, 0x37, 0x76, 0x61, 0xc2, 0x7d, 0x14, 0x3c, 0xd3, 0x3a,
+ 0x13, 0xb9, 0x33, 0x07, 0xf6, 0x53, 0xc9, 0x5b, 0xb9, 0x97, 0x03, 0xd0, 0x76, 0xb8, 0xd1, 0xf1, 0x43, 0x9d, 0x7f, 0x37,
+ 0x46, 0x1a, 0xda, 0xdf, 0xd7, 0x4a, 0xb7, 0x79, 0x84, 0x9e, 0x47, 0x73, 0xac, 0x26, 0xf7, 0xd7, 0x54, 0x16, 0xad, 0x49,
+ 0x5e, 0x5d, 0x77, 0x61, 0x79, 0xdd, 0x52, 0x13, 0x2f, 0x20, 0xce, 0x26, 0x35, 0xa3, 0x60, 0x28, 0x3f, 0xc5, 0x67, 0xce,
+ 0x43, 0xa0, 0x86, 0x28, 0xf7, 0xa6, 0xf9, 0x6a, 0xbf, 0x25, 0x41, 0xb7, 0x7d, 0xbc, 0x04, 0x02, 0xd1, 0xe5, 0xed, 0x74,
+ 0xf5, 0xf5, 0x39, 0xf5, 0x18, 0x42, 0x9f, 0xdc, 0xaf, 0x46, 0xb6, 0x55, 0x48, 0x72, 0xa6, 0x66, 0x94, 0xef, 0x4a, 0x45,
+ 0x92, 0xf8, 0x31, 0x7a, 0x19, 0x69, 0xcb, 0xcf, 0xf3, 0x10, 0x4a, 0x65, 0x53, 0x18, 0xf4, 0x7f, 0x47, 0xe8, 0xe5, 0x07,
+ 0xb1, 0x8b, 0x3c, 0x3b, 0xb1, 0x1f, 0xdb, 0xb8, 0x5d, 0x53, 0xcb, 0xad, 0xf7, 0x38, 0x91, 0x8a, 0x1e, 0xa6, 0x76, 0x05,
+ 0x48, 0x89, 0xcc, 0xff, 0x51, 0x59, 0x53, 0xe9, 0xd7, 0x6e, 0x1a, 0x6e, 0xad, 0xf2, 0xcb, 0xf5, 0xfd, 0x48, 0xbe, 0xa8,
+ 0x70, 0xae, 0x5e, 0xc1, 0x7e, 0x1e, 0x07, 0x8e, 0x64, 0x0d, 0x70, 0xb7, 0x92, 0xda, 0x6f, 0x45, 0xb0, 0xe3, 0x8a, 0x30,
+ 0xbc, 0x45, 0xd1, 0x65, 0xf2, 0xb7, 0xab, 0x4e, 0x16, 0x5c, 0xa2, 0xb2, 0x9a, 0x4d, 0x2f, 0x76, 0x26, 0x62, 0x92, 0x7a,
+ 0x3c, 0x47, 0xf6, 0x87, 0x04, 0x0f, 0x7b, 0xda, 0x4b, 0x02, 0x6b, 0xd6, 0x16, 0x79, 0xbd, 0x16, 0x24, 0x42, 0x7a, 0xf4,
+ 0x44, 0x58, 0xb4, 0x68, 0x71, 0xce, 0xb3, 0x28, 0xba, 0x84, 0x6c, 0x26, 0x82, 0x1e, 0xba, 0x19, 0x83, 0xb7, 0x75, 0x1b,
+ 0xde, 0x09, 0xf6, 0x1b, 0x4f, 0x31, 0x65, 0xae, 0xb6, 0x45, 0xc2, 0xa7, 0x35, 0x2d, 0x9f, 0x14, 0x10, 0xe0, 0x3e, 0x43,
+ 0xa7, 0x82, 0x01, 0x06, 0x95, 0x2c, 0x19, 0x43, 0x8c, 0x94, 0xd4, 0x8c, 0x85, 0x6d, 0x88, 0x33, 0xff, 0x19, 0x51, 0xd3,
+ 0x7c, 0xf2, 0xa7, 0x5b, 0x05, 0xd1, 0x2b, 0x56, 0x18, 0x5e, 0xa6, 0xb9, 0x66, 0x3c, 0xf7, 0x4d, 0xbd, 0xa9, 0x95, 0x75,
+ 0xa9, 0xa1, 0x87, 0x24, 0x87, 0xf0, 0x60, 0xbb, 0x39, 0xec, 0xd1, 0xe5, 0x67, 0x51, 0x76, 0x99, 0xbc, 0x64, 0x7b, 0x5a,
+ 0xd5, 0xa6, 0x54, 0x4f, 0x16, 0x10, 0xb2, 0xe9, 0x43, 0x1c, 0x3a, 0x4c, 0x88, 0x51, 0xf4, 0xc2, 0x95, 0x16, 0x8e, 0xbf,
+ 0x79, 0x19, 0x22, 0x95, 0xd1, 0x76, 0x99, 0xb8, 0x68, 0xf3, 0x6a, 0x1a, 0x4e, 0x43, 0xf8, 0x9c, 0x6b, 0x75, 0x8c, 0xa5,
+ 0xbd, 0x65, 0x3a, 0x83, 0x0b, 0x47, 0xcf, 0x08, 0xf7, 0x22, 0x86, 0xad, 0xd5, 0x89, 0xd0, 0x6f, 0x4e, 0xbe, 0x2a, 0x81,
+ 0x1d, 0x1c, 0xf1, 0xc8, 0xf3, 0x18, 0x44, 0x40, 0xf3, 0x99, 0xfd, 0x18, 0xe3, 0x1a, 0xc9, 0x7f, 0x3b, 0x93, 0x68, 0x84,
+ 0xe2, 0x49, 0xb9, 0xcf, 0x00, 0x5c, 0x76, 0xc4, 0xcc, 0x4b, 0x7e, 0x86, 0x7e, 0x3f, 0x4b, 0x23, 0x61, 0x92, 0x7c, 0xcb,
+ 0x0c, 0x0c, 0x3e, 0x97, 0x34, 0xcc, 0xfd, 0x34, 0xa9, 0xcc, 0xf0, 0x83, 0xb1, 0xbc, 0x50, 0x4c, 0x84, 0x6f, 0xba, 0x68,
+ 0x01, 0x4f, 0x71, 0x57, 0x05, 0x7f, 0x01, 0xe2, 0x18, 0x23, 0xe9, 0x44, 0xa8, 0x4d, 0x93, 0x11, 0xee, 0xc0, 0x79, 0x5a,
+ 0x94, 0x13, 0x81, 0xf4, 0x67, 0xa0, 0x50, 0x79, 0x83, 0xa1, 0x13, 0x5f, 0x0e, 0x82, 0x9a, 0x72, 0x90, 0xba, 0x43, 0x21,
+ 0x28, 0xa9, 0x65, 0x1c, 0x16, 0x97, 0x6f, 0xdb, 0xc3, 0x1e, 0x23, 0xc5, 0x4a, 0xdb, 0x3b, 0x3c, 0x42, 0x4a, 0xc4, 0xb5,
+ 0x7f, 0x6b, 0x5d, 0xfc, 0x09, 0x08, 0x43, 0x2f, 0xf8, 0x11, 0x27, 0x6f, 0x1d, 0xc0, 0x12, 0x59, 0x04, 0xa4, 0x5b, 0xe9,
+ 0x9f, 0x25, 0xd1, 0x58, 0x3a, 0x1f, 0xac, 0x05, 0x15, 0x18, 0xea, 0xbd, 0x4b, 0xd2, 0xba, 0x67, 0xf3, 0x1d, 0x89, 0x09,
+ 0x52, 0xe5, 0x0e, 0x15, 0xd6, 0x5b, 0x87, 0xf5, 0xc3, 0x3c, 0x98, 0xbc, 0x46, 0x4e, 0x19, 0x8d, 0xbb, 0x3e, 0xe0, 0xde,
+ 0x19, 0x59, 0x53, 0x32, 0x62, 0x31, 0x16, 0xd4, 0xea, 0x63, 0xda, 0xf4, 0xcc, 0x94, 0xd0, 0x18, 0x98, 0xbc, 0x00, 0xd3,
+ 0x6c, 0xe2, 0xa5, 0xac, 0x30, 0x08, 0x9d, 0x68, 0x82, 0x8e, 0xbb, 0xdf, 0x9a, 0xa1, 0x13, 0xa5, 0x98, 0x18, 0xa9, 0x11,
+ 0xde, 0x49, 0x18, 0x88, 0xab, 0xff, 0xc6, 0x2c, 0xa8, 0xe1, 0xf7, 0x49, 0xba, 0x17, 0x93, 0x1c, 0x6c, 0x7f, 0x2c, 0xa9,
+ 0x3a, 0xee, 0x77, 0x9d, 0x46, 0x0c, 0xf9, 0x1c, 0x24, 0x33, 0x6f, 0x9b, 0xf8, 0x47, 0x9d, 0xc9, 0x7f, 0x9c, 0x80, 0xa0,
+ 0x2c, 0x96, 0x63, 0xe1, 0x97, 0x75, 0x75, 0x1f, 0xb3, 0xc6, 0x0d, 0xa9, 0x49, 0x82, 0x66, 0x86, 0x13, 0xa4, 0x62, 0x4c,
+ 0x56, 0x89, 0x73, 0x03, 0x1b, 0x61, 0xff, 0xfa, 0x0f, 0xf4, 0x84, 0xe3, 0xad, 0x89, 0xc0, 0x8e, 0x03, 0x91, 0x1c, 0x99,
+ 0x9f, 0x99, 0x92, 0x7e, 0xb5, 0xd8, 0xe3, 0xee, 0x6c, 0x21, 0x27, 0x5d, 0xa2, 0xa5, 0x90, 0xf2, 0x67, 0xed, 0xf3, 0xca,
+ 0x51, 0x56, 0x28, 0x7d, 0xa9, 0xd0, 0x4a, 0x4b, 0x76, 0x2b, 0xa8, 0x95, 0x8a, 0x37, 0xb4, 0x72, 0x96, 0xb2, 0xa0, 0xbe,
+ 0x90, 0x4f, 0x4e, 0x37, 0xbb, 0x14, 0xf8, 0xd2, 0x76, 0x7c, 0x79, 0xf3, 0xd2, 0xbf, 0x35, 0xad, 0x64, 0xbc, 0x98, 0x73,
+ 0xe5, 0xb9, 0xb3, 0xa2, 0x9b, 0x54, 0x17, 0x9b, 0x99, 0xa1, 0xeb, 0xfd, 0xc2, 0x8b, 0xbd, 0xac, 0x6d, 0x14, 0x35, 0xc2,
+ 0x3b, 0xc9, 0x88, 0x57, 0x64, 0xaa, 0x52, 0x3d, 0xf1, 0x80, 0x9c, 0xb2, 0xfc, 0xe9, 0x53, 0x7c, 0x12, 0x81, 0xe6, 0x07,
+ 0xa1, 0x0b, 0x2b, 0xb3, 0x88, 0xa6, 0x07, 0xb8, 0x10, 0x7e, 0xc4, 0x55, 0x14, 0xa2, 0x66, 0xf1, 0xcc, 0xff, 0x49, 0x84,
+ 0xbc, 0x54, 0x15, 0x41, 0x26, 0x15, 0x44, 0xf1, 0xe4, 0x4e, 0x8a, 0xf4, 0x02, 0xb1, 0x87, 0x51, 0xa7, 0xa4, 0xe6, 0x4f,
+ 0xbb, 0xff, 0xfe, 0x94, 0x51, 0x54, 0x20, 0x7e, 0x16, 0x60, 0x23, 0xfe, 0x05, 0x8c, 0x1a, 0xe1, 0x12, 0x7c, 0xd4, 0xc0,
+ 0xae, 0x3a, 0x96, 0x13, 0x5d, 0x83, 0x89, 0x49, 0x99, 0x2c, 0x3e, 0x19, 0x8b, 0xa8, 0xf0, 0x0d, 0x65, 0x5d, 0x35, 0x37,
+ 0xa1, 0x2d, 0xdd, 0xe2, 0x6b, 0x0d, 0xa9, 0x47, 0x9e, 0xf0, 0x22, 0xb5, 0x8e, 0xab, 0xc1, 0x34, 0x93, 0x4c, 0xff, 0x89,
+ 0x9b, 0x24, 0xd4, 0x01, 0x24, 0xbc, 0xf5, 0x42, 0xd8, 0xee, 0xc2, 0xbc, 0x78, 0x03, 0xc1, 0x24, 0xa8, 0x88, 0xba, 0x3f,
+ 0x71, 0x58, 0x3d, 0xdd, 0xef, 0xa8, 0xf8, 0x15, 0x4c, 0xb0, 0x68, 0x7c, 0xbc, 0x41, 0x66, 0x72, 0xc4, 0x4d, 0x9f, 0xd0,
+ 0xdb, 0x9a, 0xd0, 0x65, 0xde, 0xf1, 0x25, 0x02, 0x35, 0xff, 0x49, 0x4a, 0xd8, 0xa4, 0x19, 0x49, 0xb4, 0x51, 0xda, 0x4b,
+ 0x75, 0x81, 0x17, 0xa7, 0x84, 0x80, 0x70, 0x3f, 0xc7, 0x0d, 0xb2, 0x79, 0x24, 0x25, 0x7c, 0xe2, 0x30, 0x67, 0x15, 0x00,
+ 0x80, 0x68, 0x1e, 0xde, 0xf0, 0x3e, 0xda, 0xc6, 0x31, 0x4d, 0xa7, 0xf0, 0x53, 0x0d, 0x88, 0x08, 0xe1, 0xd8, 0xe2, 0x8b,
+ 0x01, 0xdb, 0x9f, 0x5b, 0x7c, 0xd4, 0x68, 0x89, 0xb1, 0xeb, 0xdb, 0x4e, 0x6f, 0xac, 0x21, 0xad, 0xf2, 0xed, 0x6f, 0x61,
+ 0x4d, 0x1f, 0x2f, 0x64, 0x0b, 0xdb, 0x07, 0x54, 0x65, 0xd7, 0xf0, 0xf8, 0x40, 0xdb, 0xd9, 0x5e, 0x2d, 0xaf, 0x4f, 0x14,
+ 0x9f, 0x5b, 0x0b, 0x74, 0x4e, 0xad, 0x07, 0x60, 0xac, 0x24, 0x04, 0x5b, 0xc8, 0xf4, 0xc9, 0x6f, 0x28, 0xb0, 0x2b, 0xb3,
+ 0xd9, 0x43, 0xf1, 0x55, 0xc9, 0x25, 0x01, 0xb7, 0xab, 0x8f, 0xd8, 0x0f, 0x78, 0x6a, 0xbf, 0xa0, 0x4e, 0x80, 0x22, 0xc6,
+ 0x8a, 0x42, 0x37, 0x6d, 0x3a, 0xbd, 0xf3, 0x66, 0xbe, 0x84, 0x87, 0xf6, 0xa1, 0xa0, 0x99, 0x7f, 0x13, 0x66, 0x40, 0x39,
+ 0xce, 0x43, 0x8f, 0xe5, 0x83, 0x48, 0x94, 0xc6, 0x59, 0xc2, 0xce, 0x55, 0x35, 0x44, 0x74, 0xa6, 0x37, 0x0c, 0x3c, 0x69,
+ 0xdc, 0xdb, 0x2b, 0x3a, 0xd8, 0x32, 0x4d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x01, 0xae, 0x1a, 0x61, 0x75, 0xae, 0x23, 0xd9, 0x11, 0x5c, 0x28, 0x93, 0xa9, 0xe2,
+ 0x49, 0x5e, 0x74, 0x28, 0x4c, 0x08, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
+ 0x00, 0x04, 0x14, 0x3d, 0xc6, 0xb0, 0x07, 0xf5, 0xd4, 0xa7, 0x42, 0x90, 0xa1, 0x2f, 0x4d, 0x1e, 0x43, 0x09, 0x7d, 0xd5,
+ 0xfe, 0x15, 0xb1, 0x04, 0x08, 0xdd, 0xee, 0x2c, 0x8a, 0x3d, 0x65, 0x41, 0x94, 0x02, 0x02, 0x08, 0x00
+};
--- /dev/null
+#ifndef si_cms_signing_identity_p12_h
+#define si_cms_signing_identity_p12_h
+
+/*
+ * password: "password"
+ * localKeyID: 01 AE 1A 61 75 AE 23 D9 11 5C 28 93 A9 E2 49 5E 74 28 4C 08
+ * subject=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
+ * issuer=/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering and Architecture/CN=CMS Test Signer
+ */
+extern unsigned char signing_identity_p12[4477];
+
+#endif /* si_cms_signing_identity_p12_h */
return @[@"publickey", @"publickeyHash", @"musr"];
}
-- (NSDictionary<NSString*,NSString*>*) whereClauseToFindSelf {
+- (NSDictionary<NSString*,id>*) whereClauseToFindSelf {
return @{@"publickeyHash": self.publickeyHash};
}
// used by saveToDatabaseWithConnection to write to db
-- (NSDictionary<NSString*,NSString*>*) sqlValues {
+- (NSDictionary<NSString*,id>*) sqlValues {
return @{
@"publickey": self.publickey,
@"publickeyHash": self.publickeyHash,
--- /dev/null
+/*
+ * Copyright (c) 2006-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@
+ */
+
+/*
+ * SecBase.c
+ */
+
+#ifdef STANDALONE
+/* Allows us to build genanchors against the BaseSDK. */
+#undef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
+#undef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
+#endif
+
+#include <Availability.h>
+#include "SecFramework.h"
+#include <dispatch/dispatch.h>
+#include <CoreFoundation/CFBundle.h>
+#include <CoreFoundation/CFURLAccess.h>
+#include <Security/SecRandom.h>
+#include <CommonCrypto/CommonRandomSPI.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecBase.h>
+#include <inttypes.h>
+
+#if !TARGET_OS_OSX
+
+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;
+
+int SecRandomCopyBytes(__unused SecRandomRef rnd, size_t count, void *bytes) {
+ return CCRandomCopyBytes(kCCRandomDefault, bytes, count);
+}
+
+#endif // TARGET_OS_OSX
CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts");
CFTypeRef kSecCMSHashAgility = CFSTR("kSecCMSHashAgility");
CFTypeRef kSecCMSHashAgilityV2 = CFSTR("kSecCMSHashAgilityV2");
+CFTypeRef kSecCMSExpirationDate = CFSTR("kSecCMSExpirationDate");
CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm");
CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC");
}
}
+ CFAbsoluteTime expiration_time;
+ if (errSecSuccess == SecCmsSignerInfoGetAppleExpirationTime(sigd->signerInfos[0], &expiration_time)) {
+ CFDateRef expiration_date = CFDateCreate(NULL, expiration_time);
+ if (expiration_date) {
+ CFDictionarySetValue(attrs, kSecCMSExpirationDate, expiration_date);
+ CFReleaseSafe(expiration_date);
+ }
+ }
+
*signed_attributes = attrs;
CFReleaseSafe(certs);
}
SecCmsSignedDataRef sigd = NULL;
CFMutableArrayRef certs = NULL;
+ if (!message) {
+ return NULL;
+ }
+
SecAsn1Item encoded_message = { CFDataGetLength(message), (uint8_t*)CFDataGetBytePtr(message) };
require_noerr_quiet(SecCmsMessageDecode(&encoded_message, NULL, NULL, NULL, NULL, NULL, NULL, &cmsg), out);
/* expected to be a signed data message at the top level */
}
out:
- if (cmsg)
- SecCmsMessageDestroy(cmsg);
+ if (cmsg) { SecCmsMessageDestroy(cmsg); }
+ if (certs && CFArrayGetCount(certs) < 1) {
+ CFReleaseNull(certs);
+ }
return certs;
}
extern const void * kSecCMSAllCerts;
extern const void * kSecCMSHashAgility;
extern const void * kSecCMSHashAgilityV2;
+extern const void * kSecCMSExpirationDate;
extern const void * kSecCMSEncryptionAlgorithmDESCBC;
extern const void * kSecCMSEncryptionAlgorithmAESCBC;
+++ /dev/null
-/*
- * 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 <AssertMacros.h>
-#include <Security/SecFramework.h>
-#include <Security/SecKeyPriv.h>
-#include <Security/SecItem.h>
-#include <Security/SecItemPriv.h>
-#include <Security/SecItemInternal.h>
-#include <Security/SecBasePriv.h>
-#include <utilities/SecCFError.h>
-#include <utilities/SecCFWrappers.h>
-#include <utilities/array_size.h>
-#include <ctkclient.h>
-#include <libaks_acl_cf_keys.h>
-
-#include "SecECKey.h"
-#include "SecRSAKey.h"
-#include "SecCTKKeyPriv.h"
-
-const CFStringRef kSecUseToken = CFSTR("u_Token");
-
-typedef struct {
- TKTokenRef token;
- CFStringRef token_id;
- CFDataRef object_id;
- SecCFDictionaryCOW auth_params;
- SecCFDictionaryCOW attributes;
- CFMutableDictionaryRef params;
-} SecCTKKeyData;
-
-static void SecCTKKeyDestroy(SecKeyRef key) {
- SecCTKKeyData *kd = key->key;
- CFReleaseNull(kd->token);
- CFReleaseNull(kd->token_id);
- CFReleaseNull(kd->object_id);
- CFReleaseNull(kd->auth_params.mutable_dictionary);
- CFReleaseNull(kd->attributes.mutable_dictionary);
- CFReleaseNull(kd->params);
-}
-
-static CFIndex SecCTKGetAlgorithmID(SecKeyRef key) {
- SecCTKKeyData *kd = key->key;
- if (CFEqualSafe(CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom) ||
- CFEqualSafe(CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandomPKA) ||
- CFEqualSafe(CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeyType), kSecAttrKeyTypeSecureEnclaveAttestation)) {
- return kSecECDSAAlgorithmID;
- }
- return kSecRSAAlgorithmID;
-}
-
-static SecItemAuthResult SecCTKProcessError(CFStringRef operation, TKTokenRef token, CFDataRef object_id, CFArrayRef *ac_pairs, CFErrorRef *error) {
- if (CFEqualSafe(CFErrorGetDomain(*error), CFSTR(kTKErrorDomain)) &&
- CFErrorGetCode(*error) == kTKErrorCodeAuthenticationFailed) {
- CFDataRef access_control = TKTokenCopyObjectAccessControl(token, object_id, error);
- if (access_control != NULL) {
- CFArrayRef ac_pair = CFArrayCreateForCFTypes(NULL, access_control, operation, NULL);
- CFAssignRetained(*ac_pairs, CFArrayCreateForCFTypes(NULL, ac_pair, NULL));
-
- CFReleaseNull(*error);
- CFRelease(ac_pair);
- CFRelease(access_control);
- return kSecItemAuthResultNeedAuth;
- }
- }
- return kSecItemAuthResultError;
-}
-
-static const CFTypeRef *aclOperations[] = {
- [kSecKeyOperationTypeSign] = &kAKSKeyOpSign,
- [kSecKeyOperationTypeDecrypt] = &kAKSKeyOpDecrypt,
- [kSecKeyOperationTypeKeyExchange] = &kAKSKeyOpComputeKey,
-};
-
-static TKTokenRef SecCTKKeyCreateToken(SecKeyRef key, CFDictionaryRef auth_params, CFDictionaryRef *last_params, CFErrorRef *error) {
- TKTokenRef token = NULL;
- SecCTKKeyData *kd = key->key;
- SecCFDictionaryCOW attributes = { auth_params };
- if (kd->params && CFDictionaryGetCount(kd->params) > 0) {
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attributes), CFSTR(kTKTokenCreateAttributeAuxParams), kd->params);
- }
- require_quiet(token = SecTokenCreate(kd->token_id, attributes.dictionary, error), out);
- if (last_params != NULL) {
- CFAssignRetained(*last_params, auth_params ? CFDictionaryCreateCopy(NULL, auth_params) : NULL);
- }
-
-out:
- CFReleaseNull(attributes.mutable_dictionary);
- return token;
-}
-
-static TKTokenRef SecCTKKeyCopyToken(SecKeyRef key, CFErrorRef *error) {
- SecCTKKeyData *kd = key->key;
- TKTokenRef token = CFRetainSafe(kd->token);
- if (token == NULL) {
- token = SecCTKKeyCreateToken(key, kd->auth_params.dictionary, NULL, error);
- }
- return token;
-}
-
-static CFTypeRef SecCTKKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm,
- CFArrayRef algorithms, SecKeyOperationMode mode,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- SecCTKKeyData *kd = key->key;
- __block SecCFDictionaryCOW auth_params = { kd->auth_params.dictionary };
- __block CFDictionaryRef last_params = kd->auth_params.dictionary ? CFDictionaryCreateCopy(NULL, kd->auth_params.dictionary) : NULL;
- __block TKTokenRef token = CFRetainSafe(kd->token);
- __block CFTypeRef result = kCFNull;
-
- CFErrorRef localError = NULL;
- SecItemAuthDo(&auth_params, &localError, ^SecItemAuthResult(CFArrayRef *ac_pairs, CFErrorRef *error) {
- if (!CFEqualSafe(last_params, auth_params.dictionary) || token == NULL) {
- // token was not connected yet or auth_params were modified, so reconnect the token in order to update the attributes.
- CFAssignRetained(token, SecCTKKeyCreateToken(key, auth_params.dictionary, &last_params, error));
- if (token == NULL) {
- return kSecItemAuthResultError;
- }
- }
-
- result = kCFBooleanTrue;
- if (mode == kSecKeyOperationModePerform) {
- // Check, whether we are not trying to perform the operation with large data. If yes, explicitly do the check whether
- // the operation is supported first, in order to avoid jetsam of target extension with operation type which is typically
- // not supported by the extension at all.
- // <rdar://problem/31762984> unable to decrypt large data with kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM
- CFIndex inputSize = 0;
- if (in1 != NULL && CFGetTypeID(in1) == CFDataGetTypeID()) {
- inputSize += CFDataGetLength(in1);
- }
- if (in2 != NULL && CFGetTypeID(in2) == CFDataGetTypeID()) {
- inputSize += CFDataGetLength(in2);
- }
- if (inputSize > 32 * 1024) {
- result = TKTokenCopyOperationResult(token, kd->object_id, operation, algorithms, kSecKeyOperationModeCheckIfSupported,
- NULL, NULL, error);
- }
- }
-
- if (CFEqualSafe(result, kCFBooleanTrue)) {
- result = TKTokenCopyOperationResult(token, kd->object_id, operation, algorithms, mode, in1, in2, error);
- }
- return (result != NULL) ? kSecItemAuthResultOK : SecCTKProcessError(*aclOperations[operation], token,
- kd->object_id, ac_pairs, error);
- }, ^{
- CFAssignRetained(token, SecCTKKeyCreateToken(key, auth_params.dictionary, &last_params, NULL));
- });
-
- CFErrorPropagate(localError, error);
- CFReleaseNull(auth_params.mutable_dictionary);
- CFReleaseNull(token);
- CFReleaseNull(last_params);
- return result;
-}
-
-static size_t SecCTKKeyBlockSize(SecKeyRef key) {
- SecCTKKeyData *kd = key->key;
- CFTypeRef keySize = CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeySizeInBits);
- if (CFGetTypeID(keySize) == CFNumberGetTypeID()) {
- CFIndex bitSize;
- if (CFNumberGetValue(keySize, kCFNumberCFIndexType, &bitSize))
- return (bitSize + 7) / 8;
- }
-
- return 0;
-}
-
-static OSStatus SecCTKKeyCopyPublicOctets(SecKeyRef key, CFDataRef *data) {
- OSStatus status = errSecSuccess;
- CFErrorRef error = NULL;
- CFDataRef publicData = NULL;
- TKTokenRef token = NULL;
-
- SecCTKKeyData *kd = key->key;
- require_action_quiet(token = SecCTKKeyCopyToken(key, &error), out, status = SecErrorGetOSStatus(error));
- require_action_quiet(publicData = TKTokenCopyPublicKeyData(token, kd->object_id, &error), out,
- status = SecErrorGetOSStatus(error));
- *data = publicData;
-
-out:
- CFReleaseSafe(error);
- CFReleaseSafe(token);
- return status;
-}
-
-static CFStringRef SecCTKKeyCopyKeyDescription(SecKeyRef key) {
- SecCTKKeyData *kd = key->key;
- return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SecKeyRef:('%@') %p>"),
- CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrTokenID), key);
-}
-
-// Attributes allowed to be exported from all internal key attributes.
-static const CFStringRef *kSecExportableCTKKeyAttributes[] = {
- &kSecClass,
- &kSecAttrTokenID,
- &kSecAttrKeyClass,
- &kSecAttrAccessControl,
- &kSecAttrIsPrivate,
- &kSecAttrIsModifiable,
- &kSecAttrKeyType,
- &kSecAttrKeySizeInBits,
- &kSecAttrEffectiveKeySize,
- &kSecAttrIsSensitive,
- &kSecAttrWasAlwaysSensitive,
- &kSecAttrIsExtractable,
- &kSecAttrWasNeverExtractable,
- &kSecAttrCanEncrypt,
- &kSecAttrCanDecrypt,
- &kSecAttrCanDerive,
- &kSecAttrCanSign,
- &kSecAttrCanVerify,
- &kSecAttrCanSignRecover,
- &kSecAttrCanVerifyRecover,
- &kSecAttrCanWrap,
- &kSecAttrCanUnwrap,
- NULL
-};
-
-static CFDictionaryRef SecCTKKeyCopyAttributeDictionary(SecKeyRef key) {
- CFMutableDictionaryRef attrs = NULL;
- CFErrorRef error = NULL;
- CFDataRef publicData = NULL, digest = NULL;
- TKTokenRef token = NULL;
- SecCTKKeyData *kd = key->key;
-
- // Encode ApplicationLabel as SHA1 digest of public key bytes.
- require_quiet(token = SecCTKKeyCopyToken(key, &error), out);
- require_quiet(publicData = TKTokenCopyPublicKeyData(token, kd->object_id, &error), out);
-
- // Calculate the digest of the public key.
- require(digest = SecSHA1DigestCreate(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData)), out);
- attrs = CFDictionaryCreateMutableForCFTypes(CFGetAllocator(key));
- CFDictionarySetValue(attrs, kSecAttrApplicationLabel, digest);
-
- for (const CFStringRef **attrKey = &kSecExportableCTKKeyAttributes[0]; *attrKey != NULL; attrKey++) {
- CFTypeRef value = CFDictionaryGetValue(kd->attributes.dictionary, **attrKey);
- if (value != NULL) {
- CFDictionarySetValue(attrs, **attrKey, value);
- }
- }
-
- // Consistently with existing RSA and EC software keys implementation, mark all keys as permanent ones.
- CFDictionarySetValue(attrs, kSecAttrIsPermanent, kCFBooleanTrue);
-
- // Always export token_id and object_id.
- CFDictionarySetValue(attrs, kSecAttrTokenID, kd->token_id);
- CFDictionarySetValue(attrs, kSecAttrTokenOID, kd->object_id);
-
-out:
- CFReleaseSafe(error);
- CFReleaseSafe(publicData);
- CFReleaseSafe(digest);
- CFReleaseSafe(token);
- return attrs;
-}
-
-static SecKeyRef SecCTKKeyCreateDuplicate(SecKeyRef key);
-
-static Boolean SecCTKKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error) {
- SecCTKKeyData *kd = key->key;
- CFTypeRef acm_reference = NULL;
-
- static const CFStringRef *const knownUseFlags[] = {
- &kSecUseOperationPrompt,
- &kSecUseAuthenticationContext,
- &kSecUseAuthenticationUI,
- &kSecUseCallerName,
- &kSecUseCredentialReference,
- };
-
- // Check, whether name is part of known use flags.
- bool isUseFlag = false;
- for (size_t i = 0; i < array_size(knownUseFlags); i++) {
- if (CFEqual(*knownUseFlags[i], name)) {
- isUseFlag = true;
- break;
- }
- }
-
- if (CFEqual(name, kSecUseAuthenticationContext)) {
- // Preprocess LAContext to ACMRef value.
- if (value != NULL) {
- require_quiet(acm_reference = SecItemAttributesCopyPreparedAuthContext(value, error), out);
- value = acm_reference;
- }
- name = kSecUseCredentialReference;
- }
-
- // Release existing token connection to enforce creation of new connection with new params.
- CFReleaseNull(kd->token);
-
- if (isUseFlag) {
- if (value != NULL) {
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->auth_params), name, value);
- } else {
- CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->auth_params), name);
- }
- } else {
- if (kd->params == NULL) {
- kd->params = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- }
- if (value != NULL) {
- CFDictionarySetValue(kd->params, name, value);
- } else {
- CFDictionaryRemoveValue(kd->params, name);
- }
- }
-
-out:
- CFReleaseSafe(acm_reference);
- return TRUE;
-}
-
-static SecKeyDescriptor kSecCTKKeyDescriptor = {
- .version = kSecKeyDescriptorVersion,
- .name = "CTKKey",
- .extraBytes = sizeof(SecCTKKeyData),
-
- .destroy = SecCTKKeyDestroy,
- .blockSize = SecCTKKeyBlockSize,
- .copyDictionary = SecCTKKeyCopyAttributeDictionary,
- .describe = SecCTKKeyCopyKeyDescription,
- .getAlgorithmID = SecCTKGetAlgorithmID,
- .copyPublic = SecCTKKeyCopyPublicOctets,
- .copyOperationResult = SecCTKKeyCopyOperationResult,
- .createDuplicate = SecCTKKeyCreateDuplicate,
- .setParameter = SecCTKKeySetParameter,
-};
-
-static SecKeyRef SecCTKKeyCreateDuplicate(SecKeyRef key) {
- SecKeyRef result = SecKeyCreate(CFGetAllocator(key), &kSecCTKKeyDescriptor, 0, 0, 0);
- SecCTKKeyData *kd = key->key, *rd = result->key;
- rd->token = CFRetainSafe(kd->token);
- rd->object_id = CFRetainSafe(kd->object_id);
- rd->token_id = CFRetainSafe(kd->token_id);
- if (kd->attributes.dictionary != NULL) {
- rd->attributes.dictionary = kd->attributes.dictionary;
- SecCFDictionaryCOWGetMutable(&rd->attributes);
- }
- if (kd->auth_params.dictionary != NULL) {
- rd->auth_params.dictionary = kd->auth_params.dictionary;
- SecCFDictionaryCOWGetMutable(&rd->auth_params);
- }
- return result;
-}
-
-SecKeyRef SecKeyCreateCTKKey(CFAllocatorRef allocator, CFDictionaryRef refAttributes, CFErrorRef *error) {
- SecKeyRef key = SecKeyCreate(allocator, &kSecCTKKeyDescriptor, 0, 0, 0);
- SecCTKKeyData *kd = key->key;
- kd->token = CFRetainSafe(CFDictionaryGetValue(refAttributes, kSecUseToken));
- kd->object_id = CFRetainSafe(CFDictionaryGetValue(refAttributes, kSecAttrTokenOID));
- kd->token_id = CFRetainSafe(CFDictionaryGetValue(refAttributes, kSecAttrTokenID));
- kd->attributes.dictionary = refAttributes;
- CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecUseToken);
- CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrTokenOID);
- SecItemAuthCopyParams(&kd->auth_params, &kd->attributes);
- if (CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrIsPrivate) == NULL) {
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrIsPrivate, kCFBooleanTrue);
- }
-
- // Convert some attributes which are stored as numbers in iOS keychain but a lot of code counts that the values
- // are actually strings as specified by kSecAttrXxx constants.
- static const CFStringRef *numericAttributes[] = {
- &kSecAttrKeyType,
- &kSecAttrKeyClass,
- NULL,
- };
-
- if (kd->token == NULL) {
- kd->token = SecCTKKeyCopyToken(key, error);
- if (kd->token != NULL) {
- CFMutableDictionaryRef attrs = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, kd->attributes.dictionary);
- CFAssignRetained(kd->object_id, TKTokenCreateOrUpdateObject(kd->token, kd->object_id, attrs, error));
- CFDictionaryForEach(attrs, ^(const void *key, const void *value) {
- CFDictionaryAddValue(SecCFDictionaryCOWGetMutable(&kd->attributes), key, value);
- });
- CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrTokenOID);
- CFReleaseSafe(attrs);
- }
-
- if (kd->token == NULL || kd->object_id == NULL) {
- CFReleaseNull(key);
- }
- }
-
- if (key != NULL) {
- for (const CFStringRef **attrName = &numericAttributes[0]; *attrName != NULL; attrName++) {
- CFTypeRef value = CFDictionaryGetValue(kd->attributes.dictionary, **attrName);
- if (value != NULL && CFGetTypeID(value) == CFNumberGetTypeID()) {
- CFIndex number;
- if (CFNumberGetValue(value, kCFNumberCFIndexType, &number)) {
- CFStringRef newValue = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), (long)number);
- if (newValue != NULL) {
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->attributes), **attrName, newValue);
- CFRelease(newValue);
- }
- }
- }
- }
- }
-
- return key;
-}
-
-OSStatus SecCTKKeyGeneratePair(CFDictionaryRef parameters, SecKeyRef *publicKey, SecKeyRef *privateKey) {
- OSStatus status;
- __block SecCFDictionaryCOW attrs = { NULL };
- CFDataRef publicData = NULL;
-
- require_action_quiet(publicKey != NULL, out, status = errSecParam);
- require_action_quiet(privateKey != NULL, out, status = errSecParam);
-
- // Simply adding key on the token without value will cause the token to generate the key.
- // Prepare dictionary specifying item to add.
- attrs.dictionary = CFDictionaryGetValue(parameters, kSecPrivateKeyAttrs);
-
- CFDictionaryForEach(parameters, ^(const void *key, const void *value) {
- if (!CFEqual(key, kSecPrivateKeyAttrs) && !CFEqual(key, kSecPublicKeyAttrs)) {
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), key, value);
- }
- });
- CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&attrs), kSecValueData);
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecClass, kSecClassKey);
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecAttrKeyClass, kSecAttrKeyClassPrivate);
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecReturnRef, kCFBooleanTrue);
-
- // Do not automatically store tke key into the keychain, caller will do it on its own if it is really requested.
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecAttrIsPermanent, kCFBooleanFalse);
-
- // Add key from given attributes to the token (having no data will cause the token to actually generate the key).
- require_noerr_quiet(status = SecItemAdd(attrs.dictionary, (CFTypeRef *)privateKey), out);
-
- // Create non-token public key.
- require_noerr_quiet(status = SecCTKKeyCopyPublicOctets(*privateKey, &publicData), out);
- if (CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeEC) ||
- CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandomPKA) ||
- CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeSecureEnclaveAttestation)) {
- *publicKey = SecKeyCreateECPublicKey(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData),
- kSecKeyEncodingBytes);
- } else if (CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA)) {
- *publicKey = SecKeyCreateRSAPublicKey(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData),
- kSecKeyEncodingBytes);
- }
-
- if (*publicKey != NULL) {
- status = errSecSuccess;
- } else {
- status = errSecInvalidKey;
- CFReleaseNull(*privateKey);
- }
-
-out:
- CFReleaseSafe(attrs.mutable_dictionary);
- CFReleaseSafe(publicData);
- return status;
-}
-
-const CFStringRef kSecKeyParameterSETokenAttestationNonce = CFSTR("com.apple.security.seckey.setoken.attestation-nonce");
-
-SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef *error) {
- CFDictionaryRef attributes = NULL;
- CFDataRef object_id = NULL;
- SecKeyRef key = NULL;
-
- require_action_quiet(keyType == kSecKeyAttestationKeyTypeSIK || keyType == kSecKeyAttestationKeyTypeGID, out,
- SecError(errSecParam, error, CFSTR("unexpected attestation key type %u"), (unsigned)keyType));
-
- // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.sik" dataUsingEncoding:NSUTF8StringEncoding]].data
- static const uint8_t sikObjectIDBytes[] = { 0x04, 21, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 's', 'i', 'k' };
- // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.gid" dataUsingEncoding:NSUTF8StringEncoding]].data
- static const uint8_t gidObjectIDBytes[] = { 0x04, 21, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 'g', 'i', 'd' };
-
- object_id = (keyType == kSecKeyAttestationKeyTypeSIK ?
- CFDataCreate(kCFAllocatorDefault, sikObjectIDBytes, sizeof(sikObjectIDBytes)) :
- CFDataCreate(kCFAllocatorDefault, gidObjectIDBytes, sizeof(gidObjectIDBytes)));
-
- attributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- kSecAttrTokenOID, object_id,
- kSecAttrTokenID, kSecAttrTokenIDAppleKeyStore,
- NULL);
- key = SecKeyCreateCTKKey(kCFAllocatorDefault, attributes, error);
-
-out:
- CFReleaseSafe(attributes);
- CFReleaseSafe(object_id);
- return key;
-}
-
-CFDataRef SecKeyCreateAttestation(SecKeyRef key, SecKeyRef keyToAttest, CFErrorRef *error) {
- __block CFDictionaryRef attributes = NULL, outputAttributes = NULL;
- CFDataRef attestationData = NULL;
- CFErrorRef localError = NULL;
- SecCTKKeyData *attestingKeyData = key->key;
- SecCTKKeyData *keyToAttestData = keyToAttest->key;
- __block TKTokenRef token = NULL;
-
- if (error == NULL) {
- error = &localError;
- }
-
- __block SecCFDictionaryCOW auth_params = { keyToAttestData->auth_params.dictionary };
-
- require_action_quiet(key->key_class == &kSecCTKKeyDescriptor, out,
- SecError(errSecUnsupportedOperation, error, CFSTR("attestation not supported by key %@"), key));
- require_action_quiet(keyToAttest->key_class == &kSecCTKKeyDescriptor, out,
- SecError(errSecUnsupportedOperation, error, CFSTR("attestation not supported for key %@"), keyToAttest));
-
- attributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- CFSTR(kTKTokenControlAttribAttestingKey), attestingKeyData->object_id,
- CFSTR(kTKTokenControlAttribKeyToAttest), keyToAttestData->object_id,
- NULL);
-
- bool ok = SecItemAuthDo(&auth_params, error, ^SecItemAuthResult(CFArrayRef *ac_pairs, CFErrorRef *error) {
- if (auth_params.mutable_dictionary != NULL || token == NULL) {
- CFAssignRetained(token, SecCTKKeyCopyToken(key, error));
- if (token == NULL) {
- return kSecItemAuthResultError;
- }
- }
-
- outputAttributes = TKTokenControl(token, attributes, error);
- return outputAttributes ? kSecItemAuthResultOK : SecCTKProcessError(kAKSKeyOpAttest, keyToAttestData->token, keyToAttestData->object_id, ac_pairs, error);
- }, NULL);
- require_quiet(ok, out);
- require_action_quiet(attestationData = CFRetainSafe(CFDictionaryGetValue(outputAttributes, CFSTR(kTKTokenControlAttribAttestationData))),
- out, SecError(errSecInternal, error, CFSTR("could not get attestation data")));
-
-out:
- CFReleaseSafe(attributes);
- CFReleaseSafe(outputAttributes);
- CFReleaseSafe(localError);
- CFReleaseSafe(auth_params.mutable_dictionary);
- CFReleaseSafe(token);
- return attestationData;
-}
--- /dev/null
+/*
+ * 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@
+ */
+
+#import <Foundation/Foundation.h>
+
+#include <AssertMacros.h>
+#include <Security/SecFramework.h>
+#include <Security/SecKeyPriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecItemInternal.h>
+#include <Security/SecBasePriv.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/array_size.h>
+#include <ctkclient.h>
+#include <libaks_acl_cf_keys.h>
+
+#include "SecECKey.h"
+#include "SecRSAKey.h"
+#include "SecCTKKeyPriv.h"
+
+const CFStringRef kSecUseToken = CFSTR("u_Token");
+
+typedef struct {
+ TKTokenRef token;
+ CFStringRef token_id;
+ CFDataRef object_id;
+ SecCFDictionaryCOW auth_params;
+ SecCFDictionaryCOW attributes;
+ CFMutableDictionaryRef params;
+} SecCTKKeyData;
+
+static void SecCTKKeyDestroy(SecKeyRef key) {
+ SecCTKKeyData *kd = key->key;
+ CFReleaseNull(kd->token);
+ CFReleaseNull(kd->token_id);
+ CFReleaseNull(kd->object_id);
+ CFReleaseNull(kd->auth_params.mutable_dictionary);
+ CFReleaseNull(kd->attributes.mutable_dictionary);
+ CFReleaseNull(kd->params);
+}
+
+static CFIndex SecCTKGetAlgorithmID(SecKeyRef key) {
+ SecCTKKeyData *kd = key->key;
+ if (CFEqualSafe(CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom) ||
+ CFEqualSafe(CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandomPKA) ||
+ CFEqualSafe(CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeyType), kSecAttrKeyTypeSecureEnclaveAttestation)) {
+ return kSecECDSAAlgorithmID;
+ }
+ return kSecRSAAlgorithmID;
+}
+
+static SecItemAuthResult SecCTKProcessError(CFStringRef operation, TKTokenRef token, CFDataRef object_id, CFArrayRef *ac_pairs, CFErrorRef *error) {
+ if (CFEqualSafe(CFErrorGetDomain(*error), CFSTR(kTKErrorDomain)) &&
+ CFErrorGetCode(*error) == kTKErrorCodeAuthenticationFailed) {
+ CFDataRef access_control = TKTokenCopyObjectAccessControl(token, object_id, error);
+ if (access_control != NULL) {
+ CFArrayRef ac_pair = CFArrayCreateForCFTypes(NULL, access_control, operation, NULL);
+ CFAssignRetained(*ac_pairs, CFArrayCreateForCFTypes(NULL, ac_pair, NULL));
+
+ CFReleaseNull(*error);
+ CFRelease(ac_pair);
+ CFRelease(access_control);
+ return kSecItemAuthResultNeedAuth;
+ }
+ }
+ return kSecItemAuthResultError;
+}
+
+static const CFTypeRef *aclOperations[] = {
+ [kSecKeyOperationTypeSign] = &kAKSKeyOpSign,
+ [kSecKeyOperationTypeDecrypt] = &kAKSKeyOpDecrypt,
+ [kSecKeyOperationTypeKeyExchange] = &kAKSKeyOpComputeKey,
+};
+
+static TKTokenRef SecCTKKeyCreateToken(SecKeyRef key, CFDictionaryRef auth_params, CFDictionaryRef *last_params, CFErrorRef *error) {
+ TKTokenRef token = NULL;
+ SecCTKKeyData *kd = key->key;
+ SecCFDictionaryCOW attributes = { auth_params };
+ if (kd->params && CFDictionaryGetCount(kd->params) > 0) {
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attributes), CFSTR(kTKTokenCreateAttributeAuxParams), kd->params);
+ }
+ require_quiet(token = SecTokenCreate(kd->token_id, &attributes, error), out);
+ if (last_params != NULL) {
+ CFAssignRetained(*last_params, auth_params ? CFDictionaryCreateCopy(NULL, auth_params) : NULL);
+ }
+
+out:
+ CFReleaseNull(attributes.mutable_dictionary);
+ return token;
+}
+
+static TKTokenRef SecCTKKeyCopyToken(SecKeyRef key, CFErrorRef *error) {
+ SecCTKKeyData *kd = key->key;
+ TKTokenRef token = CFRetainSafe(kd->token);
+ if (token == NULL) {
+ token = SecCTKKeyCreateToken(key, kd->auth_params.dictionary, NULL, error);
+ }
+ return token;
+}
+
+static CFTypeRef SecCTKKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm,
+ CFArrayRef algorithms, SecKeyOperationMode mode,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ SecCTKKeyData *kd = key->key;
+ __block SecCFDictionaryCOW auth_params = { kd->auth_params.dictionary };
+ __block CFDictionaryRef last_params = kd->auth_params.dictionary ? CFDictionaryCreateCopy(NULL, kd->auth_params.dictionary) : NULL;
+ __block TKTokenRef token = CFRetainSafe(kd->token);
+ __block CFTypeRef result = kCFNull;
+
+ CFErrorRef localError = NULL;
+ SecItemAuthDo(&auth_params, &localError, ^SecItemAuthResult(CFArrayRef *ac_pairs, CFErrorRef *error) {
+ if (!CFEqualSafe(last_params, auth_params.dictionary) || token == NULL) {
+ // token was not connected yet or auth_params were modified, so reconnect the token in order to update the attributes.
+ CFAssignRetained(token, SecCTKKeyCreateToken(key, auth_params.dictionary, &last_params, error));
+ if (token == NULL) {
+ return kSecItemAuthResultError;
+ }
+ }
+
+ result = kCFBooleanTrue;
+ if (mode == kSecKeyOperationModePerform) {
+ // Check, whether we are not trying to perform the operation with large data. If yes, explicitly do the check whether
+ // the operation is supported first, in order to avoid jetsam of target extension with operation type which is typically
+ // not supported by the extension at all.
+ // <rdar://problem/31762984> unable to decrypt large data with kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM
+ CFIndex inputSize = 0;
+ if (in1 != NULL && CFGetTypeID(in1) == CFDataGetTypeID()) {
+ inputSize += CFDataGetLength(in1);
+ }
+ if (in2 != NULL && CFGetTypeID(in2) == CFDataGetTypeID()) {
+ inputSize += CFDataGetLength(in2);
+ }
+ if (inputSize > 32 * 1024) {
+ result = TKTokenCopyOperationResult(token, kd->object_id, operation, algorithms, kSecKeyOperationModeCheckIfSupported,
+ NULL, NULL, error);
+ }
+ }
+
+ if (CFEqualSafe(result, kCFBooleanTrue)) {
+ result = TKTokenCopyOperationResult(token, kd->object_id, operation, algorithms, mode, in1, in2, error);
+ }
+ return (result != NULL) ? kSecItemAuthResultOK : SecCTKProcessError(*aclOperations[operation], token,
+ kd->object_id, ac_pairs, error);
+ }, ^{
+ CFAssignRetained(token, SecCTKKeyCreateToken(key, auth_params.dictionary, &last_params, NULL));
+ });
+
+ CFErrorPropagate(localError, error);
+ CFReleaseNull(auth_params.mutable_dictionary);
+ CFReleaseNull(token);
+ CFReleaseNull(last_params);
+ return result;
+}
+
+static size_t SecCTKKeyBlockSize(SecKeyRef key) {
+ SecCTKKeyData *kd = key->key;
+ CFTypeRef keySize = CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrKeySizeInBits);
+ if (CFGetTypeID(keySize) == CFNumberGetTypeID()) {
+ CFIndex bitSize;
+ if (CFNumberGetValue(keySize, kCFNumberCFIndexType, &bitSize))
+ return (bitSize + 7) / 8;
+ }
+
+ return 0;
+}
+
+static OSStatus SecCTKKeyCopyPublicOctets(SecKeyRef key, CFDataRef *data) {
+ OSStatus status = errSecSuccess;
+ CFErrorRef error = NULL;
+ CFDataRef publicData = NULL;
+ TKTokenRef token = NULL;
+
+ SecCTKKeyData *kd = key->key;
+ require_action_quiet(token = SecCTKKeyCopyToken(key, &error), out, status = SecErrorGetOSStatus(error));
+ require_action_quiet(publicData = TKTokenCopyPublicKeyData(token, kd->object_id, &error), out,
+ status = SecErrorGetOSStatus(error));
+ *data = publicData;
+
+out:
+ CFReleaseSafe(error);
+ CFReleaseSafe(token);
+ return status;
+}
+
+static CFStringRef SecCTKKeyCopyKeyDescription(SecKeyRef key) {
+ SecCTKKeyData *kd = key->key;
+ return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SecKeyRef:('%@') %p>"),
+ CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrTokenID), key);
+}
+
+// Attributes allowed to be exported from all internal key attributes.
+static const CFStringRef *kSecExportableCTKKeyAttributes[] = {
+ &kSecClass,
+ &kSecAttrTokenID,
+ &kSecAttrKeyClass,
+ &kSecAttrAccessControl,
+ &kSecAttrIsPrivate,
+ &kSecAttrIsModifiable,
+ &kSecAttrKeyType,
+ &kSecAttrKeySizeInBits,
+ &kSecAttrEffectiveKeySize,
+ &kSecAttrIsSensitive,
+ &kSecAttrWasAlwaysSensitive,
+ &kSecAttrIsExtractable,
+ &kSecAttrWasNeverExtractable,
+ &kSecAttrCanEncrypt,
+ &kSecAttrCanDecrypt,
+ &kSecAttrCanDerive,
+ &kSecAttrCanSign,
+ &kSecAttrCanVerify,
+ &kSecAttrCanSignRecover,
+ &kSecAttrCanVerifyRecover,
+ &kSecAttrCanWrap,
+ &kSecAttrCanUnwrap,
+ NULL
+};
+
+static CFDictionaryRef SecCTKKeyCopyAttributeDictionary(SecKeyRef key) {
+ CFMutableDictionaryRef attrs = NULL;
+ CFErrorRef error = NULL;
+ CFDataRef publicData = NULL, digest = NULL;
+ TKTokenRef token = NULL;
+ SecCTKKeyData *kd = key->key;
+
+ // Encode ApplicationLabel as SHA1 digest of public key bytes.
+ require_quiet(token = SecCTKKeyCopyToken(key, &error), out);
+ require_quiet(publicData = TKTokenCopyPublicKeyData(token, kd->object_id, &error), out);
+
+ // Calculate the digest of the public key.
+ require_quiet(digest = SecSHA1DigestCreate(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData)), out);
+ attrs = CFDictionaryCreateMutableForCFTypes(CFGetAllocator(key));
+ CFDictionarySetValue(attrs, kSecAttrApplicationLabel, digest);
+
+ for (const CFStringRef **attrKey = &kSecExportableCTKKeyAttributes[0]; *attrKey != NULL; attrKey++) {
+ CFTypeRef value = CFDictionaryGetValue(kd->attributes.dictionary, **attrKey);
+ if (value != NULL) {
+ CFDictionarySetValue(attrs, **attrKey, value);
+ }
+ }
+
+ // Consistently with existing RSA and EC software keys implementation, mark all keys as permanent ones.
+ CFDictionarySetValue(attrs, kSecAttrIsPermanent, kCFBooleanTrue);
+
+ // Always export token_id and object_id.
+ CFDictionarySetValue(attrs, kSecAttrTokenID, kd->token_id);
+ CFDictionarySetValue(attrs, kSecAttrTokenOID, kd->object_id);
+
+out:
+ CFReleaseSafe(error);
+ CFReleaseSafe(publicData);
+ CFReleaseSafe(digest);
+ CFReleaseSafe(token);
+ return attrs;
+}
+
+static SecKeyRef SecCTKKeyCreateDuplicate(SecKeyRef key);
+
+static Boolean SecCTKKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error) {
+ SecCTKKeyData *kd = key->key;
+ CFTypeRef acm_reference = NULL;
+
+ static const CFStringRef *const knownUseFlags[] = {
+ &kSecUseOperationPrompt,
+ &kSecUseAuthenticationContext,
+ &kSecUseAuthenticationUI,
+ &kSecUseCallerName,
+ &kSecUseCredentialReference,
+ };
+
+ // Check, whether name is part of known use flags.
+ bool isUseFlag = false;
+ for (size_t i = 0; i < array_size(knownUseFlags); i++) {
+ if (CFEqual(*knownUseFlags[i], name)) {
+ isUseFlag = true;
+ break;
+ }
+ }
+
+ if (CFEqual(name, kSecUseAuthenticationContext)) {
+ // Preprocess LAContext to ACMRef value.
+ if (value != NULL) {
+ require_quiet(acm_reference = SecItemAttributesCopyPreparedAuthContext(value, error), out);
+ value = acm_reference;
+ }
+ name = kSecUseCredentialReference;
+ }
+
+ // Release existing token connection to enforce creation of new connection with new params.
+ CFReleaseNull(kd->token);
+
+ if (isUseFlag) {
+ if (value != NULL) {
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->auth_params), name, value);
+ } else {
+ CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->auth_params), name);
+ }
+ } else {
+ if (kd->params == NULL) {
+ kd->params = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
+ }
+ if (value != NULL) {
+ CFDictionarySetValue(kd->params, name, value);
+ } else {
+ CFDictionaryRemoveValue(kd->params, name);
+ }
+ }
+
+out:
+ CFReleaseSafe(acm_reference);
+ return TRUE;
+}
+
+static SecKeyDescriptor kSecCTKKeyDescriptor = {
+ .version = kSecKeyDescriptorVersion,
+ .name = "CTKKey",
+ .extraBytes = sizeof(SecCTKKeyData),
+
+ .destroy = SecCTKKeyDestroy,
+ .blockSize = SecCTKKeyBlockSize,
+ .copyDictionary = SecCTKKeyCopyAttributeDictionary,
+ .describe = SecCTKKeyCopyKeyDescription,
+ .getAlgorithmID = SecCTKGetAlgorithmID,
+ .copyPublic = SecCTKKeyCopyPublicOctets,
+ .copyOperationResult = SecCTKKeyCopyOperationResult,
+ .createDuplicate = SecCTKKeyCreateDuplicate,
+ .setParameter = SecCTKKeySetParameter,
+};
+
+static SecKeyRef SecCTKKeyCreateDuplicate(SecKeyRef key) {
+ SecKeyRef result = SecKeyCreate(CFGetAllocator(key), &kSecCTKKeyDescriptor, 0, 0, 0);
+ SecCTKKeyData *kd = key->key, *rd = result->key;
+ rd->token = CFRetainSafe(kd->token);
+ rd->object_id = CFRetainSafe(kd->object_id);
+ rd->token_id = CFRetainSafe(kd->token_id);
+ if (kd->attributes.dictionary != NULL) {
+ rd->attributes.dictionary = kd->attributes.dictionary;
+ SecCFDictionaryCOWGetMutable(&rd->attributes);
+ }
+ if (kd->auth_params.dictionary != NULL) {
+ rd->auth_params.dictionary = kd->auth_params.dictionary;
+ SecCFDictionaryCOWGetMutable(&rd->auth_params);
+ }
+ return result;
+}
+
+SecKeyRef SecKeyCreateCTKKey(CFAllocatorRef allocator, CFDictionaryRef refAttributes, CFErrorRef *error) {
+ SecKeyRef key = SecKeyCreate(allocator, &kSecCTKKeyDescriptor, 0, 0, 0);
+ SecCTKKeyData *kd = key->key;
+ kd->token = CFRetainSafe(CFDictionaryGetValue(refAttributes, kSecUseToken));
+ kd->object_id = CFRetainSafe(CFDictionaryGetValue(refAttributes, kSecAttrTokenOID));
+ kd->token_id = CFRetainSafe(CFDictionaryGetValue(refAttributes, kSecAttrTokenID));
+ kd->attributes.dictionary = refAttributes;
+ CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecUseToken);
+ CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrTokenOID);
+ SecItemAuthCopyParams(&kd->auth_params, &kd->attributes);
+ if (CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrIsPrivate) == NULL) {
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrIsPrivate, kCFBooleanTrue);
+ }
+
+ // Convert some attributes which are stored as numbers in iOS keychain but a lot of code counts that the values
+ // are actually strings as specified by kSecAttrXxx constants.
+ static const CFStringRef *numericAttributes[] = {
+ &kSecAttrKeyType,
+ &kSecAttrKeyClass,
+ NULL,
+ };
+
+ if (kd->token == NULL) {
+ kd->token = SecCTKKeyCopyToken(key, error);
+ if (kd->token != NULL) {
+ CFMutableDictionaryRef attrs = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, kd->attributes.dictionary);
+ CFAssignRetained(kd->object_id, TKTokenCreateOrUpdateObject(kd->token, kd->object_id, attrs, error));
+ CFDictionaryForEach(attrs, ^(const void *key, const void *value) {
+ CFDictionaryAddValue(SecCFDictionaryCOWGetMutable(&kd->attributes), key, value);
+ });
+ CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrTokenOID);
+ CFReleaseSafe(attrs);
+ }
+
+ if (kd->token == NULL || kd->object_id == NULL) {
+ CFReleaseNull(key);
+ }
+ }
+
+ if (key != NULL) {
+ for (const CFStringRef **attrName = &numericAttributes[0]; *attrName != NULL; attrName++) {
+ CFTypeRef value = CFDictionaryGetValue(kd->attributes.dictionary, **attrName);
+ if (value != NULL && CFGetTypeID(value) == CFNumberGetTypeID()) {
+ CFIndex number;
+ if (CFNumberGetValue(value, kCFNumberCFIndexType, &number)) {
+ CFStringRef newValue = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), (long)number);
+ if (newValue != NULL) {
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->attributes), **attrName, newValue);
+ CFRelease(newValue);
+ }
+ }
+ }
+ }
+ }
+
+ return key;
+}
+
+OSStatus SecCTKKeyGeneratePair(CFDictionaryRef parameters, SecKeyRef *publicKey, SecKeyRef *privateKey) {
+ OSStatus status;
+ __block SecCFDictionaryCOW attrs = { NULL };
+ CFDataRef publicData = NULL;
+
+ require_action_quiet(publicKey != NULL, out, status = errSecParam);
+ require_action_quiet(privateKey != NULL, out, status = errSecParam);
+
+ // Simply adding key on the token without value will cause the token to generate the key.
+ // Prepare dictionary specifying item to add.
+ attrs.dictionary = CFDictionaryGetValue(parameters, kSecPrivateKeyAttrs);
+
+ CFDictionaryForEach(parameters, ^(const void *key, const void *value) {
+ if (!CFEqual(key, kSecPrivateKeyAttrs) && !CFEqual(key, kSecPublicKeyAttrs)) {
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), key, value);
+ }
+ });
+ CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&attrs), kSecValueData);
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecClass, kSecClassKey);
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecAttrKeyClass, kSecAttrKeyClassPrivate);
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecReturnRef, kCFBooleanTrue);
+
+ // Do not automatically store tke key into the keychain, caller will do it on its own if it is really requested.
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&attrs), kSecAttrIsPermanent, kCFBooleanFalse);
+
+ // Add key from given attributes to the token (having no data will cause the token to actually generate the key).
+ require_noerr_quiet(status = SecItemAdd(attrs.dictionary, (CFTypeRef *)privateKey), out);
+
+ // Create non-token public key.
+ require_noerr_quiet(status = SecCTKKeyCopyPublicOctets(*privateKey, &publicData), out);
+ if (CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeEC) ||
+ CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandomPKA) ||
+ CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeSecureEnclaveAttestation)) {
+ *publicKey = SecKeyCreateECPublicKey(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData),
+ kSecKeyEncodingBytes);
+ } else if (CFEqualSafe(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA)) {
+ *publicKey = SecKeyCreateRSAPublicKey(NULL, CFDataGetBytePtr(publicData), CFDataGetLength(publicData),
+ kSecKeyEncodingBytes);
+ }
+
+ if (*publicKey != NULL) {
+ status = errSecSuccess;
+ } else {
+ status = errSecInvalidKey;
+ CFReleaseNull(*privateKey);
+ }
+
+out:
+ CFReleaseSafe(attrs.mutable_dictionary);
+ CFReleaseSafe(publicData);
+ return status;
+}
+
+const CFStringRef kSecKeyParameterSETokenAttestationNonce = CFSTR("com.apple.security.seckey.setoken.attestation-nonce");
+
+SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef *error) {
+ CFDictionaryRef attributes = NULL;
+ CFDataRef object_id = NULL;
+ SecKeyRef key = NULL;
+
+ // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.sik" dataUsingEncoding:NSUTF8StringEncoding]].data
+ static const uint8_t sikObjectIDBytes[] = { 0x04, 21, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 's', 'i', 'k' };
+ // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.gid" dataUsingEncoding:NSUTF8StringEncoding]].data
+ static const uint8_t gidObjectIDBytes[] = { 0x04, 21, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 'g', 'i', 'd' };
+ // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.uikc" dataUsingEncoding:NSUTF8StringEncoding]].data
+ static const uint8_t uikCommittedObjectIDBytes[] = { 0x04, 22, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 'u', 'i', 'k', 'c' };
+ // [[TKTLVBERRecord alloc] initWithPropertyList:[@"com.apple.setoken.uikp" dataUsingEncoding:NSUTF8StringEncoding]].data
+ static const uint8_t uikProposedObjectIDBytes[] = { 0x04, 22, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 't', 'o', 'k', 'e', 'n', '.', 'u', 'i', 'k', 'p' };
+
+ switch (keyType) {
+ case kSecKeyAttestationKeyTypeSIK:
+ object_id = CFDataCreate(kCFAllocatorDefault, sikObjectIDBytes, sizeof(sikObjectIDBytes));
+ break;
+ case kSecKeyAttestationKeyTypeGID:
+ object_id = CFDataCreate(kCFAllocatorDefault, gidObjectIDBytes, sizeof(gidObjectIDBytes));
+ break;
+ case kSecKeyAttestationKeyTypeUIKCommitted:
+ object_id = CFDataCreate(kCFAllocatorDefault, uikCommittedObjectIDBytes, sizeof(uikCommittedObjectIDBytes));
+ break;
+ case kSecKeyAttestationKeyTypeUIKProposed:
+ object_id = CFDataCreate(kCFAllocatorDefault, uikProposedObjectIDBytes, sizeof(uikProposedObjectIDBytes));
+ break;
+ default:
+ SecError(errSecParam, error, CFSTR("unexpected attestation key type %d"), (int)keyType);
+ goto out;
+ }
+
+ attributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+ kSecAttrTokenOID, object_id,
+ kSecAttrTokenID, kSecAttrTokenIDAppleKeyStore,
+ NULL);
+ key = SecKeyCreateCTKKey(kCFAllocatorDefault, attributes, error);
+
+out:
+ CFReleaseSafe(attributes);
+ CFReleaseSafe(object_id);
+ return key;
+}
+
+CFDataRef SecKeyCreateAttestation(SecKeyRef key, SecKeyRef keyToAttest, CFErrorRef *error) {
+ __block CFDictionaryRef attributes = NULL, outputAttributes = NULL;
+ CFDataRef attestationData = NULL;
+ CFErrorRef localError = NULL;
+ SecCTKKeyData *attestingKeyData = key->key;
+ SecCTKKeyData *keyToAttestData = keyToAttest->key;
+ __block TKTokenRef token = NULL;
+
+ if (error == NULL) {
+ error = &localError;
+ }
+
+ __block SecCFDictionaryCOW auth_params = { keyToAttestData->auth_params.dictionary };
+
+ require_action_quiet(key->key_class == &kSecCTKKeyDescriptor, out,
+ SecError(errSecUnsupportedOperation, error, CFSTR("attestation not supported by key %@"), key));
+ require_action_quiet(keyToAttest->key_class == &kSecCTKKeyDescriptor, out,
+ SecError(errSecUnsupportedOperation, error, CFSTR("attestation not supported for key %@"), keyToAttest));
+
+ attributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+ CFSTR(kTKTokenControlAttribAttestingKey), attestingKeyData->object_id,
+ CFSTR(kTKTokenControlAttribKeyToAttest), keyToAttestData->object_id,
+ NULL);
+
+ bool ok = SecItemAuthDo(&auth_params, error, ^SecItemAuthResult(CFArrayRef *ac_pairs, CFErrorRef *error) {
+ if (auth_params.mutable_dictionary != NULL || token == NULL) {
+ CFAssignRetained(token, SecCTKKeyCopyToken(key, error));
+ if (token == NULL) {
+ return kSecItemAuthResultError;
+ }
+ }
+
+ outputAttributes = TKTokenControl(token, attributes, error);
+ return outputAttributes ? kSecItemAuthResultOK : SecCTKProcessError(kAKSKeyOpAttest, keyToAttestData->token, keyToAttestData->object_id, ac_pairs, error);
+ }, NULL);
+ require_quiet(ok, out);
+ require_action_quiet(attestationData = CFRetainSafe(CFDictionaryGetValue(outputAttributes, CFSTR(kTKTokenControlAttribAttestationData))),
+ out, SecError(errSecInternal, error, CFSTR("could not get attestation data")));
+
+out:
+ CFReleaseSafe(attributes);
+ CFReleaseSafe(outputAttributes);
+ CFReleaseSafe(localError);
+ CFReleaseSafe(auth_params.mutable_dictionary);
+ CFReleaseSafe(token);
+ return attestationData;
+}
+
+#if TKTOKEN_CLIENT_INTERFACE_VERSION < 4
+#define kTKTokenControlAttribLifetimeControlKey "lifetimeControlKey"
+#define kTKTokenControlAttribLifetimeType "lifetimeType"
+#endif
+
+Boolean SecKeyControlLifetime(SecKeyRef key, SecKeyControlLifetimeType type, CFErrorRef *error) {
+ NSError *localError;
+ __block id token;
+ if (error == NULL) {
+ error = (void *)&localError;
+ }
+
+ SecCTKKeyData *keyData = key->key;
+ NSDictionary *attributes = @{
+ @kTKTokenControlAttribLifetimeControlKey: (__bridge NSData *)keyData->object_id,
+ @kTKTokenControlAttribLifetimeType: @(type),
+ };
+
+ if (key->key_class != &kSecCTKKeyDescriptor) {
+ return SecError(errSecUnsupportedOperation, error, CFSTR("lifetimecontrol not supported for key %@"), key);
+ }
+
+ __block SecCFDictionaryCOW auth_params = { keyData->auth_params.dictionary };
+ return SecItemAuthDo(&auth_params, error, ^SecItemAuthResult(CFArrayRef *ac_pairs, CFErrorRef *error) {
+ if (auth_params.mutable_dictionary != NULL || token == NULL) {
+ token = CFBridgingRelease(SecCTKKeyCopyToken(key, error));
+ if (token == nil) {
+ return kSecItemAuthResultError;
+ }
+ }
+
+ NSDictionary *outputAttributes = CFBridgingRelease(TKTokenControl((__bridge TKTokenRef)token, (__bridge CFDictionaryRef)attributes, error));
+ return outputAttributes ? kSecItemAuthResultOK : kSecItemAuthResultError;
+ }, NULL);
+}
&certificate->_algId, localized);
/* Public Key Size */
-#if TARGET_OS_IPHONE
- SecKeyRef publicKey = SecCertificateCopyPublicKey(certificate);
-#else
- SecKeyRef publicKey = SecCertificateCopyPublicKey_ios(certificate);
-#endif
+ SecKeyRef publicKey = SecCertificateCopyKey(certificate);
if (publicKey) {
size_t sizeInBytes = SecKeyGetBlockSize(publicKey);
CFStringRef sizeInBitsString = CFStringCreateWithFormat(allocator, NULL,
return certificate->_serialNumber;
}
-#if TARGET_OS_OSX
-/* On OS X, the SecCertificateCopySerialNumber API takes two arguments. */
-CFDataRef SecCertificateCopySerialNumber(
- SecCertificateRef certificate,
- CFErrorRef *error) {
- return SecCertificateCopySerialNumberData(certificate, error);
-}
-#else
+#if !TARGET_OS_OSX
/* On iOS, the SecCertificateCopySerialNumber API takes one argument. */
CFDataRef SecCertificateCopySerialNumber(
SecCertificateRef certificate) {
CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault,
0, &kCFTypeArrayCallBacks);
OSStatus status = parseX501NameContent(&certificate->_subject, dnsNames,
- appendDNSNamesFromX501Name, true);
+ appendDNSNamesFromX501Name, true);
if (status || CFArrayGetCount(dnsNames) == 0) {
CFReleaseNull(dnsNames);
}
__nullable SecKeyRef SecCertificateCopyPublicKey(SecCertificateRef certificate)
#endif
{
+ return SecCertificateCopyKey(certificate);
+}
+
+SecKeyRef SecCertificateCopyKey(SecCertificateRef certificate) {
if (certificate->_pubKey == NULL) {
const DERAlgorithmId *algId =
SecCertificateGetPublicKeyAlgorithm(certificate);
SecKeyRef pubKey = NULL;
require_quiet(certificate, out);
-#if TARGET_OS_OSX
- require_quiet(pubKey = SecCertificateCopyPublicKey_ios(certificate), out);
-#else
- require_quiet(pubKey = SecCertificateCopyPublicKey(certificate) ,out);
-#endif
+ require_quiet(pubKey = SecCertificateCopyKey(certificate) ,out);
size = SecKeyGetBlockSize(pubKey);
keyAlgID = SecKeyGetAlgorithmId(pubKey);
certificate->_isSelfSigned = kSecSelfSignedFalse;
SecKeyRef publicKey = NULL;
require(certificate && (CFGetTypeID(certificate) == SecCertificateGetTypeID()), out);
-#if TARGET_OS_OSX
- require(publicKey = SecCertificateCopyPublicKey_ios(certificate), out);
-#else
- require(publicKey = SecCertificateCopyPublicKey(certificate), out);
-#endif
+ require(publicKey = SecCertificateCopyKey(certificate), out);
CFDataRef normalizedIssuer =
SecCertificateGetNormalizedIssuerContent(certificate);
CFDataRef normalizedSubject =
return kSeciAuthInvalid;
}
+static CFStringRef SecCertificateiAPSWAuthCapabilitiesTypeToOID(SeciAPSWAuthCapabilitiesType type) {
+ CFStringRef extensionOID = NULL;
+ /* Get the oid for the type */
+ if (type == kSeciAPSWAuthGeneralCapabilities) {
+ extensionOID = CFSTR("1.2.840.113635.100.6.59.1");
+ } else if (type == kSeciAPSWAuthAirPlayCapabilities) {
+ extensionOID = CFSTR("1.2.840.113635.100.6.59.2");
+ } else if (type == kSeciAPSWAuthHomeKitCapabilities) {
+ extensionOID = CFSTR("1.2.840.113635.100.6.59.3");
+ }
+ return extensionOID;
+}
+
+CFDataRef SecCertificateCopyiAPSWAuthCapabilities(SecCertificateRef certificate, SeciAPSWAuthCapabilitiesType type) {
+ if (!certificate) {
+ return NULL;
+ }
+ CFDataRef extensionData = NULL;
+ DERItem *extensionValue = NULL;
+ CFStringRef extensionOID = SecCertificateiAPSWAuthCapabilitiesTypeToOID(type);
+ require_quiet(extensionOID, out);
+ extensionValue = SecCertificateGetExtensionValue(certificate, extensionOID);
+ require_quiet(extensionValue, out);
+ /* The extension is a octet string containing the DER-encoded variable-length octet string */
+ DERDecodedInfo decodedValue;
+ require_noerr_quiet(DERDecodeItem(extensionValue, &decodedValue), out);
+ if (decodedValue.tag == ASN1_OCTET_STRING) {
+ extensionData = CFDataCreate(NULL, decodedValue.content.data,
+ decodedValue.content.length);
+ }
+out:
+ return extensionData;
+}
+
SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator,
CFDataRef pem_certificate)
{
SecCertificateRef SecCertificateCreateFromAttributeDictionary(
CFDictionaryRef refAttributes);
+/* Return a SecKeyRef for the public key embedded in the cert. */
+#if TARGET_OS_OSX
+SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certificate)
+ __OSX_DEPRECATED(__MAC_10_12, __MAC_10_14, "Use SecCertificateCopyKey instead.");
+#endif
+
/* Return the SecCEBasicConstraints extension for this certificate if it
has one. */
const SecCEBasicConstraints *
}
CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject,
- CFDictionaryRef parameters, SecKeyRef __unused publicKey, SecKeyRef privateKey)
+ CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey)
{
if (subject == NULL || *subject == NULL) {
return NULL;
}
const unsigned min1atv_num = atv_num > 0 ? atv_num : 1;
const unsigned min1num = num > 0 ? num : 1;
- NSS_ATV atvs[min1atv_num];
- NSS_ATV *atvps[min1atv_num];
- NSS_RDN rdns[min1num];
- NSS_RDN *rdnps[num+1];
+ NSS_ATV *atvs = (NSS_ATV *)malloc(sizeof(NSS_ATV) * min1atv_num);
+ NSS_ATV **atvps = (NSS_ATV **)malloc(sizeof(NSS_ATV *) * min1atv_num);
+ NSS_RDN *rdns = (NSS_RDN *)malloc(sizeof(NSS_RDN) * min1num);
+ NSS_RDN **rdnps = (NSS_RDN **)malloc(sizeof(NSS_RDN *) * (num + 1));
atv_num = 0;
unsigned rdn_num = 0;
for (one_rdn = subject; *one_rdn; one_rdn++) {
/* public key info */
realPublicKey = SecKeyCopyPublicKey(privateKey);
+ if (!realPublicKey) {
+ /* If we can't get the public key from the private key,
+ * fall back to the public key provided by the caller. */
+ realPublicKey = CFRetainSafe(publicKey);
+ }
require_quiet(realPublicKey, out);
publicKeyData = make_public_key(realPublicKey, &certReq.reqInfo.subjectPublicKeyInfo, &allocated_parameters);
require_quiet(publicKeyData, out);
CFReleaseSafe(realPublicKey);
CFReleaseSafe(publicKeyData);
CFReleaseSafe(signature);
+ free(atvs);
+ free(atvps);
+ free(rdns);
+ free(rdnps);
return csr;
}
CFDataRef SecGenerateCertificateRequest(CFArrayRef subject,
- CFDictionaryRef parameters, SecKeyRef __unused publicKey, SecKeyRef privateKey)
+ CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey)
{
CFDataRef csr = NULL;
PRArenaPool *poolp = PORT_NewArena(1024);
/* public key info */
realPublicKey = SecKeyCopyPublicKey(privateKey);
+ if (!realPublicKey) {
+ /* If we can't get the public key from the private key,
+ * fall back to the public key provided by the caller. */
+ realPublicKey = CFRetainSafe(publicKey);
+ }
require_quiet(realPublicKey, out);
publicKeyData = make_public_key(realPublicKey, &certReq.reqInfo.subjectPublicKeyInfo, &allocated_parameters);
require_quiet(publicKeyData, out);
+++ /dev/null
-/*
- * Copyright (c) 2010-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@
- */
-
-/*
- * SecECKey.c - CoreFoundation based rsa key object
- */
-
-#include "SecECKey.h"
-#include "SecECKeyPriv.h"
-
-#include <Security/SecKeyInternal.h>
-#include <Security/SecItem.h>
-#include <Security/SecBasePriv.h>
-#include <AssertMacros.h>
-#include <Security/SecureTransport.h> /* For error codes. */
-#include <CoreFoundation/CFData.h> /* For error codes. */
-#include <fcntl.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <CoreFoundation/CFNumber.h>
-#include <Security/SecFramework.h>
-#include <Security/SecRandom.h>
-#include <utilities/debugging.h>
-#include "SecItemPriv.h"
-#include <Security/SecInternal.h>
-#include <utilities/SecCFError.h>
-#include <utilities/SecCFWrappers.h>
-#include <utilities/array_size.h>
-#include <corecrypto/ccec.h>
-#include <corecrypto/ccsha1.h>
-#include <corecrypto/ccsha2.h>
-#include <corecrypto/ccrng.h>
-#include <corecrypto/ccder_decode_eckey.h>
-
-#define kMaximumECKeySize 521
-
-static CFIndex SecECKeyGetAlgorithmID(SecKeyRef key) {
- return kSecECDSAAlgorithmID;
-}
-
-
-/*
- *
- * Public Key
- *
- */
-
-/* Public key static functions. */
-static void SecECPublicKeyDestroy(SecKeyRef key) {
- /* Zero out the public key */
- ccec_pub_ctx_t pubkey = key->key;
- if (ccec_ctx_cp(pubkey))
- cc_clear(ccec_pub_ctx_size(ccn_sizeof_n(ccec_ctx_n(pubkey))), pubkey);
-}
-
-static ccec_const_cp_t getCPForPublicSize(CFIndex encoded_length)
-{
- size_t keysize = ccec_x963_import_pub_size(encoded_length);
- if(ccec_keysize_is_supported(keysize)) {
- return ccec_get_cp(keysize);
- }
- return NULL;
-}
-
-static ccec_const_cp_t getCPForPrivateSize(CFIndex encoded_length)
-{
- size_t keysize = ccec_x963_import_priv_size(encoded_length);
- if(ccec_keysize_is_supported(keysize)) {
- return ccec_get_cp(keysize);
- }
- return NULL;
-}
-
-static ccoid_t ccoid_secp192r1 = CC_EC_OID_SECP192R1;
-static ccoid_t ccoid_secp256r1 = CC_EC_OID_SECP256R1;
-static ccoid_t ccoid_secp224r1 = CC_EC_OID_SECP224R1;
-static ccoid_t ccoid_secp384r1 = CC_EC_OID_SECP384R1;
-static ccoid_t ccoid_secp521r1 = CC_EC_OID_SECP521R1;
-
-static ccec_const_cp_t ccec_cp_for_oid(const unsigned char *oid)
-{
- if (oid!=NULL) {
- if (ccoid_equal(oid, ccoid_secp192r1)) {
- return ccec_cp_192();
- } else if (ccoid_equal(oid, ccoid_secp256r1)) {
- return ccec_cp_256();
- } else if (ccoid_equal(oid, ccoid_secp224r1)) {
- return ccec_cp_224();
- } else if (ccoid_equal(oid, ccoid_secp384r1)) {
- return ccec_cp_384();
- } else if (ccoid_equal(oid, ccoid_secp521r1)) {
- return ccec_cp_521();
- }
- }
- return (ccec_const_cp_t){NULL};
-}
-
-static OSStatus SecECPublicKeyInit(SecKeyRef key,
- const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
- ccec_pub_ctx_t pubkey = key->key;
- OSStatus err = errSecParam;
-
- switch (encoding) {
- case kSecDERKeyEncoding:
- {
- const SecDERKey *derKey = (const SecDERKey *)keyData;
- if (keyDataLength != sizeof(SecDERKey)) {
- err = errSecDecode;
- break;
- }
-
- ccec_const_cp_t cp = getCPForPublicSize(derKey->keyLength);
- require_action_quiet(cp, errOut, err = errSecDecode);
-
- /* TODO: Parse and use real params from passed in derKey->algId.params */
- err = (ccec_import_pub(cp, derKey->keyLength, derKey->key, pubkey)
- ? errSecDecode : errSecSuccess);
- break;
- }
- case kSecKeyEncodingBytes:
- {
- ccec_const_cp_t cp = getCPForPublicSize(keyDataLength);
- require_action_quiet(cp, errOut, err = errSecDecode);
- err = (ccec_import_pub(cp, keyDataLength, keyData, pubkey)
- ? errSecDecode : errSecSuccess);
- break;
- }
- case kSecExtractPublicFromPrivate:
- {
- ccec_full_ctx_t fullKey = (ccec_full_ctx_t)keyData;
-
- cc_size fullKeyN = ccec_ctx_n(fullKey);
- require_quiet(fullKeyN <= ccn_nof(kMaximumECKeySize), errOut);
- memcpy(pubkey, fullKey, ccec_pub_ctx_size(ccn_sizeof_n(fullKeyN)));
- err = errSecSuccess;
- break;
- }
- case kSecKeyEncodingApplePkcs1:
- default:
- err = errSecParam;
- break;
- }
-
-errOut:
- return err;
-}
-
-static CFTypeRef SecECPublicKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm,
- CFArrayRef algorithms, SecKeyOperationMode mode,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- if (operation != kSecKeyOperationTypeVerify) {
- // EC public key supports only signature verification.
- return kCFNull;
- }
-
- if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureRFC4754) || CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureDigestX962)) {
- if (mode == kSecKeyOperationModePerform) {
- bool valid = false;
- int err = -1;
- size_t sigLen = CFDataGetLength(in2);
- uint8_t *sig = (uint8_t *)CFDataGetBytePtr(in2);
- ccec_pub_ctx_t pubkey = key->key;
-
- if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureDigestX962)) {
- err = ccec_verify(pubkey, CFDataGetLength(in1), CFDataGetBytePtr(in1), sigLen, sig, &valid);
- } else {
- if (ccec_signature_r_s_size(pubkey) * 2 != sigLen) {
- SecError(errSecParam, error, CFSTR("bad signature size, got %d, expecting %d bytes"),
- (int)sigLen, (int)ccec_signature_r_s_size(pubkey) * 2);
- return NULL;
- }
- err = ccec_verify_composite(pubkey, CFDataGetLength(in1), CFDataGetBytePtr(in1),
- sig, sig + (sigLen >> 1), &valid);
- }
-
- if (err != 0) {
- SecError(errSecVerifyFailed, error, CFSTR("EC signature verification failed (ccerr %d)"), err);
- return NULL;
- } else if (!valid) {
- SecError(errSecVerifyFailed, error, CFSTR("EC signature verification failed, no match"));
- return NULL;
- } else {
- return kCFBooleanTrue;
- }
- } else {
- // Algorithm is supported.
- return kCFBooleanTrue;
- }
- } else {
- // Other algorithms are unsupported.
- return kCFNull;
- }
-}
-
-static size_t SecECPublicKeyBlockSize(SecKeyRef key) {
- /* Get key size in octets */
- return ccec_ctx_size(ccec_ctx_pub(key->key));
-}
-
-/* Encode the public key and return it in a newly allocated CFDataRef. */
-static CFDataRef SecECPublicKeyExport(CFAllocatorRef allocator,
- ccec_pub_ctx_t pubkey) {
- size_t pub_size = ccec_export_pub_size(pubkey);
- CFMutableDataRef blob = CFDataCreateMutableWithScratch(allocator, pub_size);
- ccec_export_pub(pubkey, CFDataGetMutableBytePtr(blob));
- return blob;
-}
-
-static CFDataRef SecECPublicKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) {
- ccec_pub_ctx_t pubkey = key->key;
- return SecECPublicKeyExport(NULL, pubkey);
-}
-
-static OSStatus SecECPublicKeyCopyPublicOctets(SecKeyRef key, CFDataRef *serailziation)
-{
- ccec_pub_ctx_t pubkey = key->key;
-
- CFAllocatorRef allocator = CFGetAllocator(key);
- *serailziation = SecECPublicKeyExport(allocator, pubkey);
-
- if (NULL == *serailziation)
- return errSecDecode;
- else
- return errSecSuccess;
-}
-
-static CFDictionaryRef SecECPublicKeyCopyAttributeDictionary(SecKeyRef key) {
- CFDictionaryRef dict = SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeEC);
- CFMutableDictionaryRef mutableDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
- CFDictionarySetValue(mutableDict, kSecAttrCanDerive, kCFBooleanFalse);
- CFAssignRetained(dict, mutableDict);
- return dict;
-}
-
-static const char *
-getCurveName(SecKeyRef key)
-{
- SecECNamedCurve curveType = SecECKeyGetNamedCurve(key);
-
- switch (curveType)
- {
- case kSecECCurveSecp256r1:
- return "kSecECCurveSecp256r1";
- break;
- case kSecECCurveSecp384r1:
- return "kSecECCurveSecp384r1";
- break;
- case kSecECCurveSecp521r1:
- return "kSecECCurveSecp521r1";
- default:
- return "kSecECCurveNone";
- }
-}
-
-static CFStringRef SecECPublicKeyCopyKeyDescription(SecKeyRef key)
-{
- CFStringRef keyDescription = NULL;
- CFMutableStringRef strings[2] = { NULL, };
- const char* curve = getCurveName(key);
-
- ccec_pub_ctx_t ecPubkey = key->key;
- size_t len = ccec_ctx_size(ecPubkey);
- uint8_t buffer[len];
- for (int i = 0; i < 2; ++i) {
- ccn_write_uint(ccec_ctx_n(ecPubkey), (i == 0) ? ccec_ctx_x(ecPubkey) : ccec_ctx_y(ecPubkey), len, buffer);
- require_quiet(strings[i] = CFStringCreateMutable(kCFAllocatorDefault, len * 2), fail);
- for (size_t byteIndex = 0; byteIndex < len; ++byteIndex) {
- CFStringAppendFormat(strings[i], NULL, CFSTR("%02X"), buffer[byteIndex]);
- }
- }
-
- keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- CFSTR( "<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, y: %@, x: %@, addr: %p>"),
- curve, (long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version,
- 8 * SecKeyGetBlockSize(key), strings[1], strings[0], key);
-
-fail:
- CFReleaseSafe(strings[0]);
- CFReleaseSafe(strings[1]);
- if(!keyDescription)
- keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- CFSTR("<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"),
- curve,(long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version,
- 8 * SecKeyGetBlockSize(key), key);
-
- return keyDescription;
-}
-
-static const struct ccec_rfc6637_curve * get_rfc6637_curve(SecKeyRef key)
-{
- SecECNamedCurve curveType = SecECKeyGetNamedCurve(key);
-
- if (curveType == kSecECCurveSecp256r1) {
- return &ccec_rfc6637_dh_curve_p256;
- } else if (curveType == kSecECCurveSecp521r1) {
- return &ccec_rfc6637_dh_curve_p521;
- }
- return NULL;
-}
-
-static CFDataRef SecECKeyCopyWrapKey(SecKeyRef key, SecKeyWrapType type, CFDataRef unwrappedKey, CFDictionaryRef parameters, CFDictionaryRef *outParam, CFErrorRef *error)
-{
- ccec_pub_ctx_t pubkey = key->key;
- int err = errSecUnimplemented;
- const struct ccec_rfc6637_curve *curve;
- const struct ccec_rfc6637_wrap *wrap = NULL;
- uint8_t sym_alg = 0;
- int32_t flags = 0;
-
- if (type != kSecKeyWrapPublicKeyPGP) {
- SecError(errSecUnsupportedOperation, error, CFSTR("unsupported key wrapping algorithm"));
- return NULL;
- }
-
- curve = get_rfc6637_curve(key);
- if (curve == NULL) {
- SecError(errSecUnsupportedOperation, error, CFSTR("unsupported curve"));
- return NULL;
- }
-
- CFNumberRef num = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPSymAlg);
- if (!isNumber(num) || !CFNumberGetValue(num, kCFNumberSInt8Type, &sym_alg)) {
- SecError(errSecUnsupportedOperation, error, CFSTR("unknown symalg given"));
- return NULL;
- }
-
- CFDataRef fingerprint = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPFingerprint);
- if (!isData(fingerprint) || CFDataGetLength(fingerprint) < kSecKeyWrapPGPFingerprintMinSize) {
- SecError(errSecUnsupportedOperation, error, CFSTR("invalid fingerprint"));
- return NULL;
- }
-
- CFTypeRef wrapAlg = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPWrapAlg);
- if (wrapAlg == NULL) {
- SecError(errSecUnsupportedOperation, error, CFSTR("no wrap alg"));
- return NULL;
- } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA256KekAES128)) {
- wrap = &ccec_rfc6637_wrap_sha256_kek_aes128;
- } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA512KekAES256)) {
- wrap = &ccec_rfc6637_wrap_sha512_kek_aes256;
- } else {
- SecError(errSecUnsupportedOperation, error, CFSTR("unknown wrap alg"));
- return NULL;
- }
-
- num = CFDictionaryGetValue(parameters, _kSecKeyWrapRFC6637Flags);
- if (isNumber(num)) {
- if (!CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
- SecError(errSecUnsupportedOperation, error, CFSTR("invalid flags: %@"), num);
- return NULL;
- }
- } else if (num) {
- SecError(errSecUnsupportedOperation, error, CFSTR("unknown flags"));
- return NULL;
- }
-
- CFIndex unwrappedKey_size = CFDataGetLength(unwrappedKey);
-
- CFIndex output_size = ccec_rfc6637_wrap_key_size(pubkey, flags, unwrappedKey_size);
- if (output_size == 0) {
- SecError(errSecUnsupportedOperation, error, CFSTR("can't wrap that key, can't build size"));
- return NULL;
- }
-
- CFMutableDataRef data = CFDataCreateMutableWithScratch(NULL, output_size);
- require_quiet(data, errOut);
-
- err = ccec_rfc6637_wrap_key(pubkey, CFDataGetMutableBytePtr(data), flags,
- sym_alg, CFDataGetLength(unwrappedKey), CFDataGetBytePtr(unwrappedKey),
- curve, wrap, CFDataGetBytePtr(fingerprint),
- ccrng_seckey);
- if (err) {
- SecError(errSecUnsupportedOperation, error, CFSTR("Failed to wrap key"));
- CFReleaseNull(data);
- }
-
-errOut:
- return data;
-}
-
-SecKeyDescriptor kSecECPublicKeyDescriptor = {
- .version = kSecKeyDescriptorVersion,
- .name = "ECPublicKey",
- .extraBytes = ccec_pub_ctx_size(ccn_sizeof(kMaximumECKeySize)),
- .init = SecECPublicKeyInit,
- .destroy = SecECPublicKeyDestroy,
- .blockSize = SecECPublicKeyBlockSize,
- .copyDictionary = SecECPublicKeyCopyAttributeDictionary,
- .copyExternalRepresentation = SecECPublicKeyCopyExternalRepresentation,
- .describe = SecECPublicKeyCopyKeyDescription,
- .getAlgorithmID = SecECKeyGetAlgorithmID,
- .copyPublic = SecECPublicKeyCopyPublicOctets,
- .copyWrapKey = SecECKeyCopyWrapKey,
- .copyOperationResult = SecECPublicKeyCopyOperationResult,
-};
-
-/* Public Key API functions. */
-SecKeyRef SecKeyCreateECPublicKey(CFAllocatorRef allocator,
- const uint8_t *keyData, CFIndex keyDataLength,
- SecKeyEncoding encoding) {
- return SecKeyCreate(allocator, &kSecECPublicKeyDescriptor, keyData,
- keyDataLength, encoding);
-}
-
-
-
-/*
- *
- * Private Key
- *
- */
-
-/* Private key static functions. */
-static void SecECPrivateKeyDestroy(SecKeyRef key) {
- /* Zero out the public key */
- ccec_full_ctx_t fullkey = key->key;
-
- if (ccec_ctx_cp(fullkey))
- cc_clear(ccec_full_ctx_size(ccn_sizeof_n(ccec_ctx_n(fullkey))), fullkey);
-}
-
-
-static OSStatus SecECPrivateKeyInit(SecKeyRef key,
- const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
- ccec_full_ctx_t fullkey = key->key;
- OSStatus err = errSecParam;
-
- switch (encoding) {
- case kSecKeyEncodingPkcs1:
- {
- /* TODO: DER import size (and thus cp), pub.x, pub.y and k. */
- //err = ecc_import(keyData, keyDataLength, fullkey);
-
- /* DER != PKCS#1, but we'll go along with it */
- const unsigned char *oid;
- size_t n;
- ccec_const_cp_t cp;
-
- require_noerr_quiet(ccec_der_import_priv_keytype(keyDataLength, keyData, (ccoid_t*)&oid, &n), abort);
- cp = ccec_cp_for_oid(oid);
- if (cp == NULL) {
- cp = ccec_curve_for_length_lookup(n * 8 /* bytes -> bits */,
- ccec_cp_192(), ccec_cp_224(), ccec_cp_256(), ccec_cp_384(), ccec_cp_521(), NULL);
- }
- require_action_quiet(cp != NULL, abort, err = errSecDecode);
- ccec_ctx_init(cp, fullkey);
-
- require_noerr_quiet(ccec_der_import_priv(cp, keyDataLength, keyData, fullkey), abort);
- err = errSecSuccess;
- break;
- }
- case kSecKeyEncodingBytes:
- {
- ccec_const_cp_t cp = getCPForPrivateSize(keyDataLength);
- require_quiet(cp != NULL, abort);
-
- ccec_ctx_init(cp, fullkey);
- size_t pubSize = ccec_export_pub_size(ccec_ctx_pub(fullkey));
-
- require(pubSize < (size_t) keyDataLength, abort);
- require_noerr_action_quiet(ccec_import_pub(cp, pubSize, keyData, ccec_ctx_pub(fullkey)),
- abort,
- err = errSecDecode);
-
-
- keyData += pubSize;
- keyDataLength -= pubSize;
-
- cc_unit *k = ccec_ctx_k(fullkey);
- require_noerr_action_quiet(ccn_read_uint(ccec_ctx_n(fullkey), k, keyDataLength, keyData),
- abort,
- err = errSecDecode);
-
- err = errSecSuccess;
- break;
-
- }
- case kSecGenerateKey:
- {
- CFDictionaryRef parameters = (CFDictionaryRef) keyData;
-
- CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
- CFIndex keyLengthInBits = getIntValue(ksize);
-
- ccec_const_cp_t cp = ccec_get_cp(keyLengthInBits);
-
- if (!cp) {
- secwarning("Invalid or missing key size in: %@", parameters);
- return errSecKeySizeNotAllowed;
- }
-
- if (!ccec_generate_key_fips(cp, ccrng_seckey, fullkey))
- err = errSecSuccess;
- break;
- }
-
- default:
- break;
- }
-abort:
- return err;
-}
-
-static CFTypeRef SecECPrivateKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm,
- CFArrayRef allAlgorithms, SecKeyOperationMode mode,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- // Default answer is 'unsupported', unless we find out that we can support it.
- CFTypeRef result = kCFNull;
-
- ccec_full_ctx_t fullkey = key->key;
- switch (operation) {
- case kSecKeyOperationTypeSign: {
- if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureRFC4754)) {
- if (mode == kSecKeyOperationModePerform) {
- // Perform r/s mode of signature.
- cc_size r_s_size = ccec_signature_r_s_size(ccec_ctx_public(fullkey));
- result = CFDataCreateMutableWithScratch(NULL, r_s_size << 1);
- uint8_t *signatureBuffer = CFDataGetMutableBytePtr((CFMutableDataRef)result);
- int err = ccec_sign_composite(fullkey, CFDataGetLength(in1), CFDataGetBytePtr(in1),
- signatureBuffer, signatureBuffer + r_s_size, ccrng_seckey);
- require_action_quiet(err == 0, out, (CFReleaseNull(result),
- SecError(errSecParam, error, CFSTR("%@: RFC4754 signing failed (ccerr %d)"),
- key, err)));
- } else {
- // Operation is supported.
- result = kCFBooleanTrue;
- }
- } else if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureDigestX962)) {
- if (mode == kSecKeyOperationModePerform) {
- // Perform x962 mode of signature.
- size_t size = ccec_sign_max_size(ccec_ctx_cp(fullkey));
- result = CFDataCreateMutableWithScratch(NULL, size);
- int err = ccec_sign(fullkey, CFDataGetLength(in1), CFDataGetBytePtr(in1),
- &size, CFDataGetMutableBytePtr((CFMutableDataRef)result), ccrng_seckey);
- require_action_quiet(err == 0, out, (CFReleaseNull(result),
- SecError(errSecParam, error, CFSTR("%@: X962 signing failed (ccerr %d)"),
- key, err)));
- CFDataSetLength((CFMutableDataRef)result, size);
- } else {
- // Operation is supported.
- result = kCFBooleanTrue;
- }
- }
- break;
- }
- case kSecKeyOperationTypeKeyExchange:
- if (CFEqual(algorithm, kSecKeyAlgorithmECDHKeyExchangeStandard) ||
- CFEqual(algorithm, kSecKeyAlgorithmECDHKeyExchangeCofactor)) {
- if (mode == kSecKeyOperationModePerform) {
- int err;
- ccec_const_cp_t cp = getCPForPublicSize(CFDataGetLength(in1));
- require_action_quiet(cp != NULL, out,
- SecError(errSecParam, error, CFSTR("ECpriv sharedsecret: bad public key")));
- ccec_pub_ctx_decl_cp(cp, pubkey);
- err = ccec_import_pub(cp, CFDataGetLength(in1), CFDataGetBytePtr(in1), pubkey);
- require_noerr_action_quiet(err, out, SecError(errSecParam, error,
- CFSTR("ECpriv sharedsecret: bad public key (err %d)"), err));
- size_t size = ccec_ccn_size(cp);
- result = CFDataCreateMutableWithScratch(NULL, size);
- err = ccecdh_compute_shared_secret(fullkey, pubkey, &size,
- CFDataGetMutableBytePtr((CFMutableDataRef)result), ccrng_seckey);
- require_noerr_action_quiet(err, out, (CFReleaseNull(result),
- SecError(errSecDecode, error,
- CFSTR("ECpriv failed to compute shared secret (err %d)"), err)));
- CFDataSetLength((CFMutableDataRef)result, size);
- } else {
- // Operation is supported.
- result = kCFBooleanTrue;
- }
- }
- break;
- default:
- break;
- }
-
-out:
- return result;
-}
-
-static size_t SecECPrivateKeyBlockSize(SecKeyRef key) {
- ccec_full_ctx_t fullkey = key->key;
- /* Get key size in octets */
- return ccec_ctx_size(fullkey);
-}
-
-static OSStatus SecECPrivateKeyCopyPublicOctets(SecKeyRef key, CFDataRef *serailziation)
-{
- ccec_full_ctx_t fullkey = key->key;
-
- CFAllocatorRef allocator = CFGetAllocator(key);
- *serailziation = SecECPublicKeyExport(allocator, ccec_ctx_pub(fullkey));
-
- if (NULL == *serailziation)
- return errSecDecode;
- else
- return errSecSuccess;
-}
-
-static CFDataRef SecECPrivateKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) {
- ccec_full_ctx_t fullkey = key->key;
- size_t prime_size = ccec_cp_prime_size(ccec_ctx_cp(fullkey));
- size_t key_size = ccec_export_pub_size(ccec_ctx_pub(fullkey)) + prime_size;
- CFMutableDataRef blob = CFDataCreateMutableWithScratch(NULL, key_size);
- ccec_export_pub(ccec_ctx_pub(fullkey), CFDataGetMutableBytePtr(blob));
- UInt8 *dest = CFDataGetMutableBytePtr(blob) + ccec_export_pub_size(ccec_ctx_pub(fullkey));
- const cc_unit *k = ccec_ctx_k(fullkey);
- ccn_write_uint_padded(ccec_ctx_n(fullkey), k, prime_size, dest);
- return blob;
-}
-
-static CFDictionaryRef SecECPrivateKeyCopyAttributeDictionary(SecKeyRef key) {
- /* Export the full ec key pair. */
- CFDataRef fullKeyBlob = SecECPrivateKeyCopyExternalRepresentation(key, NULL);
-
- CFDictionaryRef dict = SecKeyGeneratePrivateAttributeDictionary(key, kSecAttrKeyTypeEC, fullKeyBlob);
- CFReleaseSafe(fullKeyBlob);
- return dict;
-}
-static CFStringRef SecECPrivateKeyCopyKeyDescription(SecKeyRef key) {
-
- const char* curve = getCurveName(key);
-
- return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), curve, (long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
-
-}
-
-static CFDataRef SecECKeyCopyUnwrapKey(SecKeyRef key, SecKeyWrapType type, CFDataRef wrappedKey, CFDictionaryRef parameters, CFDictionaryRef *outParam, CFErrorRef *error)
-{
- const struct ccec_rfc6637_curve *curve;
- const struct ccec_rfc6637_unwrap *unwrap;
- ccec_full_ctx_t fullkey = key->key;
- CFMutableDataRef data;
- int res;
- uint8_t sym_alg = 0;
- int32_t flags = 0;
-
- curve = get_rfc6637_curve(key);
- if (curve == NULL) {
- SecError(errSecUnsupportedOperation, error, CFSTR("unsupported curve"));
- return NULL;
- }
-
- CFTypeRef wrapAlg = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPWrapAlg);
- if (wrapAlg == NULL) {
- SecError(errSecUnsupportedOperation, error, CFSTR("no wrap alg"));
- return NULL;
- } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA256KekAES128)) {
- unwrap = &ccec_rfc6637_unwrap_sha256_kek_aes128;
- } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA512KekAES256)) {
- unwrap = &ccec_rfc6637_unwrap_sha512_kek_aes256;
- } else {
- SecError(errSecUnsupportedOperation, error, CFSTR("unknown wrap alg"));
- return NULL;
- }
-
- CFDataRef fingerprint = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPFingerprint);
- if (!isData(fingerprint) || CFDataGetLength(fingerprint) < kSecKeyWrapPGPFingerprintMinSize) {
- SecError(errSecUnsupportedOperation, error, CFSTR("invalid fingerprint"));
- return NULL;
- }
-
- CFNumberRef num = CFDictionaryGetValue(parameters, _kSecKeyWrapRFC6637Flags);
- if (isNumber(num)) {
- if (!CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
- SecError(errSecUnsupportedOperation, error, CFSTR("invalid flags: %@"), num);
- return NULL;
- }
- } else if (num) {
- SecError(errSecUnsupportedOperation, error, CFSTR("unknown flags"));
- return NULL;
- }
-
- size_t keysize = CFDataGetLength(wrappedKey);
- data = CFDataCreateMutableWithScratch(NULL, keysize);
- if (data == NULL)
- return NULL;
-
- res = ccec_rfc6637_unwrap_key(fullkey, &keysize, CFDataGetMutableBytePtr(data),
- flags, &sym_alg, curve, unwrap,
- CFDataGetBytePtr(fingerprint),
- CFDataGetLength(wrappedKey), CFDataGetBytePtr(wrappedKey));
- if (res != 0) {
- CFReleaseNull(data);
- SecError(errSecUnsupportedOperation, error, CFSTR("failed to wrap key"));
- return NULL;
- }
- assert(keysize <= (size_t)CFDataGetLength(data));
- CFDataSetLength(data, keysize);
-
- if (outParam) {
- CFMutableDictionaryRef out = CFDictionaryCreateMutableForCFTypes(NULL);
- if (out) {
- CFNumberRef num = CFNumberCreate(NULL, kCFNumberSInt8Type, &sym_alg);
- if (num) {
- CFDictionarySetValue(out, _kSecKeyWrapPGPSymAlg, num);
- CFRelease(num);
- }
- *outParam = out;
- }
- }
-
- return data;
-}
-
-SecKeyDescriptor kSecECPrivateKeyDescriptor = {
- .version = kSecKeyDescriptorVersion,
- .name = "ECPrivateKey",
- .extraBytes = ccec_full_ctx_size(ccn_sizeof(kMaximumECKeySize)),
-
- .init = SecECPrivateKeyInit,
- .destroy = SecECPrivateKeyDestroy,
- .blockSize = SecECPrivateKeyBlockSize,
- .copyDictionary = SecECPrivateKeyCopyAttributeDictionary,
- .describe = SecECPrivateKeyCopyKeyDescription,
- .getAlgorithmID = SecECKeyGetAlgorithmID,
- .copyPublic = SecECPrivateKeyCopyPublicOctets,
- .copyExternalRepresentation = SecECPrivateKeyCopyExternalRepresentation,
- .copyWrapKey = SecECKeyCopyWrapKey,
- .copyUnwrapKey = SecECKeyCopyUnwrapKey,
- .copyOperationResult = SecECPrivateKeyCopyOperationResult,
-};
-
-/* Private Key API functions. */
-SecKeyRef SecKeyCreateECPrivateKey(CFAllocatorRef allocator,
- const uint8_t *keyData, CFIndex keyDataLength,
- SecKeyEncoding encoding) {
- return SecKeyCreate(allocator, &kSecECPrivateKeyDescriptor, keyData,
- keyDataLength, encoding);
-}
-
-
-OSStatus SecECKeyGeneratePair(CFDictionaryRef parameters,
- SecKeyRef *publicKey, SecKeyRef *privateKey) {
- OSStatus status = errSecParam;
-
- CFAllocatorRef allocator = NULL; /* @@@ get from parameters. */
- SecKeyRef pubKey = NULL;
-
- SecKeyRef privKey = SecKeyCreate(allocator, &kSecECPrivateKeyDescriptor,
- (const void*) parameters, 0, kSecGenerateKey);
-
- require(privKey, errOut);
-
- /* Create SecKeyRef's from the pkcs1 encoded keys. */
- pubKey = SecKeyCreate(allocator, &kSecECPublicKeyDescriptor,
- privKey->key, 0, kSecExtractPublicFromPrivate);
-
- require(pubKey, errOut);
-
- if (publicKey) {
- *publicKey = pubKey;
- pubKey = NULL;
- }
- if (privateKey) {
- *privateKey = privKey;
- privKey = NULL;
- }
-
- status = errSecSuccess;
-
-errOut:
- CFReleaseSafe(pubKey);
- CFReleaseSafe(privKey);
-
- return status;
-}
-
-
-/* It's debatable whether this belongs here or in the ssl code since the
- curve values come from a tls related rfc4492. */
-SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef key) {
- SecECNamedCurve result = kSecECCurveNone;
- CFDictionaryRef attributes = NULL;
- require_quiet(SecKeyGetAlgorithmId(key) == kSecECDSAAlgorithmID, out);
- require_quiet(attributes = SecKeyCopyAttributes(key), out);
- CFTypeRef bitsRef = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
- CFIndex bits = 0;
- require_quiet(bitsRef != NULL && CFGetTypeID(bitsRef) == CFNumberGetTypeID() &&
- CFNumberGetValue(bitsRef, kCFNumberCFIndexType, &bits), out);
- switch (bits) {
-#if 0
- case 192:
- result = kSecECCurveSecp192r1;
- break;
- case 224:
- result = kSecECCurveSecp224r1;
- break;
-#endif
- case 256:
- result = kSecECCurveSecp256r1;
- break;
- case 384:
- result = kSecECCurveSecp384r1;
- break;
- case 521:
- result = kSecECCurveSecp521r1;
- break;
- }
-
-out:
- CFReleaseSafe(attributes);
- return result;
-}
-
-CFDataRef SecECKeyCopyPublicBits(SecKeyRef key) {
- CFDataRef bytes = NULL;
- SecKeyCopyPublicBytes(key, &bytes);
- return bytes;
-}
-
-/* Vile accessors that get us the pub or priv key to use temporarily */
-
-bool SecECDoWithFullKey(SecKeyRef key, CFErrorRef* error, void (^action)(ccec_full_ctx_t private)) {
- if (key->key_class == &kSecECPrivateKeyDescriptor) {
- action(key->key);
- } else {
- return SecError(errSecParam, error, CFSTR("Not an EC Full Key object, sorry can't do."));
- }
-
- return true;
-}
-
-bool SecECDoWithPubKey(SecKeyRef key, CFErrorRef* error, void (^action)(ccec_pub_ctx_t public)) {
- if (key->key_class == &kSecECPublicKeyDescriptor) {
- action(key->key);
- } else {
- return SecError(errSecParam, error, CFSTR("Not an EC Public Key object, sorry can't do."));
- }
-
- return true;
-}
-
CFIndex exponentLength;
} SecECPublicKeyParams;
-enum {
- kSecPaddingECIES_SHA2_AES128GCM_MAC128 = 0x9000, /* EC Key Using IESGCM to encrypt */
-};
-
/* Given an EC public key in encoded form return a SecKeyRef representing
that key. Supported encodings are kSecKeyEncodingPkcs1. */
SecKeyRef SecKeyCreateECPublicKey(CFAllocatorRef allocator,
const uint8_t *keyData, CFIndex keyDataLength,
SecKeyEncoding encoding);
-#if SEC_OS_IPHONE_INCLUDES
-/* These are the named curves we support. These values come from RFC 4492
- section 5.1.1, with the exception of SSL_Curve_None which means
- "ECDSA not negotiated". */
-typedef enum
-{
- kSecECCurveNone = -1,
- kSecECCurveSecp256r1 = 23,
- kSecECCurveSecp384r1 = 24,
- kSecECCurveSecp521r1 = 25
-} SecECNamedCurve;
-
-/* Return a named curve enum for ecPrivateKey. */
-SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef ecPrivateKey);
-CFDataRef SecECKeyCopyPublicBits(SecKeyRef key);
-#endif
-
-
__END_DECLS
#endif /* !_SECURITY_SECECKEY_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2010-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@
+ */
+
+/*
+ * SecECKey.m - CoreFoundation based ECDSA key object
+ */
+
+#include "SecECKey.h"
+#include "SecECKeyPriv.h"
+
+#import <Foundation/Foundation.h>
+
+#include <Security/SecKeyInternal.h>
+#include <Security/SecItem.h>
+#include <Security/SecBasePriv.h>
+#include <AssertMacros.h>
+#include <Security/SecureTransport.h> /* For error codes. */
+#include <CoreFoundation/CFData.h> /* For error codes. */
+#include <CoreFoundation/CFNumber.h>
+#include <Security/SecFramework.h>
+#include <Security/SecRandom.h>
+#include <utilities/debugging.h>
+#include "SecItemPriv.h"
+#include <Security/SecInternal.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/array_size.h>
+#include <corecrypto/ccec.h>
+#include <corecrypto/ccsha1.h>
+#include <corecrypto/ccsha2.h>
+#include <corecrypto/ccrng.h>
+#include <corecrypto/ccder_decode_eckey.h>
+
+#define kMaximumECKeySize 521
+
+static CFIndex SecECKeyGetAlgorithmID(SecKeyRef key) {
+ return kSecECDSAAlgorithmID;
+}
+
+
+/*
+ *
+ * Public Key
+ *
+ */
+
+/* Public key static functions. */
+static void SecECPublicKeyDestroy(SecKeyRef key) {
+ /* Zero out the public key */
+ ccec_pub_ctx_t pubkey = key->key;
+ if (ccec_ctx_cp(pubkey))
+ cc_clear(ccec_pub_ctx_size(ccn_sizeof_n(ccec_ctx_n(pubkey))), pubkey);
+}
+
+static ccec_const_cp_t getCPForPublicSize(CFIndex encoded_length)
+{
+ size_t keysize = ccec_x963_import_pub_size(encoded_length);
+ if(ccec_keysize_is_supported(keysize)) {
+ return ccec_get_cp(keysize);
+ }
+ return NULL;
+}
+
+static ccec_const_cp_t getCPForPrivateSize(CFIndex encoded_length)
+{
+ size_t keysize = ccec_x963_import_priv_size(encoded_length);
+ if(ccec_keysize_is_supported(keysize)) {
+ return ccec_get_cp(keysize);
+ }
+ return NULL;
+}
+
+static ccoid_t ccoid_secp192r1 = CC_EC_OID_SECP192R1;
+static ccoid_t ccoid_secp256r1 = CC_EC_OID_SECP256R1;
+static ccoid_t ccoid_secp224r1 = CC_EC_OID_SECP224R1;
+static ccoid_t ccoid_secp384r1 = CC_EC_OID_SECP384R1;
+static ccoid_t ccoid_secp521r1 = CC_EC_OID_SECP521R1;
+
+static ccec_const_cp_t ccec_cp_for_oid(const unsigned char *oid)
+{
+ if (oid!=NULL) {
+ if (ccoid_equal(oid, ccoid_secp192r1)) {
+ return ccec_cp_192();
+ } else if (ccoid_equal(oid, ccoid_secp256r1)) {
+ return ccec_cp_256();
+ } else if (ccoid_equal(oid, ccoid_secp224r1)) {
+ return ccec_cp_224();
+ } else if (ccoid_equal(oid, ccoid_secp384r1)) {
+ return ccec_cp_384();
+ } else if (ccoid_equal(oid, ccoid_secp521r1)) {
+ return ccec_cp_521();
+ }
+ }
+ return (ccec_const_cp_t){NULL};
+}
+
+static OSStatus SecECPublicKeyInit(SecKeyRef key,
+ const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
+ ccec_pub_ctx_t pubkey = key->key;
+ OSStatus err = errSecParam;
+
+ switch (encoding) {
+ case kSecDERKeyEncoding:
+ {
+ const SecDERKey *derKey = (const SecDERKey *)keyData;
+ if (keyDataLength != sizeof(SecDERKey)) {
+ err = errSecDecode;
+ break;
+ }
+
+ ccec_const_cp_t cp = getCPForPublicSize(derKey->keyLength);
+ require_action_quiet(cp, errOut, err = errSecDecode);
+
+ /* TODO: Parse and use real params from passed in derKey->algId.params */
+ err = (ccec_import_pub(cp, derKey->keyLength, derKey->key, pubkey)
+ ? errSecDecode : errSecSuccess);
+ break;
+ }
+ case kSecKeyEncodingBytes:
+ {
+ ccec_const_cp_t cp = getCPForPublicSize(keyDataLength);
+ require_action_quiet(cp, errOut, err = errSecDecode);
+ err = (ccec_import_pub(cp, keyDataLength, keyData, pubkey)
+ ? errSecDecode : errSecSuccess);
+ break;
+ }
+ case kSecExtractPublicFromPrivate:
+ {
+ ccec_full_ctx_t fullKey = (ccec_full_ctx_t)keyData;
+
+ cc_size fullKeyN = ccec_ctx_n(fullKey);
+ require_quiet(fullKeyN <= ccn_nof(kMaximumECKeySize), errOut);
+ memcpy(pubkey, fullKey, ccec_pub_ctx_size(ccn_sizeof_n(fullKeyN)));
+ err = errSecSuccess;
+ break;
+ }
+ case kSecKeyEncodingApplePkcs1:
+ default:
+ err = errSecParam;
+ break;
+ }
+
+errOut:
+ return err;
+}
+
+static CFTypeRef SecECPublicKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm,
+ CFArrayRef algorithms, SecKeyOperationMode mode,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ if (operation != kSecKeyOperationTypeVerify) {
+ // EC public key supports only signature verification.
+ return kCFNull;
+ }
+
+ if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureRFC4754) || CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureDigestX962)) {
+ if (mode == kSecKeyOperationModePerform) {
+ bool valid = false;
+ int err = -1;
+ size_t sigLen = CFDataGetLength(in2);
+ uint8_t *sig = (uint8_t *)CFDataGetBytePtr(in2);
+ ccec_pub_ctx_t pubkey = key->key;
+
+ if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureDigestX962)) {
+ err = ccec_verify(pubkey, CFDataGetLength(in1), CFDataGetBytePtr(in1), sigLen, sig, &valid);
+ } else {
+ if (ccec_signature_r_s_size(pubkey) * 2 != sigLen) {
+ SecError(errSecParam, error, CFSTR("bad signature size, got %d, expecting %d bytes"),
+ (int)sigLen, (int)ccec_signature_r_s_size(pubkey) * 2);
+ return NULL;
+ }
+ err = ccec_verify_composite(pubkey, CFDataGetLength(in1), CFDataGetBytePtr(in1),
+ sig, sig + (sigLen >> 1), &valid);
+ }
+
+ if (err != 0) {
+ SecError(errSecVerifyFailed, error, CFSTR("EC signature verification failed (ccerr %d)"), err);
+ return NULL;
+ } else if (!valid) {
+ SecError(errSecVerifyFailed, error, CFSTR("EC signature verification failed, no match"));
+ return NULL;
+ } else {
+ return kCFBooleanTrue;
+ }
+ } else {
+ // Algorithm is supported.
+ return kCFBooleanTrue;
+ }
+ } else {
+ // Other algorithms are unsupported.
+ return kCFNull;
+ }
+}
+
+static size_t SecECPublicKeyBlockSize(SecKeyRef key) {
+ /* Get key size in octets */
+ return ccec_ctx_size(ccec_ctx_pub(key->key));
+}
+
+/* Encode the public key and return it in a newly allocated CFDataRef. */
+static CFDataRef SecECPublicKeyExport(CFAllocatorRef allocator,
+ ccec_pub_ctx_t pubkey) {
+ size_t pub_size = ccec_export_pub_size(pubkey);
+ CFMutableDataRef blob = CFDataCreateMutableWithScratch(allocator, pub_size);
+ ccec_export_pub(pubkey, CFDataGetMutableBytePtr(blob));
+ return blob;
+}
+
+static CFDataRef SecECPublicKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) {
+ ccec_pub_ctx_t pubkey = key->key;
+ return SecECPublicKeyExport(NULL, pubkey);
+}
+
+static OSStatus SecECPublicKeyCopyPublicOctets(SecKeyRef key, CFDataRef *serailziation)
+{
+ ccec_pub_ctx_t pubkey = key->key;
+
+ CFAllocatorRef allocator = CFGetAllocator(key);
+ *serailziation = SecECPublicKeyExport(allocator, pubkey);
+
+ if (NULL == *serailziation)
+ return errSecDecode;
+ else
+ return errSecSuccess;
+}
+
+static CFDictionaryRef SecECPublicKeyCopyAttributeDictionary(SecKeyRef key) {
+ CFDictionaryRef dict = SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeEC);
+ CFMutableDictionaryRef mutableDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
+ CFDictionarySetValue(mutableDict, kSecAttrCanDerive, kCFBooleanFalse);
+ CFAssignRetained(dict, mutableDict);
+ return dict;
+}
+
+static const char *
+getCurveName(SecKeyRef key)
+{
+ SecECNamedCurve curveType = SecECKeyGetNamedCurve(key);
+
+ switch (curveType)
+ {
+ case kSecECCurveSecp256r1:
+ return "kSecECCurveSecp256r1";
+ break;
+ case kSecECCurveSecp384r1:
+ return "kSecECCurveSecp384r1";
+ break;
+ case kSecECCurveSecp521r1:
+ return "kSecECCurveSecp521r1";
+ default:
+ return "kSecECCurveNone";
+ }
+}
+
+static CFStringRef SecECPublicKeyCopyKeyDescription(SecKeyRef key)
+{
+ NSMutableString *strings[2];
+ const char* curve = getCurveName(key);
+
+ ccec_pub_ctx_t ecPubkey = key->key;
+ size_t len = ccec_ctx_size(ecPubkey);
+ NSMutableData *buffer = [NSMutableData dataWithLength:len];
+ for (int i = 0; i < 2; ++i) {
+ ccn_write_uint(ccec_ctx_n(ecPubkey), (i == 0) ? ccec_ctx_x(ecPubkey) : ccec_ctx_y(ecPubkey), len, buffer.mutableBytes);
+ strings[i] = [NSMutableString stringWithCapacity:len * 2];
+ for (size_t byteIndex = 0; byteIndex < len; ++byteIndex) {
+ [strings[i] appendFormat:@"%02X", ((const uint8_t *)buffer.bytes)[byteIndex]];
+ }
+ }
+
+ NSString *description = [NSString stringWithFormat:@"<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, y: %@, x: %@, addr: %p>",
+ curve, (long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version,
+ 8 * SecKeyGetBlockSize(key), strings[1], strings[0], key];
+ return CFBridgingRetain(description);
+}
+
+static const struct ccec_rfc6637_curve * get_rfc6637_curve(SecKeyRef key)
+{
+ SecECNamedCurve curveType = SecECKeyGetNamedCurve(key);
+
+ if (curveType == kSecECCurveSecp256r1) {
+ return &ccec_rfc6637_dh_curve_p256;
+ } else if (curveType == kSecECCurveSecp521r1) {
+ return &ccec_rfc6637_dh_curve_p521;
+ }
+ return NULL;
+}
+
+static CFDataRef SecECKeyCopyWrapKey(SecKeyRef key, SecKeyWrapType type, CFDataRef unwrappedKey, CFDictionaryRef parameters, CFDictionaryRef *outParam, CFErrorRef *error)
+{
+ ccec_pub_ctx_t pubkey = key->key;
+ int err = errSecUnimplemented;
+ const struct ccec_rfc6637_curve *curve;
+ const struct ccec_rfc6637_wrap *wrap = NULL;
+ uint8_t sym_alg = 0;
+ int32_t flags = 0;
+
+ if (type != kSecKeyWrapPublicKeyPGP) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unsupported key wrapping algorithm"));
+ return NULL;
+ }
+
+ curve = get_rfc6637_curve(key);
+ if (curve == NULL) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unsupported curve"));
+ return NULL;
+ }
+
+ CFNumberRef num = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPSymAlg);
+ if (!isNumber(num) || !CFNumberGetValue(num, kCFNumberSInt8Type, &sym_alg)) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unknown symalg given"));
+ return NULL;
+ }
+
+ CFDataRef fingerprint = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPFingerprint);
+ if (!isData(fingerprint) || CFDataGetLength(fingerprint) < kSecKeyWrapPGPFingerprintMinSize) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("invalid fingerprint"));
+ return NULL;
+ }
+
+ CFTypeRef wrapAlg = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPWrapAlg);
+ if (wrapAlg == NULL) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("no wrap alg"));
+ return NULL;
+ } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA256KekAES128)) {
+ wrap = &ccec_rfc6637_wrap_sha256_kek_aes128;
+ } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA512KekAES256)) {
+ wrap = &ccec_rfc6637_wrap_sha512_kek_aes256;
+ } else {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unknown wrap alg"));
+ return NULL;
+ }
+
+ num = CFDictionaryGetValue(parameters, _kSecKeyWrapRFC6637Flags);
+ if (isNumber(num)) {
+ if (!CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("invalid flags: %@"), num);
+ return NULL;
+ }
+ } else if (num) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unknown flags"));
+ return NULL;
+ }
+
+ CFIndex unwrappedKey_size = CFDataGetLength(unwrappedKey);
+
+ CFIndex output_size = ccec_rfc6637_wrap_key_size(pubkey, flags, unwrappedKey_size);
+ if (output_size == 0) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("can't wrap that key, can't build size"));
+ return NULL;
+ }
+
+ CFMutableDataRef data = CFDataCreateMutableWithScratch(NULL, output_size);
+ require_quiet(data, errOut);
+
+ err = ccec_rfc6637_wrap_key(pubkey, CFDataGetMutableBytePtr(data), flags,
+ sym_alg, CFDataGetLength(unwrappedKey), CFDataGetBytePtr(unwrappedKey),
+ curve, wrap, CFDataGetBytePtr(fingerprint),
+ ccrng_seckey);
+ if (err) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("Failed to wrap key"));
+ CFReleaseNull(data);
+ }
+
+errOut:
+ return data;
+}
+
+SecKeyDescriptor kSecECPublicKeyDescriptor = {
+ .version = kSecKeyDescriptorVersion,
+ .name = "ECPublicKey",
+ .extraBytes = ccec_pub_ctx_size(ccn_sizeof(kMaximumECKeySize)),
+ .init = SecECPublicKeyInit,
+ .destroy = SecECPublicKeyDestroy,
+ .blockSize = SecECPublicKeyBlockSize,
+ .copyDictionary = SecECPublicKeyCopyAttributeDictionary,
+ .copyExternalRepresentation = SecECPublicKeyCopyExternalRepresentation,
+ .describe = SecECPublicKeyCopyKeyDescription,
+ .getAlgorithmID = SecECKeyGetAlgorithmID,
+ .copyPublic = SecECPublicKeyCopyPublicOctets,
+ .copyWrapKey = SecECKeyCopyWrapKey,
+ .copyOperationResult = SecECPublicKeyCopyOperationResult,
+};
+
+/* Public Key API functions. */
+SecKeyRef SecKeyCreateECPublicKey(CFAllocatorRef allocator,
+ const uint8_t *keyData, CFIndex keyDataLength,
+ SecKeyEncoding encoding) {
+ return SecKeyCreate(allocator, &kSecECPublicKeyDescriptor, keyData,
+ keyDataLength, encoding);
+}
+
+
+
+/*
+ *
+ * Private Key
+ *
+ */
+
+/* Private key static functions. */
+static void SecECPrivateKeyDestroy(SecKeyRef key) {
+ /* Zero out the public key */
+ ccec_full_ctx_t fullkey = key->key;
+
+ if (ccec_ctx_cp(fullkey))
+ cc_clear(ccec_full_ctx_size(ccn_sizeof_n(ccec_ctx_n(fullkey))), fullkey);
+}
+
+
+static OSStatus SecECPrivateKeyInit(SecKeyRef key,
+ const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
+ ccec_full_ctx_t fullkey = key->key;
+ OSStatus err = errSecParam;
+
+ switch (encoding) {
+ case kSecKeyEncodingPkcs1:
+ {
+ /* TODO: DER import size (and thus cp), pub.x, pub.y and k. */
+ //err = ecc_import(keyData, keyDataLength, fullkey);
+
+ /* DER != PKCS#1, but we'll go along with it */
+ const unsigned char *oid;
+ size_t n;
+ ccec_const_cp_t cp;
+
+ require_noerr_quiet(ccec_der_import_priv_keytype(keyDataLength, keyData, (ccoid_t*)&oid, &n), abort);
+ cp = ccec_cp_for_oid(oid);
+ if (cp == NULL) {
+ cp = ccec_curve_for_length_lookup(n * 8 /* bytes -> bits */,
+ ccec_cp_192(), ccec_cp_224(), ccec_cp_256(), ccec_cp_384(), ccec_cp_521(), NULL);
+ }
+ require_action_quiet(cp != NULL, abort, err = errSecDecode);
+ ccec_ctx_init(cp, fullkey);
+
+ require_noerr_quiet(ccec_der_import_priv(cp, keyDataLength, keyData, fullkey), abort);
+ err = errSecSuccess;
+ break;
+ }
+ case kSecKeyEncodingBytes:
+ {
+ ccec_const_cp_t cp = getCPForPrivateSize(keyDataLength);
+ require_quiet(cp != NULL, abort);
+
+ ccec_ctx_init(cp, fullkey);
+ size_t pubSize = ccec_export_pub_size(ccec_ctx_pub(fullkey));
+
+ require_quiet(pubSize < (size_t) keyDataLength, abort);
+ require_noerr_action_quiet(ccec_import_pub(cp, pubSize, keyData, ccec_ctx_pub(fullkey)),
+ abort,
+ err = errSecDecode);
+
+
+ keyData += pubSize;
+ keyDataLength -= pubSize;
+
+ cc_unit *k = ccec_ctx_k(fullkey);
+ require_noerr_action_quiet(ccn_read_uint(ccec_ctx_n(fullkey), k, keyDataLength, keyData),
+ abort,
+ err = errSecDecode);
+
+ err = errSecSuccess;
+ break;
+
+ }
+ case kSecGenerateKey:
+ {
+ CFDictionaryRef parameters = (CFDictionaryRef) keyData;
+
+ CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
+ CFIndex keyLengthInBits = getIntValue(ksize);
+
+ ccec_const_cp_t cp = ccec_get_cp(keyLengthInBits);
+
+ if (!cp) {
+ secwarning("Invalid or missing key size in: %@", parameters);
+ return errSecKeySizeNotAllowed;
+ }
+
+ if (!ccec_generate_key_fips(cp, ccrng_seckey, fullkey))
+ err = errSecSuccess;
+ break;
+ }
+
+ default:
+ break;
+ }
+abort:
+ return err;
+}
+
+static CFTypeRef SecECPrivateKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm,
+ CFArrayRef allAlgorithms, SecKeyOperationMode mode,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ // Default answer is 'unsupported', unless we find out that we can support it.
+ CFTypeRef result = kCFNull;
+
+ ccec_full_ctx_t fullkey = key->key;
+ switch (operation) {
+ case kSecKeyOperationTypeSign: {
+ if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureRFC4754)) {
+ if (mode == kSecKeyOperationModePerform) {
+ // Perform r/s mode of signature.
+ cc_size r_s_size = ccec_signature_r_s_size(ccec_ctx_public(fullkey));
+ result = CFDataCreateMutableWithScratch(NULL, r_s_size << 1);
+ uint8_t *signatureBuffer = CFDataGetMutableBytePtr((CFMutableDataRef)result);
+ int err = ccec_sign_composite(fullkey, CFDataGetLength(in1), CFDataGetBytePtr(in1),
+ signatureBuffer, signatureBuffer + r_s_size, ccrng_seckey);
+ require_action_quiet(err == 0, out, (CFReleaseNull(result),
+ SecError(errSecParam, error, CFSTR("%@: RFC4754 signing failed (ccerr %d)"),
+ key, err)));
+ } else {
+ // Operation is supported.
+ result = kCFBooleanTrue;
+ }
+ } else if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureDigestX962)) {
+ if (mode == kSecKeyOperationModePerform) {
+ // Perform x962 mode of signature.
+ size_t size = ccec_sign_max_size(ccec_ctx_cp(fullkey));
+ result = CFDataCreateMutableWithScratch(NULL, size);
+ int err = ccec_sign(fullkey, CFDataGetLength(in1), CFDataGetBytePtr(in1),
+ &size, CFDataGetMutableBytePtr((CFMutableDataRef)result), ccrng_seckey);
+ require_action_quiet(err == 0, out, (CFReleaseNull(result),
+ SecError(errSecParam, error, CFSTR("%@: X962 signing failed (ccerr %d)"),
+ key, err)));
+ CFDataSetLength((CFMutableDataRef)result, size);
+ } else {
+ // Operation is supported.
+ result = kCFBooleanTrue;
+ }
+ }
+ break;
+ }
+ case kSecKeyOperationTypeKeyExchange:
+ if (CFEqual(algorithm, kSecKeyAlgorithmECDHKeyExchangeStandard) ||
+ CFEqual(algorithm, kSecKeyAlgorithmECDHKeyExchangeCofactor)) {
+ if (mode == kSecKeyOperationModePerform) {
+ int err;
+ ccec_const_cp_t cp = getCPForPublicSize(CFDataGetLength(in1));
+ require_action_quiet(cp != NULL, out,
+ SecError(errSecParam, error, CFSTR("ECpriv sharedsecret: bad public key")));
+ ccec_pub_ctx_decl_cp(cp, pubkey);
+ err = ccec_import_pub(cp, CFDataGetLength(in1), CFDataGetBytePtr(in1), pubkey);
+ require_noerr_action_quiet(err, out, SecError(errSecParam, error,
+ CFSTR("ECpriv sharedsecret: bad public key (err %d)"), err));
+ size_t size = ccec_ccn_size(cp);
+ result = CFDataCreateMutableWithScratch(NULL, size);
+ err = ccecdh_compute_shared_secret(fullkey, pubkey, &size,
+ CFDataGetMutableBytePtr((CFMutableDataRef)result), ccrng_seckey);
+ require_noerr_action_quiet(err, out, (CFReleaseNull(result),
+ SecError(errSecDecode, error,
+ CFSTR("ECpriv failed to compute shared secret (err %d)"), err)));
+ CFDataSetLength((CFMutableDataRef)result, size);
+ } else {
+ // Operation is supported.
+ result = kCFBooleanTrue;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+out:
+ return result;
+}
+
+static size_t SecECPrivateKeyBlockSize(SecKeyRef key) {
+ ccec_full_ctx_t fullkey = key->key;
+ /* Get key size in octets */
+ return ccec_ctx_size(fullkey);
+}
+
+static OSStatus SecECPrivateKeyCopyPublicOctets(SecKeyRef key, CFDataRef *serailziation)
+{
+ ccec_full_ctx_t fullkey = key->key;
+
+ CFAllocatorRef allocator = CFGetAllocator(key);
+ *serailziation = SecECPublicKeyExport(allocator, ccec_ctx_pub(fullkey));
+
+ if (NULL == *serailziation)
+ return errSecDecode;
+ else
+ return errSecSuccess;
+}
+
+static CFDataRef SecECPrivateKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) {
+ ccec_full_ctx_t fullkey = key->key;
+ size_t prime_size = ccec_cp_prime_size(ccec_ctx_cp(fullkey));
+ size_t key_size = ccec_export_pub_size(ccec_ctx_pub(fullkey)) + prime_size;
+ CFMutableDataRef blob = CFDataCreateMutableWithScratch(NULL, key_size);
+ ccec_export_pub(ccec_ctx_pub(fullkey), CFDataGetMutableBytePtr(blob));
+ UInt8 *dest = CFDataGetMutableBytePtr(blob) + ccec_export_pub_size(ccec_ctx_pub(fullkey));
+ const cc_unit *k = ccec_ctx_k(fullkey);
+ ccn_write_uint_padded(ccec_ctx_n(fullkey), k, prime_size, dest);
+ return blob;
+}
+
+static CFDictionaryRef SecECPrivateKeyCopyAttributeDictionary(SecKeyRef key) {
+ /* Export the full ec key pair. */
+ CFDataRef fullKeyBlob = SecECPrivateKeyCopyExternalRepresentation(key, NULL);
+
+ CFDictionaryRef dict = SecKeyGeneratePrivateAttributeDictionary(key, kSecAttrKeyTypeEC, fullKeyBlob);
+ CFReleaseSafe(fullKeyBlob);
+ return dict;
+}
+static CFStringRef SecECPrivateKeyCopyKeyDescription(SecKeyRef key) {
+
+ const char* curve = getCurveName(key);
+
+ return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef curve type: %s, algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), curve, (long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
+
+}
+
+static CFDataRef SecECKeyCopyUnwrapKey(SecKeyRef key, SecKeyWrapType type, CFDataRef wrappedKey, CFDictionaryRef parameters, CFDictionaryRef *outParam, CFErrorRef *error)
+{
+ const struct ccec_rfc6637_curve *curve;
+ const struct ccec_rfc6637_unwrap *unwrap;
+ ccec_full_ctx_t fullkey = key->key;
+ CFMutableDataRef data;
+ int res;
+ uint8_t sym_alg = 0;
+ int32_t flags = 0;
+
+ curve = get_rfc6637_curve(key);
+ if (curve == NULL) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unsupported curve"));
+ return NULL;
+ }
+
+ CFTypeRef wrapAlg = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPWrapAlg);
+ if (wrapAlg == NULL) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("no wrap alg"));
+ return NULL;
+ } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA256KekAES128)) {
+ unwrap = &ccec_rfc6637_unwrap_sha256_kek_aes128;
+ } else if (CFEqual(wrapAlg, _kSecKeyWrapRFC6637WrapDigestSHA512KekAES256)) {
+ unwrap = &ccec_rfc6637_unwrap_sha512_kek_aes256;
+ } else {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unknown wrap alg"));
+ return NULL;
+ }
+
+ CFDataRef fingerprint = CFDictionaryGetValue(parameters, _kSecKeyWrapPGPFingerprint);
+ if (!isData(fingerprint) || CFDataGetLength(fingerprint) < kSecKeyWrapPGPFingerprintMinSize) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("invalid fingerprint"));
+ return NULL;
+ }
+
+ CFNumberRef num = CFDictionaryGetValue(parameters, _kSecKeyWrapRFC6637Flags);
+ if (isNumber(num)) {
+ if (!CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("invalid flags: %@"), num);
+ return NULL;
+ }
+ } else if (num) {
+ SecError(errSecUnsupportedOperation, error, CFSTR("unknown flags"));
+ return NULL;
+ }
+
+ size_t keysize = CFDataGetLength(wrappedKey);
+ data = CFDataCreateMutableWithScratch(NULL, keysize);
+ if (data == NULL)
+ return NULL;
+
+ res = ccec_rfc6637_unwrap_key(fullkey, &keysize, CFDataGetMutableBytePtr(data),
+ flags, &sym_alg, curve, unwrap,
+ CFDataGetBytePtr(fingerprint),
+ CFDataGetLength(wrappedKey), CFDataGetBytePtr(wrappedKey));
+ if (res != 0) {
+ CFReleaseNull(data);
+ SecError(errSecUnsupportedOperation, error, CFSTR("failed to wrap key"));
+ return NULL;
+ }
+ assert(keysize <= (size_t)CFDataGetLength(data));
+ CFDataSetLength(data, keysize);
+
+ if (outParam) {
+ CFMutableDictionaryRef out = CFDictionaryCreateMutableForCFTypes(NULL);
+ if (out) {
+ CFNumberRef num = CFNumberCreate(NULL, kCFNumberSInt8Type, &sym_alg);
+ if (num) {
+ CFDictionarySetValue(out, _kSecKeyWrapPGPSymAlg, num);
+ CFRelease(num);
+ }
+ *outParam = out;
+ }
+ }
+
+ return data;
+}
+
+SecKeyDescriptor kSecECPrivateKeyDescriptor = {
+ .version = kSecKeyDescriptorVersion,
+ .name = "ECPrivateKey",
+ .extraBytes = ccec_full_ctx_size(ccn_sizeof(kMaximumECKeySize)),
+
+ .init = SecECPrivateKeyInit,
+ .destroy = SecECPrivateKeyDestroy,
+ .blockSize = SecECPrivateKeyBlockSize,
+ .copyDictionary = SecECPrivateKeyCopyAttributeDictionary,
+ .describe = SecECPrivateKeyCopyKeyDescription,
+ .getAlgorithmID = SecECKeyGetAlgorithmID,
+ .copyPublic = SecECPrivateKeyCopyPublicOctets,
+ .copyExternalRepresentation = SecECPrivateKeyCopyExternalRepresentation,
+ .copyWrapKey = SecECKeyCopyWrapKey,
+ .copyUnwrapKey = SecECKeyCopyUnwrapKey,
+ .copyOperationResult = SecECPrivateKeyCopyOperationResult,
+};
+
+/* Private Key API functions. */
+SecKeyRef SecKeyCreateECPrivateKey(CFAllocatorRef allocator,
+ const uint8_t *keyData, CFIndex keyDataLength,
+ SecKeyEncoding encoding) {
+ return SecKeyCreate(allocator, &kSecECPrivateKeyDescriptor, keyData,
+ keyDataLength, encoding);
+}
+
+
+OSStatus SecECKeyGeneratePair(CFDictionaryRef parameters,
+ SecKeyRef *publicKey, SecKeyRef *privateKey) {
+ OSStatus status = errSecParam;
+
+ CFAllocatorRef allocator = NULL; /* @@@ get from parameters. */
+ SecKeyRef pubKey = NULL;
+
+ SecKeyRef privKey = SecKeyCreate(allocator, &kSecECPrivateKeyDescriptor,
+ (const void*) parameters, 0, kSecGenerateKey);
+
+ require_quiet(privKey, errOut);
+
+ /* Create SecKeyRef's from the pkcs1 encoded keys. */
+ pubKey = SecKeyCreate(allocator, &kSecECPublicKeyDescriptor,
+ privKey->key, 0, kSecExtractPublicFromPrivate);
+
+ require_quiet(pubKey, errOut);
+
+ if (publicKey) {
+ *publicKey = pubKey;
+ pubKey = NULL;
+ }
+ if (privateKey) {
+ *privateKey = privKey;
+ privKey = NULL;
+ }
+
+ status = errSecSuccess;
+
+errOut:
+ CFReleaseSafe(pubKey);
+ CFReleaseSafe(privKey);
+
+ return status;
+}
+
+
+/* It's debatable whether this belongs here or in the ssl code since the
+ curve values come from a tls related rfc4492. */
+SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef key) {
+ SecECNamedCurve result = kSecECCurveNone;
+ CFDictionaryRef attributes = NULL;
+ require_quiet(SecKeyGetAlgorithmId(key) == kSecECDSAAlgorithmID, out);
+ require_quiet(attributes = SecKeyCopyAttributes(key), out);
+ CFTypeRef bitsRef = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
+ CFIndex bits = 0;
+ require_quiet(bitsRef != NULL && CFGetTypeID(bitsRef) == CFNumberGetTypeID() &&
+ CFNumberGetValue(bitsRef, kCFNumberCFIndexType, &bits), out);
+ switch (bits) {
+#if 0
+ case 192:
+ result = kSecECCurveSecp192r1;
+ break;
+ case 224:
+ result = kSecECCurveSecp224r1;
+ break;
+#endif
+ case 256:
+ result = kSecECCurveSecp256r1;
+ break;
+ case 384:
+ result = kSecECCurveSecp384r1;
+ break;
+ case 521:
+ result = kSecECCurveSecp521r1;
+ break;
+ }
+
+out:
+ CFReleaseSafe(attributes);
+ return result;
+}
+
+CFDataRef SecECKeyCopyPublicBits(SecKeyRef key) {
+ CFDataRef bytes = NULL;
+ SecKeyCopyPublicBytes(key, &bytes);
+ return bytes;
+}
+
+/* Vile accessors that get us the pub or priv key to use temporarily */
+
+bool SecECDoWithFullKey(SecKeyRef key, CFErrorRef* error, void (^action)(ccec_full_ctx_t private)) {
+ if (key->key_class == &kSecECPrivateKeyDescriptor) {
+ action(key->key);
+ } else {
+ return SecError(errSecParam, error, CFSTR("Not an EC Full Key object, sorry can't do."));
+ }
+
+ return true;
+}
+
+bool SecECDoWithPubKey(SecKeyRef key, CFErrorRef* error, void (^action)(ccec_pub_ctx_t public)) {
+ if (key->key_class == &kSecECPublicKeyDescriptor) {
+ action(key->key);
+ } else {
+ return SecError(errSecParam, error, CFSTR("Not an EC Public Key object, sorry can't do."));
+ }
+
+ return true;
+}
+
* Assume users use the same normalization rules always
*/
- CFIndex strLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength((__bridge CFStringRef)managedCredential), kCFStringEncodingUTF8);
- strLength += 1;
- char buffer[strLength];
- if (!CFStringGetCString((__bridge CFStringRef)managedCredential, buffer, strLength, kCFStringEncodingUTF8)) {
- return NULL;
- }
-
-
CFMutableDataRef key = CFDataCreateMutable(SecCFAllocatorZeroize(), KEY_LENGTH);
if (key == NULL) {
- memset_s(buffer, strLength, 0, strLength);
return NULL;
}
int ret;
ret = ccpbkdf2_hmac(ccsha256_di(),
- strlen(buffer), buffer,
+ strlen(managedCredential.UTF8String), managedCredential.UTF8String,
CFDataGetLength(salt), CFDataGetBytePtr(salt),
iterations,
KEY_LENGTH, CFDataGetMutableBytePtr(key));
- memset_s(buffer, strLength, 0, strLength);
if (ret) {
CFRelease(key);
return NULL;
_SecPolicyCopyProperties
_SecPolicyCreate
+_SecPolicyCreateiAPSWAuthWithExpiration
_SecPolicyCreateWithProperties
_SecPolicyGetName
_SecPolicyGetOidString
_SecTrustDeserialize
_SecTrustEvaluate
_SecTrustEvaluateAsync
+_SecTrustEvaluateFastAsync
_SecTrustEvaluateLeafOnly
_SecTrustEvaluateWithError
_SecTrustFlushResponseCache
_SecCertificateCopyExtendedKeyUsage
_SecCertificateCopyExtensionValue
_SecCertificateCopyiAPAuthCapabilities
+_SecCertificateCopyiAPSWAuthCapabilities
_SecCertificateCopyIPAddresses
_SecCertificateCopyIPAddressesFromSubject
_SecCertificateCopyiPhoneDeviceCAChain
_SecCertificateCopyIssuerSHA1Digest
_SecCertificateCopyIssuerSequence
_SecCertificateCopyIssuerSummary
+_SecCertificateCopyKey
_SecCertificateCopyKeychainItem
_SecCertificateCopyLegacyProperties
_SecCertificateCopyNormalizedIssuerSequence
_kSecXPCKeyPeerInfoArray
_kSecXPCKeyPeerInfo
+_kSecXPCKeySignInAnalytics
_kSecXPCKeyOperation
_kSecXPCKeyResult
_kSecXPCKeyEndpoint
_CMSEncoderSetSigningTime
_CMSEncoderSetAppleCodesigningHashAgility
_CMSEncoderSetAppleCodesigningHashAgilityV2
+_CMSEncoderSetAppleExpirationTime
_CMSEncoderSetCertificateChainMode
_CMSEncoderGetCertificateChainMode
_CMSEncoderUpdateContent
_CMSDecoderCopySignerSigningTime
_CMSDecoderCopySignerAppleCodesigningHashAgility
_CMSDecoderCopySignerAppleCodesigningHashAgilityV2
+_CMSDecoderCopySignerAppleExpirationTime
_SecCMSCertificatesOnlyMessageCopyCertificates
_SecCMSCreateCertificatesOnlyMessage
_SecCMSCreateCertificatesOnlyMessageIAP
_SecCmsSignedDataVerifySignerInfo
_SecCmsSignerInfoAddAppleCodesigningHashAgility
_SecCmsSignerInfoAddAppleCodesigningHashAgilityV2
+_SecCmsSignerInfoAddAppleExpirationTime
_SecCmsSignerInfoAddCounterSignature
_SecCmsSignerInfoAddMSSMIMEEncKeyPrefs
_SecCmsSignerInfoAddSMIMECaps
_SecCmsSignerInfoCreateWithSubjKeyID
_SecCmsSignerInfoGetAppleCodesigningHashAgility
_SecCmsSignerInfoGetAppleCodesigningHashAgilityV2
+_SecCmsSignerInfoGetAppleExpirationTime
_SecCmsSignerInfoGetCertList
_SecCmsSignerInfoGetDigestAlg
_SecCmsSignerInfoGetDigestAlgTag
_kSecCMSCertChainModeNone
_kSecCMSEncryptionAlgorithmAESCBC
_kSecCMSEncryptionAlgorithmDESCBC
+_kSecCMSExpirationDate
_kSecCMSHashAgility
_kSecCMSHashAgilityV2
_kSecCMSHashingAlgorithmMD5
_SecCmsSignedDataVerifySignerInfo
_SecCmsSignerInfoAddAppleCodesigningHashAgility
_SecCmsSignerInfoAddAppleCodesigningHashAgilityV2
+_SecCmsSignerInfoAddAppleExpirationTime
_SecCmsSignerInfoAddCounterSignature
_SecCmsSignerInfoAddMSSMIMEEncKeyPrefs
_SecCmsSignerInfoAddSMIMECaps
_SecCmsSignerInfoDestroy
_SecCmsSignerInfoGetAppleCodesigningHashAgility
_SecCmsSignerInfoGetAppleCodesigningHashAgilityV2
+_SecCmsSignerInfoGetAppleExpirationTime
_SecCmsSignerInfoGetCertList
_SecCmsSignerInfoGetDigestAlg
_SecCmsSignerInfoGetDigestAlgTag
_kSecCMSCertChainMode
_kSecCMSEncryptionAlgorithmAESCBC
_kSecCMSEncryptionAlgorithmDESCBC
+_kSecCMSExpirationDate
_kSecCMSHashAgility
_kSecCMSHashAgilityV2
_kSecCMSHashingAlgorithmSHA1
// Key
//
_CreatePrivateKeyMatchingQuery
-#if TARGET_OS_IPHONE
_SecECDoWithFullKey
_SecECDoWithPubKey
-#endif
_SecECKeyCopyPublicBits
_SecECKeyGetNamedCurve
+_SecKeyControlLifetime
_SecKeyCopyAttestationKey
-#if TARGET_OS_IPHONE
_SecKeyCopyAttributeDictionary
_SecKeyCreatePublicFromDER
_SecKeyGeneratePrivateAttributeDictionary
_SecKeyGeneratePublicAttributeDictionary
-#endif /* TARGET_OS_IPHONE */
_SecKeyCopyAttributes
_SecKeyCopyExponent
_SecKeyCopyExternalRepresentation
#endif /* TARGET_OS_OSX */
_SecKeyCreatePersistentRefToMatchingPrivateKey
_SecKeyCreatePublicFromPrivate
-#if TARGET_OS_IPHONE
_SecKeyCreateRSAPrivateKey
-#endif /* TARGET_OS_IPHONE */
_SecKeyCreateRSAPublicKey
-#if TARGET_OS_IPHONE
_SecKeyCreateRSAPublicKey_ios
-#endif /* TARGET_OS_IPHONE */
_SecKeyCreateRandomKey
_SecKeyCreateSignature
#if TARGET_OS_OSX
#if TARGET_OS_OSX
_SecKeyDeriveFromPassword
#endif
-#if TARGET_OS_IPHONE
_SecKeyDigestAndSign
-#endif /* TARGET_OS_IPHONE */
_SecKeyDigestAndVerify
_SecKeyEncrypt
#if TARGET_OS_OSX
_SecKeyGenerate
#endif
-#if TARGET_OS_IPHONE
_SecKeyFindWithPersistentRef
-#endif /* TARGET_OS_IPHONE */
_SecKeyGeneratePair
#if TARGET_OS_OSX
_SecKeyGeneratePairAsync
#endif /* TARGET_OS_OSX */
_SecKeyGetAlgorithmID
_SecKeyGetAlgorithmId
-#if TARGET_OS_IPHONE
-_SecKeyGetAlgorithmIdentifier
-#endif /* TARGET_OS_IPHONE */
_SecKeyGetBlockSize
#if TARGET_OS_OSX
_SecKeyGetCSPHandle
#if TARGET_OS_OSX
_SecKeyWrapSymmetric
#endif
-#if TARGET_OS_IPHONE
__SecKeyCopyUnwrapKey
__SecKeyCopyWrapKey
__kSecKeyWrapPGPFingerprint
__kSecKeyWrapRFC6637Flags
__kSecKeyWrapRFC6637WrapDigestSHA256KekAES128
__kSecKeyWrapRFC6637WrapDigestSHA512KekAES256
-#endif /* TARGET_OS_IPHONE */
_kSecKeyAlgorithmECDHKeyExchangeCofactor
_kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1
_kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224
_kSecKeyKeyExchangeParameterRequestedSize
_kSecKeyKeyExchangeParameterSharedInfo
_kSecKeyParameterSETokenAttestationNonce
-#if TARGET_OS_IPHONE
_kSecPrivateKeyAttrs
_kSecPublicKeyAttrs
-#endif /* TARGET_OS_IPHONE */
+
+.objc_class_name_SecKeyProxy
//
// Keychain/SecItem
_kSecReturnData
_kSecReturnPersistentRef
_kSecReturnRef
+_kSecUseCertificatesWithMatchIssuers
_SecItemAdd
_SecItemCertificateExists
_SecItemCopyDisplayNames
_SecItemDelete
#if TARGET_OS_IPHONE
_SecItemDeleteAll
-_SecItemUpdateWithError
#endif
+_SecItemUpdateWithError
_SecItemUpdate
__SecItemAddAndNotifyOnSync
_SecItemSetCurrentItemAcrossAllDevices
_SecTokenItemValueCopy
__SecSecuritydCopyCKKSEndpoint
+__SecSecuritydCopySFKeychainEndpoint
__SecSecuritydCopyKeychainControlEndpoint
#if TARGET_OS_IPHONE
_kSecXPCOTRSession
_kSecXPCData
_kSecXPCOTRReady
-_kSecXPCKeyDeviceID
-_kSecXPCKeyIDSMessage
-_kSecXPCKeySendIDSMessage
#endif
_SecCertificateXPCArrayCopyArray
// Custom CFAllocators
//
_SecCFAllocatorZeroize
+
+
+//
+// SecProtocol
+//
+_sec_array_create
+_sec_array_append
+_sec_array_get_count
+_sec_array_apply
+_sec_certificate_copy_ref
+_sec_certificate_create
+_sec_identity_copy_ref
+_sec_identity_copy_certificates_ref
+_sec_identity_create
+_sec_identity_create_with_certificates
+_sec_tls_extension_create
+_sec_tls_extension_copy_add_block
+_sec_tls_extension_copy_free_block
+_sec_tls_extension_copy_parse_block
+_sec_tls_extension_get_type
+_sec_protocol_metadata_create_secret
+_sec_protocol_metadata_create_secret_with_context
+_sec_protocol_metadata_access_distinguished_names
+_sec_protocol_metadata_access_ocsp_response
+_sec_protocol_metadata_access_peer_certificate_chain
+_sec_protocol_metadata_copy_peer_public_key
+_sec_protocol_metadata_access_supported_signature_algorithms
+_sec_protocol_metadata_get_negotiated_ciphersuite
+_sec_protocol_metadata_get_negotiated_protocol
+_sec_protocol_metadata_get_negotiated_protocol_version
+_sec_protocol_metadata_get_early_data_accepted
+_sec_protocol_metadata_peers_are_equal
+_sec_protocol_metadata_challenge_parameters_are_equal
+_sec_protocol_metadata_get_session_renewed
+_sec_protocol_metadata_get_session_resumed
+_sec_protocol_metadata_get_ticket_offered
+_sec_protocol_metadata_get_ticket_received
+_sec_protocol_metadata_get_tls_false_start_used
+_sec_protocol_options_add_tls_application_protocol
+_sec_protocol_options_add_tls_ciphersuite
+_sec_protocol_options_add_tls_ciphersuite_group
+_sec_protocol_options_add_pre_shared_key
+_sec_protocol_options_set_challenge_block
+_sec_protocol_options_set_key_update_block
+_sec_protocol_options_set_local_identity
+_sec_protocol_options_set_tls_early_data_enabled
+_sec_protocol_options_set_tls_false_start_enabled
+_sec_protocol_options_set_tls_max_version
+_sec_protocol_options_set_tls_min_version
+_sec_protocol_options_set_tls_ocsp_enabled
+_sec_protocol_options_set_tls_renegotiation_enabled
+_sec_protocol_options_set_tls_resumption_enabled
+_sec_protocol_options_set_tls_sct_enabled
+_sec_protocol_options_set_tls_server_name
+_sec_protocol_options_set_tls_sni_disabled
+_sec_protocol_options_set_enforce_ev
+_sec_protocol_options_set_tls_tickets_enabled
+_sec_protocol_options_set_tls_is_fallback_attempt
+_sec_protocol_options_set_verify_block
+_sec_protocol_options_set_tls_diffie_hellman_parameters
+_sec_protocol_options_set_peer_authentication_required
+_sec_protocol_options_add_tls_extension
+_sec_release
+_sec_retain
+_sec_trust_copy_ref
+_sec_trust_create
+
+//
+// SecureTransport
+//
+_SSLCiphersuiteGroupToCiphersuiteList
+_SSLCiphersuiteMaximumTLSVersion
+_SSLCiphersuiteMinimumTLSVersion
+
+#if __OBJC2__ && (TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__))
+_OBJC_CLASS_$_SFSignInAnalytics
+#endif //__OBJC2__ && IPHONE || OSX
#include <Security/SecBase.h>
#include <inttypes.h>
-#if !(TARGET_IPHONE_SIMULATOR && defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090)
-#include <sys/guarded.h>
-#define USE_GUARDED_OPEN 1
-#else
-#define USE_GUARDED_OPEN 0
-#endif
-
-
/* Security.framework's bundle id. */
#if TARGET_OS_IPHONE
-static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security");
+CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.Security");
#else
-static CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.security");
+CFStringRef kSecFrameworkBundleID = CFSTR("com.apple.security");
#endif
CFGiblisGetSingleton(CFBundleRef, SecFrameworkGetBundle, bundle, ^{
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;
-
-int SecRandomCopyBytes(SecRandomRef rnd, size_t count, void *bytes) {
- if (rnd != kSecRandomDefault)
- return errSecParam;
- return CCRandomCopyBytes(kCCRandomDefault, bytes, count);
-}
// Wrapper to provide a CFErrorRef for legacy API.
OSStatus SecOSStatusWith(bool (^perform)(CFErrorRef *error));
+extern CFStringRef kSecFrameworkBundleID;
+
__END_DECLS
#endif /* !_SECURITY_SECFRAMEWORK_H_ */
#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_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_MISSING_INTERMEDIATE_KEY SecStringWithDefaultValue("Unable to build chain to root certificate.", "Certificate", 0, "Unable to build chain to root certificate.", "")
#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_BLOCKED SecStringWithDefaultValue("“%@” certificate is blocked", "Trust", 0, "“%@” certificate is blocked", "Error for blocked certificates")
#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")
#include <libaks_acl_cf_keys.h>
#include <os/activity.h>
#include <pthread.h>
+#include <os/lock.h>
#include <Security/SecInternal.h>
#include "SOSInternal.h"
}
}
-static OSStatus osstatus_for_ids_error(CFIndex idsError) {
- switch (idsError)
- {
- case kSecIDSErrorNoDeviceID:
- return errSecDeviceIDNeeded;
- case kSecIDSErrorNotRegistered:
- return errSecIDSNotRegistered;
- case kSecIDSErrorFailedToSend:
- return errSecFailedToSendIDSMessage;
- case kSecIDSErrorCouldNotFindMatchingAuthToken:
- return errSecDeviceIDNoMatch;
- case kSecIDSErrorNoPeersAvailable:
- return errSecPeersNotAvailable;
- default:
- return errSecInternal;
- }
-}
-
static OSStatus osstatus_for_localauthentication_error(CFIndex laError) {
// Wrap LA error in Sec error.
switch (laError) {
status = osstatus_for_xpc_error(CFErrorGetCode(error));
} else if (CFEqual(sSecDERErrorDomain, domain)) {
status = osstatus_for_der_error(CFErrorGetCode(error));
- }else if (CFEqual(kSecIDSErrorDomain, domain)) {
- status = osstatus_for_ids_error(CFErrorGetCode(error));
} else if (CFEqual(CFSTR(kLAErrorDomain), domain)) {
status = osstatus_for_localauthentication_error(CFErrorGetCode(error));
} else if (CFEqual(CFSTR(kTKErrorDomain), domain)) {
return ref;
}
+#if !TARGET_OS_OSX
OSStatus
SecItemCopyDisplayNames(CFArrayRef items, CFArrayRef *displayNames)
{
// @@@ TBI
return -1 /* errSecUnimplemented */;
}
+#endif // TARGET_OS_OSX
typedef OSStatus (*secitem_operation)(CFDictionaryRef attributes, CFTypeRef *result);
return plist;
}
-TKTokenRef SecTokenCreate(CFStringRef token_id, CFDictionaryRef auth_params, CFErrorRef *error) {
+TKTokenRef SecTokenCreate(CFStringRef token_id, SecCFDictionaryCOW *auth_params, CFErrorRef *error) {
CFMutableDictionaryRef token_attrs = NULL;
TKTokenRef token = NULL;
- token_attrs = (auth_params != NULL) ?
- CFDictionaryCreateMutableCopy(NULL, 0, auth_params) :
+
+ static CFMutableDictionaryRef sharedLAContexts = NULL;
+ static dispatch_once_t onceToken;
+ static os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
+ if ((auth_params->dictionary == NULL || CFDictionaryGetValue(auth_params->dictionary, kSecUseCredentialReference) == NULL) && !CFStringHasPrefix(token_id, kSecAttrTokenIDSecureEnclave)) {
+ dispatch_once(&onceToken, ^{
+ sharedLAContexts = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ });
+
+ os_unfair_lock_lock(&lock);
+ CFTypeRef ctx = CFDictionaryGetValue(sharedLAContexts, token_id);
+ if (ctx == nil) {
+ ctx = LACreateNewContextWithACMContext(NULL, error);
+ if (!ctx) {
+ secerror("Failed to create authentication context %@", *error);
+ return token;
+ }
+ CFDictionarySetValue(sharedLAContexts, token_id, ctx);
+ CFRelease(ctx);
+ ctx = CFDictionaryGetValue(sharedLAContexts, token_id);
+ }
+
+ CFDataRef credRef = NULL;
+ if (ctx != nil) {
+ credRef = LACopyACMContext(ctx, NULL);
+ }
+
+ if (credRef) {
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseAuthenticationContext, ctx);
+ CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseCredentialReference, credRef);
+ CFRelease(credRef);
+ }
+ os_unfair_lock_unlock(&lock);
+ }
+
+ token_attrs = (auth_params->dictionary != NULL) ?
+ CFDictionaryCreateMutableCopy(NULL, 0, auth_params->dictionary) :
CFDictionaryCreateMutableForCFTypes(NULL);
CFDictionarySetValue(token_attrs, kSecAttrTokenID, token_id);
return token;
}
-static bool SecTokenItemCreateFromAttributes(CFDictionaryRef attributes, CFDictionaryRef auth_params,
+static bool SecTokenItemCreateFromAttributes(CFDictionaryRef attributes, CFDictionaryRef auth_params_dict,
TKTokenRef token, CFDataRef object_id, CFTypeRef *ref, CFErrorRef *error) {
bool ok = false;
+ SecCFDictionaryCOW auth_params = { auth_params_dict };
CFMutableDictionaryRef attrs = CFDictionaryCreateMutableCopy(NULL, 0, attributes);
CFTypeRef token_id = CFDictionaryGetValue(attributes, kSecAttrTokenID);
if (token_id != NULL && object_id != NULL) {
if (CFRetainSafe(token) == NULL) {
- require_quiet(token = SecTokenCreate(token_id, auth_params, error), out);
+ require_quiet(token = SecTokenCreate(token_id, &auth_params, error), out);
}
- if (auth_params != NULL) {
- CFDictionaryForEach(auth_params, ^(const void *key, const void *value) {
+ if (auth_params.dictionary != NULL) {
+ CFDictionaryForEach(auth_params.dictionary, ^(const void *key, const void *value) {
CFDictionaryAddValue(attrs, key, value);
});
}
out:
CFReleaseSafe(attrs);
+ CFReleaseSafe(auth_params.mutable_dictionary);
return ok;
}
/* Turn the returned single value or dictionary that contains all the attributes to create a
ref into the exact result the client asked for */
static bool SecItemResultCopyPrepared(CFTypeRef raw_result, TKTokenRef token,
- CFDictionaryRef query, CFDictionaryRef auth_params,
+ CFDictionaryRef query, CFDictionaryRef auth_params_dict,
CFTypeRef *result, CFErrorRef *error) {
bool ok = false;
CFDataRef ac_data = NULL;
CFDataRef cert_data = NULL;
CFDataRef cert_object_id = NULL;
TKTokenRef cert_token = NULL;
+ SecCFDictionaryCOW auth_params = { auth_params_dict };
bool wants_ref = cf_bool_value(CFDictionaryGetValue(query, kSecReturnRef));
bool wants_data = cf_bool_value(CFDictionaryGetValue(query, kSecReturnData));
if ((wants_data || wants_ref) && object_value == NULL) {
// Retrieve value directly from the token.
if (token == NULL) {
- require_quiet(token = SecTokenCreate(token_id, auth_params, error), out);
+ require_quiet(token = SecTokenCreate(token_id, &auth_params, error), out);
}
require_quiet(object_value = TKTokenCopyObjectData(token, object_id, error), out);
if (CFEqual(object_value, kCFNull))
if (cert_data == NULL) {
// Retrieve value directly from the token.
if (cert_token == NULL) {
- require_quiet(cert_token = SecTokenCreate(cert_token_id, auth_params, error), out);
+ require_quiet(cert_token = SecTokenCreate(cert_token_id, &auth_params, error), out);
}
require_quiet(cert_data = TKTokenCopyObjectData(cert_token, cert_object_id, error), out);
if (CFEqual(cert_data, kCFNull))
if (wants_ref) {
CFTypeRef ref;
- require_quiet(SecTokenItemCreateFromAttributes(output, auth_params, token, object_id, &ref, error), out);
+ require_quiet(SecTokenItemCreateFromAttributes(output, auth_params.dictionary, token, object_id, &ref, error), out);
if (!(wants_attributes || wants_data || wants_persistent_ref)) {
CFAssignRetained(*result, ref);
} else if (ref != NULL) {
CFReleaseSafe(attrs);
CFReleaseSafe(token);
CFReleaseSafe(cert_token);
+ CFReleaseSafe(auth_params.mutable_dictionary);
return ok;
}
}
bool SecItemAuthDo(SecCFDictionaryCOW *auth_params, CFErrorRef *error, SecItemAuthResult (^perform)(CFArrayRef *ac_pairs, CFErrorRef *error),
- void (^newCredentialRefAdded)()) {
+ void (^newCredentialRefAdded)(void)) {
bool ok = false;
CFArrayRef ac_pairs = NULL;
SecCFDictionaryCOW auth_options = { NULL };
- // We need to create shared LAContext for Mail to reduce popups with Auth UI.
- // This app-hack will be removed by:<rdar://problem/28305552>
- // Similar workaround is for Safari, will be removed by fixing <rdar://problem/29683072>
- static CFTypeRef sharedLAContext = NULL;
- static CFDataRef sharedACMContext = NULL;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- CFBundleRef bundle = CFBundleGetMainBundle();
- CFStringRef bundleName = (bundle != NULL) ? CFBundleGetIdentifier(bundle) : NULL;
- if (CFEqualSafe(bundleName, CFSTR("com.apple.mail")) ||
- CFEqualSafe(bundleName, CFSTR("com.apple.WebKit.Networking"))) {
- sharedLAContext = LACreateNewContextWithACMContext(NULL, error);
- sharedACMContext = (sharedLAContext != NULL) ? LACopyACMContext(sharedLAContext, error) : NULL;
- }
- });
- if (sharedLAContext && sharedACMContext &&
- (auth_params->dictionary == NULL || (CFDictionaryGetValue(auth_params->dictionary, kSecUseAuthenticationContext) == NULL &&
- CFDictionaryGetValue(auth_params->dictionary, kSecUseCredentialReference) == NULL))) {
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseAuthenticationContext, sharedLAContext);
- CFDictionarySetValue(SecCFDictionaryCOWGetMutable(auth_params), kSecUseCredentialReference, sharedACMContext);
- }
for (uint32_t i = 0;; ++i) {
// If the operation succeeded or failed with other than auth-needed error, just leave.
// Prepare connection to target token if it is present.
CFStringRef token_id = CFDictionaryGetValue(query->dictionary, kSecAttrTokenID);
if (secItemOperation != SecItemCopyMatching && token_id != NULL) {
- require_quiet(CFAssignRetained(token, SecTokenCreate(token_id, auth_params.dictionary, error)), out);
+ require_quiet(CFAssignRetained(token, SecTokenCreate(token_id, &auth_params, error)), out);
}
CFDictionaryRef attrs = (attributes != NULL) ? attributes->dictionary : NULL;
return result;
}
-#ifndef SECITEM_SHIM_OSX
-OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
-
-OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement)
-{
- return -1; /* this is only on OS X currently */
-}
-
-#else
-
-extern OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
-
-#endif
-
#define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
bool _SecKeychainRollKeys(bool force, CFErrorRef *error)
/* String constant declarations */
-#define SEC_CONST_DECL(k,v) const CFTypeRef k = CFSTR(v);
+#define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
/* Class Key Constant */
SEC_CONST_DECL (kSecClass, "class");
SEC_CONST_DECL (kSecUseSyncBubbleKeychain, "u_SyncBubbleKeychain");
SEC_CONST_DECL (kSecUseCallerName, "u_CallerName");
SEC_CONST_DECL (kSecUseTokenRawItems, "u_TokenRawItems");
+SEC_CONST_DECL (kSecUseCertificatesWithMatchIssuers, "u_CertWithIssuers");
/* kSecAttrAccessible Value Constants. */
SEC_CONST_DECL (kSecAttrAccessibleWhenUnlocked, "ak");
} SecItemAuthResult;
bool SecItemAuthDo(SecCFDictionaryCOW *auth_params, CFErrorRef *error, SecItemAuthResult (^perform)(CFArrayRef *ac_pairs, CFErrorRef *error),
- void (^newCredentialRefAdded)());
+ void (^newCredentialRefAdded)(void));
bool SecItemAuthDoQuery(SecCFDictionaryCOW *query, SecCFDictionaryCOW *attributes, const void *secItemOperation, CFErrorRef *error,
bool (^perform)(TKTokenRef token, CFDictionaryRef query, CFDictionaryRef attributes, CFDictionaryRef auth_params, CFErrorRef *error));
void SecItemAuthCopyParams(SecCFDictionaryCOW *auth_params, SecCFDictionaryCOW *query);
-TKTokenRef SecTokenCreate(CFStringRef token_id, CFDictionaryRef auth_params, CFErrorRef *error);
+TKTokenRef SecTokenCreate(CFStringRef token_id, SecCFDictionaryCOW *auth_params, CFErrorRef *error);
CFDictionaryRef SecTokenItemValueCopy(CFDataRef db_value, CFErrorRef *error);
#include <utilities/SecCFWrappers.h>
#include <utilities/array_size.h>
+#include "SecKeyPriv.h"
#include "SecRSAKeyPriv.h"
#include "SecECKeyPriv.h"
#include "SecCTKKeyPriv.h"
#include "SecBasePriv.h"
-#include <Security/SecKeyPriv.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFPriv.h>
#include <pthread.h>
#include <string.h>
#include <AssertMacros.h>
static void SecKeyDestroy(CFTypeRef cf) {
SecKeyRef key = (SecKeyRef)cf;
-#if !TARGET_OS_IPHONE
+#if TARGET_OS_OSX
CFReleaseNull(key->cdsaKey);
#endif
if (key->key_class->destroy)
return result;
}
-CFIndex SecKeyGetAlgorithmIdentifier(SecKeyRef key) {
+CFIndex SecKeyGetAlgorithmId(SecKeyRef key) {
if (!key || !key->key_class) {
// TBD: somehow, a key can be created with a NULL key_class in the
// SecCertificateCopyPublicKey -> SecKeyCreatePublicFromDER code path
memset(&spki, 0, sizeof(spki));
/* encode the public key. */
- require_noerr(SecKeyCopyPublicBytes(key, &publicKey), errOut);
+ require_noerr_quiet(SecKeyCopyPublicBytes(key, &publicKey), errOut);
require_quiet(publicKey, errOut);
- require(CFDataGetLength(publicKey) != 0, errOut);
+ require_quiet(CFDataGetLength(publicKey) != 0, errOut);
// Add prefix 00 is needed to avoid creating negative bit strings
if (((uint8_t *)CFDataGetBytePtr(publicKey))[0] & 0x80)
spki.pubKey.length = CFDataGetLength(publicKey);
// Encode algId according to algorithm used.
- CFIndex algorithm = SecKeyGetAlgorithmIdentifier(key);
+ CFIndex algorithm = SecKeyGetAlgorithmId(key);
if (algorithm == kSecRSAAlgorithmID) {
spki.algId.data = (DERByte *)oidRSA;
spki.algId.length = sizeof(oidRSA);
DERNumSubjPubKeyInfoItemSpecs,
DERSubjPubKeyInfoItemSpecs,
CFDataGetMutableBytePtr(data), &size);
- require(drtn == DR_Success, errOut);
+ require_quiet(drtn == DR_Success, errOut);
CFDataSetLength(data, size);
dataret = CFRetain(data);
}
static SecKeyAlgorithm SecKeyGetSignatureAlgorithmForPadding(SecKeyRef key, SecPadding padding) {
- switch (SecKeyGetAlgorithmIdentifier(key)) {
- case kSecRSAAlgorithmID:
- switch (padding) {
- case kSecPaddingNone:
- return kSecKeyAlgorithmRSASignatureRaw;
- case kSecPaddingPKCS1:
- return kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw;
-#if TARGET_OS_IPHONE
- case kSecPaddingPKCS1SHA1:
- return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1;
- case kSecPaddingPKCS1SHA224:
- return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224;
- case kSecPaddingPKCS1SHA256:
- return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256;
- case kSecPaddingPKCS1SHA384:
- return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384;
- case kSecPaddingPKCS1SHA512:
- return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512;
-#else
- // On CSSM-based implementation, these functions actually did hash its input,
- // so keep doing that for backward compatibility.
- case kSecPaddingPKCS1SHA1:
- return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1;
- case kSecPaddingPKCS1SHA224:
- return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224;
- case kSecPaddingPKCS1SHA256:
- return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256;
- case kSecPaddingPKCS1SHA384:
- return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384;
- case kSecPaddingPKCS1SHA512:
- return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512;
+ switch (SecKeyGetAlgorithmId(key)) {
+ case kSecRSAAlgorithmID: {
+#if TARGET_OS_OSX
+ if (!_CFMZEnabled()) {
+ // On CSSM-based implementation, these functions actually did hash its input,
+ // so keep doing that for backward compatibility.
+ switch (padding) {
+ case kSecPaddingNone:
+ return kSecKeyAlgorithmRSASignatureRaw;
+ case kSecPaddingPKCS1:
+ return kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw;
+ case kSecPaddingPKCS1SHA1:
+ return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1;
+ case kSecPaddingPKCS1SHA224:
+ return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224;
+ case kSecPaddingPKCS1SHA256:
+ return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256;
+ case kSecPaddingPKCS1SHA384:
+ return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384;
+ case kSecPaddingPKCS1SHA512:
+ return kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512;
+ default:
+ return NULL;
+ }
+ } else
#endif
- default:
- return NULL;
+ {
+ switch (padding) {
+ case kSecPaddingNone:
+ return kSecKeyAlgorithmRSASignatureRaw;
+ case kSecPaddingPKCS1:
+ return kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw;
+ case kSecPaddingPKCS1SHA1:
+ return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1;
+ case kSecPaddingPKCS1SHA224:
+ return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224;
+ case kSecPaddingPKCS1SHA256:
+ return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256;
+ case kSecPaddingPKCS1SHA384:
+ return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384;
+ case kSecPaddingPKCS1SHA512:
+ return kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512;
+ default:
+ return NULL;
+ }
}
+ }
case kSecECDSAAlgorithmID:
switch (padding) {
case kSecPaddingSigRaw:
}
static SecKeyAlgorithm SecKeyGetEncryptionAlgorithmForPadding(SecKeyRef key, SecPadding padding) {
- switch (SecKeyGetAlgorithmIdentifier(key)) {
+ switch (SecKeyGetAlgorithmId(key)) {
case kSecRSAAlgorithmID:
switch (padding) {
case kSecPaddingNone:
[false] = &kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
[true] = &kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
} },
+ { &CSSMOID_MD5WithRSA, NULL, {
+ [false] = &kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
+ [true] = &kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
+ } },
{ NULL },
}, translationTableECDSA[] = {
{ &CSSMOID_ECDSA_WithSHA1, &CSSMOID_SHA1, {
};
const struct TableItem *table;
- switch (SecKeyGetAlgorithmIdentifier(key)) {
+ switch (SecKeyGetAlgorithmId(key)) {
case kSecRSAAlgorithmID:
table = translationTableRSA;
break;
});
}
-CFIndex SecKeyGetAlgorithmId(SecKeyRef key) {
- return SecKeyGetAlgorithmIdentifier(key);
-}
-
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
+#if TARGET_OS_OSX
/* On OS X, SecKeyGetAlgorithmID has a different function signature (two arguments,
with output in the second argument). Therefore, avoid implementing this function here
if compiling for OS X.
*/
#else
+// Export original SecKeyGetAlgorithmID symbol for backward binary compatibility.
+#undef SecKeyGetAlgorithmID
+CFIndex SecKeyGetAlgorithmID(SecKeyRef key);
CFIndex SecKeyGetAlgorithmID(SecKeyRef key) {
- return SecKeyGetAlgorithmIdentifier(key);
+ return SecKeyGetAlgorithmId(key);
}
#endif
{
size_t result = SecKeyGetBlockSize(key);
- if (kSecECDSAAlgorithmID == SecKeyGetAlgorithmIdentifier(key)) {
+ if (whichSize == 0 || whichSize == 10) {
+ // kSecKeyKeySizeInBits is declared as 0 on iOS (SPI) and 10 on macOS (API). Unified implementation
+ // here deals with both values.
+ whichSize = kSecKeyKeySizeInBits;
+ }
+
+ if (kSecECDSAAlgorithmID == SecKeyGetAlgorithmId(key)) {
switch (whichSize) {
case kSecKeyEncryptedDataSize:
result = 0;
CFRelease(blockSizeRef);
}
- switch (SecKeyGetAlgorithmIdentifier(key)) {
+ switch (SecKeyGetAlgorithmId(key)) {
case kSecRSAAlgorithmID:
CFDictionarySetValue(dict, kSecAttrKeyType, kSecAttrKeyTypeRSA);
break;
require_noerr_quiet(SecKeyCopyPublicBytes(key, &serializedPublic), fail);
require_quiet(serializedPublic, fail);
- result = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmIdentifier(key), serializedPublic);
+ result = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmId(key), serializedPublic);
fail:
CFReleaseSafe(serializedPublic);
{ &kSecKeyAlgorithmRSAEncryptionOAEPSHA1, kSecRSAAlgorithmID, kSecPaddingOAEP },
};
SecPadding padding = (SecPadding)-1;
- CFIndex keyAlg = SecKeyGetAlgorithmIdentifier(context->key);
+ CFIndex keyAlg = SecKeyGetAlgorithmId(context->key);
for (size_t i = 0; i < array_size(paddingMap); ++i) {
if (keyAlg == paddingMap[i].keyAlg && CFEqual(algorithm, *paddingMap[i].algorithm)) {
padding = paddingMap[i].padding;
+++ /dev/null
-/*
- * 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@
- */
-
-/*
- * SecKeyAdaptors.c - Implementation of assorted algorithm adaptors for SecKey.
- * Algorithm adaptor is able to perform some transformation on provided input and calculated results and invoke
- * underlying operation with different algorithm. Typical adaptors are message->digest or unpadded->padded.
- * To invoke underlying operation, add algorithm to the context algorithm array and invoke SecKeyRunAlgorithmAndCopyResult().
- */
-
-#include <Security/SecBase.h>
-#include <Security/SecKeyInternal.h>
-#include <Security/SecItem.h>
-#include <Security/SecCFAllocator.h>
-
-#include <AssertMacros.h>
-#include <utilities/SecCFWrappers.h>
-#include <utilities/array_size.h>
-#include <utilities/debugging.h>
-#include <utilities/SecCFError.h>
-#include <utilities/SecBuffer.h>
-
-#include <corecrypto/ccsha1.h>
-#include <corecrypto/ccsha2.h>
-#include <corecrypto/ccmd5.h>
-#include <corecrypto/ccrsa_priv.h>
-#include <corecrypto/ccansikdf.h>
-#include <corecrypto/ccmode.h>
-#include <corecrypto/ccaes.h>
-
-#pragma mark Algorithm constants value definitions
-
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRaw = CFSTR("algid:sign:RSA:raw");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRawCCUnit = CFSTR("algid:sign:RSA:raw-cc");
-
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw = CFSTR("algid:sign:RSA:digest-PKCS1v15");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5 = CFSTR("algid:sign:RSA:digest-PKCS1v15:MD5");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA1");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA224");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA256");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA384");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA512");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA1 = CFSTR("algid:sign:RSA:digest-PSS:SHA1:SHA1:20");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA224 = CFSTR("algid:sign:RSA:digest-PSS:SHA224:SHA224:24");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA256 = CFSTR("algid:sign:RSA:digest-PSS:SHA256:SHA256:32");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA384 = CFSTR("algid:sign:RSA:digest-PSS:SHA384:SHA384:48");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA512 = CFSTR("algid:sign:RSA:digest-PSS:SHA512:SHA512:64");
-
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5 = CFSTR("algid:sign:RSA:message-PKCS1v15:MD5");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA1");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA224");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA256");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA384");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA512");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA1 = CFSTR("algid:sign:RSA:message-PSS:SHA1:SHA1:20");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA224 = CFSTR("algid:sign:RSA:message-PSS:SHA224:SHA224:24");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA256 = CFSTR("algid:sign:RSA:message-PSS:SHA256:SHA256:32");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA384 = CFSTR("algid:sign:RSA:message-PSS:SHA384:SHA384:48");
-const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA512 = CFSTR("algid:sign:RSA:message-PSS:SHA512:SHA512:64");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureRFC4754 = CFSTR("algid:sign:ECDSA:RFC4754");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962 = CFSTR("algid:sign:ECDSA:digest-X962");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA1 = CFSTR("algid:sign:ECDSA:digest-X962:SHA1");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA224 = CFSTR("algid:sign:ECDSA:digest-X962:SHA224");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA256 = CFSTR("algid:sign:ECDSA:digest-X962:SHA256");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA384 = CFSTR("algid:sign:ECDSA:digest-X962:SHA384");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA512 = CFSTR("algid:sign:ECDSA:digest-X962:SHA512");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA1 = CFSTR("algid:sign:ECDSA:message-X962:SHA1");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA224 = CFSTR("algid:sign:ECDSA:message-X962:SHA224");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA256 = CFSTR("algid:sign:ECDSA:message-X962:SHA256");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA384 = CFSTR("algid:sign:ECDSA:message-X962:SHA384");
-const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA512 = CFSTR("algid:sign:ECDSA:message-X962:SHA512");
-
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRaw = CFSTR("algid:encrypt:RSA:raw");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRawCCUnit = CFSTR("algid:encrypt:RSA:raw-cc");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionPKCS1 = CFSTR("algid:encrypt:RSA:PKCS1");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1 = CFSTR("algid:encrypt:RSA:OAEP:SHA1");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224 = CFSTR("algid:encrypt:RSA:OAEP:SHA224");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256 = CFSTR("algid:encrypt:RSA:OAEP:SHA256");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384 = CFSTR("algid:encrypt:RSA:OAEP:SHA384");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512 = CFSTR("algid:encrypt:RSA:OAEP:SHA512");
-
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA1:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA224:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA256:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA384:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA512:AESGCM");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA1:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA224:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA384:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA512:AESGCM");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA1:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA224:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA384:AESGCM");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA512:AESGCM");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA224:AESGCM-KDFIV");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM-KDFIV");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA384:AESGCM-KDFIV");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA512:AESGCM-KDFIV");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA224:AESGCM-KDFIV");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM-KDFIV");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA384:AESGCM-KDFIV");
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA512:AESGCM-KDFIV");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandard = CFSTR("algid:keyexchange:ECDH");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA1");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA224");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA256");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA384");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA512");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactor = CFSTR("algid:keyexchange:ECDHC");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA1");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA224");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA256");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA384");
-const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA512");
-
-const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionAKSSmartCard = CFSTR("algid:encrypt:ECIES:ECDH:SHA256:2PubKeys");
-
-void SecKeyOperationContextDestroy(SecKeyOperationContext *context) {
- CFReleaseNull(context->algorithm);
-}
-
-static void PerformWithCFDataBuffer(CFIndex size, void (^operation)(uint8_t *buffer, CFDataRef data)) {
- PerformWithBuffer(size, ^(size_t size, uint8_t *buffer) {
- CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)buffer, size, kCFAllocatorNull);
- operation(buffer, data);
- CFRelease(data);
- });
-}
-
-static CFDataRef SecKeyCopyDigestForMessage(SecKeyOperationContext *context, CFDataRef message, CFDataRef in2,
- const struct ccdigest_info *di, CFErrorRef *error) {
- if (context->mode == kSecKeyOperationModeCheckIfSupported) {
- return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
- }
-
- __block CFTypeRef result;
- PerformWithCFDataBuffer(di->output_size, ^(uint8_t *buffer, CFDataRef data) {
- ccdigest(di, CFDataGetLength(message), CFDataGetBytePtr(message), buffer);
- result = SecKeyRunAlgorithmAndCopyResult(context, data, in2, error);
- });
- return result;
-}
-
-static CFTypeRef SecKeyCopyECDSASignatureForDigest(SecKeyOperationContext *context, CFDataRef digest, CFDataRef in2,
- SecKeyAlgorithm algorithm, const struct ccdigest_info *di, CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigestX962);
- if (context->mode == kSecKeyOperationModeCheckIfSupported) {
- return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
- }
-
- if (CFDataGetLength(digest) != (CFIndex)di->output_size) {
- SecError(errSecParam, error, CFSTR("bad digest size for signing with algorithm %@"), algorithm);
- return NULL;
- }
-
- return SecKeyRunAlgorithmAndCopyResult(context, digest, in2, error);
-}
-
-#define DIGEST_RSA_ADAPTORS(name, di) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessage ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigest ## name); \
- return SecKeyCopyDigestForMessage(context, in1, in2, di, error); \
-}
-
-#define DIGEST_ECDSA_ADAPTORS(name, di) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessage ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigest ## name); \
- return SecKeyCopyDigestForMessage(context, in1, in2, di, error); \
-} \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigest ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyCopyECDSASignatureForDigest(context, in1, in2, kSecKeyAlgorithmECDSASignatureDigest ## name, di, error); \
-}
-
-DIGEST_RSA_ADAPTORS(PKCS1v15SHA1, ccsha1_di())
-DIGEST_RSA_ADAPTORS(PKCS1v15SHA224, ccsha224_di())
-DIGEST_RSA_ADAPTORS(PKCS1v15SHA256, ccsha256_di())
-DIGEST_RSA_ADAPTORS(PKCS1v15SHA384, ccsha384_di())
-DIGEST_RSA_ADAPTORS(PKCS1v15SHA512, ccsha512_di())
-DIGEST_RSA_ADAPTORS(PKCS1v15MD5, ccmd5_di())
-DIGEST_RSA_ADAPTORS(PSSSHA1, ccsha1_di())
-DIGEST_RSA_ADAPTORS(PSSSHA224, ccsha224_di())
-DIGEST_RSA_ADAPTORS(PSSSHA256, ccsha256_di())
-DIGEST_RSA_ADAPTORS(PSSSHA384, ccsha384_di())
-DIGEST_RSA_ADAPTORS(PSSSHA512, ccsha512_di())
-DIGEST_ECDSA_ADAPTORS(X962SHA1, ccsha1_di())
-DIGEST_ECDSA_ADAPTORS(X962SHA224, ccsha224_di())
-DIGEST_ECDSA_ADAPTORS(X962SHA256, ccsha256_di())
-DIGEST_ECDSA_ADAPTORS(X962SHA384, ccsha384_di())
-DIGEST_ECDSA_ADAPTORS(X962SHA512, ccsha512_di())
-
-#undef DIGEST_RSA_ADAPTORS
-#undef DIGEST_ECDSA_ADAPTORS
-
-static CFDataRef SecKeyRSACopyBigEndianToCCUnit(CFDataRef bigEndian, size_t size) {
- CFMutableDataRef result = NULL;
- if (bigEndian != NULL) {
- size_t dataSize = CFDataGetLength(bigEndian);
- if (dataSize > size) {
- size = dataSize;
- }
- result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, ccrsa_sizeof_n_from_size(size));
- ccn_read_uint(ccn_nof_size(size), (cc_unit *)CFDataGetMutableBytePtr(result), dataSize, CFDataGetBytePtr(bigEndian));
- }
- return result;
-}
-
-static void PerformWithBigEndianToCCUnit(CFDataRef bigEndian, size_t size, void (^operation)(CFDataRef ccunits)) {
- if (bigEndian == NULL) {
- return operation(NULL);
- }
- size_t dataSize = CFDataGetLength(bigEndian);
- if (dataSize > size) {
- size = dataSize;
- }
- PerformWithCFDataBuffer(ccrsa_sizeof_n_from_size(size), ^(uint8_t *buffer, CFDataRef data) {
- ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, dataSize, CFDataGetBytePtr(bigEndian));
- operation(data);
- });
-}
-
-static CFDataRef SecKeyRSACopyCCUnitToBigEndian(CFDataRef ccunits, size_t size) {
- CFMutableDataRef result = NULL;
- if (ccunits != NULL) {
- cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
- const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
- result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, size);
- ccn_write_uint_padded(n, s, CFDataGetLength(result), CFDataGetMutableBytePtr(result));
- }
- return result;
-}
-
-static void PerformWithCCUnitToBigEndian(CFDataRef ccunits, size_t size, void (^operation)(CFDataRef bigEndian)) {
- if (ccunits == NULL) {
- return operation(NULL);
- }
- PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
- cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
- const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
- ccn_write_uint_padded(n, s, size, buffer);
- operation(data);
- });
-}
-
-static CFTypeRef SecKeyRSACopyEMSASignature(SecKeyOperationContext *context,
- CFDataRef in1, CFDataRef in2, CFErrorRef *error, bool pss, const struct ccdigest_info *di) {
- CFDictionaryRef parameters = NULL;
- __block CFTypeRef result = NULL;
-
- require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
- SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
- CFReleaseNull(parameters);
-
- if (pss) {
- // Verify that algorithm is compatible with the modulus size.
- size_t blockSize = SecKeyGetBlockSize(context->key);
- require_action_quiet(blockSize >= di->output_size * 2 + 2, out,
- SecError(errSecParam, error, CFSTR("algorithm %@ incompatible with %lubit RSA key"),
- CFArrayGetValueAtIndex(context->algorithm, CFArrayGetCount(context->algorithm) - 1),
- blockSize * 8));
- }
-
- if (!pss && di != NULL) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw);
- }
-
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
- if (context->mode == kSecKeyOperationModeCheckIfSupported) {
- return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
- }
-
- size_t size = SecKeyGetBlockSize(context->key);
- if (size == 0) {
- SecError(errSecParam, error, CFSTR("expecting RSA key"));
- return NULL;
- }
- PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
- uint8_t s[size];
- if (pss) {
- uint8_t salt[di->output_size];
- int err = ccrng_generate(ccrng_seckey, di->output_size, salt);
- require_noerr_action_quiet(err, out, SecError(errSecInternal, error, CFSTR("PSS salt gen fail (%zu bytes), err %d"),
- di->output_size, err));
- err = ccrsa_emsa_pss_encode(di, di, di->output_size, salt,
- CFDataGetLength(in1), CFDataGetBytePtr(in1), size * 8 - 1, s);
- require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSASSA-PSS incompatible algorithm for key size")));
- } else {
- int err = ccrsa_emsa_pkcs1v15_encode(size, s, CFDataGetLength(in1), CFDataGetBytePtr(in1), di ? di->oid : NULL);
- require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSAsign wrong input data length")));
- }
- ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, size, s);
- require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
- CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
- out:;
- });
-
-out:
- CFReleaseSafe(parameters);
- return result;
-}
-
-#define RSA_EMSA_SIGN_ADAPTOR(name, pss, di) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigest ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyRSACopyEMSASignature(context, in1, in2, error, pss, di); \
-}
-
-RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA1, false, ccsha1_di())
-RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA224, false, ccsha224_di())
-RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA256, false, ccsha256_di())
-RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA384, false, ccsha384_di())
-RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA512, false, ccsha512_di())
-RSA_EMSA_SIGN_ADAPTOR(PKCS1v15Raw, false, NULL)
-RSA_EMSA_SIGN_ADAPTOR(PKCS1v15MD5, false, ccmd5_di())
-RSA_EMSA_SIGN_ADAPTOR(PSSSHA1, true, ccsha1_di())
-RSA_EMSA_SIGN_ADAPTOR(PSSSHA224, true, ccsha224_di())
-RSA_EMSA_SIGN_ADAPTOR(PSSSHA256, true, ccsha256_di())
-RSA_EMSA_SIGN_ADAPTOR(PSSSHA384, true, ccsha384_di())
-RSA_EMSA_SIGN_ADAPTOR(PSSSHA512, true, ccsha512_di())
-
-#undef RSA_EMSA_SIGN_ADAPTOR
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- if (context->mode == kSecKeyOperationModeCheckIfSupported) {
- return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
- }
-
- __block CFTypeRef result = NULL;
- PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
- result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, in2, error);
- if (result != NULL) {
- CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
- }
- });
- return result;
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- if (context->mode == kSecKeyOperationModeCheckIfSupported) {
- return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
- }
-
- __block CFTypeRef result = NULL;
- PerformWithCCUnitToBigEndian(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef bigEndian) {
- result = SecKeyRunAlgorithmAndCopyResult(context, bigEndian, in2, error);
- if (result != NULL) {
- CFAssignRetained(result, SecKeyRSACopyBigEndianToCCUnit(result, SecKeyGetBlockSize(context->key)));
- }
- });
- return result;
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
- return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRaw);
- return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
-}
-
-static bool SecKeyVerifyBadSignature(CFErrorRef *error) {
- return SecError(errSecVerifyFailed, error, CFSTR("RSA signature verification failed, no match"));
-}
-
-static CFTypeRef SecKeyRSAVerifyAdaptorCopyResult(SecKeyOperationContext *context, CFTypeRef signature, CFErrorRef *error,
- Boolean (^verifyBlock)(CFDataRef decrypted)) {
- CFTypeRef result = NULL;
- context->operation = kSecKeyOperationTypeDecrypt;
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
- result = SecKeyRunAlgorithmAndCopyResult(context, signature, NULL, error);
- if (context->mode == kSecKeyOperationModePerform && result != NULL) {
- if (verifyBlock(result)) {
- CFRetainAssign(result, kCFBooleanTrue);
- } else {
- CFRetainAssign(result, kCFBooleanFalse);
- SecKeyVerifyBadSignature(error);
- }
- }
- return result;
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) {
- // Skip zero-padding from the beginning of the decrypted signature.
- const UInt8 *data = CFDataGetBytePtr(decrypted);
- CFIndex length = CFDataGetLength(decrypted);
- while (*data == 0x00 && length > 0) {
- data++;
- length--;
- }
- // The rest of the decrypted signature must be the same as input data.
- return length == CFDataGetLength(in1) && memcmp(CFDataGetBytePtr(in1), data, length) == 0;
- });
-};
-
-#define PKCS1v15_EMSA_VERIFY_ADAPTOR(name, oid) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15 ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) { \
- return ccrsa_emsa_pkcs1v15_verify(CFDataGetLength(decrypted), \
- (uint8_t *)CFDataGetBytePtr(decrypted), \
- CFDataGetLength(in1), CFDataGetBytePtr(in1), oid) == 0; \
- }); \
-}
-
-#define PSS_EMSA_VERIFY_ADAPTOR(name, di) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSS ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) { \
- return ccrsa_emsa_pss_decode(di, di, di->output_size, CFDataGetLength(in1), CFDataGetBytePtr(in1), \
- CFDataGetLength(decrypted) * 8 - 1, (uint8_t *)CFDataGetBytePtr(decrypted)) == 0; \
- }); \
-}
-
-PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA1, ccsha1_di()->oid)
-PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA224, ccsha224_di()->oid)
-PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA256, ccsha256_di()->oid)
-PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA384, ccsha384_di()->oid)
-PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA512, ccsha512_di()->oid)
-PKCS1v15_EMSA_VERIFY_ADAPTOR(Raw, NULL)
-PKCS1v15_EMSA_VERIFY_ADAPTOR(MD5, ccmd5_di()->oid)
-
-PSS_EMSA_VERIFY_ADAPTOR(SHA1, ccsha1_di())
-PSS_EMSA_VERIFY_ADAPTOR(SHA224, ccsha224_di())
-PSS_EMSA_VERIFY_ADAPTOR(SHA256, ccsha256_di())
-PSS_EMSA_VERIFY_ADAPTOR(SHA384, ccsha384_di())
-PSS_EMSA_VERIFY_ADAPTOR(SHA512, ccsha512_di())
-
-#undef PKCS1v15_EMSA_VERIFY_ADAPTOR
-#undef PSS_EMSA_VERIFY_ADAPTOR
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
- return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
- return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
-}
-
-static CFTypeRef SecKeyRSACopyEncryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
- CFDataRef in1, CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
- size_t size = SecKeyGetBlockSize(context->key);
- size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
- if (size < minSize) {
- return kCFNull;
- }
- if (context->mode == kSecKeyOperationModeCheckIfSupported) {
- return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
- }
-
- __block CFTypeRef result = NULL;
- PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
- int err;
- if (di != NULL) {
- err = ccrsa_oaep_encode(di, ccrng_seckey, size, (cc_unit *)buffer,
- CFDataGetLength(in1), CFDataGetBytePtr(in1));
- } else {
- err = ccrsa_eme_pkcs1v15_encode(ccrng_seckey, size, (cc_unit *)buffer,
- CFDataGetLength(in1), CFDataGetBytePtr(in1));
- }
- require_noerr_action_quiet(err, out, SecError(errSecParam, error,
- CFSTR("RSAencrypt wrong input size (err %d)"), err));
- require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
- CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
- out:;
- });
- return result;
-}
-
-static CFTypeRef SecKeyRSACopyDecryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
- CFDataRef in1, CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
- size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
- if (SecKeyGetBlockSize(context->key) < minSize) {
- return kCFNull;
- }
- if (context->mode == kSecKeyOperationModeCheckIfSupported) {
- return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
- }
-
- __block CFMutableDataRef result = NULL;
- PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
- CFDataRef cc_result = NULL;
- require_quiet(cc_result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, NULL, error), out);
- size_t size = CFDataGetLength(cc_result);
- result = CFDataCreateMutableWithScratch(NULL, size);
- int err;
- if (di != NULL) {
- err = ccrsa_oaep_decode(di, &size, CFDataGetMutableBytePtr(result),
- CFDataGetLength(cc_result), (cc_unit *)CFDataGetBytePtr(cc_result));
- } else {
- err = ccrsa_eme_pkcs1v15_decode(&size, CFDataGetMutableBytePtr(result),
- CFDataGetLength(cc_result), (cc_unit *)CFDataGetBytePtr(cc_result));
- }
- require_noerr_action_quiet(err, out, (CFReleaseNull(result),
- SecError(errSecParam, error, CFSTR("RSAdecrypt wrong input (err %d)"), err)));
- CFDataSetLength(result, size);
- out:
- CFReleaseSafe(cc_result);
- });
- return result;
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- return SecKeyRSACopyEncryptedWithPadding(context, NULL, in1, error);
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- return SecKeyRSACopyDecryptedWithPadding(context, NULL, in1, error);
-}
-
-#define RSA_OAEP_CRYPT_ADAPTOR(name, di) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyRSACopyEncryptedWithPadding(context, di, in1, error); \
-} \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## name( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyRSACopyDecryptedWithPadding(context, di, in1, error); \
-}
-
-RSA_OAEP_CRYPT_ADAPTOR(SHA1, ccsha1_di());
-RSA_OAEP_CRYPT_ADAPTOR(SHA224, ccsha224_di());
-RSA_OAEP_CRYPT_ADAPTOR(SHA256, ccsha256_di());
-RSA_OAEP_CRYPT_ADAPTOR(SHA384, ccsha384_di());
-RSA_OAEP_CRYPT_ADAPTOR(SHA512, ccsha512_di());
-
-#undef RSA_OAEP_CRYPT_ADAPTOR
-
-const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize = CFSTR("requestedSize");
-const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo = CFSTR("sharedInfo");
-
-static CFTypeRef SecKeyECDHCopyX963Result(SecKeyOperationContext *context, const struct ccdigest_info *di,
- CFTypeRef in1, CFTypeRef params, CFErrorRef *error) {
- CFTypeRef result = NULL;
- require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, in1, NULL, error), out);
-
- if (context->mode == kSecKeyOperationModePerform) {
- // Parse params.
- CFTypeRef value = NULL;
- CFIndex requestedSize = 0;
- require_action_quiet((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterRequestedSize)) != NULL
- && CFGetTypeID(value) == CFNumberGetTypeID() &&
- CFNumberGetValue(value, kCFNumberCFIndexType, &requestedSize), out,
- SecError(errSecParam, error, CFSTR("kSecKeyKeyExchangeParameterRequestedSize is missing")));
- size_t sharedInfoLength = 0;
- const void *sharedInfo = NULL;
- if ((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterSharedInfo)) != NULL &&
- CFGetTypeID(value) == CFDataGetTypeID()) {
- sharedInfo = CFDataGetBytePtr(value);
- sharedInfoLength = CFDataGetLength(value);
- }
-
- CFMutableDataRef kdfResult = CFDataCreateMutableWithScratch(kCFAllocatorDefault, requestedSize);
- int err = ccansikdf_x963(di, CFDataGetLength(result), CFDataGetBytePtr(result), sharedInfoLength, sharedInfo,
- requestedSize, CFDataGetMutableBytePtr(kdfResult));
- CFAssignRetained(result, kdfResult);
- require_noerr_action_quiet(err, out, (CFReleaseNull(result),
- SecError(errSecParam, error, CFSTR("ECDHKeyExchange wrong input (%d)"), err)));
- }
-out:
- return result;
-}
-
-#define ECDH_X963_ADAPTOR(hashname, di, cofactor) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDH ## cofactor ## X963 ## hashname( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDHKeyExchange ## cofactor); \
- return SecKeyECDHCopyX963Result(context, di, in1, in2, error); \
-}
-
-ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Standard)
-ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Standard)
-ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Standard)
-ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Standard)
-ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Standard)
-ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Cofactor)
-ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Cofactor)
-ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Cofactor)
-ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Cofactor)
-ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Cofactor)
-
-#undef ECDH_X963_ADAPTOR
-
-// Extract number value of either CFNumber or CFString.
-static CFIndex SecKeyGetCFIndexFromRef(CFTypeRef ref) {
- CFIndex result = 0;
- if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
- if (!CFNumberGetValue(ref, kCFNumberCFIndexType, &result)) {
- result = 0;
- }
- } else if (CFGetTypeID(ref) == CFStringGetTypeID()) {
- result = CFStringGetIntValue(ref);
- }
- return result;
-}
-
-typedef CFDataRef (*SecKeyECIESKeyExchangeCopyResult)(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm, bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV, CFErrorRef *error);
-typedef Boolean (*SecKeyECIESEncryptCopyResult)(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result, CFErrorRef *error);
-typedef CFDataRef SecKeyECIESDecryptCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error);
-
-static CFTypeRef SecKeyECIESCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
- SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
- SecKeyECIESEncryptCopyResult encryptCopyResult, bool variableIV,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFDictionaryRef parameters = NULL;
- SecKeyRef ephemeralPrivateKey = NULL, ephemeralPublicKey = NULL;
- CFDataRef pubKeyData = NULL, ephemeralPubKeyData = NULL, keyExchangeResult = NULL;
- CFTypeRef result = NULL;
- SecKeyRef originalKey = context->key;
- CFMutableDataRef ciphertext = NULL;
-
- require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
- SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
-
- // Generate ephemeral key.
- require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
- CFAssignRetained(parameters, CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- kSecAttrKeyType, CFDictionaryGetValue(parameters, kSecAttrKeyType),
- kSecAttrKeySizeInBits, CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits),
- NULL));
- require_quiet(ephemeralPrivateKey = SecKeyCreateRandomKey(parameters, error), out);
- require_action_quiet(ephemeralPublicKey = SecKeyCopyPublicKey(ephemeralPrivateKey), out,
- SecError(errSecParam, error, CFSTR("Unable to get public key from generated ECkey")));
- require_quiet(ephemeralPubKeyData = SecKeyCopyExternalRepresentation(ephemeralPublicKey, error), out);
-
- context->key = ephemeralPrivateKey;
- require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, true,
- ephemeralPubKeyData, pubKeyData, variableIV, error), out);
- if (context->mode == kSecKeyOperationModePerform) {
- // Encrypt input data using AES-GCM.
- ciphertext = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, ephemeralPubKeyData);
- require_quiet(encryptCopyResult(keyExchangeResult, in1, ciphertext, error), out);
- result = CFRetain(ciphertext);
- } else {
- result = CFRetain(keyExchangeResult);
- }
-
-out:
- CFReleaseSafe(parameters);
- CFReleaseSafe(ephemeralPrivateKey);
- CFReleaseSafe(ephemeralPublicKey);
- CFReleaseSafe(pubKeyData);
- CFReleaseSafe(ephemeralPubKeyData);
- CFReleaseSafe(keyExchangeResult);
- CFReleaseSafe(ciphertext);
- context->key = originalKey;
- return result;
-}
-
-static CFTypeRef SecKeyECIESCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
- SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
- SecKeyECIESDecryptCopyResult decryptCopyResult, bool variableIV,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFTypeRef result = NULL;
- CFDictionaryRef parameters = NULL;
- CFDataRef ephemeralPubKeyData = NULL, keyExchangeResult = NULL, pubKeyData = NULL;
- SecKeyRef pubKey = NULL;
- CFDataRef ciphertext = NULL;
- const UInt8 *ciphertextBuffer = NULL;
- CFIndex keySize = 0;
-
- require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
- SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
-
- if (context->mode == kSecKeyOperationModePerform) {
- // Extract ephemeral public key from the packet.
- keySize = (SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits)) + 7) / 8;
- require_action_quiet(CFDataGetLength(in1) >= keySize * 2 + 1, out,
- SecError(errSecParam, error, CFSTR("%@: too small input packet for ECIES decrypt"), context->key));
- ciphertextBuffer = CFDataGetBytePtr(in1);
- ephemeralPubKeyData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, keySize * 2 + 1, kCFAllocatorNull);
- ciphertextBuffer += keySize * 2 + 1;
-
- require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
- SecError(errSecParam, error, CFSTR("%@: Unable to get public key"), context->key));
- require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
- }
-
- // Perform keyExchange operation.
- require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, false,
- ephemeralPubKeyData, pubKeyData, variableIV, error), out);
- if (context->mode == kSecKeyOperationModePerform) {
- // Decrypt ciphertext using AES-GCM.
- ciphertext = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, CFDataGetLength(in1) - (keySize * 2 + 1),
- kCFAllocatorNull);
- require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, error), out);
- } else {
- result = CFRetain(keyExchangeResult);
- }
-
-out:
- CFReleaseSafe(parameters);
- CFReleaseSafe(ephemeralPubKeyData);
- CFReleaseSafe(keyExchangeResult);
- CFReleaseSafe(pubKeyData);
- CFReleaseSafe(pubKey);
- CFReleaseSafe(ciphertext);
- return result;
-}
-
-static const CFIndex kSecKeyIESTagLength = 16;
-static const UInt8 kSecKeyIESIV[16] = { 0 };
-
-static CFDataRef SecKeyECIESKeyExchangeKDFX963CopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
- bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
- CFErrorRef *error) {
- CFDictionaryRef parameters = NULL;
- CFNumberRef keySizeRef = NULL;
- CFDataRef result = NULL;
-
- CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
- context->operation = kSecKeyOperationTypeKeyExchange;
-
- if (context->mode == kSecKeyOperationModePerform) {
- // Use 128bit AES for EC keys <= 256bit, 256bit AES for larger keys.
- CFIndex keySize = ((CFDataGetLength(pubKey) - 1) / 2) * 8;
- keySize = (keySize > 256) ? (256 / 8) : (128 / 8);
-
- if (variableIV) {
- keySize += sizeof(kSecKeyIESIV);
- }
-
- // Generate shared secret using KDF.
- keySizeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &keySize);
- parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
- kSecKeyKeyExchangeParameterSharedInfo, ephemeralPubKey,
- kSecKeyKeyExchangeParameterRequestedSize, keySizeRef,
- NULL);
- }
-
- result = SecKeyRunAlgorithmAndCopyResult(context, encrypt ? pubKey : ephemeralPubKey, parameters, error);
- if (context->mode == kSecKeyOperationModePerform && !variableIV && result != NULL) {
- // Append all-zero IV to the result.
- CFMutableDataRef data = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, result);
- CFDataAppendBytes(data, kSecKeyIESIV, sizeof(kSecKeyIESIV));
- CFAssignRetained(result, data);
- }
- CFReleaseSafe(parameters);
- CFReleaseSafe(keySizeRef);
- return result;
-}
-
-static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result,
- CFErrorRef *error) {
- Boolean res = FALSE;
- CFIndex prefix = CFDataGetLength(result);
- CFDataSetLength(result, prefix + CFDataGetLength(inData) + kSecKeyIESTagLength);
- UInt8 *resultBuffer = CFDataGetMutableBytePtr(result) + prefix;
- UInt8 *tagBuffer = resultBuffer + CFDataGetLength(inData);
- CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
- const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
- require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
- aesKeySize, CFDataGetBytePtr(keyExchangeResult),
- sizeof(kSecKeyIESIV), ivBuffer,
- 0, NULL,
- CFDataGetLength(inData), CFDataGetBytePtr(inData),
- resultBuffer, kSecKeyIESTagLength, tagBuffer) == 0, out,
- SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm encrypt data")));
- res = TRUE;
-out:
- return res;
-}
-
-static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
- CFDataRef result = NULL;
- CFMutableDataRef plaintext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData) - kSecKeyIESTagLength);
- CFMutableDataRef tag = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), kSecKeyIESTagLength);
- CFDataGetBytes(inData, CFRangeMake(CFDataGetLength(inData) - kSecKeyIESTagLength, kSecKeyIESTagLength),
- CFDataGetMutableBytePtr(tag));
- CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
- const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
- require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
- aesKeySize, CFDataGetBytePtr(keyExchangeResult),
- sizeof(kSecKeyIESIV), ivBuffer,
- 0, NULL,
- CFDataGetLength(plaintext), CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(plaintext),
- kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
- SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm decrypt data")));
- result = CFRetain(plaintext);
-out:
- CFReleaseSafe(plaintext);
- CFReleaseSafe(tag);
- return result;
-}
-
-#define ECIES_X963_ADAPTOR(hashname, cofactor, namepart, variableIV) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIES ## cofactor ## namepart ## hashname( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyECIESCopyEncryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
- SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESEncryptAESGCMCopyResult, variableIV, in1, in2, error); \
-} \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES ## cofactor ## namepart ## hashname( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
- SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESDecryptAESGCMCopyResult, variableIV, in1, in2, error); \
-}
-
-ECIES_X963_ADAPTOR(SHA1, Standard, X963, false)
-ECIES_X963_ADAPTOR(SHA224, Standard, X963, false)
-ECIES_X963_ADAPTOR(SHA256, Standard, X963, false)
-ECIES_X963_ADAPTOR(SHA384, Standard, X963, false)
-ECIES_X963_ADAPTOR(SHA512, Standard, X963, false)
-ECIES_X963_ADAPTOR(SHA1, Cofactor, X963, false)
-ECIES_X963_ADAPTOR(SHA224, Cofactor, X963, false)
-ECIES_X963_ADAPTOR(SHA256, Cofactor, X963, false)
-ECIES_X963_ADAPTOR(SHA384, Cofactor, X963, false)
-ECIES_X963_ADAPTOR(SHA512, Cofactor, X963, false)
-
-ECIES_X963_ADAPTOR(SHA224, Standard, VariableIVX963, true)
-ECIES_X963_ADAPTOR(SHA256, Standard, VariableIVX963, true)
-ECIES_X963_ADAPTOR(SHA384, Standard, VariableIVX963, true)
-ECIES_X963_ADAPTOR(SHA512, Standard, VariableIVX963, true)
-ECIES_X963_ADAPTOR(SHA224, Cofactor, VariableIVX963, true)
-ECIES_X963_ADAPTOR(SHA256, Cofactor, VariableIVX963, true)
-ECIES_X963_ADAPTOR(SHA384, Cofactor, VariableIVX963, true)
-ECIES_X963_ADAPTOR(SHA512, Cofactor, VariableIVX963, true)
-
-#undef ECIES_X963_ADAPTOR
-
-static CFDataRef SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
- bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
- CFErrorRef *error) {
- CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
- context->operation = kSecKeyOperationTypeKeyExchange;
- CFMutableDataRef result = (CFMutableDataRef)SecKeyRunAlgorithmAndCopyResult(context, ephemeralPubKey, NULL, error);
- if (result != NULL && context->mode == kSecKeyOperationModePerform) {
- const struct ccdigest_info *di = ccsha256_di();
- ccdigest_di_decl(di, ctx);
- ccdigest_init(di, ctx);
- ccdigest_update(di, ctx, CFDataGetLength(result), CFDataGetBytePtr(result));
- ccdigest_update(di, ctx, CFDataGetLength(ephemeralPubKey), CFDataGetBytePtr(ephemeralPubKey));
- ccdigest_update(di, ctx, CFDataGetLength(pubKey), CFDataGetBytePtr(pubKey));
- CFAssignRetained(result, CFDataCreateMutableWithScratch(kCFAllocatorDefault, di->output_size));
- ccdigest_final(di, ctx, CFDataGetMutableBytePtr(result));
- }
- return result;
-}
-
-static CFDataRef SecKeyECIESDecryptAESCBCCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
- CFMutableDataRef result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData));
- cccbc_one_shot(ccaes_cbc_decrypt_mode(),
- CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
- NULL, CFDataGetLength(keyExchangeResult) / CCAES_BLOCK_SIZE,
- CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(result));
- return result;
-}
-
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys(
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchangeStandard,
- SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult,
- SecKeyECIESDecryptAESCBCCopyResult, false,
- in1, in2, error);
-}
-
-static CFTypeRef SecKeyRSAAESGCMCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFTypeRef result = NULL;
- CFDictionaryRef parameters = NULL;
- CFDataRef pubKeyData = NULL, wrappedKey = NULL, sessionKey = NULL;
- CFMutableDataRef ciphertext = NULL;
-
- require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
- SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
-
- CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
- require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
- result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
-
- // Generate session key. Use 128bit AES for RSA keys < 4096bit, 256bit AES for larger keys.
- require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
- CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
- require_action_quiet(sessionKey = CFDataCreateWithRandomBytes((keySize >= 4096) ? (256 / 8) : (128 / 8)), out,
- SecError(errSecParam, error, CFSTR("Failed to generate session key")));
-
- // Encrypt session key using wrapping algorithm and store at the beginning of the result packet.
- require_action_quiet(wrappedKey = SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error), out,
- CFReleaseNull(result));
- ciphertext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(wrappedKey) + CFDataGetLength(in1) + kSecKeyIESTagLength);
- UInt8 *resultBuffer = CFDataGetMutableBytePtr(ciphertext);
- CFDataGetBytes(wrappedKey, CFRangeMake(0, CFDataGetLength(wrappedKey)), resultBuffer);
- resultBuffer += CFDataGetLength(wrappedKey);
-
- // Encrypt input data using AES-GCM.
- UInt8 *tagBuffer = resultBuffer + CFDataGetLength(in1);
- require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
- CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
- sizeof(kSecKeyIESIV), kSecKeyIESIV,
- CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
- CFDataGetLength(in1), CFDataGetBytePtr(in1), resultBuffer,
- kSecKeyIESTagLength, tagBuffer) == 0, out,
- SecError(errSecParam, error, CFSTR("RSAWRAP: Failed to aes-gcm encrypt data")));
- result = CFRetain(ciphertext);
-
-out:
- CFReleaseSafe(parameters);
- CFReleaseSafe(pubKeyData);
- CFReleaseSafe(wrappedKey);
- CFReleaseSafe(sessionKey);
- CFReleaseSafe(ciphertext);
- return result;
-}
-
-static CFTypeRef SecKeyRSAAESGCMCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
- CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
- CFTypeRef result = NULL;
- CFDictionaryRef parameters = NULL;
- CFMutableDataRef plaintext = NULL, tag = NULL;
- CFDataRef pubKeyData = NULL, sessionKey = NULL;
- SecKeyRef pubKey = NULL;
-
- require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
- SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
- require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
-
- CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
- require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
- result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
-
- // Extract encrypted session key.
- require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
- SecError(errSecParam, error, CFSTR("%@: unable to get public key"), context->key));
- require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
-
- CFIndex wrappedKeySize = SecKeyGetBlockSize(context->key);
- require_action_quiet(CFDataGetLength(in1) >= wrappedKeySize + kSecKeyIESTagLength, out,
- SecError(errSecParam, error, CFSTR("RSA-WRAP too short input data")));
- sessionKey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(in1), wrappedKeySize, kCFAllocatorNull);
-
- // Decrypt session key.
- CFAssignRetained(sessionKey, SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error));
- require_quiet(sessionKey, out);
- CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
- keySize = (keySize >= 4096) ? (256 / 8) : (128 / 8);
- require_action_quiet(CFDataGetLength(sessionKey) == keySize, out,
- SecError(errSecParam, error, CFSTR("RSA-WRAP bad ciphertext, unexpected session key size")));
-
- // Decrypt ciphertext using AES-GCM.
- plaintext = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), CFDataGetLength(in1) - wrappedKeySize - kSecKeyIESTagLength);
- tag = CFDataCreateMutableWithScratch(kCFAllocatorDefault, kSecKeyIESTagLength);
- CFDataGetBytes(in1, CFRangeMake(CFDataGetLength(in1) - kSecKeyIESTagLength, kSecKeyIESTagLength),
- CFDataGetMutableBytePtr(tag));
- const UInt8 *ciphertextBuffer = CFDataGetBytePtr(in1);
- ciphertextBuffer += wrappedKeySize;
- require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
- CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
- sizeof(kSecKeyIESIV), kSecKeyIESIV,
- CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
- CFDataGetLength(plaintext), ciphertextBuffer, CFDataGetMutableBytePtr(plaintext),
- kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
- SecError(errSecParam, error, CFSTR("RSA-WRAP: Failed to aes-gcm decrypt data")));
- result = CFRetain(plaintext);
-
-out:
- CFReleaseSafe(parameters);
- CFReleaseSafe(sessionKey);
- CFReleaseSafe(tag);
- CFReleaseSafe(pubKeyData);
- CFReleaseSafe(pubKey);
- CFReleaseSafe(plaintext);
- return result;
-}
-
-#define RSA_OAEP_AESGCM_ADAPTOR(hashname) \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyRSAAESGCMCopyEncryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
-} \
-static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
- SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
- return SecKeyRSAAESGCMCopyDecryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
-}
-
-RSA_OAEP_AESGCM_ADAPTOR(SHA1)
-RSA_OAEP_AESGCM_ADAPTOR(SHA224)
-RSA_OAEP_AESGCM_ADAPTOR(SHA256)
-RSA_OAEP_AESGCM_ADAPTOR(SHA384)
-RSA_OAEP_AESGCM_ADAPTOR(SHA512)
-
-#undef RSA_OAEP_AESGCM_ADAPTOR
-
-SecKeyAlgorithmAdaptor SecKeyGetAlgorithmAdaptor(SecKeyOperationType operation, SecKeyAlgorithm algorithm) {
- static CFDictionaryRef adaptors[kSecKeyOperationTypeCount];
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- const void *signKeys[] = {
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
-
- kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
-
- kSecKeyAlgorithmRSASignatureRaw,
- kSecKeyAlgorithmRSASignatureRawCCUnit,
-
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
-
- kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
-
- kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
-
- kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
- };
- const void *signValues[] = {
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA1,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA512,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15Raw,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15MD5,
-
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA1,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA224,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA256,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA384,
- SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
- };
- check_compile_time(array_size(signKeys) == array_size(signValues));
- adaptors[kSecKeyOperationTypeSign] = CFDictionaryCreate(kCFAllocatorDefault, signKeys, signValues,
- array_size(signKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
-
- const void *verifyKeys[] = {
- kSecKeyAlgorithmRSASignatureRaw,
-
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
- kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
-
- kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
- kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
-
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
- kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
-
- kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
- kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
-
- kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
- kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
-
- kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
- kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
- };
- const void *verifyValues[] = {
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw,
-
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA1,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA512,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15Raw,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15MD5,
-
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA1,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA224,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA256,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA384,
- SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
- SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
- };
- check_compile_time(array_size(verifyKeys) == array_size(verifyValues));
- adaptors[kSecKeyOperationTypeVerify] = CFDictionaryCreate(kCFAllocatorDefault, verifyKeys, verifyValues,
- array_size(verifyKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
-
- const void *encryptKeys[] = {
- kSecKeyAlgorithmRSAEncryptionRaw,
- kSecKeyAlgorithmRSAEncryptionRawCCUnit,
-
- kSecKeyAlgorithmRSAEncryptionPKCS1,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
-
- kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
- };
- const void *encryptValues[] = {
- SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
- SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
-
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512AESGCM,
-
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA1,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA1,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA512,
- };
- check_compile_time(array_size(encryptKeys) == array_size(encryptValues));
- adaptors[kSecKeyOperationTypeEncrypt] = CFDictionaryCreate(kCFAllocatorDefault, encryptKeys, encryptValues,
- array_size(encryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
-
- const void *decryptKeys[] = {
- kSecKeyAlgorithmRSAEncryptionRaw,
- kSecKeyAlgorithmRSAEncryptionRawCCUnit,
-
- kSecKeyAlgorithmRSAEncryptionPKCS1,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
-
- kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
- kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
- kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
-
- kSecKeyAlgorithmECIESEncryptionAKSSmartCard,
- };
- const void *decryptValues[] = {
- SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
- SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
-
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384AESGCM,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512AESGCM,
-
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA1,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA1,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys,
- };
- check_compile_time(array_size(decryptKeys) == array_size(decryptValues));
- adaptors[kSecKeyOperationTypeDecrypt] = CFDictionaryCreate(kCFAllocatorDefault, decryptKeys, decryptValues,
- array_size(decryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
-
- const void *keyExchangeKeys[] = {
- kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1,
- kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224,
- kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256,
- kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384,
- kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512,
-
- kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1,
- kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224,
- kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256,
- kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384,
- kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512,
- };
- const void *keyExchangeValues[] = {
-
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA1,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA512,
-
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA1,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA224,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA256,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA384,
- SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA512,
- };
- check_compile_time(array_size(keyExchangeKeys) == array_size(keyExchangeKeys));
- adaptors[kSecKeyOperationTypeKeyExchange] = CFDictionaryCreate(kCFAllocatorDefault, keyExchangeKeys, keyExchangeValues,
- array_size(keyExchangeKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
- });
-
- return CFDictionaryGetValue(adaptors[operation], algorithm);
-}
--- /dev/null
+/*
+ * 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@
+ */
+
+/*
+ * SecKeyAdaptors.m - Implementation of assorted algorithm adaptors for SecKey.
+ * Algorithm adaptor is able to perform some transformation on provided input and calculated results and invoke
+ * underlying operation with different algorithm. Typical adaptors are message->digest or unpadded->padded.
+ * To invoke underlying operation, add algorithm to the context algorithm array and invoke SecKeyRunAlgorithmAndCopyResult().
+ */
+
+#import <Foundation/Foundation.h>
+
+#include <Security/SecBase.h>
+#include <Security/SecKeyInternal.h>
+#include <Security/SecItem.h>
+#include <Security/SecCFAllocator.h>
+
+#include <AssertMacros.h>
+#include <utilities/SecCFWrappers.h>
+#include <utilities/array_size.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFError.h>
+#include <utilities/SecBuffer.h>
+
+#include <corecrypto/ccsha1.h>
+#include <corecrypto/ccsha2.h>
+#include <corecrypto/ccmd5.h>
+#include <corecrypto/ccrsa_priv.h>
+#include <corecrypto/ccansikdf.h>
+#include <corecrypto/ccmode.h>
+#include <corecrypto/ccaes.h>
+
+#pragma mark Algorithm constants value definitions
+
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRaw = CFSTR("algid:sign:RSA:raw");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRawCCUnit = CFSTR("algid:sign:RSA:raw-cc");
+
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw = CFSTR("algid:sign:RSA:digest-PKCS1v15");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5 = CFSTR("algid:sign:RSA:digest-PKCS1v15:MD5");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA1");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA224");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA256");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA384");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA512");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA1 = CFSTR("algid:sign:RSA:digest-PSS:SHA1:SHA1:20");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA224 = CFSTR("algid:sign:RSA:digest-PSS:SHA224:SHA224:24");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA256 = CFSTR("algid:sign:RSA:digest-PSS:SHA256:SHA256:32");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA384 = CFSTR("algid:sign:RSA:digest-PSS:SHA384:SHA384:48");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA512 = CFSTR("algid:sign:RSA:digest-PSS:SHA512:SHA512:64");
+
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5 = CFSTR("algid:sign:RSA:message-PKCS1v15:MD5");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA1");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA224");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA256");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA384");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA512");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA1 = CFSTR("algid:sign:RSA:message-PSS:SHA1:SHA1:20");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA224 = CFSTR("algid:sign:RSA:message-PSS:SHA224:SHA224:24");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA256 = CFSTR("algid:sign:RSA:message-PSS:SHA256:SHA256:32");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA384 = CFSTR("algid:sign:RSA:message-PSS:SHA384:SHA384:48");
+const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA512 = CFSTR("algid:sign:RSA:message-PSS:SHA512:SHA512:64");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureRFC4754 = CFSTR("algid:sign:ECDSA:RFC4754");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962 = CFSTR("algid:sign:ECDSA:digest-X962");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA1 = CFSTR("algid:sign:ECDSA:digest-X962:SHA1");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA224 = CFSTR("algid:sign:ECDSA:digest-X962:SHA224");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA256 = CFSTR("algid:sign:ECDSA:digest-X962:SHA256");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA384 = CFSTR("algid:sign:ECDSA:digest-X962:SHA384");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA512 = CFSTR("algid:sign:ECDSA:digest-X962:SHA512");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA1 = CFSTR("algid:sign:ECDSA:message-X962:SHA1");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA224 = CFSTR("algid:sign:ECDSA:message-X962:SHA224");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA256 = CFSTR("algid:sign:ECDSA:message-X962:SHA256");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA384 = CFSTR("algid:sign:ECDSA:message-X962:SHA384");
+const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA512 = CFSTR("algid:sign:ECDSA:message-X962:SHA512");
+
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRaw = CFSTR("algid:encrypt:RSA:raw");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRawCCUnit = CFSTR("algid:encrypt:RSA:raw-cc");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionPKCS1 = CFSTR("algid:encrypt:RSA:PKCS1");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1 = CFSTR("algid:encrypt:RSA:OAEP:SHA1");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224 = CFSTR("algid:encrypt:RSA:OAEP:SHA224");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256 = CFSTR("algid:encrypt:RSA:OAEP:SHA256");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384 = CFSTR("algid:encrypt:RSA:OAEP:SHA384");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512 = CFSTR("algid:encrypt:RSA:OAEP:SHA512");
+
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA1:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA224:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA256:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA384:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA512:AESGCM");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA1:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA224:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA384:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA512:AESGCM");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA1:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA224:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA384:AESGCM");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA512:AESGCM");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA224:AESGCM-KDFIV");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM-KDFIV");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA384:AESGCM-KDFIV");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA512:AESGCM-KDFIV");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA224:AESGCM-KDFIV");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM-KDFIV");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA384:AESGCM-KDFIV");
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA512:AESGCM-KDFIV");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandard = CFSTR("algid:keyexchange:ECDH");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA1");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA224");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA256");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA384");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA512");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactor = CFSTR("algid:keyexchange:ECDHC");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA1");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA224");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA256");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA384");
+const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA512");
+
+const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionAKSSmartCard = CFSTR("algid:encrypt:ECIES:ECDH:SHA256:2PubKeys");
+
+void SecKeyOperationContextDestroy(SecKeyOperationContext *context) {
+ CFReleaseNull(context->algorithm);
+}
+
+static void PerformWithCFDataBuffer(CFIndex size, void (^operation)(uint8_t *buffer, CFDataRef data)) {
+ PerformWithBuffer(size, ^(size_t size, uint8_t *buffer) {
+ CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)buffer, size, kCFAllocatorNull);
+ operation(buffer, data);
+ CFRelease(data);
+ });
+}
+
+static CFDataRef SecKeyCopyDigestForMessage(SecKeyOperationContext *context, CFDataRef message, CFDataRef in2,
+ const struct ccdigest_info *di, CFErrorRef *error) {
+ if (context->mode == kSecKeyOperationModeCheckIfSupported) {
+ return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
+ }
+
+ __block CFTypeRef result;
+ PerformWithCFDataBuffer(di->output_size, ^(uint8_t *buffer, CFDataRef data) {
+ ccdigest(di, CFDataGetLength(message), CFDataGetBytePtr(message), buffer);
+ result = SecKeyRunAlgorithmAndCopyResult(context, data, in2, error);
+ });
+ return result;
+}
+
+static CFTypeRef SecKeyCopyECDSASignatureForDigest(SecKeyOperationContext *context, CFDataRef digest, CFDataRef in2,
+ SecKeyAlgorithm algorithm, const struct ccdigest_info *di, CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigestX962);
+ if (context->mode == kSecKeyOperationModeCheckIfSupported) {
+ return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
+ }
+
+ if (CFDataGetLength(digest) != (CFIndex)di->output_size) {
+ SecError(errSecParam, error, CFSTR("bad digest size for signing with algorithm %@"), algorithm);
+ return NULL;
+ }
+
+ return SecKeyRunAlgorithmAndCopyResult(context, digest, in2, error);
+}
+
+#define DIGEST_RSA_ADAPTORS(name, di) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessage ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigest ## name); \
+ return SecKeyCopyDigestForMessage(context, in1, in2, di, error); \
+}
+
+#define DIGEST_ECDSA_ADAPTORS(name, di) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessage ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigest ## name); \
+ return SecKeyCopyDigestForMessage(context, in1, in2, di, error); \
+} \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigest ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyCopyECDSASignatureForDigest(context, in1, in2, kSecKeyAlgorithmECDSASignatureDigest ## name, di, error); \
+}
+
+DIGEST_RSA_ADAPTORS(PKCS1v15SHA1, ccsha1_di())
+DIGEST_RSA_ADAPTORS(PKCS1v15SHA224, ccsha224_di())
+DIGEST_RSA_ADAPTORS(PKCS1v15SHA256, ccsha256_di())
+DIGEST_RSA_ADAPTORS(PKCS1v15SHA384, ccsha384_di())
+DIGEST_RSA_ADAPTORS(PKCS1v15SHA512, ccsha512_di())
+DIGEST_RSA_ADAPTORS(PKCS1v15MD5, ccmd5_di())
+DIGEST_RSA_ADAPTORS(PSSSHA1, ccsha1_di())
+DIGEST_RSA_ADAPTORS(PSSSHA224, ccsha224_di())
+DIGEST_RSA_ADAPTORS(PSSSHA256, ccsha256_di())
+DIGEST_RSA_ADAPTORS(PSSSHA384, ccsha384_di())
+DIGEST_RSA_ADAPTORS(PSSSHA512, ccsha512_di())
+DIGEST_ECDSA_ADAPTORS(X962SHA1, ccsha1_di())
+DIGEST_ECDSA_ADAPTORS(X962SHA224, ccsha224_di())
+DIGEST_ECDSA_ADAPTORS(X962SHA256, ccsha256_di())
+DIGEST_ECDSA_ADAPTORS(X962SHA384, ccsha384_di())
+DIGEST_ECDSA_ADAPTORS(X962SHA512, ccsha512_di())
+
+#undef DIGEST_RSA_ADAPTORS
+#undef DIGEST_ECDSA_ADAPTORS
+
+static CFDataRef SecKeyRSACopyBigEndianToCCUnit(CFDataRef bigEndian, size_t size) {
+ CFMutableDataRef result = NULL;
+ if (bigEndian != NULL) {
+ size_t dataSize = CFDataGetLength(bigEndian);
+ if (dataSize > size) {
+ size = dataSize;
+ }
+ result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, ccrsa_sizeof_n_from_size(size));
+ ccn_read_uint(ccn_nof_size(size), (cc_unit *)CFDataGetMutableBytePtr(result), dataSize, CFDataGetBytePtr(bigEndian));
+ }
+ return result;
+}
+
+static void PerformWithBigEndianToCCUnit(CFDataRef bigEndian, size_t size, void (^operation)(CFDataRef ccunits)) {
+ if (bigEndian == NULL) {
+ return operation(NULL);
+ }
+ size_t dataSize = CFDataGetLength(bigEndian);
+ if (dataSize > size) {
+ size = dataSize;
+ }
+ PerformWithCFDataBuffer(ccrsa_sizeof_n_from_size(size), ^(uint8_t *buffer, CFDataRef data) {
+ ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, dataSize, CFDataGetBytePtr(bigEndian));
+ operation(data);
+ });
+}
+
+static CFDataRef SecKeyRSACopyCCUnitToBigEndian(CFDataRef ccunits, size_t size) {
+ CFMutableDataRef result = NULL;
+ if (ccunits != NULL) {
+ cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
+ const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
+ result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, size);
+ ccn_write_uint_padded(n, s, CFDataGetLength(result), CFDataGetMutableBytePtr(result));
+ }
+ return result;
+}
+
+static void PerformWithCCUnitToBigEndian(CFDataRef ccunits, size_t size, void (^operation)(CFDataRef bigEndian)) {
+ if (ccunits == NULL) {
+ return operation(NULL);
+ }
+ PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
+ cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
+ const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
+ ccn_write_uint_padded(n, s, size, buffer);
+ operation(data);
+ });
+}
+
+static CFTypeRef SecKeyRSACopyEMSASignature(SecKeyOperationContext *context,
+ CFDataRef in1, CFDataRef in2, CFErrorRef *error, bool pss, const struct ccdigest_info *di) {
+ CFDictionaryRef parameters = NULL;
+ __block CFTypeRef result = NULL;
+
+ require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
+ SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
+ CFReleaseNull(parameters);
+
+ if (pss) {
+ // Verify that algorithm is compatible with the modulus size.
+ size_t blockSize = SecKeyGetBlockSize(context->key);
+ require_action_quiet(blockSize >= di->output_size * 2 + 2, out,
+ SecError(errSecParam, error, CFSTR("algorithm %@ incompatible with %lubit RSA key"),
+ CFArrayGetValueAtIndex(context->algorithm, CFArrayGetCount(context->algorithm) - 1),
+ blockSize * 8));
+ }
+
+ if (!pss && di != NULL) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw);
+ }
+
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
+ if (context->mode == kSecKeyOperationModeCheckIfSupported) {
+ return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
+ }
+
+ size_t size = SecKeyGetBlockSize(context->key);
+ if (size == 0) {
+ SecError(errSecParam, error, CFSTR("expecting RSA key"));
+ return NULL;
+ }
+ PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
+ NSMutableData *s = [NSMutableData dataWithLength:size];
+ require_action_quiet(s != nil, out, SecError(errSecAllocate, error, CFSTR("out of memory")));
+ if (pss) {
+ NSMutableData *salt = [NSMutableData dataWithLength:di->output_size];
+ require_action_quiet(salt != nil, out, SecError(errSecAllocate, error, CFSTR("out of memory")));
+ int err = ccrng_generate(ccrng_seckey, di->output_size, salt.mutableBytes);
+ require_noerr_action_quiet(err, out, SecError(errSecInternal, error, CFSTR("PSS salt gen fail (%zu bytes), err %d"),
+ di->output_size, err));
+ err = ccrsa_emsa_pss_encode(di, di, di->output_size, salt.bytes,
+ CFDataGetLength(in1), CFDataGetBytePtr(in1), size * 8 - 1, s.mutableBytes);
+ require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSASSA-PSS incompatible algorithm for key size")));
+ } else {
+ int err = ccrsa_emsa_pkcs1v15_encode(size, s.mutableBytes, CFDataGetLength(in1), CFDataGetBytePtr(in1), di ? di->oid : NULL);
+ require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSAsign wrong input data length")));
+ }
+ ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, size, s.bytes);
+ require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
+ CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
+ out:;
+ });
+
+out:
+ CFReleaseSafe(parameters);
+ return result;
+}
+
+#define RSA_EMSA_SIGN_ADAPTOR(name, pss, di) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigest ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyRSACopyEMSASignature(context, in1, in2, error, pss, di); \
+}
+
+RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA1, false, ccsha1_di())
+RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA224, false, ccsha224_di())
+RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA256, false, ccsha256_di())
+RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA384, false, ccsha384_di())
+RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA512, false, ccsha512_di())
+RSA_EMSA_SIGN_ADAPTOR(PKCS1v15Raw, false, NULL)
+RSA_EMSA_SIGN_ADAPTOR(PKCS1v15MD5, false, ccmd5_di())
+RSA_EMSA_SIGN_ADAPTOR(PSSSHA1, true, ccsha1_di())
+RSA_EMSA_SIGN_ADAPTOR(PSSSHA224, true, ccsha224_di())
+RSA_EMSA_SIGN_ADAPTOR(PSSSHA256, true, ccsha256_di())
+RSA_EMSA_SIGN_ADAPTOR(PSSSHA384, true, ccsha384_di())
+RSA_EMSA_SIGN_ADAPTOR(PSSSHA512, true, ccsha512_di())
+
+#undef RSA_EMSA_SIGN_ADAPTOR
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ if (context->mode == kSecKeyOperationModeCheckIfSupported) {
+ return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
+ }
+
+ __block CFTypeRef result = NULL;
+ PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
+ result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, in2, error);
+ if (result != NULL) {
+ CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
+ }
+ });
+ return result;
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ if (context->mode == kSecKeyOperationModeCheckIfSupported) {
+ return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
+ }
+
+ __block CFTypeRef result = NULL;
+ PerformWithCCUnitToBigEndian(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef bigEndian) {
+ result = SecKeyRunAlgorithmAndCopyResult(context, bigEndian, in2, error);
+ if (result != NULL) {
+ CFAssignRetained(result, SecKeyRSACopyBigEndianToCCUnit(result, SecKeyGetBlockSize(context->key)));
+ }
+ });
+ return result;
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
+ return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRaw);
+ return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
+}
+
+static bool SecKeyVerifyBadSignature(CFErrorRef *error) {
+ return SecError(errSecVerifyFailed, error, CFSTR("RSA signature verification failed, no match"));
+}
+
+static CFTypeRef SecKeyRSAVerifyAdaptorCopyResult(SecKeyOperationContext *context, CFTypeRef signature, CFErrorRef *error,
+ Boolean (^verifyBlock)(CFDataRef decrypted)) {
+ CFTypeRef result = NULL;
+ context->operation = kSecKeyOperationTypeDecrypt;
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
+ result = SecKeyRunAlgorithmAndCopyResult(context, signature, NULL, error);
+ if (context->mode == kSecKeyOperationModePerform && result != NULL) {
+ if (verifyBlock(result)) {
+ CFRetainAssign(result, kCFBooleanTrue);
+ } else {
+ CFRetainAssign(result, kCFBooleanFalse);
+ SecKeyVerifyBadSignature(error);
+ }
+ }
+ return result;
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) {
+ // Skip zero-padding from the beginning of the decrypted signature.
+ const UInt8 *data = CFDataGetBytePtr(decrypted);
+ CFIndex length = CFDataGetLength(decrypted);
+ while (*data == 0x00 && length > 0) {
+ data++;
+ length--;
+ }
+ // The rest of the decrypted signature must be the same as input data.
+ return length == CFDataGetLength(in1) && memcmp(CFDataGetBytePtr(in1), data, length) == 0;
+ });
+};
+
+#define PKCS1v15_EMSA_VERIFY_ADAPTOR(name, oid) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15 ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) { \
+ return ccrsa_emsa_pkcs1v15_verify(CFDataGetLength(decrypted), \
+ (uint8_t *)CFDataGetBytePtr(decrypted), \
+ CFDataGetLength(in1), CFDataGetBytePtr(in1), oid) == 0; \
+ }); \
+}
+
+#define PSS_EMSA_VERIFY_ADAPTOR(name, di) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSS ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) { \
+ return ccrsa_emsa_pss_decode(di, di, di->output_size, CFDataGetLength(in1), CFDataGetBytePtr(in1), \
+ CFDataGetLength(decrypted) * 8 - 1, (uint8_t *)CFDataGetBytePtr(decrypted)) == 0; \
+ }); \
+}
+
+PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA1, ccsha1_di()->oid)
+PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA224, ccsha224_di()->oid)
+PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA256, ccsha256_di()->oid)
+PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA384, ccsha384_di()->oid)
+PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA512, ccsha512_di()->oid)
+PKCS1v15_EMSA_VERIFY_ADAPTOR(Raw, NULL)
+PKCS1v15_EMSA_VERIFY_ADAPTOR(MD5, ccmd5_di()->oid)
+
+PSS_EMSA_VERIFY_ADAPTOR(SHA1, ccsha1_di())
+PSS_EMSA_VERIFY_ADAPTOR(SHA224, ccsha224_di())
+PSS_EMSA_VERIFY_ADAPTOR(SHA256, ccsha256_di())
+PSS_EMSA_VERIFY_ADAPTOR(SHA384, ccsha384_di())
+PSS_EMSA_VERIFY_ADAPTOR(SHA512, ccsha512_di())
+
+#undef PKCS1v15_EMSA_VERIFY_ADAPTOR
+#undef PSS_EMSA_VERIFY_ADAPTOR
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
+ return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
+ return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
+}
+
+static CFTypeRef SecKeyRSACopyEncryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
+ CFDataRef in1, CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
+ size_t size = SecKeyGetBlockSize(context->key);
+ size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
+ if (size < minSize) {
+ return kCFNull;
+ }
+ if (context->mode == kSecKeyOperationModeCheckIfSupported) {
+ return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
+ }
+
+ __block CFTypeRef result = NULL;
+ PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
+ int err;
+ if (di != NULL) {
+ err = ccrsa_oaep_encode(di, ccrng_seckey, size, (cc_unit *)buffer,
+ CFDataGetLength(in1), CFDataGetBytePtr(in1));
+ } else {
+ err = ccrsa_eme_pkcs1v15_encode(ccrng_seckey, size, (cc_unit *)buffer,
+ CFDataGetLength(in1), CFDataGetBytePtr(in1));
+ }
+ require_noerr_action_quiet(err, out, SecError(errSecParam, error,
+ CFSTR("RSAencrypt wrong input size (err %d)"), err));
+ require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
+ CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
+ out:;
+ });
+ return result;
+}
+
+static CFTypeRef SecKeyRSACopyDecryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
+ CFDataRef in1, CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
+ size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
+ if (SecKeyGetBlockSize(context->key) < minSize) {
+ return kCFNull;
+ }
+ if (context->mode == kSecKeyOperationModeCheckIfSupported) {
+ return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
+ }
+
+ __block CFMutableDataRef result = NULL;
+ PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
+ CFDataRef cc_result = NULL;
+ require_quiet(cc_result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, NULL, error), out);
+ size_t size = CFDataGetLength(cc_result);
+ result = CFDataCreateMutableWithScratch(NULL, size);
+ int err;
+ if (di != NULL) {
+ err = ccrsa_oaep_decode(di, &size, CFDataGetMutableBytePtr(result),
+ CFDataGetLength(cc_result), (cc_unit *)CFDataGetBytePtr(cc_result));
+ } else {
+ err = ccrsa_eme_pkcs1v15_decode(&size, CFDataGetMutableBytePtr(result),
+ CFDataGetLength(cc_result), (cc_unit *)CFDataGetBytePtr(cc_result));
+ }
+ require_noerr_action_quiet(err, out, (CFReleaseNull(result),
+ SecError(errSecParam, error, CFSTR("RSAdecrypt wrong input (err %d)"), err)));
+ CFDataSetLength(result, size);
+ out:
+ CFReleaseSafe(cc_result);
+ });
+ return result;
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ return SecKeyRSACopyEncryptedWithPadding(context, NULL, in1, error);
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ return SecKeyRSACopyDecryptedWithPadding(context, NULL, in1, error);
+}
+
+#define RSA_OAEP_CRYPT_ADAPTOR(name, di) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyRSACopyEncryptedWithPadding(context, di, in1, error); \
+} \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## name( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyRSACopyDecryptedWithPadding(context, di, in1, error); \
+}
+
+RSA_OAEP_CRYPT_ADAPTOR(SHA1, ccsha1_di());
+RSA_OAEP_CRYPT_ADAPTOR(SHA224, ccsha224_di());
+RSA_OAEP_CRYPT_ADAPTOR(SHA256, ccsha256_di());
+RSA_OAEP_CRYPT_ADAPTOR(SHA384, ccsha384_di());
+RSA_OAEP_CRYPT_ADAPTOR(SHA512, ccsha512_di());
+
+#undef RSA_OAEP_CRYPT_ADAPTOR
+
+const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize = CFSTR("requestedSize");
+const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo = CFSTR("sharedInfo");
+
+static CFTypeRef SecKeyECDHCopyX963Result(SecKeyOperationContext *context, const struct ccdigest_info *di,
+ CFTypeRef in1, CFTypeRef params, CFErrorRef *error) {
+ CFTypeRef result = NULL;
+ require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, in1, NULL, error), out);
+
+ if (context->mode == kSecKeyOperationModePerform) {
+ // Parse params.
+ CFTypeRef value = NULL;
+ CFIndex requestedSize = 0;
+ require_action_quiet((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterRequestedSize)) != NULL
+ && CFGetTypeID(value) == CFNumberGetTypeID() &&
+ CFNumberGetValue(value, kCFNumberCFIndexType, &requestedSize), out,
+ SecError(errSecParam, error, CFSTR("kSecKeyKeyExchangeParameterRequestedSize is missing")));
+ size_t sharedInfoLength = 0;
+ const void *sharedInfo = NULL;
+ if ((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterSharedInfo)) != NULL &&
+ CFGetTypeID(value) == CFDataGetTypeID()) {
+ sharedInfo = CFDataGetBytePtr(value);
+ sharedInfoLength = CFDataGetLength(value);
+ }
+
+ CFMutableDataRef kdfResult = CFDataCreateMutableWithScratch(kCFAllocatorDefault, requestedSize);
+ int err = ccansikdf_x963(di, CFDataGetLength(result), CFDataGetBytePtr(result), sharedInfoLength, sharedInfo,
+ requestedSize, CFDataGetMutableBytePtr(kdfResult));
+ CFAssignRetained(result, kdfResult);
+ require_noerr_action_quiet(err, out, (CFReleaseNull(result),
+ SecError(errSecParam, error, CFSTR("ECDHKeyExchange wrong input (%d)"), err)));
+ }
+out:
+ return result;
+}
+
+#define ECDH_X963_ADAPTOR(hashname, di, cofactor) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDH ## cofactor ## X963 ## hashname( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDHKeyExchange ## cofactor); \
+ return SecKeyECDHCopyX963Result(context, di, in1, in2, error); \
+}
+
+ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Standard)
+ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Standard)
+ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Standard)
+ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Standard)
+ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Standard)
+ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Cofactor)
+ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Cofactor)
+ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Cofactor)
+ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Cofactor)
+ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Cofactor)
+
+#undef ECDH_X963_ADAPTOR
+
+// Extract number value of either CFNumber or CFString.
+static CFIndex SecKeyGetCFIndexFromRef(CFTypeRef ref) {
+ CFIndex result = 0;
+ if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
+ if (!CFNumberGetValue(ref, kCFNumberCFIndexType, &result)) {
+ result = 0;
+ }
+ } else if (CFGetTypeID(ref) == CFStringGetTypeID()) {
+ result = CFStringGetIntValue(ref);
+ }
+ return result;
+}
+
+typedef CFDataRef (*SecKeyECIESKeyExchangeCopyResult)(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm, bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV, CFErrorRef *error);
+typedef Boolean (*SecKeyECIESEncryptCopyResult)(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result, CFErrorRef *error);
+typedef CFDataRef SecKeyECIESDecryptCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error);
+
+static CFTypeRef SecKeyECIESCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
+ SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
+ SecKeyECIESEncryptCopyResult encryptCopyResult, bool variableIV,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFDictionaryRef parameters = NULL;
+ SecKeyRef ephemeralPrivateKey = NULL, ephemeralPublicKey = NULL;
+ CFDataRef pubKeyData = NULL, ephemeralPubKeyData = NULL, keyExchangeResult = NULL;
+ CFTypeRef result = NULL;
+ SecKeyRef originalKey = context->key;
+ CFMutableDataRef ciphertext = NULL;
+
+ require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
+ SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
+
+ // Generate ephemeral key.
+ require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
+ CFAssignRetained(parameters, CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+ kSecAttrKeyType, CFDictionaryGetValue(parameters, kSecAttrKeyType),
+ kSecAttrKeySizeInBits, CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits),
+ NULL));
+ require_quiet(ephemeralPrivateKey = SecKeyCreateRandomKey(parameters, error), out);
+ require_action_quiet(ephemeralPublicKey = SecKeyCopyPublicKey(ephemeralPrivateKey), out,
+ SecError(errSecParam, error, CFSTR("Unable to get public key from generated ECkey")));
+ require_quiet(ephemeralPubKeyData = SecKeyCopyExternalRepresentation(ephemeralPublicKey, error), out);
+
+ context->key = ephemeralPrivateKey;
+ require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, true,
+ ephemeralPubKeyData, pubKeyData, variableIV, error), out);
+ if (context->mode == kSecKeyOperationModePerform) {
+ // Encrypt input data using AES-GCM.
+ ciphertext = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, ephemeralPubKeyData);
+ require_quiet(encryptCopyResult(keyExchangeResult, in1, ciphertext, error), out);
+ result = CFRetain(ciphertext);
+ } else {
+ result = CFRetain(keyExchangeResult);
+ }
+
+out:
+ CFReleaseSafe(parameters);
+ CFReleaseSafe(ephemeralPrivateKey);
+ CFReleaseSafe(ephemeralPublicKey);
+ CFReleaseSafe(pubKeyData);
+ CFReleaseSafe(ephemeralPubKeyData);
+ CFReleaseSafe(keyExchangeResult);
+ CFReleaseSafe(ciphertext);
+ context->key = originalKey;
+ return result;
+}
+
+static CFTypeRef SecKeyECIESCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
+ SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
+ SecKeyECIESDecryptCopyResult decryptCopyResult, bool variableIV,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFTypeRef result = NULL;
+ CFDictionaryRef parameters = NULL;
+ CFDataRef ephemeralPubKeyData = NULL, keyExchangeResult = NULL, pubKeyData = NULL;
+ SecKeyRef pubKey = NULL;
+ CFDataRef ciphertext = NULL;
+ const UInt8 *ciphertextBuffer = NULL;
+ CFIndex keySize = 0;
+
+ require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
+ SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
+
+ if (context->mode == kSecKeyOperationModePerform) {
+ // Extract ephemeral public key from the packet.
+ keySize = (SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits)) + 7) / 8;
+ require_action_quiet(CFDataGetLength(in1) >= keySize * 2 + 1, out,
+ SecError(errSecParam, error, CFSTR("%@: too small input packet for ECIES decrypt"), context->key));
+ ciphertextBuffer = CFDataGetBytePtr(in1);
+ ephemeralPubKeyData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, keySize * 2 + 1, kCFAllocatorNull);
+ ciphertextBuffer += keySize * 2 + 1;
+
+ require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
+ SecError(errSecParam, error, CFSTR("%@: Unable to get public key"), context->key));
+ require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
+ }
+
+ // Perform keyExchange operation.
+ require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, false,
+ ephemeralPubKeyData, pubKeyData, variableIV, error), out);
+ if (context->mode == kSecKeyOperationModePerform) {
+ // Decrypt ciphertext using AES-GCM.
+ ciphertext = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, CFDataGetLength(in1) - (keySize * 2 + 1),
+ kCFAllocatorNull);
+ require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, error), out);
+ } else {
+ result = CFRetain(keyExchangeResult);
+ }
+
+out:
+ CFReleaseSafe(parameters);
+ CFReleaseSafe(ephemeralPubKeyData);
+ CFReleaseSafe(keyExchangeResult);
+ CFReleaseSafe(pubKeyData);
+ CFReleaseSafe(pubKey);
+ CFReleaseSafe(ciphertext);
+ return result;
+}
+
+static const CFIndex kSecKeyIESTagLength = 16;
+static const UInt8 kSecKeyIESIV[16] = { 0 };
+
+static CFDataRef SecKeyECIESKeyExchangeKDFX963CopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
+ bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
+ CFErrorRef *error) {
+ CFDictionaryRef parameters = NULL;
+ CFNumberRef keySizeRef = NULL;
+ CFDataRef result = NULL;
+
+ CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
+ context->operation = kSecKeyOperationTypeKeyExchange;
+
+ if (context->mode == kSecKeyOperationModePerform) {
+ // Use 128bit AES for EC keys <= 256bit, 256bit AES for larger keys.
+ CFIndex keySize = ((CFDataGetLength(pubKey) - 1) / 2) * 8;
+ keySize = (keySize > 256) ? (256 / 8) : (128 / 8);
+
+ if (variableIV) {
+ keySize += sizeof(kSecKeyIESIV);
+ }
+
+ // Generate shared secret using KDF.
+ keySizeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &keySize);
+ parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
+ kSecKeyKeyExchangeParameterSharedInfo, ephemeralPubKey,
+ kSecKeyKeyExchangeParameterRequestedSize, keySizeRef,
+ NULL);
+ }
+
+ result = SecKeyRunAlgorithmAndCopyResult(context, encrypt ? pubKey : ephemeralPubKey, parameters, error);
+ if (context->mode == kSecKeyOperationModePerform && !variableIV && result != NULL) {
+ // Append all-zero IV to the result.
+ CFMutableDataRef data = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, result);
+ CFDataAppendBytes(data, kSecKeyIESIV, sizeof(kSecKeyIESIV));
+ CFAssignRetained(result, data);
+ }
+ CFReleaseSafe(parameters);
+ CFReleaseSafe(keySizeRef);
+ return result;
+}
+
+static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result,
+ CFErrorRef *error) {
+ Boolean res = FALSE;
+ CFIndex prefix = CFDataGetLength(result);
+ CFDataSetLength(result, prefix + CFDataGetLength(inData) + kSecKeyIESTagLength);
+ UInt8 *resultBuffer = CFDataGetMutableBytePtr(result) + prefix;
+ UInt8 *tagBuffer = resultBuffer + CFDataGetLength(inData);
+ CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
+ const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
+ require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
+ aesKeySize, CFDataGetBytePtr(keyExchangeResult),
+ sizeof(kSecKeyIESIV), ivBuffer,
+ 0, NULL,
+ CFDataGetLength(inData), CFDataGetBytePtr(inData),
+ resultBuffer, kSecKeyIESTagLength, tagBuffer) == 0, out,
+ SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm encrypt data")));
+ res = TRUE;
+out:
+ return res;
+}
+
+static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
+ CFDataRef result = NULL;
+ CFMutableDataRef plaintext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData) - kSecKeyIESTagLength);
+ CFMutableDataRef tag = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), kSecKeyIESTagLength);
+ CFDataGetBytes(inData, CFRangeMake(CFDataGetLength(inData) - kSecKeyIESTagLength, kSecKeyIESTagLength),
+ CFDataGetMutableBytePtr(tag));
+ CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
+ const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
+ require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
+ aesKeySize, CFDataGetBytePtr(keyExchangeResult),
+ sizeof(kSecKeyIESIV), ivBuffer,
+ 0, NULL,
+ CFDataGetLength(plaintext), CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(plaintext),
+ kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
+ SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm decrypt data")));
+ result = CFRetain(plaintext);
+out:
+ CFReleaseSafe(plaintext);
+ CFReleaseSafe(tag);
+ return result;
+}
+
+#define ECIES_X963_ADAPTOR(hashname, cofactor, namepart, variableIV) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIES ## cofactor ## namepart ## hashname( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyECIESCopyEncryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
+ SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESEncryptAESGCMCopyResult, variableIV, in1, in2, error); \
+} \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES ## cofactor ## namepart ## hashname( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
+ SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESDecryptAESGCMCopyResult, variableIV, in1, in2, error); \
+}
+
+ECIES_X963_ADAPTOR(SHA1, Standard, X963, false)
+ECIES_X963_ADAPTOR(SHA224, Standard, X963, false)
+ECIES_X963_ADAPTOR(SHA256, Standard, X963, false)
+ECIES_X963_ADAPTOR(SHA384, Standard, X963, false)
+ECIES_X963_ADAPTOR(SHA512, Standard, X963, false)
+ECIES_X963_ADAPTOR(SHA1, Cofactor, X963, false)
+ECIES_X963_ADAPTOR(SHA224, Cofactor, X963, false)
+ECIES_X963_ADAPTOR(SHA256, Cofactor, X963, false)
+ECIES_X963_ADAPTOR(SHA384, Cofactor, X963, false)
+ECIES_X963_ADAPTOR(SHA512, Cofactor, X963, false)
+
+ECIES_X963_ADAPTOR(SHA224, Standard, VariableIVX963, true)
+ECIES_X963_ADAPTOR(SHA256, Standard, VariableIVX963, true)
+ECIES_X963_ADAPTOR(SHA384, Standard, VariableIVX963, true)
+ECIES_X963_ADAPTOR(SHA512, Standard, VariableIVX963, true)
+ECIES_X963_ADAPTOR(SHA224, Cofactor, VariableIVX963, true)
+ECIES_X963_ADAPTOR(SHA256, Cofactor, VariableIVX963, true)
+ECIES_X963_ADAPTOR(SHA384, Cofactor, VariableIVX963, true)
+ECIES_X963_ADAPTOR(SHA512, Cofactor, VariableIVX963, true)
+
+#undef ECIES_X963_ADAPTOR
+
+static CFDataRef SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
+ bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
+ CFErrorRef *error) {
+ CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
+ context->operation = kSecKeyOperationTypeKeyExchange;
+ CFMutableDataRef result = (CFMutableDataRef)SecKeyRunAlgorithmAndCopyResult(context, ephemeralPubKey, NULL, error);
+ if (result != NULL && context->mode == kSecKeyOperationModePerform) {
+ const struct ccdigest_info *di = ccsha256_di();
+ ccdigest_di_decl(di, ctx);
+ ccdigest_init(di, ctx);
+ ccdigest_update(di, ctx, CFDataGetLength(result), CFDataGetBytePtr(result));
+ ccdigest_update(di, ctx, CFDataGetLength(ephemeralPubKey), CFDataGetBytePtr(ephemeralPubKey));
+ ccdigest_update(di, ctx, CFDataGetLength(pubKey), CFDataGetBytePtr(pubKey));
+ CFAssignRetained(result, CFDataCreateMutableWithScratch(kCFAllocatorDefault, di->output_size));
+ ccdigest_final(di, ctx, CFDataGetMutableBytePtr(result));
+ }
+ return result;
+}
+
+static CFDataRef SecKeyECIESDecryptAESCBCCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
+ CFMutableDataRef result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData));
+ cccbc_one_shot(ccaes_cbc_decrypt_mode(),
+ CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
+ NULL, CFDataGetLength(keyExchangeResult) / CCAES_BLOCK_SIZE,
+ CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(result));
+ return result;
+}
+
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys(
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchangeStandard,
+ SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult,
+ SecKeyECIESDecryptAESCBCCopyResult, false,
+ in1, in2, error);
+}
+
+static CFTypeRef SecKeyRSAAESGCMCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFTypeRef result = NULL;
+ CFDictionaryRef parameters = NULL;
+ CFDataRef pubKeyData = NULL, wrappedKey = NULL, sessionKey = NULL;
+ CFMutableDataRef ciphertext = NULL;
+
+ require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
+ SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
+
+ CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
+ require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
+ result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
+
+ // Generate session key. Use 128bit AES for RSA keys < 4096bit, 256bit AES for larger keys.
+ require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
+ CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
+ require_action_quiet(sessionKey = CFDataCreateWithRandomBytes((keySize >= 4096) ? (256 / 8) : (128 / 8)), out,
+ SecError(errSecParam, error, CFSTR("Failed to generate session key")));
+
+ // Encrypt session key using wrapping algorithm and store at the beginning of the result packet.
+ require_action_quiet(wrappedKey = SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error), out,
+ CFReleaseNull(result));
+ ciphertext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(wrappedKey) + CFDataGetLength(in1) + kSecKeyIESTagLength);
+ UInt8 *resultBuffer = CFDataGetMutableBytePtr(ciphertext);
+ CFDataGetBytes(wrappedKey, CFRangeMake(0, CFDataGetLength(wrappedKey)), resultBuffer);
+ resultBuffer += CFDataGetLength(wrappedKey);
+
+ // Encrypt input data using AES-GCM.
+ UInt8 *tagBuffer = resultBuffer + CFDataGetLength(in1);
+ require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
+ CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
+ sizeof(kSecKeyIESIV), kSecKeyIESIV,
+ CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
+ CFDataGetLength(in1), CFDataGetBytePtr(in1), resultBuffer,
+ kSecKeyIESTagLength, tagBuffer) == 0, out,
+ SecError(errSecParam, error, CFSTR("RSAWRAP: Failed to aes-gcm encrypt data")));
+ result = CFRetain(ciphertext);
+
+out:
+ CFReleaseSafe(parameters);
+ CFReleaseSafe(pubKeyData);
+ CFReleaseSafe(wrappedKey);
+ CFReleaseSafe(sessionKey);
+ CFReleaseSafe(ciphertext);
+ return result;
+}
+
+static CFTypeRef SecKeyRSAAESGCMCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
+ CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ CFTypeRef result = NULL;
+ CFDictionaryRef parameters = NULL;
+ CFMutableDataRef plaintext = NULL, tag = NULL;
+ CFDataRef pubKeyData = NULL, sessionKey = NULL;
+ SecKeyRef pubKey = NULL;
+
+ require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
+ SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
+ require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
+
+ CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
+ require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
+ result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
+
+ // Extract encrypted session key.
+ require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
+ SecError(errSecParam, error, CFSTR("%@: unable to get public key"), context->key));
+ require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
+
+ CFIndex wrappedKeySize = SecKeyGetBlockSize(context->key);
+ require_action_quiet(CFDataGetLength(in1) >= wrappedKeySize + kSecKeyIESTagLength, out,
+ SecError(errSecParam, error, CFSTR("RSA-WRAP too short input data")));
+ sessionKey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(in1), wrappedKeySize, kCFAllocatorNull);
+
+ // Decrypt session key.
+ CFAssignRetained(sessionKey, SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error));
+ require_quiet(sessionKey, out);
+ CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
+ keySize = (keySize >= 4096) ? (256 / 8) : (128 / 8);
+ require_action_quiet(CFDataGetLength(sessionKey) == keySize, out,
+ SecError(errSecParam, error, CFSTR("RSA-WRAP bad ciphertext, unexpected session key size")));
+
+ // Decrypt ciphertext using AES-GCM.
+ plaintext = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), CFDataGetLength(in1) - wrappedKeySize - kSecKeyIESTagLength);
+ tag = CFDataCreateMutableWithScratch(kCFAllocatorDefault, kSecKeyIESTagLength);
+ CFDataGetBytes(in1, CFRangeMake(CFDataGetLength(in1) - kSecKeyIESTagLength, kSecKeyIESTagLength),
+ CFDataGetMutableBytePtr(tag));
+ const UInt8 *ciphertextBuffer = CFDataGetBytePtr(in1);
+ ciphertextBuffer += wrappedKeySize;
+ require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
+ CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
+ sizeof(kSecKeyIESIV), kSecKeyIESIV,
+ CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
+ CFDataGetLength(plaintext), ciphertextBuffer, CFDataGetMutableBytePtr(plaintext),
+ kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
+ SecError(errSecParam, error, CFSTR("RSA-WRAP: Failed to aes-gcm decrypt data")));
+ result = CFRetain(plaintext);
+
+out:
+ CFReleaseSafe(parameters);
+ CFReleaseSafe(sessionKey);
+ CFReleaseSafe(tag);
+ CFReleaseSafe(pubKeyData);
+ CFReleaseSafe(pubKey);
+ CFReleaseSafe(plaintext);
+ return result;
+}
+
+#define RSA_OAEP_AESGCM_ADAPTOR(hashname) \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyRSAAESGCMCopyEncryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
+} \
+static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
+ SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
+ return SecKeyRSAAESGCMCopyDecryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
+}
+
+RSA_OAEP_AESGCM_ADAPTOR(SHA1)
+RSA_OAEP_AESGCM_ADAPTOR(SHA224)
+RSA_OAEP_AESGCM_ADAPTOR(SHA256)
+RSA_OAEP_AESGCM_ADAPTOR(SHA384)
+RSA_OAEP_AESGCM_ADAPTOR(SHA512)
+
+#undef RSA_OAEP_AESGCM_ADAPTOR
+
+SecKeyAlgorithmAdaptor SecKeyGetAlgorithmAdaptor(SecKeyOperationType operation, SecKeyAlgorithm algorithm) {
+ static CFDictionaryRef adaptors[kSecKeyOperationTypeCount];
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ const void *signKeys[] = {
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
+
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
+
+ kSecKeyAlgorithmRSASignatureRaw,
+ kSecKeyAlgorithmRSASignatureRawCCUnit,
+
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
+
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
+
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
+
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
+ };
+ const void *signValues[] = {
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA512,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15Raw,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15MD5,
+
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
+ };
+ check_compile_time(array_size(signKeys) == array_size(signValues));
+ adaptors[kSecKeyOperationTypeSign] = CFDictionaryCreate(kCFAllocatorDefault, signKeys, signValues,
+ array_size(signKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
+
+ const void *verifyKeys[] = {
+ kSecKeyAlgorithmRSASignatureRaw,
+
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
+ kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
+
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
+ kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
+
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
+ kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
+
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
+ kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
+
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
+ kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
+
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
+ kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
+ };
+ const void *verifyValues[] = {
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw,
+
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA512,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15Raw,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15MD5,
+
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
+ };
+ check_compile_time(array_size(verifyKeys) == array_size(verifyValues));
+ adaptors[kSecKeyOperationTypeVerify] = CFDictionaryCreate(kCFAllocatorDefault, verifyKeys, verifyValues,
+ array_size(verifyKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
+
+ const void *encryptKeys[] = {
+ kSecKeyAlgorithmRSAEncryptionRaw,
+ kSecKeyAlgorithmRSAEncryptionRawCCUnit,
+
+ kSecKeyAlgorithmRSAEncryptionPKCS1,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
+
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
+ };
+ const void *encryptValues[] = {
+ SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
+ SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
+
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512AESGCM,
+
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA512,
+ };
+ check_compile_time(array_size(encryptKeys) == array_size(encryptValues));
+ adaptors[kSecKeyOperationTypeEncrypt] = CFDictionaryCreate(kCFAllocatorDefault, encryptKeys, encryptValues,
+ array_size(encryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
+
+ const void *decryptKeys[] = {
+ kSecKeyAlgorithmRSAEncryptionRaw,
+ kSecKeyAlgorithmRSAEncryptionRawCCUnit,
+
+ kSecKeyAlgorithmRSAEncryptionPKCS1,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
+
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
+ kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
+ kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
+
+ kSecKeyAlgorithmECIESEncryptionAKSSmartCard,
+ };
+ const void *decryptValues[] = {
+ SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
+ SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
+
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384AESGCM,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512AESGCM,
+
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys,
+ };
+ check_compile_time(array_size(decryptKeys) == array_size(decryptValues));
+ adaptors[kSecKeyOperationTypeDecrypt] = CFDictionaryCreate(kCFAllocatorDefault, decryptKeys, decryptValues,
+ array_size(decryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
+
+ const void *keyExchangeKeys[] = {
+ kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1,
+ kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224,
+ kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256,
+ kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384,
+ kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512,
+
+ kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1,
+ kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224,
+ kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256,
+ kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384,
+ kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512,
+ };
+ const void *keyExchangeValues[] = {
+
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA512,
+
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA1,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA224,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA256,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA384,
+ SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA512,
+ };
+ check_compile_time(array_size(keyExchangeKeys) == array_size(keyExchangeKeys));
+ adaptors[kSecKeyOperationTypeKeyExchange] = CFDictionaryCreate(kCFAllocatorDefault, keyExchangeKeys, keyExchangeValues,
+ array_size(keyExchangeKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
+ });
+
+ return CFDictionaryGetValue(adaptors[operation], algorithm);
+}
__BEGIN_DECLS
extern struct ccrng_state *ccrng_seckey;
-CFIndex SecKeyGetAlgorithmIdentifier(SecKeyRef key);
enum {
// Keep in sync with SecKeyOperationType enum in SecKey.h
--- /dev/null
+/*
+ * Copyright (c) 2006-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@
+ */
+
+/*
+ * SecKeyProxy.m - Remote access to SecKey instance
+ */
+
+#import <Foundation/Foundation.h>
+#import <Foundation/NSXPCConnection_Private.h>
+
+#include <Security/SecBasePriv.h>
+#include <Security/SecKeyInternal.h>
+#include <Security/SecIdentityPriv.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFError.h>
+
+#include <Security/SecKeyProxy.h>
+
+// MARK: XPC-level protocol for communication between server and client.
+@protocol SecKeyProxyProtocol
+- (void)initializeWithReply:(void (^)(NSData * _Nullable certificate))reply;
+- (void)getBlockSizeWithReply:(void (^)(size_t blockSize))reply;
+- (void)getAttributesWithReply:(void (^)(NSDictionary *attributes))reply;
+- (void)getExternalRepresentationWithReply:(void (^)(NSData *data, NSError *error))reply;
+- (void)getDescriptionWithReply:(void (^)(NSString *description))reply;
+- (void)getAlgorithmIDWithReply:(void (^)(NSInteger algorithmID))reply;
+- (void)getPublicKey:(void (^)(NSXPCListenerEndpoint *endpoint))reply;
+- (void)performOperation:(SecKeyOperationType)operation algorithm:(NSString *)algorithm parameters:(NSArray *)parameters reply:(void (^)(NSArray *result, NSError *error))reply;
+@end
+
+// MARK: XPC target object for SecKeyProxy side
+// Logically could be embedded in SecKeyProxy, but that would cause ownership cycles, since target object is always owned by its associated XPC connection.
+@interface SecKeyProxyTarget : NSObject<SecKeyProxyProtocol> {
+ id _key;
+ NSData *_certificate;
+ SecKeyProxy *_publicKeyProxy;
+}
+- (instancetype)initWithKey:(id)key certificate:(nullable NSData *)certificate;
+@property (readonly, nonatomic) SecKeyRef key;
+@end
+
+@implementation SecKeyProxyTarget
+- (instancetype)initWithKey:(id)key certificate:(nullable NSData *)certificate {
+ if (self = [super init]) {
+ _key = key;
+ _certificate = certificate;
+ }
+ return self;
+}
+
+- (SecKeyRef)key {
+ return (__bridge SecKeyRef)_key;
+}
+
+- (void)initializeWithReply:(void (^)(NSData *_Nullable))reply {
+ return reply(_certificate);
+}
+
+- (void)getBlockSizeWithReply:(void (^)(size_t))reply {
+ return reply(SecKeyGetBlockSize(self.key));
+}
+
+- (void)getAttributesWithReply:(void (^)(NSDictionary *))reply {
+ return reply(CFBridgingRelease(SecKeyCopyAttributes(self.key)));
+}
+
+- (void)getExternalRepresentationWithReply:(void (^)(NSData *, NSError *))reply {
+ NSError *error;
+ NSData *data = CFBridgingRelease(SecKeyCopyExternalRepresentation(self.key, (void *)&error));
+ return reply(data, error);
+}
+
+- (void)getDescriptionWithReply:(void (^)(NSString *))reply {
+ NSString *description = CFBridgingRelease(CFCopyDescription(self.key));
+
+ // Strip wrapping "<SecKeyRef " and ">" if present.
+ if ([description hasPrefix:@"<SecKeyRef "] && [description hasSuffix:@">"]) {
+ description = [description substringWithRange:NSMakeRange(11, description.length - 12)];
+ } else if ([description hasPrefix:@"<SecKeyRef: "] && [description hasSuffix:@">"]) {
+ description = [description substringWithRange:NSMakeRange(12, description.length - 13)];
+ }
+
+ return reply(description);
+}
+
+- (void)getAlgorithmIDWithReply:(void (^)(NSInteger))reply {
+ return reply(SecKeyGetAlgorithmId(self.key));
+}
+
+- (void)getPublicKey:(void (^)(NSXPCListenerEndpoint *endpoint))reply {
+ if (_publicKeyProxy == nil) {
+ id publicKey = CFBridgingRelease(SecKeyCopyPublicKey(self.key));
+ if (publicKey == nil) {
+ return reply(nil);
+ }
+ _publicKeyProxy = [[SecKeyProxy alloc] initWithKey:(__bridge SecKeyRef)publicKey];
+ }
+ return reply(_publicKeyProxy.endpoint);
+}
+
+- (void)performOperation:(SecKeyOperationType)operation algorithm:(NSString *)algorithm parameters:(NSArray *)parameters reply:(void (^)(NSArray *, NSError *))reply {
+ NSMutableArray *algorithms = @[algorithm].mutableCopy;
+ CFTypeRef in1 = (__bridge CFTypeRef)(parameters.count > 0 ? parameters[0] : nil);
+ CFTypeRef in2 = (__bridge CFTypeRef)(parameters.count > 1 ? parameters[1] : nil);
+ NSError *error;
+ SecKeyOperationContext context = { self.key, operation, (__bridge CFMutableArrayRef)algorithms };
+ id result = CFBridgingRelease(SecKeyRunAlgorithmAndCopyResult(&context, in1, in2, (void *)&error));
+ return reply(result ? @[result] : @[], error);
+}
+@end
+
+// MARK: SecKeyProxy implementation
+@interface SecKeyProxy() <NSXPCListenerDelegate>
+@end
+
+@implementation SecKeyProxy
+- (instancetype)initWithKey:(SecKeyRef)key certificate:(nullable NSData *)certificate {
+ if (self = [super init]) {
+ _key = CFBridgingRelease(CFRetain(key));
+ _certificate = certificate;
+ _listener = [NSXPCListener anonymousListener];
+ _listener.delegate = self;
+
+ // All connections created to this proxy instance are serialized to this single queue.
+ [_listener _setQueue: dispatch_queue_create("SecKeyProxy", NULL)];
+ [_listener resume];
+ }
+
+ return self;
+}
+
+- (instancetype)initWithKey:(SecKeyRef)key {
+ return [self initWithKey:key certificate:nil];
+}
+
+- (instancetype)initWithIdentity:(SecIdentityRef)identity {
+ id key;
+ id certificate;
+ SecIdentityCopyPrivateKey(identity, (void *)&key);
+ SecIdentityCopyCertificate(identity, (void *)&certificate);
+ if (key == nil && certificate == nil) {
+ return nil;
+ }
+
+ // Extract data from the certificate.
+ NSData *certificateData = CFBridgingRelease(SecCertificateCopyData((SecCertificateRef)certificate));
+ if (certificateData == nil) {
+ return nil;
+ }
+
+ return [self initWithKey:(__bridge SecKeyRef)key certificate:certificateData];
+}
+
+- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
+ newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SecKeyProxyProtocol)];
+ newConnection.exportedObject = [[SecKeyProxyTarget alloc] initWithKey:_key certificate:_certificate];
+ [newConnection _setQueue:[_listener _queue]];
+ [newConnection resume];
+ return YES;
+}
+
+- (void)invalidate {
+ [_listener invalidate];
+}
+
+- (void)dealloc {
+ [self invalidate];
+}
+
+- (NSXPCListenerEndpoint *)endpoint {
+ return _listener.endpoint;
+}
+
+// MARK: Client side: remote-connected SecKey instance.
+static OSStatus SecRemoteKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
+ // keyData and key->key are both actually type-punned NSXPCConnection owning pointers.
+ key->key = (void *)keyData;
+ return errSecSuccess;
+}
+
+static void SecRemoteKeyDestroy(SecKeyRef key) {
+ NSXPCConnection *conn = CFBridgingRelease(key->key);
+ [conn invalidate];
+}
+
++ (id<SecKeyProxyProtocol>)targetForKey:(SecKeyRef)key error:(CFErrorRef *)error {
+ NSXPCConnection *connection = (__bridge NSXPCConnection *)key->key;
+ id<SecKeyProxyProtocol> result = [connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull _error) {
+ if (error != NULL) {
+ *error = (__bridge_retained CFErrorRef)_error;
+ }
+ }];
+ return result;
+}
+
+static size_t SecRemoteKeyBlockSize(SecKeyRef key) {
+ __block size_t localBlockSize = 0;
+ [[SecKeyProxy targetForKey:key error:NULL] getBlockSizeWithReply:^(size_t blockSize) {
+ localBlockSize = blockSize;
+ }];
+ return localBlockSize;
+}
+
+static CFDictionaryRef SecRemoteKeyCopyAttributeDictionary(SecKeyRef key) {
+ __block NSDictionary *localAttributes;
+ [[SecKeyProxy targetForKey:key error:NULL] getAttributesWithReply:^(NSDictionary *attributes) {
+ localAttributes = attributes;
+ }];
+ return CFBridgingRetain(localAttributes);
+}
+
+static CFDataRef SecRemoteKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) {
+ __block NSData *localData;
+ __block NSError *localError;
+ [[SecKeyProxy targetForKey:key error:error] getExternalRepresentationWithReply:^(NSData *data, NSError *error) {
+ localData = data;
+ localError = error;
+ }];
+ if (localData == nil && error != NULL) {
+ *error = (__bridge_retained CFErrorRef)localError;
+ }
+ return CFBridgingRetain(localData);
+}
+
+static CFStringRef SecRemoteKeyCopyDescription(SecKeyRef key) {
+ __block NSString *localDescription;
+ [[SecKeyProxy targetForKey:key error:NULL] getDescriptionWithReply:^(NSString *description) {
+ localDescription = [NSString stringWithFormat:@"<SecKeyRef remoteKey: %@>", description];
+ }];
+ return CFBridgingRetain(localDescription);
+}
+
+static CFIndex SecRemoteKeyGetAlgorithmID(SecKeyRef key) {
+ __block CFIndex localAlgorithmID = kSecNullAlgorithmID;
+ [[SecKeyProxy targetForKey:key error:NULL] getAlgorithmIDWithReply:^(NSInteger algorithmID) {
+ localAlgorithmID = algorithmID;
+ }];
+ return localAlgorithmID;
+}
+
+static SecKeyRef SecRemoteKeyCopyPublicKey(SecKeyRef key) {
+ __block id publicKey;
+ [[SecKeyProxy targetForKey:key error:NULL] getPublicKey:^(NSXPCListenerEndpoint *endpoint) {
+ if (endpoint != nil) {
+ publicKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:endpoint error:nil]);
+ }
+ }];
+ return (__bridge_retained SecKeyRef)publicKey;
+}
+
+static CFTypeRef SecRemoteKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType operation, SecKeyAlgorithm algorithm, CFArrayRef algorithms, SecKeyOperationMode mode, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
+ NSMutableArray *parameters = @[].mutableCopy;
+ if (in1 != NULL) {
+ [parameters addObject:(__bridge id)in1];
+ if (in2 != NULL) {
+ [parameters addObject:(__bridge id)in2];
+ }
+ }
+ __block id localResult;
+ [[SecKeyProxy targetForKey:key error:error] performOperation:operation algorithm:(__bridge NSString *)algorithm parameters:parameters reply:^(NSArray *result, NSError *_error) {
+ if (result.count > 0) {
+ localResult = result[0];
+ }
+ else if (error != NULL) {
+ *error = (__bridge_retained CFErrorRef)_error;
+ }
+ }];
+ return CFBridgingRetain(localResult);
+}
+
+static const SecKeyDescriptor SecRemoteKeyDescriptor = {
+ .version = kSecKeyDescriptorVersion,
+ .name = "RemoteKey",
+ .init = SecRemoteKeyInit,
+ .destroy = SecRemoteKeyDestroy,
+ .blockSize = SecRemoteKeyBlockSize,
+ .copyDictionary = SecRemoteKeyCopyAttributeDictionary,
+ .copyExternalRepresentation = SecRemoteKeyCopyExternalRepresentation,
+ .describe = SecRemoteKeyCopyDescription,
+ .getAlgorithmID = SecRemoteKeyGetAlgorithmID,
+ .copyPublicKey = SecRemoteKeyCopyPublicKey,
+ .copyOperationResult = SecRemoteKeyCopyOperationResult,
+};
+
++ (SecKeyRef)createItemFromEndpoint:(NSXPCListenerEndpoint *)endpoint certificate:(NSData **)certificate error:(NSError * _Nullable __autoreleasing *)error {
+ // Connect to the server proxy object.
+ NSXPCConnection *connection = [[NSXPCConnection alloc] initWithListenerEndpoint:endpoint];
+ connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SecKeyProxyProtocol)];
+ [connection resume];
+
+ // Initialize remote object.
+ __block NSError *localError;
+ __block NSData *localCertificate;
+ [[connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
+ localError = [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecItemNotFound userInfo:@{NSUnderlyingErrorKey: error}];
+ }] initializeWithReply:^(NSData *_Nullable _certificate){
+ localCertificate = _certificate;
+ }];
+ if (localError == nil) {
+ if (certificate != nil) {
+ *certificate = localCertificate;
+ }
+ } else {
+ [connection invalidate];
+ if (error != NULL) {
+ *error = localError;
+ }
+ return NULL;
+ }
+
+ // Wrap returned connection in SecKeyRef instance.
+ return SecKeyCreate(kCFAllocatorDefault, &SecRemoteKeyDescriptor, CFBridgingRetain(connection), 0, kSecKeyEncodingRaw);
+}
+
++ (SecKeyRef)createKeyFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError * _Nullable __autoreleasing *)error {
+ return [self createItemFromEndpoint:endpoint certificate:nil error:error];
+}
+
++ (SecIdentityRef)createIdentityFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError * _Nullable __autoreleasing *)error {
+ NSData *certificateData;
+ id key = CFBridgingRelease([self createItemFromEndpoint:endpoint certificate:&certificateData error:error]);
+ if (key == nil) {
+ return NULL;
+ }
+ if (certificateData == nil) {
+ if (error != NULL) {
+ *error = [NSError errorWithDomain:(NSString *)kSecErrorDomain code:errSecParam userInfo:@{(id)NSLocalizedDescriptionKey: @"Attempt to create remote identity from key-only proxy"}];
+ }
+ return NULL;
+ }
+
+ id certificate = CFBridgingRelease(SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certificateData));
+ return SecIdentityCreate(kCFAllocatorDefault, (__bridge SecCertificateRef)certificate, (__bridge SecKeyRef)key);
+}
+@end
#define kECKeySize 256
-static void GenerateHashForKey(ccec_pub_ctx_t public_key, void *output)
+static OSStatus GenerateHashForKey(ccec_pub_ctx_t public_key, void *output)
{
size_t size = ccec_export_pub_size(public_key);
- uint8_t pub_key_bytes_buffer[size];
+ uint8_t *pub_key_bytes_buffer = malloc(size);
+ if (pub_key_bytes_buffer == NULL) {
+ return errSecMemoryError;
+ }
ccec_export_pub(public_key, pub_key_bytes_buffer);
ccdigest(ccsha1_di(), size, pub_key_bytes_buffer, output);
+
+ free(pub_key_bytes_buffer);
+
+ return errSecSuccess;
}
bzero(fullKey->_key, sizeof(fullKey->_key));
}
-static inline void SecOTRFDHKUpdateHash(SecOTRFullDHKeyRef fullKey)
+static inline OSStatus SecOTRFDHKUpdateHash(SecOTRFullDHKeyRef fullKey)
{
- GenerateHashForKey(ccec_ctx_pub(fullKey->_key), fullKey->keyHash);
+ return GenerateHashForKey(ccec_ctx_pub(fullKey->_key), fullKey->keyHash);
}
SecOTRFullDHKeyRef SecOTRFullDHKCreate(CFAllocatorRef allocator)
require_noerr(ReadMPI(bytes, size, ccec_ctx_n(newFDHK->_key), ccec_ctx_k(newFDHK->_key)), fail);
- SecOTRFDHKUpdateHash(newFDHK);
+ require_noerr(SecOTRFDHKUpdateHash(newFDHK), fail);
return newFDHK;
return NULL;
}
-void SecFDHKNewKey(SecOTRFullDHKeyRef fullKey)
+OSStatus SecFDHKNewKey(SecOTRFullDHKeyRef fullKey)
{
struct ccrng_state *rng=ccDRBGGetRngState();
// ccecdh_generate_key or ccechd_generate_compact_key, but for now ecdh are fine for compact use IFF we don't
// use the non-compact pub part.
- ccec_compact_generate_key(ccec_cp_256(), rng, fullKey->_key);
+ // ccec_cmp() assumes public keys are 65 bytes or shorter.
+ // If we ever generate different DHKeys, we will need to make a change there too.
- SecOTRFDHKUpdateHash(fullKey);
+ ccec_compact_generate_key(ccec_cp_256(), rng, fullKey->_key);
+ return SecOTRFDHKUpdateHash(fullKey);
}
void SecFDHKAppendSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo)
(void) pubKey;
}
-static inline void SecOTRPDHKUpdateHash(SecOTRPublicDHKeyRef pubKey)
+static inline OSStatus SecOTRPDHKUpdateHash(SecOTRPublicDHKeyRef pubKey)
{
- GenerateHashForKey(pubKey->_key, pubKey->keyHash);
+ return GenerateHashForKey(pubKey->_key, pubKey->keyHash);
}
static void ccec_copy_public(ccec_pub_ctx_t source, ccec_pub_ctx_t dest)
*size -= publicKeySize;
*bytes += publicKeySize;
- SecOTRPDHKUpdateHash(newPDHK);
+ require_noerr(SecOTRPDHKUpdateHash(newPDHK), fail);
return newPDHK;
fail:
*bytes += *size;
*size = 0;
- SecOTRPDHKUpdateHash(newPDHK);
+ require_noerr(SecOTRPDHKUpdateHash(newPDHK), fail);
return newPDHK;
fail:
int result = 0;
if (lsize == rsize) {
- uint8_t lpub[lsize];
- uint8_t rpub[rsize];
+ // Keys should never be larger than 256.
+ // But if they are, we want to draw attention to it.
+ if (lsize > 65) {
+ secerror("The size of an SecOTRDHKey is larger than 65 bytes. \
+ This is not supported in SecOTR and will result in malformed ciphertexts.");
+ return false;
+ }
+
+ uint8_t lpub[65];
+ uint8_t rpub[65];
ccec_export_pub(l, lpub);
ccec_export_pub(r, rpub);
-
+
result = memcmp(lpub, rpub, lsize);
} else {
result = rsize < lsize ? -1 : 1;
SecOTRFullDHKeyRef SecOTRFullDHKCreate(CFAllocatorRef allocator);
SecOTRFullDHKeyRef SecOTRFullDHKCreateFromBytes(CFAllocatorRef allocator, const uint8_t**bytes, size_t*size);
-void SecFDHKNewKey(SecOTRFullDHKeyRef key);
+OSStatus SecFDHKNewKey(SecOTRFullDHKeyRef key);
void SecFDHKAppendSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo);
void SecFDHKAppendPublicSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo);
void SecFDHKAppendCompactPublicSerialization(SecOTRFullDHKeyRef fullKey, CFMutableDataRef appendTo);
(uint8_t*)signatureStart, signatureSize, NULL), fail);
return true;
fail: ;
+ uint8_t *replacementSignature = malloc(signatureSize + 3);
+ require(replacementSignature != NULL, fail2);
- uint8_t replacementSignature[signatureSize + 3];
size_t replacementSignatureLen = sizeof(replacementSignature);
uint8_t *replacementSignaturePtr = replacementSignature;
require(SecKeyDigestAndVerifyWithError(publicID->publicSigningKey, kOTRSignatureAlgIDPtr,
dataToHash, amountToHash,
replacementSignaturePtr, replacementSignatureLen, error), fail2);
+ free(replacementSignature);
return true;
fail2:
+ free(replacementSignature);
return false;
}
}
}
-static void SecOTRGenerateNewProposedKey(SecOTRSessionRef session)
+static OSStatus SecOTRGenerateNewProposedKey(SecOTRSessionRef session)
{
SecOTRSExpireCachedKeysForFullKey(session, session->_myKey);
}
// Derive a new next key by regenerating over the old key.
- SecFDHKNewKey(session->_myNextKey);
+ OSStatus ret = SecFDHKNewKey(session->_myNextKey);
session->_keyID += 1;
+
+ return ret;
}
#include "Security/pbkdf2.h"
#include <CommonCrypto/CommonHMAC.h>
+#include "Security/SecBase.h"
+#include <stdlib.h>
#include <string.h>
/* CC Based HMAC PRF functions */
/* This implements the HMAC SHA-1 version of pbkdf2 and allocates a local buffer for the HMAC */
-void pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen,
+OSStatus pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen,
const uint8_t *saltPtr, size_t saltLen,
uint32_t iterationCount,
void *dkPtr, size_t dkLen)
{
// MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20;
// salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize.
- const size_t kBigEnoughSize = (saltLen + CC_SHA1_DIGEST_LENGTH) + 2 * CC_SHA1_DIGEST_LENGTH;
- uint8_t temp_data[kBigEnoughSize];
+ size_t kBigEnoughSize = (saltLen + CC_SHA1_DIGEST_LENGTH) + 2 * CC_SHA1_DIGEST_LENGTH;
+ uint8_t *temp_data = malloc(kBigEnoughSize);
+
+ if (temp_data == NULL) {
+ return errSecMemoryError;
+ }
pbkdf2(hmac_sha1_PRF, CC_SHA1_DIGEST_LENGTH,
passwordPtr, passwordLen,
dkPtr, dkLen,
temp_data);
- bzero(temp_data, kBigEnoughSize);
+ bzero(temp_data, kBigEnoughSize);
+
+ return errSecSuccess;
}
/* This implements the HMAC SHA-256 version of pbkdf2 and allocates a local buffer for the HMAC */
-void pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen,
+OSStatus pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen,
const uint8_t *saltPtr, size_t saltLen,
uint32_t iterationCount,
void *dkPtr, size_t dkLen)
{
// MAX(salt_length + 4, 32 /* SHA1 Digest size */) + 2 * 32;
// salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize.
- const size_t kBigEnoughSize = (saltLen + CC_SHA256_DIGEST_LENGTH) + 2 * CC_SHA256_DIGEST_LENGTH;
- uint8_t temp_data[kBigEnoughSize];
+ size_t kBigEnoughSize = (saltLen + CC_SHA256_DIGEST_LENGTH) + 2 * CC_SHA256_DIGEST_LENGTH;
+ uint8_t *temp_data = malloc(kBigEnoughSize);
+
+ if (temp_data == NULL) {
+ return errSecMemoryError;
+ }
pbkdf2(hmac_sha256_PRF, CC_SHA256_DIGEST_LENGTH,
passwordPtr, passwordLen,
temp_data);
bzero(temp_data, kBigEnoughSize);
+
+ return errSecSuccess;
}
-void SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey)
+OSStatus SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey)
{
- pbkdf2_hmac_sha1(CFDataGetBytePtr(password), CFDataGetLength(password),
+ return pbkdf2_hmac_sha1(CFDataGetBytePtr(password), CFDataGetLength(password),
CFDataGetBytePtr(salt), CFDataGetLength(salt),
interationCount,
CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey));
}
-void SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey)
+OSStatus SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey)
{
- pbkdf2_hmac_sha256(CFDataGetBytePtr(password), CFDataGetLength(password),
+ return pbkdf2_hmac_sha256(CFDataGetBytePtr(password), CFDataGetLength(password),
CFDataGetBytePtr(salt), CFDataGetLength(salt),
interationCount,
CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey));
size_t text_len,
uint8_t digest[CC_SHA256_DIGEST_LENGTH]);
-/* PBKDF for clients who want to let us allocate the intermediate buffer.
- We over write any intermediate results we use in calculating */
-void pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen,
+
+/**
+ PBKDF2 key derivation with HMAC-SHA1.
+
+ @param passwordPtr The pointer to the passsword data
+ @param passwordLen The password data length
+ @param saltPtr The pointer to the salt
+ @param saltLen The salt length
+ @param iterationCount Number of PBKDF2 iterations
+ @param dkPtr The pointer to the derived key
+ @param dkLen The derived key length
+ @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise.
+ */
+OSStatus pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen,
const uint8_t *saltPtr, size_t saltLen,
uint32_t iterationCount,
void *dkPtr, size_t dkLen);
-void pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen,
+/**
+ PBKDF2 key derivation with HMAC-SHA256.
+
+ @param passwordPtr The pointer to the passsword data
+ @param passwordLen The password data length
+ @param saltPtr The pointer to the salt
+ @param saltLen The salt length
+ @param iterationCount Number of PBKDF2 iterations
+ @param dkPtr The pointer to the derived key
+ @param dkLen The derived key length
+ @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise.
+ */
+OSStatus pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen,
const uint8_t *saltPtr, size_t saltLen,
uint32_t iterationCount,
void *dkPtr, size_t dkLen);
*/
-void SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey);
-void SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey);
+/**
+ PBKDF2 key derivation with HMAC-SHA1.
+
+ @param password Password data
+ @param salt Salt data
+ @param interationCount Number of PBKDF2 iterations
+ @param derivedKey Mutable data reference to write the result of the key derivation
+ @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise.
+ */
+OSStatus SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey);
+
+/**
+ PBKDF2 key derivation with HMAC-SHA256.
+
+ @param password Password data
+ @param salt Salt data
+ @param interationCount Number of PBKDF2 iterations
+ @param derivedKey Mutable data reference to write the result of the key derivation
+ @return errSecMemoryError on a failure to allocate the buffer. errSecSuccess otherwise.
+ */
+OSStatus SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey);
return false;
}
-static void getPasswordRandomCharacters(CFStringRef *returned, CFDictionaryRef requirements, CFIndex *numberOfRandomCharacters, CFStringRef allowedCharacters)
+static OSStatus getPasswordRandomCharacters(CFStringRef *returned, CFDictionaryRef requirements, CFIndex *numberOfRandomCharacters, CFStringRef allowedCharacters)
{
- uint8_t randomNumbers[*numberOfRandomCharacters];
- unsigned char randomCharacters[*numberOfRandomCharacters];
+ uint8_t *randomNumbers = malloc(*numberOfRandomCharacters);
+ unsigned char *randomCharacters = malloc(*numberOfRandomCharacters);
+
+ if (randomNumbers == NULL || randomCharacters == NULL) {
+ free(randomNumbers);
+ free(randomCharacters);
+ return errSecMemoryError;
+ }
+
getUniformRandomNumbers(randomNumbers, *numberOfRandomCharacters, CFStringGetLength(allowedCharacters));
CFTypeRef prohibitedCharacters = NULL;
}
*returned = CFStringCreateWithBytes(kCFAllocatorDefault, randomCharacters, *numberOfRandomCharacters, kCFStringEncodingUTF8, false);
+
+ free(randomCharacters);
+ free(randomNumbers);
+
+ return errSecSuccess;
}
static bool doesPasswordEndWith(CFStringRef password, CFStringRef prohibitedCharacters)
while (true) {
allowedChars = CFDictionaryGetValue(properlyFormattedRequirements, kSecAllowedCharactersKey);
- getPasswordRandomCharacters(&randomCharacters, properlyFormattedRequirements, &requiredCharactersSize, allowedChars);
+ require_noerr(getPasswordRandomCharacters(&randomCharacters, properlyFormattedRequirements, &requiredCharactersSize, allowedChars), fail);
if(numberOfGroupsRef && groupSizeRef){
finalPassword = CFStringCreateMutable(kCFAllocatorDefault, 0);
/* Chain length check */
require(SecPolicyAddChainLengthOptions(options, 3), errOut);
+ /* Skip networked revocation checks */
+ CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
+
require(result = SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning,
kSecPolicyNameiPhoneApplicationSigning, options),
errOut);
/* Chain length check */
require(SecPolicyAddChainLengthOptions(options, 3), errOut);
+ /* Skip networked revocation checks */
+ CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
+
require(result = SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning,
kSecPolicyNameiPhoneVPNApplicationSigning, options),
errOut);
/* Revocation via any available method */
CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
-
require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning,
kSecPolicyNameiPhoneProfileApplicationSigning,
options), errOut);
/* Revocation via any available method */
CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
-
require(result = SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning,
kSecPolicyNameMacOSProfileApplicationSigning,
options), errOut);
require(SecPolicyAddChainLengthOptions(options, 3), errOut);
require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProvisioningProfileSigning), errOut);
+ /* Skip networked revocation checks */
+ CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
+
require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning,
kSecPolicyNameiPhoneProvisioningProfileSigning, options),
errOut);
add_leaf_marker(options, &oidAppleTVOSApplicationSigningProd);
add_leaf_marker(options, &oidAppleTVOSApplicationSigningProdQA);
+ /* Skip networked revocation checks */
+ CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
+
require(result = SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning,
kSecPolicyNameTVOSApplicationSigning, options),
errOut);
/* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
/* Signature Algorithm: ecdsa-with-SHA384 */
const uint8_t BASystemRootCA_SHA256[kSecPolicySHA256Size] = {
- 0x29, 0x75, 0x9b, 0x53, 0x8a, 0xd1, 0xcb, 0x4f, 0x3b, 0xa5, 0x20, 0x4d, 0x60, 0x4b, 0x25, 0x81,
- 0x8d, 0x18, 0x9f, 0x62, 0xe3, 0x94, 0x2d, 0x99, 0x52, 0x54, 0x22, 0x5a, 0xe5, 0x7f, 0x42, 0xca
+ 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
+ 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
};
/* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
return result;
}
+SecPolicyRef SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration) {
+ CFMutableDictionaryRef options = NULL;
+ SecPolicyRef result = NULL;
+
+ require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks), errOut);
+
+ /* iAP checks expiration on developement certs, but not on production certs */
+ if (checkExpiration) {
+ SecPolicyAddBasicX509Options(options);
+ } else {
+ SecPolicyAddBasicCertOptions(options);
+ }
+
+ /* Exactly 2 certs in the chain */
+ require(SecPolicyAddChainLengthOptions(options, 2), errOut);
+
+ /* iAP SW Auth General Capabilities Extension present */
+ add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.59.1"));
+
+ require(result = SecPolicyCreate(kSecPolicyAppleiAPSWAuth,
+ kSecPolicyNameiAPSWAuth, options), errOut);
+
+errOut:
+ CFReleaseSafe(options);
+ return result;
+}
+
+SecPolicyRef SecPolicyCreateiAPSWAuth(void) {
+ /* By default, iAP SW Auth certs don't expire */
+ return SecPolicyCreateiAPSWAuthWithExpiration(false);
+}
+
SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) {
CFMutableDictionaryRef options = NULL;
SecPolicyRef result = NULL;
CFReleaseSafe(options);
return result;
}
+
+SecPolicyRef SecPolicyCreateAppleAssetReceipt(void) {
+ CFMutableDictionaryRef options = NULL;
+ SecPolicyRef result = NULL;
+
+ require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks), errOut);
+
+ /* No expiration check. */
+ SecPolicyAddBasicCertOptions(options);
+
+ /* Apple Anchor */
+ require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAssetReceipt), errOut);
+
+ /* Exactly 3 certs in the chain */
+ require(SecPolicyAddChainLengthOptions(options, 3), errOut);
+
+ /* Intermediate marker OID is Apple System Integration 2 CA */
+ add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10"));
+
+ /* Leaf marker OID is the Asset Receipt OID */
+ add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.61"));
+
+ /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
+ require(SecPolicyAddStrongKeySizeOptions(options), errOut);
+
+ require(result = SecPolicyCreate(kSecPolicyAppleAssetReceipt,
+ kSecPolicyNameAssetReceipt, options), errOut);
+
+errOut:
+ CFReleaseNull(options);
+ return result;
+}
+
+SecPolicyRef SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
+ CFMutableDictionaryRef options = NULL;
+ SecPolicyRef result = NULL;
+
+ require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks), errOut);
+
+ /* No expiration check. */
+ SecPolicyAddBasicCertOptions(options);
+
+ /* Apple Anchor */
+ require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameDeveloperIDPlusTicket), errOut);
+
+ /* Exactly 3 certs in the chain */
+ require(SecPolicyAddChainLengthOptions(options, 3), errOut);
+
+ /* Intermediate marker OID is Apple System Integration CA 4 */
+ add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.17"));
+
+ /* Leaf marker OID is the Developer ID+ Ticket OID */
+ add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.30"));
+
+ /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
+ require(SecPolicyAddStrongKeySizeOptions(options), errOut);
+
+ require(result = SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket,
+ kSecPolicyNameDeveloperIDPlusTicket, options), errOut);
+
+errOut:
+ CFReleaseNull(options);
+ return result;
+}
+
+SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void) {
+ CFMutableDictionaryRef options = NULL;
+ SecPolicyRef result = NULL;
+
+ require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks), errOut);
+
+ /* No expiration check. */
+ SecPolicyAddBasicCertOptions(options);
+
+ require(result = SecPolicyCreate(kSecPolicyAppleFDRProvisioning,
+ kSecPolicyNameFDRProvisioning, options), errOut);
+errOut:
+ CFReleaseNull(options);
+ return result;
+}
POLICYMACRO(BasicAttestationSystem, 84, , BAA-SCRT, , , AppleBasicAttestationSystem)
POLICYMACRO(BasicAttestationUser, 85, , BAA-UCRT, , , AppleBasicAttestationUser)
POLICYMACRO(iPhoneVPNApplicationSigning, 86, , iPhoneVPNApplicationSigning, , Y, iPhoneVPNApplicationSigning)
+POLICYMACRO(iAPSWAuth, 87, , iAPSWAuth, , Y, iAPSWAuth)
POLICYMACRO(DemoDigitalCatalog, 88, , DemoCatalog, , Y, DemoDigitalCatalogSigning)
+POLICYMACRO(AssetReceipt, 89, , AssetReceipt, , Y, AppleAssetReceipt)
+POLICYMACRO(DeveloperIDPlusTicket, 90, , DeveloperIDPlusTicket, , Y, AppleDeveloperIDPlusTicket)
+POLICYMACRO(FDRProvisioning, 91, , FDRProvisioning, , Y, AppleFDRProvisioning)
// 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
+// T is trust, C is compliance, D is denied, B is blocked
// 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
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(WeakSignature, F, 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(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(BlackListedLeaf, F, B, L, , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED
POLICYCHECKMACRO(GrayListedLeaf, R, T, L, , , 0x8001212A, errSecNotTrusted) //CSSMERR_TP_NOT_TRUSTED
/********************************************************
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(BlackListedKey, F, B, , , , 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
CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD2);
CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD4);
CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD5);
- if (!SecPolicyCheckCertSignatureHashAlgorithms(cert, disallowedHashes)) {
+
+ /* Weak Signature failures only for non-self-signed certs */
+ Boolean isSelfSigned = false;
+ OSStatus status = SecCertificateIsSelfSigned(cert, &isSelfSigned);
+ if (!SecPolicyCheckCertSignatureHashAlgorithms(cert, disallowedHashes) && (status != errSecSuccess || !isSelfSigned)) {
result = false;
}
CFReleaseSafe(disallowedHashes);
void SecLeafPVCInit(SecLeafPVCRef pvc, SecCertificateRef leaf, CFArrayRef policies,
CFAbsoluteTime verifyTime) {
- secdebug("alloc", "%p", pvc);
+ secdebug("alloc", "leafpvc %p", pvc);
// Weird logging policies crashes.
//secdebug("policy", "%@", policies);
pvc->leaf = CFRetainSafe(leaf);
void SecLeafPVCDelete(SecLeafPVCRef pvc) {
- secdebug("alloc", "%p", pvc);
+ secdebug("alloc", "delete leaf pvc %p", pvc);
CFReleaseNull(pvc->policies);
CFReleaseNull(pvc->details);
CFReleaseNull(pvc->callbacks);
CFDataRef
SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters,
- SecKeyRef __unused publicKey, SecKeyRef privateKey,
+ SecKeyRef publicKey, SecKeyRef privateKey,
SecIdentityRef signer, CFTypeRef recipients)
{
CFDataRef csr = NULL;
require(recipient, out);
/* We don't support EC recipients for SCEP yet. */
-#if TARGET_OS_IPHONE
- recipientKey = SecCertificateCopyPublicKey(recipient);
-#else
- recipientKey = SecCertificateCopyPublicKey_ios(recipient);
-#endif
+ recipientKey = SecCertificateCopyKey(recipient);
require(SecKeyGetAlgorithmId(recipientKey) == kSecRSAAlgorithmID, out);
- require(realPublicKey = SecKeyCopyPublicKey(privateKey), out);
+ realPublicKey = SecKeyCopyPublicKey(privateKey);
+ if (!realPublicKey) {
+ /* If we can't get the public key from the private key,
+ * fall back to the public key provided by the caller. */
+ realPublicKey = CFRetainSafe(publicKey);
+ }
+ require(realPublicKey, 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);
CFMutableDictionaryRef parameters = NULL;
require_noerr(SecIdentityCopyCertificate(ca_identity, &ca_certificate), out);
-#if TARGET_OS_IPHONE
- ca_public_key = SecCertificateCopyPublicKey(ca_certificate); /*@@@*/
-#else
- ca_public_key = SecCertificateCopyPublicKey_ios(ca_certificate);
-#endif
+ ca_public_key = SecCertificateCopyKey(ca_certificate);
/* unwrap outer layer: */
policy = SecPolicyCreateBasicX509();
//
/* Caution: These functions take an iOS SecKeyRef. Careful use is required on OS X. */
CFDataRef SecCopyDecryptedForServer(SecKeyRef serverFullKey, CFDataRef encryptedData, CFErrorRef* error)
- __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, __IPHONE_8_0, __IPHONE_11_0,"Migrate to SecKeyCreateEncryptedData with kSecKeyAlgorithmECIESEncryptionStandardVariableIV* or Security Foundation SFIESOperation for improved security (encryption is not compatible)");
+ API_DEPRECATED("Migrate to SecKeyCreateEncryptedData with kSecKeyAlgorithmECIESEncryptionStandardVariableIV* or Security Foundation SFIESOperation for improved security (encryption is not compatible)", macos(10.12,10.13), ios(8.0,11.0));
// SFIESCiphertext
/* Forward declarations of static functions. */
static OSStatus SecTrustEvaluateIfNecessary(SecTrustRef trust);
+static void SecTrustEvaluateIfNecessaryFastAsync(SecTrustRef trust,
+ dispatch_queue_t queue,
+ void (^handler)(OSStatus status));
/* Static functions. */
static CFStringRef SecTrustCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
}
typedef enum {
+ kSecTrustErrorSubTypeBlocked,
kSecTrustErrorSubTypeRevoked,
kSecTrustErrorSubTypeKeySize,
kSecTrustErrorSubTypeWeakHash,
#define __PC_SUBTYPE_T kSecTrustErrorSubTypeTrust
#define __PC_SUBTYPE_C kSecTrustErrorSubTypeCompliance
#define __PC_SUBTYPE_D kSecTrustErrorSubTypeDenied
+#define __PC_SUBTYPE_B kSecTrustErrorSubTypeBlocked
#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
{ __PC_SUBTYPE_##SUBTYPE , OSSTATUS, SEC_TRUST_ERROR_##NAME },
#include "SecPolicyChecks.list"
CFStringRef format = NULL;
CFStringRef certSummary = SecCertificateCopySubjectSummary(SecTrustGetCertificateAtIndex(trust, simpleErrorCertIndex));
switch (simpleErrorSubType) {
+ case kSecTrustErrorSubTypeBlocked: {
+ format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_BLOCKED);
+ break;
+ }
case kSecTrustErrorSubTypeRevoked: {
format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_REVOKED);
break;
return simpleErrorStatus;
}
-static CFErrorRef SecTrustCopyError(SecTrustRef trust) {
+static CF_RETURNS_RETAINED CFErrorRef SecTrustCopyError(SecTrustRef trust) {
if (!trust) { return NULL; }
(void)SecTrustEvaluateIfNecessary(trust);
OSStatus status = errSecSuccess;
CFStringRef detailedError = NULL;
CFStringRef simpleError = NULL;
status = SecTrustCopyErrorStrings(trust, &simpleError, &detailedError);
+ /* failure to obtain either string must not cause a failure to create the CFErrorRef */
+ if (!simpleError) {
+ simpleError = SecCopyErrorMessageString(status, NULL);
+ }
+ if (!detailedError) {
+ detailedError = SecCopyErrorMessageString(status, NULL);
+ }
CFDictionaryRef userInfo = CFDictionaryCreate(NULL, (const void **)&kCFErrorLocalizedDescriptionKey,
(const void **)&detailedError, 1,
&kCFTypeDictionaryKeyCallBacks,
OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
dispatch_queue_t queue, SecTrustCallback result)
{
- CFRetainSafe(trust);
+ CFRetainSafe(trust);
dispatch_async(queue, ^{
SecTrustResultType trustResult;
if (errSecSuccess != SecTrustEvaluate(trust, &trustResult)) {
trustResult = kSecTrustResultInvalid;
}
result(trust, trustResult);
- CFReleaseSafe(trust);
+ CFReleaseSafe(trust);
+ });
+ return errSecSuccess;
+}
+
+OSStatus SecTrustEvaluateFastAsync(SecTrustRef trust,
+ dispatch_queue_t queue, SecTrustCallback result)
+{
+ if (trust == NULL || queue == NULL || result == NULL) {
+ return errSecParam;
+ }
+
+ dispatch_assert_queue(queue);
+ SecTrustEvaluateIfNecessaryFastAsync(trust, queue, ^(OSStatus status) {
+ if (status != noErr) {
+ result(trust, kSecTrustResultInvalid);
+ return;
+ }
+ __block SecTrustResultType trustResult = kSecTrustResultInvalid;
+ dispatch_sync(trust->_trustQueue, ^{
+ trustResult = trust->_trustResult;
+ });
+ /* log to syslog when there is a trust failure */
+ if (trustResult != kSecTrustResultProceed &&
+ trustResult != kSecTrustResultUnspecified) {
+ CFStringRef failureDesc = SecTrustCopyFailureDescription(trust);
+ secerror("Trust evaluate failure:%{public}@", failureDesc);
+ CFRelease(failureDesc);
+ }
+
+
+ result(trust, trustResult);
});
return errSecSuccess;
}
return tr;
}
+typedef void (^trust_handler_t)(SecTrustResultType tr, CFErrorRef error);
+
+static void handle_trust_evaluate_xpc_async(dispatch_queue_t replyq, trust_handler_t trustHandler,
+ enum SecXPCOperation op, 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)
+{
+ securityd_send_async_and_do(op, replyq, ^bool(xpc_object_t message, CFErrorRef *error) {
+ if (!SecXPCDictionarySetCertificates(message, kSecTrustCertificatesKey, certificates, error))
+ return false;
+ if (anchors && !SecXPCDictionarySetCertificates(message, kSecTrustAnchorsKey, anchors, error))
+ return false;
+ if (anchorsOnly)
+ xpc_dictionary_set_bool(message, kSecTrustAnchorsOnlyKey, anchorsOnly);
+ xpc_dictionary_set_bool(message, kSecTrustKeychainsAllowedKey, keychainsAllowed);
+ if (!SecXPCDictionarySetPolicies(message, kSecTrustPoliciesKey, policies, error))
+ return false;
+ if (responses && !SecXPCDictionarySetDataArray(message, kSecTrustResponsesKey, responses, error))
+ return false;
+ if (SCTs && !SecXPCDictionarySetDataArray(message, kSecTrustSCTsKey, SCTs, error))
+ return false;
+ if (trustedLogs && !SecXPCDictionarySetPList(message, kSecTrustTrustedLogsKey, trustedLogs, error))
+ return false;
+ xpc_dictionary_set_double(message, kSecTrustVerifyDateKey, verifyTime);
+ if (exceptions && !SecXPCDictionarySetPList(message, kSecTrustExceptionsKey, exceptions, error))
+ return false;
+ return true;
+ }, ^(xpc_object_t response, CFErrorRef error) {
+ secdebug("trust", "response: %@", response);
+ if (response == NULL || error != NULL) {
+ trustHandler(kSecTrustResultInvalid, error);
+ return;
+ }
+ SecTrustResultType tr = kSecTrustResultInvalid;
+ CFErrorRef error2 = NULL;
+ if (SecXPCDictionaryCopyArrayOptional(response, kSecTrustDetailsKey, details, &error2) &&
+ SecXPCDictionaryCopyDictionaryOptional(response, kSecTrustInfoKey, info, &error2) &&
+ SecXPCDictionaryCopyChainOptional(response, kSecTrustChainKey, chain, &error2)) {
+ tr = SecXPCDictionaryGetNonZeroInteger(response, kSecTrustResultKey, &error2);
+ }
+ trustHandler(tr, error2);
+ CFReleaseNull(error2);
+ });
+}
+
OSStatus validate_array_of_items(CFArrayRef array, CFStringRef arrayItemType, CFTypeID itemTypeID, bool required) {
OSStatus result = errSecSuccess;
CFIndex index, count;
return result;
}
+// IMPORTANT: this MUST be called on the provided queue as it will call the handler synchronously
+// if no asynchronous work is needed
+static void SecTrustEvaluateIfNecessaryFastAsync(SecTrustRef trust,
+ dispatch_queue_t queue,
+ void (^handler)(OSStatus status)) {
+ check(trust);
+ check(queue);
+ check(handler);
+ if (handler == NULL) {
+ return;
+ }
+ if (trust == NULL || queue == NULL) {
+ handler(errSecParam);
+ return;
+ }
+
+ __block bool shouldReturnSuccess = false;
+ __block CFAbsoluteTime verifyTime = SecTrustGetVerifyTime(trust);
+ SecTrustAddPolicyAnchors(trust);
+ dispatch_sync(trust->_trustQueue, ^{
+ if (trust->_trustResult != kSecTrustResultInvalid) {
+ shouldReturnSuccess = true;
+ return;
+ }
+
+ trust->_trustResult = kSecTrustResultOtherError; /* to avoid potential recursion */
+
+ CFReleaseNull(trust->_chain);
+ CFReleaseNull(trust->_details);
+ CFReleaseNull(trust->_info);
+ if (trust->_legacy_info_array) {
+ free(trust->_legacy_info_array);
+ trust->_legacy_info_array = NULL;
+ }
+ if (trust->_legacy_status_array) {
+ free(trust->_legacy_status_array);
+ trust->_legacy_status_array = NULL;
+ }
+
+ os_activity_t activity = os_activity_create("SecTrustEvaluateIfNecessaryFastAsync",
+ OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
+ __block struct os_activity_scope_state_s activityState;
+ os_activity_scope_enter(activity, &activityState);
+ os_release(activity);
+
+ SecTrustValidateInput(trust);
+
+ CFRetainSafe(trust);
+ TRUSTD_XPC_ASYNC(sec_trust_evaluate,
+ handle_trust_evaluate_xpc_async,
+ queue,
+ ^(SecTrustResultType tr, CFErrorRef error) {
+ __block OSStatus result = errSecInternalError;
+ dispatch_sync(trust->_trustQueue, ^{
+ trust->_trustResult = tr;
+ if (trust->_trustResult == kSecTrustResultInvalid /* TODO check domain */ &&
+ SecErrorGetOSStatus(error) == errSecNotAvailable &&
+ CFArrayGetCount(trust->_certificates)) {
+ /* We failed to talk to securityd. The only time this should
+ happen is when we are running prior to launchd enabling
+ registration of services. This currently happens when we
+ are running from the ramdisk. To make ASR happy we initialize
+ _chain and return success with a failure as the trustResult, to
+ make it seem like we did a cert evaluation, so ASR can extract
+ the public key from the leaf. */
+ SecCertificateRef leafCert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0);
+ CFArrayRef leafCertArray = CFArrayCreate(NULL, (const void**)&leafCert, 1, &kCFTypeArrayCallBacks);
+ trust->_chain = leafCertArray;
+ result = errSecSuccess;
+ return;
+ }
+ result = SecOSStatusWith(^bool (CFErrorRef *error2) {
+ if (error2 != NULL) {
+ *error2 = error;
+ }
+ return trust->_trustResult != kSecTrustResultInvalid;
+ });
+ });
+ os_activity_scope_leave(&activityState);
+ handler(result);
+ CFReleaseSafe(trust);
+ },
+ trust->_certificates, trust->_anchors, trust->_anchorsOnly, trust->_keychainsAllowed,
+ trust->_policies, trust->_responses, trust->_SCTs, trust->_trustedLogs,
+ verifyTime, SecAccessGroupsGetCurrent(), trust->_exceptions,
+ &trust->_details, &trust->_info, &trust->_chain);
+ });
+ if (shouldReturnSuccess) {
+ handler(errSecSuccess);
+ }
+}
+
/* Helper for the qsort below. */
static int compare_strings(const void *a1, const void *a2) {
CFStringRef s1 = *(CFStringRef *)a1;
return;
}
SecCertificateRef leaf = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0);
-#if TARGET_OS_OSX
- trust->_publicKey = SecCertificateCopyPublicKey_ios(leaf);
-#else
- trust->_publicKey = SecCertificateCopyPublicKey(leaf);
-#endif
+ trust->_publicKey = SecCertificateCopyKey(leaf);
if (trust->_publicKey) {
publicKey = CFRetainSafe(trust->_publicKey);
}
dispatch_sync(trust->_trustQueue, ^{
if (trust->_chain) {
SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_chain, 0);
-#if TARGET_OS_OSX
- trust->_publicKey = SecCertificateCopyPublicKey_ios(cert);
-#else
- trust->_publicKey = SecCertificateCopyPublicKey(cert);
-#endif
+ trust->_publicKey = SecCertificateCopyKey(cert);
publicKey = CFRetainSafe(trust->_publicKey);
}
});
bool badLinkage;
bool unknownCritExtn;
bool untrustedAnchor;
+ bool missingIntermediate;
bool hostnameMismatch;
bool policyFail;
bool invalidCert;
} else if (CFEqual(key, kSecPolicyCheckAnchorTrusted)
|| CFEqual(key, kSecPolicyCheckAnchorSHA1)
|| CFEqual(key, kSecPolicyCheckAnchorSHA256)
- || CFEqual(key, kSecPolicyCheckAnchorApple)
- || CFEqual(key, kSecPolicyCheckMissingIntermediate)) {
+ || CFEqual(key, kSecPolicyCheckAnchorApple)) {
tf->untrustedAnchor = true;
+ } else if (CFEqual(key, kSecPolicyCheckMissingIntermediate)) {
+ tf->missingIntermediate = true;
} else if (CFEqual(key, kSecPolicyCheckSSLHostname)) {
tf->hostnameMismatch = true;
} else if (CFEqual(key, kSecPolicyCheckTemporalValidity)) {
if (tf.untrustedAnchor) {
appendError(properties, CFSTR("Root certificate is not trusted."), localized);
}
+ if (tf.missingIntermediate) {
+ appendError(properties, CFSTR("Unable to build chain to root certificate."), localized);
+ }
if (tf.hostnameMismatch) {
appendError(properties, CFSTR("Hostname mismatch."), localized);
}
const char *kSecXPCOTRSession = "otrsess"; // OTR session bytes
const char *kSecXPCData = "data"; // Data to process
const char *kSecXPCOTRReady = "otrrdy"; // OTR ready for messages
-const char *kSecXPCKeyDeviceID = "deviceID";
-const char *kSecXPCKeySendIDSMessage = "sendIDSMessageCommand";
-const char *kSecXPCKeyIDSMessage = "idsMessage";
const char *kSecXPCKeyViewName = "viewname";
const char *kSecXPCKeyViewActionCode = "viewactioncode";
const char *kSecXPCKeyHSA2AutoAcceptInfo = "autoacceptinfo";
const char *kSecXPCKeyBackupKeybagIdentifier = "backupKeybagID";
const char *kSecXPCKeyBackupKeybagPath = "backupKeybagPath";
const char *kSecXPCVersion = "version";
-
+const char *kSecXPCKeySignInAnalytics = "signinanalytics";
//
// XPC Functions for both client and server.
//
return CFSTR("GetAllTheRings");
case kSecXPCOpGetLastDepartureReason:
return CFSTR("GetLastDepartureReason");
- case kSecXPCOpHandleIDSMessage:
- return CFSTR("HandleIDSMessage");
case kSecXPCOpSyncWithKVSPeer:
return CFSTR("SyncKVSPeer");
- case kSecXPCOpSyncWithIDSPeer:
- return CFSTR("SyncIDSPeer");
- case kSecXPCOpIDSDeviceID:
- return CFSTR("IDSDeviceID");
case kSecXPCOpClearKVSPeerMessage:
return CFSTR("kSecXPCOpClearKVSPeerMessage");
case kSecXPCOpLoggedOutOfAccount:
return CFSTR("LoggedOutOfAccount");
- case kSecXPCOpPingTest:
- return CFSTR("PingTest");
case kSecXPCOpProcessSyncWithAllPeers:
return CFSTR("ProcessSyncWithAllPeers");
case kSecXPCOpProcessSyncWithPeers:
return CFSTR("RejectApplicants");
case kSecXPCOpRemoveThisDeviceFromCircle:
return CFSTR("RemoveThisDeviceFromCircle");
+ case kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics:
+ return CFSTR("RemoveThisDeviceFromCircleWithAnalytics");
case kSecXPCOpRemovePeersFromCircle:
return CFSTR("RemovePeersFromCircle");
- case kSecXPCOpRequestDeviceID:
- return CFSTR("RequestDeviceID");
+ case kSecXPCOpRemovePeersFromCircleWithAnalytics:
+ return CFSTR("RemovePeersFromCircleWithAnalytics");
case kSecXPCOpRequestEnsureFreshParameters:
return CFSTR("RequestEnsureFreshParameters");
case kSecXPCOpRequestToJoin:
return CFSTR("RequestToJoin");
+ case kSecXPCOpRequestToJoinWithAnalytics:
+ return CFSTR("RequestToJoinWithAnalytics");
case kSecXPCOpRequestToJoinAfterRestore:
return CFSTR("RequestToJoinAfterRestore");
+ case kSecXPCOpRequestToJoinAfterRestoreWithAnalytics:
+ return CFSTR("RequestToJoinAfterRestoreWithAnalytics");
case kSecXPCOpResetToEmpty:
return CFSTR("ResetToEmpty");
+ case kSecXPCOpResetToEmptyWithAnalytics:
+ return CFSTR("ResetToEmptyWithAnalytics");
case kSecXPCOpResetToOffering:
return CFSTR("ResetToOffering");
case kSecXPCOpRingStatus:
return CFSTR("RingStatus");
case kSecXPCOpRollKeys:
return CFSTR("RollKeys");
- case kSecXPCOpSecurityProperty:
- return CFSTR("SecurityProperty");
- case kSecXPCOpSendIDSMessage:
- return CFSTR("SendIDSMessage");
case kSecXPCOpSetBagForAllSlices:
return CFSTR("SetBagForAllSlices");
- case kSecXPCOpSetDeviceID:
- return CFSTR("SetDeviceID");
case kSecXPCOpSetLastDepartureReason:
return CFSTR("SetLastDepartureReason");
case kSecXPCOpSetNewPublicBackupKey:
return CFSTR("SetUserCredentials");
case kSecXPCOpSetUserCredentialsAndDSID:
return CFSTR("SetUserCredentialsAndDSID");
+ case kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics:
+ return CFSTR("SetUserCredentialsAndDSIDWithAnalytics");
case kSecXPCOpTryUserCredentials:
return CFSTR("TryUserCredentials");
case kSecXPCOpValidateUserPublic:
*/
#include <CoreFoundation/CoreFoundation.h>
+#import <Foundation/Foundation.h>
#include <Security/SecItem.h>
#include <Security/SecItemPriv.h>
#include <Security/SecAccessControl.h>
#include <Security/SecAccessControlPriv.h>
+#import <SecurityFoundation/SFKeychain.h>
+
//
// Craptastic hacks.
-
+#ifndef _SECURITY_SECKEYCHAIN_H_
typedef uint32_t SecProtocolType;
typedef uint32_t SecAuthenticationType;
+#endif
static CFMutableDictionaryRef
const void *keys[11], *values[11];
CFIndex ix = 0;
+ if (do_delete && !serverName && !securityDomain && !accountName && !path && !port && !protocol && !authenticationType) {
+ return SHOW_USAGE_MESSAGE;
+ }
+
keys[ix] = kSecClass;
values[ix++] = kSecClassInternetPassword;
if (serverName) {
const void *keys[6], *values[6];
CFIndex ix = 0;
+ if (do_delete && !serviceName && !accountName) {
+ return SHOW_USAGE_MESSAGE;
+ }
+
keys[ix] = kSecClass;
values[ix++] = kSecClassGenericPassword;
if (serviceName) {
return result;
}
+static SFServiceIdentifier* serviceIdentifierInQuery(NSDictionary* query)
+{
+ NSString* domain = query[@"domain"];
+ NSString* bundleID = query[@"bundleID"];
+ NSString* accessGroup = query[@"accessGroup"];
+ NSString* customServiceID = query[@"customServiceID"];
+
+ SFServiceIdentifier* serviceIdentifier = nil;
+ if (domain) {
+ serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:domain forType:SFServiceIdentifierTypeDomain];
+ }
+ else if (bundleID) {
+ serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:bundleID forType:SFServiceIdentifierTypeBundleID];
+ }
+ else if (accessGroup) {
+ serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:accessGroup forType:SFServiceIdentifierTypeAccessGroup];
+ }
+ else if (customServiceID) {
+ serviceIdentifier = [[SFServiceIdentifier alloc] initWithServiceID:customServiceID forType:SFServiceIdentifierTypeCustom];
+ }
+ if (!serviceIdentifier) {
+ sec_error("need service identifier");
+ }
+
+ return serviceIdentifier;
+}
+
+static SFPasswordCredential* lookupCredential(SFServiceIdentifier* serviceIdentifier, NSString* username)
+{
+ __block SFPasswordCredential* result = nil;
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ [[SFCredentialStore defaultCredentialStore] lookupCredentialsForServiceIdentifiers:@[serviceIdentifier] withResultHandler:^(NSArray<SFCredential*>* results, NSError* error) {
+ if (error) {
+ sec_error("error looking up credentials: %s", error.description.UTF8String);
+ }
+ else {
+ bool foundCredential = false;
+ for (SFPasswordCredential* credential in results) {
+ if ([credential.username isEqualToString:username]) {
+ result = credential;
+ dispatch_semaphore_signal(semaphore);
+ return;
+ }
+ }
+
+ if (!foundCredential) {
+ sec_error("did not find credential");
+ }
+ }
+
+ dispatch_semaphore_signal(semaphore);
+ }];
+ if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
+ sec_error("timed out trying to communicate with credential store");
+ }
+
+ return result;
+}
+
+static SFPasswordCredential* credentialFromQuery(NSDictionary* query)
+{
+ NSString* username = query[@"username"];
+ NSData* passwordData = query[(__bridge id)kSecValueData];
+ NSString* password = [[NSString alloc] initWithData:passwordData encoding:NSUTF8StringEncoding];
+ if (!username) {
+ sec_error("need username");
+ return nil;
+ }
+ if (!password) {
+ sec_error("need password");
+ return nil;
+ }
+
+ SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery(query);
+
+ if (username && password && serviceIdentifier) {
+ return [[SFPasswordCredential alloc] initWithUsername:username password:password primaryServiceIdentifier:serviceIdentifier];
+ }
+ else {
+ return nil;
+ }
+}
+
+static SFAccessPolicy* accessPolicyInQuery(NSDictionary* query)
+{
+ CFStringRef accessibility = (__bridge CFStringRef)query[(__bridge id)kSecAttrAccessible];
+ if (!accessibility) {
+ accessibility = kSecAttrAccessibleWhenUnlocked;
+ }
+
+ SFAccessPolicy* accessPolicy = [SFAccessPolicy accessPolicyWithSecAccessibility:accessibility error:nil];
+ NSNumber* synchronizableValue = query[(__bridge id)kSecAttrSynchronizable];
+ if (accessPolicy.sharingPolicy == SFSharingPolicyWithTrustedDevices && synchronizableValue && synchronizableValue.boolValue == NO) {
+ accessPolicy.sharingPolicy = SFSharingPolicyWithBackup;
+ }
+ if (!accessPolicy) {
+ sec_error("need access policy");
+ }
+
+ return accessPolicy;
+}
+
int keychain_item(int argc, char * const *argv) {
- int ch, result = 0;
+ int ch = 0;
+ __block int result = 0;
CFMutableDictionaryRef query, update = NULL;
bool get_password = false;
bool do_delete = false;
CFShow(query);
OSStatus error;
+ bool useCredentialStore = [(__bridge id)CFDictionaryGetValue(query, kSecClass) isEqual:@"credential"];
if (do_add) {
- error = SecItemAdd(query, NULL);
- if (error) {
- sec_perror("SecItemAdd", error);
- result = 1;
+ if (useCredentialStore) {
+ SFPasswordCredential* credential = credentialFromQuery((__bridge NSDictionary*)query);
+ SFAccessPolicy* accessPolicy = accessPolicyInQuery((__bridge NSDictionary*)query);
+ if (credential && accessPolicy) {
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ [[SFCredentialStore defaultCredentialStore] addCredential:credential withAccessPolicy:accessPolicy resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ if (error) {
+ sec_error("error adding credential to credential store: %s", error.description.UTF8String);
+ result = 1;
+ }
+ dispatch_semaphore_signal(semaphore);
+ }];
+ if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
+ sec_error("timed out waiting for response from credential store");
+ result = 1;
+ }
+ }
+ else {
+ sec_error("need username, password, service identiifer, and access policy to create a credential");
+ result = 1;
+ }
+ }
+ else {
+ error = SecItemAdd(query, NULL);
+ if (error) {
+ sec_perror("SecItemAdd", error);
+ result = 1;
+ }
}
} else if (update) {
- error = SecItemUpdate(query, update);
- if (error) {
- sec_perror("SecItemUpdate", error);
- result = 1;
+ if (useCredentialStore) {
+ NSString* username = (__bridge NSString*)CFDictionaryGetValue(query, CFSTR("username"));
+ SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery((__bridge NSDictionary*)query);
+ SFPasswordCredential* credential = lookupCredential(serviceIdentifier, username);
+ if (credential) {
+ SFPasswordCredential* updatedCredential = credentialFromQuery((__bridge NSDictionary*)update);
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ [[SFCredentialStore defaultCredentialStore] replaceOldCredential:credential withNewCredential:updatedCredential resultHandler:^(NSString* newPersistentIdentifier, NSError* error) {
+ if (error) {
+ sec_error("error updating credential: %s", error.description.UTF8String);
+ result = 1;
+ }
+ dispatch_semaphore_signal(semaphore);
+ }];
+ if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
+ sec_error("timed out trying to communicate with credential store");
+ result = 1;
+ }
+ }
+ else {
+ result = 1;
+ }
+ }
+ else {
+ error = SecItemUpdate(query, update);
+ if (error) {
+ sec_perror("SecItemUpdate", error);
+ result = 1;
+ }
}
} else if (do_delete) {
- error = SecItemDelete(query);
- if (error) {
- sec_perror("SecItemDelete", error);
- result = 1;
+ if (useCredentialStore) {
+ NSString* username = (__bridge NSString*)CFDictionaryGetValue(query, CFSTR("username"));
+ SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery((__bridge NSDictionary*)query);
+ SFPasswordCredential* credential = lookupCredential(serviceIdentifier, username);
+ if (credential) {
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ [[SFCredentialStore defaultCredentialStore] removeCredentialWithPersistentIdentifier:credential.persistentIdentifier withResultHandler:^(BOOL success, NSError* error) {
+ if (!success) {
+ sec_error("failed to remove credential with error: %s", error.description.UTF8String);
+ result = 1;
+ }
+ dispatch_semaphore_signal(semaphore);
+ }];
+ if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
+ sec_error("timed out trying to communicate with credential store");
+ result = 1;
+ }
+ }
+ else {
+ result = 1;
+ }
+ }
+ else {
+ error = SecItemDelete(query);
+ if (error) {
+ sec_perror("SecItemDelete", error);
+ result = 1;
+ }
}
} else {
- if (!do_delete && CFDictionaryGetValue(query, kSecUseAuthenticationUI) == NULL)
- CFDictionarySetValue(query, kSecUseAuthenticationUI, kSecUseAuthenticationUISkip);
- do_find_or_delete(query, do_delete);
+ if (useCredentialStore) {
+ NSString* username = (__bridge NSString*)CFDictionaryGetValue(query, CFSTR("username"));
+ SFServiceIdentifier* serviceIdentifier = serviceIdentifierInQuery((__bridge NSDictionary*)query);
+ SFPasswordCredential* credential = lookupCredential(serviceIdentifier, username);
+ if (credential) {
+ CFStringWriteToFileWithNewline((__bridge CFStringRef)credential.description, stdout);
+ }
+ else {
+ result = 1;
+ }
+ }
+ else {
+ if (!do_delete && CFDictionaryGetValue(query, kSecUseAuthenticationUI) == NULL) {
+ CFDictionarySetValue(query, kSecUseAuthenticationUI, kSecUseAuthenticationUISkip);
+ }
+ do_find_or_delete(query, do_delete);
+ }
}
out:
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));
+typedef void (^securityd_handler_t)(xpc_object_t reply, CFErrorRef error);
+void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq,
+ bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
+ securityd_handler_t handler);
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);
/* tmp1 = B+1 */
const cc_size tmp_n = ccn_nof_size(A_i_len + 1) > ccn_nof_size(hash_blocksize) ? ccn_nof_size(A_i_len + 1) : ccn_nof_size(hash_blocksize);
- cc_unit tmp1[tmp_n];
+ cc_unit *tmp1 = (cc_unit *)malloc(tmp_n * sizeof(cc_unit));
+ if (!tmp1) {
+ free(A_i);
+ free(I_data);
+ free(temp_buf);
+ return -1;
+ }
ccn_read_uint(tmp_n, tmp1, A_i_len, A_i);
ccn_add1(tmp_n, tmp1, tmp1, 1);
free(A_i);
- cc_unit tmp2[tmp_n];
+ cc_unit *tmp2 = (cc_unit *)malloc(tmp_n * sizeof(cc_unit));
+ if (!tmp2) {
+ free(I_data);
+ free(temp_buf);
+ free(tmp1);
+ return -1;
+ }
unsigned int j;
for (j = 0; j < I_length; j+=hash_blocksize) {
/* tempg = I[j]; */
}
cursor += hash_outputsize;
+ free(tmp1);
+ free(tmp2);
}
/*
dispatch_semaphore_signal(sema1);
}];
-
- [[self.connection remoteObjectProxy] idsPerformanceCounters:^(NSDictionary <NSString *, NSNumber *> *counters){
- if (counters == NULL){
- printf("no IDS counters!");
- return;
- }
- [merged addEntriesFromDictionary:counters];
- dispatch_semaphore_signal(sema2);
- }];
-
[[self.connection remoteObjectProxy] rateLimitingPerformanceCounters:^(NSDictionary <NSString *, NSString *> *returnedDiagnostics){
if (returnedDiagnostics == NULL){
printf("no rate limiting counters!");
CFUserNotificationRef notification = NULL;
NSMutableDictionary *notification_dictionary = NULL;
NSString *request_key;
- NSString *request_format;
NSString *default_button_key;
NSString *alternate_button_key;
NSString *other_button_key;
goto out;
}
request_key = [NSString stringWithFormat:@"SWC_REQUEST_%s", op];
- request_format = NSLocalizedStringFromTableInBundle(request_key, swca_string_table, swca_get_security_bundle(), nil);
alternate_button_key = (op) ? [NSString stringWithFormat:@"SWC_ALLOW_%s", op] : nil;
default_button_key = @"SWC_NEVER";
other_button_key = @"SWC_DENY";
info_message_key = @"SWC_INFO_MESSAGE";
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
- notification_dictionary[(__bridge NSString *)kCFUserNotificationAlertHeaderKey] = [NSString stringWithFormat:request_format, client.client_name, domain];
-#pragma clang diagnostic pop
+ notification_dictionary[(__bridge NSString *)kCFUserNotificationAlertHeaderKey] = NSLocalizedStringFromTableInBundle(request_key, swca_string_table, swca_get_security_bundle(), nil);;
notification_dictionary[(__bridge NSString *)kCFUserNotificationAlertMessageKey] = NSLocalizedStringFromTableInBundle(info_message_key, swca_string_table, swca_get_security_bundle(), nil);
notification_dictionary[(__bridge NSString *)kCFUserNotificationDefaultButtonTitleKey] = NSLocalizedStringFromTableInBundle(default_button_key, swca_string_table, swca_get_security_bundle(), nil);
notification_dictionary[(__bridge NSString *)kCFUserNotificationAlternateButtonTitleKey] = NSLocalizedStringFromTableInBundle(alternate_button_key, swca_string_table, swca_get_security_bundle(), nil);
// select a dictionary from an input array of dictionaries
if (swca_select_item(items, client, accessGroups, &result, &error) && result) {
#if TARGET_OS_IOS
- if (MGGetBoolAnswer(kMGOPearlIDCapability) &&
+ LAContext *ctx = [LAContext new];
+ if ([ctx canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil] &&
[[MCProfileConnection sharedConnection] isAuthenticationBeforeAutoFillRequired]) {
- LAContext *ctx = [LAContext new];
NSString *subTitle = NSLocalizedStringFromTableInBundle(@"SWC_FILLPWD", swca_string_table, swca_get_security_bundle(), nil);
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[ctx evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:subTitle reply:^(BOOL success, NSError * _Nullable laError) {
- if (success || ([laError.domain isEqual:LAErrorDomain] && laError.code == LAErrorPasscodeNotSet))
+ if (success || ([laError.domain isEqual:LAErrorDomain] && laError.code == LAErrorPasscodeNotSet)) {
SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
+ }
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
extern const char *kSecXPCKeyDigest;
extern const char *kSecXPCKeyCertificate;
extern const char *kSecXPCKeySettings;
-extern const char *kSecXPCKeyDeviceID;
-extern const char *kSecXPCKeyIDSMessage;
-extern const char *kSecXPCKeySendIDSMessage;
extern const char *kSecXPCKeyEscrowLabel;
extern const char *kSecXPCKeyTriesLabel;
extern const char *kSecXPCKeyViewName;
#include <utilities/SecAKSWrappers.h>
#include <ipc/securityd_client.h>
+#include "server_security_helpers.h"
+
struct securityd *gSecurityd;
struct trustd *gTrustd;
CFSTR("lockdown-identities"),
CFSTR("123456.test.group"),
CFSTR("123456.test.group2"),
+ CFSTR("com.apple.cfnetwork"),
#else
CFSTR("sync"),
#endif
CFSTR("com.apple.security.sos-usercredential"),
CFSTR("com.apple.sbd"),
CFSTR("com.apple.lakitu"),
+ CFSTR("com.apple.security.securityd"),
kSecAttrAccessGroupToken,
NULL);
}
}
// Only for testing.
-void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
void SecAccessGroupsSetCurrent(CFArrayRef accessGroups) {
// Not thread safe at all, but OK because it is meant to be used only by tests.
gClient.accessGroups = accessGroups;
xpc_release(oldConection);
}
+
+#define SECURITYD_MAX_XPC_TRIES 4
+// Per <rdar://problem/17829836> N61/12A342: Audio Playback... for why this needs to be at least 3, so we made it 4.
+
+static bool
+_securityd_process_message_reply(xpc_object_t *reply,
+ CFErrorRef *error,
+ xpc_connection_t connection,
+ uint64_t operation)
+{
+ if (xpc_get_type(*reply) != XPC_TYPE_ERROR) {
+ return true;
+ }
+ CFIndex code = 0;
+ if (*reply == XPC_ERROR_CONNECTION_INTERRUPTED || *reply == XPC_ERROR_CONNECTION_INVALID) {
+ code = kSecXPCErrorConnectionFailed;
+ seccritical("Failed to talk to %s after %d attempts.",
+ (is_trust_operation((enum SecXPCOperation)operation)) ? "trustd" :
+#if TARGET_OS_IPHONE
+ "securityd",
+#else
+ "secd",
+#endif
+ SECURITYD_MAX_XPC_TRIES);
+ } else if (*reply == XPC_ERROR_TERMINATION_IMMINENT) {
+ code = kSecXPCErrorUnknown;
+ } else {
+ code = kSecXPCErrorUnknown;
+ }
+
+ char *conn_desc = xpc_copy_description(connection);
+ const char *description = xpc_dictionary_get_string(*reply, XPC_ERROR_KEY_DESCRIPTION);
+ SecCFCreateErrorWithFormat(code, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("%s: %s"), conn_desc, description);
+ free(conn_desc);
+ xpc_release(*reply);
+ *reply = NULL;
+ return false;
+}
+
+
XPC_RETURNS_RETAINED
xpc_object_t
securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error)
uint64_t operation = xpc_dictionary_get_uint64(message, kSecXPCKeyOperation);
xpc_connection_t connection = securityd_connection_for_operation((enum SecXPCOperation)operation);
- const int max_tries = 4; // Per <rdar://problem/17829836> N61/12A342: Audio Playback... for why this needs to be at least 3, so we made it 4.
+ const int max_tries = SECURITYD_MAX_XPC_TRIES;
unsigned int tries_left = max_tries;
do {
reply = xpc_connection_send_message_with_reply_sync(connection, message);
} while (reply == XPC_ERROR_CONNECTION_INTERRUPTED && --tries_left > 0);
- if (xpc_get_type(reply) == XPC_TYPE_ERROR) {
- CFIndex code = 0;
- if (reply == XPC_ERROR_CONNECTION_INTERRUPTED || reply == XPC_ERROR_CONNECTION_INVALID) {
- code = kSecXPCErrorConnectionFailed;
- seccritical("Failed to talk to %s after %d attempts.",
- (is_trust_operation((enum SecXPCOperation)operation)) ? "trustd" :
-#if TARGET_OS_IPHONE
- "securityd",
-#else
- "secd",
-#endif
- max_tries);
- } else if (reply == XPC_ERROR_TERMINATION_IMMINENT)
- code = kSecXPCErrorUnknown;
- else
- code = kSecXPCErrorUnknown;
-
- char *conn_desc = xpc_copy_description(connection);
- const char *description = xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION);
- SecCFCreateErrorWithFormat(code, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("%s: %s"), conn_desc, description);
- free(conn_desc);
- xpc_release(reply);
- reply = NULL;
- }
+ _securityd_process_message_reply(&reply, error, connection, operation);
return reply;
}
+static void
+_securityd_message_with_reply_async_inner(xpc_object_t message,
+ dispatch_queue_t replyq,
+ securityd_handler_t handler,
+ uint32_t tries_left)
+{
+ uint64_t operation = xpc_dictionary_get_uint64(message, kSecXPCKeyOperation);
+ xpc_connection_t connection = securityd_connection_for_operation((enum SecXPCOperation)operation);
+
+ xpc_retain(message);
+ dispatch_retain(replyq);
+ securityd_handler_t handlerCopy = Block_copy(handler);
+ xpc_connection_send_message_with_reply(connection, message, replyq, ^(xpc_object_t _Nonnull reply) {
+ if (reply == XPC_ERROR_CONNECTION_INTERRUPTED && tries_left > 0) {
+ _securityd_message_with_reply_async_inner(message, replyq, handlerCopy, tries_left - 1);
+ } else {
+ CFErrorRef error = NULL;
+ _securityd_process_message_reply(&reply, &error, connection, operation);
+ handlerCopy(reply, error);
+ CFReleaseNull(error);
+ }
+ xpc_release(message);
+ dispatch_release(replyq);
+ Block_release(handlerCopy);
+ });
+}
+
+void
+securityd_message_with_reply_async(xpc_object_t message,
+ dispatch_queue_t replyq,
+ securityd_handler_t handler)
+{
+ _securityd_message_with_reply_async_inner(message, replyq, handler, SECURITYD_MAX_XPC_TRIES);
+}
+
XPC_RETURNS_RETAINED
xpc_object_t
securityd_create_message(enum SecXPCOperation op, CFErrorRef* error)
return ok;
}
+void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq,
+ bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
+ securityd_handler_t handler) {
+ CFErrorRef error = NULL;
+ xpc_object_t message = securityd_create_message(op, &error);
+ if (message == NULL) {
+ handler(NULL, error);
+ CFReleaseNull(error);
+ return;
+ }
+
+ if (add_to_message != NULL) {
+ if (!add_to_message(message, &error)) {
+ handler(NULL, error);
+ xpc_release(message);
+ CFReleaseNull(error);
+ return;
+ }
+ }
+
+ securityd_message_with_reply_async(message, replyq, ^(xpc_object_t reply, CFErrorRef error2) {
+ if (error2 != NULL) {
+ handler(NULL, error2);
+ return;
+ }
+ CFErrorRef error3 = NULL;
+ if (!securityd_message_no_error(reply, &error3)) {
+ handler(NULL, error3);
+ CFReleaseNull(error3);
+ return;
+ }
+ handler(reply, NULL);
+ });
+ xpc_release(message);
+}
+
CFDictionaryRef
_SecSecuritydCopyWhoAmI(CFErrorRef *error)
{
return _SecSecuritydCopyEndpoint(kSecXPCOpKeychainControlEndpoint, error);
}
+
+XPC_RETURNS_RETAINED xpc_endpoint_t
+_SecSecuritydCopySFKeychainEndpoint(CFErrorRef* error)
+{
+ return _SecSecuritydCopyEndpoint(kSecXPCOpSFKeychainEndpoint, error);
+}
<true/>
<key>com.apple.securityd.sos</key>
<true/>
+ <key>com.apple.security.sfkeychainserver</key>
+ <true/>
</dict>
<key>ProgramArguments</key>
<array>
<true/>
<key>com.apple.securityd.sos</key>
<true/>
+ <key>com.apple.security.sfkeychainserver</key>
+ <true/>
</dict>
<key>ProgramArguments</key>
<array>
#define SECURITYD_XPC(sdp, wrapper, ...) ((gSecurityd && gSecurityd->sdp) ? gSecurityd->sdp(__VA_ARGS__) : wrapper(sdp ## _id, __VA_ARGS__))
#define TRUSTD_XPC(sdp, wrapper, ...) ((gTrustd && gTrustd->sdp) ? gTrustd->sdp(__VA_ARGS__) : wrapper(sdp ## _id, __VA_ARGS__))
+#define TRUSTD_XPC_ASYNC(sdp, wrapper, q, h, ...) do { \
+ if (gTrustd != NULL && gTrustd->sdp != NULL) { \
+ dispatch_async(q, ^{ \
+ CFErrorRef _error = NULL; \
+ SecTrustResultType _tr = gTrustd->sdp(__VA_ARGS__, &_error); \
+ h(_tr, _error); \
+ }); \
+ } else { \
+ wrapper(q, h, sdp ## _id, __VA_ARGS__); \
+ } \
+} while (0)
+
//
// MARK: Object to XPC format conversion.
//
extern const char *kSecXPCOTRSession; // OTR session bytes
extern const char *kSecXPCData; // Data to process
extern const char *kSecXPCOTRReady; // OTR ready for messages
-extern const char *kSecXPCKeyDeviceID;
-extern const char *kSecXPCKeyIDSMessage;
extern const char *kSecXPCKeyViewName;
extern const char *kSecXPCKeyViewActionCode;
-extern const char *kSecXPCKeySendIDSMessage;
extern const char *kSecXPCKeyHSA2AutoAcceptInfo;
extern const char *kSecXPCKeyEscrowLabel;
extern const char *kSecXPCKeyTriesLabel;
extern const char *kSecXPCKeySet;
extern const char *kSecXPCKeySet2;
extern const char *kSecXPCVersion;
-
+extern const char *kSecXPCKeySignInAnalytics;
extern const char *kSecXPCKeyReason;
//
kSecXPCOpTryUserCredentials,
kSecXPCOpSetUserCredentials,
kSecXPCOpSetUserCredentialsAndDSID,
+ kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics,
kSecXPCOpCanAuthenticate,
kSecXPCOpPurgeUserCredentials,
kSecXPCOpDeviceInCircle,
kSecXPCOpRequestToJoin,
+ kSecXPCOpRequestToJoinWithAnalytics,
kSecXPCOpRequestToJoinAfterRestore,
+ kSecXPCOpRequestToJoinAfterRestoreWithAnalytics,
kSecXPCOpResetToOffering,
kSecXPCOpResetToEmpty,
+ kSecXPCOpResetToEmptyWithAnalytics,
kSecXPCOpView,
kSecXPCOpViewSet,
- kSecXPCOpSecurityProperty,
+ kSecXPCOpViewSetWithAnalytics,
kSecXPCOpRemoveThisDeviceFromCircle,
+ kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics,
kSecXPCOpRemovePeersFromCircle,
+ kSecXPCOpRemovePeersFromCircleWithAnalytics,
kSecXPCOpLoggedOutOfAccount,
kSecXPCOpBailFromCircle,
kSecXPCOpAcceptApplicants,
kSecXPCOpSetNewPublicBackupKey,
kSecXPCOpSetBagForAllSlices,
kSecXPCOpWaitForInitialSync,
+ kSecXPCOpWaitForInitialSyncWithAnalytics,
kSecXPCOpCopyYetToSyncViews,
kSecXPCOpSetEscrowRecord,
kSecXPCOpGetEscrowRecord,
sec_item_certificate_exists_id,
kSecXPCOpBackupKeybagAdd,
kSecXPCOpBackupKeybagDelete,
+ kSecXPCOpSFKeychainEndpoint,
kSecXPCOpKeychainControlEndpoint,
kSecXPCOpTLSAnaltyicsReport,
};
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_SetUserCredentialsAndDSIDWithAnalytics)(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error);
bool (*soscc_CanAuthenticate)(CFErrorRef *error);
bool (*soscc_PurgeUserCredentials)(CFErrorRef *error);
SOSCCStatus (*soscc_ThisDeviceIsInCircle)(CFErrorRef* error);
bool (*soscc_RequestToJoinCircle)(CFErrorRef* error);
+ bool (*soscc_RequestToJoinCircleWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error);
bool (*soscc_RequestToJoinCircleAfterRestore)(CFErrorRef* error);
+ bool (*soscc_RequestToJoinCircleAfterRestoreWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error);
bool (*soscc_RequestEnsureFreshParameters)(CFErrorRef* error);
CFStringRef (*soscc_GetAllTheRings)(CFErrorRef *error);
bool (*soscc_ApplyToARing)(CFStringRef ringName, CFErrorRef* error);
bool (*soscc_WithdrawlFromARing)(CFStringRef ringName, CFErrorRef* error);
bool (*soscc_EnableRing)(CFStringRef ringName, CFErrorRef* error);
SOSRingStatus (*soscc_RingStatus)(CFStringRef ringName, CFErrorRef* error);
- CFStringRef (*soscc_CopyDeviceID)(CFErrorRef* error);
- bool (*soscc_SetDeviceID)(CFStringRef IDS, CFErrorRef *error);
- HandleIDSMessageReason (*soscc_HandleIDSMessage)(CFDictionaryRef IDS, CFErrorRef *error);
- bool (*soscc_CheckIDSRegistration)(CFStringRef message, CFErrorRef *error);
- bool (*soscc_PingTest)(CFStringRef message, CFErrorRef *error);
- bool (*soscc_GetIDSIDFromIDS)(CFErrorRef *error);
bool (*soscc_SetToNew)(CFErrorRef *error);
bool (*soscc_ResetToOffering)(CFErrorRef* error);
bool (*soscc_ResetToEmpty)(CFErrorRef* error);
+ bool (*soscc_ResetToEmptyWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error);
SOSViewResultCode (*soscc_View)(CFStringRef view, SOSViewActionCode action, CFErrorRef *error);
bool (*soscc_ViewSet)(CFSetRef enabledViews, CFSetRef disabledViews);
- SOSSecurityPropertyResultCode (*soscc_SecurityProperty)(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error);
+ bool (*soscc_ViewSetWithAnalytics)(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent);
bool (*soscc_RegisterSingleRecoverySecret)(CFDataRef backupSlice, bool forV0Only, CFErrorRef *error);
bool (*soscc_RegisterRecoveryPublicKey)(CFDataRef recovery_key, CFErrorRef *error);
CFDataRef (*soscc_CopyRecoveryPublicKey)(CFErrorRef *error);
bool (*soscc_RemoveThisDeviceFromCircle)(CFErrorRef* error);
+ bool (*soscc_RemoveThisDeviceFromCircleWithAnalytics)(CFDataRef parentEvent, CFErrorRef* error);
bool (*soscc_RemovePeersFromCircle)(CFArrayRef peers, CFErrorRef* error);
+ bool (*soscc_RemovePeersFromCircleWithAnalytics)(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error);
bool (*soscc_LoggedOutOfAccount)(CFErrorRef* error);
bool (*soscc_BailFromCircle)(uint64_t limit_in_seconds, CFErrorRef* error);
bool (*soscc_AcceptApplicants)(CFArrayRef applicants, CFErrorRef* error);
bool (*sec_set_circle_log_settings)(CFTypeRef type, CFErrorRef* error);
SOSPeerInfoRef (*soscc_CopyMyPeerInfo)(CFErrorRef*);
bool (*soscc_WaitForInitialSync)(CFErrorRef*);
+ bool (*soscc_WaitForInitialSyncWithAnalytics)(CFDataRef parentEvent, CFErrorRef *error);
CFArrayRef (*soscc_CopyYetToSyncViewsList)(CFErrorRef*);
bool (*soscc_SetEscrowRecords)(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error);
CFDictionaryRef (*soscc_CopyEscrowRecords)(CFErrorRef *error);
bool (*sec_delete_items_with_access_groups)(CFArrayRef bundleIDs, SecurityClient *client, CFErrorRef *error);
bool (*soscc_IsThisDeviceLastBackup)(CFErrorRef *error);
bool (*soscc_requestSyncWithPeerOverKVS)(CFStringRef peerID, CFDataRef message, CFErrorRef *error);
- bool (*soscc_requestSyncWithPeerOverIDS)(CFStringRef peerID, CFErrorRef *error);
CFBooleanRef (*soscc_SOSCCPeersHaveViewsEnabled)(CFArrayRef views, CFErrorRef *error);
bool (*socc_clearPeerMessageKeyInKVS)(CFStringRef peerID, CFErrorRef *error);
- bool (*soscc_requestSyncWithPeerOverKVSIDOnly)(CFStringRef peerID, CFErrorRef *error);
bool (*soscc_SOSCCMessageFromPeerIsPending)(SOSPeerInfoRef peer, CFErrorRef* error);
bool (*soscc_SOSCCSendToPeerIsPending)(SOSPeerInfoRef peer, CFErrorRef* error);
CFTypeRef (*soscc_status)(void);
// TODO Rename me
CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op);
XPC_RETURNS_RETAINED xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error);
+typedef void (^securityd_handler_t)(xpc_object_t reply, CFErrorRef error);
+void securityd_message_with_reply_async(xpc_object_t message, dispatch_queue_t replyq,
+ securityd_handler_t handler);
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);
bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
bool (^handle_response)(xpc_object_t response, CFErrorRef* error));
+void securityd_send_async_and_do(enum SecXPCOperation op, dispatch_queue_t replyq,
+ bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
+ securityd_handler_t handler);
+
// For testing only, never call this in a threaded program!
void SecServerSetTrustdMachServiceName(const char *name);
#include <keychain/ckks/CKKSControlServer.h>
#include "keychain/ot/OctagonControlServer.h"
+#include <securityd/SFKeychainServer.h>
+
#include <AssertMacros.h>
#include <CoreFoundation/CFXPCBridge.h>
#include <CoreFoundation/CoreFoundation.h>
});
}
break;
+ case kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ with_label_and_password_and_dsid(event, ^(CFStringRef label, CFDataRef password, CFStringRef dsid) {
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server(label, password, dsid, parentEvent, &error));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetUserCredentialsAndDSID_Server(label, password, dsid, &error));
+ }
+ CFReleaseNull(parentEvent);
+ });
+ }
+ break;
case kSecXPCOpView:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
with_label_and_number(event, ^(CFStringRef view, uint64_t actionCode) {
CFReleaseNull(disabledViews);
}
break;
- case kSecXPCOpSecurityProperty:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- with_label_and_number(event, ^(CFStringRef property, uint64_t actionCode) {
- xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
- SOSCCSecurityProperty_Server(property, (SOSSecurityPropertyActionCode)actionCode, &error));
- });
- }
+ case kSecXPCOpViewSetWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ CFSetRef enabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyEnabledViewsKey);
+ CFSetRef disabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyDisabledViewsKey);
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCViewSetWithAnalytics_Server(enabledViews, disabledViews, parentEvent));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCViewSet_Server(enabledViews, disabledViews));
+ }
+ CFReleaseNull(enabledViews);
+ CFReleaseNull(disabledViews);
+ CFReleaseNull(parentEvent);
+ }
break;
case kSecXPCOpCanAuthenticate:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
SOSCCRequestToJoinCircle_Server(&error));
}
break;
+ case kSecXPCOpRequestToJoinWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircleWithAnalytics_Server(parentEvent, &error));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircle_Server(&error));
+ }
+ CFReleaseNull(parentEvent);
+ }
+ break;
case kSecXPCOpAccountHasPublicKey:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
SOSCCRequestToJoinCircleAfterRestore_Server(&error));
}
break;
+ case kSecXPCOpRequestToJoinAfterRestoreWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server(parentEvent, &error));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircleAfterRestore_Server(&error));
+ }
+ CFReleaseNull(parentEvent);
+ }
+ break;
case kSecXPCOpRequestEnsureFreshParameters:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
}
break;
case kSecXPCOpRequestDeviceID:
- if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- CFStringRef deviceID = SOSCCCopyDeviceID_Server(&error);
- if (deviceID) {
- SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, deviceID, &error);
- }
- CFReleaseNull(deviceID);
- }
- break;
case kSecXPCOpSetDeviceID:
- if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- CFStringRef IDS = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
- xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetDeviceID_Server(IDS, &error));
- CFReleaseNull(IDS);
- }
- break;
case kSecXPCOpHandleIDSMessage:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- CFDictionaryRef IDS = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyIDSMessage, &error);
- xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCHandleIDSMessage_Server(IDS, &error));
- CFReleaseNull(IDS);
- }
- break;
- case kSecXPCOpClearKVSPeerMessage:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
- xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCClearPeerMessageKeyInKVS_Server(peerID, &error));
- CFReleaseNull(peerID);
- }
- break;
+ case kSecXPCOpSyncWithIDSPeer:
case kSecXPCOpSendIDSMessage:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error);
- xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSServiceRegistrationTest_Server(message, &error));
- CFReleaseNull(message);
- }
- break;
- case kSecXPCOpSyncWithKVSPeer:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- 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;
- case kSecXPCOpSyncWithKVSPeerIDOnly:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
- xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server(peerID, &error));
- CFReleaseNull(peerID);
- }
- break;
case kSecXPCOpPingTest:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error);
- xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSPingTest_Server(message, &error));
- CFReleaseNull(message);
- }
- break;
case kSecXPCOpIDSDeviceID:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSDeviceIDIsAvailableTest_Server(&error));
+ case kSecXPCOpSyncWithKVSPeerIDOnly:{
+ xpc_dictionary_set_int64(replyMessage, kSecXPCKeyError, errSecUnimplemented);
}
break;
case kSecXPCOpAccountSetToNew:
SOSCCResetToEmpty_Server(&error));
}
break;
+ case kSecXPCOpResetToEmptyWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCResetToEmptyWithAnalytics_Server(parentEvent, &error));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCResetToEmpty_Server(&error));
+ }
+ }
+ break;
case kSecXPCOpRemoveThisDeviceFromCircle:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
SOSCCRemoveThisDeviceFromCircle_Server(&error));
}
break;
+ case kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server(parentEvent, &error));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemoveThisDeviceFromCircle_Server(&error));
+ }
+ CFReleaseNull(parentEvent);
+ }
+ break;
case kSecXPCOpRemovePeersFromCircle:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfoArray, &error);
CFReleaseNull(applicants);
}
break;
+ case kSecXPCOpRemovePeersFromCircleWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfoArray, &error);
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemovePeersFromCircleWithAnalytics_Server(applicants, parentEvent, &error));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemovePeersFromCircle_Server(applicants, &error));
+ }
+ CFReleaseNull(parentEvent);
+ CFReleaseNull(applicants);
+ }
+ break;
case kSecXPCOpLoggedOutOfAccount:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
}
break;
+ case kSecXPCOpWaitForInitialSyncWithAnalytics:
+ if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
+ CFDataRef parentEvent = NULL;
+ if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCWaitForInitialSyncWithAnalytics_Server(parentEvent, &error));
+ }else{
+ xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCWaitForInitialSync_Server(&error));
+ }
+ CFReleaseNull(parentEvent);
+ }
+ break;
case kSecXPCOpCopyYetToSyncViews:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
CFArrayRef array = SOSCCCopyYetToSyncViewsList_Server(&error);
CFReleaseNull(record);
}
break;
-
- case kSecXPCOpCheckPeerAvailability:
- if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
- xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCCheckPeerAvailability_Server(&error));
- }
- break;
-
case kSecXPCOpIsThisDeviceLastBackup:
if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
}
if (xpcError)
xpc_release(xpcError);
-#if TARGET_OS_IPHONE
- pthread_setspecific(taskThreadKey, NULL);
-#endif
CFReleaseSafe(error);
CFReleaseSafe(client.accessGroups);
CFReleaseSafe(client.musr);
static void securityd_xpc_init(const char *service_name)
{
-#if TARGET_OS_IPHONE
- pthread_key_create(&taskThreadKey, NULL);
- SecTaskDiagnoseEntitlements = secTaskDiagnoseEntitlements;
-#endif
-
secdebug("serverxpc", "start");
xpc_connection_t listener = xpc_connection_create_mach_service(service_name, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
if (!listener) {
if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) {
xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) {
- xpc_retain(connection);
- xpc_retain(event);
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ /*
+ * rdar://problem/37690394&39323293
+ * Some operations cannot be performed synchronously.
+ * SecItemCopyMatching is particularly important, and
+ * should be safe to perform synchronously.
+ */
+ uint64_t operation = xpc_dictionary_get_uint64(event, kSecXPCKeyOperation);
+ if (operation == sec_item_copy_matching_id) {
securityd_xpc_dictionary_handler(connection, event);
- xpc_release(event);
- xpc_release(connection);
- });
+ } else {
+ xpc_retain(connection);
+ xpc_retain(event);
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ securityd_xpc_dictionary_handler(connection, event);
+ xpc_release(event);
+ xpc_release(connection);
+ });
+ }
}
});
xpc_connection_resume(connection);
CKKSControlServerInitialize();
SOSControlServerInitialize();
OctagonControlServerInitialize();
+ SFKeychainServerInitialize();
// <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
#if TARGET_OS_EMBEDDED
CFStringRef value = (CFStringRef)SecTaskCopyValueForEntitlement(task,
entitlement, NULL);
if (value && CFGetTypeID(value) != CFStringGetTypeID()) {
- CFRelease(value);
- value = NULL;
+ CFReleaseNull(value);
}
return value;
for (ix = 0; ix < count; ++ix) {
CFStringRef string = (CFStringRef)CFArrayGetValueAtIndex(value, ix);
if (CFGetTypeID(string) != CFStringGetTypeID()) {
- CFRelease(value);
- value = NULL;
+ CFReleaseNull(value);
break;
}
}
} else {
- CFRelease(value);
- value = NULL;
+ CFReleaseNull(value);
}
}
return SecTaskCopyStringForEntitlement(task,
kSecEntitlementApplicationIdentifier);
}
+
#if TARGET_OS_IOS
CFArrayRef SecTaskCopySharedWebCredentialDomains(SecTaskRef task) {
return SecTaskCopyArrayOfStringsForEntitlement(task,
kSecEntitlementAssociatedDomains);
}
#endif
-CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) {
+
+CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task)
+{
CFMutableArrayRef groups = NULL;
- CFArrayRef keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task,
- kSecEntitlementKeychainAccessGroups);
- CFArrayRef appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task,
- kSecEntitlementAppleSecurityApplicationGroups);
- CFStringRef appID = SecTaskCopyApplicationIdentifier(task);
- CFIndex kagLen = keychainAccessGroups ? CFArrayGetCount(keychainAccessGroups) : 0;
- CFIndex asagLen = appleSecurityApplicationGroups ? CFArrayGetCount(appleSecurityApplicationGroups) : 0;
- bool entitlementsValidated = true;
- bool hasEntitlements = (kagLen + asagLen + (appID ? 1 : 0)) > 0;
-#if TARGET_OS_OSX
- entitlementsValidated = SecTaskEntitlementsValidated(task);
- if ((appID || asagLen) && !entitlementsValidated) {
- CFReleaseNull(appID);
- asagLen = 0;
+
+#if TARGET_SIMULATOR
+ groups = (CFMutableArrayRef)CFRetainSafe(SecAccessGroupsGetCurrent());
+#else
+ CFArrayRef keychainAccessGroups, appleSecurityApplicationGroups;
+ CFStringRef appID;
+
+ keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementKeychainAccessGroups);
+ appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAppleSecurityApplicationGroups);
+ appID = SecTaskCopyApplicationIdentifier(task);
+
+ groups = CFArrayCreateMutableForCFTypes(NULL);
+
+ if (keychainAccessGroups) {
+ CFArrayAppendArray(groups, keychainAccessGroups, CFRangeMake(0, CFArrayGetCount(keychainAccessGroups)));
}
+
+#if TARGET_OS_OSX
+ const bool entitlementsValidated = SecTaskEntitlementsValidated(task);
+#else
+ const bool entitlementsValidated = true;
#endif
- CFIndex len = kagLen + asagLen + (appID ? 1 : 0);
- // Always allow access to com.apple.token access group, unless entitlement validation explicitly failed.
- CFIndex tokenLen = (!hasEntitlements || entitlementsValidated) ? 1 : 0;
-#if TARGET_OS_IPHONE
- if (len + tokenLen)
-#endif
- {
- groups = CFArrayCreateMutable(kCFAllocatorDefault, len + tokenLen, &kCFTypeArrayCallBacks);
- if (kagLen)
- CFArrayAppendArray(groups, keychainAccessGroups, CFRangeMake(0, kagLen));
- if (appID)
+
+ if (entitlementsValidated) {
+ // If app-id or k-a-g are present but binary is not validated, just honor k-a-g.
+ // Because AMFI would not allow client to run if it would have k-a-g entitlement
+ // and not being properly signed.
+ if (appID) {
CFArrayAppendValue(groups, appID);
- if (asagLen)
- CFArrayAppendArray(groups, appleSecurityApplicationGroups, CFRangeMake(0, asagLen));
- if (tokenLen)
- CFArrayAppendValue(groups, kSecAttrAccessGroupToken);
-#if TARGET_IPHONE_SIMULATOR
+ }
+ if (appleSecurityApplicationGroups) {
+ CFArrayAppendArray(groups, appleSecurityApplicationGroups, CFRangeMake(0, CFArrayGetCount(appleSecurityApplicationGroups)));
+ }
} else {
- secwarning("No keychain access group specified while running in simulator, falling back to default set");
- groups = (CFMutableArrayRef)CFRetainSafe(SecAccessGroupsGetCurrent());
-#endif
- }
-
- CFReleaseSafe(appID);
- CFReleaseSafe(keychainAccessGroups);
- CFReleaseSafe(appleSecurityApplicationGroups);
- return groups;
-}
-
-#if TARGET_OS_IPHONE
-pthread_key_t taskThreadKey;
-void secTaskDiagnoseEntitlements(CFArrayRef accessGroups) {
- SecTaskRef taskRef = pthread_getspecific(taskThreadKey);
- if (taskRef == NULL)
- return;
-
- CFErrorRef error = NULL;
- CFArrayRef entitlementNames = CFArrayCreateForCFTypes(NULL,
- kSecEntitlementApplicationIdentifier,
- kSecEntitlementKeychainAccessGroups,
- kSecEntitlementAppleSecurityApplicationGroups,
- NULL);
- CFDictionaryRef rawEntitlements = SecTaskCopyValuesForEntitlements(taskRef, entitlementNames, &error);
- CFReleaseNull(entitlementNames);
-
- // exclude some error types because they're accounted-for and not the reason we're here
- if (rawEntitlements == NULL && error) {
- CFErrorDomain domain = CFErrorGetDomain(error);
- if (domain && CFEqual(domain, kCFErrorDomainPOSIX)) {
- CFIndex c = CFErrorGetCode(error);
- int err = (int) c;
-
- switch (err) {
- case ESRCH: // no such process (bad pid or process died)
- return;
- default:
- break;
+ // Try to provide some hopefully helpful diagnostics for common failure cases.
+ if (CFArrayGetCount(groups) == 0) {
+ if (appID) {
+ secwarning("Entitlement %@=%@ is ignored because of invalid application signature or incorrect provisioning profile",
+ kSecEntitlementApplicationIdentifier, appID);
+ }
+ if (appleSecurityApplicationGroups) {
+ secwarning("Entitlement %@=%@ is ignored because of invalid application signature or incorrect provisioning profile",
+ kSecEntitlementAppleSecurityApplicationGroups, appleSecurityApplicationGroups);
}
}
}
- uint32_t cs_flags = SecTaskGetCodeSignStatus(taskRef);
- CFStringRef identifier = SecTaskCopySigningIdentifier(taskRef, NULL);
- CFStringRef message = NULL;
-
- if (rawEntitlements == NULL) { // NULL indicates failure-to-fetch (SecTask entitlements not initialized)
- message = CFStringCreateWithFormat(NULL, NULL, CFSTR("failed to fetch keychain client entitlements. task=%@ procid=%@ cs_flags=0x%08.8x error=%@"),
- taskRef, identifier, cs_flags, error);
- secerror("MISSING keychain entitlements: retrieve-entitlements error %@", error);
- } else {
- // non-NULL entitlement return => SecTaskCopyEntitlements succeeeded, no error
- // but note that kernel EINVAL => no entitlements, no error to deal with unsigned code
- message = CFStringCreateWithFormat(NULL, NULL, CFSTR("found no keychain client entitlements. task=%@ procid=%@ cs_flags=0x%08.8x"),
- taskRef, identifier, cs_flags);
- secerror("MISSING keychain entitlements: raw entitlement values: %@", rawEntitlements);
- secerror("MISSING keychain entitlements: original ag: %@", accessGroups);
- CFArrayRef newAccessGroups = SecTaskCopyAccessGroups(taskRef);
- secerror("MISSING keychain entitlements: newly parsed ag: %@", newAccessGroups);
- CFReleaseNull(newAccessGroups);
+ /*
+ * We would like to add implicit token access group always, but we avoid doing that in case that application
+ * clearly intended to use non-smartcard functionality of keychain but messed up signing or provisioning. In this case,
+ * we want to return -34018 (errSecMissingEntitlements) to help diagnosing the issue for the app authors and adding
+ * implicit token access group would instead result in errSecItemNotFound.
+ */
+ bool entitlementsFailure = (CFArrayGetCount(groups) == 0 && appID != NULL);
+ if (!entitlementsFailure) {
+ CFArrayAppendValue(groups, kSecAttrAccessGroupToken);
}
- char buffer[1000] = "?";
- CFStringGetCString(message, buffer, sizeof(buffer), kCFStringEncodingUTF8);
- secerror("%s", buffer);
- __security_simulatecrash(message, __sec_exception_code_MissingEntitlements);
-
- CFReleaseNull(rawEntitlements);
- CFReleaseNull(message);
- CFReleaseNull(identifier);
- CFReleaseNull(error);
-}
+
+ CFReleaseNull(appID);
+ CFReleaseNull(keychainAccessGroups);
+ CFReleaseNull(appleSecurityApplicationGroups);
#endif
-bool SecTaskGetBooleanValueForEntitlement(SecTaskRef task,
- CFStringRef entitlement) {
- CFTypeRef canModify = SecTaskCopyValueForEntitlement(task, entitlement, NULL);
- if (!canModify)
- return false;
- CFTypeID canModifyType = CFGetTypeID(canModify);
- bool ok = (CFBooleanGetTypeID() == canModifyType) && CFBooleanGetValue((CFBooleanRef)canModify);
- CFRelease(canModify);
- return ok;
+ return groups;
}
+bool
+SecTaskGetBooleanValueForEntitlement(SecTaskRef task, CFStringRef entitlement)
+{
+ CFTypeRef value = SecTaskCopyValueForEntitlement(task, entitlement, NULL);
+ bool ok = false;
+
+ if (value && CFBooleanGetTypeID() == CFGetTypeID(value)) {
+ ok = CFBooleanGetValue(value);
+ }
+ CFReleaseNull(value);
+ return ok;
+}
CFArrayRef SecTaskCopyArrayOfStringsForEntitlement(SecTaskRef task,
CFStringRef entitlement);
-#if TARGET_OS_IPHONE
-void secTaskDiagnoseEntitlements(CFArrayRef accessGroups);
-extern pthread_key_t taskThreadKey;
-#endif
#if TARGET_OS_IOS
CFArrayRef SecTaskCopySharedWebCredentialDomains(SecTaskRef task);
#endif
client->task = SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken);
-#if TARGET_OS_IPHONE
- pthread_setspecific(taskThreadKey, client->task);
-#endif
-
client->accessGroups = SecTaskCopyAccessGroups(client->task);
#if TARGET_OS_IPHONE
void fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken);
CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task);
+void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
#endif /* server_security_helpers_h */
#include <os/transaction_private.h>
#if OCTAGON
-#include "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#include <CloudKit/CloudKit_Private.h>
// 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.
CF_EXPORT
uint64_t SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef);
+// Accessor to retrieve the last check in time for the OTAPKI asset
+CF_EXPORT
+CFDateRef SecOTAPKICopyLastAssetCheckInDate(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
#include <string.h>
#include <unistd.h>
#include <dirent.h>
+#include <copyfile.h>
#include <sys/syslimits.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <pthread.h>
#include <sys/param.h>
#include <stdlib.h>
+#include <os/transaction_private.h>
#include <utilities/SecCFRelease.h>
#include <utilities/SecCFError.h>
#include <utilities/SecCFWrappers.h>
static uint64_t GetAssetVersion(void);
#if !TARGET_OS_BRIDGE
static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version);
+static BOOL UpdateOTACheckInDate(void);
#endif
// MARK: Constants
NSString *kOTATrustContentVersionKey = @"MobileAssetContentVersion";
+NSString *kOTATrustLastCheckInKey = @"MobileAssetLastCheckIn";
NSString *kOTATrustContextFilename = @"OTAPKIContext.plist";
NSString *kOTATrustTrustedCTLogsFilename = @"TrustedCTLogs.plist";
NSString *kOTATrustAnalyticsSamplingRatesFilename = @"AnalyticsSamplingRates.plist";
const NSString *OTATrustMobileAssetType = @"com.apple.MobileAsset.PKITrustSupplementals";
#define kOTATrustMobileAssetNotification "com.apple.MobileAsset.PKITrustSupplementals.cached-metadata-updated"
#define kOTATrustOnDiskAssetNotification "com.apple.trustd.asset-updated"
+#define kOTATrustCheckInNotification "com.apple.trustd.asset-check-in"
const NSUInteger OTATrustMobileAssetCompatibilityVersion = 1;
#define kOTATrustDefaultUpdatePeriod 60*60*12 // 12 hours
#define kOTATrustMinimumUpdatePeriod 60*5 // 5 min
OTATrustLogLevelError,
} OTATrustLogLevel;
-static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(4,5);
+static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(5,6);
static void LogLocally(OTATrustLogLevel level, NSString *errorString) {
switch (level) {
#endif // ENABLE_TRUSTD_ANALYTICS
}
-static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, OSStatus errCode, NSString *format,...) {
+static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, 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
+ NSError *localError = nil;
+ NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
+ if (format) {
+ [userInfo setObject:formattedString forKey:NSLocalizedDescriptionKey];
+ }
+ localError = [NSError errorWithDomain:errDomain
code:errCode
userInfo:userInfo];
- }
LogLocally(level, formattedString);
- LogRemotely(level, error);
+ LogRemotely(level, &localError);
+ if (error) { *error = localError; }
va_end(args);
}
}
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);
+ NSURL *fileURL = GetAssetFileURL(filename);
+ if (remove([fileURL fileSystemRepresentation]) == -1) {
+ int error = errno;
+ if (error != ENOENT) {
+ secnotice("OTATrust", "failed to remove %@: %s", fileURL, strerror(error));
+ }
}
}
}
}
-static BOOL WriteAssetVersionToDisk(NSNumber *asset_version) {
+static BOOL UpdateOTAContextOnDisk(NSString *key, id value) {
if (SecOTAPKIIsSystemTrustd()) {
+ /* Get current context, if applicable, and update/add key/value */
+ NSURL *otaContextFile = GetAssetFileURL(kOTATrustContextFilename);
+ NSDictionary *currentContext = [NSDictionary dictionaryWithContentsOfURL:otaContextFile];
+ NSMutableDictionary *newContext = nil;
+ if (currentContext) {
+ newContext = [currentContext mutableCopy];
+ } else {
+ newContext = [NSMutableDictionary dictionary];
+ }
+ newContext[key] = value;
+
+ /* Write dictionary to disk */
NSError *error = nil;
- NSDictionary *version_dict = @{ kOTATrustContentVersionKey : asset_version };
- [version_dict writeToURL:GetAssetFileURL(kOTATrustContextFilename) error:&error];
+ [newContext writeToURL:otaContextFile error:&error];
if (error) {
secerror("OTATrust: unable to write asset version to disk: %@", error);
LogRemotely(OTATrustLogLevelError, &error);
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);
+ NSURL *toFileURL = GetAssetFileURL(filename);
+ secdebug("OTATrust", "will copy asset file data from \"%@\"", localURL);
+ copyfile_state_t state = copyfile_state_alloc();
+ int retval = copyfile([localURL fileSystemRepresentation], [toFileURL fileSystemRepresentation],
+ state, COPYFILE_DATA);
+ copyfile_state_free(state);
+ if (retval < 0) {
+ secerror("OTATrust: copyfile error for asset %d", retval);
return NO;
+ } else {
+ return YES;
}
- return YES;
}
return NO;
}
}];
return asset_version;
} else {
- MakeOTATrustError(error, OTATrustLogLevelError, errSecCallbackFailed,
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, 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,
+ MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable,
@"MobileAsset disabled, skipping check.");
return NO;
}
__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;
+ @autoreleasepool {
+ os_transaction_t transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.download");
+ if (result != MADownloadSucceesful) {
+ MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", result,
+ @"failed to download catalog: %ld", (long)result);
+ return;
}
- /* 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;
+ 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, @"MAQueryResult", queryResult,
+ @"failed to query MobileAsset metadata: %ld", (long)queryResult);
+ return;
}
- switch (asset.state) {
- default:
- MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal,
- @"unknown asset state %ld", (long)asset.state);
+ if (!query.results) {
+ MakeOTATrustError(&ma_error, OTATrustLogLevelError, NSOSStatusErrorDomain, 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, NSOSStatusErrorDomain, errSecIncompatibleVersion,
+ @"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion);
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");
+ }
+
+ /* We got an Asset that this device could use; write the last check-in time as now. */
+ (void)UpdateOTACheckInDate();
+
+ /* Check Content Version against the current content version */
+ NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"];
+ if (!ShouldUpdateWithAsset(asset_version)) {
+ MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem,
+ @"skipping asset because we already have _ContentVersion %@ (or newer)", asset_version);
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;
- }
+ }
+
+ switch (asset.state) {
+ default:
+ MakeOTATrustError(&ma_error, OTATrustLogLevelError, NSOSStatusErrorDomain, 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);
- if (wait) {
- dispatch_semaphore_signal(done);
- }
- }];
- break;
- } /* switch (asset.state) */
- } /* for (MAAsset.. */
- if (wait && !began_async_job) {
- dispatch_semaphore_signal(done);
- }
+ break;
+ case MAUnknown:
+ MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAAssetState", asset.state,
+ @"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) {
+ @autoreleasepool {
+ os_transaction_t inner_transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.downloadAsset");
+ if (downloadResult != MADownloadSucceesful) {
+ MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", downloadResult,
+ @"failed to download asset: %ld", (long)downloadResult);
+ return;
+ }
+ updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error);
+ if (wait) {
+ dispatch_semaphore_signal(done);
+ }
+ (void)inner_transaction; // dead store
+ inner_transaction = nil;
+ }
+ }];
+ break;
+ } /* switch (asset.state) */
+ } /* for (MAAsset.. */
+ if (wait && !began_async_job) {
+ dispatch_semaphore_signal(done);
+ }
+ /* Done with the transaction */
+ (void)transaction; // dead store
+ transaction = nil;
+ } /* autoreleasepool */
}]; /* [MAAsset startCatalogDownload: ] */
/* If the caller is waiting for a response, wait up to one minute for the update to complete.
BOOL result = NO;
if (wait) {
if (dispatch_semaphore_wait(done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) {
- MakeOTATrustError(error, OTATrustLogLevelError, errSecNetworkFailure,
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, 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,
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternalComponent,
@"Unknown error occurred.");
}
}
}
#else /* !TARGET_OS_IPHONE */
/* <rdar://problem/30879827> MobileAssetV2 fails on macOS, so use V1 */
-static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NSError ** error) {
+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);
[[TrustdHealthAnalytics logger] logSuccessForEventNamed:TrustdHealthAnalyticsEventOTAPKIEvent];
#endif // ENABLE_TRUSTD_ANALYTICS
[asset purge:^(NSError *ma_error) {
- if (error) {
+ if (ma_error) {
secerror("OTATrust: purge failed %@", ma_error);
}
}];
return asset_version;
} else {
- MakeOTATrustError(error, OTATrustLogLevelError, errSecCallbackFailed,
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, 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,
+ MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable,
@"MobileAsset disabled, skipping check.");
return NO;
}
+ NSError *localError = nil; // -[ASAssetQuery runQueryAndReturnError:] leaks if you pass null
ASAssetQuery *query = [[ASAssetQuery alloc] initWithAssetType:(NSString *)OTATrustMobileAssetType];
[query setQueriesLocalAssetInformationOnly:isLocalOnly]; // Omitting this leads to a notifcation loop.
- NSArray<ASAsset *>*query_results = [query runQueryAndReturnError:error];
+ NSArray<ASAsset *>*query_results = [query runQueryAndReturnError:&localError];
if (!query_results) {
- if (error) {
- secerror("OTATrust: asset query failed: %@", *error);
- LogRemotely(OTATrustLogLevelError, error);
+ if (localError) {
+ secerror("OTATrust: asset query failed: %@", localError);
+ LogRemotely(OTATrustLogLevelError, &localError);
+ if (error) { *error = localError; }
}
return NO;
}
for (ASAsset *asset in query_results) {
NSDictionary *attributes = [asset attributes];
+ /* Check Compatibility Version against this software version */
NSNumber *compatibilityVersion = [attributes objectForKey:ASAttributeCompatibilityVersion];
if (!isNSNumber(compatibilityVersion) ||
[compatibilityVersion unsignedIntegerValue] != OTATrustMobileAssetCompatibilityVersion) {
- MakeOTATrustError(error, OTATrustLogLevelNotice, errSecIncompatibleVersion,
+ MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecIncompatibleVersion,
@"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion);
continue;
}
+ /* We got an Asset that this device could use; write the last check-in time as now. */
+ (void)UpdateOTACheckInDate();
+
+ /* Check Content Version against the current content version */
NSNumber *contentVersion = [attributes objectForKey:ASAttributeContentVersion];
if (!ShouldUpdateWithAsset(contentVersion)) {
- MakeOTATrustError(error, OTATrustLogLevelNotice, errSecDuplicateItem,
+ MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, 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);
+ secerror("progress handler failed: %@", progressError);
+ LogRemotely(OTATrustLogLevelError, &progressError);
+ handler_error = [progressError copy];
if (wait) {
dispatch_semaphore_signal(done);
}
}
if (!state) {
- MakeOTATrustError(&handler_error, OTATrustLogLevelError, errSecInternal,
+ MakeOTATrustError(&handler_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal,
@"OTATrust: no asset state in progress handler");
if (wait) {
dispatch_semaphore_signal(done);
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);
+ if (![asset resumeDownloadAndReturnError:&localError]) {
+ if (localError) {
+ secerror("OTATrust: failed to resume download of asset: %@", localError);
+ LogRemotely(OTATrustLogLevelError, &localError);
+ if (error) { *error = localError; }
}
} else {
began_async_job = true;
began_async_job = true;
break;
default:
- MakeOTATrustError(error, OTATrustLogLevelError, errSecInternal,
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal,
@"unhandled asset state %ld", (long)asset.state);
continue;
}
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,
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecNetworkFailure,
@"Failed to get asset metadata within 1 minute.");
} else {
/* finished an async job, update the result */
/* If we failed and don't know why, report an unknown error */
if (!result && error && (*error == NULL)) {
- MakeOTATrustError(error, OTATrustLogLevelError, errSecInternalComponent,
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternalComponent,
@"Unknown error occurred.");
}
return result;
secnotice("OTATrust", "Got notification about a new PKITrustSupplementals asset from system trustd.");
UpdateFromAsset(GetAssetFileURL(nil), [NSNumber numberWithUnsignedLongLong:GetAssetVersion()]);
});
+ int out_token2 = 0;
+ notify_register_dispatch(kOTATrustCheckInNotification, &out_token2, queue, ^(int __unused token) {
+ secinfo("OTATrust", "Got notification about successful PKITrustSupplementals asset check-in");
+ (void)UpdateOTACheckInDate();
+ });
}
}
CFIndex _validSnapshotVersion;
CFIndex _validSnapshotFormat;
uint64_t _assetVersion;
+ CFDateRef _lastAssetCheckIn;
CFDictionaryRef _eventSamplingRates;
CFArrayRef _appleCAs;
};
CFReleaseNull(otapkiref->_pinningList);
CFReleaseNull(otapkiref->_eventSamplingRates);
CFReleaseNull(otapkiref->_appleCAs);
+ CFReleaseNull(otapkiref->_lastAssetCheckIn);
if (otapkiref->_anchorTable) {
free((void *)otapkiref->_anchorTable);
}
}
+static CF_RETURNS_RETAINED CFDateRef InitializeLastAssetCheckIn(void) {
+#if !TARGET_OS_BRIDGE
+ NSDictionary *OTAPKIContext = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustContextFilename)];
+ if (isNSDictionary(OTAPKIContext)) {
+ NSDate *checkIn = OTAPKIContext[kOTATrustLastCheckInKey];
+ return CFRetainSafe((__bridge CFDateRef)checkIn);
+ }
+#endif
+ return NULL;
+}
+
static SecOTAPKIRef SecOTACreate() {
SecOTAPKIRef otapkiref = NULL;
// Get the asset version (after possible reset due to missing asset date)
otapkiref->_assetVersion = GetAssetVersion();
+ otapkiref->_lastAssetCheckIn = InitializeLastAssetCheckIn();
// Get the valid update snapshot version and format
CFIndex update_format = 0;
}
#if !TARGET_OS_BRIDGE
+static BOOL UpdateOTACheckInDate(void) {
+ __block NSDate *checkIn = [NSDate date];
+ dispatch_sync(kOTAQueue, ^{
+ CFRetainAssign(kCurrentOTAPKIRef->_lastAssetCheckIn, (__bridge CFDateRef)checkIn);
+ });
+
+ if (SecOTAPKIIsSystemTrustd()) {
+ /* Let the other trustds know we successfully checked in */
+ notify_post(kOTATrustCheckInNotification);
+
+ /* Update the on-disk check-in date, so when we re-launch we remember */
+ return UpdateOTAContextOnDisk(kOTATrustLastCheckInKey, checkIn);
+ } else {
+ return NO;
+ }
+}
+
static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version) {
if (!localURL || !asset_version) {
secerror("OTATrust: missing url and version for downloaded asset");
if (CopyFileToDisk(kOTATrustTrustedCTLogsFilename, TrustedCTLogsFileLoc) &&
CopyFileToDisk(kOTATrustAnalyticsSamplingRatesFilename, AnalyticsSamplingRatesFileLoc) &&
CopyFileToDisk(kOTATrustAppleCertifcateAuthoritiesFilename, AppleCAsFileLoc) &&
- WriteAssetVersionToDisk(asset_version)) {
+ UpdateOTAContextOnDisk(kOTATrustContentVersionKey, asset_version)) {
/* If we successfully updated the "asset" on disk, signal the other trustds to pick up the changes */
notify_post(kOTATrustOnDiskAssetNotification);
}
return otapkiRef->_assetVersion;
}
+CFDateRef SecOTAPKICopyLastAssetCheckInDate(SecOTAPKIRef otapkiRef) {
+ if (NULL == otapkiRef) {
+ return NULL;
+ }
+ return CFRetainSafe(otapkiRef->_lastAssetCheckIn);
+}
+
NSNumber *SecOTAPKIGetSamplingRateForEvent(SecOTAPKIRef otapkiRef, NSString *eventName) {
if (NULL == otapkiRef) {
return nil;
return result;
}
-static inline bool SOSAccountSetMyDSID_wTxn(SOSAccount* acct, CFStringRef dsid, CFErrorRef* error)
-{
- __block bool result = false;
- [acct performTransaction:^(SOSAccountTransaction * _Nonnull txn) {
- result = SOSAccountSetMyDSID(txn, dsid, error);
- }];
- return result;
-}
-
//
// Account comparison
//
SOSUnregisterTransportKeyParameter(a.key_transport);
SOSUnregisterTransportCircle((SOSCircleStorageTransport*)a.circle_transport);
SOSUnregisterTransportMessage((SOSMessage*)a.kvs_message_transport);
- SOSUnregisterTransportMessage((SOSMessage*)a.ids_message_transport);
if(key_transports)
CFArrayRemoveAllValue(key_transports, (__bridge CFTypeRef)(a.key_transport));
if(message_transports){
- CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)a.ids_message_transport);
CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)a.kvs_message_transport);
}
if(circle_transports)
a.circle_transport = nil;
a.key_transport = nil;
- a.ids_message_transport = nil;
a.kvs_message_transport = nil;
SOSAccountEnsureFactoryCirclesTest(a, accountName);
}
SOSTransportMessageTestClearChanges(tpt);
}
- else if([(__bridge SOSMessage*)value SOSTransportMessageGetTransportType] == kIDSTest){
- SOSMessageIDSTest* ids = (__bridge SOSMessageIDSTest*) value;
- CFDictionaryRemoveValue(SOSTransportMessageIDSTestGetChanges(ids), kCFNull);
- if (AddNewChanges(changes, SOSTransportMessageIDSTestGetChanges(ids), SOSTransportMessageIDSTestGetAccount(ids))) {
- changed |= true;
- CFSetAddValue(changedAccounts, (__bridge CFTypeRef)(SOSTransportMessageIDSTestGetAccount(ids)));
- }
- SOSTransportMessageIDSTestClearChanges(ids);
- }
});
secnotice("process-changes", "Accounts with change (%@): %@", changed ? CFSTR("YES") : CFSTR("NO"), changedAccounts);
SOSTransportMessageTestClearChanges(tpt);
}
}
- else{
- SOSMessageIDSTest* tpt = (__bridge SOSMessageIDSTest*) value;
- if(CFEqualSafe((__bridge CFTypeRef)(forAccount), (__bridge CFTypeRef)(SOSTransportMessageIDSTestGetAccount(tpt)))){
- CFDictionaryRemoveValue(SOSTransportMessageIDSTestGetChanges(tpt), kCFNull);
- AddNewChanges(changes, SOSTransportMessageIDSTestGetChanges(tpt), SOSTransportMessageIDSTestGetAccount(tpt));
- SOSTransportMessageIDSTestClearChanges(tpt);
- }
- }
});
}
CFMutableDictionaryRef testV2dict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
CFDictionaryAddValue(testV2dict, sSerialNumberKey, serial);
- CFDictionaryAddValue(testV2dict, sPreferIDS, preferIDS);
- CFDictionaryAddValue(testV2dict, sPreferIDSFragmentation, preferIDSFragmentation);
- CFDictionaryAddValue(testV2dict, sPreferIDSACKModel, preferIDSACKModel);
- CFDictionaryAddValue(testV2dict, sTransportType, transportType);
- CFDictionaryAddValue(testV2dict, sDeviceID, deviceID);
SOSAccount* result = SOSAccountCreateTest(kCFAllocatorDefault, name, gestalt, factory);
[result.trust updateV2Dictionary:result v2:testV2dict];
is(ProcessChangesUntilNoChange(changes, approver, joiner, NULL), 2, "updates");
- ok((retval = [joiner.trust isInCircle:NULL]), "Joiner is in");
+ ok((retval = [joiner isInCircle:NULL]), "Joiner is in");
accounts_agree_internal("Successful join shows same circle view", joiner, approver, false);
is(countPeers(joiner), expectedCount, "There should be %d valid peers", expectedCount);
#import "Security/SecureObjectSync/SOSTransportCircleKVS.h"
#import "Security/SecureObjectSync/SOSTransportMessageKVS.h"
-#import "Security/SecureObjectSync/SOSTransportMessageIDS.h"
extern CFMutableArrayRef key_transports;
extern CFMutableArrayRef circle_transports;
void SOSAccountUpdateTestTransports(SOSAccount* account, CFDictionaryRef gestalt);
-@interface SOSMessageIDSTest : SOSMessageIDS
-
-@property (nonatomic) CFMutableDictionaryRef changes;
-@property (nonatomic) CFStringRef accountName;
-
--(SOSMessageIDSTest*) initWithAccount:(SOSAccount*)acct andAccountName:(CFStringRef) aN andCircleName:(CFStringRef) cN err:(CFErrorRef *)error;
--(CFIndex) SOSTransportMessageGetTransportType;
--(CFStringRef) SOSTransportMessageGetCircleName;
--(CFTypeRef) SOSTransportMessageGetEngine;
--(SOSAccount*) SOSTransportMessageGetAccount;
-void SOSTransportMessageIDSTestSetName(SOSMessageIDSTest* transport, CFStringRef acctName);
--(bool) SOSTransportMessageSendMessages:(SOSMessageIDSTest*) transport pm:(CFDictionaryRef) peer_messages err:(CFErrorRef *)error;
--(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct;
--(CFDictionaryRef)CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessageIDSTest*) transport peerMessages:(CFMutableDictionaryRef)message err:(CFErrorRef *)error;
--(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)acct m:(CFDictionaryRef) message err:(CFErrorRef *)error;
-
-@end
-
@interface CKKeyParameterTest : CKKeyParameter
@property (nonatomic) CFMutableDictionaryRef changes;
-(CFMutableDictionaryRef) SOSTransportCircleTestGetChanges;
@end
-void SOSTransportMessageIDSTestSetName(SOSMessageIDSTest* transport, CFStringRef n);
void SOSTransportMessageTestClearChanges(SOSMessageKVSTest* transport);
void SOSTransportMessageKVSTestSetName(SOSMessageKVSTest* transport, CFStringRef n);
void SOSTransportKeyParameterTestClearChanges(CKKeyParameterTest* transport);
SOSAccount* SOSTransportKeyParameterTestGetAccount(CKKeyParameterTest* transport);
SOSAccount* SOSTransportMessageKVSTestGetAccount(SOSMessageKVSTest* transport);
-void SOSTransportMessageIDSTestClearChanges(SOSMessageIDSTest* transport);
-
-CFMutableDictionaryRef SOSTransportMessageIDSTestGetChanges(SOSMessageIDSTest* transport);
-SOSAccount* SOSTransportMessageIDSTestGetAccount(SOSMessageIDSTest* transport);
-CFStringRef SOSTransportMessageIDSTestGetName(SOSMessageIDSTest* transport);
#endif
#include <Security/SecureObjectSync/SOSTransport.h>
#import <Security/SecureObjectSync/SOSTransportKeyParameter.h>
#import <Security/SecureObjectSync/SOSTransportCircleKVS.h>
-#import <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#import <Security/SecureObjectSync/SOSTransportMessageKVS.h>
#include <Security/SecureObjectSync/SOSKVSKeys.h>
#include <Security/SecureObjectSync/SOSPeerCoder.h>
CFArrayRemoveAllValue(key_transports, (__bridge CFTypeRef)(acct.key_transport));
}
if(message_transports){
- CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)acct.ids_message_transport);
CFArrayRemoveAllValue(message_transports, (__bridge CFTypeRef)acct.kvs_message_transport);
}
if(circle_transports)
return result;
}
--(CFDictionaryRef)CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessageIDSTest*) transport peerMessages:(CFMutableDictionaryRef) circle_peer_messages_table err:(CFErrorRef *)error{
- CFMutableDictionaryRef handled = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- CFDictionaryRef peerToMessage = CFDictionaryGetValue(circle_peer_messages_table, (__bridge CFStringRef)transport.circleName);
- CFMutableArrayRef handled_peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
- CFDictionaryAddValue(handled, (__bridge CFStringRef)transport.circleName, handled_peers);
-
- if(peerToMessage){
- CFDictionaryForEach(peerToMessage, ^(const void *key, const void *value) {
- CFStringRef peer_id = (CFStringRef) key;
- CFDataRef peer_message = (CFDataRef) value;
- CFErrorRef localError = NULL;
-
- if ([transport SOSTransportMessageHandlePeerMessage:transport id:peer_id cm:peer_message err:&localError]){
- CFArrayAppendValue(handled_peers, key);
- } else {
- secdebug("transport", "%@ KVSTransport handle message failed: %@", peer_id, localError);
- }
- CFReleaseNull(localError);
- });
- }
- CFReleaseNull(handled_peers);
-
- return handled;
-}
-
-(bool) SOSTransportMessageFlushChanges:(SOSMessageKVSTest*) transport err:(CFErrorRef *)error
{
return true;
}
@end
-///
-//MARK IDS Message Test Transport
-///
-
-@implementation SOSMessageIDSTest
--(SOSMessageIDSTest*) initWithAccount:(SOSAccount*)acct andAccountName:(CFStringRef) aN andCircleName:(CFStringRef) cN err:(CFErrorRef *)error
-{
- self = [super init];
- if(self){
- self.engine = SOSDataSourceFactoryGetEngineForDataSourceName(acct.factory, cN, NULL);
- self.useFragmentation = kCFBooleanTrue;
- self.account = acct;
- self.changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- self.circleName = (__bridge NSString*)cN;
- self.accountName = CFRetainSafe(aN);
-
- if(!message_transports)
- message_transports = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
- CFArrayAppendValue(message_transports, (__bridge CFTypeRef)self);
- SOSRegisterTransportMessage((SOSMessageIDSTest*)self);
- }
-
- return self;
-}
-
--(bool) SOSTransportMessageIDSGetIDSDeviceID:(SOSAccount*)acct{
- return true;
-}
-
--(CFIndex) SOSTransportMessageGetTransportType
-{
- return kIDSTest;
-}
--(CFStringRef) SOSTransportMessageGetCircleName
-{
- return (__bridge CFStringRef)circleName;
-}
--(CFTypeRef) SOSTransportMessageGetEngine
-{
- return engine;
-}
--(SOSAccount*) SOSTransportMessageGetAccount
-{
- return self.account;
-}
-
-void SOSTransportMessageIDSTestSetName(SOSMessageIDSTest* transport, CFStringRef acctName){
- transport.accountName = acctName;
-}
-
-
-static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFStringRef fromDeviceID, CFStringRef fromPeerID, CFStringRef *peerID, SOSPeerInfoRef *theirPeerInfo){
- SOSAccountTrustClassic *trust = account.trust;
- __block HandleIDSMessageReason reason = kHandleIDSMessageDontHandle;
-
- SOSCircleForEachPeer(trust.trustedCircle, ^(SOSPeerInfoRef peer) {
- CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer);
- CFStringRef pID = SOSPeerInfoGetPeerID(peer);
-
- if( deviceID && pID && fromPeerID && fromDeviceID && CFStringGetLength(fromPeerID) != 0 ){
- if(CFStringCompare(pID, fromPeerID, 0) == 0){
- if(CFStringGetLength(deviceID) == 0){
- secnotice("ids transport", "device ID was empty in the peer list, holding on to message");
- CFReleaseNull(deviceID);
- reason = kHandleIDSMessageNotReady;
- return;
- }
- else if(CFStringCompare(fromDeviceID, deviceID, 0) != 0){ //IDSids do not match, ghost
- reason = kHandleIDSmessageDeviceIDMismatch;
- CFReleaseNull(deviceID);
- return;
- }
- else if(CFStringCompare(deviceID, fromDeviceID, 0) == 0){
- *peerID = pID;
- *theirPeerInfo = peer;
- CFReleaseNull(deviceID);
- reason = kHandleIDSMessageSuccess;
- return;
- }
- }
- }
- CFReleaseNull(deviceID);
- });
-
- return reason;
-}
-const char *kMessageKeyIDSDataMessage = "idsDataMessage";
-const char *kMessageKeyDeviceID = "deviceID";
-const char *kMessageKeyPeerID = "peerID";
-const char *kMessageKeySendersPeerID = "sendersPeerID";
-
--(HandleIDSMessageReason) SOSTransportMessageIDSHandleMessage:(SOSAccount*)acct m:(CFDictionaryRef) message err:(CFErrorRef *)error
-{
- secnotice("IDS Transport", "SOSTransportMessageIDSHandleMessage!");
-
- CFStringRef dataKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyIDSDataMessage, kCFStringEncodingASCII);
- CFStringRef deviceIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyDeviceID, kCFStringEncodingASCII);
- CFStringRef sendersPeerIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeySendersPeerID, kCFStringEncodingASCII);
- CFStringRef ourPeerIdKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyPeerID, kCFStringEncodingASCII);
-
- HandleIDSMessageReason result = kHandleIDSMessageSuccess;
-
- CFDataRef messageData = asData(CFDictionaryGetValue(message, dataKey), NULL);
- __block CFStringRef fromDeviceID = asString(CFDictionaryGetValue(message, deviceIDKey), NULL);
- __block CFStringRef fromPeerID = (CFStringRef)CFDictionaryGetValue(message, sendersPeerIDKey);
- CFStringRef ourPeerID = asString(CFDictionaryGetValue(message, ourPeerIdKey), NULL);
-
- 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(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);
-
- if ([account.ids_message_transport SOSTransportMessageHandlePeerMessage:account.ids_message_transport id:peerID cm:messageData err:error]) {
- CFMutableDictionaryRef peersToSyncWith = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- CFMutableSetRef peerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(peerIDs, peerID);
- SOSAccountTrustClassic* trust = account.trust;
- //sync using fragmentation?
- if(SOSPeerInfoShouldUseIDSMessageFragmentation(trust.peerInfo, theirPeer)){
- //set useFragmentation bit
- [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanTrue];
- }
- else{
- [account.ids_message_transport SOSTransportMessageIDSSetFragmentationPreference:account.ids_message_transport pref: kCFBooleanFalse];
- }
-
- if(![account.ids_message_transport SOSTransportMessageSyncWithPeers:account.ids_message_transport p:peerIDs err:error]){
- secerror("SOSTransportMessageIDSHandleMessage Could not sync with all peers: %@", *error);
- }else{
- secnotice("IDS Transport", "Synced with all peers!");
- }
-
- CFReleaseNull(peersToSyncWith);
- CFReleaseNull(peerIDs);
- }else{
- if(error && *error != NULL){
- CFStringRef errorMessage = CFErrorCopyDescription(*error);
- if (-25308 == CFErrorGetCode(*error)) { // tell KeychainSyncingOverIDSProxy to call us back when device unlocks
- result = kHandleIDSMessageLocked;
- }else{ //else drop it, couldn't handle the message
- result = kHandleIDSMessageDontHandle;
- }
- secerror("IDS Transport Could not handle message: %@, %@", messageData, *error);
- CFReleaseNull(errorMessage);
-
- }
- else{ //no error but failed? drop it, log message
- secerror("IDS Transport Could not handle message: %@", messageData);
- result = kHandleIDSMessageDontHandle;
-
- }
- }
-
-exit:
- CFReleaseNull(ourPeerIdKey);
- CFReleaseNull(sendersPeerIDKey);
- CFReleaseNull(deviceIDKey);
- CFReleaseNull(dataKey);
- return result;
-}
-
--(CFDictionaryRef)CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessageIDSTest*) transport peerMessages:(CFMutableDictionaryRef)message err:(CFErrorRef *)error
-{
-
- CFMutableDictionaryRef handled = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- CFDictionaryRef peerToMessage = CFDictionaryGetValue(message, (__bridge CFTypeRef)(transport.circleName));
- CFMutableArrayRef handled_peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
-
- secerror("Received IDS message!");
- if(peerToMessage){
- CFDictionaryForEach(peerToMessage, ^(const void *key, const void *value) {
- CFStringRef peer_id = asString(key, NULL);
- CFDataRef peer_message = asData(value, NULL);
- CFErrorRef localError = NULL;
-
- if (peer_id && peer_message && [transport SOSTransportMessageHandlePeerMessage:transport id:peer_id cm:peer_message err:&localError]) {
- CFArrayAppendValue(handled_peers, key);
- } else {
- secnotice("transport", "%@ KVSTransport handle message failed: %@", peer_id, localError);
- }
- CFReleaseNull(localError);
- });
- }
- CFDictionaryAddValue(handled, (__bridge CFStringRef)(transport.circleName), handled_peers);
- CFReleaseNull(handled_peers);
-
- return handled;
-}
-
-static void SOSTransportMessageIDSTestAddBulkToChanges(SOSMessageIDSTest* transport, CFDictionaryRef updates){
-#ifndef __clang_analyzer__ // The analyzer thinks transport.changes is a leak, but I don't know why.
- if (transport.changes == NULL) {
- transport.changes = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(updates), updates);
-
- }
- else{
- CFDictionaryForEach(updates, ^(const void *key, const void *value) {
- CFDictionaryAddValue(transport.changes, key, value);
- });
- }
-#endif
-}
-static bool sendDataToPeerIDSTest(SOSMessageIDSTest* transport, CFStringRef circleName, CFStringRef deviceID, CFStringRef peerID, CFDataRef message, CFErrorRef *error)
-{
- secerror("sending message through test transport: %@", message);
- NSString* myID = transport.account.peerID;
- CFStringRef message_to_peer_key = SOSMessageKeyCreateFromTransportToPeer(transport, (__bridge CFStringRef) myID, peerID);
- CFDictionaryRef a_message_to_a_peer = CFDictionaryCreateForCFTypes(NULL, message_to_peer_key, message, NULL);
-
- SOSTransportMessageIDSTestAddBulkToChanges(transport, a_message_to_a_peer);
-
- CFReleaseNull(message_to_peer_key);
- CFReleaseNull(a_message_to_a_peer);
- return true;
-
-}
-static bool sendDictionaryToPeerIDSTest(SOSMessageIDSTest* transport, CFStringRef circleName, CFStringRef deviceID, CFStringRef peerID, CFDictionaryRef message, CFErrorRef *error)
-{
- secerror("sending message through test transport: %@", message);
- NSString* myID = transport.account.peerID;
- CFStringRef message_to_peer_key = SOSMessageKeyCreateFromTransportToPeer(transport, (__bridge CFStringRef) myID, peerID);
- CFDictionaryRef a_message_to_a_peer = CFDictionaryCreateForCFTypes(NULL, message_to_peer_key, message, NULL);
-
- SOSTransportMessageIDSTestAddBulkToChanges(transport, a_message_to_a_peer);
-
- CFReleaseNull(message_to_peer_key);
- CFReleaseNull(a_message_to_a_peer);
- return true;
-
-}
-
--(bool) SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*) transport p:(CFSetRef)peers err:(CFErrorRef *)error
-{
- // Each entry is keyed by circle name and contains a list of peerIDs
- __block bool result = true;
-
- CFSetForEach(peers, ^(const void *value) {
- CFStringRef peerID = asString(value, NULL);
- if (peerID) {
- secnotice("transport", "IDS sync with peerIDs %@", peerID);
- result &= [transport SOSTransportMessageSendMessageIfNeeded:transport id:(__bridge CFStringRef)transport.circleName pID:peerID err:error];
- }
- });
-
- return result;
-}
-
--(bool) SOSTransportMessageSendMessages:(SOSMessageIDSTest*) transport pm:(CFDictionaryRef) peer_messages err:(CFErrorRef *)error
-{
- __block bool result = true;
- CFDictionaryForEach(peer_messages, ^(const void *key, const void *value) {
- CFStringRef idsDeviceID = NULL;;
- CFStringRef peerID = asString(key, NULL);
- SOSPeerInfoRef pi = NULL;
- if(peerID){
- if(!CFEqualSafe(peerID, (__bridge CFStringRef) transport.account.peerID)){
-
- pi = SOSAccountCopyPeerWithID(transport.account, peerID, NULL);
- if(pi){
- idsDeviceID = SOSPeerInfoCopyDeviceID(pi);
- if(idsDeviceID != NULL){
-
- CFDictionaryRef messageDictionary = asDictionary(value, NULL);
- if (messageDictionary) {
- result &= sendDictionaryToPeerIDSTest(transport, (__bridge CFStringRef)transport.circleName, idsDeviceID, peerID, messageDictionary, error);
- } else {
- CFDataRef messageData = asData(value, NULL);
- if (messageData) {
- result &= sendDataToPeerIDSTest(transport, (__bridge CFStringRef)transport.circleName, idsDeviceID, peerID, messageData, error);
- }
- }
- }
- }
- }
- }
- CFReleaseNull(idsDeviceID);
- CFReleaseNull(pi);
- });
-
- return result;
-}
-
--(bool) SOSTransportMessageFlushChanges:(SOSMessageIDSTest*) transport err:(CFErrorRef *)error
-{
- return true;
-}
-
--(bool) SOSTransportMessageCleanupAfterPeerMessages:(SOSMessageIDSTest*) transport peers:(CFDictionaryRef) peers err:(CFErrorRef*) error
-{
- return true;
-}
-
-void SOSTransportMessageIDSTestClearChanges(SOSMessageIDSTest* transport)
-{
- transport.changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
-}
-
-CFMutableDictionaryRef SOSTransportMessageIDSTestGetChanges(SOSMessageIDSTest* transport)
-{
- return transport.changes;
-}
-
-SOSAccount* SOSTransportMessageIDSTestGetAccount(SOSMessageIDSTest* transport)
-{
- return transport.account;
-}
-
-CFStringRef SOSTransportMessageIDSTestGetName(SOSMessageIDSTest* transport){
- return transport.accountName;
-}
-
-@end
-
void SOSAccountUpdateTestTransports(SOSAccount* account, CFDictionaryRef gestalt){
CFStringRef new_name = (CFStringRef)CFDictionaryGetValue(gestalt, kPIUserDefinedDeviceNameKey);
SOSTransportKeyParameterTestSetName((CKKeyParameterTest*)account.key_transport, new_name);
SOSTransportCircleTestSetName((SOSCircleStorageTransportTest*)account.circle_transport, new_name);
SOSTransportMessageKVSTestSetName((SOSMessageKVSTest*)account.kvs_message_transport, new_name);
- SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)account.ids_message_transport, new_name);
-
}
static CF_RETURNS_RETAINED SOSCircleRef SOSAccountEnsureCircleTest(SOSAccount* a, CFStringRef name, CFStringRef accountName)
if(account.kvs_message_transport == nil){
account.kvs_message_transport = (SOSMessageKVS*)[[SOSMessageKVSTest alloc] initWithAccount:account andName:accountName andCircleName:circleName];
}
- if(account.ids_message_transport == nil){
- account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:account andAccountName:accountName andCircleName:circleName err:NULL];
- }
success = true;
fail:
#define N_THREADS 10
void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
-CFArrayRef SecAccessGroupsGetCurrent();
+CFArrayRef SecAccessGroupsGetCurrent(void);
int secd_02_upgrade_while_locked(int argc, char *const *argv)
{
#import "SOSTransportTestTransports.h"
#include "SOSTestDevice.h"
#include "SOSTestDataSource.h"
-#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#include <Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h>
static int kTestTestCount = 114;
-static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) {
- SOSAccountTrustClassic* trust = account.trust;
- SOSPeerInfoRef mypi = trust.peerInfo;
- ok(mypi);
- CFStringRef myPeerID = SOSPeerInfoGetPeerID(mypi);
- ok(myPeerID);
- return myPeerID && CFEqualSafe(myPeerID, peerID);
-}
-
-__unused static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){
-
- CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- __block bool SyncingCompletedOverIDS = false;
- __block CFErrorRef localError = NULL;
-
- SOSAccountTrustClassic* aliceTrust = alice_account.trust;
- SOSAccountTrustClassic* bobTrust = bob_account.trust;
- SOSDataSourceRef bob_ds = SOSDataSourceFactoryCreateDataSource(bob_account.factory, CFSTR("ak"), NULL);
- SOSEngineRef bob_engine = bob_ds ? SOSDataSourceGetSharedEngine(bob_ds, NULL) : (SOSEngineRef) NULL;
- SOSDataSourceRef alice_ds = SOSDataSourceFactoryCreateDataSource(alice_account.factory, CFSTR("ak"), NULL);
- SOSEngineRef alice_engine = alice_ds ? SOSDataSourceGetSharedEngine(alice_ds, NULL) : (SOSEngineRef) NULL;
-
- /* new routines to test */
- __block NSString *bobID = bob_account.peerID;
- __block NSString *aliceID = alice_account.peerID;
-
-
- ///////////////////////////
- //second exchange//
- ///////////////////////////
-
- SOSCircleForEachValidPeer(aliceTrust.trustedCircle, alice_account.accountKey, ^(SOSPeerInfoRef peer) {
- if (!SOSAccountIsThisPeerIDMe(alice_account, SOSPeerInfoGetPeerID(peer))) {
- if(SOSPeerInfoShouldUseIDSTransport(aliceTrust.peerInfo, peer) &&
- SOSPeerInfoShouldUseIDSMessageFragmentation(aliceTrust.peerInfo, peer)){
- secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
-
- CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer));
-
- SyncingCompletedOverIDS = [alice_account.ids_message_transport SOSTransportMessageSyncWithPeers:alice_account.ids_message_transport p:ids err:&localError];
- CFReleaseNull(ids);
- }
- }
- });
-
- SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
- ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID));
- ok(false == SOSPeerTimerForPeerExist(bob_peer));
- ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID));
- ok(true == SOSCoderIsCoderInAwaitingState(coder));
- });
-
- ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
-
- SOSCircleForEachValidPeer(bobTrust.trustedCircle, bob_account.accountKey, ^(SOSPeerInfoRef peer) {
- if (!SOSAccountIsThisPeerIDMe(bob_account, SOSPeerInfoGetPeerID(peer))) {
- if(SOSPeerInfoShouldUseIDSTransport(bobTrust.peerInfo, peer) &&
- SOSPeerInfoShouldUseIDSMessageFragmentation(bobTrust.peerInfo, peer)){
- secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
-
- CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer));
-
- SyncingCompletedOverIDS = [(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)bob_account.ids_message_transport p:ids err:&localError];
- CFReleaseNull(ids);
- }
- }
- });
-
- ok(SyncingCompletedOverIDS, "synced items over IDS");
-
- SOSEngineWithPeerID(bob_engine, (__bridge CFStringRef)aliceID, NULL, ^(SOSPeerRef alice_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
- ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(bob_account , aliceID));
- ok(false == SOSPeerTimerForPeerExist(alice_peer));
- ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(bob_account, aliceID));
- });
-
- ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
-
- SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
- ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID));
- ok(false == SOSPeerTimerForPeerExist(bob_peer));
- ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID));
- ok(true == SOSCoderIsCoderInAwaitingState(coder));
- });
-
- ///////////////////////////
- //second sync exchange //
- ///////////////////////////
-
- SOSCircleForEachValidPeer(aliceTrust.trustedCircle, alice_account.accountKey, ^(SOSPeerInfoRef peer) {
- if (!SOSAccountIsThisPeerIDMe(alice_account, SOSPeerInfoGetPeerID(peer))) {
- if(SOSPeerInfoShouldUseIDSTransport(aliceTrust.peerInfo, peer) &&
- SOSPeerInfoShouldUseIDSMessageFragmentation(aliceTrust.peerInfo, peer)){
- secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
-
- CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer));
-
- SyncingCompletedOverIDS = [alice_account.ids_message_transport SOSTransportMessageSyncWithPeers:alice_account.ids_message_transport p:ids err:&localError];
- CFReleaseNull(ids);
- }
- }
- });
-
- SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
- ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID));
- ok(false == SOSPeerTimerForPeerExist(bob_peer));
- ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID));
- ok(true == SOSCoderIsCoderInAwaitingState(coder));
- });
-
- ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
-
- SOSCircleForEachValidPeer(bobTrust.trustedCircle, bob_account.accountKey, ^(SOSPeerInfoRef peer) {
- if (!SOSAccountIsThisPeerIDMe(bob_account, SOSPeerInfoGetPeerID(peer))) {
- if(SOSPeerInfoShouldUseIDSTransport(bobTrust.peerInfo, peer) &&
- SOSPeerInfoShouldUseIDSMessageFragmentation(bobTrust.peerInfo, peer)){
- secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
-
- CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer));
-
- SyncingCompletedOverIDS = [(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)bob_account.ids_message_transport p:ids err:&localError];
- CFReleaseNull(ids);
- }
- }
- });
-
- ok(SyncingCompletedOverIDS, "synced items over IDS");
-
- SOSEngineWithPeerID(bob_engine, (__bridge CFStringRef)aliceID, NULL, ^(SOSPeerRef alice_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
- ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(bob_account , aliceID));
- ok(false == SOSPeerTimerForPeerExist(alice_peer));
- ok(false == SOSPeerOTRTimerHaveAnRTTAvailable(bob_account, aliceID));
- });
-
- ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
-
- SOSEngineWithPeerID(alice_engine, (__bridge CFStringRef)bobID, NULL, ^(SOSPeerRef bob_peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
- ok(false == SOSPeerOTRTimerHaveReachedMaxRetryAllowance(alice_account , bobID));
- ok(false == SOSPeerTimerForPeerExist(bob_peer));
- ok(true == SOSPeerOTRTimerHaveAnRTTAvailable(alice_account, bobID));
- ok(false == SOSCoderIsCoderInAwaitingState(coder));
- });
-
- CFReleaseNull(changes);
-}
-
static void tests(void)
{
SOSUnregisterAllTransportMessages();
CFArrayRemoveAllValues(message_transports);
- SOSAccountTrustClassic* aliceTrust = alice_account.trust;
- SOSAccountTrustClassic* bobTrust = bob_account.trust;
-
- alice_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:alice_account andAccountName:CFSTR("Alice") andCircleName:SOSCircleGetName(aliceTrust.trustedCircle) err:&error ];
-
- bob_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:bob_account andAccountName:CFSTR("Bob") andCircleName:SOSCircleGetName(bobTrust.trustedCircle) err:&error];
-
- ok(alice_account.ids_message_transport != NULL, "Alice Account, Created IDS Test Transport");
- ok(bob_account.ids_message_transport != NULL, "Bob Account, Created IDS Test Transport");
-
- bool result = [alice_account.trust modifyCircle:alice_account.circle_transport err:&error action:^bool(SOSCircleRef circle) {
- CFErrorRef localError = NULL;
-
- SOSFullPeerInfoUpdateTransportType(aliceTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError);
- SOSFullPeerInfoUpdateTransportPreference(aliceTrust.fullPeerInfo, kCFBooleanFalse, &localError);
- SOSFullPeerInfoUpdateTransportFragmentationPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError);
- SOSFullPeerInfoUpdateTransportAckModelPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError);
-
- return SOSCircleHasPeer(circle, aliceTrust.peerInfo, NULL);
- }];
-
- ok(result, "Alice account update circle with transport type");
-
- is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
-
- result = [bob_account.trust modifyCircle:bob_account.circle_transport err:&error action:^bool(SOSCircleRef circle) {
- CFErrorRef localError = NULL;
-
- SOSFullPeerInfoUpdateTransportType(bobTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError);
- SOSFullPeerInfoUpdateTransportPreference(bobTrust.fullPeerInfo, kCFBooleanFalse, &localError);
- SOSFullPeerInfoUpdateTransportFragmentationPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError);
- SOSFullPeerInfoUpdateTransportAckModelPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError);
-
- return SOSCircleHasPeer(circle, bobTrust.peerInfo, NULL);
- }];
-
- ok(result, "Bob account update circle with transport type");
- is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
-
- CFStringRef alice_transportType =SOSPeerInfoCopyTransportType(alice_account.peerInfo);
- CFStringRef bob_accountTransportType = SOSPeerInfoCopyTransportType(bob_account.peerInfo);
- ok(CFEqualSafe(alice_transportType, CFSTR("IDS2.0")), "Alice transport type not IDS");
- ok(CFEqualSafe(bob_accountTransportType, CFSTR("IDS2.0")), "Bob transport type not IDS");
-
- CFReleaseNull(alice_transportType);
- CFReleaseNull(bob_accountTransportType);
-
- SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)alice_account.ids_message_transport, CFSTR("Alice Account"));
- ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)alice_account.ids_message_transport) != NULL, "retrieved getting account name");
- ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(alice_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy");
-
- SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)bob_account.ids_message_transport, CFSTR("Bob Account"));
- ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)bob_account.ids_message_transport) != NULL, "retrieved getting account name");
- ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(bob_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy");
-
-
- ok(SOSAccountSetMyDSID_wTxn(alice_account, CFSTR("Alice"),&error), "Setting IDS device ID");
- CFStringRef alice_dsid = SOSAccountCopyDeviceID(alice_account, &error);
- ok(CFEqualSafe(alice_dsid, CFSTR("Alice")), "Getting IDS device ID");
- CFReleaseNull(alice_dsid);
-
- ok(SOSAccountSetMyDSID_wTxn(bob_account, CFSTR("Bob"),&error), "Setting IDS device ID");
- CFStringRef bob_dsid = SOSAccountCopyDeviceID(bob_account, &error);
- ok(CFEqualSafe(bob_dsid, CFSTR("Bob")), "Getting IDS device ID");
- CFReleaseNull(bob_dsid);
- is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates");
-
ok(SOSAccountEnsurePeerRegistration(alice_account, NULL), "ensure peer registration - alice");
ok(SOSAccountEnsurePeerRegistration(bob_account, NULL), "ensure peer registration - bob");
}
void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
-CFArrayRef SecAccessGroupsGetCurrent();
+CFArrayRef SecAccessGroupsGetCurrent(void);
int
secd_20_keychain_upgrade(int argc, char *const *argv)
return retval;
}
+static void timeval_delta(struct timeval *delta, struct timeval *start, struct timeval *end) {
+ if(end->tv_usec >= start->tv_usec) {
+ delta->tv_usec = end->tv_usec - start->tv_usec;
+ } else {
+ end->tv_sec--;
+ end->tv_usec += 1000000;
+ delta->tv_usec = end->tv_usec - start->tv_usec;
+ }
+ delta->tv_sec = end->tv_sec - start->tv_sec;
+}
+
+static void reportTime(int peers, void(^action)(void)) {
+ struct rusage start_rusage;
+ struct rusage end_rusage;
+ struct timeval delta_utime;
+ struct timeval delta_stime;
+
+ getrusage(RUSAGE_SELF, &start_rusage);
+ action();
+ getrusage(RUSAGE_SELF, &end_rusage);
+ timeval_delta(&delta_utime, &start_rusage.ru_utime, &end_rusage.ru_utime);
+ timeval_delta(&delta_stime, &start_rusage.ru_stime, &end_rusage.ru_stime);
+
+ diag("AccountLogState for %d peers: %ld.%06d user %ld.%06d system", peers,
+ delta_utime.tv_sec, delta_utime.tv_usec,
+ delta_stime.tv_sec, delta_stime.tv_usec);
+}
+
static void tests(void)
{
NSError* ns_error = nil;
CFReleaseNull(cfpassword);
secLogEnable();
- SOSAccountLogState(master_account);
+ reportTime(1, ^{
+ SOSAccountLogState(master_account);
+ });
secLogDisable();
ok(MakeTheBigCircle(changes, master_account, minion_accounts, &error), "Get Everyone into the circle %@", error);
diag("WHAT?");
secLogEnable();
- SOSAccountLogState(master_account);
+ reportTime(HOW_MANY_MINIONS+1, ^{
+ SOSAccountLogState(master_account);
+ });
SOSAccountLogViewState(master_account);
secLogDisable();
#include "SecdTestKeychainUtilities.h"
-static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) {
- SOSAccountTrustClassic*trust = account.trust;
- SOSPeerInfoRef mypi = trust.peerInfo;
- CFStringRef myPeerID = SOSPeerInfoGetPeerID(mypi);
-
- return myPeerID && CFEqualSafe(myPeerID, peerID);
-}
-
-static void compareCoders(CFMutableDictionaryRef beforeCoders, CFMutableDictionaryRef afterCoderState)
-{
- CFDictionaryForEach(beforeCoders, ^(const void *key, const void *value) {
- CFStringRef beforePeerid = (CFStringRef)key;
- SOSCoderRef beforeCoderData = (SOSCoderRef)value;
- SOSCoderRef afterCoderData = (SOSCoderRef)CFDictionaryGetValue(afterCoderState, beforePeerid);
- ok(CFEqual(beforeCoderData,afterCoderData));
- });
-}
-
-static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){
-
- CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
- __block bool SyncingCompletedOverIDS = false;
- __block CFErrorRef localError = NULL;
- __block bool done = false;
- SOSAccountTrustClassic *aliceTrust = alice_account.trust;
- SOSAccountTrustClassic *bobTrust = bob_account.trust;
-
- do{
- SOSCircleForEachValidPeer(aliceTrust.trustedCircle, alice_account.accountKey, ^(SOSPeerInfoRef peer) {
- if (!SOSAccountIsThisPeerIDMe(alice_account, SOSPeerInfoGetPeerID(peer))) {
- if(SOSPeerInfoShouldUseIDSTransport(aliceTrust.peerInfo, peer) &&
- SOSPeerInfoShouldUseIDSMessageFragmentation(aliceTrust.peerInfo, peer)){
- secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
-
- CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer));
-
- CFTypeRef alice_engine = [(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageGetEngine];
-
- //testing loading and saving coders
- ok(TestSOSEngineGetCoders(alice_engine));
- CFMutableDictionaryRef beforeCoders = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(alice_engine)), TestSOSEngineGetCoders(alice_engine));
- TestSOSEngineDoTxnOnQueue(alice_engine, &localError, ^(SOSTransactionRef txn, bool *commit) {
- ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError));
- });
-
- ok(TestSOSEngineGetCoders(alice_engine));
-
- TestSOSEngineDoTxnOnQueue(alice_engine, &localError, ^(SOSTransactionRef txn, bool *commit) {
- ok(SOSTestEngineSaveCoders(alice_engine, txn, &localError));
- });
-
- compareCoders(beforeCoders, TestSOSEngineGetCoders(alice_engine));
-
- //syncing with all peers
- SyncingCompletedOverIDS = [(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)alice_account.ids_message_transport p:ids err:&localError];
- //testing load after sync with all peers
- CFMutableDictionaryRef codersAfterSyncBeforeLoad = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(alice_engine)), TestSOSEngineGetCoders(alice_engine));
- TestSOSEngineDoTxnOnQueue(alice_engine, &localError, ^(SOSTransactionRef txn, bool *commit) {
- ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)alice_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError));
- });
- compareCoders(codersAfterSyncBeforeLoad, TestSOSEngineGetCoders(alice_engine));
-
- CFReleaseNull(codersAfterSyncBeforeLoad);
- CFReleaseNull(beforeCoders);
- CFReleaseNull(ids);
- }
- }
- });
-
- ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
-
- SOSCircleForEachValidPeer(bobTrust.trustedCircle, bob_account.accountKey, ^(SOSPeerInfoRef peer) {
- if (!SOSAccountIsThisPeerIDMe(bob_account, SOSPeerInfoGetPeerID(peer))) {
- if(SOSPeerInfoShouldUseIDSTransport(bobTrust.peerInfo, peer) &&
- SOSPeerInfoShouldUseIDSMessageFragmentation(bobTrust.peerInfo, peer)){
- secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
-
- CFMutableSetRef ids = CFSetCreateMutableForCFTypes(kCFAllocatorDefault);
- CFSetAddValue(ids, SOSPeerInfoGetPeerID(peer));
-
- SOSEngineRef bob_engine = (SOSEngineRef)[(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageGetEngine];
-
- //testing loading and saving coders
- ok(TestSOSEngineGetCoders(bob_engine));
- CFMutableDictionaryRef beforeCoders = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(bob_engine)), TestSOSEngineGetCoders(bob_engine));
- TestSOSEngineDoTxnOnQueue(bob_engine, &localError, ^(SOSTransactionRef txn, bool *commit) {
- ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError));
- });
-
- ok((SOSEngineRef)TestSOSEngineGetCoders(bob_engine));
-
- TestSOSEngineDoTxnOnQueue(bob_engine, &localError, ^(SOSTransactionRef txn, bool *commit) {
- ok(SOSTestEngineSaveCoders(bob_engine, txn, &localError));
- });
-
- compareCoders(beforeCoders, TestSOSEngineGetCoders(bob_engine));
-
- SyncingCompletedOverIDS &= [(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageSyncWithPeers:(SOSMessageIDSTest*)bob_account.ids_message_transport p:ids err:&localError];
-
- //testing load after sync with all peers
- CFMutableDictionaryRef codersAfterSyncBeforeLoad = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(TestSOSEngineGetCoders(bob_engine)), TestSOSEngineGetCoders(bob_engine));
- TestSOSEngineDoTxnOnQueue(bob_engine, &localError, ^(SOSTransactionRef txn, bool *commit) {
- ok(TestSOSEngineLoadCoders((SOSEngineRef)[(SOSMessageIDSTest*)bob_account.ids_message_transport SOSTransportMessageGetEngine], txn, &localError));
- });
- compareCoders(codersAfterSyncBeforeLoad, TestSOSEngineGetCoders(bob_engine));
- CFReleaseNull(codersAfterSyncBeforeLoad);
- CFReleaseNull(beforeCoders);
- CFReleaseNull(ids);
- }
- }
- });
- if(!SyncingCompletedOverIDS)
- return;
-
- if(CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges((SOSMessageIDSTest*)alice_account.ids_message_transport)) == 0 && CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges((SOSMessageIDSTest*)bob_account.ids_message_transport)) == 0){
- done = true;
- break;
- }
-
- ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
-
- }while(done == false);
- CFReleaseNull(changes);
-
- ok(SyncingCompletedOverIDS, "synced items over IDS");
-
-}
-
static void tests(void)
{
SOSUnregisterAllTransportMessages();
CFArrayRemoveAllValues(message_transports);
- SOSAccountTrustClassic *aliceTrust = alice_account.trust;
- SOSAccountTrustClassic *bobTrust = bob_account.trust;
-
- alice_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:alice_account andAccountName:CFSTR("Alice") andCircleName:CFSTR("TestSource") err:&error];
-
- bob_account.ids_message_transport = (SOSMessageIDS*)[[SOSMessageIDSTest alloc] initWithAccount:bob_account andAccountName:CFSTR("Bob") andCircleName:CFSTR("TestSource") err:&error];
-
- bool result = [alice_account.trust modifyCircle:alice_account.circle_transport err:&error action:^(SOSCircleRef circle) {
-
- CFErrorRef localError = NULL;
-
- SOSFullPeerInfoUpdateTransportType(aliceTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError);
- SOSFullPeerInfoUpdateTransportPreference(aliceTrust.fullPeerInfo, kCFBooleanFalse, &localError);
- SOSFullPeerInfoUpdateTransportFragmentationPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError);
- SOSFullPeerInfoUpdateTransportAckModelPreference(aliceTrust.fullPeerInfo, kCFBooleanTrue, &localError);
-
- return SOSCircleHasPeer(circle, aliceTrust.peerInfo, NULL);
- }];
-
- ok(result, "Alice account update circle with transport type");
-
- is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
-
- result = [bob_account.trust modifyCircle:bob_account.circle_transport err:&error action:^(SOSCircleRef circle) {
- CFErrorRef localError = NULL;
-
- SOSFullPeerInfoUpdateTransportType(bobTrust.fullPeerInfo, SOSTransportMessageTypeIDSV2, &localError);
- SOSFullPeerInfoUpdateTransportPreference(bobTrust.fullPeerInfo, kCFBooleanFalse, &localError);
- SOSFullPeerInfoUpdateTransportFragmentationPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError);
- SOSFullPeerInfoUpdateTransportAckModelPreference(bobTrust.fullPeerInfo, kCFBooleanTrue, &localError);
-
- return SOSCircleHasPeer(circle, bobTrust.peerInfo, NULL);
- }];
-
- ok(result, "Bob account update circle with transport type");
- is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
-
- CFStringRef alice_transportType =SOSPeerInfoCopyTransportType(alice_account.peerInfo);
- CFStringRef bob_accountTransportType = SOSPeerInfoCopyTransportType(bob_account.peerInfo);
- ok(CFEqualSafe(alice_transportType, CFSTR("IDS2.0")), "Alice transport type not IDS");
- ok(CFEqualSafe(bob_accountTransportType, CFSTR("IDS2.0")), "Bob transport type not IDS");
-
- CFReleaseNull(alice_transportType);
- CFReleaseNull(bob_accountTransportType);
-
- SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)alice_account.ids_message_transport, CFSTR("Alice Account"));
- ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)alice_account.ids_message_transport) != NULL, "retrieved getting account name");
- ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(alice_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy");
-
- SOSTransportMessageIDSTestSetName((SOSMessageIDSTest*)bob_account.ids_message_transport, CFSTR("Bob Account"));
- ok(SOSTransportMessageIDSTestGetName((SOSMessageIDSTest*)bob_account.ids_message_transport) != NULL, "retrieved getting account name");
- ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(bob_account, &error) != false, "device ID from KeychainSyncingOverIDSProxy");
-
-
- ok(SOSAccountSetMyDSID_wTxn(alice_account, CFSTR("Alice"),&error), "Setting IDS device ID");
- CFStringRef alice_dsid = SOSAccountCopyDeviceID(alice_account, &error);
- ok(CFEqualSafe(alice_dsid, CFSTR("Alice")), "Getting IDS device ID");
- CFReleaseNull(alice_dsid);
-
- ok(SOSAccountSetMyDSID_wTxn(bob_account, CFSTR("Bob"),&error), "Setting IDS device ID");
- CFStringRef bob_dsid = SOSAccountCopyDeviceID(bob_account, &error);
- ok(CFEqualSafe(bob_dsid, CFSTR("Bob")), "Getting IDS device ID");
- CFReleaseNull(bob_dsid);
-
- is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates");
ok(SOSAccountEnsurePeerRegistration(alice_account, NULL), "ensure peer registration - alice");
ok(SOSAccountEnsurePeerRegistration(bob_account, NULL), "ensure peer registration - bob");
- ids_test_sync(alice_account, bob_account);
-
alice_account = nil;
bob_account = nil;
#include "SecdTestKeychainUtilities.h"
void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
-CFArrayRef SecAccessGroupsGetCurrent();
+CFArrayRef SecAccessGroupsGetCurrent(void);
int
secd_21_transmogrify(int argc, char *const *argv)
static const bool kTestLocalKeybag = false;
void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
-CFArrayRef SecAccessGroupsGetCurrent();
+CFArrayRef SecAccessGroupsGetCurrent(void);
#define kSecdTestCreateCustomKeybagTestCount 6
#define kSecdTestLocalKeybagTestCount 1
#include "ios8-inet-keychain-2.h"
void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
-CFArrayRef SecAccessGroupsGetCurrent();
+CFArrayRef SecAccessGroupsGetCurrent(void);
int secd_35_keychain_migrate_inet(int argc, char *const *argv)
{
#include "SecdTestKeychainUtilities.h"
void SecAccessGroupsSetCurrent(CFArrayRef accessGroups);
-CFArrayRef SecAccessGroupsGetCurrent();
+CFArrayRef SecAccessGroupsGetCurrent(void);
static void AddItem(NSDictionary *attr)
static int kTestTestCount = 1;
static void tests(void)
{
- CFStringRef osVersion = CopyOSVersion();
+ CFStringRef osVersion = SOSCCCopyOSVersion();
ok(osVersion != NULL, "OS Version Exists");
#include "SecdTestKeychainUtilities.h"
-static int kTestTestCount = 324;
+static int kTestTestCount = 257;
static void tests(void)
{
ok(SOSAccountJoinCircles_wTxn(alice_account, &error), "Alice re-applies (%@)", error);
CFReleaseNull(error);
- FeedChangesTo(changes, bob_account); // Bob sees Alice reapply.
-
+ //FeedChangesTo(changes, bob_account); // Bob sees Alice reapply.
+ is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
+
{
CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
CFReleaseNull(error);
CFReleaseNull(applicants);
}
- is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carol_account, NULL), 2, "updates");
+ is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carol_account, NULL), 3, "updates");
accounts_agree("Alice comes back", bob_account, alice_account);
is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carol_account, NULL), 4, "Remove peers");
- ok([alice_account.trust isInCircle:&error], "Alice still here");
- ok(![bob_account.trust isInCircle:&error], "Bob not in circle");
+ ok([alice_account isInCircle:&error], "Alice still here");
+ ok(![bob_account isInCircle:&error], "Bob not in circle");
// Carol's not in circle, but reapplied, as she's persistent until positive rejection.
- ok(![carol_account.trust isInCircle:NULL], "carol not in circle");
+ ok(![carol_account isInCircle:NULL], "carol not in circle");
CFReleaseNull(peers_to_remove_array);
is(ProcessChangesUntilNoChange(changes, alice_account, NULL), 1, "updates");
- ok([alice_account.trust isInCircle:&error], "Alice is back in the circle (%@)", error);
+ ok([alice_account isInCircle:&error], "Alice is back in the circle (%@)", error);
CFReleaseNull(error);
is(countActivePeers(alice_account), 2, "Alice sees 2 active peers");
ok([bob_account.trust leaveCircle:bob_account err:&error], "bob Leaves w/o credentials (%@)", error);
CFReleaseNull(error);
- ok(![bob_account.trust isInCircle:&error], "bob knows he's out (%@)", error);
+ ok(![bob_account isInCircle:&error], "bob knows he's out (%@)", error);
CFReleaseNull(error);
alice_account = nil;
bob_account = nil;
static int kTestTestCount = 107;
typedef void (^stir_block)(int expected_iterations);
-typedef int (^execute_block)();
+typedef int (^execute_block)(void);
static void stirBetween(stir_block stir, ...) {
va_list va;
CFReleaseNull(error);
return 1;
}, ^{
- ok(![alice_resurrected.trust isInCircle:&error], "Ressurrected not in circle: %@", error);
+ ok(![alice_resurrected isInCircle:&error], "Ressurrected not in circle: %@", error);
CFReleaseNull(error);
ok(SOSAccountJoinCircles_wTxn(alice_resurrected, &error), "Risen-alice Applies (%@)", error);
static int kTestTestCount = 43;
typedef void (^stir_block)(int expected_iterations);
-typedef int (^execute_block)();
+typedef int (^execute_block)(void);
static void stirBetween(stir_block stir, ...) {
va_list va;
CFReleaseNull(error);
return 1;
}, ^{
- ok(![alice_resurrected.trust isInCircle:&error], "Ressurrected not in circle: %@", error);
+ ok(![alice_resurrected isInCircle:&error], "Ressurrected not in circle: %@", error);
CFReleaseNull(error);
- ok([bob_account.trust isInCircle:&error], "Should be in circle: %@", error);
+ ok([bob_account isInCircle:&error], "Should be in circle: %@", error);
CFReleaseNull(error);
return 1;
// Did ghostbuster work?
is(ProcessChangesUntilNoChange(changes, bobFinal, NULL), 2, "updates");
if(expectGhostBusted) { // ghostbusting is currently disabled for MacOSX Peers
- ok([bobFinal.trust isInCircle:NULL], "Bob is in");
+ ok([bobFinal isInCircle:NULL], "Bob is in");
} else {
- ok(![bobFinal.trust isInCircle:NULL], "Bob is not in");
+ ok(![bobFinal isInCircle:NULL], "Bob is not in");
}
is(countPeers(bobFinal), 1, "There should only be 1 valid peer");
CFReleaseNull(cfpassword);
- ok([bobFinal_account.trust isInCircle:NULL], "bobFinal_account is in");
+ ok([bobFinal_account isInCircle:NULL], "bobFinal_account is in");
is(countPeers(bobFinal_account), 2, "Expect ghostBobs to be gone");
is(countPeers(alice_account), 2, "Expect ghostBobs to be gone");
+++ /dev/null
-/*
- * 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 <Foundation/Foundation.h>
-#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;
-}
+++ /dev/null
-//
-// secd-82-secproperties-basic.c
-// sec
-//
-// Created by Richard Murphy on 4/16/15.
-//
-//
-
-#include <stdio.h>
-//
-// secd-80-views-basic.c
-// sec
-//
-// Created by Richard Murphy on 1/26/15.
-//
-//
-
-#include <stdio.h>
-/*
- * 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@
- */
-
-
-
-#include <Security/SecBase.h>
-#include <Security/SecItem.h>
-
-#include <Security/SecureObjectSync/SOSAccount.h>
-#include <Security/SecureObjectSync/SOSCloudCircle.h>
-#include <Security/SecureObjectSync/SOSInternal.h>
-#include <Security/SecureObjectSync/SOSFullPeerInfo.h>
-#include <Security/SecureObjectSync/SOSUserKeygen.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "secd_regressions.h"
-#include "SOSTestDataSource.h"
-
-#include "SOSRegressionUtilities.h"
-#include <utilities/SecCFWrappers.h>
-
-#include <securityd/SOSCloudCircleServer.h>
-#include "SecdTestKeychainUtilities.h"
-#include "SOSAccountTesting.h"
-
-
-static void testSecurityProperties(SOSAccount* account, SOSSecurityPropertyResultCode expected, CFStringRef property, SOSSecurityPropertyActionCode action, char *label) {
- CFErrorRef error = NULL;
- SOSSecurityPropertyResultCode pcode = 9999;
- switch(action) {
- case kSOSCCSecurityPropertyQuery:
- pcode = [account.trust SecurityPropertyStatus:property err:&error];
- break;
- case kSOSCCSecurityPropertyEnable:
- case kSOSCCSecurityPropertyDisable: // fallthrough
- pcode = [account.trust UpdateSecurityProperty:account property:property code:action err:&error];
- break;
- default:
- break;
- }
- ok((pcode == expected), "%s (%@)", label, error);
- CFReleaseNull(error);
-}
-
-static int kTestTestCount = 13;
-static void tests(void)
-{
- CFErrorRef error = NULL;
- CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
- CFStringRef cfaccount = CFSTR("test@test.org");
-
- SOSDataSourceFactoryRef test_factory = SOSTestDataSourceFactoryCreate();
- SOSDataSourceRef test_source = SOSTestDataSourceCreate();
- SOSTestDataSourceFactorySetDataSource(test_factory, CFSTR("TestType"), test_source);
-
- SOSAccount* account = CreateAccountForLocalChanges(CFSTR("Test Device"),CFSTR("TestType") );
-
- ok(SOSAccountAssertUserCredentialsAndUpdate(account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
- CFReleaseNull(error);
- CFReleaseNull(cfpassword);
-
- ok(SOSAccountJoinCircles_wTxn(account, &error), "Join Cirlce");
-
- ok(NULL != account, "Created");
-
- testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyHasEntropy, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyHasEntropy");
- testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyScreenLock, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyScreenLock");
- testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertySEP, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertySEP");
- testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyIOS");
- testSecurityProperties(account, kSOSCCSecurityPropertyValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyEnable, "Expected to add property: kSOSSecPropertyIOS");
- testSecurityProperties(account, kSOSCCSecurityPropertyValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyIOS");
- testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyDisable, "Expected to disable property: kSOSSecPropertyIOS");
- testSecurityProperties(account, kSOSCCSecurityPropertyNotValid, kSOSSecPropertyIOS, kSOSCCSecurityPropertyQuery, "Expected no property: kSOSSecPropertyIOS");
- testSecurityProperties(account, kSOSCCNoSuchSecurityProperty, CFSTR("FOO"), kSOSCCSecurityPropertyQuery, "Expected no such property for FOO");
- SOSDataSourceRelease(test_source, NULL);
- SOSDataSourceFactoryRelease(test_factory);
-
- SOSTestCleanup();
-}
-
-int secd_82_secproperties_basic(int argc, char *const *argv)
-{
- plan_tests(kTestTestCount);
-
- secd_test_setup_temp_keychain(__FUNCTION__, NULL);
-
- tests();
-
- return 0;
-}
ONE_TEST(secd_70_engine_corrupt)
ONE_TEST(secd_70_engine_smash)
ONE_TEST(secd_71_engine_save)
-ONE_TEST(secd_76_idstransport)
-ONE_TEST(secd_77_ids_messaging)
ONE_TEST(secd_68_ghosts)
ONE_TEST(secd_155_otr_negotiation_monitor)
OFF_ONE_TEST(secd_75_engine_views)
ONE_TEST(secd_80_views_basic)
ONE_TEST(secd_80_views_alwayson)
-ONE_TEST(secd_82_secproperties_basic)
#if TARGET_IPHONE_SIMULATOR
OFF_ONE_TEST(secd_81_item_acl_stress)
OFF_ONE_TEST(secd_81_item_acl)
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)
--- /dev/null
+/*
+ * 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 <TargetConditionals.h>
+
+#define kSFKeychainServerServiceName "com.apple.security.sfkeychainserver"
+
+#if !TARGET_OS_BRIDGE && __OBJC2__
+
+#import <Foundation/Foundation.h>
+#import <SecurityFoundation/SFKeychainServerProtocol.h>
+#import "SecCDKeychain.h"
+
+@interface SFKeychainServer : NSObject <NSXPCListenerDelegate>
+
+- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase;
+
+@end
+
+@interface SecCDKeychainItemTypeCredential : SecCDKeychainItemType
+@end
+
+@interface SFKeychainServerConnection : NSObject <SFKeychainServerProtocol>
+
+@property (readonly) NSArray<NSString*>* clientAccessGroups;
+
+@end
+
+#endif // !TARGET_OS_BRIDGE && __OBJC2__
+
+void SFKeychainServerInitialize(void);
--- /dev/null
+/*
+ * 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 "SFKeychainServer.h"
+#import <TargetConditionals.h>
+
+#if !TARGET_OS_BRIDGE
+#if __OBJC2__
+
+#import "SecCDKeychain.h"
+#import "SecFileLocations.h"
+#import "debugging.h"
+#import "CloudKitCategories.h"
+#import "SecAKSWrappers.h"
+#include "securityd_client.h"
+#import "server_entitlement_helpers.h"
+#import "SecTask.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
+#import "SecEntitlements.h"
+#import <SecurityFoundation/SFKeychain.h>
+#import <SecurityFoundation/SFCredential_Private.h>
+#import <SecurityFoundation/SFCredentialStore_Private.h>
+#import <Foundation/NSKeyedArchiver_Private.h>
+#import <Foundation/NSXPCConnection_Private.h>
+
+static NSString* const SFKeychainItemAttributeLocalizedLabel = @"label";
+static NSString* const SFKeychainItemAttributeLocalizedDescription = @"description";
+
+static NSString* const SFCredentialAttributeUsername = @"username";
+static NSString* const SFCredentialAttributePrimaryServiceIdentifier = @"primaryServiceID";
+static NSString* const SFCredentialAttributeSupplementaryServiceIdentifiers = @"supplementaryServiceIDs";
+static NSString* const SFCredentialAttributeCreationDate = @"creationDate";
+static NSString* const SFCredentialAttributeModificationDate = @"modificationDate";
+static NSString* const SFCredentialAttributeCustom = @"customAttributes";
+static NSString* const SFCredentialSecretPassword = @"password";
+
+@interface SFCredential (securityd_only)
+
+- (instancetype)_initWithUsername:(NSString*)username primaryServiceIdentifier:(SFServiceIdentifier*)primaryServiceIdentifier supplementaryServiceIdentifiers:(nullable NSArray<SFServiceIdentifier*>*)supplementaryServiceIdentifiers;
+
+@end
+
+@interface SFKeychainServerConnection ()
+
+- (instancetype)initWithKeychain:(SecCDKeychain*)keychain xpcConnection:(NSXPCConnection*)connection;
+
+@end
+
+@implementation SecCDKeychainItemTypeCredential
+
++ (instancetype)itemType
+{
+ static SecCDKeychainItemTypeCredential* itemType = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ itemType = [[self alloc] _initWithName:@"Credential" version:1 primaryKeys:@[SFCredentialAttributeUsername, SFCredentialAttributePrimaryServiceIdentifier] syncableKeys:nil];
+ });
+
+ return itemType;
+}
+
+@end
+
+@implementation SFKeychainServer {
+ SecCDKeychain* _keychain;
+}
+
+- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase
+{
+ if (self = [super init]) {
+ _keychain = [[SecCDKeychain alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectURL encryptDatabase:encryptDatabase];
+ }
+
+ return self;
+}
+
+- (BOOL)listener:(NSXPCListener*)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection
+{
+ NSNumber* keychainDenyEntitlement = [newConnection valueForEntitlement:(__bridge NSString*)kSecEntitlementKeychainDeny];
+ if ([keychainDenyEntitlement isKindOfClass:[NSNumber class]] && keychainDenyEntitlement.boolValue == YES) {
+ secerror("SFKeychainServer: connection denied due to entitlement %@", kSecEntitlementKeychainDeny);
+ return NO;
+ }
+
+ // wait a bit for shared function from SecurityFoundation to get to SDK, then addopt that
+ NSXPCInterface* interface = [NSXPCInterface interfaceWithProtocol:@protocol(SFKeychainServerProtocol)];
+ [interface setClasses:[NSSet setWithObjects:[NSArray class], [SFServiceIdentifier class], nil] forSelector:@selector(rpcLookupCredentialsForServiceIdentifiers:reply:) argumentIndex:0 ofReply:NO];
+ [interface setClasses:[NSSet setWithObjects:[NSArray class], [SFPasswordCredential class], nil] forSelector:@selector(rpcLookupCredentialsForServiceIdentifiers:reply:) argumentIndex:0 ofReply:YES];
+ newConnection.exportedInterface = interface;
+ newConnection.exportedObject = [[SFKeychainServerConnection alloc] initWithKeychain:_keychain xpcConnection:newConnection];
+ [newConnection resume];
+ return YES;
+}
+
+- (SecCDKeychain*)_keychain
+{
+ return _keychain;
+}
+
+@end
+
+@implementation SFKeychainServerConnection {
+ SecCDKeychain* _keychain;
+ NSArray* _clientAccessGroups;
+}
+
+@synthesize clientAccessGroups = _clientAccessGroups;
+
+- (instancetype)initWithKeychain:(SecCDKeychain*)keychain xpcConnection:(NSXPCConnection*)connection
+{
+ if (self = [super init]) {
+ _keychain = keychain;
+
+ SecTaskRef task = SecTaskCreateWithAuditToken(NULL, connection.auditToken);
+ if (task) {
+ _clientAccessGroups = (__bridge_transfer NSArray*)SecTaskCopyAccessGroups(task);
+ }
+ CFReleaseNull(task);
+ }
+
+ return self;
+}
+
+- (keyclass_t)keyclassForAccessPolicy:(SFAccessPolicy*)accessPolicy
+{
+ if (accessPolicy.accessibility.mode == SFAccessibleAfterFirstUnlock) {
+ if (accessPolicy.sharingPolicy == SFSharingPolicyThisDeviceOnly) {
+ return key_class_cku;
+ }
+ else {
+ return key_class_ck;
+ }
+ }
+ else {
+ if (accessPolicy.sharingPolicy == SFSharingPolicyThisDeviceOnly) {
+ return key_class_aku;
+ }
+ else {
+ return key_class_ak;
+ }
+ }
+}
+
+- (void)rpcAddCredential:(SFCredential*)credential withAccessPolicy:(SFAccessPolicy*)accessPolicy reply:(void (^)(NSString* persistentIdentifier, NSError* error))reply
+{
+ if (![credential isKindOfClass:[SFPasswordCredential class]]) {
+ reply(nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidParameter userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"attempt to add credential to SFCredentialStore that is not a password credential: %@", credential]}]);
+ return;
+ }
+
+ NSString* accessGroup = accessPolicy.accessGroup;
+ if (!accessGroup) {
+ NSError* error = nil;
+ accessGroup = self.clientAccessGroups.firstObject;
+ if (!accessGroup) {
+ error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorMissingAccessGroup userInfo:@{NSLocalizedDescriptionKey : @"no keychain access group found; ensure that your process has the keychain-access-groups entitlement"}];
+ reply(nil, error);
+ return;
+ }
+ }
+
+ SFPasswordCredential* passwordCredential = (SFPasswordCredential*)credential;
+
+ NSError* error = nil;
+ NSData* primaryServiceIdentifierData = [NSKeyedArchiver archivedDataWithRootObject:passwordCredential.primaryServiceIdentifier requiringSecureCoding:YES error:&error];
+ if (!primaryServiceIdentifierData) {
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
+ reply(nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSaveFailed userInfo:@{ NSLocalizedDescriptionKey : @"failed to serialize primary service identifier", NSUnderlyingErrorKey : error }]);
+ });
+ return;
+ }
+
+ NSMutableArray* serializedSupplementaryServiceIdentifiers = [[NSMutableArray alloc] initWithCapacity:passwordCredential.supplementaryServiceIdentifiers.count];
+ for (SFServiceIdentifier* serviceIdentifier in passwordCredential.supplementaryServiceIdentifiers) {
+ NSData* serviceIdentifierData = [NSKeyedArchiver archivedDataWithRootObject:serviceIdentifier requiringSecureCoding:YES error:&error];
+ if (serviceIdentifierData) {
+ [serializedSupplementaryServiceIdentifiers addObject:serviceIdentifierData];
+ }
+ else {
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
+ reply(nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSaveFailed userInfo:@{ NSLocalizedDescriptionKey : @"failed to serialize supplementary service identifier", NSUnderlyingErrorKey : error }]);
+ });
+ return;
+ }
+ }
+
+ NSDictionary* attributes = @{ SFCredentialAttributeUsername : passwordCredential.username,
+ SFCredentialAttributePrimaryServiceIdentifier : primaryServiceIdentifierData,
+ SFCredentialAttributeSupplementaryServiceIdentifiers : serializedSupplementaryServiceIdentifiers,
+ SFCredentialAttributeCreationDate : [NSDate date],
+ SFCredentialAttributeModificationDate : [NSDate date],
+ SFKeychainItemAttributeLocalizedLabel : passwordCredential.localizedLabel,
+ SFKeychainItemAttributeLocalizedDescription : passwordCredential.localizedDescription,
+ SFCredentialAttributeCustom : passwordCredential.customAttributes ?: [NSDictionary dictionary] };
+
+ NSDictionary* secrets = @{ SFCredentialSecretPassword : passwordCredential.password };
+ NSUUID* persistentID = [NSUUID UUID];
+
+ // lookup attributes:
+ // 1. primaryServiceIdentifier (always)
+ // 2. username (always)
+ // 3. label (if present)
+ // 4. description (if present)
+ // 5. each of the service identifiers by type, e.g. "domain"
+ // 6. any custom attributes that fit the requirements (key is string, and value is plist type)
+
+ SecCDKeychainLookupTuple* primaryServiceIdentifierLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFCredentialAttributePrimaryServiceIdentifier value:primaryServiceIdentifierData];
+ SecCDKeychainLookupTuple* usernameLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFCredentialAttributeUsername value:passwordCredential.username];
+ SecCDKeychainLookupTuple* labelLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFKeychainItemAttributeLocalizedLabel value:passwordCredential.localizedLabel];
+ SecCDKeychainLookupTuple* descriptionLookup = [SecCDKeychainLookupTuple lookupTupleWithKey:SFKeychainItemAttributeLocalizedDescription value:passwordCredential.localizedDescription];
+ NSMutableArray* lookupAttributes = [[NSMutableArray alloc] initWithObjects:primaryServiceIdentifierLookup, usernameLookup, nil];
+ if (labelLookup) {
+ [lookupAttributes addObject:labelLookup];
+ }
+ if (descriptionLookup) {
+ [lookupAttributes addObject:descriptionLookup];
+ }
+
+ SFServiceIdentifier* primaryServiceIdentifier = credential.primaryServiceIdentifier;
+ [lookupAttributes addObject:[SecCDKeychainLookupTuple lookupTupleWithKey:primaryServiceIdentifier.lookupKey value:primaryServiceIdentifier.serviceID]];
+ for (SFServiceIdentifier* serviceIdentifier in credential.supplementaryServiceIdentifiers) {
+ [lookupAttributes addObject:[SecCDKeychainLookupTuple lookupTupleWithKey:serviceIdentifier.lookupKey value:serviceIdentifier.serviceID]];
+ }
+
+ [passwordCredential.customAttributes enumerateKeysAndObjectsUsingBlock:^(NSString* customKey, id value, BOOL* stop) {
+ if ([customKey isKindOfClass:[NSString class]]) {
+ SecCDKeychainLookupTuple* lookupTuple = [SecCDKeychainLookupTuple lookupTupleWithKey:customKey value:value];
+ if (lookupTuple) {
+ [lookupAttributes addObject:lookupTuple];
+ }
+ else {
+ // TODO: an error here?
+ }
+ }
+ }];
+
+ SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:accessGroup];
+ keyclass_t keyclass = [self keyclassForAccessPolicy:accessPolicy];
+ SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[SecCDKeychainItemTypeCredential itemType] withPersistentID:persistentID attributes:attributes lookupAttributes:lookupAttributes secrets:secrets owner:owner keyclass:keyclass];
+ [_keychain insertItems:@[item] withConnection:self completionHandler:^(bool success, NSError* error) {
+ if (success && !error) {
+ reply(persistentID.UUIDString, nil);
+ }
+ else {
+ reply(nil, error);
+ }
+ }];
+}
+
+- (void)rpcFetchPasswordCredentialForPersistentIdentifier:(NSString*)persistentIdentifier reply:(void (^)(SFPasswordCredential* credential, NSString* password, NSError* error))reply
+{
+ // TODO: negative testing
+ NSUUID* persistentID = [[NSUUID alloc] initWithUUIDString:persistentIdentifier];
+ if (!persistentID) {
+ secerror("SFKeychainServer: attempt to fetch credential with invalid persistent identifier; %@", persistentIdentifier);
+ reply(nil, nil, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidPersistentIdentifier userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"invalid persistent identifier: %@", persistentIdentifier]}]);
+ return;
+ }
+
+ [_keychain fetchItemForPersistentID:persistentID withConnection:self completionHandler:^(SecCDKeychainItem* item, NSError* error) {
+ NSError* localError = error;
+ SFPasswordCredential* credential = nil;
+ if (item && !error) {
+ credential = [self passwordCredentialForItem:item error:&localError];
+ }
+
+ if (credential) {
+ reply(credential, credential.password, nil);
+ }
+ else {
+ reply(nil, nil, localError);
+ }
+ }];
+}
+
+- (void)rpcLookupCredentialsForServiceIdentifiers:(nullable NSArray<SFServiceIdentifier*>*)serviceIdentifiers reply:(void (^)(NSArray<SFCredential*>* _Nullable results, NSError* _Nullable error))reply
+{
+ __block NSMutableDictionary* resultsDict = [[NSMutableDictionary alloc] init];
+ __block NSError* resultError = nil;
+
+ void (^processFetchedItems)(NSArray*) = ^(NSArray* fetchedItems) {
+ for (SecCDKeychainItemMetadata* item in fetchedItems) {
+ if ([item.itemType isKindOfClass:[SecCDKeychainItemTypeCredential class]]) {
+ SFPasswordCredential* credential = [self passwordCredentialForItemMetadata:item error:&resultError];
+ if (credential) {
+ resultsDict[item.persistentID] = credential;
+ }
+ else {
+ resultsDict = nil; // got an error
+ }
+ }
+ }
+ };
+
+ if (!serviceIdentifiers) {
+ // TODO: lookup everything
+ }
+ else {
+ for (SFServiceIdentifier* serviceIdentifier in serviceIdentifiers) {
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ // TODO: this is lamé; make fetchItemsWithValue take an array and get rid of the semaphore crap
+ [_keychain fetchItemsWithValue:serviceIdentifier.serviceID forLookupKey:serviceIdentifier.lookupKey ofType:SecCDKeychainLookupValueTypeString withConnection:self completionHandler:^(NSArray<SecCDKeychainItemMetadata*>* items, NSError* error) {
+ if (items && !error) {
+ processFetchedItems(items);
+ }
+ else {
+ resultsDict = nil;
+ resultError = error;
+ }
+
+ dispatch_semaphore_signal(semaphore);
+ }];
+ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
+ }
+ }
+
+ reply(resultsDict.allValues, resultError);
+}
+
+- (void)rpcRemoveCredentialWithPersistentIdentifier:(NSString*)persistentIdentifier reply:(void (^)(BOOL success, NSError* _Nullable error))reply
+{
+ NSUUID* persistentID = [[NSUUID alloc] initWithUUIDString:persistentIdentifier];
+ if (!persistentID) {
+ secerror("SFKeychainServer: attempt to remove credential with invalid persistent identifier; %@", persistentIdentifier);
+ reply(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidPersistentIdentifier userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"invalid persistent identifier: %@", persistentIdentifier]}]);
+ return;
+ }
+
+ [_keychain deleteItemWithPersistentID:persistentID withConnection:self completionHandler:^(bool success, NSError* error) {
+ reply(success, error);
+ }];
+}
+
+- (void)rpcReplaceOldCredential:(SFCredential*)oldCredential withNewCredential:(SFCredential*)newCredential reply:(void (^)(NSString* newPersistentIdentifier, NSError* _Nullable error))reply
+{
+ // TODO: implement
+ reply(nil, nil);
+}
+
+- (SFPasswordCredential*)passwordCredentialForItem:(SecCDKeychainItem*)item error:(NSError**)error
+{
+ SFPasswordCredential* credential = [self passwordCredentialForItemMetadata:item.metadata error:error];
+ if (credential) {
+ credential.password = item.secrets[SFCredentialSecretPassword];
+ if (!credential.password) {
+ if (error) {
+ *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSecureDecodeFailed userInfo:@{NSLocalizedDescriptionKey : @"failed to get password for SFCredential"}];
+ }
+ return nil;
+ }
+ }
+
+ return credential;
+}
+
+- (SFPasswordCredential*)passwordCredentialForItemMetadata:(SecCDKeychainItemMetadata*)metadata error:(NSError**)error
+{
+ NSDictionary* attributes = metadata.attributes;
+ NSString* username = attributes[SFCredentialAttributeUsername];
+
+ NSError* localError = nil;
+ SFServiceIdentifier* primaryServiceIdentifier = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFServiceIdentifier class] fromData:attributes[SFCredentialAttributePrimaryServiceIdentifier] error:&localError];
+
+ NSArray* serializedSupplementaryServiceIdentifiers = attributes[SFCredentialAttributeSupplementaryServiceIdentifiers];
+ NSMutableArray* supplementaryServiceIdentifiers = [[NSMutableArray alloc] initWithCapacity:serializedSupplementaryServiceIdentifiers.count];
+ for (NSData* serializedServiceIdentifier in serializedSupplementaryServiceIdentifiers) {
+ if ([serializedServiceIdentifier isKindOfClass:[NSData class]]) {
+ SFServiceIdentifier* serviceIdentifier = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFServiceIdentifier class] fromData:serializedServiceIdentifier error:&localError];
+ if (serviceIdentifier) {
+ [supplementaryServiceIdentifiers addObject:serviceIdentifier];
+ }
+ else {
+ supplementaryServiceIdentifiers = nil;
+ break;
+ }
+ }
+ else {
+ supplementaryServiceIdentifiers = nil;
+ localError = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSecureDecodeFailed userInfo:@{NSLocalizedDescriptionKey : @"malformed supplementary service identifiers array in SecCDKeychainItem"}];
+ break;
+ }
+ }
+
+ if (username && primaryServiceIdentifier && supplementaryServiceIdentifiers) {
+ SFPasswordCredential* credential = [[SFPasswordCredential alloc] _initWithUsername:username primaryServiceIdentifier:primaryServiceIdentifier supplementaryServiceIdentifiers:supplementaryServiceIdentifiers];
+ credential.creationDate = attributes[SFCredentialAttributeCreationDate];
+ credential.modificationDate = attributes[SFCredentialAttributeModificationDate];
+ credential.localizedLabel = attributes[SFKeychainItemAttributeLocalizedLabel];
+ credential.localizedDescription = attributes[SFKeychainItemAttributeLocalizedDescription];
+ credential.persistentIdentifier = metadata.persistentID.UUIDString;
+ credential.customAttributes = attributes[SFCredentialAttributeCustom];
+ return credential;
+ }
+ else {
+ if (error) {
+ *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorSecureDecodeFailed userInfo:@{ NSLocalizedDescriptionKey : @"failed to deserialize SFCredential", NSUnderlyingErrorKey : localError }];
+ }
+ return nil;
+ }
+}
+
+@end
+
+#endif // ___OBJC2__
+
+void SFKeychainServerInitialize(void)
+{
+ static dispatch_once_t once;
+ static SFKeychainServer* server;
+ static NSXPCListener* listener;
+
+ dispatch_once(&once, ^{
+ @autoreleasepool {
+ NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain");
+ NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"];
+ NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"];
+ server = [[SFKeychainServer alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:true];
+ listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSFKeychainServerServiceName)];
+ listener.delegate = server;
+ [listener resume];
+ }
+ });
+}
+
+#else // !TARGET_OS_BRIDGE
+
+void SFKeychainServerInitialize(void) {}
+
+#endif
+
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);
+bool SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error);
bool SOSCCCanAuthenticate_Server(CFErrorRef *error);
bool SOSCCPurgeUserCredentials_Server(CFErrorRef *error);
SOSCCStatus SOSCCThisDeviceIsInCircle_Server(CFErrorRef *error);
bool SOSCCRequestToJoinCircle_Server(CFErrorRef* error);
+bool SOSCCRequestToJoinCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error);
bool SOSCCRequestToJoinCircleAfterRestore_Server(CFErrorRef* error);
-CFStringRef SOSCCCopyDeviceID_Server(CFErrorRef *error);
-bool SOSCCSetDeviceID_Server(CFStringRef IDS, CFErrorRef *error);
-HandleIDSMessageReason SOSCCHandleIDSMessage_Server(CFDictionaryRef messageDict, CFErrorRef* error);
-bool SOSCCRequestSyncWithPeerOverKVS_Server(CFStringRef peerID, CFDataRef message, CFErrorRef *error);
-bool SOSCCClearPeerMessageKeyInKVS_Server(CFStringRef peerID, CFErrorRef *error);
-
-bool SOSCCIDSServiceRegistrationTest_Server(CFStringRef message, CFErrorRef *error);
-bool SOSCCIDSPingTest_Server(CFStringRef message, CFErrorRef *error);
-bool SOSCCIDSDeviceIDIsAvailableTest_Server(CFErrorRef *error);
+bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error);
bool SOSCCRemoveThisDeviceFromCircle_Server(CFErrorRef* error);
+bool SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error);
bool SOSCCRemovePeersFromCircle_Server(CFArrayRef peers, CFErrorRef* error);
+bool SOSCCRemovePeersFromCircleWithAnalytics_Server(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error);
bool SOSCCLoggedOutOfAccount_Server(CFErrorRef *error);
bool SOSCCBailFromCircle_Server(uint64_t limit_in_seconds, CFErrorRef* error);
bool SOSCCRequestEnsureFreshParameters_Server(CFErrorRef* error);
CFArrayRef SOSCCCopyPeerPeerInfo_Server(CFErrorRef* error);
CFArrayRef SOSCCCopyConcurringPeerPeerInfo_Server(CFErrorRef* error);
-bool SOSCCCheckPeerAvailability_Server(CFErrorRef *error);
bool SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(CFErrorRef *error);
bool SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(CFErrorRef *error);
bool SOSCCAccountSetToNew_Server(CFErrorRef *error);
bool SOSCCResetToOffering_Server(CFErrorRef* error);
bool SOSCCResetToEmpty_Server(CFErrorRef* error);
+bool SOSCCResetToEmptyWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error);
CFBooleanRef SOSCCPeersHaveViewsEnabled_Server(CFArrayRef viewNames, CFErrorRef *error);
SOSViewResultCode SOSCCView_Server(CFStringRef view, SOSViewActionCode action, CFErrorRef *error);
+bool SOSCCViewSetWithAnalytics_Server(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent);
bool SOSCCViewSet_Server(CFSetRef enabledView, CFSetRef disabledViews);
-SOSSecurityPropertyResultCode SOSCCSecurityProperty_Server(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error);
-
CFStringRef SOSCCCopyIncompatibilityInfo_Server(CFErrorRef* error);
enum DepartureReason SOSCCGetLastDepartureReason_Server(CFErrorRef* error);
bool SOSCCSetLastDepartureReason_Server(enum DepartureReason reason, CFErrorRef *error);
CF_RETURNS_RETAINED CFSetRef SOSCCProcessSyncWithPeers_Server(CFSetRef peers, CFSetRef backupPeers, CFErrorRef *error);
SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers_Server(CFErrorRef* error);
-bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server(CFStringRef deviceID, CFErrorRef *error);
SOSPeerInfoRef SOSCCSetNewPublicBackupKey_Server(CFDataRef newPublicBackup, CFErrorRef *error);
bool SOSCCRegisterSingleRecoverySecret_Server(CFDataRef backupSlice, bool setupV0Only, CFErrorRef *error);
bool SOSCCWaitForInitialSync_Server(CFErrorRef*);
+bool SOSCCWaitForInitialSyncWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error);
CFArrayRef SOSCCCopyYetToSyncViewsList_Server(CFErrorRef*);
bool SOSWrapToBackupSliceKeyBagForView_Server(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error);
void SOSCCRequestSyncWithPeers(CFSetRef /*SOSPeerInfoRef/CFStringRef*/ peerIDs);
void SOSCCRequestSyncWithPeersList(CFArrayRef /*CFStringRef*/ peerIDs);
void SOSCCRequestSyncWithBackupPeer(CFStringRef backupPeerId);
-
bool SOSCCIsSyncPendingFor(CFStringRef peerID, CFErrorRef *error);
void SOSCCEnsurePeerRegistration(void);
//
// MARK: Internal SPIs for testing
//
-CFStringRef CopyOSVersion(void);
+
+void SOSCCSetGestalt_Server(CFStringRef name, CFStringRef version, CFStringRef model, CFStringRef serial);
+CFStringRef SOSCCCopyOSVersion(void);
CFDataRef SOSCCCopyAccountState_Server(CFErrorRef* error);
CFDataRef SOSCCCopyEngineData_Server(CFErrorRef* error);
bool SOSCCDeleteEngineState_Server(CFErrorRef* error);
#include <AssertMacros.h>
-#include <CoreFoundation/CFURL.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFPriv.h>
#include <Security/SecureObjectSync/SOSAccountTransaction.h>
#include <Security/SecureObjectSync/SOSAccount.h>
#include <Security/SecureObjectSync/SOSAccountPriv.h>
#include <Security/SecureObjectSync/SOSTransport.h>
-#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
#include <Security/SecureObjectSync/SOSFullPeerInfo.h>
#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
+#include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
#include <Security/SecureObjectSync/SOSPeerInfoInternal.h>
#include <Security/SecureObjectSync/SOSInternal.h>
#include <Security/SecureObjectSync/SOSUserKeygen.h>
#import <Security/SecureObjectSync/SOSAccountTrustClassic.h>
#import <Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h>
#import <Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h>
+#import <Security/SecureObjectSync/SOSAuthKitHelpers.h>
+
#include <utilities/SecADWrapper.h>
#include <utilities/SecCFWrappers.h>
CFStringRef const SOSAggdSyncCompletionKey = CFSTR("com.apple.security.sos.synccompletion");
CFStringRef const SOSAggdSyncTimeoutKey = CFSTR("com.apple.security.sos.timeout");
-typedef SOSDataSourceFactoryRef (^SOSCCAccountDataSourceFactoryBlock)();
+typedef SOSDataSourceFactoryRef (^SOSCCAccountDataSourceFactoryBlock)(void);
static SOSCCAccountDataSourceFactoryBlock accountDataSourceOverride = NULL;
// Mark: Gestalt Handling
//
-CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
-CF_EXPORT CFStringRef _kCFSystemVersionBuildVersionKey;
+CFStringRef SOSGestaltVersion = NULL;
+CFStringRef SOSGestaltModel = NULL;
+CFStringRef SOSGestaltDeviceName = NULL;
-CFStringRef CopyOSVersion(void)
+void
+SOSCCSetGestalt_Server(CFStringRef deviceName,
+ CFStringRef version,
+ CFStringRef model,
+ CFStringRef serial)
+{
+ SOSGestaltDeviceName = CFRetainSafe(deviceName);
+ SOSGestaltVersion = CFRetainSafe(version);
+ SOSGestaltModel = CFRetainSafe(model);
+ SOSGestaltSerial = CFRetainSafe(serial);
+}
+
+CFStringRef SOSCCCopyOSVersion(void)
{
static dispatch_once_t once;
- static CFStringRef osVersion = NULL;
dispatch_once(&once, ^{
-#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
- osVersion = MGCopyAnswer(kMGQBuildVersion, NULL);
-#else
- CFDictionaryRef versions = _CFCopySystemVersionDictionary();
-
- if (versions) {
- CFTypeRef versionValue = CFDictionaryGetValue(versions, _kCFSystemVersionBuildVersionKey);
+ if (SOSGestaltVersion == NULL) {
+ CFDictionaryRef versions = _CFCopySystemVersionDictionary();
+ if (versions) {
+ CFTypeRef versionValue = CFDictionaryGetValue(versions, _kCFSystemVersionBuildVersionKey);
+ if (isString(versionValue))
+ SOSGestaltVersion = CFRetainSafe((CFStringRef) versionValue);
+ }
- if (isString(versionValue))
- osVersion = CFRetainSafe((CFStringRef) versionValue);
+ CFReleaseNull(versions);
+ if (SOSGestaltVersion == NULL) {
+ SOSGestaltVersion = CFSTR("Unknown model");
+ }
}
-
- CFReleaseNull(versions);
-#endif
- // What to do on MacOS.
- if (osVersion == NULL)
- osVersion = CFSTR("Unknown model");
});
- return CFRetainSafe(osVersion);
+ return CFRetainSafe(SOSGestaltVersion);
}
static CFStringRef CopyModelName(void)
{
static dispatch_once_t once;
- static CFStringRef modelName = NULL;
dispatch_once(&once, ^{
+ if (SOSGestaltModel == NULL) {
#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
- modelName = MGCopyAnswer(kMGQDeviceName, NULL);
+ SOSGestaltModel = MGCopyAnswer(kMGQDeviceName, NULL);
#else
- modelName = ASI_CopyComputerModelName(FALSE);
+ SOSGestaltModel = ASI_CopyComputerModelName(FALSE);
#endif
- if (modelName == NULL)
- modelName = CFSTR("Unknown model");
+ if (SOSGestaltModel == NULL)
+ SOSGestaltModel = CFSTR("Unknown model");
+ }
});
- return CFStringCreateCopy(kCFAllocatorDefault, modelName);
+ return CFStringCreateCopy(kCFAllocatorDefault, SOSGestaltModel);
}
static CFStringRef CopyComputerName(SCDynamicStoreRef store)
{
- CFStringRef deviceName = SCDynamicStoreCopyComputerName(store, NULL);
- if (deviceName == NULL) {
- deviceName = CFSTR("Unknown name");
+ if (SOSGestaltDeviceName == NULL) {
+ CFStringRef deviceName = SCDynamicStoreCopyComputerName(store, NULL);
+ if (deviceName == NULL) {
+ deviceName = CFSTR("Unknown name");
+ }
+ return deviceName;
}
- return deviceName;
+ return SOSGestaltDeviceName;
}
static bool _EngineMessageProtocolV2Enabled(void)
{
CFStringRef modelName = CopyModelName();
CFStringRef computerName = CopyComputerName(store);
- CFStringRef osVersion = CopyOSVersion();
+ CFStringRef osVersion = SOSCCCopyOSVersion();
SInt32 version = _EngineMessageProtocolV2Enabled() ? kEngineMessageProtocolVersion : 0;
CFNumberRef protocolVersion = CFNumberCreate(0, kCFNumberSInt32Type, &version);
if(txn.account){
CFDictionaryRef gestalt = CreateDeviceGestaltDictionary(store, keys, context);
if ([txn.account.trust updateGestalt:txn.account newGestalt:gestalt]) {
- // we used to notify_post(kSOSCCCircleChangedNotification);
secnotice("circleOps", "Changed our peer's gestalt information. This is not a circle change.");
}
CFReleaseSafe(gestalt);
sSharedAccount = SOSKeychainAccountCreateSharedAccount(gestalt);
- SOSAccountAddChangeBlock(sSharedAccount, ^(SOSCircleRef circle,
+ SOSAccountAddChangeBlock(sSharedAccount, ^(SOSAccount *account, SOSCircleRef circle,
CFSetRef peer_additions, CFSetRef peer_removals,
CFSetRef applicant_additions, CFSetRef applicant_removals) {
CFErrorRef pi_error = NULL;
- SOSPeerInfoRef me = sSharedAccount.peerInfo;
+ SOSPeerInfoRef me = account.peerInfo;
if(!me) {
secinfo("circleOps", "Change block called with no peerInfo");
return;
CFSetForEach(peer_removals, ^(const void *value) {
CFArrayAppendValue(removed, value);
});
- SOSAccountRemoveBackupPeers(sSharedAccount, removed, &localError);
+ SOSAccountRemoveBackupPeers(account, removed, &localError);
if(localError)
secerror("Had trouble removing: %@, error: %@", removed, localError);
CFReleaseNull(localError);
CFReleaseNull(removed);
}
secnotice("circleOps", "peer counts changed, posting kSOSCCCircleChangedNotification");
- notify_post(kSOSCCCircleChangedNotification);
+ account.notifyCircleChangeOnExit = true;
}
});
secerror("error getting circle status on first unlock: %@", cferror);
} else if (status == kSOSCCInCircle) {
secnotice("secdNotify", "Notified clients of kSOSCCCircleChangedNotification && kSOSCCViewMembershipChangedNotification for in-circle initial unlock");
- notify_post(kSOSCCCircleChangedNotification);
- notify_post(kSOSCCViewMembershipChangedNotification);
+ txn.account.notifyCircleChangeOnExit = true;
+ txn.account.notifyViewChangeOnExit = true;
}
CFReleaseNull(cferror);
});
result = SecAKSDoWhileUserBagLocked(&localError, ^{
do_with_account(^(SOSAccountTransaction* txn) {
+ SOSAccount *account = txn.account;
+ if(![SOSAuthKitHelpers peerinfoHasMID: account]) {
+ // This is the first good opportunity to update our FullPeerInfo and
+ // push the resulting circle.
+ [SOSAuthKitHelpers updateMIDInPeerInfo: account];
+ }
attempted_action = true;
action_result = action(txn, error);
});
CFReleaseNull(localError);
CFReleaseNull(statusError);
- return result;
+ return (result && action_result);
}
if(attempted_action){
if (error && !*error && localError) {
return status;
}
-
-bool SOSCCViewSet_Server(CFSetRef enabledViews, CFSetRef disabledViews) {
+bool SOSCCViewSetWithAnalytics_Server(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent) {
__block bool status = false;
-
+
do_with_account_if_after_first_unlock(NULL, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
- status = [txn.account.trust updateViewSets:txn.account enabled:enabledViews disabled:disabledViews];
+ status = [txn.account.trust updateViewSetsWithAnalytics:txn.account enabled:enabledViews disabled:disabledViews parentEvent:(__bridge NSData*)parentEvent];
return true;
});
return status;
}
-SOSSecurityPropertyResultCode SOSCCSecurityProperty_Server(CFStringRef property, SOSSecurityPropertyActionCode action, CFErrorRef *error) {
+bool SOSCCViewSet_Server(CFSetRef enabledViews, CFSetRef disabledViews) {
+ __block bool status = false;
- __block SOSViewResultCode status = kSOSCCGeneralSecurityPropertyError;
- do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
- switch(action) {
- case kSOSCCSecurityPropertyQuery:
- status = [txn.account.trust SecurityPropertyStatus:property err:error];
- break;
- case kSOSCCSecurityPropertyEnable:
- case kSOSCCSecurityPropertyDisable: // fallthrough
- status = [txn.account.trust UpdateSecurityProperty:txn.account property:property code:action err:error];
- break;
- default:
- secnotice("secprop", "Bad SOSSecurityPropertyActionCode - %d", (int) action);
- return false;
- break;
- }
+ do_with_account_if_after_first_unlock(NULL, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ status = [txn.account.trust updateViewSets:txn.account enabled:enabledViews disabled:disabledViews];
return true;
});
return status;
}
+
void sync_the_last_data_to_kvs(CFTypeRef account, bool waitForeverForSynchronization){
dispatch_semaphore_t wait_for = dispatch_semaphore_create(0);
return result;
}
+static bool SOSCCAssertUserCredentialsAndOptionalDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, NSData* parentEvent, CFErrorRef *error) {
+ secnotice("updates", "Setting credentials and dsid (%@) for %@", dsid, user_label);
+
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError];
+
+ SFSignInAnalytics *syncAndWaitEvent = nil;
+ SFSignInAnalytics *flushEvent = nil;
+ SFSignInAnalytics *secondFlushEvent = nil;
+ SFSignInAnalytics *generationSignatureUpdateEvent = nil;
+
+ bool result = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ if (dsid != NULL && CFStringCompare(dsid, CFSTR(""), 0) != 0) {
+ SOSAccountAssertDSID(txn.account, dsid);
+ }
+ return true;
+ });
+
+ require_quiet(result, done);
+ syncAndWaitEvent = [parent newSubTaskForEvent:@"syncAndWaitEvent"];
+ require_quiet(SyncKVSAndWait(error), done); // Make sure we've seen what the server has
+ [syncAndWaitEvent stopWithAttributes:nil];
+
+ flushEvent = [parent newSubTaskForEvent:@"flushEvent"];
+ require_quiet(Flush(error), done); // And processed it already...before asserting
+ [flushEvent stopWithAttributes:nil];
+
+ result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *block_error) {
+ return SOSAccountAssertUserCredentials(txn.account, user_label, user_password, block_error);
+ });
+
+ require_quiet(result, done);
+ secondFlushEvent = [parent newSubTaskForEvent:@"secondFlushEvent"];
+ require_quiet(Flush(error), done); // Process any incoming information..circles et.al. before fixing our signature
+ [secondFlushEvent stopWithAttributes:nil];
+
+ generationSignatureUpdateEvent = [parent newSubTaskForEvent:@"generationSignatureUpdateEvent"];
+ result = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ return SOSAccountGenerationSignatureUpdate(txn.account, error);
+ });
+ [generationSignatureUpdateEvent stopWithAttributes:nil];
+
+
+done:
+ if(syncAndWaitEvent){
+ [syncAndWaitEvent stopWithAttributes:nil];
+ }
+ if(flushEvent){
+ [flushEvent stopWithAttributes:nil];
+ }
+ if(secondFlushEvent){
+ [secondFlushEvent stopWithAttributes:nil];
+ }
+ if(generationSignatureUpdateEvent){
+ [generationSignatureUpdateEvent stopWithAttributes:nil];
+ }
+ return result;
+}
+
bool SOSCCSetUserCredentialsAndDSID_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
{
// TODO: Return error if DSID is NULL to insist our callers provide one?
return SOSCCAssertUserCredentialsAndOptionalDSID(user_label, user_password, dsid, error);
}
+bool SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error)
+{
+ return SOSCCAssertUserCredentialsAndOptionalDSIDWithAnalytics(user_label, user_password, dsid, (__bridge NSData*)parentEvent, error);
+}
bool SOSCCSetUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error)
{
return SOSCCAssertUserCredentialsAndOptionalDSID(user_label, user_password, NULL, error);
});
}
+bool SOSCCRequestToJoinCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error)
+{
+ __block bool result = true;
+
+ return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ result = SOSAccountJoinCirclesWithAnalytics(txn, (__bridge NSData*)parentEvent, block_error);
+ return result;
+ });
+}
+
bool SOSCCAccountHasPublicKey_Server(CFErrorRef *error)
{
__block bool result = true;
}
+bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error)
+{
+ __block bool result = true;
+ bool returned = false;
+ returned = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:(__bridge NSData*)parentEvent error:&localError];
+
+ SFSignInAnalytics *ensurePeerRegistrationEvent = [parent newSubTaskForEvent:@"ensurePeerRegistrationEvent"];
+ SOSAccountEnsurePeerRegistration(txn.account, block_error);
+ if(block_error && *block_error){
+ NSError* blockError = (__bridge NSError*)*block_error;
+ if(blockError){
+ [ensurePeerRegistrationEvent logRecoverableError:blockError];
+ secerror("ensure peer registration error: %@", blockError);
+ }
+ }
+ [ensurePeerRegistrationEvent stopWithAttributes:nil];
+ result = SOSAccountJoinCirclesAfterRestoreWithAnalytics(txn, (__bridge NSData*)parentEvent, block_error);
+ return result;
+ });
+ return returned;
+
+}
+
bool SOSCCRequestEnsureFreshParameters_Server(CFErrorRef* error)
{
bool returned = false;
return returned;
}
-CFStringRef SOSCCCopyDeviceID_Server(CFErrorRef *error)
-{
- __block CFStringRef result = NULL;
-
- (void) do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) {
- result = SOSAccountCopyDeviceID(txn.account, error);
- return (!isNull(result));
- });
- return result;
-}
-
-bool SOSCCSetDeviceID_Server(CFStringRef IDS, CFErrorRef *error){
-
- return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
- return SOSAccountSetMyDSID(txn, IDS, block_error);
- });
-}
-
-bool SOSCCRequestSyncWithPeerOverKVS_Server(CFStringRef peerid, CFDataRef message, CFErrorRef *error)
-{
- __block bool result = NULL;
-
- result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) {
- return SOSAccountSyncWithKVSPeerWithMessage(txn, peerid, message, error);
- });
- return result;
-}
-
-HandleIDSMessageReason SOSCCHandleIDSMessage_Server(CFDictionaryRef messageDict, CFErrorRef* error)
-{
- if (messageDict == NULL) {
- return kHandleIDSMessageDontHandle;
- }
-
- __block HandleIDSMessageReason result = kHandleIDSMessageSuccess;
- CFErrorRef action_error = NULL;
-
- if (!do_with_account_while_unlocked(&action_error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
- result = [txn.account.ids_message_transport SOSTransportMessageIDSHandleMessage:txn.account m:messageDict err:block_error];
- return true;
- })) {
- if (action_error) {
- if(CFErrorIsMalfunctioningKeybagError(action_error)){
- secnotice("updates", "SOSCCHandleIDSMessage_Server failed because device is locked; letting KeychainSyncingOverIDSProxy know");
- result = kHandleIDSMessageLocked; // tell KeychainSyncingOverIDSProxy to call us back when device unlock
- } else {
- secerror("Unexpected error: %@", action_error);
- }
-
- if (error && *error == NULL) {
- *error = action_error;
- action_error = NULL;
- }
- CFReleaseNull(action_error);
- }
- }
- return result;
-}
-
-bool SOSCCClearPeerMessageKeyInKVS_Server(CFStringRef peerID, CFErrorRef *error)
-{
- __block bool result = false;
-
- result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) {
- return SOSAccountClearPeerMessageKey(txn, peerID, error);
- });
-
- return result;
-}
-
-bool SOSCCIDSPingTest_Server(CFStringRef message, CFErrorRef *error){
- return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
- return SOSAccountStartPingTest(txn.account, message, block_error);
- });
-}
-
-bool SOSCCIDSServiceRegistrationTest_Server(CFStringRef message, CFErrorRef *error){
- return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
- return SOSAccountSendIDSTestMessage(txn.account, message, block_error);
- });
-}
-
-bool SOSCCIDSDeviceIDIsAvailableTest_Server(CFErrorRef *error){
- return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
- return SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(txn.account, block_error);
- });
-}
-
bool SOSCCAccountSetToNew_Server(CFErrorRef *error)
{
return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
}
+bool SOSCCResetToEmptyWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error)
+{
+ return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ if (!SOSAccountHasPublicKey(txn.account, error))
+ return false;
+ return [txn.account.trust resetAccountToEmptyWithAnalytics:txn.account transport:txn.account.circle_transport parentEvent:(__bridge NSData*)parentEvent err:block_error];
+ });
+
+}
+
+bool SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error)
+{
+ return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ return [txn.account.trust leaveCircleWithAccount:txn.account withAnalytics:(__bridge NSData*)parentEvent err:error];
+ });
+}
+
bool SOSCCRemoveThisDeviceFromCircle_Server(CFErrorRef* error)
{
return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
});
}
+bool SOSCCRemovePeersFromCircleWithAnalytics_Server(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error)
+{
+ return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ return SOSAccountRemovePeersFromCircleWithAnalytics(txn.account, peers, (__bridge NSData*)parentEvent, block_error);
+ });
+}
bool SOSCCLoggedOutOfAccount_Server(CFErrorRef *error)
{
return timeout;
}
+bool SOSCCWaitForInitialSyncWithAnalytics_Server(CFDataRef parentEvent, CFErrorRef* error) {
+ __block dispatch_semaphore_t inSyncSema = NULL;
+ __block bool result = false;
+ __block bool synced = false;
+ bool timed_out = false;
+ __block CFStringRef inSyncCallID = NULL;
+ __block time_t start;
+ __block CFBooleanRef shouldUseInitialSyncV0 = false;
+ SFSignInAnalytics* syncingEvent = nil;
+
+ NSError* localError = nil;
+ SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:(__bridge NSData*)parentEvent error:&localError];
+
+ secnotice("initial sync", "Wait for initial sync start!");
+
+ result = do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
+ shouldUseInitialSyncV0 = (CFBooleanRef)SOSAccountGetValue(txn.account, kSOSInitialSyncTimeoutV0, error);
+ bool alreadyInSync = (SOSAccountHasCompletedInitialSync(txn.account));
+
+ if (!alreadyInSync) {
+ txn.account.isInitialSyncing = true;
+ start = time(NULL);
+ inSyncSema = dispatch_semaphore_create(0);
+
+ SFSignInAnalytics* callWhenInSyncEvent = [parent newSubTaskForEvent:@"callWhenInSync"];
+ inSyncCallID = SOSAccountCallWhenInSync(txn.account, ^bool(SOSAccount* mightBeSynced) {
+ synced = true;
+
+ if(inSyncSema){
+ dispatch_semaphore_signal(inSyncSema);
+ NSDictionary* attributes = @{@"finishedSyncing" : @YES};
+ [syncingEvent stopWithAttributes:attributes];
+ }
+ return true;
+ });
+ NSDictionary* attributes = @{};
+ [callWhenInSyncEvent stopWithAttributes:attributes];
+ }
+ else{
+ synced = true;
+ }
+ return true;
+ });
+
+ require_quiet(result, fail);
+
+
+ if(inSyncSema){
+ syncingEvent = [parent newSubTaskForEvent:@"initialSyncEvent"];
+ if(shouldUseInitialSyncV0){
+ secnotice("piggy","setting initial sync timeout to 5 minutes");
+ timed_out = dispatch_semaphore_wait(inSyncSema, dispatch_time(DISPATCH_TIME_NOW, 300ull * NSEC_PER_SEC));
+ }
+ else{
+ uint64_t timeoutFromDefaultsWrite = initialSyncTimeoutFromDefaultsWrite();
+ secnotice("piggy","setting initial sync timeout to %llu seconds", timeoutFromDefaultsWrite);
+ timed_out = dispatch_semaphore_wait(inSyncSema, dispatch_time(DISPATCH_TIME_NOW, timeoutFromDefaultsWrite * NSEC_PER_SEC));
+ }
+ }
+ if (timed_out && shouldUseInitialSyncV0) {
+ do_with_account(^(SOSAccountTransaction* txn) {
+ if (SOSAccountUnregisterCallWhenInSync(txn.account, inSyncCallID)) {
+ if(inSyncSema){
+ inSyncSema = NULL; // We've canceled the timeout so we must be the last.
+ }
+ }
+ });
+ NSError* error = [NSError errorWithDomain:@"securityd" code:errSecTimedOut userInfo:@{NSLocalizedDescriptionKey: @"timed out waiting for initial sync"}];
+ [syncingEvent logUnrecoverableError:error];
+ NSDictionary* attributes = @{@"finishedSyncing" : @NO, @"legacyPiggybacking" : @YES};
+ [syncingEvent stopWithAttributes:attributes];
+ }
+
+ require_quiet(result, fail);
+
+ if(result)
+ {
+ SecADClientPushValueForDistributionKey(SOSAggdSyncCompletionKey, getTimeDifference(start));
+ }
+ else if(!result)
+ {
+ SecADAddValueForScalarKey(SOSAggdSyncTimeoutKey, 1);
+ }
+
+ (void)do_with_account(^(SOSAccountTransaction *txn) {
+ txn.account.isInitialSyncing = false;
+ });
+
+ secnotice("initial sync", "Finished!: %d", result);
+
+fail:
+ CFReleaseNull(inSyncCallID);
+ return result;
+}
+
bool SOSCCWaitForInitialSync_Server(CFErrorRef* error) {
__block dispatch_semaphore_t inSyncSema = NULL;
return result;
}
-bool SOSCCCheckPeerAvailability_Server(CFErrorRef *error)
-{
- __block bool pingedPeersInCircle = false;
- __block dispatch_semaphore_t peerSemaphore = NULL;
- __block bool peerIsAvailable = false;
-
- static dispatch_queue_t time_out;
- static dispatch_once_t once;
- dispatch_once(&once, ^{
- time_out = dispatch_queue_create("peersAvailableTimeout", DISPATCH_QUEUE_SERIAL);
- });
- __block int token = -1;
-
- bool result = do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
-
- peerSemaphore = dispatch_semaphore_create(0);
- notify_register_dispatch(kSOSCCPeerAvailable, &token, time_out, ^(int token) {
- if(peerSemaphore != NULL){
- dispatch_semaphore_signal(peerSemaphore);
- peerIsAvailable = true;
- notify_cancel(token);
- }
- });
-
- pingedPeersInCircle = SOSAccountCheckPeerAvailability(txn.account, block_error);
- return pingedPeersInCircle;
- });
-
- if (result) {
- dispatch_semaphore_wait(peerSemaphore, dispatch_time(DISPATCH_TIME_NOW, 7ull * NSEC_PER_SEC));
- }
-
- if(time_out != NULL && peerSemaphore != NULL){
- dispatch_sync(time_out, ^{
- if(!peerIsAvailable){
- peerSemaphore = NULL;
- notify_cancel(token);
- secnotice("peer available", "checking peer availability timed out, releasing semaphore");
- }
- });
- }
- if(!peerIsAvailable){
- CFStringRef errorMessage = CFSTR("There are no peers in the circle currently available");
- CFDictionaryRef userInfo = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kCFErrorLocalizedDescriptionKey, errorMessage, NULL);
- if(error != NULL){
- *error =CFErrorCreate(kCFAllocatorDefault, CFSTR("com.apple.security.ids.error"), kSecIDSErrorNoPeersAvailable, userInfo);
- secerror("%@", *error);
- }
- CFReleaseNull(userInfo);
- return false;
- }
- else
- return true;
-}
-
-
bool SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(CFErrorRef *error) {
bool result = do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) {
return SOSAccountIsLastBackupPeer(txn.account, block_error);
return result;
}
-
-
enum DepartureReason SOSCCGetLastDepartureReason_Server(CFErrorRef* error)
{
__block enum DepartureReason result = kSOSDepartureReasonError;
CFReleaseNull(peers);
}
-bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server(CFStringRef deviceID, CFErrorRef *error)
-{
- return do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) {
- return SOSAccountSyncWithKVSUsingIDSID(txn.account, deviceID, error);
- });
-}
-
void SOSCCRequestSyncWithPeers(CFSetRef /*SOSPeerInfoRef/CFStringRef*/ peerIDs) {
CFMutableArrayRef peerIDArray = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
os_activity_initiate("CloudCircle RequestSyncWithPeersList", OS_ACTIVITY_FLAG_DEFAULT, ^(void) {
CFArrayRef empty = CFArrayCreateForCFTypes(kCFAllocatorDefault, NULL);
- CFStringArrayPerfromWithDescription(peerIDs, ^(CFStringRef description) {
+ CFStringArrayPerformWithDescription(peerIDs, ^(CFStringRef description) {
secnotice("syncwith", "Request Sync With: %@", description);
});
CFArrayRef empty = CFArrayCreateForCFTypes(kCFAllocatorDefault, NULL);
CFArrayRef backupPeerList = CFArrayCreateForCFTypes(kCFAllocatorDefault, backupPeerId, NULL);
- CFStringArrayPerfromWithDescription(backupPeerList, ^(CFStringRef description) {
+ CFStringArrayPerformWithDescription(backupPeerList, ^(CFStringRef description) {
secnotice("syncwith", "Request backup sync With: %@", description);
});
#include <CoreFoundation/CFUtilities.h>
#include <utilities/SecFileLocations.h>
+#include <utilities/SecCFWrappers.h>
static const char expireSQL[] = "DELETE FROM issuers WHERE expires<?";
static const char beginTxnSQL[] = "BEGIN EXCLUSIVE TRANSACTION";
atexit(SecCAIssuerCacheGC);
}
+static CF_RETURNS_RETAINED CFDataRef convertArrayOfCertsToData(CFArrayRef certificates) {
+ if (!certificates || CFArrayGetCount(certificates) == 0) {
+ return NULL;
+ }
+
+ CFMutableDataRef output = CFDataCreateMutable(NULL, 0);
+ CFArrayForEach(certificates, ^(const void *value) {
+ CFDataRef certData = SecCertificateCopyData((SecCertificateRef)value);
+ if (certData) {
+ CFDataAppend(output, certData);
+ }
+ CFReleaseNull(certData);
+ });
+
+ return output;
+}
+
+static CF_RETURNS_RETAINED CFArrayRef convertDataToArrayOfCerts(uint8_t *data, size_t dataLen) {
+ if (!data || dataLen == 0) {
+ return NULL;
+ }
+
+ CFMutableArrayRef output = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ uint8_t *nextCertPtr = data;
+ size_t remainingDataLen = dataLen;
+ while (nextCertPtr < data + dataLen) {
+ SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, nextCertPtr, remainingDataLen);
+ if (cert) {
+ CFArrayAppendValue(output, cert);
+ nextCertPtr += SecCertificateGetLength(cert);
+ remainingDataLen -= SecCertificateGetLength(cert);
+ CFReleaseNull(cert);
+ } else {
+ /* We don't know where the next cert starts, so we should just stop */
+ break;
+ }
+ }
+
+ if (CFArrayGetCount(output) < 1) {
+ CFReleaseNull(output);
+ }
+ return output;
+}
+
/* Instance implemenation. */
-static void _SecCAIssuerCacheAddCertificate(SecCAIssuerCacheRef this,
- SecCertificateRef certificate,
+static void _SecCAIssuerCacheAddCertificates(SecCAIssuerCacheRef this,
+ CFArrayRef certificates,
CFURLRef uri, CFAbsoluteTime expires) {
int s3e;
+ CFDataRef certsData = NULL;
+ CFDataRef uriData = NULL;
secdebug("caissuercache", "adding certificate from %@", uri);
require_noerr(s3e = SecCAIssuerCacheEnsureTxn(this), errOut);
/* issuer.uri */
- CFDataRef uriData;
require_action(uriData = CFURLCreateData(kCFAllocatorDefault, uri,
kCFStringEncodingUTF8, false), errOut, s3e = SQLITE_NOMEM);
s3e = sqlite3_bind_blob_wrapper(this->insertIssuer, 1,
if (!s3e) s3e = sqlite3_bind_double(this->insertIssuer, 2, expires);
/* issuer.certificate */
- if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertIssuer, 3,
- SecCertificateGetBytePtr(certificate),
- SecCertificateGetLength(certificate), SQLITE_TRANSIENT);
+ require_action(certsData = convertArrayOfCertsToData(certificates), errOut,
+ s3e = SQLITE_NOMEM);
+ if (!s3e) {
+ s3e = sqlite3_bind_blob_wrapper(this->insertIssuer, 3,
+ CFDataGetBytePtr(certsData),
+ CFDataGetLength(certsData), SQLITE_TRANSIENT);
+ }
+ CFReleaseNull(certsData);
/* Execute the insert statement. */
if (!s3e) s3e = sqlite3_step(this->insertIssuer);
}
}
-static SecCertificateRef _SecCAIssuerCacheCopyMatching(SecCAIssuerCacheRef this,
+static CFArrayRef _SecCAIssuerCacheCopyMatching(SecCAIssuerCacheRef this,
CFURLRef uri) {
- SecCertificateRef certificate = NULL;
+ CFArrayRef certificates = NULL;
int s3e = SQLITE_OK;
CFDataRef uriData = NULL;
const void *respData = sqlite3_column_blob(this->selectIssuer, 0);
int respLen = sqlite3_column_bytes(this->selectIssuer, 0);
- certificate = SecCertificateCreateWithBytes(NULL, respData, respLen);
+ certificates = convertDataToArrayOfCerts((uint8_t *)respData, respLen);
}
require_noerr(s3e = sec_sqlite3_reset(this->selectIssuer, s3e), errOut);
/* TODO: Blow away the cache and create a new db. */
}
- if (certificate) {
- CFRelease(certificate);
- certificate = NULL;
+ if (certificates) {
+ CFRelease(certificates);
+ certificates = NULL;
}
}
- secdebug("caissuercache", "returning %s for %@", (certificate ? "cached response" : "NULL"), uri);
-
- return certificate;
+ secdebug("caissuercache", "returning %s for %@", (certificates ? "cached response" : "NULL"), uri);
+ return certificates;
}
static void _SecCAIssuerCacheGC(void *context) {
/* Public API */
-void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate,
+void SecCAIssuerCacheAddCertificates(CFArrayRef certificates,
CFURLRef uri, CFAbsoluteTime expires) {
dispatch_once(&kSecCAIssuerCacheOnce, ^{
SecCAIssuerCacheInit();
return;
dispatch_sync(kSecCAIssuerCache->queue, ^{
- _SecCAIssuerCacheAddCertificate(kSecCAIssuerCache, certificate, uri, expires);
+ _SecCAIssuerCacheAddCertificates(kSecCAIssuerCache, certificates, uri, expires);
+ _SecCAIssuerCacheFlush(kSecCAIssuerCache);
});
}
-SecCertificateRef SecCAIssuerCacheCopyMatching(CFURLRef uri) {
+CFArrayRef SecCAIssuerCacheCopyMatching(CFURLRef uri) {
dispatch_once(&kSecCAIssuerCacheOnce, ^{
SecCAIssuerCacheInit();
});
- __block SecCertificateRef cert = NULL;
+ __block CFArrayRef certs = NULL;
if (kSecCAIssuerCache)
dispatch_sync(kSecCAIssuerCache->queue, ^{
- cert = _SecCAIssuerCacheCopyMatching(kSecCAIssuerCache, uri);
+ certs = _SecCAIssuerCacheCopyMatching(kSecCAIssuerCache, uri);
});
- return cert;
+ return certs;
}
/* This should be called on a normal non emergency exit. This function
_SecCAIssuerCacheGC(kSecCAIssuerCache);
});
}
-
-/* Call this periodically or perhaps when we are exiting due to low memory. */
-void SecCAIssuerCacheFlush(void) {
- if (kSecCAIssuerCache)
- dispatch_sync(kSecCAIssuerCache->queue, ^{
- _SecCAIssuerCacheFlush(kSecCAIssuerCache);
- });
-}
__BEGIN_DECLS
-void SecCAIssuerCacheAddCertificate(SecCertificateRef certificate,
+void SecCAIssuerCacheAddCertificates(CFArrayRef certificates,
CFURLRef uri, CFAbsoluteTime expires);
-SecCertificateRef SecCAIssuerCacheCopyMatching(CFURLRef uri);
+CFArrayRef SecCAIssuerCacheCopyMatching(CFURLRef uri);
/* This should be called on a normal non emergency exit. */
void SecCAIssuerCacheGC(void);
-/* Call this periodically or perhaps when we are exiting due to low memory. */
-void SecCAIssuerCacheFlush(void);
-
__END_DECLS
#endif /* _SECURITY_SECCAISSUERCACHE_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2009-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@
- */
-
-/*
- * SecCAIssuerRequest.c - asynchronous CAIssuer request fetching engine.
- */
-
-
-#include "SecCAIssuerRequest.h"
-#include "SecCAIssuerCache.h"
-
-#include <Security/SecInternal.h>
-#include <Security/SecCMS.h>
-#include <CoreFoundation/CFURL.h>
-#include <CFNetwork/CFHTTPMessage.h>
-#include <utilities/debugging.h>
-#include <Security/SecCertificateInternal.h>
-#include <securityd/asynchttp.h>
-#include <securityd/SecTrustServer.h>
-#include <stdlib.h>
-#include <mach/mach_time.h>
-
-#define MAX_CA_ISSUERS 3
-#define CA_ISSUERS_REQUEST_THRESHOLD 10
-
-
-/* CA Issuer lookup code. */
-
-typedef struct SecCAIssuerRequest *SecCAIssuerRequestRef;
-struct SecCAIssuerRequest {
- asynchttp_t http; /* Must be first field. */
- SecCertificateRef certificate;
- CFArrayRef issuers; /* NONRETAINED */
- CFIndex issuerIX;
- void *context;
- void (*callback)(void *, CFArrayRef);
-};
-
-static void SecCAIssuerRequestRelease(SecCAIssuerRequestRef request) {
- CFRelease(request->certificate);
- asynchttp_free(&request->http);
- free(request);
-}
-
-static bool SecCAIssuerRequestIssue(SecCAIssuerRequestRef request) {
- CFIndex count = CFArrayGetCount(request->issuers);
- if (count >= CA_ISSUERS_REQUEST_THRESHOLD) {
- secnotice("caissuer", "too many caIssuer entries (%ld)", (long)count);
- request->callback(request->context, NULL);
- 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++);
- CFStringRef scheme = CFURLCopyScheme(issuer);
- if (scheme) {
- if (CFEqual(CFSTR("http"), scheme)) {
- CFHTTPMessageRef msg = CFHTTPMessageCreateRequest(kCFAllocatorDefault,
- CFSTR("GET"), issuer, kCFHTTPVersion1_1);
- 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);
- return done;
- }
- }
- secdebug("caissuer", "failed to get %@", issuer);
- } else {
- secnotice("caissuer", "skipping unsupported uri %@", issuer);
- }
- CFRelease(scheme);
- }
- }
-
- /* No more issuers left to try, we're done. */
- secdebug("caissuer", "no request issued");
- request->callback(request->context, NULL);
- SecCAIssuerRequestRelease(request);
- return true;
-}
-
-/* Releases parent unconditionally, and return a CFArrayRef containing
- parent if the normalized subject of parent matches the normalized issuer
- of certificate. */
-static CF_RETURNS_RETAINED CFArrayRef SecCAIssuerConvertToParents(SecCertificateRef certificate,
- SecCertificateRef CF_CONSUMED parent) {
- CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate);
- CFArrayRef parents = NULL;
- if (parent) {
- CFDataRef parent_nic = SecCertificateGetNormalizedSubjectContent(parent);
- if (nic && parent_nic && CFEqual(nic, parent_nic)) {
- const void *ventry = parent;
- parents = CFArrayCreate(NULL, &ventry, 1, &kCFTypeArrayCallBacks);
- }
- CFRelease(parent);
- }
- return parents;
-}
-
-#define SECONDS_PER_DAY (86400.0)
-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) {
- /* RFC5280 4.2.2.1:
- "accessLocation MUST be a uniformResourceIdentifier and the URI
- MUST point to either a single DER encoded certificate as speci-
- fied in [RFC2585] or a collection of certificates in a BER or
- DER encoded "certs-only" CMS message as specified in [RFC2797]." */
-
- /* DER-encoded certificate */
- SecCertificateRef parent = SecCertificateCreateWithData(NULL, data);
-
- /* "certs-only" CMS Message */
- if (!parent) {
- CFArrayRef certificates = NULL;
- certificates = SecCMSCertificatesOnlyMessageCopyCertificates(data);
- /* @@@ Technically these can have more than one certificate */
- 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);
- }
-
- /* Retry in case the certificate is in PEM format. Some CAs
- incorrectly return a PEM encoded cert, despite RFC 5280 4.2.2.1 */
- if (!parent) {
- parent = SecCertificateCreateWithPEM(NULL, data);
- }
- CFRelease(data);
- if (parent) {
- /* We keep responses in the cache for at least 7 days, or longer
- if the http response tells us to keep it around for more. */
- if (maxAge < SECONDS_PER_DAY * 7)
- maxAge = SECONDS_PER_DAY * 7;
- CFAbsoluteTime expires = CFAbsoluteTimeGetCurrent() + maxAge;
- CFURLRef issuer = CFArrayGetValueAtIndex(request->issuers,
- request->issuerIX - 1);
- SecCAIssuerCacheAddCertificate(parent, issuer, expires);
- CFArrayRef parents = SecCAIssuerConvertToParents(
- request->certificate, parent); /* note: this releases parent */
- if (parents) {
- secdebug("caissuer", "response: %@ good", http->response);
- request->callback(request->context, parents);
- CFRelease(parents);
- 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",
- http->response);
- /* We're re-using this http object, so we need to free all the old memory. */
- asynchttp_free(&request->http);
- SecCAIssuerRequestIssue(request);
-}
-
-static CFArrayRef SecCAIssuerRequestCacheCopyParents(SecCertificateRef cert,
- CFArrayRef issuers) {
- CFIndex ix = 0, ex = CFArrayGetCount(issuers);
- for (;ix < ex; ++ix) {
- CFURLRef issuer = CFArrayGetValueAtIndex(issuers, ix);
- CFStringRef scheme = CFURLCopyScheme(issuer);
- if (scheme) {
- if (CFEqual(CFSTR("http"), scheme)) {
- CFArrayRef parents = SecCAIssuerConvertToParents(cert,
- SecCAIssuerCacheCopyMatching(issuer));
- if (parents) {
- secdebug("caissuer", "cache hit, for %@ no request issued", issuer);
- CFRelease(scheme);
- return parents;
- }
- }
- CFRelease(scheme);
- }
- }
- return NULL;
-}
-
-bool SecCAIssuerCopyParents(SecCertificateRef certificate, dispatch_queue_t queue,
- void *context, void (*callback)(void *, CFArrayRef)) {
- CFArrayRef issuers = SecCertificateGetCAIssuers(certificate);
- if (!issuers) {
- /* certificate has no caissuer urls, we're done. */
- callback(context, NULL);
- 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 =
- (SecCAIssuerRequestRef)calloc(1, sizeof(*request));
- request->http.queue = queue;
- request->http.completed = SecCAIssuerRequestCompleted;
- CFRetain(certificate);
- request->certificate = certificate;
- request->issuers = issuers;
- request->issuerIX = 0;
- request->context = context;
- request->callback = callback;
-
- return SecCAIssuerRequestIssue(request);
-}
-
#include <CoreFoundation/CFArray.h>
#include <dispatch/dispatch.h>
-bool SecCAIssuerCopyParents(SecCertificateRef certificate,
- dispatch_queue_t queue, void *context, void (*callback)(void *, CFArrayRef));
+bool SecCAIssuerCopyParents(SecCertificateRef certificate, void *context, void (*callback)(void *, CFArrayRef));
--- /dev/null
+/*
+ * Copyright (c) 2009-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@
+ */
+
+/*
+ * SecCAIssuerRequest.m - asynchronous CAIssuer request fetching engine.
+ */
+
+
+#include "SecCAIssuerRequest.h"
+#include "SecCAIssuerCache.h"
+
+#import <Foundation/Foundation.h>
+#import <CFNetwork/CFNSURLConnection.h>
+#include <Security/SecInternal.h>
+#include <Security/SecCMS.h>
+#include <CoreFoundation/CFURL.h>
+#include <CFNetwork/CFHTTPMessage.h>
+#include <utilities/debugging.h>
+#include <Security/SecCertificateInternal.h>
+#include <securityd/SecTrustServer.h>
+#include <securityd/TrustURLSessionDelegate.h>
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+#define MAX_CA_ISSUERS 3
+#define CA_ISSUERS_REQUEST_THRESHOLD 10
+
+typedef void (*CompletionHandler)(void *context, CFArrayRef parents);
+
+/* CA Issuer lookup code. */
+@interface CAIssuerDelegate: TrustURLSessionDelegate
+@property (assign) CompletionHandler callback;
+@end
+
+static NSArray *certificatesFromData(NSData *data) {
+ /* RFC5280 4.2.2.1:
+ "accessLocation MUST be a uniformResourceIdentifier and the URI
+ MUST point to either a single DER encoded certificate as speci-
+ fied in [RFC2585] or a collection of certificates in a BER or
+ DER encoded "certs-only" CMS message as specified in [RFC2797]." */
+
+ /* DER-encoded certificate */
+ SecCertificateRef parent = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data);
+ if (parent) {
+ NSArray *result = @[(__bridge id)parent];
+ CFReleaseNull(parent);
+ return result;
+ }
+
+ /* "certs-only" CMS Message */
+ CFArrayRef certificates = SecCMSCertificatesOnlyMessageCopyCertificates((__bridge CFDataRef)data);
+ if (certificates) {
+ return CFBridgingRelease(certificates);
+ }
+
+ /* Retry in case the certificate is in PEM format. Some CAs
+ incorrectly return a PEM encoded cert, despite RFC 5280 4.2.2.1 */
+ parent = SecCertificateCreateWithPEM(NULL, (__bridge CFDataRef)data);
+ if (parent) {
+ NSArray *result = @[(__bridge id)parent];
+ CFReleaseNull(parent);
+ return result;
+ }
+ return nil;
+}
+
+@implementation CAIssuerDelegate
+- (BOOL)fetchNext:(NSURLSession *)session {
+ SecPathBuilderRef builder = (SecPathBuilderRef)self.context;
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder);
+
+ BOOL result = false;
+ if (!(result = [super fetchNext:session]) && analytics) {
+ analytics->ca_issuer_fetches++;
+ }
+ return result;
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
+ /* call the superclass's method to set taskTime and expiration */
+ [super URLSession:session task:task didCompleteWithError:error];
+
+ __block SecPathBuilderRef builder =(SecPathBuilderRef)self.context;
+ if (!builder) {
+ /* We already returned to the PathBuilder state machine. */
+ return;
+ }
+
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder);
+ __block NSArray *parents = nil;
+ if (error) {
+ /* Log the error */
+ secnotice("caissuer", "Failed to download issuer %@, with error %@", task.originalRequest.URL, error);
+ if (analytics) {
+ analytics->ca_issuer_fetch_failed++;
+ }
+ } else if (self.response) {
+ /* Get the parent cert from the data */
+ parents = certificatesFromData(self.response);
+ if (analytics && !parents) {
+ analytics->ca_issuer_unsupported_data = true;
+ } else if (analytics && [parents count] > 1) {
+ analytics->ca_issuer_multiple_certs = true;
+ }
+ }
+
+ if (parents) {
+ /* Found some parents, add to cache, close session, and return to SecPathBuilder */
+ secdebug("caissuer", "found parents for %@", task.originalRequest.URL);
+ SecCAIssuerCacheAddCertificates((__bridge CFArrayRef)parents, (__bridge CFURLRef)task.originalRequest.URL, self.expiration);
+ self.context = nil; // set the context to NULL before we call back because the callback may free the builder
+ [session invalidateAndCancel];
+ dispatch_async(SecPathBuilderGetQueue(builder), ^{
+ self.callback(builder, (__bridge CFArrayRef)parents);
+ });
+ } else {
+ secdebug("caissuer", "no parents for %@", task.originalRequest.URL);
+ if ([self fetchNext:session]) { // Try the next CAIssuer URI
+ /* no fetch scheduled, close this session and jump back into the state machine on the builder's queue */
+ secdebug("caissuer", "no more fetches. returning to builder");
+ self.context = nil; // set the context to NULL before we call back because the callback may free the builder
+ [session invalidateAndCancel];
+ dispatch_async(SecPathBuilderGetQueue(builder), ^{
+ self.callback(builder, NULL);
+ });
+ }
+ }
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)taskMetrics {
+ secdebug("caissuer", "got metrics with task interval %f", taskMetrics.taskInterval.duration);
+ SecPathBuilderRef builder =(SecPathBuilderRef)self.context;
+ if (builder) {
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder);
+ if (analytics) {
+ analytics->ca_issuer_fetch_time += (uint64_t)(taskMetrics.taskInterval.duration * NSEC_PER_SEC);
+ }
+ }
+}
+@end
+
+/* Releases parent unconditionally, and return a CFArrayRef containing
+ parent if the normalized subject of parent matches the normalized issuer
+ of certificate. */
+static CF_RETURNS_RETAINED CFArrayRef SecCAIssuerConvertToParents(SecCertificateRef certificate, CFArrayRef CF_CONSUMED putativeParents) {
+ CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate);
+ NSMutableArray *parents = [NSMutableArray array];
+ NSArray *possibleParents = CFBridgingRelease(putativeParents);
+ for (id parent in possibleParents) {
+ CFDataRef parent_nic = SecCertificateGetNormalizedSubjectContent((__bridge SecCertificateRef)parent);
+ if (nic && parent_nic && CFEqual(nic, parent_nic)) {
+ [parents addObject:parent];
+ }
+ }
+
+ if ([parents count] > 0) {
+ return CFBridgingRetain(parents);
+ } else {
+ return nil;
+ }
+}
+
+static CFArrayRef SecCAIssuerRequestCacheCopyParents(SecCertificateRef cert,
+ CFArrayRef issuers) {
+ CFIndex ix = 0, ex = CFArrayGetCount(issuers);
+ for (;ix < ex; ++ix) {
+ CFURLRef issuer = CFArrayGetValueAtIndex(issuers, ix);
+ CFStringRef scheme = CFURLCopyScheme(issuer);
+ if (scheme) {
+ if (CFEqual(CFSTR("http"), scheme)) {
+ CFArrayRef parents = SecCAIssuerConvertToParents(cert,
+ SecCAIssuerCacheCopyMatching(issuer));
+ if (parents) {
+ secdebug("caissuer", "cache hit, for %@. no request issued", issuer);
+ CFRelease(scheme);
+ return parents;
+ }
+ }
+ CFRelease(scheme);
+ }
+ }
+ return NULL;
+}
+
+bool SecCAIssuerCopyParents(SecCertificateRef certificate, void *context, void (*callback)(void *, CFArrayRef)) {
+ @autoreleasepool {
+ CFArrayRef issuers = CFRetainSafe(SecCertificateGetCAIssuers(certificate));
+ NSArray *nsIssuers = CFBridgingRelease(issuers);
+ if (!issuers) {
+ /* certificate has no caissuer urls, we're done. */
+ callback(context, NULL);
+ return true;
+ }
+
+ SecPathBuilderRef builder = (SecPathBuilderRef)context;
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder);
+ CFArrayRef parents = SecCAIssuerRequestCacheCopyParents(certificate, (__bridge CFArrayRef)nsIssuers);
+ 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;
+ }
+
+ NSInteger count = [nsIssuers count];
+ if (count >= CA_ISSUERS_REQUEST_THRESHOLD) {
+ secnotice("caissuer", "too many caIssuer entries (%ld)", (long)count);
+ callback(context, NULL);
+ return true;
+ }
+
+ NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
+ config.timeoutIntervalForResource = TrustURLSessionGetResourceTimeout();
+ config.HTTPAdditionalHeaders = @{@"User-Agent" : @"com.apple.trustd/2.0"};
+
+ NSData *auditToken = CFBridgingRelease(SecPathBuilderCopyClientAuditToken(builder));
+ if (auditToken) {
+ config._sourceApplicationAuditTokenData = auditToken;
+ }
+
+ CAIssuerDelegate *delegate = [[CAIssuerDelegate alloc] init];
+ delegate.context = context;
+ delegate.callback = callback;
+ delegate.URIs = nsIssuers;
+ delegate.URIix = 0;
+
+ NSOperationQueue *queue = [[NSOperationQueue alloc] init];
+
+ NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:queue];
+ secdebug("caissuer", "created URLSession for %@", certificate);
+
+ bool result = false;
+ if ((result = [delegate fetchNext:session])) {
+ /* no fetch scheduled, close the session */
+ [session invalidateAndCancel];
+ }
+ return result;
+ }
+}
+
bool pathValidated;
+ /* If checkedIssuers is true, then the value of unknownCAIndex contains
+ * the index of the first CA which violates known-only constraints, or
+ * -1 if all CA certificates are either known or not constrained. */
+ bool checkedIssuers;
+ CFIndex unknownCAIndex;
+
/* 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;
+ /* Issuance time, as determined by earliest SCT timestamp for leaf. */
+ CFAbsoluteTime issuanceTime;
+
SecCertificateVCRef certificates[];
};
CFGiblisWithHashFor(SecCertificatePathVC)
}
}
-static void SecCertificatePathVCDeleteRVCs(SecCertificatePathVCRef path) {
+void SecCertificatePathVCDeleteRVCs(SecCertificatePathVCRef path) {
if (path->rvcs) {
CFIndex certIX, certCount = path->rvcCount;
for (certIX = 0; certIX < certCount; ++certIX) {
SecCertificatePathVCRef certificatePath, CFIndex ix) {
SecCertificateRef certificate =
SecCertificatePathVCGetCertificateAtIndex(certificatePath, ix);
-#if TARGET_OS_OSX
- return SecCertificateCopyPublicKey_ios(certificate);
-#else
- return SecCertificateCopyPublicKey(certificate);
-#endif
+ return SecCertificateCopyKey(certificate);
}
CFArrayRef SecCertificatePathVCGetUsageConstraintsAtIndex(
cvc->require_revocation_response = true;
}
+bool SecCertificatePathVCCheckedIssuers(SecCertificatePathVCRef certificatePath) {
+ return certificatePath->checkedIssuers;
+}
+
+void SecCertificatePathVCSetCheckedIssuers(SecCertificatePathVCRef certificatePath, bool checked) {
+ certificatePath->checkedIssuers = checked;
+}
+
+CFIndex SecCertificatePathVCUnknownCAIndex(SecCertificatePathVCRef certificatePath) {
+ return certificatePath->unknownCAIndex;
+}
+
+void SecCertificatePathVCSetUnknownCAIndex(SecCertificatePathVCRef certificatePath, CFIndex index) {
+ certificatePath->unknownCAIndex = index;
+}
+
bool SecCertificatePathVCIsPathValidated(SecCertificatePathVCRef certificatePath) {
if (!certificatePath) { return false; }
return certificatePath->pathValidated;
certificatePath->requiresCT = requiresCT;
}
+CFAbsoluteTime SecCertificatePathVCIssuanceTime(SecCertificatePathVCRef certificatePath) {
+ if (!certificatePath) { return 0; }
+ return certificatePath->issuanceTime;
+}
+
+void SecCertificatePathVCSetIssuanceTime(SecCertificatePathVCRef certificatePath, CFAbsoluteTime issuanceTime) {
+ certificatePath->issuanceTime = issuanceTime;
+}
+
bool SecCertificatePathVCIsAllowlisted(SecCertificatePathVCRef certificatePath) {
if (!certificatePath) { return false; }
return certificatePath->is_allowlisted;
void SecCertificatePathVCResetScore(SecCertificatePathVCRef certificatePath); // reset score to 0
/* Revocation */
+void SecCertificatePathVCDeleteRVCs(SecCertificatePathVCRef path);
bool SecCertificatePathVCIsRevocationDone(SecCertificatePathVCRef certificatePath);
void SecCertificatePathVCAllocateRVCs(SecCertificatePathVCRef certificatePath, CFIndex certCount);
CFAbsoluteTime SecCertificatePathVCGetEarliestNextUpdate(SecCertificatePathVCRef path);
void SecCertificatePathVCSetRevocationRequiredForCertificateAtIndex(SecCertificatePathVCRef certificatePath,
CFIndex ix);
+bool SecCertificatePathVCCheckedIssuers(SecCertificatePathVCRef certificatePath);
+void SecCertificatePathVCSetCheckedIssuers(SecCertificatePathVCRef certificatePath, bool checked);
+CFIndex SecCertificatePathVCUnknownCAIndex(SecCertificatePathVCRef certificatePath);
+void SecCertificatePathVCSetUnknownCAIndex(SecCertificatePathVCRef certificatePath, CFIndex index);
+
/* Did we already validate this path (setting EV, CT, RVC, etc.) */
bool SecCertificatePathVCIsPathValidated(SecCertificatePathVCRef certificatePath);
void SecCertificatePathVCSetPathValidated(SecCertificatePathVCRef certificatePath);
void SecCertificatePathVCSetIsCT(SecCertificatePathVCRef certificatePath, bool isCT);
SecPathCTPolicy SecCertificatePathVCRequiresCT(SecCertificatePathVCRef certificatePath);
void SecCertificatePathVCSetRequiresCT(SecCertificatePathVCRef certificatePath, SecPathCTPolicy requiresCT);
+CFAbsoluteTime SecCertificatePathVCIssuanceTime(SecCertificatePathVCRef certificatePath);
+void SecCertificatePathVCSetIssuanceTime(SecCertificatePathVCRef certificatePath, CFAbsoluteTime issuanceTime);
/* Allowlist */
bool SecCertificatePathVCIsAllowlisted(SecCertificatePathVCRef certificatePath);
return result;
}
-static bool SecItemCertificateSourceCopyParents(
- SecCertificateSourceRef source, SecCertificateRef certificate,
+static bool SecItemCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate,
void *context, SecCertificateSourceParents callback) {
SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source;
CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate);
/* Look up a certificate by issuer and serial number. */
CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate);
CFRetainSafe(normalizedIssuer);
- CFDataRef serialNumber =
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
- SecCertificateCopySerialNumber(certificate, NULL);
-#else
- SecCertificateCopySerialNumber(certificate);
-#endif
CFErrorRef localError = NULL;
+ CFDataRef serialNumber = SecCertificateCopySerialNumberData(certificate, &localError);
bool result = SecItemCertificateExists(normalizedIssuer, serialNumber, msource->accessGroups, &localError);
if (localError) {
if (CFErrorGetCode(localError) != errSecItemNotFound) {
*********** SecSystemAnchorSource object ************
********************************************************/
-static bool SecSystemAnchorSourceCopyParents(
- SecCertificateSourceRef source, SecCertificateRef certificate,
+static bool SecSystemAnchorSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate,
void *context, SecCertificateSourceParents callback) {
//#ifndef SECITEM_SHIM_OSX
CFArrayRef parents = NULL;
};
typedef struct SecMemoryCertificateSource *SecMemoryCertificateSourceRef;
-static bool SecMemoryCertificateSourceCopyParents(
- SecCertificateSourceRef source, SecCertificateRef certificate,
+static bool SecMemoryCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate,
void *context, SecCertificateSourceParents callback) {
SecMemoryCertificateSourceRef msource =
(SecMemoryCertificateSourceRef)source;
CFArrayAppendValue(values, value);
}
-static void SecMemoryCertificateSourceApplierFunction(const void *value,
- void *context) {
+static void SecMemoryCertificateSourceApplierFunction(const void *value, void *context) {
SecMemoryCertificateSourceRef msource =
(SecMemoryCertificateSourceRef)context;
SecCertificateRef certificate = (SecCertificateRef)value;
/********************************************************
********* SecCAIssuerCertificateSource object **********
********************************************************/
-static bool SecCAIssuerCertificateSourceCopyParents(
- SecCertificateSourceRef source, SecCertificateRef certificate,
+static bool SecCAIssuerCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate,
void *context, SecCertificateSourceParents callback) {
/* Some expired certs have dead domains. Let's not check them. */
SecPathBuilderRef builder = (SecPathBuilderRef)context;
callback(context, NULL);
return true;
}
- return SecCAIssuerCopyParents(certificate, SecPathBuilderGetQueue(builder), context, callback);
+ return SecCAIssuerCopyParents(certificate, context, callback);
}
-static bool SecCAIssuerCertificateSourceContains(
- SecCertificateSourceRef source, SecCertificateRef certificate) {
+static bool SecCAIssuerCertificateSourceContains(SecCertificateSourceRef source, SecCertificateRef certificate) {
return false;
}
********** SecLegacyCertificateSource object ***********
********************************************************/
-static bool SecLegacyCertificateSourceCopyParents(
- SecCertificateSourceRef source, SecCertificateRef certificate,
+static bool SecLegacyCertificateSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate,
void *context, SecCertificateSourceParents callback) {
CFArrayRef parents = SecItemCopyParentCertificates_osx(certificate, NULL);
callback(context, parents);
return true;
}
-static bool SecLegacyCertificateSourceContains(
- SecCertificateSourceRef source, SecCertificateRef certificate) {
+static bool SecLegacyCertificateSourceContains(SecCertificateSourceRef source, SecCertificateRef certificate) {
SecCertificateRef cert = SecItemCopyStoredCertificate(certificate, NULL);
bool result = (cert) ? true : false;
CFReleaseSafe(cert);
#include <utilities/der_plist_internal.h>
#include <utilities/SecCFCCWrappers.h>
#import "SecDbKeychainItemV7.h"
+#import "sec_action.h"
#if USE_KEYSTORE
#include <LocalAuthentication/LAPublicDefines.h>
return ok;
}
+static void
+ks_warn_non_device_keybag(void)
+{
+ static dispatch_once_t once;
+ static sec_action_t action;
+
+ dispatch_once(&once, ^{
+ action = sec_action_create("non-device keybag", 2);
+ sec_action_set_handler(action, ^{
+ secwarning("ks_encrypt_data: called with non-device keybag - call should be rerouted to ks_encrypt_data_legacy");
+ });
+ });
+ sec_action_perform(action);
+}
+
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) {
}
if (keybag != KEYBAG_DEVICE) {
- secwarning("ks_encrypt_data: called with non-device keybag - call should be rerouted to ks_encrypt_data_legacy");
+ ks_warn_non_device_keybag();
CFMutableDictionaryRef allAttributes = CFDictionaryCreateMutableCopy(NULL, CFDictionaryGetCount(secretData) + CFDictionaryGetCount(attributes), attributes);
CFDictionaryForEach(secretData, ^(const void *key, const void *value) {
- (SFAESKey*)keyForKeyclass:(keyclass_t)keyClass
keybag:(keybag_handle_t)keybag
keySpecifier:(SFAESKeySpecifier*)keySpecifier
+ createKeyIfMissing:(bool)createIfMissing
overwriteCorruptKey:(bool)overwriteCorruptKey
error:(NSError**)error;
@end
- (SFAESKey*)keyForKeyclass:(keyclass_t)keyclass
keybag:(keybag_handle_t)keybag
keySpecifier:(SFAESKeySpecifier*)keySpecifier
+ createKeyIfMissing:(bool)createIfMissing
overwriteCorruptKey:(bool)overwriteCorruptKey
error:(NSError**)error
{
// 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];
+
+ // However, we must not cache a newly-created key, just in case someone above us in the stack rolls back our database transaction and the stored key is lost.
+ __block bool keyIsNewlyCreated = false;
#if 0
// <rdar://problem/37523001> Fix keychain lock state check to be both secure and fast for EDU mode
if (![SecDbKeychainItemV7 isKeychainUnlocked]) {
if (!key) {
__block bool ok = true;
__block bool metadataKeyDoesntAuthenticate = false;
- ok &= kc_with_dbt_non_item_tables(true, &cfError, ^bool(SecDbConnectionRef dbt) {
+ ok &= kc_with_dbt_non_item_tables(createIfMissing, &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) {
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(!key) {
+ os_log_fault(secLogObjForScope("SecDbKeychainItemV7"), "Metadata class key (%d) decrypted, but didn't become a key: %@", keyclass, nsErrorLocal);
+ }
if (actualKeyclass == 0) {
actualKeyclassToWriteBackToDB = keyclassForUnwrapping;
if (ok) {
secerror("SecDbKeychainItemV7: successfully decrypted metadata key using keyrolled keyclass %d", keyrolledKeyclass);
key = [[SFAESKey alloc] initWithData:unwrappedKeyData specifier:keySpecifier error:&retryError];
+
+ if(!key) {
+ os_log_fault(secLogObjForScope("SecDbKeychainItemV7"), "Metadata class key (%d) decrypted using keyrolled keyclass %d, but didn't become a key: %@", keyclass, keyrolledKeyclass, retryError);
+ nsErrorLocal = retryError;
+ }
}
else {
secerror("SecDbKeychainItemV7: failed to decrypt metadata key with keyrolled keyclass %d; error: %@", keyrolledKeyclass, retryError);
}
#endif
- if (ok) {
+ if (ok && key) {
if (actualKeyclassToWriteBackToDB > 0) {
// check if we have updated this keyclass or not already
static NSMutableDictionary* updated = NULL;
});
sec_action_perform(kclockedaction);
} else {
- secerror("SecDbKeychainItemV7: failed to decrypt metadata key for class %d; error: %@", keyclass, nsErrorLocal);
+ secerror("SecDbKeychainItemV7: failed to decrypt and create 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;
+ if(metadataKeyDoesntAuthenticate) {
+ os_log_fault(secLogObjForScope("SecDbKeychainItemV7"), "Metadata class key (%d) failed to decrypt: %@", keyclass, nsErrorLocal);
+ }
}
}
});
bool keyNotYetCreated = ok && !key;
bool forceOverwriteBadKey = !key && metadataKeyDoesntAuthenticate && overwriteCorruptKey;
- if (keyNotYetCreated || forceOverwriteBadKey) {
+ if (createIfMissing && (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");
ok = true; // Reset 'ok': we have a second chance
key = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:&nsErrorLocal];
+ keyIsNewlyCreated = true;
+
if (key) {
NSMutableData* wrappedKey = [NSMutableData dataWithLength:key.keyData.length + 40];
- keyclass_t outKeyclass;
+ keyclass_t outKeyclass = keyclass;
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);
else {
ok = false;
}
+ } else if(!key) {
+ // No key, but we're not supposed to make one. Make an error if one doesn't yet exist.
+ ok = false;
+ if(!nsErrorLocal) {
+ nsErrorLocal = [NSError errorWithDomain:(id)kSecErrorDomain code:errSecDecode userInfo:@{NSLocalizedDescriptionKey: @"Unable to find or create a suitable metadata key"}];
+ }
}
return ok;
});
if (ok && key) {
- if (allowKeyCaching) {
+ // We can't cache a newly-created key, just in case this db transaction is rolled back and we lose the persisted key.
+ // Don't worry, we'll cache it as soon as it's used again.
+ if (allowKeyCaching && !keyIsNewlyCreated) {
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, ^{
return result;
}
+// bring back with <rdar://problem/37523001>
+#if 0
+ (bool)isKeychainUnlocked
{
return kc_is_unlocked();
}
+#endif
- (instancetype)initWithData:(NSData*)data decryptionKeybag:(keybag_handle_t)decryptionKeybag error:(NSError**)error
{
{
if (!_metadataAttributes) {
SFAESKey* metadataClassKey = [self metadataClassKeyWithKeybag:_keybag
+ createKeyIfMissing:false
overwriteCorruptKey:false
error:error];
if (metadataClassKey) {
SFAuthenticatedCiphertext* ciphertext = [encryptionOperation encrypt:metadata withKey:key error:error];
SFAESKey* metadataClassKey = [self metadataClassKeyWithKeybag:keybag
+ createKeyIfMissing:true
overwriteCorruptKey:true
error:error];
if (metadataClassKey) {
}
- (SFAESKey*)metadataClassKeyWithKeybag:(keybag_handle_t)keybag
+ createKeyIfMissing:(bool)createIfMissing
overwriteCorruptKey:(bool)force
error:(NSError**)error
{
return [[SecDbKeychainMetadataKeyStore sharedStore] keyForKeyclass:_keyclass
keybag:keybag
keySpecifier:[self.class keySpecifier]
+ createKeyIfMissing:(bool)createIfMissing
overwriteCorruptKey:force
error:error];
}
*/
static void query_add_use(const void *key, const void *value, Query *q)
{
- if (CFEqual(key, kSecUseItemList)) {
+ // Gotta use a string literal because we just outlawed this symbol on iOS
+ if (CFEqual(key, CFSTR("u_ItemList"))) {
/* TODO: Add sanity checking when we start using this. */
q->q_use_item_list = value;
} else if (CFEqual(key, kSecUseTombstones)) {
return NULL;
}
-bool kc_transaction(SecDbConnectionRef dbt, CFErrorRef *error, bool(^perform)()) {
+bool kc_transaction(SecDbConnectionRef dbt, CFErrorRef *error, bool(^perform)(void)) {
return kc_transaction_type(dbt, kSecDbExclusiveTransactionType, error, perform);
}
-bool kc_transaction_type(SecDbConnectionRef dbt, SecDbTransactionType type, CFErrorRef *error, bool(^perform)()) {
+bool kc_transaction_type(SecDbConnectionRef dbt, SecDbTransactionType type, CFErrorRef *error, bool(^perform)(void)) {
__block bool ok = true;
return ok && SecDbTransaction(dbt, type, error, ^(bool *commit) {
ok = *commit = perform();
CFStringAppend(sql, CFSTR(");"));
- // Create indicies
+ // Create indices
SecDbForEachAttrWithMask(c,desc, kSecDbIndexFlag | kSecDbInFlag) {
- CFStringAppendFormat(sql, 0, CFSTR("CREATE INDEX %@%@ ON %@(%@);"), c->name, desc->name, c->name, desc->name);
+ if (desc->kind == kSecDbSyncAttr) {
+ CFStringAppendFormat(sql, 0, CFSTR("CREATE INDEX %@%@0 ON %@(%@) WHERE %@=0;"), c->name, desc->name, c->name, desc->name, desc->name);
+ } else {
+ CFStringAppendFormat(sql, 0, CFSTR("CREATE INDEX %@%@ ON %@(%@);"), c->name, desc->name, c->name, desc->name);
+ }
}
}
SECDB_ATTR(v6mdat, "mdat",ModificationDate,SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), SecDbKeychainItemCopyCurrentDate, NULL);
SECDB_ATTR(v6labl, "labl", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6data, "data", EncryptedData, SecDbFlags( ,L, , , , , , , ,B, , , , , , ), SecDbKeychainItemCopyEncryptedData, NULL);
-SECDB_ATTR(v6agrp, "agrp", String, SecDbFlags(P,L, , ,A, , , ,H, , , ,N,U,V0,Y), NULL, NULL);
+SECDB_ATTR(v6agrp, "agrp", String, SecDbFlags(P,L,I, ,A, , , ,H, , , ,N,U,V0,Y), NULL, NULL);
SECDB_ATTR(v6pdmn, "pdmn", Access, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6sync, "sync", Sync, SecDbFlags(P,L,I, ,A, , , ,H, ,Z, ,N,U,V0, ), NULL, NULL);
SECDB_ATTR(v6tomb, "tomb", Tomb, SecDbFlags( ,L, , , , , , ,H, ,Z, ,N,U, ,Y), NULL, NULL);
SECDB_ATTR(v6accc, "accc", AccessControl, SecDbFlags( , , , ,A, , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v6v_Data, "v_Data", Data, SecDbFlags( , , , , ,D, ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6v_pk, "v_pk", PrimaryKey, SecDbFlags( , , , , , , , , , , , , , , , ), SecDbKeychainItemCopyPrimaryKey, NULL);
-SECDB_ATTR(v7vwht, "vwht", String, SecDbFlags(P,L, , ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL);
-SECDB_ATTR(v7tkid, "tkid", String, SecDbFlags(P,L, , ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL);
+SECDB_ATTR(v7vwht, "vwht", String, SecDbFlags(P,L,I, ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL);
+SECDB_ATTR(v7tkid, "tkid", String, SecDbFlags(P,L,I, ,A, , , ,H, , , , ,U,V2,Y), NULL, NULL);
SECDB_ATTR(v7utomb, "u_Tomb", UTomb, SecDbFlags( , , , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v8musr, "musr", UUID, SecDbFlags(P,L,I, , , , , , , , , ,N,U, ,Y), NULL, NULL);
// genp and inet and keys | | | | | | | | | | | | | | | |
// genp and inet | | | | | | | | | | | | | | | |
SECDB_ATTR(v6desc, "desc", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6icmt, "icmt", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL);
-SECDB_ATTR(v6type, "type", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
+SECDB_ATTR(v6type, "type", Number, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6invi, "invi", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6nega, "nega", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6cusi, "cusi", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6prot, "prot", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6scrp, "scrp", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
-SECDB_ATTR(v6acct, "acct", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6acct, "acct", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
// genp only | | | | | | | | | | | | | | | |
-SECDB_ATTR(v6svce, "svce", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6svce, "svce", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
SECDB_ATTR(v6gena, "gena", Blob, SecDbFlags( ,L, ,S,A, , ,C,H, , , , , , ,Y), NULL, NULL);
// inet only | | | | | | | | | | | | | | | |
-SECDB_ATTR(v6sdmn, "sdmn", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6srvr, "srvr", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6ptcl, "ptcl", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6atyp, "atyp", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6port, "port", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6path, "path", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6sdmn, "sdmn", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6srvr, "srvr", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6ptcl, "ptcl", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6atyp, "atyp", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6port, "port", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6path, "path", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
// cert only | | | | | | | | | | | | | | | |
-SECDB_ATTR(v6ctyp, "ctyp", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6ctyp, "ctyp", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
SECDB_ATTR(v6cenc, "cenc", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6subj, "subj", Data, SecDbFlags( ,L,I,S,A, , ,C,H, , , , , , ,Y), NULL, NULL);
-SECDB_ATTR(v6issr, "issr", Data, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6slnr, "slnr", Data, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6issr, "issr", Data, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6slnr, "slnr", Data, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
SECDB_ATTR(v6skid, "skid", Data, SecDbFlags( ,L,I,S,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6pkhh, "pkhh", Data, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
// cert attributes that share names with common ones but have different flags
SECDB_ATTR(v6priv, "priv", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6modi, "modi", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6klbl, "klbl", Data, SecDbFlags(P,L,I, ,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6atag, "atag", Blob, SecDbFlags(P,L, ,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6bsiz, "bsiz", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6esiz, "esiz", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6sdat, "sdat", Date, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6edat, "edat", Date, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6atag, "atag", Blob, SecDbFlags(P,L,I,S,A, , ,C,H, , ,E,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6bsiz, "bsiz", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6esiz, "esiz", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6sdat, "sdat", Date, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6edat, "edat", Date, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
SECDB_ATTR(v6sens, "sens", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6asen, "asen", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6extr, "extr", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6wrap, "wrap", Number, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v6unwp, "unwp", Number, SecDbFlags( ,L,I, ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
// keys attributes that share names with common ones but have different flags
-SECDB_ATTR(v6keytype, "type", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
-SECDB_ATTR(v6keycrtr, "crtr", Number, SecDbFlags(P,L, , ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6keytype, "type", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
+SECDB_ATTR(v6keycrtr, "crtr", Number, SecDbFlags(P,L,I, ,A, , ,C,H, ,Z, ,N, ,V0,Y), NULL, NULL);
// | | | | | | | | | | | | | | |
-SECDB_ATTR(v6version, "version", Number, SecDbFlags(P,L, , , , , , , , , , ,N, , ,Y), NULL, NULL);
+SECDB_ATTR(v6version, "version", Number, SecDbFlags(P,L,I, , , , , , , , , ,N, , ,Y), NULL, NULL);
SECDB_ATTR(v91minor, "minor", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , ,Y), NULL, NULL);
SECDB_ATTR(v10_1pcsservice, "pcss", Number, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v10_1pcspublickey, "pcsk", Blob, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
SECDB_ATTR(v10_1pcspublicidentity,"pcsi", Blob, SecDbFlags( ,L, , ,A, , ,C,H, , , , , , ,Y), NULL, NULL);
-SECDB_ATTR(v10itemuuid, "UUID", String, SecDbFlags( ,L, , , , , , , , , , , ,U, , ), NULL, NULL);
-SECDB_ATTR(v10syncuuid, "UUID", String, SecDbFlags(P,L, , , , , , , , , , , ,U, , ), NULL, NULL);
-SECDB_ATTR(v10parentKeyUUID, "parentKeyUUID", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
+SECDB_ATTR(v10itemuuid, "UUID", String, SecDbFlags( ,L,I, , , , , , , , , , ,U, , ), NULL, NULL);
+SECDB_ATTR(v10syncuuid, "UUID", String, SecDbFlags(P,L,I, , , , , , , , , , ,U, , ), NULL, NULL);
+SECDB_ATTR(v10parentKeyUUID, "parentKeyUUID", String, SecDbFlags( ,L,I, , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10currentKeyUUID,"currentKeyUUID",String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10wrappedkey, "wrappedkey", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10encrypteditem, "encitem", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10gencount, "gencount", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , , ), NULL, NULL);
-SECDB_ATTR(v10action, "action", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
-SECDB_ATTR(v10state, "state", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL);
+SECDB_ATTR(v10action, "action", String, SecDbFlags( ,L,I, , , , , , , , , ,N, , , ), NULL, NULL);
+SECDB_ATTR(v10state, "state", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10waituntiltime, "waituntil", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10encodedCKRecord, "ckrecord", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10_1wasCurrent, "wascurrent", Number, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
-SECDB_ATTR(v10accessgroup, "accessgroup", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
-SECDB_ATTR(v10keyclass, "keyclass", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL);
+SECDB_ATTR(v10accessgroup, "accessgroup", String, SecDbFlags( ,L,I, , , , , , , , , ,N, , , ), NULL, NULL);
+SECDB_ATTR(v10keyclass, "keyclass", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10currentkey, "currentkey", Number, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
-SECDB_ATTR(v10ckzone, "ckzone", String, SecDbFlags(P,L, , , , , , , , , , ,N,U, , ), NULL, NULL);
+SECDB_ATTR(v10ckzone, "ckzone", String, SecDbFlags(P,L,I, , , , , , , , , ,N,U, , ), NULL, NULL);
SECDB_ATTR(v10ckzonecreated, "ckzonecreated", Number, SecDbFlags( ,L, , , , , , , , ,Z, , ,N, , ), NULL, NULL);
SECDB_ATTR(v10ckzonesubscribed,"ckzonesubscribed", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , , ), NULL, NULL);
SECDB_ATTR(v10ratelimiter, "ratelimiter", Blob, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10sysbound, "sysb", Number, SecDbFlags( ,L, , ,A, , ,C,H, ,Z, , , , , ), NULL, NULL);
SECDB_ATTR(v10encryptionver, "encver", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N,U, , ), NULL, NULL);
-SECDB_ATTR(v10primaryKey, "primaryKey", String, SecDbFlags(P,L, , ,A, , , , , , , ,N,U, , ), NULL, NULL);
-SECDB_ATTR(v10publickeyHash, "publickeyHash", Blob, SecDbFlags(P,L, , , , , , , , , , ,N,U, , ), NULL, NULL);
+SECDB_ATTR(v10primaryKey, "primaryKey", String, SecDbFlags(P,L,I, ,A, , , , , , , ,N,U, , ), NULL, NULL);
+SECDB_ATTR(v10publickeyHash, "publickeyHash", Blob, SecDbFlags(P,L,I, , , , , , , , , ,N,U, , ), NULL, NULL);
SECDB_ATTR(v10publickey, "publickey", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10backupData, "backupData", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10_2schema, "schema", Blob, SecDbFlags( ,L, , , , , , , , , , ,N,U, , ), NULL, NULL);
SECDB_ATTR(v10_1encRecord, "ckrecord", Blob, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
-SECDB_ATTR(v10_1keyArchiveHash, "key_archive_hash", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL);
-SECDB_ATTR(v10_1keyArchive, "key_archive", String, SecDbFlags(P,L, , , , , , , , , , ,N, , , ), NULL, NULL);
+SECDB_ATTR(v10_1keyArchiveHash, "key_archive_hash", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL);
+SECDB_ATTR(v10_1keyArchive, "key_archive", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10_1archivedKey, "archived_key", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10_1keyArchiveName, "keyarchive_name", String, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL);
SECDB_ATTR(v10_1optionalEncodedCKRecord, "ckrecord", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_1itempersistentref,"persistref", UUID, SecDbFlags( ,L,I, , , , , , , , , ,N,U, , ), NULL, NULL);
-SECDB_ATTR(v10_1currentItemUUID,"currentItemUUID",String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL);
+SECDB_ATTR(v10_1currentItemUUID,"currentItemUUID",String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_4currentItemUUID,"currentItemUUID",String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
-SECDB_ATTR(v10_1currentPtrIdentifier,"identifier",String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL);
+SECDB_ATTR(v10_1currentPtrIdentifier,"identifier",String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL);
-SECDB_ATTR(v10_2device, "device", String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL);
+SECDB_ATTR(v10_2device, "device", String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_2peerid, "peerid", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_2circleStatus,"circlestatus", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_2keyState, "keystate", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_4lastFixup, "lastfixup", Number, SecDbFlags( ,L, , , , , , , , ,Z, , ,N, , ), NULL, NULL);
-SECDB_ATTR(v10_5senderPeerID,"senderpeerid", String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL);
-SECDB_ATTR(v10_5recvPeerID, "recvpeerid", String, SecDbFlags(P,L, , , , , , , , , , , , , , ), NULL, NULL);
+SECDB_ATTR(v10_5senderPeerID,"senderpeerid", String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL);
+SECDB_ATTR(v10_5recvPeerID, "recvpeerid", String, SecDbFlags(P,L,I, , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_5recvPubKey, "recvpubenckey", Blob, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_5curve, "curve", Number, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL);
SECDB_ATTR(v10_5poisoned, "poisoned", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N, , , ), NULL, NULL);
},
};
+/*
+ * Version 11.4 (Add some more indexes)
+ */
+const SecDbSchema v11_4_schema = {
+ .majorVersion = 11,
+ .minorVersion = 4,
+ .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.3 (no changes, restores the use of indexes in upgrade code. Gotta go fast!)
+ */
+const SecDbSchema v11_3_schema = {
+ .majorVersion = 11,
+ .minorVersion = 3,
+ .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.2
*/
SecDbSchema const * const * kc_schemas = NULL;
const SecDbSchema *v10_kc_schemas[] = {
+ &v11_4_schema,
+ &v11_3_schema,
&v11_2_schema,
&v11_1_schema,
&v11_schema,
#include <SharedWebCredentials/SharedWebCredentials.h>
#endif
+#include "Analytics/Clients/LocalKeychainAnalytics.h"
+
/* Changed the name of the keychain changed notification, for testing */
static const char *g_keychain_changed_notification = kSecServerKeychainChangedNotification;
ok &= SecDbPrepare(dbt, CFSTR("SELECT name FROM sqlite_master WHERE type='table' AND name='tversion'"), &localError, ^(sqlite3_stmt *stmt) {
ok = SecDbStep(dbt, stmt, NULL, ^(bool *stop) {
found = true;
- *stop = 1;
+ *stop = true;
});
});
require_action(ok, out, SecDbError(SQLITE_CORRUPT, error, CFSTR("Failed to read sqlite_master table: %@"), localError));
return oldTableVersion < 10 || !DBClassesAreEqual(class1, class2);
}
+#define SCHEMA_VERSION(schema) ((((schema)->minorVersion) << 8) | ((schema)->majorVersion))
+#define VERSION_MAJOR(version) ((version) & 0xff)
+#define VERSION_MINOR(version) (((version) >> 8) & 0xff)
+#define VERSION_NEW(version) ((version) & 0xffff)
+#define VERSION_OLD(version) (((version) >> 16) & 0xffff)
+
// Goes through all tables represented by old_schema and tries to migrate all items from them into new (current version) tables.
static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSchema, CFErrorRef *error)
{
- __block bool ok = true;
+ int oldVersion = SCHEMA_VERSION(oldSchema);
const SecDbSchema *newSchema = current_schema();
+ int newVersion = SCHEMA_VERSION(newSchema);
+ __block bool ok = true;
SecDbClass const *const *oldClass;
SecDbClass const *const *newClass;
SecDbQueryRef query = NULL;
}
if(CFStringGetLength(sql) > 0) {
- require_quiet(ok &= SecDbExec(dbt, sql, error), out);
+ require_action_quiet(ok &= SecDbExec(dbt, sql, error), out,
+ LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1AlterTables, error ? *error : NULL));
}
CFReleaseNull(sql);
// Drop indices that that new schemas will use
sql = CFStringCreateMutable(NULL, 0);
for (newClass = newSchema->classes; *newClass != NULL; newClass++) {
- SecDbForEachAttrWithMask((*newClass),desc, kSecDbIndexFlag | kSecDbInFlag) {
+ SecDbForEachAttrWithMask((*newClass), desc, kSecDbIndexFlag | kSecDbInFlag) {
CFStringAppendFormat(sql, 0, CFSTR("DROP INDEX IF EXISTS %@%@;"), (*newClass)->name, desc->name);
+ if (desc->kind == kSecDbSyncAttr) {
+ CFStringAppendFormat(sql, 0, CFSTR("DROP INDEX IF EXISTS %@%@0;"), (*newClass)->name, desc->name);
+ }
}
}
- require_quiet(ok &= SecDbExec(dbt, sql, error), out);
+ require_action_quiet(ok &= SecDbExec(dbt, sql, error), out,
+ LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1DropIndices, error ? *error : NULL));
CFReleaseNull(sql);
// Create tables for new schema.
- require_quiet(ok &= SecItemDbCreateSchema(dbt, newSchema, classIndexesForNewTables, false, error), out);
+ require_action_quiet(ok &= SecItemDbCreateSchema(dbt, newSchema, classIndexesForNewTables, false, error), out,
+ LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1CreateSchema, error ? *error : NULL));
// Go through all classes of current schema to transfer all items to new tables.
for (oldClass = oldSchema->classes, newClass = newSchema->classes;
*oldClass != NULL && *newClass != NULL; oldClass++, newClass++) {
}
*stop = !ok;
+
});
- require_quiet(ok, out);
+ require_action_quiet(ok, out,
+ LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1Items, error ? *error : NULL));
} else {
// This table does not contain secdb items, and must be transferred without using SecDbItemSelect.
// For now, this code does not support removing or renaming any columns, or adding any new non-null columns.
CFStringAppendFormat(sql, NULL, CFSTR("INSERT OR REPLACE INTO %@ (%@) SELECT %@ FROM %@;"), (*newClass)->name, columns, columns, renamedOldClass->name);
CFReleaseNull(columns);
- require_quiet(ok &= SecDbExec(dbt, sql, error), out);
+ require_action_quiet(ok &= SecDbExec(dbt, sql, error), out,
+ LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1NonItems, error ? *error : NULL));
}
}
}
if(CFStringGetLength(sql) > 0) {
- require_quiet(ok &= SecDbExec(dbt, sql, error), out);
+ require_action_quiet(ok &= SecDbExec(dbt, sql, error), out,
+ LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1DropOld, error ? *error : NULL));
}
out:
#if TARGET_OS_EMBEDDED
}
__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 inDbt, bool *inProgress, CFErrorRef *error) {
+static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, int oldVersion, CFErrorRef *error) {
SecDbConnectionRef oldDbt = dbt;
dbt = inDbt;
__block bool ok = true;
// Go through all classes in new schema
const SecDbSchema *newSchema = current_schema();
+ int newVersion = SCHEMA_VERSION(newSchema);
for (const SecDbClass *const *class = newSchema->classes; *class != NULL && !*inProgress; class++) {
if(!((*class)->itemclass)) {
//Don't try to decrypt non-item 'classes'
// remember that DB still needs phase2 migration to be run next time a connection is made. Also
// stop iterating next items, it would be just waste of time because the whole iteration will be run
// next time when this phase2 will be rerun.
+ LKAReportKeychainUpgradeOutcome(oldVersion, newVersion, LKAKeychainUpgradeOutcomeLocked);
*inProgress = true;
*stop = true;
ok = true;
*stop = *stop || !ok;
});
- require(ok, out);
+ require_action(ok, out, LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase2, error ? *error : NULL));
}
#if TARGET_OS_EMBEDDED
return ok;
}
-#define SCHEMA_VERSION(schema) ((((schema)->minorVersion) << 8) | ((schema)->majorVersion))
-#define VERSION_MAJOR(version) ((version) & 0xff)
-#define VERSION_MINOR(version) (((version) >> 8) & 0xff)
-#define VERSION_NEW(version) ((version) & 0xffff)
-#define VERSION_OLD(version) (((version) >> 16) & 0xffff)
-
static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, bool *inProgress, CFErrorRef *error) {
__block bool didPhase2 = false;
__block bool ok = true;
*error = NULL;
const SecDbSchema *newSchema = current_schema();
+ int newVersion = SCHEMA_VERSION(newSchema);
+ bool skipped_upgrade = false;
// If DB schema is the one we want, we are done.
- require_quiet(SCHEMA_VERSION(newSchema) != version, out);
+ require_action_quiet(SCHEMA_VERSION(newSchema) != version, out, skipped_upgrade = true);
// Check if the schema of the database on disk is the same major, but newer version then what we have
// in code, lets just skip this since a newer version of the OS have upgrade it. Since its the same
goto out;
}
- if (VERSION_MAJOR(version) < 6) {
- // Pre v6 keychains need to have WAL enabled, since SecDb only does this at db creation time.
- // NOTE: This has to be run outside of a transaction.
- require_action_quiet(ok = (SecDbExec(dbt, CFSTR("PRAGMA auto_vacuum = FULL"), &localError) &&
- SecDbExec(dbt, CFSTR("PRAGMA journal_mode = WAL"), &localError)),
- out, secerror("upgrade: unable to enable WAL or auto vacuum, marking DB as corrupt: %@",
- localError));
- }
-
ok &= SecDbTransaction(dbt, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
CFStringRef sql = NULL;
bool didPhase1 = false;
require_quiet(SCHEMA_VERSION(newSchema) != version2, out);
// If this is empty database, just create table according to schema and be done with it.
- require_action_quiet(version2 != 0, out, ok = SecItemDbCreateSchema(dbt, newSchema, NULL, true, &localError));
+ require_action_quiet(version2 != 0, out, ok = SecItemDbCreateSchema(dbt, newSchema, NULL, true, &localError);
+ LKAReportKeychainUpgradeOutcomeWithError(version2, newVersion, LKAKeychainUpgradeOutcomeNewDb, localError));
int oldVersion = VERSION_OLD(version2);
version2 = VERSION_NEW(version2);
require_action_quiet(version2 == SCHEMA_VERSION(newSchema) || oldVersion == 0, out,
ok = SecDbError(SQLITE_CORRUPT, &localError,
CFSTR("Half migrated but obsolete DB found: found 0x%x(0x%x) but 0x%x is needed"),
- version2, oldVersion, SCHEMA_VERSION(newSchema)));
+ version2, oldVersion, SCHEMA_VERSION(newSchema));
+ LKAReportKeychainUpgradeOutcome(version2, newVersion, LKAKeychainUpgradeOutcomeObsoleteDb));
// Check whether we have both old and new tables in the DB.
if (oldVersion == 0) {
// If we are attempting to upgrade from a version for which we have no schema, fail.
require_action_quiet(oldSchema != NULL, out,
ok = SecDbError(SQLITE_CORRUPT, &localError, CFSTR("no schema for version: 0x%x"), oldVersion);
- secerror("no schema for version 0x%x", oldVersion));
+ secerror("no schema for version 0x%x", oldVersion);
+ LKAReportKeychainUpgradeOutcome(version2, newVersion, LKAKeychainUpgradeOutcomeNoSchema));
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);
// 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);
+ ok = UpgradeItemPhase2(dbt, inProgress, version2, &phase2Error);
if (!ok) {
if (didPhase1) {
*inProgress = true;
SecADSetValueForScalarKey(CFSTR("com.apple.keychain.migration-failure"), 1);
#endif
}
+ } else {
+ // Things seemed to go okay!
+ if (didPhase2) {
+ LKAReportKeychainUpgradeOutcome(version, newVersion, LKAKeychainUpgradeOutcomeSuccess);
+ }
+
+ //If we're done here, we should opportunistically re-add all indices (just in case)
+ if(skipped_upgrade || didPhase2) {
+ // Create indices, ignoring all errors
+ for (SecDbClass const* const* newClass = newSchema->classes; *newClass; ++newClass) {
+ SecDbForEachAttrWithMask((*newClass), desc, kSecDbIndexFlag | kSecDbInFlag) {
+ CFStringRef sql = NULL;
+ CFErrorRef localError = NULL;
+ bool localOk = true;
+
+ if (desc->kind == kSecDbSyncAttr) {
+ // Replace the complete sync index with a partial index for sync=0. Most items are sync=1, so the complete index isn't helpful for sync=1 queries.
+ sql = CFStringCreateWithFormat(NULL, NULL, CFSTR("DROP INDEX IF EXISTS %@%@; CREATE INDEX IF NOT EXISTS %@%@0 on %@(%@) WHERE %@=0;"),
+ (*newClass)->name, desc->name, (*newClass)->name, desc->name, (*newClass)->name, desc->name, desc->name);
+ } else {
+ sql = CFStringCreateWithFormat(NULL, NULL, CFSTR("CREATE INDEX IF NOT EXISTS %@%@ ON %@(%@);"), (*newClass)->name, desc->name, (*newClass)->name, desc->name);
+ }
+ localOk &= SecDbExec(dbt, sql, &localError);
+ CFReleaseNull(sql);
+
+ if(!localOk) {
+ secerror("upgrade: unable to opportunistically create index (%@,%@): %@", (*newClass)->name, desc->name, localError);
+ }
+ CFReleaseNull(localError);
+ }
+ }
+ }
}
if (localError) {
if (error) {
SecDbRef SecKeychainDbCreate(CFStringRef path, CFErrorRef* error) {
__block CFErrorRef localerror = NULL;
- SecDbRef kc = SecDbCreate(path, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) {
+ SecDbRef kc = SecDbCreate(path, 0600, true, true, true, true, kSecDbMaxIdleHandles,
+ ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)
+ {
// Upgrade from version 0 means create the schema in empty db.
int version = 0;
bool ok = true;
});
}
-static bool checkIsUnlocked()
-{
- CFErrorRef aksError = NULL;
- bool locked = true;
-
- if(!SecAKSGetIsLocked(&locked, &aksError)) {
- secerror("error querying lock state: %@", aksError);
- CFReleaseNull(aksError);
- }
-
- return !locked;
-}
-
static bool kc_acquire_dbt(bool writeAndRead, SecDbConnectionRef* dbconn, CFErrorRef *error) {
SecDbRef db = kc_dbhandle(error);
if (db == NULL) {
}
bool ok = false;
- if (kc_acquire_dbt(writeAndRead, &dbt, error)) {
- isUnlocked = checkIsUnlocked();
+ if (kc_acquire_dbt(writeAndRead, &dbt, error)) {
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)
**************** Beginning of Externally Callable Interface ****************
****************************************************************************/
-void (*SecTaskDiagnoseEntitlements)(CFArrayRef accessGroups) = NULL;
-
static bool SecEntitlementError(OSStatus status, CFErrorRef *error)
{
#if TARGET_OS_OSX
CFIndex ag_count;
if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
- if (SecTaskDiagnoseEntitlements)
- SecTaskDiagnoseEntitlements(accessGroups);
return SecEntitlementError(errSecMissingEntitlement, error);
}
}
#endif
+static CFArrayRef
+SecurityClientCopyWritableAccessGroups(SecurityClient *client) {
+ if (client == NULL || client->accessGroups == NULL) {
+ return NULL;
+ }
+ CFIndex count = CFArrayGetCount(client->accessGroups);
+ if (CFArrayContainsValue(client->accessGroups, CFRangeMake(0, count), kSecAttrAccessGroupToken)) {
+ CFMutableArrayRef writableGroups = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, client->accessGroups);
+ CFArrayRemoveAllValue(writableGroups, kSecAttrAccessGroupToken);
+ return writableGroups;
+ } else {
+ return CFRetainSafe(client->accessGroups);
+ }
+}
+
/* AUDIT[securityd](done):
attributes (ok) is a caller provided dictionary, only its cf type has
bool
_SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *result, CFErrorRef *error)
{
- CFArrayRef accessGroups = client->accessGroups;
+ CFArrayRef accessGroups = SecurityClientCopyWritableAccessGroups(client);
bool ok = true;
CFIndex ag_count;
if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
- if (SecTaskDiagnoseEntitlements)
- SecTaskDiagnoseEntitlements(accessGroups);
+ CFReleaseNull(accessGroups);
return SecEntitlementError(errSecMissingEntitlement, error);
}
/* Having the special accessGroup "*" allows access to all accessGroups. */
if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*")))
- accessGroups = NULL;
+ CFReleaseNull(accessGroups);
if (agrp) {
/* The user specified an explicit access group, validate it. */
query_add_attribute(kSecAttrAccessGroup, agrp, q);
}
- if (CFEqual(agrp, kSecAttrAccessGroupToken)) {
- ok = SecError(errSecParam, error, CFSTR("storing items into kSecAttrAccessGroupToken is not allowed"));
- }
-
if (SecPLShouldLogRegisteredEvent(CFSTR("SecItem"))) {
CFDictionaryRef dict = CFDictionaryCreateForCFTypes(NULL, CFSTR("operation"), CFSTR("add"), CFSTR("AccessGroup"), agrp, NULL);
if (dict) {
SecSignpostStop(SecSignpostSecItemAdd);
+ CFReleaseNull(accessGroups);
return ok;
}
_SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate,
SecurityClient *client, CFErrorRef *error)
{
- CFArrayRef accessGroups = client->accessGroups;
+ CFArrayRef accessGroups = SecurityClientCopyWritableAccessGroups(client);
CFIndex ag_count;
if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
- if (SecTaskDiagnoseEntitlements)
- SecTaskDiagnoseEntitlements(accessGroups);
+ CFReleaseNull(accessGroups);
return SecEntitlementError(errSecMissingEntitlement, error);
}
if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) {
/* Having the special accessGroup "*" allows access to all accessGroups. */
- accessGroups = NULL;
+ CFReleaseNull(accessGroups);
}
bool ok = true;
if (agrp) {
/* The user is attempting to modify the access group column,
validate it to make sure the new value is allowable. */
- if (CFEqual(agrp, kSecAttrAccessGroupToken)) {
- ok = SecError(errSecParam, error, CFSTR("storing items into kSecAttrAccessGroupToken is not allowed"));
- }
if (!accessGroupsAllows(accessGroups, agrp, client)) {
ok = SecError(errSecNoAccessForItem, error, CFSTR("accessGroup %@ not in %@"), agrp, accessGroups);
}
SecSignpostStop(SecSignpostSecItemUpdate);
+ CFReleaseNull(accessGroups);
return ok;
}
bool
_SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error)
{
- CFArrayRef accessGroups = client->accessGroups;
+ CFArrayRef accessGroups = SecurityClientCopyWritableAccessGroups(client);
CFIndex ag_count;
if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
- if (SecTaskDiagnoseEntitlements)
- SecTaskDiagnoseEntitlements(accessGroups);
+ CFReleaseNull(accessGroups);
return SecEntitlementError(errSecMissingEntitlement, error);
}
if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) {
/* Having the special accessGroup "*" allows access to all accessGroups. */
- accessGroups = NULL;
+ CFReleaseNull(accessGroups);
}
Query *q = query_create_with_limit(query, client->musr, kSecMatchUnlimited, error);
SecSignpostStop(SecSignpostSecItemDelete);
+ CFReleaseNull(accessGroups);
return ok;
}
CFArrayRef accessGroups = client->accessGroups;
CFIndex ag_count;
if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) {
- if (SecTaskDiagnoseEntitlements)
- SecTaskDiagnoseEntitlements(accessGroups);
return SecEntitlementError(errSecMissingEntitlement, error);
}
if (creator) {
CFDictionarySetValue(query, kSecAttrCreator, creator);
CFReleaseSafe(creator);
- ok = true;
- }
- else {
- // confirm the add
- // (per rdar://16680019, we won't prompt here in the normal case)
- ok = /*approved ||*/ swca_confirm_operation(swca_add_request_id, clientAuditToken, query, error,
- ^void (CFStringRef fqdn) { _SecAddNegativeWebCredential(client, fqdn, appID, false); });
}
+
+ // confirm the add
+ ok = swca_confirm_operation(swca_add_request_id, clientAuditToken, query, error, ^void (CFStringRef fqdn) {
+ _SecAddNegativeWebCredential(client, fqdn, appID, false);
+ });
}
if (ok) {
ok = _SecItemAdd(query, &swcclient, result, error);
if (flags & SecServerInitialSyncCredentialFlagBluetoothMigration) {
require_action(InitialSyncItems(items, false, CFSTR("com.apple.nanoregistry.migration"), NULL, genp_class(), error), fail,
secerror("failed to collect com.apple.nanoregistry.migration-genp item: %@", error ? *error : NULL));
+ require_action(InitialSyncItems(items, false, CFSTR("com.apple.nanoregistry.migration2"), NULL, genp_class(), error), fail,
+ secerror("failed to collect com.apple.nanoregistry.migration2-genp item: %@", error ? *error : NULL));
require_action(InitialSyncItems(items, false, CFSTR("com.apple.bluetooth"), CFSTR("BluetoothLESync"), genp_class(), error), fail,
secerror("failed to collect com.apple.bluetooth-genp item: %@", error ? *error : NULL));
bool _SecItemUpdateTokenItems(CFStringRef tokenID, CFArrayRef items, SecurityClient *client, CFErrorRef *error);
CF_RETURNS_RETAINED CFArrayRef _SecServerKeychainSyncUpdateMessage(CFDictionaryRef updates, CFErrorRef *error);
-bool _SecServerKeychainSyncUpdateIDSMessage(CFDictionaryRef updates, CFErrorRef *error);
CF_RETURNS_RETAINED CFDictionaryRef _SecServerBackupSyncable(CFDictionaryRef backup, CFDataRef keybag, CFDataRef password, CFErrorRef *error);
int SecServerKeychainTakeOverBackupFD(CFStringRef backupName, CFErrorRef *error);
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 */
bool itemInAccessGroup(CFDictionaryRef item, CFArrayRef accessGroups);
void SecKeychainChanged(void);
-extern void (*SecTaskDiagnoseEntitlements)(CFArrayRef accessGroups);
-
__END_DECLS
#endif /* _SECURITYD_SECITEMSERVER_H_ */
// MARK: SecOCSPCacheDb
static SecDbRef SecOCSPCacheDbCreate(CFStringRef path) {
- return SecDbCreate(path, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) {
- __block bool ok;
- ok = (SecDbExec(dbconn, CFSTR("PRAGMA auto_vacuum = FULL"), error) &&
- SecDbExec(dbconn, CFSTR("PRAGMA journal_mode = WAL"), error));
+ return SecDbCreate(path, 0600, true, true, true, true, 1,
+ ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) {
+ __block bool ok = true;
+
CFErrorRef localError = NULL;
- if (ok && !SecDbWithSQL(dbconn, selectHashAlgorithmSQL /* expireSQL */, &localError, NULL) && CFErrorGetCode(localError) == SQLITE_ERROR) {
+ if (!SecDbWithSQL(dbconn, selectHashAlgorithmSQL /* expireSQL */, &localError, NULL) && CFErrorGetCode(localError) == SQLITE_ERROR) {
/* SecDbWithSQL returns SQLITE_ERROR if the table we are preparing the above statement for doesn't exist. */
ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, error, ^(bool *commit) {
ok &= SecDbExec(dbconn,
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);
- if (!ok) {
- secerror("_SecOCSPCacheAddResponse VACUUM failed: %@", localError);
- TrustdHealthAnalyticsLogErrorCodeForDatabase(TAOCSPCache, TAOperationWrite, TAFatalError,
- localError ? CFErrorGetCode(localError) : errSecInternalComponent);
- }
- });
}
CFReleaseSafe(localError);
}
require(publicKey = SecCertificateGetPublicKeyData(request->issuer), errOut);
require(issuer = SecCertificateCopyIssuerSequence(request->certificate), errOut);
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
- require(serial = SecCertificateCopySerialNumber(request->certificate, NULL), errOut);
-#else
- require(serial = SecCertificateCopySerialNumber(request->certificate), errOut);
-#endif
+ require(serial = SecCertificateCopySerialNumberData(request->certificate, NULL), errOut);
ok &= SecDbPerformRead(this->db, &localError, ^(SecDbConnectionRef dbconn) {
ok &= SecDbWithSQL(dbconn, selectHashAlgorithmSQL, &localError, ^bool(sqlite3_stmt *selectHash) {
and call SecDigestCreate here instead. */
issuerNameDigest = SecCertificateCopyIssuerSHA1Digest(this->certificate);
issuerPubKeyDigest = SecCertificateCopyPublicKeySHA1Digest(this->issuer);
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
- serial = SecCertificateCopySerialNumber(this->certificate, NULL);
-#else
- serial = SecCertificateCopySerialNumber(this->certificate);
-#endif
+ serial = SecCertificateCopySerialNumberData(this->certificate, NULL);
/* build the CertID from those components */
certId->issuerNameHash.Length = CC_SHA1_DIGEST_LENGTH;
/*
- * Copyright (c) 2008-2009,2012-2016 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2008-2009,2012-2018 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
SecOCSPResponseRef SecOCSPResponseCreateWithID(CFDataRef ocspResponse, int64_t responseID) {
SecAsn1OCSPResponse topResp = {};
- SecOCSPResponseRef this;
+ SecOCSPResponseRef this = NULL;
+ require(ocspResponse, errOut);
require(this = (SecOCSPResponseRef)calloc(1, sizeof(struct __SecOCSPResponse)),
errOut);
require_noerr(SecAsn1CoderCreate(&this->coder), errOut);
errOut:
#ifdef DEBUG
{
- CFStringRef hexResp = CFDataCopyHexString(this->data);
+ CFStringRef hexResp = (this) ? CFDataCopyHexString(this->data) : NULL;
secdebug("ocsp", "bad ocsp response: %@", hexResp);
CFReleaseSafe(hexResp);
}
if (!request) { return sr; }
CFDataRef issuer = SecCertificateCopyIssuerSequence(request->certificate);
const DERItem *publicKey = SecCertificateGetPublicKeyData(request->issuer);
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
- CFDataRef serial = SecCertificateCopySerialNumber(request->certificate, NULL);
-#else
- CFDataRef serial = SecCertificateCopySerialNumber(request->certificate);
-#endif
+ CFDataRef serial = SecCertificateCopySerialNumberData(request->certificate, NULL);
CFDataRef issuerNameHash = NULL;
CFDataRef issuerPubKeyHash = NULL;
SecAsn1Oid *algorithm = NULL;
}
if (shouldBeSigner) {
-#if TARGET_OS_IPHONE
- SecKeyRef key = SecCertificateCopyPublicKey(issuer);
-#else
- SecKeyRef key = SecCertificateCopyPublicKey_ios(issuer);
-#endif
+ SecKeyRef key = SecCertificateCopyKey(issuer);
if (key) {
shouldBeSigner = SecOCSPResponseVerifySignature(this, key);
ocspdDebug("ocsp response signature %sok", shouldBeSigner ? "" : "not ");
/*
- * Copyright (c) 2009,2012-2016 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2009,2012-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,
* 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 <Foundation/Foundation.h>
#import <sys/stat.h>
#import <notify.h>
+#import <os/lock.h>
#if !TARGET_OS_BRIDGE
#import <MobileAsset/MAAsset.h>
@property (assign) SecDbRef db;
@property dispatch_queue_t queue;
@property NSURL *dbPath;
+@property (assign) os_unfair_lock regexCacheLock;
+@property NSMutableDictionary *regexCache;
- (instancetype) init;
- ( NSDictionary * _Nullable ) queryForDomain:(NSString *)domain;
- ( NSDictionary * _Nullable ) queryForPolicyName:(NSString *)policyName;
ok &= SecDbPerformWrite(self->_db, &error, ^(SecDbConnectionRef dbconn) {
ok &= [self updateDb:dbconn error:&error pinningList:pinningList updateSchema:NO updateContent:YES];
});
+ /* We changed the database, so clear the database cache */
+ [self clearCache];
});
if (!ok || error) {
#endif
CFStringRef path = CFStringCreateWithCString(NULL, [_dbPath fileSystemRepresentation], kCFStringEncodingUTF8);
- SecDbRef result = SecDbCreateWithOptions(path, mode, readWrite, readWrite, false,
+ SecDbRef result = SecDbCreate(path, mode, readWrite, readWrite, false, false, 1,
^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) {
if (!SecOTAPKIIsSystemTrustd()) {
/* Non-owner process can't update the db, but it should get a db connection.
- (instancetype) init {
if (self = [super init]) {
_queue = dispatch_queue_create("Pinning DB Queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+ _regexCache = [NSMutableDictionary dictionary];
+ _regexCacheLock = OS_UNFAIR_LOCK_INIT;
[self initializedDb];
}
return self;
CFReleaseNull(_db);
}
+/* MARK: DB Cache
+ * The cache is represented a dictionary defined as { suffix : { regex : resultsDictionary } } */
+- (void) clearCache {
+ os_unfair_lock_lock(&_regexCacheLock);
+ self.regexCache = [NSMutableDictionary dictionary];
+ os_unfair_lock_unlock(&_regexCacheLock);
+}
+
+- (void) addSuffixToCache:(NSString *)suffix entry:(NSDictionary <NSRegularExpression *, NSDictionary *> *)entry {
+ os_unfair_lock_lock(&_regexCacheLock);
+ secinfo("SecPinningDb", "adding %llu entries for %@ to cache", (unsigned long long)[entry count], suffix);
+ self.regexCache[suffix] = entry;
+ os_unfair_lock_unlock(&_regexCacheLock);
+}
+
+/* Because we iterate over all DB entries for a suffix, even if we find a match, we guarantee
+ * that the cache, if the cache has an entry for a suffix, it has all the entries for that suffix */
+- (BOOL) queryCacheForSuffix:(NSString *)suffix firstLabel:(NSString *)firstLabel results:(NSDictionary * __autoreleasing *)results{
+ __block BOOL foundSuffix = NO;
+ os_unfair_lock_lock(&_regexCacheLock);
+ NSDictionary <NSRegularExpression *, NSDictionary *> *cacheEntry;
+ if (NULL != (cacheEntry = self.regexCache[suffix])) {
+ foundSuffix = YES;
+ for (NSRegularExpression *regex in cacheEntry) {
+ NSUInteger numMatches = [regex numberOfMatchesInString:firstLabel
+ options:0
+ range:NSMakeRange(0, [firstLabel length])];
+ if (numMatches == 0) {
+ continue;
+ }
+ secinfo("SecPinningDb", "found matching rule in cache for %@.%@", firstLabel, suffix);
+ NSDictionary *resultDictionary = [cacheEntry objectForKey:regex];
+
+ /* Check the policyName for no-pinning settings */
+ if ([self isPinningDisabled:resultDictionary[(__bridge NSString *)kSecPinningDbKeyPolicyName]]) {
+ continue;
+ }
+
+ /* Return the pinning rules */
+ if (results) {
+ *results = resultDictionary;
+ }
+ }
+ }
+ os_unfair_lock_unlock(&_regexCacheLock);
+
+ return foundSuffix;
+}
+
- (BOOL) isPinningDisabled:(NSString * _Nullable)policy {
static dispatch_once_t once;
static sec_action_t action;
return pinningDisabled;
}
-- ( NSDictionary * _Nullable ) queryForDomain:(NSString *)domain {
+- (NSDictionary * _Nullable) queryForDomain:(NSString *)domain {
if (!_queue) { (void)[self init]; }
if (!_db) { [self initializedDb]; }
__block NSString *firstLabel = [domain substringToIndex:firstDot.location];
__block NSString *suffix = [domain substringFromIndex:(firstDot.location + 1)];
- /* Perform SELECT */
+ /* Search cache */
+ NSDictionary *cacheResult = nil;
+ if ([self queryCacheForSuffix:suffix firstLabel:firstLabel results:&cacheResult]) {
+ return cacheResult;
+ }
+
+ /* Cache miss. Perform SELECT */
__block bool ok = true;
__block CFErrorRef error = NULL;
__block NSMutableArray *resultRules = [NSMutableArray array];
__block NSString *resultName = nil;
+ __block NSMutableDictionary <NSRegularExpression *, NSDictionary *> *newCacheEntry = [NSMutableDictionary dictionary];
ok &= SecDbPerformRead(_db, &error, ^(SecDbConnectionRef dbconn) {
ok &= SecDbWithSQL(dbconn, selectDomainSQL, &error, ^bool(sqlite3_stmt *selectDomain) {
ok &= SecDbBindText(selectDomain, 1, [suffix UTF8String], [suffix length], SQLITE_TRANSIENT, &error);
ok &= SecDbStep(dbconn, selectDomain, &error, ^(bool *stop) {
- /* Match the labelRegex */
- const uint8_t *regex = sqlite3_column_text(selectDomain, 0);
- if (!regex) { return; }
- NSString *regexStr = [NSString stringWithUTF8String:(const char *)regex];
- if (!regexStr) { return; }
- NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regexStr
- options:NSRegularExpressionCaseInsensitive
- error:nil];
- if (!regularExpression) { return; }
- NSUInteger numMatches = [regularExpression numberOfMatchesInString:firstLabel
- options:0
- range:NSMakeRange(0, [firstLabel length])];
- if (numMatches == 0) {
- return;
+ @autoreleasepool {
+ /* Get the data from the entry */
+ // First Label Regex
+ const uint8_t *regex = sqlite3_column_text(selectDomain, 0);
+ verify_action(regex, return);
+ NSString *regexStr = [NSString stringWithUTF8String:(const char *)regex];
+ verify_action(regexStr, return);
+ NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regexStr
+ options:NSRegularExpressionCaseInsensitive
+ error:nil];
+ verify_action(regularExpression, return);
+ // Policy name
+ const uint8_t *policyName = sqlite3_column_text(selectDomain, 1);
+ NSString *policyNameStr = [NSString stringWithUTF8String:(const char *)policyName];
+ // Policies
+ NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectDomain, 2) length:sqlite3_column_bytes(selectDomain, 2)];
+ verify_action(xmlPolicies, return);
+ id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil];
+ verify_action(isNSArray(policies), return);
+
+ /* Add to cache entry */
+ [newCacheEntry setObject:@{(__bridge NSString*)kSecPinningDbKeyPolicyName:policyNameStr,
+ (__bridge NSString*)kSecPinningDbKeyRules:policies}
+ forKey:regularExpression];
+
+ /* Match the labelRegex */
+ NSUInteger numMatches = [regularExpression numberOfMatchesInString:firstLabel
+ options:0
+ range:NSMakeRange(0, [firstLabel length])];
+ if (numMatches == 0) {
+ return;
+ }
+ secinfo("SecPinningDb", "found matching rule in DB for %@.%@", firstLabel, suffix);
+
+ /* Check the policyName for no-pinning settings */
+ if ([self isPinningDisabled:policyNameStr]) {
+ return;
+ }
+
+ /* Add return data
+ * @@@ Assumes there is only one rule with matching suffix/label pairs. */
+ [resultRules addObjectsFromArray:(NSArray *)policies];
+ resultName = policyNameStr;
}
- secdebug("SecPinningDb", "found matching rule for %@.%@", firstLabel, suffix);
-
- /* Check the policyName for no-pinning settings */
- const uint8_t *policyName = sqlite3_column_text(selectDomain, 1);
- NSString *policyNameStr = [NSString stringWithUTF8String:(const char *)policyName];
- if ([self isPinningDisabled:policyNameStr]) {
- return;
- }
-
- /* Deserialize the policies and return.
- * @@@ Assumes there is only one rule with matching suffix/label pairs. */
- NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectDomain, 2) length:sqlite3_column_bytes(selectDomain, 2)];
- if (!xmlPolicies) { return; }
- id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil];
- if (!isNSArray(policies)) {
- return;
- }
- [resultRules addObjectsFromArray:(NSArray *)policies];
- resultName = policyNameStr;
});
return ok;
});
CFReleaseNull(error);
}
+ /* Add new cache entry to cache. */
+ if ([newCacheEntry count] > 0) {
+ [self addSuffixToCache:suffix entry:newCacheEntry];
+ }
+
+ /* Return results if found */
if ([resultRules count] > 0) {
NSDictionary *results = @{(__bridge NSString*)kSecPinningDbKeyRules:resultRules,
(__bridge NSString*)kSecPinningDbKeyPolicyName:resultName};
ok &= SecDbWithSQL(dbconn, selectPolicyNameSQL, &error, ^bool(sqlite3_stmt *selectPolicyName) {
ok &= SecDbBindText(selectPolicyName, 1, [policyName UTF8String], [policyName length], SQLITE_TRANSIENT, &error);
ok &= SecDbStep(dbconn, selectPolicyName, &error, ^(bool *stop) {
- secdebug("SecPinningDb", "found matching rule for %@ policy", policyName);
-
- /* Deserialize the policies and return */
- NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectPolicyName, 0) length:sqlite3_column_bytes(selectPolicyName, 0)];
- if (!xmlPolicies) { return; }
- id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil];
- if (!isNSArray(policies)) {
- return;
+ @autoreleasepool {
+ secinfo("SecPinningDb", "found matching rule for %@ policy", policyName);
+
+ /* Deserialize the policies and return */
+ NSData *xmlPolicies = [NSData dataWithBytes:sqlite3_column_blob(selectPolicyName, 0) length:sqlite3_column_bytes(selectPolicyName, 0)];
+ if (!xmlPolicies) { return; }
+ id policies = [NSPropertyListSerialization propertyListWithData:xmlPolicies options:0 format:nil error:nil];
+ if (!isNSArray(policies)) {
+ return;
+ }
+ [resultRules addObjectsFromArray:(NSArray *)policies];
}
- [resultRules addObjectsFromArray:(NSArray *)policies];
});
return ok;
});
/*
- * Copyright (c) 2008-2017 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2008-2018 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <Security/SecPolicyInternal.h>
#include <Security/SecPolicyPriv.h>
#include <Security/SecTask.h>
-#include <securityd/asynchttp.h>
#include <securityd/policytree.h>
#include <securityd/nameconstraints.h>
#include <CoreFoundation/CFTimeZone.h>
#include <Security/SecInternal.h>
#include <Security/SecKeyPriv.h>
#include <Security/SecTask.h>
-#include <CFNetwork/CFHTTPMessage.h>
-#include <CFNetwork/CFHTTPStream.h>
#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
#include <asl.h>
#include <securityd/SecTrustServer.h>
(0 == memcmp(UTN_USERFirst_Hardware_Normalized_Issuer, CFDataGetBytePtr(issuer),
UTN_USERFirst_Hardware_Normalized_Issuer_len)))
{
- #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
- CFDataRef serial = SecCertificateCopySerialNumber(cert, NULL);
- #else
- CFDataRef serial = SecCertificateCopySerialNumber(cert);
- #endif
-
+ CFDataRef serial = SecCertificateCopySerialNumberData(cert, NULL);
if (serial) {
CFIndex serial_length = CFDataGetLength(serial);
const uint8_t *serial_ptr = CFDataGetBytePtr(serial);
/* Prepare for Next Cert */
/* (a) (b) Done by SecCertificatePathVCVerifyPolicyTree */
/* (c)(d)(e)(f) Done by SecPathBuilderGetNext and SecCertificatePathVCVerify */
- //working_issuer_name = SecCertificateGetNormalizedSubjectContent(cert);
- //working_public_key = SecCertificateCopyPublicKey(cert);
- //working_public_key_parameters = SecCertificateCopyPublicKeyParameters(cert);
- //working_public_key_algorithm = SecCertificateCopyPublicKeyAlgorithm(cert);
#if POLICY_SUBTREES
/* (g) If a name constraints extension is included in the certificate, modify the permitted_subtrees and excluded_subtrees state variables.
*/
/* Wrap up */
/* (a) (b) done by SecCertificatePathVCVerifyPolicyTree */
/* (c) */
- //working_public_key = SecCertificateCopyPublicKey(cert);
/* (d) */
/* If the subjectPublicKeyInfo field of the certificate contains an algorithm field with null parameters or parameters are omitted, compare the certificate subjectPublicKey algorithm to the working_public_key_algorithm. If the certificate subjectPublicKey algorithm and the
working_public_key_algorithm are different, set the working_public_key_parameters to null. */
- //working_public_key_parameters = SecCertificateCopyPublicKeyParameters(cert);
/* (e) */
- //working_public_key_algorithm = SecCertificateCopyPublicKeyAlgorithm(cert);
/* (f) Recognize and process any other critical extension present in the certificate n. Process any other recognized non-critical extension present in certificate n that is relevant to path processing. */
if (SecCertificateHasUnknownCriticalExtension(cert)) {
/* Certificate contains one or more unknown critical extensions. */
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;
+ __block CFAbsoluteTime issuanceTime = SecPVCGetVerifyTime(pvc);
+ TA_CTFailureReason failureReason = TA_CTNoFailure;
// This eventually contain list of logs who validated the SCT.
CFMutableDictionaryRef currentLogsValidatingScts = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
__block bool at_least_one_currently_valid_external = 0;
__block bool at_least_one_currently_valid_embedded = 0;
+ __block bool unknown_log = 0;
+ __block bool disqualified_log = 0;
require(logsValidatingEmbeddedScts, out);
require(currentLogsValidatingScts, out);
+ /* Skip if there are no SCTs. */
+ require_action((embeddedScts && CFArrayGetCount(embeddedScts) > 0) ||
+ (builderScts && CFArrayGetCount(builderScts) > 0) ||
+ (ocspScts && CFArrayGetCount(ocspScts) > 0),
+ out,
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(pvc->builder);
+ if (analytics) {
+ analytics->ct_failure_reason = TA_CTNoSCTs;
+ }
+ );
+
if(trustedLogs) { // Don't bother trying to validate SCTs if we don't have any trusted logs.
if(embeddedScts && precertEntry) { // Don't bother if we could not get the precert.
CFArrayForEach(embeddedScts, ^(const void *value){
addValidatingLog(currentLogsValidatingScts, log, sct_at);
at_least_one_currently_valid_embedded = true;
trustedSCTCount++;
+ } else {
+ disqualified_log = true;
}
+ } else {
+ unknown_log = true;
}
- totalSCTSize += CFDataGetLength(value);
});
}
addValidatingLog(currentLogsValidatingScts, log, sct_at);
at_least_one_currently_valid_external = true;
trustedSCTCount++;
+ } else {
+ unknown_log = true;
}
- totalSCTSize += CFDataGetLength(value);
});
}
addValidatingLog(currentLogsValidatingScts, log, sct_at);
at_least_one_currently_valid_external = true;
trustedSCTCount++;
+ } else {
+ unknown_log = true;
}
- totalSCTSize += CFDataGetLength(value);
});
}
+ } else {
+ failureReason = TA_CTMissingLogs;
}
*/
- SecCertificatePathVCSetIsCT(SecPathBuilderGetPath(pvc->builder), false);
-
- if(at_least_one_currently_valid_external && CFDictionaryGetCount(currentLogsValidatingScts)>=2) {
- SecCertificatePathVCSetIsCT(SecPathBuilderGetPath(pvc->builder), true);
- } else if(at_least_one_currently_valid_embedded) {
- __block CFAbsoluteTime issuanceTime = SecPVCGetVerifyTime(pvc);
- __block int lifetime; // in Months
- __block unsigned once_or_current_qualified_embedded = 0;
+ bool hasValidExternalSCT = (at_least_one_currently_valid_external && CFDictionaryGetCount(currentLogsValidatingScts)>=2);
+ bool hasValidEmbeddedSCT = (at_least_one_currently_valid_embedded);
+ SecCertificatePathVCRef path = SecPathBuilderGetPath(pvc->builder);
+ SecCertificatePathVCSetIsCT(path, false);
+ if (hasValidEmbeddedSCT) {
/* Calculate issuance time based on timestamp of SCTs from current logs */
CFDictionaryForEach(currentLogsValidatingScts, ^(const void *key, const void *value) {
CFDictionaryRef log = key;
}
}
});
+ SecCertificatePathVCSetIssuanceTime(path, issuanceTime);
+ }
+ if (hasValidExternalSCT) {
+ /* Note: since external SCT validates this cert, we do not need to
+ override issuance time here. If the cert also has a valid embedded
+ SCT, issuanceTime will be calculated and set in the block above. */
+ SecCertificatePathVCSetIsCT(path, true);
+ } else if (hasValidEmbeddedSCT) {
+ __block int lifetime; // in Months
+ __block unsigned once_or_current_qualified_embedded = 0;
/* Count Logs */
+ __block bool failed_once_check = false;
CFDictionaryForEach(logsValidatingEmbeddedScts, ^(const void *key, const void *value) {
CFDictionaryRef log = key;
CFDateRef ts = value;
issuanceTime < CFDateGetAbsoluteTime(expiry)) { // at the time of issuance.)
once_or_current_qualified_embedded++;
trustedSCTCount++;
+ } else {
+ failed_once_check = true;
}
});
}
if(once_or_current_qualified_embedded >= requiredEmbeddedSctsCount){
- SecCertificatePathVCSetIsCT(SecPathBuilderGetPath(pvc->builder), true);
+ SecCertificatePathVCSetIsCT(path, true);
+ } else {
+ /* Not enough "once or currently qualified" SCTs */
+ if (failed_once_check) {
+ failureReason = TA_CTEmbeddedNotEnoughDisqualified;
+ } else if (unknown_log) {
+ failureReason = TA_CTEmbeddedNotEnoughUnknown;
+ } else {
+ failureReason = TA_CTEmbeddedNotEnough;
+ }
+ }
+ } else if (!at_least_one_currently_valid_embedded && !at_least_one_currently_valid_external) {
+ /* No currently valid SCTs */
+ if (disqualified_log) {
+ failureReason = TA_CTNoCurrentSCTsDisqualifiedLog;
+ } else if (unknown_log) {
+ failureReason = TA_CTNoCurrentSCTsUnknownLog;
+ }
+ } else if (at_least_one_currently_valid_external) {
+ /* One presented current SCT but failed total current check */
+ if (disqualified_log) {
+ failureReason = TA_CTPresentedNotEnoughDisqualified;
+ } else if (unknown_log) {
+ failureReason = TA_CTPresentedNotEnoughUnknown;
+ } else {
+ failureReason = TA_CTPresentedNotEnough;
}
}
}
/* 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;
-
+ /* Why we failed */
+ analytics->ct_failure_reason = failureReason;
+ /* Only one current SCT -- close to failure */
+ if (CFDictionaryGetCount(currentLogsValidatingScts) == 1) {
+ analytics->ct_one_current = true;
+ }
out:
CFReleaseSafe(logsValidatingEmbeddedScts);
CFReleaseSafe(currentLogsValidatingScts);
********************************************************/
void SecPVCInit(SecPVCRef pvc, SecPathBuilderRef builder, CFArrayRef policies) {
- secdebug("alloc", "%p", pvc);
+ secdebug("alloc", "pvc %p", pvc);
// Weird logging policies crashes.
//secdebug("policy", "%@", policies);
}
void SecPVCDelete(SecPVCRef pvc) {
- secdebug("alloc", "%p", pvc);
+ secdebug("alloc", "delete pvc %p", pvc);
CFReleaseNull(pvc->policies);
CFReleaseNull(pvc->details);
CFReleaseNull(pvc->leafDetails);
return false;
}
+/* ASSUMPTIONS:
+ 1. SecPVCCheckRequireCTConstraints must be called after SecPolicyCheckCT,
+ so earliest issuance time has already been obtained from SCTs.
+ 2. If the issuance time value is 0 (i.e. 2001-01-01) or earlier, we
+ assume it was not set, and thus we did not have CT info.
+*/
+static void SecPVCCheckRequireCTConstraints(SecPVCRef pvc) {
+ SecCertificatePathVCRef path = (pvc) ? SecPathBuilderGetPath(pvc->builder) : NULL;
+ if (!path) {
+ return;
+ }
+ /* If we are evaluating for a SSL server authentication policy, make sure
+ SCT issuance time is prior to the earliest not-after date constraint.
+ Note that CT will already be required if there is a not-after date
+ constraint present (set in SecRVCProcessValidDateConstraints).
+ */
+ if (SecPVCIsSSLServerAuthenticationPolicy(pvc)) {
+ CFIndex ix, certCount = SecCertificatePathVCGetCount(path);
+ SecCertificateRef certificate = SecPathBuilderGetCertificateAtIndex(pvc->builder, 0);
+ CFAbsoluteTime earliestNotAfter = 31556908800.0; /* default: 3001-01-01 00:00:00-0000 */
+ CFAbsoluteTime issuanceTime = SecCertificatePathVCIssuanceTime(path);
+ if (issuanceTime <= 0) {
+ /* if not set (or prior to 2001-01-01), use leaf's not-before time. */
+ issuanceTime = SecCertificateNotValidBefore(certificate);
+ }
+ for (ix = 0; ix < certCount; ix++) {
+ SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, ix);
+ if (!rvc || !rvc->valid_info || !rvc->valid_info->hasDateConstraints || !rvc->valid_info->notAfterDate) {
+ continue;
+ }
+ /* Found CA certificate with a not-after date constraint. */
+ CFAbsoluteTime caNotAfter = CFDateGetAbsoluteTime(rvc->valid_info->notAfterDate);
+ if (caNotAfter < earliestNotAfter) {
+ earliestNotAfter = caNotAfter;
+ }
+ if (issuanceTime > earliestNotAfter) {
+ /* Issuance time violates the not-after date constraint. */
+ secnotice("rvc", "certificate issuance time (%f) is later than allowed value (%f)",
+ issuanceTime, earliestNotAfter);
+ SecRVCSetValidDeterminedErrorResult(rvc);
+ break;
+ }
+ }
+ }
+ /* If path is CT validated, nothing further to do here. */
+ if (SecCertificatePathVCIsCT(path)) {
+ return;
+ }
+
+ /* Path is not CT validated, so check if CT was required. */
+ SecPathCTPolicy ctp = SecCertificatePathVCRequiresCT(path);
+ if (ctp <= kSecPathCTNotRequired || !SecPVCIsSSLServerAuthenticationPolicy(pvc)) {
+ return;
+ }
+ /* 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;
+ }
+}
+
/* AUDIT[securityd](done):
policy->_options is a caller provided dictionary, only its cf type has
been checked.
}
/* Check that this path meets CT constraints. */
- if (!SecCertificatePathVCIsCT(path)) {
- SecPathCTPolicy ctp = SecCertificatePathVCRequiresCT(path);
- if (ctp > kSecPathCTNotRequired && SecPVCIsSSLServerAuthenticationPolicy(pvc)) {
- /* 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;
- }
- }
- }
+ SecPVCCheckRequireCTConstraints(pvc);
+
+ /* Check that this path meets known-intermediate constraints. */
+ SecPathBuilderCheckKnownIntermediateConstraints(pvc->builder);
secdebug("policy", "end %strusted path: %@",
(SecPVCIsOkResult(pvc) ? "" : "not "), SecPathBuilderGetPath(pvc->builder));
}
/* Do we have a definitive Valid revocation result for this cert? */
if (SecRVCHasDefinitiveValidInfo(rvc) && SecRVCHasRevokedValidInfo(rvc)) {
- SecRVCSetRevokedResult(rvc);
+ SecRVCSetValidDeterminedErrorResult(rvc);
}
}
}
*/
#include <securityd/SecRevocationDb.h>
-#include <securityd/asynchttp.h>
#include <securityd/OTATrustUtilities.h>
#include <securityd/SecRevocationNetworking.h>
#include <securityd/SecTrustLoggingServer.h>
#include <Security/SecPolicyPriv.h>
#include <AssertMacros.h>
#include <stdlib.h>
+#include <stdatomic.h>
#include <limits.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <dispatch/dispatch.h>
+#include <notify.h>
#include <asl.h>
#include <copyfile.h>
#include "utilities/debugging.h"
#include <xpc/private.h>
#include <os/transaction_private.h>
#include <os/variant_private.h>
+#include <os/lock.h>
#include <CFNetwork/CFHTTPMessage.h>
#include <CoreFoundation/CFURL.h>
#include <CoreFoundation/CFUtilities.h>
-static CFStringRef kValidUpdateProdServer = CFSTR("valid.apple.com");
-static CFStringRef kValidUpdateCarryServer = CFSTR("valid.apple.com/carry");
+const CFStringRef kValidUpdateProdServer = CFSTR("valid.apple.com");
+const CFStringRef kValidUpdateCarryServer = CFSTR("valid.apple.com/carry");
static CFStringRef kSecPrefsDomain = CFSTR("com.apple.security");
static CFStringRef kUpdateServerKey = CFSTR("ValidUpdateServer");
kSecValidInfoDateConstraints = 1u << 7,
kSecValidInfoNameConstraints = 1u << 8,
kSecValidInfoPolicyConstraints = 1u << 9,
+ kSecValidInfoNoCAv2Check = 1u << 10,
};
/* minimum update interval */
#define isDbOwner SecOTAPKIIsSystemTrustd
+#define kSecRevocationDbChanged "com.apple.trustd.valid.db-changed"
+
/* 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
+ v6 = explicitly set autovacuum and journal modes at db creation
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 5 /* current version we support */
-#define kSecRevocationDbMinSchemaVersion 5 /* minimum version we can use */
+#define kSecRevocationDbSchemaVersion 6 /* current version we support */
+#define kSecRevocationDbMinSchemaVersion 6 /* minimum version we can use */
/* update file format
*/
#define kSecRevocationDbUpdateFormat 3 /* current version we support */
#define kSecRevocationDbMinUpdateFormat 2 /* minimum version we can use */
+#define kSecRevocationDbCacheSize 100
+
+typedef struct __SecRevocationDb *SecRevocationDbRef;
+struct __SecRevocationDb {
+ SecDbRef db;
+ dispatch_queue_t update_queue;
+ bool updateInProgress;
+ bool unsupportedVersion;
+ bool changed;
+ CFMutableArrayRef info_cache_list;
+ CFMutableDictionaryRef info_cache;
+ os_unfair_lock info_cache_lock;
+};
+
+typedef struct __SecRevocationDbConnection *SecRevocationDbConnectionRef;
+struct __SecRevocationDbConnection {
+ SecRevocationDbRef db;
+ SecDbConnectionRef dbconn;
+ CFIndex precommitVersion;
+ CFIndex precommitDbVersion;
+ bool fullUpdate;
+};
+
bool SecRevocationDbVerifyUpdate(void *update, CFIndex length);
-CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion);
-void SecRevocationDbApplyUpdate(CFDictionaryRef update, CFIndex version);
+bool SecRevocationDbIngestUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex chunkVersion, CFIndex *outVersion, CFErrorRef *error);
+bool _SecRevocationDbApplyUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex version, CFErrorRef *error);
CFAbsoluteTime SecRevocationDbComputeNextUpdateTime(CFIndex updateInterval);
-bool SecRevocationDbSetVersion(CFIndex version);
-bool SecRevocationDbSetSchemaVersion(CFIndex dbversion);
-bool SecRevocationDbUpdateSchema(void);
+bool SecRevocationDbUpdateSchema(SecRevocationDbRef rdb);
CFIndex SecRevocationDbGetUpdateFormat(void);
-void SecRevocationDbSetUpdateFormat(CFIndex dbformat);
-void SecRevocationDbSetUpdateSource(CFStringRef source);
+bool _SecRevocationDbSetUpdateSource(SecRevocationDbConnectionRef dbc, CFStringRef source, CFErrorRef *error);
+bool SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef source);
CFStringRef SecRevocationDbCopyUpdateSource(void);
-void SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate);
+bool SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate, CFErrorRef *error);
CFAbsoluteTime SecRevocationDbGetNextUpdateTime(void);
dispatch_queue_t SecRevocationDbGetUpdateQueue(void);
-void SecRevocationDbRemoveAllEntries(void);
+bool _SecRevocationDbRemoveAllEntries(SecRevocationDbConnectionRef dbc, CFErrorRef *error);
void SecRevocationDbReleaseAllConnections(void);
+static void SecRevocationDbWith(void(^dbJob)(SecRevocationDbRef db));
+static bool SecRevocationDbPerformWrite(SecRevocationDbRef rdb, CFErrorRef *error, bool(^writeJob)(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError));
+static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbConnectionRef dbc, int64_t groupId, SecValidInfoFlags *flags, CFDataRef *data, CFErrorRef *error);
+static bool _SecRevocationDbSetVersion(SecRevocationDbConnectionRef dbc, CFIndex version, CFErrorRef *error);
+static int64_t _SecRevocationDbGetVersion(SecRevocationDbConnectionRef dbc, CFErrorRef *error);
+static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, SecRevocationDbConnectionRef dbc, CFErrorRef *error);
+static void SecRevocationDbResetCaches(void);
+static SecRevocationDbConnectionRef SecRevocationDbConnectionInit(SecRevocationDbRef db, SecDbConnectionRef dbconn, CFErrorRef *error);
static CFDataRef copyInflatedData(CFDataRef data) {
return (CFDataRef)outData;
}
-static CFDataRef copyInflatedDataToFile(CFDataRef data, char *fileName) {
- if (!data) {
- return NULL;
- }
- z_stream zs;
- memset(&zs, 0, sizeof(zs));
- /* 32 is a magic value which enables automatic header detection
- of gzip or zlib compressed data. */
- if (inflateInit2(&zs, 32+MAX_WBITS) != Z_OK) {
- return NULL;
- }
- zs.next_in = (UInt8 *)(CFDataGetBytePtr(data));
- zs.avail_in = (uInt)CFDataGetLength(data);
-
- (void)remove(fileName); /* We need an empty file to start */
- int fd;
- off_t off;
- fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0644);
- if (fd < 0 || (off = lseek(fd, 0, SEEK_SET)) < 0) {
- secerror("unable to open %s (errno %d)", fileName, errno);
- if (fd >= 0) {
- close(fd);
- }
- return NULL;
- }
-
- CFIndex buf_sz = malloc_good_size(zs.avail_in ? zs.avail_in : 1024 * 4);
- unsigned char *buf = malloc(buf_sz);
- int rc;
- do {
- zs.next_out = (Bytef*)buf;
- zs.avail_out = (uInt)buf_sz;
- rc = inflate(&zs, 0);
- if (off < (int64_t)zs.total_out) {
- off = write(fd, buf, (size_t)zs.total_out - (size_t)off);
- }
- } while (rc == Z_OK);
- close(fd);
-
- inflateEnd(&zs);
-
- if (buf) {
- free(buf);
- }
- if (rc != Z_STREAM_END) {
- (void)remove(fileName);
- return NULL;
- }
-
- /* Now return an mmapped version of that data */
- CFDataRef outData = NULL;
- if ((rc = readValidFile(fileName, &outData)) != 0) {
- secerror("unable to read and map %s (errno %d)", fileName, rc);
- CFReleaseNull(outData);
- }
- return outData;
-}
-
static CFDataRef copyDeflatedData(CFDataRef data) {
if (!data) {
return NULL;
return rtn;
}
-static void unmapData(CFDataRef CF_CONSUMED data) {
- if (data) {
- int rtn = munmap((void *)CFDataGetBytePtr(data), CFDataGetLength(data));
- if (rtn != 0) {
- secerror("unable to unmap %ld bytes at %p (error %d)", CFDataGetLength(data), CFDataGetBytePtr(data), rtn);
- }
-
- }
- CFReleaseNull(data);
-}
-
static bool removeFileWithSuffix(const char *basepath, const char *suffix) {
bool result = false;
char *path = NULL;
return result;
}
+static CFDataRef CF_RETURNS_RETAINED cfToHexData(CFDataRef data, bool prependWildcard) {
+ if (!isData(data)) { return NULL; }
+ CFIndex len = CFDataGetLength(data) * 2;
+ CFMutableStringRef hex = CFStringCreateMutable(NULL, len+1);
+ static const char* digits[]={
+ "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
+ if (prependWildcard) {
+ CFStringAppendCString(hex, "%", 1);
+ }
+ const uint8_t* p = CFDataGetBytePtr(data);
+ for (CFIndex i = 0; i < CFDataGetLength(data); i++) {
+ CFStringAppendCString(hex, digits[p[i] >> 4], 1);
+ CFStringAppendCString(hex, digits[p[i] & 0xf], 1);
+ }
+ CFDataRef result = CFStringCreateExternalRepresentation(NULL, hex, kCFStringEncodingUTF8, 0);
+ CFReleaseSafe(hex);
+ return result;
+}
+
// MARK: -
// MARK: SecValidUpdate
Note: the difference between g2 and g3 format is the addition of the 4-byte count in (2a).
*/
-static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) {
+static bool SecValidUpdateProcessData(SecRevocationDbConnectionRef dbc, CFIndex format, CFDataRef updateData, CFErrorRef *error) {
+ bool result = false;
if (!updateData || format < 2) {
- return false;
+ SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: invalid update format"));
+ return result;
}
- bool result = false;
CFIndex version = 0;
CFIndex interval = 0;
const UInt8* p = CFDataGetBytePtr(updateData);
/* make sure there is enough data to contain length and count */
if (bytesRemaining < ((CFIndex)sizeof(uint32_t) * 2)) {
secinfo("validupdate", "Skipping property list creation (length %ld is too short)", (long)bytesRemaining);
+ SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: data length is too short"));
return result;
}
/* get length of signed data */
if (dataLength > bytesRemaining) {
secinfo("validupdate", "Skipping property list creation (dataLength=%ld, bytesRemaining=%ld)",
(long)dataLength, (long)bytesRemaining);
+ SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: data longer than expected"));
return result;
}
/* process each chunked plist */
+ bool ok = true;
+ CFErrorRef localError = NULL;
uint32_t plistProcessed = 0;
while (plistCount > 0 && bytesRemaining > 0) {
CFPropertyListRef propertyList = NULL;
--plistCount;
++plistProcessed;
- /* We're about to use a lot of memory for the plist -- go active so we don't get jetsammed */
- os_transaction_t transaction;
- transaction = os_transaction_create("com.apple.trustd.valid");
-
if (plistLength <= bytesRemaining) {
CFDataRef data = CFDataCreateWithBytesNoCopy(NULL, p, plistLength, kCFAllocatorNull);
propertyList = CFPropertyListCreateWithData(NULL, data, kCFPropertyListImmutable, NULL, NULL);
if (isDictionary(propertyList)) {
secdebug("validupdate", "Ingesting plist chunk %u of %u, length: %u",
plistProcessed, plistTotal, plistLength);
- CFIndex curVersion = SecRevocationDbIngestUpdate((CFDictionaryRef)propertyList, version);
+ CFIndex curVersion = -1;
+ ok = ok && SecRevocationDbIngestUpdate(dbc, (CFDictionaryRef)propertyList, version, &curVersion, &localError);
if (plistProcessed == 1) {
- version = curVersion;
+ dbc->precommitVersion = version = curVersion;
// get server-provided interval
CFTypeRef value = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)propertyList,
CFSTR("check-again"));
CFNumberGetValue((CFNumberRef)value, kCFNumberCFIndexType, &interval);
}
}
- if (curVersion < 0) {
+ if (ok && curVersion < 0) {
plistCount = 0; // we already had this version; skip remaining plists
result = true;
}
} else {
secinfo("validupdate", "Failed to deserialize update chunk %u of %u",
plistProcessed, plistTotal);
+ SecError(errSecParam, error, CFSTR("SecValidUpdateProcessData: failed to get update chunk"));
if (plistProcessed == 1) {
gNextUpdate = SecRevocationDbComputeNextUpdateTime(0);
}
}
/* All finished with this property list */
CFReleaseSafe(propertyList);
- os_release(transaction);
bytesRemaining -= plistLength;
p += plistLength;
}
- if (version > 0) {
+ if (ok && version > 0) {
secdebug("validupdate", "Update received: v%ld", (long)version);
gLastVersion = version;
gNextUpdate = SecRevocationDbComputeNextUpdateTime(interval);
result = true;
}
- // remember next update time in case of restart
- SecRevocationDbSetNextUpdateTime(gNextUpdate);
-
+ (void) CFErrorPropagate(localError, error);
return result;
}
return;
}
/* Verify CMS signature on signed data */
- if (SecRevocationDbVerifyUpdate((void *)CFDataGetBytePtr(updateData), CFDataGetLength(updateData))) {
- CFStringRef dbSource = SecRevocationDbCopyUpdateSource();
- if (dbSource && updateServer && (kCFCompareEqualTo != CFStringCompare(dbSource, updateServer,
- kCFCompareCaseInsensitive))) {
- secnotice("validupdate", "switching db source from \"%@\" to \"%@\"", dbSource, updateServer);
- }
- CFReleaseNull(dbSource);
- if (fullUpdate) {
- /* Must completely replace existing database contents */
- SecRevocationDbRemoveAllEntries();
- SecRevocationDbSetUpdateSource(updateServer);
- }
- bool result = SecValidUpdateProcessData(kSecValidUpdateFormatG3, updateData);
- if (!result) {
- // Try g2 update format as a fallback if we failed to read g3
- result = SecValidUpdateProcessData(kSecValidUpdateFormatG2, updateData);
- }
- if (!result) {
- secerror("failed to process valid update");
- TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecDecode);
- } else {
- TrustdHealthAnalyticsLogSuccess(TAEventValidUpdate);
- }
- } else {
+ if (!SecRevocationDbVerifyUpdate((void *)CFDataGetBytePtr(updateData), CFDataGetLength(updateData))) {
secerror("failed to verify valid update");
TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecVerifyFailed);
+ return;
}
-}
+ /* Read current update source from database. */
+ CFStringRef dbSource = SecRevocationDbCopyUpdateSource();
+ if (dbSource && updateServer && (kCFCompareEqualTo != CFStringCompare(dbSource, updateServer,
+ kCFCompareCaseInsensitive))) {
+ secnotice("validupdate", "switching db source from \"%@\" to \"%@\"", dbSource, updateServer);
+ }
+ CFReleaseNull(dbSource);
-static bool SecValidDatabaseFromCompressed(CFDataRef CF_CONSUMED data) {
- if (!data) { return false; }
+ /* Ingest the update. This is now performed under a single immediate write transaction,
+ so other writers are blocked (but not other readers), and the changes can be rolled back
+ in their entirety if any error occurs. */
+ __block bool ok = true;
+ __block CFErrorRef localError = NULL;
+ __block SecRevocationDbConnectionRef dbc = NULL;
+ SecRevocationDbWith(^(SecRevocationDbRef rdb) {
+ ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ if (fullUpdate) {
+ /* Must completely replace existing database contents */
+ secdebug("validupdate", "starting to process full update; clearing database");
+ ok = ok && _SecRevocationDbRemoveAllEntries(dbc,blockError);
+ ok = ok && _SecRevocationDbSetUpdateSource(dbc, updateServer, blockError);
+ if (dbc) {
+ dbc->precommitVersion = 0;
+ dbc->fullUpdate = true;
+ }
+ }
+ ok = ok && SecValidUpdateProcessData(dbc, kSecValidUpdateFormatG3, updateData, blockError);
+ if (!ok) {
+ secerror("failed to process valid update: %@", blockError ? *blockError : NULL);
+ TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecDecode);
+ } else {
+ TrustdHealthAnalyticsLogSuccess(TAEventValidUpdate);
+ }
+ return ok;
+ });
+ if (rdb->changed) {
+ rdb->changed = false;
+ /* signal other trustd instances that the database has been updated */
+ notify_post(kSecRevocationDbChanged);
+ }
+ });
- secdebug("validupdate", "read %ld bytes from file", (long)CFDataGetLength(data));
+ /* remember next update time in case of restart (separate write transaction) */
+ (void) SecRevocationDbSetNextUpdateTime(gNextUpdate, NULL);
- /* 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");
+ if (dbc) {
+ free(dbc);
+ }
+ CFReleaseSafe(localError);
+}
- /* Expand the database */
- __block CFDataRef inflatedData = NULL;
- WithPathInRevocationInfoDirectory(CFSTR(kSecRevocationDbFileName), ^(const char *dbPath) {
- inflatedData = copyInflatedDataToFile(data, (char *)dbPath);
- secdebug("validupdate", "data expanded: %ld bytes", (long)CFDataGetLength(inflatedData));
- });
- unmapData(data);
- os_release(transaction);
+static bool SecValidUpdateForceReplaceDatabase(void) {
+ bool result = false;
- if (inflatedData) {
- unmapData(inflatedData);
+ // write semaphore file that we will pick up when we next launch
+ char *semPathBuf = NULL;
+ asprintf(&semPathBuf, "%s/%s", kSecRevocationBasePath, kSecRevocationDbReplaceFile);
+ if (semPathBuf) {
+ struct stat sb;
+ int fd = open(semPathBuf, O_WRONLY | O_CREAT, DEFFILEMODE);
+ if (fd == -1 || fstat(fd, &sb)) {
+ secnotice("validupdate", "unable to write %s", semPathBuf);
+ } else {
+ result = true;
+ }
+ if (fd >= 0) {
+ close(fd);
+ }
+ free(semPathBuf);
+ }
+ if (result) {
+ // exit as gracefully as possible so we can replace the database
+ secnotice("validupdate", "process exiting to replace db file");
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ xpc_transaction_exit_clean();
+ });
}
- return true;
+ return result;
}
static bool SecValidUpdateSatisfiedLocally(CFStringRef server, CFIndex version, bool safeToReplace) {
__block bool result = false;
- CFDataRef data = NULL;
SecOTAPKIRef otapkiRef = NULL;
bool relaunching = false;
- int rtn = 0;
static int sNumLocalUpdates = 0;
// if we've replaced the database with a local asset twice in a row,
// replace database only if safe to do so (i.e. called at startup)
if (!safeToReplace) {
- // write semaphore file that we will pick up when we next launch
- char *semPathBuf = NULL;
- asprintf(&semPathBuf, "%s/%s", kSecRevocationBasePath, kSecRevocationDbReplaceFile);
- if (semPathBuf) {
- struct stat sb;
- int fd = open(semPathBuf, O_WRONLY | O_CREAT, DEFFILEMODE);
- if (fd == -1 || fstat(fd, &sb)) {
- secnotice("validupdate", "unable to write %s", semPathBuf);
- } else {
- relaunching = true;
- }
- if (fd >= 0) {
- close(fd);
- }
- free(semPathBuf);
- }
- if (relaunching) {
- // exit as gracefully as possible so we can replace the database
- secnotice("validupdate", "process exiting to replace db file");
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- xpc_transaction_exit_clean();
- });
- }
+ relaunching = SecValidUpdateForceReplaceDatabase();
goto updateExit;
}
}
});
}
- if (result) {
- goto updateExit;
- }
-
- // see if compressed database asset is available
- if (validDbPathBuf) {
- char *validDbCmpPathBuf = NULL;
- asprintf(&validDbCmpPathBuf, "%s%s", validDbPathBuf, ".gz");
- if (validDbCmpPathBuf) {
- secdebug("validupdate", "will read data from \"%s\"", validDbCmpPathBuf);
- if ((rtn = readValidFile(validDbCmpPathBuf, &data)) != 0) {
- unmapData(data);
- data = NULL;
- secnotice("validupdate", "readValidFile error %d", rtn);
- }
- free(validDbCmpPathBuf);
- }
- }
- result = SecValidDatabaseFromCompressed(data);
updateExit:
CFReleaseNull(otapkiRef);
if (result) {
sNumLocalUpdates++;
gLastVersion = SecRevocationDbGetVersion();
- SecRevocationDbSetUpdateSource(server);
- SecRevocationDbUpdateSchema();
+ // note: snapshot should already have latest schema and production source,
+ // but set it here anyway so we don't keep trying to replace the db.
+ SecRevocationDbWith(^(SecRevocationDbRef db) {
+ (void)SecRevocationDbSetUpdateSource(db, server);
+ (void)SecRevocationDbUpdateSchema(db);
+ });
gUpdateStarted = 0;
secdebug("validupdate", "local update to g%ld/v%ld complete at %f",
(long)SecRevocationDbGetUpdateFormat(), (long)gLastVersion,
void SecRevocationDbInitialize() {
if (!isDbOwner()) { return; }
+ os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.initialize");
__block bool initializeDb = false;
/* create base path if it doesn't exist */
});
if (!initializeDb) {
+ os_release(transaction);
return; /* database exists and doesn't need replacing */
}
#endif
}
CFReleaseSafe(value);
+ os_release(transaction);
}
======================================================================
*/
+CFGiblisWithCompareFor(SecValidInfo);
+
static SecValidInfoRef SecValidInfoCreate(SecValidInfoFormat format,
CFOptionFlags flags,
bool isOnList,
CFDataRef nameConstraints,
CFDataRef policyConstraints) {
SecValidInfoRef validInfo;
- validInfo = (SecValidInfoRef)calloc(1, sizeof(struct __SecValidInfo));
+ validInfo = CFTypeAllocate(SecValidInfo, struct __SecValidInfo, kCFAllocatorDefault);
if (!validInfo) { return NULL; }
CFRetainSafe(certHash);
validInfo->checkOCSP = (flags & kSecValidInfoCheckOCSP);
validInfo->knownOnly = (flags & kSecValidInfoKnownOnly);
validInfo->requireCT = (flags & kSecValidInfoRequireCT);
- validInfo->noCACheck = (flags & kSecValidInfoNoCACheck);
+ validInfo->noCACheck = (flags & kSecValidInfoNoCAv2Check);
validInfo->overridable = (flags & kSecValidInfoOverridable);
validInfo->hasDateConstraints = (flags & kSecValidInfoDateConstraints);
validInfo->hasNameConstraints = (flags & kSecValidInfoNameConstraints);
return validInfo;
}
-void SecValidInfoRelease(SecValidInfoRef validInfo) {
+static void SecValidInfoDestroy(CFTypeRef cf) {
+ SecValidInfoRef validInfo = (SecValidInfoRef)cf;
if (validInfo) {
CFReleaseNull(validInfo->certHash);
CFReleaseNull(validInfo->issuerHash);
CFReleaseNull(validInfo->notAfterDate);
CFReleaseNull(validInfo->nameConstraints);
CFReleaseNull(validInfo->policyConstraints);
- free(validInfo);
}
}
validInfo->anchorHash = anchorHash;
}
+static Boolean SecValidInfoCompare(CFTypeRef a, CFTypeRef b) {
+ SecValidInfoRef validInfoA = (SecValidInfoRef)a;
+ SecValidInfoRef validInfoB = (SecValidInfoRef)b;
+ if (validInfoA == validInfoB) {
+ return true;
+ }
+ if (!validInfoA || !validInfoB ||
+ (CFGetTypeID(a) != SecValidInfoGetTypeID()) ||
+ (CFGetTypeID(b) != SecValidInfoGetTypeID())) {
+ return false;
+ }
+ return CFEqualSafe(validInfoA->certHash, validInfoB->certHash) && CFEqualSafe(validInfoA->issuerHash, validInfoB->issuerHash);
+}
+
+static CFStringRef SecValidInfoCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
+ SecValidInfoRef validInfo = (SecValidInfoRef)cf;
+ CFStringRef certHash = CFDataCopyHexString(validInfo->certHash);
+ CFStringRef issuerHash = CFDataCopyHexString(validInfo->issuerHash);
+ CFStringRef desc = CFStringCreateWithFormat(NULL, formatOptions, CFSTR("validInfo certHash: %@ issuerHash: %@"), certHash, issuerHash);
+ CFReleaseNull(certHash);
+ CFReleaseNull(issuerHash);
+ return desc;
+}
+
// MARK: -
// MARK: SecRevocationDb
dispatch_queue_t update_queue = SecRevocationDbGetUpdateQueue();
action = sec_action_create_with_queue(update_queue, "update_check", kSecMinUpdateInterval);
sec_action_set_handler(action, ^{
+ os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.checkNextUpdate");
(void)_SecRevocationDbCheckNextUpdate();
+ os_release(transaction);
});
});
sec_action_perform(action);
void SecRevocationDbComputeAndSetNextUpdateTime(void) {
gNextUpdate = SecRevocationDbComputeNextUpdateTime(0);
- SecRevocationDbSetNextUpdateTime(gNextUpdate);
+ (void) SecRevocationDbSetNextUpdateTime(gNextUpdate, NULL);
gUpdateStarted = 0; /* no update is currently in progress */
}
-CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion) {
+bool SecRevocationDbIngestUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex chunkVersion, CFIndex *outVersion, CFErrorRef *error) {
+ bool ok = false;
CFIndex version = 0;
+ CFErrorRef localError = NULL;
if (!update) {
- return version;
+ SecError(errSecParam, &localError, CFSTR("SecRevocationDbIngestUpdate: invalid update parameter"));
+ goto setVersionAndExit;
}
CFTypeRef value = (CFNumberRef)CFDictionaryGetValue(update, CFSTR("version"));
if (isNumber(value)) {
// subsequent chunks will need to pass it in chunkVersion.
version = chunkVersion;
}
- CFIndex curVersion = SecRevocationDbGetVersion();
+ // check precommitted version since update hasn't been committed yet
+ CFIndex curVersion = dbc->precommitVersion;
if (version > curVersion || chunkVersion > 0) {
- SecRevocationDbApplyUpdate(update, version);
+ ok = _SecRevocationDbApplyUpdate(dbc, update, version, &localError);
+ secdebug("validupdate", "_SecRevocationDbApplyUpdate=%s, v%ld, precommit=%ld, full=%s",
+ (ok) ? "1" : "0", (long)version, (long)dbc->precommitVersion,
+ (dbc->fullUpdate) ? "1" : "0");
} else {
secdebug("validupdate", "we have v%ld, skipping update to v%ld",
(long)curVersion, (long)version);
version = -1; // invalid, so we know to skip subsequent chunks
+ ok = true; // this is not an error condition
}
- return version;
+setVersionAndExit:
+ if (outVersion) {
+ *outVersion = version;
+ }
+ (void) CFErrorPropagate(localError, error);
+ return ok;
}
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
+ kSecValidInfoNoCACheck (0x00000020) set if this entry does not require an OCSP check to accept (deprecated)
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
+ kSecValidInfoNoCAv2Check (0x00000400) set if this entry does not require an OCSP check to accept
format (integer) // an integer describing format of entries:
kSecValidInfoFormatUnknown (0) unknown format
kSecValidInfoFormatSerial (1) serial number, not greater than 20 bytes in length
"(groupid,flags,format,data) VALUES (?,?,?,?)")
#define insertSerialRecordSQL CFSTR("INSERT OR REPLACE INTO serials " \
"(groupid,serial) VALUES (?,?)")
-#define insertDateRecordSQL CFSTR("INSERT OR REPLACE INTO dates " \
- "(groupid,notbefore,notafter) VALUES (?,?,?)")
+#define deleteSerialRecordSQL CFSTR("DELETE FROM serials " \
+ "WHERE groupid=? AND hex(serial) LIKE ?")
#define insertSha256RecordSQL CFSTR("INSERT OR REPLACE INTO hashes " \
"(groupid,sha256) VALUES (?,?)")
-#define deleteGroupRecordSQL CFSTR("DELETE FROM groups WHERE groupid=?")
+#define deleteSha256RecordSQL CFSTR("DELETE FROM hashes " \
+ "WHERE groupid=? AND hex(sha256) LIKE ?")
+#define insertDateRecordSQL CFSTR("INSERT OR REPLACE INTO dates " \
+ "(groupid,notbefore,notafter) VALUES (?,?,?)")
+#define deleteGroupRecordSQL CFSTR("DELETE FROM groups " \
+ "WHERE groupid=?")
+#define deleteGroupIssuersSQL CFSTR("DELETE FROM issuers " \
+ "WHERE groupid=?")
#define updateConstraintsTablesSQL CFSTR("" \
"CREATE TABLE IF NOT EXISTS dates(" \
"DELETE FROM admin WHERE key='version'; " \
"DELETE FROM sqlite_sequence")
+
/* Database management */
static SecDbRef SecRevocationDbCreate(CFStringRef path) {
/* only the db owner should open a read-write connection. */
- bool readWrite = isDbOwner();
+ __block bool readWrite = isDbOwner();
mode_t mode = 0644;
- SecDbRef result = SecDbCreateWithOptions(path, mode, readWrite, false, false, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) {
+ SecDbRef result = SecDbCreate(path, mode, readWrite, false, true, true, 1, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) {
__block bool ok = true;
- CFErrorRef localError = NULL;
- if (ok && !SecDbWithSQL(dbconn, selectGroupIdSQL, &localError, NULL) && CFErrorGetCode(localError) == SQLITE_ERROR) {
- /* SecDbWithSQL returns SQLITE_ERROR if the table we are preparing the above statement for doesn't exist. */
-
- /* Create all database tables, indexes, and triggers. */
+ if (readWrite) {
ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, error, ^(bool *commit) {
- ok = SecDbExec(dbconn, createTablesSQL, error);
+ /* Create all database tables, indexes, and triggers.
+ * SecDbOpen will set auto_vacuum and journal_mode for us before we get called back.*/
+ ok = ok && SecDbExec(dbconn, createTablesSQL, error);
*commit = ok;
});
}
- if (!ok || localError) {
+ if (!ok || (error && *error)) {
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;
});
return result;
}
-typedef struct __SecRevocationDb *SecRevocationDbRef;
-struct __SecRevocationDb {
- SecDbRef db;
- dispatch_queue_t update_queue;
- bool updateInProgress;
- bool unsupportedVersion;
-};
-
static dispatch_once_t kSecRevocationDbOnce;
static SecRevocationDbRef kSecRevocationDb = NULL;
rdb->update_queue = NULL;
rdb->updateInProgress = false;
rdb->unsupportedVersion = false;
+ rdb->changed = false;
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);
+ require(rdb->info_cache_list = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks), errOut);
+ require(rdb->info_cache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
+ rdb->info_cache_lock = OS_UNFAIR_LOCK_INIT;
+ if (!isDbOwner()) {
+ /* register for changes signaled by the db owner instance */
+ int out_token = 0;
+ notify_register_dispatch(kSecRevocationDbChanged, &out_token, rdb->update_queue, ^(int __unused token) {
+ secnotice("validupdate", "Got notification of database change");
+ SecRevocationDbResetCaches();
+ });
+ }
return rdb;
errOut:
if (dbPath) {
kSecRevocationDb = SecRevocationDbInit(dbPath);
CFRelease(dbPath);
+ if (kSecRevocationDb && isDbOwner()) {
+ /* check and update schema immediately after database is opened */
+ SecRevocationDbUpdateSchema(kSecRevocationDb);
+ }
}
});
// Do pre job run work here (cancel idle timers etc.)
// Do post job run work here (gc timer, etc.)
}
-static int64_t _SecRevocationDbGetVersion(SecRevocationDbRef rdb, CFErrorRef *error) {
- /* look up version entry in admin table; returns -1 on error */
- __block int64_t version = -1;
+static bool SecRevocationDbPerformWrite(SecRevocationDbRef rdb, CFErrorRef *error,
+ bool(^writeJob)(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError)) {
__block bool ok = true;
__block CFErrorRef localError = NULL;
+ ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
+ ok &= SecDbTransaction(dbconn, kSecDbImmediateTransactionType, &localError, ^(bool *commit) {
+ SecRevocationDbConnectionRef dbc = SecRevocationDbConnectionInit(rdb, dbconn, &localError);
+ ok = ok && writeJob(dbc, &localError);
+ *commit = ok;
+ free(dbc);
+ });
+ });
+ ok &= CFErrorPropagate(localError, error);
+ return ok;
+}
+
+static bool SecRevocationDbPerformRead(SecRevocationDbRef rdb, CFErrorRef *error,
+ bool(^readJob)(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError)) {
+ __block CFErrorRef localError = NULL;
+ __block bool ok = true;
+
ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- 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;
+ SecRevocationDbConnectionRef dbc = SecRevocationDbConnectionInit(rdb, dbconn, &localError);
+ ok = ok && readJob(dbc, &localError);
+ free(dbc);
+ });
+ ok &= CFErrorPropagate(localError, error);
+ return ok;
+}
+
+static SecRevocationDbConnectionRef SecRevocationDbConnectionInit(SecRevocationDbRef db, SecDbConnectionRef dbconn, CFErrorRef *error) {
+ SecRevocationDbConnectionRef dbc = NULL;
+ CFErrorRef localError = NULL;
+
+ dbc = (SecRevocationDbConnectionRef)malloc(sizeof(struct __SecRevocationDbConnection));
+ if (dbc) {
+ dbc->db = db;
+ dbc->dbconn = dbconn;
+ dbc->precommitVersion = _SecRevocationDbGetVersion(dbc, &localError);
+ dbc->precommitDbVersion = _SecRevocationDbGetSchemaVersion(db, dbc, &localError);
+ dbc->fullUpdate = false;
+ }
+ (void) CFErrorPropagate(localError, error);
+ return dbc;
+}
+
+static CF_RETURNS_RETAINED CFDataRef createCacheKey(CFDataRef certHash, CFDataRef issuerHash) {
+ CFMutableDataRef concat = CFDataCreateMutableCopy(NULL, 0, certHash);
+ CFDataAppend(concat, issuerHash);
+ CFDataRef result = SecSHA256DigestCreateFromData(NULL, concat);
+ CFReleaseNull(concat);
+ return result;
+}
+
+static CF_RETURNS_RETAINED SecValidInfoRef SecRevocationDbCacheRead(SecRevocationDbRef db,
+ SecCertificateRef certificate,
+ CFDataRef issuerHash) {
+ if (!db) {
+ return NULL;
+ }
+ SecValidInfoRef result = NULL;
+ if (!db || !db->info_cache || !db->info_cache_list) {
+ return result;
+ }
+ CFIndex ix = kCFNotFound;
+ CFDataRef certHash = SecCertificateCopySHA256Digest(certificate);
+ CFDataRef cacheKey = createCacheKey(certHash, issuerHash);
+
+ os_unfair_lock_lock(&db->info_cache_lock); // grab the cache lock before using the cache
+ if (0 <= (ix = CFArrayGetFirstIndexOfValue(db->info_cache_list,
+ CFRangeMake(0, CFArrayGetCount(db->info_cache_list)),
+ cacheKey))) {
+ result = (SecValidInfoRef)CFDictionaryGetValue(db->info_cache, cacheKey);
+ // Verify this really is the right result
+ if (CFEqualSafe(result->certHash, certHash) && CFEqualSafe(result->issuerHash, issuerHash)) {
+ // Cache hit. Move the entry to the bottom of the list.
+ CFArrayRemoveValueAtIndex(db->info_cache_list, ix);
+ CFArrayAppendValue(db->info_cache_list, cacheKey);
+ secdebug("validcache", "cache hit: %@", cacheKey);
+ } else {
+ // Just remove this bad entry
+ CFArrayRemoveValueAtIndex(db->info_cache_list, ix);
+ CFDictionaryRemoveValue(db->info_cache, cacheKey);
+ secdebug("validcache", "cache remove bad: %@", cacheKey);
+ secnotice("validcache", "found a bad valid info cache entry at %ld", (long)ix);
+ }
+ }
+ CFRetainSafe(result);
+ os_unfair_lock_unlock(&db->info_cache_lock);
+ CFReleaseSafe(certHash);
+ CFReleaseSafe(cacheKey);
+ return result;
+}
+
+static void SecRevocationDbCacheWrite(SecRevocationDbRef db,
+ SecValidInfoRef validInfo) {
+ if (!db || !validInfo || !db->info_cache || !db->info_cache_list) {
+ return;
+ }
+
+ CFDataRef cacheKey = createCacheKey(validInfo->certHash, validInfo->issuerHash);
+
+ os_unfair_lock_lock(&db->info_cache_lock); // grab the cache lock before using the cache
+ // check to make sure another thread didn't add this entry to the cache already
+ if (0 > CFArrayGetFirstIndexOfValue(db->info_cache_list,
+ CFRangeMake(0, CFArrayGetCount(db->info_cache_list)),
+ cacheKey)) {
+ CFDictionaryAddValue(db->info_cache, cacheKey, validInfo);
+ if (kSecRevocationDbCacheSize <= CFArrayGetCount(db->info_cache_list)) {
+ // Remove least recently used cache entry.
+ secdebug("validcache", "cache remove stale: %@", CFArrayGetValueAtIndex(db->info_cache_list, 0));
+ CFDictionaryRemoveValue(db->info_cache, CFArrayGetValueAtIndex(db->info_cache_list, 0));
+ CFArrayRemoveValueAtIndex(db->info_cache_list, 0);
+ }
+ CFArrayAppendValue(db->info_cache_list, cacheKey);
+ secdebug("validcache", "cache add: %@", cacheKey);
+ }
+ os_unfair_lock_unlock(&db->info_cache_lock);
+ CFReleaseNull(cacheKey);
+}
+
+static void SecRevocationDbCachePurge(SecRevocationDbRef db) {
+ if (!db || !db->info_cache || !db->info_cache_list) {
+ return;
+ }
+
+ /* grab the cache lock and clear all entries */
+ os_unfair_lock_lock(&db->info_cache_lock);
+ CFArrayRemoveAllValues(db->info_cache_list);
+ CFDictionaryRemoveAllValues(db->info_cache);
+ secdebug("validcache", "cache purge");
+ os_unfair_lock_unlock(&db->info_cache_lock);
+}
+
+static int64_t _SecRevocationDbGetVersion(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
+ /* look up version entry in admin table; returns -1 on error */
+ __block int64_t version = -1;
+ __block bool ok = (dbc != NULL);
+ __block CFErrorRef localError = NULL;
+
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectVersionSQL, &localError, ^bool(sqlite3_stmt *selectVersion) {
+ ok = ok && SecDbStep(dbc->dbconn, selectVersion, &localError, ^void(bool *stop) {
+ version = sqlite3_column_int64(selectVersion, 0);
+ *stop = true;
});
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbGetVersion failed: %@", localError);
return version;
}
-static void _SecRevocationDbSetVersion(SecRevocationDbRef rdb, CFIndex version) {
+static bool _SecRevocationDbSetVersion(SecRevocationDbConnectionRef dbc, CFIndex version, CFErrorRef *error) {
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) {
- 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;
- });
- });
+ __block bool ok = (dbc != NULL);
+ ok = ok && SecDbWithSQL(dbc->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(dbc->dbconn, insertVersion, &localError, NULL);
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbSetVersion failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
}
- CFReleaseSafe(localError);
+ (void) CFErrorPropagate(localError, error);
+ return ok;
}
-static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, CFErrorRef *error) {
+static int64_t _SecRevocationDbReadSchemaVersionFromDb(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
/* look up db_version entry in admin table; returns -1 on error */
__block int64_t db_version = -1;
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
- ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- 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;
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectDbVersionSQL, &localError, ^bool(sqlite3_stmt *selectDbVersion) {
+ ok = ok && SecDbStep(dbc->dbconn, selectDbVersion, &localError, ^void(bool *stop) {
+ db_version = sqlite3_column_int64(selectDbVersion, 0);
+ *stop = true;
});
+ return ok;
});
if (!ok || localError) {
- secerror("_SecRevocationDbGetSchemaVersion failed: %@", localError);
+ secerror("_SecRevocationDbReadSchemaVersionFromDb failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
}
return db_version;
}
-static bool _SecRevocationDbSetSchemaVersion(SecRevocationDbRef rdb, CFIndex dbversion) {
+static _Atomic int64_t gSchemaVersion = -1;
+static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ if (dbc) {
+ atomic_init(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, error));
+ } else {
+ (void) SecRevocationDbPerformRead(rdb, error, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ atomic_init(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, blockError));
+ return true;
+ });
+ }
+ });
+ if (atomic_load(&gSchemaVersion) == -1) {
+ /* Initial read(s) failed. Try to read the schema version again. */
+ if (dbc) {
+ atomic_store(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, error));
+ } else {
+ (void) SecRevocationDbPerformRead(rdb, error, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ atomic_store(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, blockError));
+ return true;
+ });
+ }
+ }
+ return atomic_load(&gSchemaVersion);
+}
+
+static void SecRevocationDbResetCaches(void) {
+ SecRevocationDbWith(^(SecRevocationDbRef db) {
+ db->unsupportedVersion = false;
+ db->changed = false;
+ (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ atomic_store(&gSchemaVersion, _SecRevocationDbReadSchemaVersionFromDb(dbc, blockError));
+ return true;
+ });
+ SecRevocationDbCachePurge(db);
+ });
+}
+
+static bool _SecRevocationDbSetSchemaVersion(SecRevocationDbConnectionRef dbc, CFIndex dbversion, CFErrorRef *error) {
if (dbversion > 0) {
- int64_t db_version = _SecRevocationDbGetSchemaVersion(rdb, NULL);
+ int64_t db_version = (dbc) ? dbc->precommitDbVersion : -1;
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) {
- 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;
- });
- });
+ __block bool ok = (dbc != NULL);
+ ok = ok && SecDbWithSQL(dbc->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(dbc->dbconn, insertDbVersion, &localError, NULL);
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbSetSchemaVersion failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
} else {
- rdb->unsupportedVersion = false;
+ dbc->db->changed = true; /* will notify clients of this change */
+ dbc->db->unsupportedVersion = false;
+ dbc->precommitDbVersion = dbversion;
+ atomic_store(&gSchemaVersion, (int64_t)dbversion);
}
CFReleaseSafe(localError);
return ok;
}
-static bool _SecRevocationDbUpdateSchema(SecRevocationDbRef rdb) {
- secdebug("validupdate", "updating db schema to v%ld", (long)kSecRevocationDbSchemaVersion);
-
+static bool _SecRevocationDbUpdateSchema(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
__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;
- });
+ __block bool ok = (dbc != NULL);
+ __block int64_t db_version = (dbc) ? dbc->precommitDbVersion : 0;
+ if (db_version >= kSecRevocationDbSchemaVersion) {
+ return ok; /* schema version already up to date */
+ }
+ secdebug("validupdate", "updating db schema from v%lld to v%lld",
+ (long long)db_version, (long long)kSecRevocationDbSchemaVersion);
+
+ if (ok && db_version < 5) {
+ /* apply v5 changes (add dates table and replace trigger) */
+ ok &= SecDbWithSQL(dbc->dbconn, updateConstraintsTablesSQL, &localError, ^bool(sqlite3_stmt *updateTables) {
+ ok = SecDbStep(dbc->dbconn, updateTables, &localError, NULL);
+ return ok;
});
- });
+ ok &= SecDbWithSQL(dbc->dbconn, updateGroupDeleteTriggerSQL, &localError, ^bool(sqlite3_stmt *updateTrigger) {
+ ok = SecDbStep(dbc->dbconn, updateTrigger, &localError, NULL);
+ return ok;
+ });
+ secdebug("validupdate", "applied schema update to v5 (%s)", (ok) ? "ok" : "failed!");
+ }
+ if (ok && db_version < 6) {
+ /* apply v6 changes (the SecDb layer will update autovacuum mode if needed, so we don't execute
+ any SQL here, but we do want the database to be replaced in case transaction scope problems
+ with earlier versions caused missing entries.) */
+ secdebug("validupdate", "applied schema update to v6 (%s)", (ok) ? "ok" : "failed!");
+ if (db_version > 0) {
+ SecValidUpdateForceReplaceDatabase();
+ }
+ }
+
if (!ok) {
secerror("_SecRevocationDbUpdateSchema failed: %@", localError);
} else {
- ok &= _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion);
+ ok = ok && _SecRevocationDbSetSchemaVersion(dbc, kSecRevocationDbSchemaVersion, &localError);
+ }
+ (void) CFErrorPropagate(localError, error);
+ return ok;
+}
+
+bool SecRevocationDbUpdateSchema(SecRevocationDbRef rdb) {
+ /* note: this function assumes it is called only by the database owner.
+ non-owner (read-only) clients will fail if changes to the db are needed. */
+ if (!rdb || !rdb->db) {
+ return false;
}
+ __block bool ok = true;
+ __block CFErrorRef localError = NULL;
+ ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ return _SecRevocationDbUpdateSchema(dbc, blockError);
+ });
CFReleaseSafe(localError);
return ok;
}
-static int64_t _SecRevocationDbGetUpdateFormat(SecRevocationDbRef rdb, CFErrorRef *error) {
+static int64_t _SecRevocationDbGetUpdateFormat(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
/* look up db_format entry in admin table; returns -1 on error */
__block int64_t db_format = -1;
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
- ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- 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;
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectDbFormatSQL, &localError, ^bool(sqlite3_stmt *selectDbFormat) {
+ ok &= SecDbStep(dbc->dbconn, selectDbFormat, &localError, ^void(bool *stop) {
+ db_format = sqlite3_column_int64(selectDbFormat, 0);
+ *stop = true;
});
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbGetUpdateFormat failed: %@", localError);
return db_format;
}
-static void _SecRevocationDbSetUpdateFormat(SecRevocationDbRef rdb, CFIndex dbformat) {
+static bool _SecRevocationDbSetUpdateFormat(SecRevocationDbConnectionRef dbc, CFIndex dbformat, CFErrorRef *error) {
secdebug("validupdate", "setting db_format to %ld", (long)dbformat);
__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, 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;
- });
- });
+ __block bool ok = (dbc != NULL);
+ ok = ok && SecDbWithSQL(dbc->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(dbc->dbconn, insertDbFormat, &localError, NULL);
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbSetUpdateFormat failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
} else {
- rdb->unsupportedVersion = false;
+ dbc->db->changed = true; /* will notify clients of this change */
+ dbc->db->unsupportedVersion = false;
}
- CFReleaseSafe(localError);
+ (void) CFErrorPropagate(localError, error);
+ return ok;
}
-static CFStringRef _SecRevocationDbCopyUpdateSource(SecRevocationDbRef rdb, CFErrorRef *error) {
+static CFStringRef _SecRevocationDbCopyUpdateSource(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
/* look up db_source entry in admin table; returns NULL on error */
__block CFStringRef updateSource = NULL;
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
- ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- 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);
- }
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectDbSourceSQL, &localError, ^bool(sqlite3_stmt *selectDbSource) {
+ ok &= SecDbStep(dbc->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;
+ }
+ *stop = true;
});
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbCopyUpdateSource failed: %@", localError);
return updateSource;
}
-static void _SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef updateSource) {
+bool _SecRevocationDbSetUpdateSource(SecRevocationDbConnectionRef dbc, CFStringRef updateSource, CFErrorRef *error) {
if (!updateSource) {
secerror("_SecRevocationDbSetUpdateSource failed: %d", errSecParam);
- return;
+ return false;
}
__block char buffer[256];
__block const char *updateSourceCStr = CFStringGetCStringPtr(updateSource, kCFStringEncodingUTF8);
}
if (!updateSourceCStr) {
secerror("_SecRevocationDbSetUpdateSource failed: unable to get UTF-8 encoding");
- return;
+ return false;
}
secdebug("validupdate", "setting update source to \"%s\"", updateSourceCStr);
__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, 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;
- });
- });
+ __block bool ok = (dbc != NULL);
+ ok = ok && SecDbWithSQL(dbc->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(dbc->dbconn, insertRecord, &localError, NULL);
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbSetUpdateSource failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
}
+ (void) CFErrorPropagate(localError, error);
+ CFReleaseSafe(localError);
+ return ok;
+}
+
+bool SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef updateSource) {
+ /* note: this function assumes it is called only by the database owner.
+ non-owner (read-only) clients will fail if changes to the db are needed. */
+ if (!rdb || !rdb->db) {
+ return false;
+ }
+ CFErrorRef localError = NULL;
+ bool ok = true;
+ ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
+ return _SecRevocationDbSetUpdateSource(dbc, updateSource, error);
+ });
CFReleaseSafe(localError);
+ return ok;
}
-static CFAbsoluteTime _SecRevocationDbGetNextUpdateTime(SecRevocationDbRef rdb, CFErrorRef *error) {
+static CFAbsoluteTime _SecRevocationDbGetNextUpdateTime(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
/* look up check_again entry in admin table; returns 0 on error */
__block CFAbsoluteTime nextUpdate = 0;
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
- ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- 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;
- }
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectNextUpdateSQL, &localError, ^bool(sqlite3_stmt *selectNextUpdate) {
+ ok &= SecDbStep(dbc->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;
+ }
+ *stop = true;
});
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbGetNextUpdateTime failed: %@", localError);
return nextUpdate;
}
-static void _SecRevocationDbSetNextUpdateTime(SecRevocationDbRef rdb, CFAbsoluteTime nextUpdate){
+static bool _SecRevocationDbSetNextUpdateTime(SecRevocationDbConnectionRef dbc, CFAbsoluteTime nextUpdate, CFErrorRef *error){
secdebug("validupdate", "setting next update to %f", (double)nextUpdate);
__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, 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;
- });
- });
+ __block bool ok = (dbc != NULL);
+ ok = ok && SecDbWithSQL(dbc->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(dbc->dbconn, insertRecord, &localError, NULL);
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbSetNextUpdate failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
}
- CFReleaseSafe(localError);
+ (void) CFErrorPropagate(localError, error);
+ return ok;
}
-static bool _SecRevocationDbRemoveAllEntries(SecRevocationDbRef rdb) {
+bool _SecRevocationDbRemoveAllEntries(SecRevocationDbConnectionRef dbc, CFErrorRef *error) {
/* clear out the contents of the database and start fresh */
- __block bool ok = true;
- __block CFErrorRef localError = NULL;
+ bool ok = (dbc != NULL);
+ CFErrorRef localError = NULL;
- /* update schema first */
- _SecRevocationDbUpdateSchema(rdb);
+ /* _SecRevocationDbUpdateSchema was called when db was opened, so no need to do it again. */
+
+ /* delete all entries */
+ ok = ok && SecDbExec(dbc->dbconn, deleteAllEntriesSQL, &localError);
+ secnotice("validupdate", "resetting database, result: %d (expected 1)", (ok) ? 1 : 0);
- ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
- /* delete all entries */
- ok &= SecDbExec(dbconn, deleteAllEntriesSQL, &localError);
- secnotice("validupdate", "resetting database, result: %d (expected 1)", (ok) ? 1 : 0);
- *commit = ok;
- });
- /* compact the db (must be done outside transaction scope) */
- ok &= SecDbExec(dbconn, CFSTR("VACUUM"), &localError);
- secnotice("validupdate", "compacting database, result: %d (expected 1)", (ok) ? 1 : 0);
- });
/* one more thing: update the schema version and format to current */
- _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion);
- _SecRevocationDbSetUpdateFormat(rdb, kSecRevocationDbUpdateFormat);
+ ok = ok && _SecRevocationDbSetSchemaVersion(dbc, kSecRevocationDbSchemaVersion, &localError);
+ ok = ok && _SecRevocationDbSetUpdateFormat(dbc, kSecRevocationDbUpdateFormat, &localError);
if (!ok || localError) {
secerror("_SecRevocationDbRemoveAllEntries failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
}
- CFReleaseSafe(localError);
+ (void) CFErrorPropagate(localError, error);
return ok;
}
-static bool _SecRevocationDbUpdateIssuers(SecRevocationDbRef rdb, int64_t groupId, CFArrayRef issuers, CFErrorRef *error) {
+static bool _SecRevocationDbUpdateIssuers(SecRevocationDbConnectionRef dbc, int64_t groupId, CFArrayRef issuers, CFErrorRef *error) {
/* insert or replace issuer records in issuers table */
if (!issuers || groupId < 0) {
return false; /* must have something to insert, and a group to associate with it */
}
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
-
- ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
- if (isArray(issuers)) {
- CFIndex issuerIX, issuerCount = CFArrayGetCount(issuers);
- for (issuerIX=0; issuerIX<issuerCount && ok; issuerIX++) {
- CFDataRef hash = (CFDataRef)CFArrayGetValueAtIndex(issuers, issuerIX);
- if (!hash) { continue; }
- ok = ok && SecDbWithSQL(dbconn, insertIssuerRecordSQL, &localError, ^bool(sqlite3_stmt *insertIssuer) {
- ok = ok && SecDbBindInt64(insertIssuer, 1,
- groupId, &localError);
- ok = ok && SecDbBindBlob(insertIssuer, 2,
- CFDataGetBytePtr(hash),
- CFDataGetLength(hash),
- SQLITE_TRANSIENT, &localError);
- /* Execute the insert statement for this issuer record. */
- ok = ok && SecDbStep(dbconn, insertIssuer, &localError, NULL);
- return ok;
- });
- }
- }
- });
- });
+ if (isArray(issuers)) {
+ CFIndex issuerIX, issuerCount = CFArrayGetCount(issuers);
+ for (issuerIX=0; issuerIX<issuerCount && ok; issuerIX++) {
+ CFDataRef hash = (CFDataRef)CFArrayGetValueAtIndex(issuers, issuerIX);
+ if (!hash) { continue; }
+ ok = ok && SecDbWithSQL(dbc->dbconn, insertIssuerRecordSQL, &localError, ^bool(sqlite3_stmt *insertIssuer) {
+ ok = ok && SecDbBindInt64(insertIssuer, 1,
+ groupId, &localError);
+ ok = ok && SecDbBindBlob(insertIssuer, 2,
+ CFDataGetBytePtr(hash),
+ CFDataGetLength(hash),
+ SQLITE_TRANSIENT, &localError);
+ /* Execute the insert statement for this issuer record. */
+ ok = ok && SecDbStep(dbc->dbconn, insertIssuer, &localError, NULL);
+ return ok;
+ });
+ }
+ }
if (!ok || localError) {
secerror("_SecRevocationDbUpdateIssuers failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
return ok;
}
-static bool _SecRevocationDbUpdateIssuerData(SecRevocationDbRef rdb, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) {
+static SecValidInfoFormat _SecRevocationDbGetGroupFormatForData(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDataRef data) {
+ /* determine existing format if groupId is supplied and this is a partial update,
+ otherwise return the expected format for the given data. */
+ SecValidInfoFormat format = kSecValidInfoFormatUnknown;
+ if (groupId >= 0 && !dbc->fullUpdate) {
+ format = _SecRevocationDbGetGroupFormat(dbc, groupId, NULL, NULL, NULL);
+ }
+ if (format == kSecValidInfoFormatUnknown && data != NULL) {
+ /* group doesn't exist, so determine format based on length of specified data.
+ len <= 20 is a serial number (actually, <=37, but != 32.)
+ len==32 is a sha256 hash. otherwise: nto1. */
+ CFIndex length = CFDataGetLength(data);
+ if (length == 32) {
+ format = kSecValidInfoFormatSHA256;
+ } else if (length <= 37) {
+ format = kSecValidInfoFormatSerial;
+ } else if (length > 0) {
+ format = kSecValidInfoFormatNto1;
+ }
+ }
+ return format;
+}
+
+static bool _SecRevocationDbUpdateIssuerData(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) {
/* update/delete records in serials or hashes table. */
if (!dict || groupId < 0) {
return false; /* must have something to insert, and a group to associate with it */
}
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
-
- ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
- CFArrayRef deleteArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("delete"));
- /* process deletions */
- if (isArray(deleteArray)) {
- //%%% delete old data here (rdar://31439625)
+ /* process deletions */
+ CFArrayRef deleteArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("delete"));
+ if (isArray(deleteArray)) {
+ SecValidInfoFormat format = kSecValidInfoFormatUnknown;
+ CFIndex processed=0, identifierIX, identifierCount = CFArrayGetCount(deleteArray);
+ for (identifierIX=0; identifierIX<identifierCount; identifierIX++) {
+ CFDataRef identifierData = (CFDataRef)CFArrayGetValueAtIndex(deleteArray, identifierIX);
+ if (!identifierData) { continue; }
+ if (format == kSecValidInfoFormatUnknown) {
+ format = _SecRevocationDbGetGroupFormatForData(dbc, groupId, identifierData);
}
- /* process additions */
- CFArrayRef addArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("add"));
- if (isArray(addArray)) {
- CFIndex identifierIX, identifierCount = CFArrayGetCount(addArray);
- for (identifierIX=0; identifierIX<identifierCount; identifierIX++) {
- CFDataRef identifierData = (CFDataRef)CFArrayGetValueAtIndex(addArray, identifierIX);
- if (!identifierData) { continue; }
- CFIndex length = CFDataGetLength(identifierData);
- /* we can figure out the format without an extra read to get the format column.
- len <= 20 is a serial number. len==32 is a sha256 hash. otherwise: xor. */
- CFStringRef sql = NULL;
- if (length <= 20) {
- sql = insertSerialRecordSQL;
- } else if (length == 32) {
- sql = insertSha256RecordSQL;
- }
- if (!sql) { continue; }
-
- ok = ok && SecDbWithSQL(dbconn, sql, &localError, ^bool(sqlite3_stmt *insertIdentifier) {
- /* rowid,(groupid,serial|sha256) */
- /* rowid is autoincremented and we never set it directly */
- ok = ok && SecDbBindInt64(insertIdentifier, 1,
- groupId, &localError);
- ok = ok && SecDbBindBlob(insertIdentifier, 2,
- CFDataGetBytePtr(identifierData),
- CFDataGetLength(identifierData),
- SQLITE_TRANSIENT, &localError);
- /* Execute the insert statement for the identifier record. */
- ok = ok && SecDbStep(dbconn, insertIdentifier, &localError, NULL);
- return ok;
- });
- }
+ CFStringRef sql = NULL;
+ if (format == kSecValidInfoFormatSerial) {
+ sql = deleteSerialRecordSQL;
+ } else if (format == kSecValidInfoFormatSHA256) {
+ sql = deleteSha256RecordSQL;
}
- });
- });
+ if (!sql) { continue; }
+
+ ok = ok && SecDbWithSQL(dbc->dbconn, sql, &localError, ^bool(sqlite3_stmt *deleteIdentifier) {
+ /* (groupid,serial|sha256) */
+ CFDataRef hexData = cfToHexData(identifierData, true);
+ if (!hexData) { return false; }
+ ok = ok && SecDbBindInt64(deleteIdentifier, 1,
+ groupId, &localError);
+ ok = ok && SecDbBindBlob(deleteIdentifier, 2,
+ CFDataGetBytePtr(hexData),
+ CFDataGetLength(hexData),
+ SQLITE_TRANSIENT, &localError);
+ /* Execute the delete statement for the identifier record. */
+ ok = ok && SecDbStep(dbc->dbconn, deleteIdentifier, &localError, NULL);
+ CFReleaseSafe(hexData);
+ return ok;
+ });
+ if (ok) { ++processed; }
+ }
+#if VERBOSE_LOGGING
+ secdebug("validupdate", "Processed %ld of %ld deletions for group %lld, result=%s",
+ processed, identifierCount, groupId, (ok) ? "true" : "false");
+#endif
+ }
+ /* process additions */
+ CFArrayRef addArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("add"));
+ if (isArray(addArray)) {
+ SecValidInfoFormat format = kSecValidInfoFormatUnknown;
+ CFIndex processed=0, identifierIX, identifierCount = CFArrayGetCount(addArray);
+ for (identifierIX=0; identifierIX<identifierCount; identifierIX++) {
+ CFDataRef identifierData = (CFDataRef)CFArrayGetValueAtIndex(addArray, identifierIX);
+ if (!identifierData) { continue; }
+ if (format == kSecValidInfoFormatUnknown) {
+ format = _SecRevocationDbGetGroupFormatForData(dbc, groupId, identifierData);
+ }
+ CFStringRef sql = NULL;
+ if (format == kSecValidInfoFormatSerial) {
+ sql = insertSerialRecordSQL;
+ } else if (format == kSecValidInfoFormatSHA256) {
+ sql = insertSha256RecordSQL;
+ }
+ if (!sql) { continue; }
+
+ ok = ok && SecDbWithSQL(dbc->dbconn, sql, &localError, ^bool(sqlite3_stmt *insertIdentifier) {
+ /* rowid,(groupid,serial|sha256) */
+ /* rowid is autoincremented and we never set it directly */
+ ok = ok && SecDbBindInt64(insertIdentifier, 1,
+ groupId, &localError);
+ ok = ok && SecDbBindBlob(insertIdentifier, 2,
+ CFDataGetBytePtr(identifierData),
+ CFDataGetLength(identifierData),
+ SQLITE_TRANSIENT, &localError);
+ /* Execute the insert statement for the identifier record. */
+ ok = ok && SecDbStep(dbc->dbconn, insertIdentifier, &localError, NULL);
+ return ok;
+ });
+ if (ok) { ++processed; }
+ }
+#if VERBOSE_LOGGING
+ secdebug("validupdate", "Processed %ld of %ld additions for group %lld, result=%s",
+ processed, identifierCount, groupId, (ok) ? "true" : "false");
+#endif
+ }
if (!ok || localError) {
secerror("_SecRevocationDbUpdatePerIssuerData failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError,
return ok;
}
-static bool _SecRevocationDbCopyDateConstraints(SecRevocationDbRef rdb,
+static bool _SecRevocationDbCopyDateConstraints(SecRevocationDbConnectionRef dbc,
int64_t groupId, CFDateRef *notBeforeDate, CFDateRef *notAfterDate, CFErrorRef *error) {
/* return true if one or both date constraints exist for a given groupId.
the actual constraints are optionally returned in output CFDateRef parameters.
caller is responsible for releasing date and error parameters, if provided.
*/
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFDateRef localNotBefore = NULL;
__block CFDateRef localNotAfter = NULL;
__block CFErrorRef localError = NULL;
- ok &= SecDbPerformRead(rdb->db, &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;
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectDateRecordSQL, &localError, ^bool(sqlite3_stmt *selectDates) {
+ /* (groupid,notbefore,notafter) */
+ ok &= SecDbBindInt64(selectDates, 1, groupId, &localError);
+ ok = ok && SecDbStep(dbc->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) {
+ /* must have at least one date constraint to return true.
+ since date constraints are optional, not finding any should not log an error. */
+ ok = ok && !localError && (localNotBefore != NULL || localNotAfter != NULL);
+ if (localError) {
secerror("_SecRevocationDbCopyDateConstraints failed: %@", localError);
TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError,
localError ? CFErrorGetCode(localError) : errSecInternalComponent);
+ }
+ if (!ok) {
CFReleaseNull(localNotBefore);
CFReleaseNull(localNotAfter);
}
return ok;
}
-static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbRef rdb, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) {
+static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) {
/* update optional records in dates, names, or policies tables. */
- if (!dict || groupId < 0) {
+ if (!dbc || !dict || groupId < 0) {
return false; /* must have something to insert, and a group to associate with it */
}
__block bool ok = true;
notAfterDate = NULL;
}
if (!(notBeforeDate || notAfterDate)) {
- return false; /* no dates supplied, so we have nothing to update for this issuer */
+ return ok; /* no dates supplied, so we have nothing to update for this issuer */
}
- if (!(notBeforeDate && notAfterDate)) {
+ if (!(notBeforeDate && notAfterDate) && !dbc->fullUpdate) {
/* 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 (_SecRevocationDbCopyDateConstraints(dbc, groupId, &curNotBeforeDate,
+ &curNotAfterDate, &localError)) {
if (!notBeforeDate) {
notBeforeDate = curNotBeforeDate;
notBefore = CFDateGetAbsoluteTime(notBeforeDate);
}
}
- 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 */
- });
+ ok = ok && SecDbWithSQL(dbc->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(dbc->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);
return ok;
}
-static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbRef rdb,
+static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbConnectionRef dbc,
int64_t groupId, SecValidInfoFlags *flags, CFDataRef *data, CFErrorRef *error) {
/* return group record fields for a given groupId.
on success, returns a non-zero format type, and other field values in optional output parameters.
caller is responsible for releasing data and error parameters, if provided.
*/
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block SecValidInfoFormat format = 0;
__block CFErrorRef localError = NULL;
/* 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 = 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) {
- //%%% stream the data from the db into a streamed decompression <rdar://32142637>
- uint8_t *p = (uint8_t *)sqlite3_column_blob(selectGroup, 2);
- if (p != NULL && format == kSecValidInfoFormatNto1) {
- CFIndex length = (CFIndex)sqlite3_column_bytes(selectGroup, 2);
- *data = CFDataCreate(kCFAllocatorDefault, p, length);
- }
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectGroupRecordSQL, &localError, ^bool(sqlite3_stmt *selectGroup) {
+ ok = ok && SecDbBindInt64(selectGroup, 1, groupId, &localError);
+ ok = ok && SecDbStep(dbc->dbconn, selectGroup, &localError, ^(bool *stop) {
+ if (flags) {
+ *flags = (SecValidInfoFlags)sqlite3_column_int(selectGroup, 0);
+ }
+ format = (SecValidInfoFormat)sqlite3_column_int(selectGroup, 1);
+ if (data) {
+ //%%% stream the data from the db into a streamed decompression <rdar://32142637>
+ uint8_t *p = (uint8_t *)sqlite3_column_blob(selectGroup, 2);
+ if (p != NULL && format == kSecValidInfoFormatNto1) {
+ CFIndex length = (CFIndex)sqlite3_column_bytes(selectGroup, 2);
+ *data = CFDataCreate(kCFAllocatorDefault, p, length);
}
- });
- return ok;
+ }
});
+ return ok;
});
if (!ok || localError) {
secdebug("validupdate", "GetGroupFormat for groupId %lu failed", (unsigned long)groupId);
}
-static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) {
+static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) {
/* insert group record for a given groupId.
if the specified groupId is < 0, a new group entry is created.
returns the groupId on success, or -1 on failure.
}
__block int64_t result = -1;
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block bool isFormatChange = false;
__block CFErrorRef localError = NULL;
if (groupId >= 0) {
/* fetch the flags and data for an existing group record, in case some are being changed. */
- format = _SecRevocationDbGetGroupFormat(rdb, groupId, &flags, &data, NULL);
+ if (ok) {
+ format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, NULL);
+ }
if (format == kSecValidInfoFormatUnknown) {
secdebug("validupdate", "existing group %lld has unknown format %d, flags=0x%lx",
(long long)groupId, format, flags);
formatUpdate != format &&
groupId >= 0);
- ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
- if (isFormatChange) {
- secdebug("validupdate", "group %lld format change from %d to %d",
- (long long)groupId, format, formatUpdate);
- /* format of an existing group is changing; delete the group first.
- this should ensure that all entries referencing the old groupid are deleted.
- */
- ok &= SecDbWithSQL(dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) {
- ok = SecDbBindInt64(deleteResponse, 1, groupId, &localError);
- /* Execute the delete statement. */
- ok = ok && SecDbStep(dbconn, deleteResponse, &localError, NULL);
- return ok;
- });
+ if (isFormatChange) {
+ secdebug("validupdate", "group %lld format change from %d to %d",
+ (long long)groupId, format, formatUpdate);
+ /* format of an existing group is changing; delete the group first.
+ this should ensure that all entries referencing the old groupid are deleted.
+ */
+ ok = ok && SecDbWithSQL(dbc->dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) {
+ ok = ok && SecDbBindInt64(deleteResponse, 1, groupId, &localError);
+ /* Execute the delete statement. */
+ ok = ok && SecDbStep(dbc->dbconn, deleteResponse, &localError, NULL);
+ return ok;
+ });
+ }
+ ok = ok && SecDbWithSQL(dbc->dbconn, insertGroupRecordSQL, &localError, ^bool(sqlite3_stmt *insertGroup) {
+ /* (groupid,flags,format,data) */
+ /* groups.groupid */
+ if (ok && (!isFormatChange) && (groupId >= 0)) {
+ /* bind to existing groupId row if known, otherwise will insert and autoincrement */
+ ok = SecDbBindInt64(insertGroup, 1, groupId, &localError);
+ if (!ok) {
+ secdebug("validupdate", "failed to set groupId %lld", (long long)groupId);
+ }
+ }
+ /* groups.flags */
+ if (ok) {
+ (void)_SecRevocationDbUpdateFlags(dict, CFSTR("complete"), kSecValidInfoComplete, &flags);
+ (void)_SecRevocationDbUpdateFlags(dict, CFSTR("check-ocsp"), kSecValidInfoCheckOCSP, &flags);
+ (void)_SecRevocationDbUpdateFlags(dict, CFSTR("known-intermediates-only"), kSecValidInfoKnownOnly, &flags);
+ (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("no-ca-v2"), kSecValidInfoNoCAv2Check, &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. */
}
- ok &= SecDbWithSQL(dbconn, insertGroupRecordSQL, &localError, ^bool(sqlite3_stmt *insertGroup) {
- /* (groupid,flags,format,data) */
- /* groups.groupid */
- if (ok && (!isFormatChange) && (groupId >= 0)) {
- /* bind to existing groupId row if known, otherwise will insert and autoincrement */
- ok = SecDbBindInt64(insertGroup, 1, groupId, &localError);
- if (!ok) {
- secdebug("validupdate", "failed to set groupId %lld", (long long)groupId);
- }
- }
- /* groups.flags */
- if (ok) {
- (void)_SecRevocationDbUpdateFlags(dict, CFSTR("complete"), kSecValidInfoComplete, &flags);
- (void)_SecRevocationDbUpdateFlags(dict, CFSTR("check-ocsp"), kSecValidInfoCheckOCSP, &flags);
- (void)_SecRevocationDbUpdateFlags(dict, CFSTR("known-intermediates-only"), kSecValidInfoKnownOnly, &flags);
- (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);
+ /* %%% (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) {
- secdebug("validupdate", "failed to set flags (%lu) for groupId %lld", flags, (long long)groupId);
- }
- }
- /* groups.format */
- if (ok) {
- SecValidInfoFormat formatValue = format;
- if (formatUpdate > kSecValidInfoFormatUnknown) {
- formatValue = formatUpdate;
- }
- ok = SecDbBindInt(insertGroup, 3, (int)formatValue, &localError);
- if (!ok) {
- secdebug("validupdate", "failed to set format (%d) for groupId %lld", formatValue, (long long)groupId);
- }
- }
- /* groups.data */
- CFDataRef xmlData = NULL;
- if (ok) {
- bool hasFilter = ((formatUpdate == kSecValidInfoFormatNto1) ||
- (formatUpdate == kSecValidInfoFormatUnknown &&
- format == kSecValidInfoFormatNto1));
- if (hasFilter) {
- CFDataRef dataValue = data; /* use existing data */
- if (_SecRevocationDbUpdateFilter(dict, data, &xmlData)) {
- dataValue = xmlData; /* use updated data */
- }
- if (dataValue) {
- ok = SecDbBindBlob(insertGroup, 4,
- CFDataGetBytePtr(dataValue),
- CFDataGetLength(dataValue),
- SQLITE_TRANSIENT, &localError);
- }
- if (!ok) {
- secdebug("validupdate", "failed to set data for groupId %lld",
- (long long)groupId);
- }
- }
- /* else there is no data, so NULL is implicitly bound to column 4 */
+ ok = SecDbBindInt(insertGroup, 2, (int)flags, &localError);
+ if (!ok) {
+ secdebug("validupdate", "failed to set flags (%lu) for groupId %lld", flags, (long long)groupId);
+ }
+ }
+ /* groups.format */
+ if (ok) {
+ SecValidInfoFormat formatValue = format;
+ if (formatUpdate > kSecValidInfoFormatUnknown) {
+ formatValue = formatUpdate;
+ }
+ ok = SecDbBindInt(insertGroup, 3, (int)formatValue, &localError);
+ if (!ok) {
+ secdebug("validupdate", "failed to set format (%d) for groupId %lld", formatValue, (long long)groupId);
+ }
+ }
+ /* groups.data */
+ CFDataRef xmlData = NULL;
+ if (ok) {
+ bool hasFilter = ((formatUpdate == kSecValidInfoFormatNto1) ||
+ (formatUpdate == kSecValidInfoFormatUnknown &&
+ format == kSecValidInfoFormatNto1));
+ if (hasFilter) {
+ CFDataRef dataValue = data; /* use existing data */
+ if (_SecRevocationDbUpdateFilter(dict, data, &xmlData)) {
+ dataValue = xmlData; /* use updated data */
}
-
- /* Execute the insert statement for the group record. */
- if (ok) {
- ok = SecDbStep(dbconn, insertGroup, &localError, NULL);
- if (!ok) {
- secdebug("validupdate", "failed to execute insertGroup statement for groupId %lld",
- (long long)groupId);
- }
- result = (int64_t)sqlite3_last_insert_rowid(SecDbHandle(dbconn));
+ if (dataValue) {
+ ok = SecDbBindBlob(insertGroup, 4,
+ CFDataGetBytePtr(dataValue),
+ CFDataGetLength(dataValue),
+ SQLITE_TRANSIENT, &localError);
}
if (!ok) {
- secdebug("validupdate", "failed to insert group %lld", (long long)result);
+ secdebug("validupdate", "failed to set data for groupId %lld",
+ (long long)groupId);
}
- /* Clean up temporary allocation made in this block. */
- CFReleaseSafe(xmlData);
- CFReleaseSafe(data);
- return ok;
- });
- });
+ }
+ /* else there is no data, so NULL is implicitly bound to column 4 */
+ }
+
+ /* Execute the insert statement for the group record. */
+ if (ok) {
+ ok = SecDbStep(dbc->dbconn, insertGroup, &localError, NULL);
+ if (!ok) {
+ secdebug("validupdate", "failed to execute insertGroup statement for groupId %lld",
+ (long long)groupId);
+ }
+ result = (int64_t)sqlite3_last_insert_rowid(SecDbHandle(dbc->dbconn));
+ }
+ if (!ok) {
+ secdebug("validupdate", "failed to insert group %lld", (long long)result);
+ }
+ /* Clean up temporary allocation made in this block. */
+ CFReleaseSafe(xmlData);
+ CFReleaseSafe(data);
+ return ok;
});
if (!ok || localError) {
secerror("_SecRevocationDbUpdateGroup failed: %@", localError);
return result;
}
-static int64_t _SecRevocationDbGroupIdForIssuerHash(SecRevocationDbRef rdb, CFDataRef hash, CFErrorRef *error) {
+static int64_t _SecRevocationDbGroupIdForIssuerHash(SecRevocationDbConnectionRef dbc, CFDataRef hash, CFErrorRef *error) {
/* look up issuer hash in issuers table to get groupid, if it exists */
__block int64_t groupId = -1;
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
if (!hash) {
secdebug("validupdate", "failed to get hash (%@)", hash);
}
- require(hash, errOut);
+ require(hash && dbc, errOut);
/* This is the starting point for any lookup; find a group id for the given issuer hash.
Before we do that, need to verify the current db_version. We cannot use results from a
update interval, if the existing schema is old, we'll be removing and recreating
the database contents with the current schema version.
*/
- int64_t db_version = _SecRevocationDbGetSchemaVersion(rdb, NULL);
+ int64_t db_version = _SecRevocationDbGetSchemaVersion(dbc->db, dbc, NULL);
if (db_version < kSecRevocationDbMinSchemaVersion) {
- if (!rdb->unsupportedVersion) {
+ if (!dbc->db->unsupportedVersion) {
secdebug("validupdate", "unsupported db_version: %lld", (long long)db_version);
- rdb->unsupportedVersion = true; /* only warn once for a given unsupported version */
+ dbc->db->unsupportedVersion = true; /* only warn once for a given unsupported version */
}
}
require_quiet(db_version >= kSecRevocationDbMinSchemaVersion, errOut);
/* Look up provided issuer_hash in the issuers table.
*/
- 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 &= SecDbStep(dbconn, selectGroupId, &localError, ^(bool *stopGroupId) {
- groupId = sqlite3_column_int64(selectGroupId, 0);
- });
- return ok;
+ ok = ok && SecDbWithSQL(dbc->dbconn, selectGroupIdSQL, &localError, ^bool(sqlite3_stmt *selectGroupId) {
+ ok &= SecDbBindBlob(selectGroupId, 1, CFDataGetBytePtr(hash), CFDataGetLength(hash), SQLITE_TRANSIENT, &localError);
+ ok &= SecDbStep(dbc->dbconn, selectGroupId, &localError, ^(bool *stopGroupId) {
+ groupId = sqlite3_column_int64(selectGroupId, 0);
});
+ return ok;
});
errOut:
return groupId;
}
-static bool _SecRevocationDbApplyGroupDelete(SecRevocationDbRef rdb, CFDataRef issuerHash, CFErrorRef *error) {
+static bool _SecRevocationDbApplyGroupDelete(SecRevocationDbConnectionRef dbc, CFDataRef issuerHash, CFErrorRef *error) {
/* delete group associated with the given issuer;
schema trigger will delete associated issuers, serials, and hashes. */
__block int64_t groupId = -1;
- __block bool ok = true;
+ __block bool ok = (dbc != NULL);
__block CFErrorRef localError = NULL;
- groupId = _SecRevocationDbGroupIdForIssuerHash(rdb, issuerHash, &localError);
- require(!(groupId < 0), errOut);
-
- 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);
- /* Execute the delete statement. */
- ok = ok && SecDbStep(dbconn, deleteResponse, &localError, NULL);
- return ok;
- });
- });
+ if (ok) {
+ groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, &localError);
+ }
+ if (groupId < 0) {
+ if (!localError) {
+ SecError(errSecParam, &localError, CFSTR("group not found for issuer"));
+ }
+ ok = false;
+ }
+ ok = ok && SecDbWithSQL(dbc->dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) {
+ ok &= SecDbBindInt64(deleteResponse, 1, groupId, &localError);
+ /* Execute the delete statement. */
+ ok = ok && SecDbStep(dbc->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;
+ return ok;
}
-static bool _SecRevocationDbApplyGroupUpdate(SecRevocationDbRef rdb, CFDictionaryRef dict, CFErrorRef *error) {
+static bool _SecRevocationDbApplyGroupUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef dict, CFErrorRef *error) {
/* process one issuer group's update dictionary */
- int64_t groupId = -1;
- CFErrorRef localError = NULL;
+ __block int64_t groupId = -1;
+ __block bool ok = (dbc != NULL);
+ __block CFErrorRef localError = NULL;
CFArrayRef issuers = (dict) ? (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("issuer-hash")) : NULL;
- if (isArray(issuers)) {
+ /* if this is not a full update, then look for existing group id */
+ if (ok && isArray(issuers) && !dbc->fullUpdate) {
CFIndex issuerIX, issuerCount = CFArrayGetCount(issuers);
/* while we have issuers and haven't found a matching group id */
for (issuerIX=0; issuerIX<issuerCount && groupId < 0; issuerIX++) {
CFDataRef hash = (CFDataRef)CFArrayGetValueAtIndex(issuers, issuerIX);
if (!hash) { continue; }
- groupId = _SecRevocationDbGroupIdForIssuerHash(rdb, hash, &localError);
+ groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, hash, &localError);
+ }
+ if (groupId >= 0) {
+ /* according to the spec, we must replace all existing issuers with
+ the new issuers list, so delete all issuers in the group first. */
+ ok = ok && SecDbWithSQL(dbc->dbconn, deleteGroupIssuersSQL, &localError, ^bool(sqlite3_stmt *deleteIssuers) {
+ ok = ok && SecDbBindInt64(deleteIssuers, 1, groupId, &localError);
+ ok = ok && SecDbStep(dbc->dbconn, deleteIssuers, &localError, NULL);
+ return ok;
+ });
}
}
/* create or update the group entry */
- groupId = _SecRevocationDbUpdateGroup(rdb, groupId, dict, &localError);
+ if (ok) {
+ groupId = _SecRevocationDbUpdateGroup(dbc, groupId, dict, &localError);
+ }
if (groupId < 0) {
secdebug("validupdate", "failed to get groupId");
+ ok = false;
} else {
/* create or update issuer entries, now that we know the group id */
- _SecRevocationDbUpdateIssuers(rdb, groupId, issuers, &localError);
+ ok = ok && _SecRevocationDbUpdateIssuers(dbc, groupId, issuers, &localError);
/* create or update entries in serials or hashes tables */
- _SecRevocationDbUpdateIssuerData(rdb, groupId, dict, &localError);
+ ok = ok && _SecRevocationDbUpdateIssuerData(dbc, groupId, dict, &localError);
/* create or update entries in dates/names/policies tables */
- _SecRevocationDbUpdateIssuerConstraints(rdb, groupId, dict, &localError);
+ ok = ok && _SecRevocationDbUpdateIssuerConstraints(dbc, groupId, dict, &localError);
}
(void) CFErrorPropagate(localError, error);
- return (groupId > 0) ? true : false;
+ return ok;
}
-static void _SecRevocationDbApplyUpdate(SecRevocationDbRef rdb, CFDictionaryRef update, CFIndex version) {
+bool _SecRevocationDbApplyUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryRef update, CFIndex version, CFErrorRef *error) {
/* process entire update dictionary */
- if (!rdb || !update) {
+ if (!dbc || !dbc->db || !update) {
secerror("_SecRevocationDbApplyUpdate failed: invalid args");
- return;
+ SecError(errSecParam, error, CFSTR("_SecRevocationDbApplyUpdate: invalid db or update parameter"));
+ return false;
}
- __block CFDictionaryRef localUpdate = (CFDictionaryRef)CFRetainSafe(update);
- __block CFErrorRef localError = NULL;
+ CFDictionaryRef localUpdate = (CFDictionaryRef)CFRetainSafe(update);
+ CFErrorRef localError = NULL;
+ bool ok = true;
CFTypeRef value = NULL;
CFIndex deleteCount = 0;
CFIndex updateCount = 0;
- rdb->updateInProgress = true;
+ dbc->db->updateInProgress = true;
/* check whether this is a full update */
value = (CFBooleanRef)CFDictionaryGetValue(update, CFSTR("full"));
if (isBoolean(value) && CFBooleanGetValue((CFBooleanRef)value)) {
/* clear the database before processing a full update */
- SecRevocationDbRemoveAllEntries();
+ dbc->fullUpdate = true;
+ secdebug("validupdate", "update has \"full\" attribute; clearing database");
+ ok = ok && _SecRevocationDbRemoveAllEntries(dbc, &localError);
}
/* process 'delete' list */
for (CFIndex deleteIX=0; deleteIX<deleteCount; deleteIX++) {
CFDataRef issuerHash = (CFDataRef)CFArrayGetValueAtIndex((CFArrayRef)value, deleteIX);
if (isData(issuerHash)) {
- (void)_SecRevocationDbApplyGroupDelete(rdb, issuerHash, &localError);
- CFReleaseNull(localError);
+ ok = ok && _SecRevocationDbApplyGroupDelete(dbc, issuerHash, &localError);
} else {
secdebug("validupdate", "skipping delete %ld (hash is not a data value)", (long)deleteIX);
}
for (CFIndex updateIX=0; updateIX<updateCount; updateIX++) {
CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex((CFArrayRef)value, updateIX);
if (isDictionary(dict)) {
- (void)_SecRevocationDbApplyGroupUpdate(rdb, dict, &localError);
- CFReleaseNull(localError);
+ ok = ok && _SecRevocationDbApplyGroupUpdate(dbc, dict, &localError);
} else {
secdebug("validupdate", "skipping update %ld (not a dictionary)", (long)updateIX);
}
}
}
- CFRelease(localUpdate);
+ CFReleaseSafe(localUpdate);
/* set version */
- _SecRevocationDbSetVersion(rdb, version);
+ ok = ok && _SecRevocationDbSetVersion(dbc, version, &localError);
/* set db_version if not already set */
- int64_t db_version = _SecRevocationDbGetSchemaVersion(rdb, NULL);
+ int64_t db_version = _SecRevocationDbGetSchemaVersion(dbc->db, dbc, NULL);
if (db_version <= 0) {
- _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion);
+ ok = ok && _SecRevocationDbSetSchemaVersion(dbc, kSecRevocationDbSchemaVersion, &localError);
}
/* set db_format if not already set */
- int64_t db_format = _SecRevocationDbGetUpdateFormat(rdb, NULL);
+ int64_t db_format = _SecRevocationDbGetUpdateFormat(dbc, NULL);
if (db_format <= 0) {
- _SecRevocationDbSetUpdateFormat(rdb, kSecRevocationDbUpdateFormat);
+ ok = ok && _SecRevocationDbSetUpdateFormat(dbc, kSecRevocationDbUpdateFormat, &localError);
}
- /* compact the db (must be done outside transaction scope) */
- (void)SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- SecDbExec(dbconn, CFSTR("VACUUM"), &localError);
- CFReleaseNull(localError);
- });
+ /* purge the in-memory cache */
+ SecRevocationDbCachePurge(dbc->db);
- rdb->updateInProgress = false;
+ dbc->db->updateInProgress = false;
+
+ (void) CFErrorPropagate(localError, error);
+ return ok;
}
-static bool _SecRevocationDbSerialInGroup(SecRevocationDbRef rdb,
+static bool _SecRevocationDbSerialInGroup(SecRevocationDbConnectionRef dbc,
CFDataRef serial,
int64_t groupId,
CFErrorRef *error) {
__block bool result = false;
__block bool ok = true;
__block CFErrorRef localError = NULL;
- require(rdb && serial, errOut);
- ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- ok &= SecDbWithSQL(dbconn, selectSerialRecordSQL, &localError, ^bool(sqlite3_stmt *selectSerial) {
- ok &= SecDbBindInt64(selectSerial, 1, groupId, &localError);
- ok &= SecDbBindBlob(selectSerial, 2, CFDataGetBytePtr(serial),
- CFDataGetLength(serial), SQLITE_TRANSIENT, &localError);
- ok &= SecDbStep(dbconn, selectSerial, &localError, ^(bool *stop) {
- int64_t foundRowId = (int64_t)sqlite3_column_int64(selectSerial, 0);
- result = (foundRowId > 0);
- });
- return ok;
+ require(dbc && serial, errOut);
+ ok &= SecDbWithSQL(dbc->dbconn, selectSerialRecordSQL, &localError, ^bool(sqlite3_stmt *selectSerial) {
+ ok &= SecDbBindInt64(selectSerial, 1, groupId, &localError);
+ ok &= SecDbBindBlob(selectSerial, 2, CFDataGetBytePtr(serial),
+ CFDataGetLength(serial), SQLITE_TRANSIENT, &localError);
+ ok &= SecDbStep(dbc->dbconn, selectSerial, &localError, ^(bool *stop) {
+ int64_t foundRowId = (int64_t)sqlite3_column_int64(selectSerial, 0);
+ result = (foundRowId > 0);
});
+ return ok;
});
errOut:
return result;
}
-static bool _SecRevocationDbCertHashInGroup(SecRevocationDbRef rdb,
+static bool _SecRevocationDbCertHashInGroup(SecRevocationDbConnectionRef dbc,
CFDataRef certHash,
int64_t groupId,
CFErrorRef *error) {
__block bool result = false;
__block bool ok = true;
__block CFErrorRef localError = NULL;
- require(rdb && certHash, errOut);
- ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) {
- ok &= SecDbWithSQL(dbconn, selectHashRecordSQL, &localError, ^bool(sqlite3_stmt *selectHash) {
- ok &= SecDbBindInt64(selectHash, 1, groupId, &localError);
- ok = SecDbBindBlob(selectHash, 2, CFDataGetBytePtr(certHash),
- CFDataGetLength(certHash), SQLITE_TRANSIENT, &localError);
- ok &= SecDbStep(dbconn, selectHash, &localError, ^(bool *stop) {
- int64_t foundRowId = (int64_t)sqlite3_column_int64(selectHash, 0);
- result = (foundRowId > 0);
- });
- return ok;
+ require(dbc && certHash, errOut);
+ ok &= SecDbWithSQL(dbc->dbconn, selectHashRecordSQL, &localError, ^bool(sqlite3_stmt *selectHash) {
+ ok &= SecDbBindInt64(selectHash, 1, groupId, &localError);
+ ok = SecDbBindBlob(selectHash, 2, CFDataGetBytePtr(certHash),
+ CFDataGetLength(certHash), SQLITE_TRANSIENT, &localError);
+ ok &= SecDbStep(dbc->dbconn, selectHash, &localError, ^(bool *stop) {
+ int64_t foundRowId = (int64_t)sqlite3_column_int64(selectHash, 0);
+ result = (foundRowId > 0);
});
+ return ok;
});
errOut:
return result;
}
-static bool _SecRevocationDbSerialInFilter(SecRevocationDbRef rdb,
+static bool _SecRevocationDbSerialInFilter(SecRevocationDbConnectionRef dbc,
CFDataRef serialData,
CFDataRef xmlData) {
/* N-To-1 filter implementation.
return result;
}
-static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRef rdb,
+static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbConnectionRef dbc,
SecCertificateRef certificate,
CFDataRef issuerHash,
CFErrorRef *error) {
require((serial = SecCertificateCopySerialNumberData(certificate, NULL)) != NULL, errOut);
require((certHash = SecCertificateCopySHA256Digest(certificate)) != NULL, errOut);
- require((groupId = _SecRevocationDbGroupIdForIssuerHash(rdb, issuerHash, &localError)) > 0, errOut);
+ require((groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, &localError)) > 0, errOut);
/* Look up the group record to determine flags and format. */
- format = _SecRevocationDbGetGroupFormat(rdb, groupId, &flags, &data, &localError);
+ format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, &localError);
if (format == kSecValidInfoFormatUnknown) {
/* No group record found for this issuer. Don't return a SecValidInfoRef */
}
else if (format == kSecValidInfoFormatSerial) {
/* Look up certificate's serial number in the serials table. */
- matched = _SecRevocationDbSerialInGroup(rdb, serial, groupId, &localError);
+ matched = _SecRevocationDbSerialInGroup(dbc, serial, groupId, &localError);
}
else if (format == kSecValidInfoFormatSHA256) {
/* Look up certificate's SHA-256 hash in the hashes table. */
- matched = _SecRevocationDbCertHashInGroup(rdb, certHash, groupId, &localError);
+ matched = _SecRevocationDbCertHashInGroup(dbc, certHash, groupId, &localError);
}
else if (format == kSecValidInfoFormatNto1) {
/* Perform a Bloom filter match against the serial. If matched is false,
then the cert is definitely not in the list. But if matched is true,
we don't know for certain, so we would need to check OCSP. */
- matched = _SecRevocationDbSerialInFilter(rdb, serial, data);
+ matched = _SecRevocationDbSerialInFilter(dbc, serial, data);
}
if (matched) {
/* If supplemental constraints are present for this issuer, then we always match. */
if ((flags & kSecValidInfoDateConstraints) &&
- (_SecRevocationDbCopyDateConstraints(rdb, groupId, ¬BeforeDate, ¬AfterDate, &localError))) {
+ (_SecRevocationDbCopyDateConstraints(dbc, groupId, ¬BeforeDate, ¬AfterDate, &localError))) {
secdebug("validupdate", "Valid db matched supplemental date constraints for groupId %lld: nb=%@, na=%@",
(long long)groupId, notBeforeDate, notAfterDate);
}
/* Prevent a catch-22. */
secdebug("validupdate", "Valid db match for Apple trust anchor: %@, format=%d, flags=0x%lx",
certHash, format, flags);
- SecValidInfoRelease(result);
- result = NULL;
+ CFReleaseNull(result);
}
errOut:
return result;
}
-static SecValidInfoRef _SecRevocationDbCopyMatching(SecRevocationDbRef db,
+static SecValidInfoRef _SecRevocationDbCopyMatching(SecRevocationDbConnectionRef dbc,
SecCertificateRef certificate,
SecCertificateRef issuer) {
SecValidInfoRef result = NULL;
CFErrorRef error = NULL;
CFDataRef issuerHash = NULL;
- require(certificate && issuer, errOut);
+ require(dbc && certificate && issuer, errOut);
require(issuerHash = SecCertificateCopySHA256Digest(issuer), errOut);
- result = _SecRevocationDbValidInfoForCertificate(db, certificate, issuerHash, &error);
+ /* Check for the result in the cache. */
+ result = SecRevocationDbCacheRead(dbc->db, certificate, issuerHash);
+
+ /* Upon cache miss, get the result from the database and add it to the cache. */
+ if (!result) {
+ result = _SecRevocationDbValidInfoForCertificate(dbc, certificate, issuerHash, &error);
+ SecRevocationDbCacheWrite(dbc->db, result);
+ }
errOut:
CFReleaseSafe(issuerHash);
return result;
}
-static dispatch_queue_t _SecRevocationDbGetUpdateQueue(SecRevocationDbRef rdb) {
- return (rdb) ? rdb->update_queue : NULL;
-}
-
-
-/* Given a valid update dictionary, insert/replace or delete records
- in the revocation database. (This function is expected to be called only
- by the database maintainer, normally the system instance of trustd.)
-*/
-void SecRevocationDbApplyUpdate(CFDictionaryRef update, CFIndex version) {
- SecRevocationDbWith(^(SecRevocationDbRef db) {
- _SecRevocationDbApplyUpdate(db, update, 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.)
-*/
-bool SecRevocationDbSetSchemaVersion(CFIndex db_version) {
- __block bool result = false;
- SecRevocationDbWith(^(SecRevocationDbRef db) {
- 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.
- (This function is expected to be called only by the database maintainer,
- normally the system instance of trustd.)
-*/
-void SecRevocationDbSetUpdateFormat(CFIndex db_format) {
- SecRevocationDbWith(^(SecRevocationDbRef db) {
- _SecRevocationDbSetUpdateFormat(db, db_format);
- });
-}
-
-/* Set the update source for the revocation database.
- (This function is expected to be called only by the database
- maintainer, normally the system instance of trustd. If the
- caller does not have write access, this is a no-op.)
-*/
-void SecRevocationDbSetUpdateSource(CFStringRef updateSource) {
- SecRevocationDbWith(^(SecRevocationDbRef db) {
- _SecRevocationDbSetUpdateSource(db, updateSource);
- });
-}
-
/* Return the update source as a retained CFStringRef.
If the value cannot be obtained, NULL is returned.
*/
CFStringRef SecRevocationDbCopyUpdateSource(void) {
__block CFStringRef result = NULL;
SecRevocationDbWith(^(SecRevocationDbRef db) {
- result = _SecRevocationDbCopyUpdateSource(db, NULL);
+ (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ result = _SecRevocationDbCopyUpdateSource(dbc, blockError);
+ return (bool)result;
+ });
});
return result;
}
maintainer, normally the system instance of trustd. If the
caller does not have write access, this is a no-op.)
*/
-void SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate) {
- SecRevocationDbWith(^(SecRevocationDbRef db) {
- _SecRevocationDbSetNextUpdateTime(db, nextUpdate);
+bool SecRevocationDbSetNextUpdateTime(CFAbsoluteTime nextUpdate, CFErrorRef *error) {
+ __block bool ok = true;
+ __block CFErrorRef localError = NULL;
+ SecRevocationDbWith(^(SecRevocationDbRef rdb) {
+ ok &= SecRevocationDbPerformWrite(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ return _SecRevocationDbSetNextUpdateTime(dbc, nextUpdate, blockError);
+ });
});
+ (void) CFErrorPropagate(localError, error);
+ return ok;
}
/* Return the next update value as a CFAbsoluteTime.
CFAbsoluteTime SecRevocationDbGetNextUpdateTime(void) {
__block CFAbsoluteTime result = -1;
SecRevocationDbWith(^(SecRevocationDbRef db) {
- result = _SecRevocationDbGetNextUpdateTime(db, NULL);
+ (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ result = _SecRevocationDbGetNextUpdateTime(dbc, blockError);
+ return true;
+ });
});
return result;
}
dispatch_queue_t SecRevocationDbGetUpdateQueue(void) {
__block dispatch_queue_t result = NULL;
SecRevocationDbWith(^(SecRevocationDbRef db) {
- result = _SecRevocationDbGetUpdateQueue(db);
+ result = (db) ? db->update_queue : NULL;
});
return result;
}
-/* Remove all entries in the revocation database and reset its version to 0.
- (This function is expected to be called only by the database maintainer,
- normally the system instance of trustd.)
-*/
-void SecRevocationDbRemoveAllEntries(void) {
- SecRevocationDbWith(^(SecRevocationDbRef db) {
- _SecRevocationDbRemoveAllEntries(db);
- });
-}
-
/* Release all connections to the revocation database.
*/
void SecRevocationDbReleaseAllConnections(void) {
/* Given a certificate and its issuer, returns a SecValidInfoRef if the
valid database contains matching info; otherwise returns NULL.
- Caller must release the returned SecValidInfoRef by calling
- SecValidInfoRelease when finished.
+ Caller must release the returned SecValidInfoRef when finished.
*/
SecValidInfoRef SecRevocationDbCopyMatching(SecCertificateRef certificate,
SecCertificateRef issuer) {
__block SecValidInfoRef result = NULL;
SecRevocationDbWith(^(SecRevocationDbRef db) {
- result = _SecRevocationDbCopyMatching(db, certificate, issuer);
+ (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ result = _SecRevocationDbCopyMatching(dbc, certificate, issuer);
+ return (bool)result;
+ });
+ });
+ return result;
+}
+
+/* Given an issuer, returns true if an entry for this issuer exists in
+ the database (i.e. a known CA). If the provided certificate is NULL,
+ or its entry is not found, the function returns false.
+*/
+bool SecRevocationDbContainsIssuer(SecCertificateRef issuer) {
+ if (!issuer) {
+ return false;
+ }
+ __block bool result = false;
+ SecRevocationDbWith(^(SecRevocationDbRef db) {
+ (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ CFDataRef issuerHash = SecCertificateCopySHA256Digest(issuer);
+ int64_t groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, blockError);
+ CFReleaseSafe(issuerHash);
+ result = (groupId > 0);
+ return result;
+ });
});
return result;
}
CFIndex SecRevocationDbGetVersion(void) {
__block CFIndex result = -1;
SecRevocationDbWith(^(SecRevocationDbRef db) {
- result = (CFIndex)_SecRevocationDbGetVersion(db, NULL);
+ (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ result = (CFIndex)_SecRevocationDbGetVersion(dbc, blockError);
+ return (result >= 0);
+ });
});
return result;
}
/* Return the current schema version of the revocation database.
- A version of 0 indicates an empty database which must be populated.
- If the schema version cannot be obtained, -1 is returned.
-*/
+ A version of 0 indicates an empty database which must be populated.
+ If the schema version cannot be obtained, -1 is returned.
+ */
CFIndex SecRevocationDbGetSchemaVersion(void) {
__block CFIndex result = -1;
SecRevocationDbWith(^(SecRevocationDbRef db) {
- result = (CFIndex)_SecRevocationDbGetSchemaVersion(db, NULL);
+ result = _SecRevocationDbGetSchemaVersion(db, NULL, NULL);
});
return result;
}
/* Return the current update format of the revocation database.
- A version of 0 indicates the format was unknown.
- If the update format cannot be obtained, -1 is returned.
-*/
+ A version of 0 indicates the format was unknown.
+ If the update format cannot be obtained, -1 is returned.
+ */
CFIndex SecRevocationDbGetUpdateFormat(void) {
__block CFIndex result = -1;
SecRevocationDbWith(^(SecRevocationDbRef db) {
- result = (CFIndex)_SecRevocationDbGetUpdateFormat(db, NULL);
+ (void) SecRevocationDbPerformRead(db, NULL, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) {
+ result = (CFIndex)_SecRevocationDbGetUpdateFormat(dbc, blockError);
+ return (result >= 0);
+ });
});
return result;
}
#ifndef _SECURITY_SECREVOCATIONDB_H_
#define _SECURITY_SECREVOCATIONDB_H_
+#include <CoreFoundation/CFRuntime.h>
#include <CoreFoundation/CFData.h>
#include <CoreFoundation/CFDate.h>
#include <CoreFoundation/CFDictionary.h>
/*!
@typedef SecValidInfoRef
- @abstract Object used to return valid info lookup results.
+ @abstract CFType used to return valid info lookup results.
*/
typedef struct __SecValidInfo *SecValidInfoRef;
struct __SecValidInfo {
+ CFRuntimeBase _base;
+
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
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 knownOnly; // true if intermediate CAs 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
CFDataRef policyConstraints; // policy constraints blob (if policyConstraints is true)
};
-/*!
- @function SecValidInfoRelease
- @abstract Releases a SecValidInfo reference previously obtained from a call to SecRevocationDbCopyMatching.
- @param validInfo The SecValidInfo reference to be released.
- */
-void SecValidInfoRelease(SecValidInfoRef validInfo);
-
/*!
@function SecValidInfoSetAnchor
@abstract Updates a SecValidInfo reference with info about the anchor certificate in a chain.
@abstract Returns a SecValidInfo reference if matching revocation (or allow list) info was found.
@param certificate The certificate whose validity status is being requested.
@param issuer The issuing CA certificate. If the cert is self-signed, the same reference should be passed in both certificate and issuer parameters. Omitting either cert parameter is an error and NULL will be returned.
- @result A SecValidInfoRef if there was matching revocation info. Caller must release this reference when finished by calling SecValidInfoRelease. NULL is returned if no matching info was found in the database.
+ @result A SecValidInfoRef if there was matching revocation info. Caller must release this reference when finished by calling CFRelease. NULL is returned if no matching info was found in the database.
*/
SecValidInfoRef SecRevocationDbCopyMatching(SecCertificateRef certificate,
SecCertificateRef issuer);
+/*!
+ @function SecRevocationDbContainsIssuer
+ @abstract Returns true if the database contains an entry for the specified CA certificate.
+ @param issuer The certificate being checked.
+ @result If a matching issuer group was found, returns true, otherwise false.
+*/
+bool SecRevocationDbContainsIssuer(SecCertificateRef issuer);
+
/*!
@function SecRevocationDbGetVersion
@abstract Returns a CFIndex containing the version number of the database.
*/
void SecRevocationDbInitialize(void);
+extern const CFStringRef kValidUpdateProdServer;
+extern const CFStringRef kValidUpdateCarryServer;
+
+/*!
+ @function SecRevocationDbCopyUpdateSource
+ @abstract Returns the server source for updates of the revocation database.
+ @result The base string of the server URI.
+ */
+CFStringRef SecRevocationDbCopyUpdateSource(void);
+
__END_DECLS
*
*/
+#ifndef _SECURITY_SECREVOCATIONNETWORKING_H_
+#define _SECURITY_SECREVOCATIONNETWORKING_H_
+
#import <CoreFoundation/CoreFoundation.h>
+#import <securityd/SecRevocationServer.h>
bool SecValidUpdateRequest(dispatch_queue_t queue, CFStringRef server, CFIndex version);
+bool SecORVCBeginFetches(SecORVCRef orvc, SecCertificateRef cert);
+
+#endif /* _SECURITY_SECREVOCATIONNETWORKING_H_ */
#include <sys/sysctl.h>
#include <sys/time.h>
+#include <mach/mach_time.h>
#include <os/transaction_private.h>
+#include <Security/SecCertificateInternal.h>
#include "utilities/debugging.h"
#include "utilities/SecCFWrappers.h"
#include "utilities/SecPLWrappers.h"
#include "utilities/SecFileLocations.h"
#include "SecRevocationDb.h"
+#include "SecRevocationServer.h"
+#include "SecTrustServer.h"
+#include "SecOCSPRequest.h"
+#include "SecOCSPResponse.h"
+
#import "SecTrustLoggingServer.h"
+#import "TrustURLSessionDelegate.h"
#import "SecRevocationNetworking.h"
+/* MARK: Valid Update Networking */
#define kSecRevocationBasePath "/Library/Keychains/crls"
static CFStringRef kSecPrefsDomain = CFSTR("com.apple.security");
@implementation ValidDelegate
- (void)reschedule {
- /* make sure we release any os transaction, if we went active */
- if (self->_transaction) {
- //os_release(self->_transaction); // ARC does this for us and won't let us call release
- self->_transaction = NULL;
- }
/* POWER LOG EVENT: operation canceled */
SecPLLogRegisteredEvent(@"ValidUpdateEvent", @{
@"timestamp" : @([[NSDate date] timeIntervalSince1970]),
self->_handler();
SecRevocationDbComputeAndSetNextUpdateTime();
+ if (self->_transaction) {
+ self->_transaction = nil;
+ }
}
- (void)updateDb:(NSUInteger)version {
return;
}
+ /* Hold a transaction until we finish the update */
+ __block os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.updateDb");
dispatch_async(_revDbUpdateQueue, ^{
/* POWER LOG EVENT: background update started */
SecPLLogRegisteredEvent(@"ValidUpdateEvent", @{
secerror("failed to read %@ with error %d", updateFileURL, rtn);
TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, rtn);
[self reschedule];
+ transaction = nil;
return;
}
gUpdateStarted = 0;
self->_handler();
+ transaction = nil; // we're all done now
});
}
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
+ /* nsurlsessiond started our download. Create a transaction since we're going to be working for a little bit */
+ self->_transaction = os_transaction_create("com.apple.trustd.valid.download");
secinfo("validupdate", "Session %@ data task %@ returned response %ld, expecting %lld bytes", session, dataTask,
(long)[(NSHTTPURLResponse *)response statusCode],[response expectedContentLength]);
return;
}
- /* We're about to begin downloading -- go active now so we don't get jetsammed */
- self->_transaction = os_transaction_create("com.apple.trustd.valid.download");
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {
- /* all finished downloading data -- go inactive */
- if (self->_transaction) {
- // os_release(self->_transaction); // ARC does this for us and won't let us call release
- self->_transaction = NULL;
- }
if (error) {
secnotice("validupdate", "Session %@ task %@ failed with error %@", session, task, error);
#if ENABLE_TRUSTD_ANALYTICS
self->_finishedDownloading = YES;
[self updateDb:[self versionFromTask:task]];
}
+ if (self->_transaction) {
+ self->_transaction = nil;
+ }
}
@end
* after system boot before trying to initiate network activity, to avoid the possibility
* of a performance regression in the boot path. */
dispatch_async(updateQueue, ^{
+ /* Take a transaction while we work */
+ os_transaction_t transaction = os_transaction_create("com.apple.trustd.valid.scheduleUpdate");
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
if (self.updateScheduled != 0.0) {
secdebug("validupdate", "update in progress (scheduled %f)", (double)self.updateScheduled);
/* clear all old sessions and cleanup disk (for previous download tasks) */
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
- [NSURLSession _obliterateAllBackgroundSessionsWithCompletionHandler:^{
- secnotice("validupdate", "removing all old sessions for trustd");
- }];
+ @autoreleasepool {
+ [NSURLSession _obliterateAllBackgroundSessionsWithCompletionHandler:^{
+ secnotice("validupdate", "removing all old sessions for trustd");
+ }];
+ }
});
if (!self.backgroundSession) {
[self createSession:updateQueue forServer:server];
+ } else {
+ ValidDelegate *delegate = (ValidDelegate *)[self.backgroundSession delegate];
+ delegate.currentUpdateServer = [server copy];
}
/* POWER LOG EVENT: scheduling our background download session now */
dataTask.taskDescription = [NSString stringWithFormat:@"%lu",(unsigned long)version];
[dataTask resume];
secnotice("validupdate", "scheduled background data task %@ at %f", dataTask, CFAbsoluteTimeGetCurrent());
+ (void) transaction; // dead store
+ transaction = nil;
});
return YES;
@end
bool SecValidUpdateRequest(dispatch_queue_t queue, CFStringRef server, CFIndex version) {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- request = [[ValidUpdateRequest alloc] init];
- });
- return [request scheduleUpdateFromServer:(__bridge NSString*)server forVersion:version withQueue:queue];
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ @autoreleasepool {
+ request = [[ValidUpdateRequest alloc] init];
+ }
+ });
+ @autoreleasepool {
+ return [request scheduleUpdateFromServer:(__bridge NSString*)server forVersion:version withQueue:queue];
+ }
+}
+
+/* MARK: - */
+/* MARK: OCSP Fetch Networking */
+#define OCSP_REQUEST_THRESHOLD 10
+
+@interface OCSPFetchDelegate : TrustURLSessionDelegate
+@end
+
+@implementation OCSPFetchDelegate
+- (BOOL)fetchNext:(NSURLSession *)session {
+ SecORVCRef orvc = (SecORVCRef)self.context;
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(orvc->builder);
+
+ BOOL result = true;
+ if ((result = [super fetchNext:session])) {
+ /* no fetch scheduled */
+ orvc->done = true;
+ } else {
+ if (self.URIix > 0) {
+ orvc->responder = (__bridge CFURLRef)self.URIs[self.URIix - 1];
+ } else {
+ orvc->responder = (__bridge CFURLRef)self.URIs[0];
+ }
+ if (analytics) {
+ analytics->ocsp_fetches++;
+ }
+ }
+ return result;
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
+ /* call the superclass's method to set expiration */
+ [super URLSession:session task:task didCompleteWithError:error];
+
+ __block SecORVCRef orvc = (SecORVCRef)self.context;
+ if (!orvc || !orvc->builder) {
+ /* We already returned to the PathBuilder state machine. */
+ return;
+ }
+
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(orvc->builder);
+ if (error) {
+ /* Log the error */
+ secnotice("rvc", "Failed to download ocsp response %@, with error %@", task.originalRequest.URL, error);
+ if (analytics) {
+ analytics->ocsp_fetch_failed++;
+ }
+ } else {
+ SecOCSPResponseRef ocspResponse = SecOCSPResponseCreate((__bridge CFDataRef)self.response);
+ if (ocspResponse) {
+ SecORVCConsumeOCSPResponse(orvc, ocspResponse, self.expiration, true, false);
+ if (analytics && !orvc->done) {
+ /* We got an OCSP response that didn't pass validation */
+ analytics-> ocsp_validation_failed = true;
+ }
+ } else if (analytics) {
+ /* We got something that wasn't an OCSP response (e.g. captive portal) --
+ * we consider that a fetch failure */
+ analytics->ocsp_fetch_failed++;
+ }
+ }
+
+ /* If we didn't get a valid OCSP response, try the next URI */
+ if (!orvc->done) {
+ (void)[self fetchNext:session];
+ }
+
+ /* We got a valid OCSP response or couldn't schedule any more fetches.
+ * Close the session, update the PVCs, decrement the async count, and callback if we're all done. */
+ if (orvc->done) {
+ secdebug("rvc", "builder %p, done with OCSP fetches for cert: %ld", orvc->builder, orvc->certIX);
+ self.context = nil;
+ [session invalidateAndCancel];
+ SecORVCUpdatePVC(orvc);
+ if (0 == SecPathBuilderDecrementAsyncJobCount(orvc->builder)) {
+ /* We're the last async job to finish, jump back into the state machine */
+ secdebug("rvc", "builder %p, done with all async jobs", orvc->builder);
+ dispatch_async(SecPathBuilderGetQueue(orvc->builder), ^{
+ SecPathBuilderStep(orvc->builder);
+ });
+ }
+ }
+}
+
+- (NSURLRequest *)createNextRequest:(NSURL *)uri {
+ SecORVCRef orvc = (SecORVCRef)self.context;
+ CFDataRef ocspDER = CFRetainSafe(SecOCSPRequestGetDER(orvc->ocspRequest));
+ NSData *nsOcspDER = CFBridgingRelease(ocspDER);
+ NSString *ocspBase64 = [nsOcspDER base64EncodedStringWithOptions:0];
+ NSString *escapedRequest = [ocspBase64 stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
+ NSURLRequest *request = nil;
+
+ /* Interesting tidbit from rfc5019
+ When sending requests that are less than or equal to 255 bytes in
+ total (after encoding) including the scheme and delimiters (http://),
+ server name and base64-encoded OCSPRequest structure, clients MUST
+ use the GET method (to enable OCSP response caching). OCSP requests
+ larger than 255 bytes SHOULD be submitted using the POST method.
+ */
+ if ([escapedRequest length] < 256) {
+ /* Use a GET */
+ NSURL *requestURL = [uri URLByAppendingPathComponent:escapedRequest];
+ request = [NSURLRequest requestWithURL:requestURL];
+ } else {
+ /* Use a POST */
+ NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:uri];
+ mutableRequest.HTTPMethod = @"POST";
+ mutableRequest.HTTPBody = nsOcspDER;
+ request = mutableRequest;
+ }
+
+ return request;
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)taskMetrics {
+ secdebug("rvc", "got metrics with task interval %f", taskMetrics.taskInterval.duration);
+ SecORVCRef orvc = (SecORVCRef)self.context;
+ if (orvc && orvc->builder) {
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(orvc->builder);
+ if (analytics) {
+ analytics->ocsp_fetch_time += (uint64_t)(taskMetrics.taskInterval.duration * NSEC_PER_SEC);
+ }
+ }
+}
+@end
+
+bool SecORVCBeginFetches(SecORVCRef orvc, SecCertificateRef cert) {
+ @autoreleasepool {
+ CFArrayRef ocspResponders = CFRetainSafe(SecCertificateGetOCSPResponders(cert));
+ NSArray *nsResponders = CFBridgingRelease(ocspResponders);
+
+ NSInteger count = [nsResponders count];
+ if (count > OCSP_REQUEST_THRESHOLD) {
+ secnotice("rvc", "too may OCSP responder entries (%ld)", (long)count);
+ orvc->done = true;
+ return true;
+ }
+
+ NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
+ config.timeoutIntervalForResource = TrustURLSessionGetResourceTimeout();
+ config.HTTPAdditionalHeaders = @{@"User-Agent" : @"com.apple.trustd/2.0"};
+
+ NSData *auditToken = CFBridgingRelease(SecPathBuilderCopyClientAuditToken(orvc->builder));
+ if (auditToken) {
+ config._sourceApplicationAuditTokenData = auditToken;
+ }
+
+ OCSPFetchDelegate *delegate = [[OCSPFetchDelegate alloc] init];
+ delegate.context = orvc;
+ delegate.URIs = nsResponders;
+ delegate.URIix = 0;
+
+ NSOperationQueue *queue = [[NSOperationQueue alloc] init];
+
+ NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:queue];
+ secdebug("rvc", "created URLSession for %@", cert);
+
+ bool result = false;
+ if ((result = [delegate fetchNext:session])) {
+ /* no fetch scheduled, close the session */
+ [session invalidateAndCancel];
+ }
+ return result;
+ }
}
#include <securityd/SecTrustServer.h>
#include <securityd/SecOCSPRequest.h>
#include <securityd/SecOCSPResponse.h>
-#include <securityd/asynchttp.h>
#include <securityd/SecOCSPCache.h>
#include <securityd/SecRevocationDb.h>
#include <securityd/SecCertificateServer.h>
#include <securityd/SecPolicyServer.h>
+#include <securityd/SecRevocationNetworking.h>
#include <securityd/SecRevocationServer.h>
const CFAbsoluteTime kSecOCSPResponseOnlineTTL = 5.0 * 60.0;
#define OCSP_RESPONSE_TIMEOUT (3 * NSEC_PER_SEC)
-/* OCSP Revocation verification context. */
-struct OpaqueSecORVC {
- /* Will contain the response data. */
- asynchttp_t http;
-
- /* Pointer to the builder for this revocation check. */
- SecPathBuilderRef builder;
-
- /* Pointer to the generic rvc for this revocation check */
- SecRVCRef rvc;
-
- /* The ocsp request we send to each responder. */
- SecOCSPRequestRef ocspRequest;
-
- /* The freshest response we received so far, from stapling or cache or responder. */
- SecOCSPResponseRef ocspResponse;
-
- /* The best validated candidate single response we received so far, from stapling or cache or responder. */
- SecOCSPSingleResponseRef ocspSingleResponse;
-
- /* Index of cert in builder that this RVC is for 0 = leaf, etc. */
- CFIndex certIX;
-
- /* Index in array returned by SecCertificateGetOCSPResponders() for current
- responder. */
- CFIndex responderIX;
-
- /* URL of current responder. */
- CFURLRef responder;
-
- /* Date until which this revocation status is valid. */
- CFAbsoluteTime nextUpdate;
-
- bool done;
-};
-
static void SecORVCFinish(SecORVCRef orvc) {
- secdebug("alloc", "%p", orvc);
- asynchttp_free(&orvc->http);
+ secdebug("alloc", "finish orvc %p", orvc);
if (orvc->ocspRequest) {
SecOCSPRequestFinalize(orvc->ocspRequest);
orvc->ocspRequest = NULL;
orvc->ocspSingleResponse = NULL;
}
}
-}
-
-#define MAX_OCSP_RESPONDERS 3
-#define OCSP_REQUEST_THRESHOLD 10
-
-/* Return the next responder we should contact for this rvc or NULL if we
- exhausted them all. */
-static CFURLRef SecORVCGetNextResponder(SecORVCRef rvc) {
- SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX);
- CFArrayRef ocspResponders = SecCertificateGetOCSPResponders(cert);
- if (ocspResponders) {
- CFIndex responderCount = CFArrayGetCount(ocspResponders);
- if (responderCount >= OCSP_REQUEST_THRESHOLD) {
- secnotice("rvc", "too many ocsp responders (%ld)", (long)responderCount);
- return NULL;
- }
- while (rvc->responderIX < responderCount && rvc->responderIX < MAX_OCSP_RESPONDERS) {
- CFURLRef responder = CFArrayGetValueAtIndex(ocspResponders, rvc->responderIX);
- rvc->responderIX++;
- CFStringRef scheme = CFURLCopyScheme(responder);
- if (scheme) {
- /* We only support http and https responders currently. */
- bool valid_responder = (CFEqual(CFSTR("http"), scheme) ||
- CFEqual(CFSTR("https"), scheme));
- CFRelease(scheme);
- if (valid_responder)
- return responder;
- }
- }
- }
- return NULL;
-}
-
-/* Fire off an async http request for this certs revocation status, return
- false if request was queued, true if we're done. */
-static bool SecORVCFetchNext(SecORVCRef rvc) {
- while ((rvc->responder = SecORVCGetNextResponder(rvc))) {
- CFDataRef request = SecOCSPRequestGetDER(rvc->ocspRequest);
- if (!request)
- goto errOut;
-
- secinfo("rvc", "Sending http ocsp request for cert %ld", rvc->certIX);
- if (!asyncHttpPost(rvc->responder, request, OCSP_RESPONSE_TIMEOUT, &rvc->http)) {
- /* Async request was posted, wait for reply. */
- return false;
- }
- }
-
-errOut:
- rvc->done = true;
- return true;
+ memset(orvc, 0, sizeof(struct OpaqueSecORVC));
}
/* Process a verified ocsp response for a given cert. Return true if the
return processed;
}
-static void SecORVCUpdatePVC(SecORVCRef rvc) {
+void SecORVCUpdatePVC(SecORVCRef rvc) {
if (rvc->ocspSingleResponse) {
SecOCSPSingleResponseProcess(rvc->ocspSingleResponse, rvc);
}
signer = (SecCertificateRef)CFArrayGetValueAtIndex(signers, 0);
if (issuer) {
-#if TARGET_OS_IPHONE
- issuerPubKey = SecCertificateCopyPublicKey(issuer);
-#else
- issuerPubKey = SecCertificateCopyPublicKey_ios(issuer);
-#endif
+ issuerPubKey = SecCertificateCopyKey(issuer);
}
if (signer && issuerPubKey && (errSecSuccess == SecCertificateIsSignedBy(signer, issuerPubKey))) {
trusted = true;
return trusted;
}
-static void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspResponse /*CF_CONSUMED*/, CFTimeInterval maxAge, bool updateCache) {
+void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspResponse /*CF_CONSUMED*/,
+ CFTimeInterval maxAge, bool updateCache, bool fromCache) {
SecOCSPSingleResponseRef sr = NULL;
require_quiet(ocspResponse, errOut);
SecOCSPResponseStatus orStatus = SecOCSPGetResponseStatus(ocspResponse);
require_quiet(!rvc->ocspSingleResponse || rvc->ocspSingleResponse->thisUpdate < sr->thisUpdate, errOut);
CFAbsoluteTime verifyTime = CFAbsoluteTimeGetCurrent();
- /* Check the OCSP response signature and verify the response. */
+#if TARGET_OS_IPHONE
+ /* Check the OCSP response signature and verify the response if not pulled from the cache.
+ * Performance optimization since we don't write invalid responses to the cache. */
+ if (!fromCache) {
+ require_quiet(SecOCSPResponseVerify(ocspResponse, rvc,
+ sr->certStatus == CS_Revoked ? SecOCSPResponseProducedAt(ocspResponse) : verifyTime), errOut);
+ }
+#else
+ /* Always check the OCSP response signature and verify the response (since the cache is user-modifiable). */
require_quiet(SecOCSPResponseVerify(ocspResponse, rvc,
sr->certStatus == CS_Revoked ? SecOCSPResponseProducedAt(ocspResponse) : verifyTime), errOut);
+#endif
// If we get here, we have a properly signed ocsp response
// but we haven't checked dates yet.
if (ocspResponse) SecOCSPResponseFinalize(ocspResponse);
}
-/* Callback from async http code after an ocsp response has been received. */
-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);
- if (data) {
- /* Parse the returned data as if it's an ocspResponse. */
- ocspResponse = SecOCSPResponseCreate(data);
- CFRelease(data);
- }
- }
-
- 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);
- }
-
- if (rvc->done) {
- secdebug("rvc", "got OCSP response for cert: %ld", rvc->certIX);
- SecORVCUpdatePVC(rvc);
- if (!SecPathBuilderDecrementAsyncJobCount(builder)) {
- secdebug("rvc", "done with all async jobs");
- SecPathBuilderStep(builder);
- }
- }
-}
-
static SecORVCRef SecORVCCreate(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) {
SecORVCRef orvc = NULL;
orvc = malloc(sizeof(struct OpaqueSecORVC));
+ secdebug("alloc", "orvc %p", orvc);
if (orvc) {
memset(orvc, 0, sizeof(struct OpaqueSecORVC));
orvc->builder = builder;
orvc->rvc = rvc;
orvc->certIX = certIX;
- orvc->http.queue = SecPathBuilderGetQueue(builder);
- orvc->http.token = SecPathBuilderCopyClientAuditToken(builder);
- orvc->http.completed = SecOCSPFetchCompleted;
- orvc->http.info = orvc;
- orvc->ocspRequest = NULL;
- orvc->responderIX = 0;
- orvc->responder = NULL;
- orvc->nextUpdate = NULL_TIME;
- orvc->ocspResponse = NULL;
- orvc->ocspSingleResponse = NULL;
- orvc->done = false;
SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(builder, certIX);
if (SecPathBuilderGetCertificateCount(builder) > (certIX + 1)) {
secdebug("rvc", "Checking stapled responses for cert %ld", rvc->certIX);
CFArrayForEach(ocspResponsesData, ^(const void *value) {
SecOCSPResponseRef ocspResponse = SecOCSPResponseCreate(value);
- SecORVCConsumeOCSPResponse(rvc, ocspResponse, NULL_TIME, false);
+ SecORVCConsumeOCSPResponse(rvc, ocspResponse, NULL_TIME, false, false);
});
CFRelease(ocspResponsesData);
}
#endif /* ENABLE_CRLS */
void SecRVCDelete(SecRVCRef rvc) {
+ secdebug("alloc", "delete rvc %p", rvc);
if (rvc->orvc) {
SecORVCFinish(rvc->orvc);
free(rvc->orvc);
}
#endif
if (rvc->valid_info) {
- SecValidInfoRelease(rvc->valid_info);
- rvc->valid_info = NULL;
+ CFReleaseNull(rvc->valid_info);
}
}
+// Forward declaration
+static void SecRVCSetFinishedWithoutNetwork(SecRVCRef rvc);
+
static void SecRVCInit(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) {
- secdebug("alloc", "%p", rvc);
+ secdebug("alloc", "rvc %p", rvc);
rvc->builder = builder;
rvc->certIX = certIX;
rvc->orvc = SecORVCCreate(rvc, builder, certIX);
#endif
) {
SecRVCDelete(rvc);
- rvc->done = true;
+ SecRVCSetFinishedWithoutNetwork(rvc);
} else {
rvc->done = false;
}
return (!info->isOnList && info->valid) || (info->isOnList && !info->valid);
}
-void SecRVCSetRevokedResult(SecRVCRef rvc) {
+void SecRVCSetValidDeterminedErrorResult(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,
+ SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckGrayListedLeaf, rvc->certIX,
+ kCFBooleanFalse, true);
+ return;
+ }
+ /* error is fatal at this point */
+ if (!SecRVCHasRevokedValidInfo(rvc) || rvc->valid_info->noCACheck) {
+ /* result key should indicate blocked instead of revoked,
+ * but result must be non-recoverable */
+ SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckBlackListedLeaf, 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,
} else {
analytics->valid_status |= definitive ? TAValidDefinitelyOK : TAValidProbablyOK;
}
+ analytics->valid_require_ct |= info->requireCT;
+ analytics->valid_known_intermediates_only |= info->knownOnly;
}
/* Handle no-ca cases */
bool allowed = (info->valid && info->complete && info->isOnList);
if (revoked) {
/* definitely revoked */
- SecRVCSetRevokedResult(rvc);
+ SecRVCSetValidDeterminedErrorResult(rvc);
} else if (allowed) {
/* definitely not revoked (allowlisted) */
SecCertificatePathVCSetIsAllowlisted(path, true);
/* Set CT requirement on path, if present. */
if (info->requireCT) {
- if (analytics) {
- analytics->valid_require_ct |= info->requireCT;
- }
SecPathCTPolicy ctp = kSecPathCTRequired;
if (info->overridable) {
ctp = kSecPathCTRequiredOverridable;
}
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) {
chain, since we don't have its issuer. */
return;
}
- CFIndex pvcIX;
- for (pvcIX = 0; pvcIX < SecPathBuilderGetPVCCount(rvc->builder); pvcIX++) {
- SecPVCRef pvc = SecPathBuilderGetPVCAtIndex(rvc->builder, pvcIX);
- if (!pvc) { continue; }
- SecPolicyRef policy = (SecPolicyRef)CFArrayGetValueAtIndex(pvc->policies, 0);
- CFStringRef policyName = (policy) ? SecPolicyGetName(policy) : NULL;
- if (policyName && CFEqual(CFSTR("sslServer"), policyName)) {
- /* perform revocation check for SSL policy;
- require for leaf if an OCSP responder is present. */
- if (0 == rvc->certIX) {
- SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX);
- CFArrayRef resps = (cert) ? SecCertificateGetOCSPResponders(cert) : NULL;
- CFIndex rcount = (resps) ? CFArrayGetCount(resps) : 0;
- if (rcount > 0) {
- // %%% rdar://31279923
- // This currently requires a valid revocation response for each cert,
- // but we only want to require a leaf check. For now, do not require.
- //SecPathBuilderSetRevocationResponseRequired(rvc->builder);
- }
- }
- secdebug("validupdate", "rvc: %s%s cert %" PRIdCFIndex " (will check OCSP)",
- (info->complete) ? "" : "possibly ", (info->valid) ? "allowed" : "revoked",
- rvc->certIX);
- SecPathBuilderSetRevocationMethod(rvc->builder, kSecPolicyCheckRevocationAny);
- }
+ secdebug("validupdate", "rvc: %s%s cert %" PRIdCFIndex " (will check OCSP)",
+ (info->complete) ? "" : "possibly ", (info->valid) ? "allowed" : "revoked",
+ rvc->certIX);
+ SecPathBuilderSetRevocationMethod(rvc->builder, kSecPolicyCheckRevocationAny);
+ if (analytics) {
+ /* Valid DB results caused us to do OCSP */
+ analytics->valid_trigger_ocsp = true;
}
}
}
SecValidInfoRef old_info = rvc->valid_info;
rvc->valid_info = info;
if (old_info) {
- SecValidInfoRelease(old_info);
+ CFReleaseNull(old_info);
}
return true;
}
} else {
response = SecOCSPCacheCopyMatching(rvc->orvc->ocspRequest, NULL);
}
- SecORVCConsumeOCSPResponse(rvc->orvc,
- response,
- NULL_TIME, false);
+ SecORVCConsumeOCSPResponse(rvc->orvc, response, NULL_TIME, false, true);
TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder);
if (rvc->orvc->done && analytics) {
/* We found a valid OCSP response in the cache */
#endif
}
+static void SecRVCSetFinishedWithoutNetwork(SecRVCRef rvc) {
+ rvc->done = true;
+ SecRVCUpdatePVC(rvc);
+ (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder);
+#if ENABLE_CRLS
+ (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder);
+#endif
+}
+
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);
+ SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder);
+ SecCertificateRef cert = SecCertificatePathVCGetCertificateAtIndex(path, rvc->certIX);
+ OCSP_fetch_finished = SecORVCBeginFetches(rvc->orvc, cert);
+ if (analytics && !OCSP_fetch_finished) {
+ /* We did a network OCSP fetch, set report appropriately */
+ analytics->ocsp_network = true;
+ }
}
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
secdebug("rvc", "Not rechecking revocation");
}
- CFIndex certIX, certCount = SecPathBuilderGetCertificateCount(builder);
- for (certIX = 0; certIX < certCount; ++certIX) {
- SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, certIX);
- if (rvc && !recheck) {
- SecRVCUpdatePVC(rvc);
- } else if (rvc) {
- SecRVCDelete(rvc); // reset the RVC for the second pass
+ if (recheck) {
+ // reset the RVCs for the second pass
+ SecCertificatePathVCDeleteRVCs(path);
+ } else {
+ CFIndex certIX, certCount = SecPathBuilderGetCertificateCount(builder);
+ for (certIX = 0; certIX < certCount; ++certIX) {
+ SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, certIX);
+ if (rvc) {
+ SecRVCUpdatePVC(rvc);
+ }
}
}
+
return !recheck;
}
return SecPathBuilderCanAccessNetwork(builder);
}
+void SecPathBuilderCheckKnownIntermediateConstraints(SecPathBuilderRef builder) {
+ SecCertificatePathVCRef path = SecPathBuilderGetPath(builder);
+ if (!path) {
+ return;
+ }
+ /* only perform this check once per path! */
+ CFIndex certIX = kCFNotFound;
+ if (SecCertificatePathVCCheckedIssuers(path)) {
+ certIX = SecCertificatePathVCUnknownCAIndex(path);
+ goto checkedIssuers;
+ }
+ /* check full path: start with anchor and decrement to leaf */
+ bool parentConstrained = false;
+ CFIndex certCount = SecPathBuilderGetCertificateCount(builder);
+ for (certIX = certCount - 1; certIX >= 0; --certIX) {
+ SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, certIX);
+ if (!rvc) {
+ continue;
+ }
+ if (parentConstrained && !rvc->valid_info) {
+ /* Parent had the known-only constraint, but our issuer is unknown.
+ Bump index to point back at the issuer since it fails the constraint. */
+ certIX++;
+ break;
+ }
+ parentConstrained = (rvc->valid_info && rvc->valid_info->knownOnly);
+ if (parentConstrained) {
+ secdebug("validupdate", "Valid db found a known-intermediate constraint on %@ (index=%ld)",
+ rvc->valid_info->issuerHash, certIX+1);
+ if (certIX == 0) {
+ /* check special case: unknown constrained CA in leaf position */
+ SecCertificateRef cert = SecCertificatePathVCGetCertificateAtIndex(path, certIX);
+ if (cert && SecCertificateIsCA(cert) && !SecRevocationDbContainsIssuer(cert)) {
+ /* leaf is a CA which violates the constraint */
+ break;
+ }
+ }
+ }
+ }
+ /* At this point, certIX will either be -1, indicating no CA was found
+ which failed a known-intermediates-only constraint on its parent, or it
+ will be the index of the first unknown CA which fails the constraint. */
+ if (certIX >= 0) {
+ secnotice("validupdate", "CA at index %ld violates known-intermediate constraint", certIX);
+ TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder);
+ if (analytics) {
+ analytics->valid_unknown_intermediate = true;
+ }
+ /* [40648172] For now, log this error but do not fail the evaluation. */
+ certIX = -1;
+ }
+ SecCertificatePathVCSetUnknownCAIndex(path, certIX);
+ SecCertificatePathVCSetCheckedIssuers(path, true);
+
+checkedIssuers:
+ if (certIX >= 0) {
+ /* Error is set on CA certificate which failed the constraint. */
+ SecRVCSetValidDeterminedErrorResult(SecCertificatePathVCGetRVCAtIndex(path, certIX));
+ }
+}
+
bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) {
secdebug("rvc", "checking revocation");
CFIndex certIX, certCount = SecPathBuilderGetCertificateCount(builder);
SecCertificatePathVCRef path = SecPathBuilderGetPath(builder);
- bool completed = true;
if (certCount <= 1) {
/* Can't verify without an issuer; we're done */
- return completed;
+ return true;
}
bool first_check_done = false;
if (SecRevocationDidCheckRevocation(builder, &first_check_done)) {
- return completed;
+ return true;
}
/* Setup things so we check revocation status of all certs. */
/* Note that if we are multi threaded and a job completes after it
is started but before we return from this function, we don't want
a callback to decrement asyncJobCount to zero before we finish issuing
- all the jobs. To avoid this we pretend we issued certCount-1 async jobs,
+ all the jobs. To avoid this we pretend we issued certCount async jobs,
and decrement pvc->asyncJobCount for each cert that we don't start a
- background fetch for. (We will never start an async job for the final
- cert in the chain.) */
+ background fetch for. We include the root, even though we'll never start
+ an async job for it so that we count all active threads for this eval. */
#if !ENABLE_CRLS
- SecPathBuilderSetAsyncJobCount(builder, (unsigned int)(certCount-1));
+ SecPathBuilderSetAsyncJobCount(builder, (unsigned int)(certCount));
#else
/* If we enable CRLS, we may end up with two async jobs per cert: one
- * for OCSP and one for fetching the CRL */
- SecPathBuilderSetAsyncJobCount(builder, 2 * (unsigned int)(certCount-1));
+ * for OCSP and one for fetching the CRL. Except the root, which only
+ * needs to track this thread. */
+ SecPathBuilderSetAsyncJobCount(builder, 2 * (unsigned int)(certCount) - 1);
#endif
/* Loop though certificates again and issue an ocsp fetch if the
/* This certificate has OCSP No-Check, so add to reporting analytics */
analytics->ocsp_no_check = true;
}
- rvc->done = true;
+ SecRVCSetFinishedWithoutNetwork(rvc);
}
if (rvc->done) {
#endif
/* Any other revocation method requires an issuer certificate to verify the response;
* skip the last cert in the chain since it doesn't have one. */
- if (certIX+1 >= certCount) {
+ if (certIX + 1 >= certCount) {
continue;
}
#if TARGET_OS_BRIDGE
/* The bridge has no writeable storage and no network. Nothing else we can
* do here. */
- rvc->done = true;
- return completed;
+ SecRVCSetFinishedWithoutNetwork(rvc);
+ continue;
#endif
/* Then check the caches for revocation results. */
SecRVCCheckRevocationCaches(rvc);
/* The check is done if we found cached responses from either method. */
- if (rvc->orvc->done
+ if (rvc->done || rvc->orvc->done
#if ENABLE_CRLS
|| rvc->crvc->done
#endif
) {
secdebug("rvc", "found cached response for cert: %ld", certIX);
- rvc->done = true;
+ SecRVCSetFinishedWithoutNetwork(rvc);
+ continue;
}
/* If we got a cached response that is no longer valid (which can only be true for
bool allow_fetch = SecRevocationCanAccessNetwork(builder, first_check_done) &&
(SecCertificatePathVCIsEV(path) || SecCertificatePathVCIsOptionallyEV(path) ||
SecPathBuilderGetRevocationMethod(builder) || old_cached_response);
- bool fetch_done = true;
if (rvc->done || !allow_fetch) {
/* We got a cache hit or we aren't allowed to access the network */
SecRVCUpdatePVC(rvc);
(void)SecPathBuilderDecrementAsyncJobCount(builder);
#endif
} else {
- fetch_done = SecRVCFetchNext(rvc);
- }
- if (!fetch_done) {
- /* We started at least one background fetch. */
- secdebug("rvc", "waiting on background fetch for cert %ld", certIX);
- completed = false;
+ (void)SecRVCFetchNext(rvc);
}
}
- /* Return false if we started any background jobs. */
- /* We can't just return !builder->asyncJobCount here, since if we started any
- jobs the completion callback will be called eventually and it will call
- SecPathBuilderStep(). If for some reason everything completed before we
- get here we still want the outer SecPathBuilderStep() to terminate so we
- keep track of whether we started any jobs and return false if so. */
- return completed;
+ /* Return false if there are still async jobs running. */
+ /* builder->asyncJobCount is atomic, so we know that if the job count is 0, all other
+ * threads are finished. If the job count is > 0, other threads will decrement the job
+ * count and SecPathBuilderStep to crank the state machine when the job count is 0. */
+ return (SecPathBuilderDecrementAsyncJobCount(builder) == 0);
}
CFAbsoluteTime SecRVCGetEarliestNextUpdate(SecRVCRef rvc) {
#include <securityd/SecTrustServer.h>
#include <securityd/SecRevocationDb.h>
+#include <securityd/SecOCSPRequest.h>
+#include <securityd/SecOCSPResponse.h>
typedef struct OpaqueSecORVC *SecORVCRef;
#if ENABLE_CRLS
};
typedef struct OpaqueSecRVC *SecRVCRef;
+/* OCSP Revocation verification context. */
+struct OpaqueSecORVC {
+ /* Pointer to the builder for this revocation check. */
+ SecPathBuilderRef builder;
+
+ /* Pointer to the generic rvc for this revocation check */
+ SecRVCRef rvc;
+
+ /* The ocsp request we send to each responder. */
+ SecOCSPRequestRef ocspRequest;
+
+ /* The freshest response we received so far, from stapling or cache or responder. */
+ SecOCSPResponseRef ocspResponse;
+
+ /* The best validated candidate single response we received so far, from stapling or cache or responder. */
+ SecOCSPSingleResponseRef ocspSingleResponse;
+
+ /* Index of cert in builder that this RVC is for 0 = leaf, etc. */
+ CFIndex certIX;
+
+ /* Date until which this revocation status is valid. */
+ CFAbsoluteTime nextUpdate;
+
+ /* URL of current responder. For logging purposes. */
+ CFURLRef responder;
+
+ bool done;
+};
+
bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder);
+void SecPathBuilderCheckKnownIntermediateConstraints(SecPathBuilderRef builder);
CFAbsoluteTime SecRVCGetEarliestNextUpdate(SecRVCRef rvc);
void SecRVCDelete(SecRVCRef rvc);
bool SecRVCHasDefinitiveValidInfo(SecRVCRef rvc);
bool SecRVCHasRevokedValidInfo(SecRVCRef rvc);
-void SecRVCSetRevokedResult(SecRVCRef rvc);
+void SecRVCSetValidDeterminedErrorResult(SecRVCRef rvc);
+
+/* OCSP verification callbacks */
+void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspResponse /*CF_CONSUMED*/,
+ CFTimeInterval maxAge, bool updateCache, bool fromCache);
+void SecORVCUpdatePVC(SecORVCRef rvc);
#endif /* _SECURITY_SECREVOCATIONSERVER_H_ */
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
+#include <stdatomic.h>
#include <limits.h>
#include <sys/codesign.h>
#include <Security/SecBase.h>
#include "personalization.h"
#include <utilities/SecInternalReleasePriv.h>
#include <mach/mach_time.h>
+#include <dispatch/private.h>
#if TARGET_OS_OSX
#include <Security/SecTaskPriv.h>
CFIndex pvcCount;
SecCertificatePathVCRef path;
- unsigned int asyncJobCount;
+ _Atomic unsigned int asyncJobCount;
bool online_revocation;
bool trusted_revocation;
CFStringRef revocation_check_method;
CFArrayRef signedCertificateTimestamps, CFArrayRef trustedLogs,
CFAbsoluteTime verifyTime, CFArrayRef accessGroups, CFArrayRef exceptions,
SecPathBuilderCompleted completed, const void *context) {
- secdebug("alloc", "%p", builder);
+ secdebug("alloc", "builder %p", builder);
CFAllocatorRef allocator = kCFAllocatorDefault;
builder->analyticsData = calloc(1, sizeof(TrustAnalyticsBuilder));
builder->clientAuditToken = (CFDataRef)
((clientAuditToken) ? CFRetain(clientAuditToken) : NULL);
- builder->queue = dispatch_queue_create("builder", DISPATCH_QUEUE_SERIAL);
+
+ /* Put all trust evaluations on the same workloop in order to avoid
+ * high thread fanout and frequent expensive context switches */
+ static dispatch_workloop_t workloop = NULL;
+ static dispatch_once_t onceToken;
+ static const char *recursion_key = "trust-evaluation-recursion-token";
+ dispatch_once(&onceToken, ^{
+ workloop = dispatch_workloop_create("com.apple.trustd.evaluation");
+ });
+ dispatch_queue_t builderQueue = NULL;
+ if (dispatch_workloop_is_current(workloop) || dispatch_get_specific(recursion_key)) {
+ /* If we're on the workloop already or are in a recursive trust evaluation, make a
+ * new thread so that the new path builder block will get scheduled and the blocked
+ * trust evaluation can proceed. */
+ builderQueue = dispatch_queue_create("com.apple.trustd.evaluation.recursive", DISPATCH_QUEUE_SERIAL);
+ dispatch_queue_set_specific(builderQueue, recursion_key, (void *)1, NULL);
+ } else {
+ builderQueue = workloop;
+ dispatch_retain_safe(builderQueue);
+ }
+ builder->queue = builderQueue;
builder->nextParentSource = 1;
#if !TARGET_OS_WATCH
/* <rdar://32728029> */
builder->canAccessNetwork = true;
#endif
+ atomic_init(&builder->asyncJobCount, 0);
builder->anchorSources = CFArrayCreateMutable(allocator, 0, NULL);
builder->parentSources = CFArrayCreateMutable(allocator, 0, NULL);
}
static void SecPathBuilderDestroy(SecPathBuilderRef builder) {
- secdebug("alloc", "%p", builder);
+ secdebug("alloc", "destroy builder %p", builder);
dispatch_release_null(builder->queue);
if (builder->anchorSource) {
SecMemoryCertificateSourceDestroy(builder->anchorSource);
}
unsigned int SecPathBuilderDecrementAsyncJobCount(SecPathBuilderRef builder) {
- return --builder->asyncJobCount;
+ unsigned int result = atomic_fetch_sub(&builder->asyncJobCount, 1);
+ secdebug("rvc", "%p: decrement asyncJobCount from %d", builder, result);
+ /* atomic_fetch_sub returns the original value, but we want this function to return the
+ * value after the operation. */
+ return --result;
}
void SecPathBuilderSetAsyncJobCount(SecPathBuilderRef builder, unsigned int jobCount) {
- builder->asyncJobCount = jobCount;
- secdebug("rvc", "set asyncJobCount to %d", builder->asyncJobCount);
+ atomic_store(&builder->asyncJobCount, jobCount);
+ secdebug("rvc", "%p: set asyncJobCount to %d", builder, jobCount);
+}
+
+unsigned int SecPathBuilderGetAsyncJobCount(SecPathBuilderRef builder) {
+ unsigned int count = atomic_load(&builder->asyncJobCount);
+ secdebug("rvc", "%p: current asyncJobCount is %d", builder, count);
+ return count;
}
CFMutableDictionaryRef SecPathBuilderGetInfo(SecPathBuilderRef builder) {
the completion callback will be invoked and the builder will be deallocated.
*/
bool SecPathBuilderStep(SecPathBuilderRef builder) {
+ secdebug("async", "step builder %p", builder);
if (builder->activations) {
secdebug("async", "activations: %lu returning true",
builder->activations);
builder->bestPath, pvc->details, result);
if (builder->completed) {
+ /* We want to retain just the data we need to return to our caller
+ * and free the rest of the builder before doing the callback.
+ * Since the callback may end an XPC transaction that made us active, we
+ * want to retain as little residual memory as possible. */
CFArrayRef resultPath = SecCertificatePathVCCopyCertificates(builder->bestPath);
- builder->completed(builder->context, resultPath,
- pvc->details, builder->info, result);
+ CFDictionaryRef info = CFRetainSafe(builder->info);
+ CFArrayRef details = CFRetainSafe(pvc->details);
+ const void *context = builder->context;
+ SecPathBuilderCompleted completed = builder->completed;
+
+ secdebug("async", "free builder");
+ SecPathBuilderDestroy(builder);
+ free(builder);
+
+ secdebug("async", "returning to caller");
+ completed(context, resultPath, details, info, result);
CFReleaseNull(resultPath);
+ CFReleaseNull(info);
+ CFReleaseNull(details);
+ } else {
+ SecPathBuilderDestroy(builder);
+ free(builder);
}
- /* Finally, destroy the builder and free it. */
- SecPathBuilderDestroy(builder);
- free(builder);
-
return false;
}
void SecPathBuilderSetResultInPVCs(SecPathBuilderRef builder, CFStringRef key,
CFIndex ix, CFTypeRef result, bool force);
-/* This is a pre-decrement operation */
+/* This is an atomic pre-decrement operation */
unsigned int SecPathBuilderDecrementAsyncJobCount(SecPathBuilderRef builder);
void SecPathBuilderSetAsyncJobCount(SecPathBuilderRef builder, unsigned int jobCount);
+unsigned int SecPathBuilderGetAsyncJobCount(SecPathBuilderRef builder);
CFMutableDictionaryRef SecPathBuilderGetInfo(SecPathBuilderRef builder);
TA_SCT_TLS = 1 << 2,
};
+typedef CF_ENUM(uint8_t, TA_CTFailureReason) {
+ TA_CTNoFailure = 0,
+ TA_CTNoSCTs = 1,
+ TA_CTMissingLogs = 2,
+ TA_CTNoCurrentSCTsUnknownLog = 3,
+ TA_CTNoCurrentSCTsDisqualifiedLog = 4,
+ TA_CTPresentedNotEnoughUnknown = 5,
+ TA_CTPresentedNotEnoughDisqualified = 6,
+ TA_CTPresentedNotEnough = 7,
+ TA_CTEmbeddedNotEnoughUnknown = 8,
+ TA_CTEmbeddedNotEnoughDisqualified = 9,
+ TA_CTEmbeddedNotEnough = 10,
+};
+
typedef CF_OPTIONS(uint8_t, TAValidStatus) {
TAValidDefinitelyOK = 1 << 0,
TAValidProbablyOK = 1 << 1,
TA_SCTSource sct_sources;
uint32_t number_scts;
uint32_t number_trusted_scts;
- size_t total_sct_size;
+ TA_CTFailureReason ct_failure_reason;
+ bool ct_one_current;
// CAIssuer
bool ca_issuer_cache_hit;
bool ca_issuer_network;
TAValidStatus valid_status;
bool valid_trigger_ocsp;
bool valid_require_ct;
+ bool valid_known_intermediates_only;
+ bool valid_unknown_intermediate;
} TrustAnalyticsBuilder;
TrustAnalyticsBuilder *SecPathBuilderGetAnalyticsData(SecPathBuilderRef builder);
static const char copyParentsSQL[] = "SELECT data FROM tsettings WHERE subj=?";
static const char containsSQL[] = "SELECT tset FROM tsettings WHERE sha1=?";
-static const char insertSQL[] = "INSERT INTO tsettings(sha1,subj,tset,data)VALUES(?,?,?,?)";
-static const char updateSQL[] = "UPDATE tsettings SET tset=? WHERE sha1=?";
+static const char insertSQL[] = "INSERT OR REPLACE INTO tsettings(sha1,subj,tset,data)VALUES(?,?,?,?)";
static const char deleteSQL[] = "DELETE FROM tsettings WHERE sha1=?";
static const char deleteAllSQL[] = "BEGIN EXCLUSIVE TRANSACTION; DELETE from tsettings; COMMIT TRANSACTION; VACUUM;";
static const char copyAllSQL[] = "SELECT data,tset FROM tsettings ORDER BY sha1";
require_quiet(ts, errOutNotLocked);
dispatch_sync(ts->queue, ^{
sqlite3_stmt *countAllStmt = NULL;
- int s3e = sqlite3_prepare(ts->s3h, countAllSQL, sizeof(countAllSQL),
+ int s3e = sqlite3_prepare_v2(ts->s3h, countAllSQL, sizeof(countAllSQL),
&countAllStmt, NULL);
if (s3e == SQLITE_OK) {
s3e = sqlite3_step(countAllStmt);
ts->queue = dispatch_queue_create("truststore", DISPATCH_QUEUE_SERIAL);
require_noerr(s3e = sec_sqlite3_open(db_name, &ts->s3h, create), errOut);
- s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
- &ts->copyParents, NULL);
+ s3e = sqlite3_prepare_v3(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
+ SQLITE_PREPARE_PERSISTENT, &ts->copyParents, NULL);
if (create && s3e == SQLITE_ERROR) {
/* sqlite3_prepare returns SQLITE_ERROR if the table we are
compiling this statement for doesn't exist. */
sqlite3_free(errmsg);
}
require_noerr(s3e, errOut);
- s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
- &ts->copyParents, NULL);
+ s3e = sqlite3_prepare_v3(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
+ SQLITE_PREPARE_PERSISTENT, &ts->copyParents, NULL);
}
require_noerr(s3e, errOut);
- require_noerr(s3e = sqlite3_prepare(ts->s3h, containsSQL, sizeof(containsSQL),
- &ts->contains, NULL), errOut);
+ require_noerr(s3e = sqlite3_prepare_v3(ts->s3h, containsSQL, sizeof(containsSQL), SQLITE_PREPARE_PERSISTENT,
+ &ts->contains, NULL), errOut);
if (SecTrustStoreCountAll(ts) == 0) {
ts->containsSettings = false;
require_action_quiet(!ts->readOnly, errOutNotLocked, ok = SecError(errSecReadOnly, error, CFSTR("truststore is readOnly")));
dispatch_sync(ts->queue, ^{
CFTypeRef trustSettingsDictOrArray = tsdoa;
- sqlite3_stmt *insert = NULL, *update = NULL;
+ sqlite3_stmt *insert = NULL;
CFDataRef xmlData = NULL;
CFArrayRef array = NULL;
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(s3e = sqlite3_prepare(ts->s3h, insertSQL, sizeof(insertSQL),
+ require_noerr_action_quiet(s3e = sqlite3_prepare_v2(ts->s3h, insertSQL, sizeof(insertSQL),
&insert, NULL), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(insert, 1,
CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
/* Great the insert worked. */
ok = true;
ts->containsSettings = true;
- } else if (s3e == SQLITE_ERROR) {
- /* Try update. */
- require_noerr_action_quiet(s3e = sqlite3_prepare(ts->s3h, updateSQL, sizeof(updateSQL),
- &update, NULL), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
- require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(update, 1,
- CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData),
- SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
- require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(update, 2,
- CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
- errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
- s3e = sqlite3_step(update);
- require_action_quiet(s3e == SQLITE_DONE, errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
- s3e = SQLITE_OK;
- ok = true;
} else {
require_noerr_action_quiet(s3e, errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e));
ok = true;
if (insert) {
s3e = sqlite3_finalize(insert);
}
- if (update) {
- s3e = sqlite3_finalize(update);
- }
if (ok && s3e == SQLITE_OK) {
s3e = sqlite3_exec(ts->s3h, "COMMIT TRANSACTION", NULL, NULL, NULL);
int s3e = SQLITE_OK;
sqlite3_stmt *deleteStmt = NULL;
- require_noerr(s3e = sqlite3_prepare(ts->s3h, deleteSQL, sizeof(deleteSQL),
+ require_noerr(s3e = sqlite3_prepare_v2(ts->s3h, deleteSQL, sizeof(deleteSQL),
&deleteStmt, NULL), errOut);
require_noerr(s3e = sqlite3_bind_blob_wrapper(deleteStmt, 1,
CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC),
/* prepared statements become unusable after deleteAllSQL, reset them */
if (ts->copyParents)
sqlite3_finalize(ts->copyParents);
- sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL),
+ sqlite3_prepare_v3(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), SQLITE_PREPARE_PERSISTENT,
&ts->copyParents, NULL);
if (ts->contains)
sqlite3_finalize(ts->contains);
- sqlite3_prepare(ts->s3h, containsSQL, sizeof(containsSQL),
+ sqlite3_prepare_v3(ts->s3h, containsSQL, sizeof(containsSQL), SQLITE_PREPARE_PERSISTENT,
&ts->contains, NULL);
});
errOutNotLocked:
CFPropertyListRef trustSettings = NULL;
CFArrayRef certSettingsPair = NULL;
int s3e = SQLITE_OK;
- require_noerr(s3e = sqlite3_prepare(ts->s3h, copyAllSQL, sizeof(copyAllSQL),
+ require_noerr(s3e = sqlite3_prepare_v2(ts->s3h, copyAllSQL, sizeof(copyAllSQL),
©AllStmt, NULL), errOut);
require(CertsAndSettings = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks), errOut);
for(;;) {
--- /dev/null
+/*
+ * 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 _SECURITY_TRUSTURLSESSIONDELEGATE_H_
+#define _SECURITY_TRUSTURLSESSIONDELEGATE_H_
+
+#if __OBJC__
+#include <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+/* This is our abstract NSURLSessionDelegate that handles the elements common to
+ * fetching data over the network during a trust evaluation */
+@interface TrustURLSessionDelegate : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
+@property (assign, nullable) void *context;
+@property NSArray <NSURL *>*URIs;
+@property NSUInteger URIix;
+@property (nullable) NSMutableData *response;
+@property NSTimeInterval expiration;
+@property NSUInteger numTasks;
+
+- (BOOL)fetchNext:(NSURLSession *)session;
+- (NSURLRequest *)createNextRequest:(NSURL *)uri;
+@end
+
+NSTimeInterval TrustURLSessionGetResourceTimeout(void);
+
+NS_ASSUME_NONNULL_END
+#endif // __OBJC__
+
+#endif /* _SECURITY_TRUSTURLSESSIONDELEGATE_H_ */
--- /dev/null
+/*
+ * 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 <AssertMacros.h>
+#import <Foundation/Foundation.h>
+#include <mach/mach_time.h>
+#include <utilities/SecCFWrappers.h>
+#include <Security/SecInternalReleasePriv.h>
+#include "TrustURLSessionDelegate.h"
+
+#define MAX_TASKS 3
+
+/* There has got to be an easier way to do this. For now we based this code
+ on CFNetwork/Connection/URLResponse.cpp. */
+static CFStringRef copyParseMaxAge(CFStringRef cacheControlHeader) {
+ if (!cacheControlHeader) { return NULL; }
+
+ /* The format of the cache control header is a comma-separated list, but
+ each list element could be a key-value pair, with the value quoted and
+ possibly containing a comma. */
+ CFStringInlineBuffer inlineBuf = {};
+ CFRange componentRange;
+ CFIndex length = CFStringGetLength(cacheControlHeader);
+ bool done = false;
+ CFCharacterSetRef whitespaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace);
+ CFStringRef maxAgeValue = NULL;
+
+ CFStringInitInlineBuffer(cacheControlHeader, &inlineBuf, CFRangeMake(0, length));
+ componentRange.location = 0;
+
+ while (!done) {
+ bool inQuotes = false;
+ bool foundComponentStart = false;
+ CFIndex charIndex = componentRange.location;
+ CFIndex componentEnd = -1;
+ CFRange maxAgeRg;
+ componentRange.length = 0;
+
+ while (charIndex < length) {
+ UniChar ch = CFStringGetCharacterFromInlineBuffer(&inlineBuf, charIndex);
+ if (!inQuotes && ch == ',') {
+ componentRange.length = charIndex - componentRange.location;
+ break;
+ }
+ if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) {
+ if (!foundComponentStart) {
+ foundComponentStart = true;
+ componentRange.location = charIndex;
+ } else {
+ componentEnd = charIndex;
+ }
+ if (ch == '\"') {
+ inQuotes = (inQuotes == false);
+ }
+ }
+ charIndex ++;
+ }
+
+ if (componentEnd == -1) {
+ componentRange.length = charIndex - componentRange.location;
+ } else {
+ componentRange.length = componentEnd - componentRange.location + 1;
+ }
+
+ if (charIndex == length) {
+ /* Fell off the end; this is the last component. */
+ done = true;
+ }
+
+ /* componentRange should now contain the range of the current
+ component; trimmed of any whitespace. */
+
+ /* We want to look for a max-age value. */
+ if (!maxAgeValue && CFStringFindWithOptions(cacheControlHeader, CFSTR("max-age"), componentRange, kCFCompareCaseInsensitive | kCFCompareAnchored, &maxAgeRg)) {
+ CFIndex equalIdx;
+ CFIndex maxCompRg = componentRange.location + componentRange.length;
+ for (equalIdx = maxAgeRg.location + maxAgeRg.length; equalIdx < maxCompRg; equalIdx ++) {
+ UniChar equalCh = CFStringGetCharacterFromInlineBuffer(&inlineBuf, equalIdx);
+ if (equalCh == '=') {
+ // Parse out max-age value
+ equalIdx ++;
+ while (equalIdx < maxCompRg && CFCharacterSetIsCharacterMember(whitespaceSet, CFStringGetCharacterAtIndex(cacheControlHeader, equalIdx))) {
+ equalIdx ++;
+ }
+ if (equalIdx < maxCompRg) {
+ CFReleaseNull(maxAgeValue);
+ maxAgeValue = CFStringCreateWithSubstring(kCFAllocatorDefault, cacheControlHeader, CFRangeMake(equalIdx, maxCompRg-equalIdx));
+ }
+ } else if (!CFCharacterSetIsCharacterMember(whitespaceSet, equalCh)) {
+ // Not a valid max-age header; break out doing nothing
+ break;
+ }
+ }
+ }
+
+ if (!done && maxAgeValue) {
+ done = true;
+ }
+ if (!done) {
+ /* Advance to the next component; + 1 to get past the comma. */
+ componentRange.location = charIndex + 1;
+ }
+ }
+
+ return maxAgeValue;
+}
+
+@implementation TrustURLSessionDelegate
+- (id)init {
+ /* Protect future developers from themselves */
+ if ([self class] == [TrustURLSessionDelegate class]) {
+ NSException *e = [NSException exceptionWithName:@"AbstractClassException"
+ reason:@"This is an abstract class. To use it, please subclass."
+ userInfo:nil];
+ @throw e;
+ } else {
+ return [super init];
+ }
+}
+
+- (NSURLRequest *)createNextRequest:(NSURL *)uri {
+ return [NSURLRequest requestWithURL:uri];
+}
+
+- (BOOL)fetchNext:(NSURLSession *)session {
+ if (self.numTasks >= MAX_TASKS) {
+ secnotice("http", "Too many fetch %@ requests for this cert", [self class]);
+ return true;
+ }
+
+ for (NSUInteger ix = self.URIix; ix < [self.URIs count]; ix++) {
+ NSURL *uri = self.URIs[ix];
+ if ([[uri scheme] isEqualToString:@"http"]) {
+ self.URIix = ix + 1; // Next time we'll start with the next index
+ self.numTasks++;
+ NSURLSessionTask *task = [session dataTaskWithRequest:[self createNextRequest:uri]];
+ [task resume];
+ secinfo("http", "request for uri: %@", uri);
+ return false; // we scheduled a job
+ } else {
+ secnotice("http", "skipping unsupported scheme %@", [uri scheme]);
+ }
+ }
+
+ /* No more issuers left to try, we're done. Report that no async jobs were started. */
+ secdebug("http", "no request issued");
+ return true;
+}
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
+ /* Append the data to the response data*/
+ if (!_response) {
+ _response = [NSMutableData data];
+ }
+ [_response appendData:data];
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
+ /* Protect future developers from themselves */
+ if ([self class] == [TrustURLSessionDelegate class]) {
+ NSException *e = [NSException exceptionWithName:@"AbstractClassException"
+ reason:@"This is an abstract class. To use it, please subclass and override didCompleteWithError."
+ userInfo:nil];
+ @throw e;
+ } else {
+ _expiration = 60.0 * 60.0 * 24.0 * 7; /* Default is 7 days */
+ if ([_response length] > 0 && [[task response] isKindOfClass:[NSHTTPURLResponse class]]) {
+ NSString *cacheControl = [[(NSHTTPURLResponse *)[task response] allHeaderFields] objectForKey:@"cache-control"];
+ NSString *maxAge = CFBridgingRelease(copyParseMaxAge((__bridge CFStringRef)cacheControl));
+ if (maxAge && [maxAge doubleValue] > _expiration) {
+ _expiration = [maxAge doubleValue];
+ }
+ }
+ }
+}
+
+- (void)URLSession:(NSURLSession *)session
+ task:(NSURLSessionTask *)task
+willPerformHTTPRedirection:(NSHTTPURLResponse *)redirectResponse
+ newRequest:(NSURLRequest *)request
+ completionHandler:(void (^)(NSURLRequest *))completionHandler {
+ /* The old code didn't allow re-direction, so we won't either. */
+ secnotice("http", "failed redirection for %@", task.originalRequest.URL);
+ [task cancel];
+}
+@end
+
+NSTimeInterval TrustURLSessionGetResourceTimeout(void) {
+ return (NSTimeInterval)3.0;
+}
+++ /dev/null
-/*
- * 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,
- * 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@
- */
-
-/*
- * asynchttp.c - asynchronous http get/post engine.
- */
-
-#include "asynchttp.h"
-
-#include <CoreFoundation/CFNumber.h>
-#include <CoreFoundation/CFStream.h>
-#include <CFNetwork/CFProxySupport.h> /* CFNetworkCopySystemProxySettings */
-#include <CFNetwork/CFSocketStreamPriv.h> /* kCFStreamPropertySourceApplication */
-#include <Security/SecInternal.h>
-#include "SecBase64.h"
-#include <AssertMacros.h>
-#include <utilities/debugging.h>
-#include <utilities/SecDispatchRelease.h>
-#include <asl.h>
-#include <string.h>
-#include <mach/mach_time.h>
-
-#include <inttypes.h>
-
-#if __LP64__
-#define PRIstatus "d"
-#else
-#define PRIstatus "ld"
-#endif
-
-static CFStringRef kUserAgent = CFSTR("User-Agent");
-static CFStringRef kAppUserAgent = CFSTR("com.apple.trustd/1.0");
-
-/* POST method has Content-Type header line equal to
- "application/ocsp-request" */
-static CFStringRef kContentType = CFSTR("Content-Type");
-static CFStringRef kAppOcspRequest = CFSTR("application/ocsp-request");
-
-/* SPI to specify timeout on CFReadStream */
-#define _kCFStreamPropertyReadTimeout CFSTR("_kCFStreamPropertyReadTimeout")
-#define _kCFStreamPropertyWriteTimeout CFSTR("_kCFStreamPropertyWriteTimeout")
-
-/* The timeout we set - 7 seconds */
-#define STREAM_TIMEOUT (7 * NSEC_PER_SEC)
-
-#define POST_BUFSIZE 2048
-
-/* There has got to be an easier way to do this. For now we based this code
- on CFNetwork/Connection/URLResponse.cpp. */
-static CFStringRef copyParseMaxAge(CFStringRef cacheControlHeader) {
- /* The format of the cache control header is a comma-separated list, but
- each list element could be a key-value pair, with the value quoted and
- possibly containing a comma. */
- CFStringInlineBuffer inlineBuf = {};
- CFRange componentRange;
- CFIndex length = CFStringGetLength(cacheControlHeader);
- bool done = false;
- CFCharacterSetRef whitespaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace);
- CFStringRef maxAgeValue = NULL;
-
- CFStringInitInlineBuffer(cacheControlHeader, &inlineBuf, CFRangeMake(0, length));
- componentRange.location = 0;
-
- while (!done) {
- bool inQuotes = false;
- bool foundComponentStart = false;
- CFIndex charIndex = componentRange.location;
- CFIndex componentEnd = -1;
- CFRange maxAgeRg;
- componentRange.length = 0;
-
- while (charIndex < length) {
- UniChar ch = CFStringGetCharacterFromInlineBuffer(&inlineBuf, charIndex);
- if (!inQuotes && ch == ',') {
- componentRange.length = charIndex - componentRange.location;
- break;
- }
- if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) {
- if (!foundComponentStart) {
- foundComponentStart = true;
- componentRange.location = charIndex;
- } else {
- componentEnd = charIndex;
- }
- if (ch == '\"') {
- inQuotes = (inQuotes == false);
- }
- }
- charIndex ++;
- }
-
- if (componentEnd == -1) {
- componentRange.length = charIndex - componentRange.location;
- } else {
- componentRange.length = componentEnd - componentRange.location + 1;
- }
-
- if (charIndex == length) {
- /* Fell off the end; this is the last component. */
- done = true;
- }
-
- /* componentRange should now contain the range of the current
- component; trimmed of any whitespace. */
-
- /* We want to look for a max-age value. */
- if (!maxAgeValue && CFStringFindWithOptions(cacheControlHeader, CFSTR("max-age"), componentRange, kCFCompareCaseInsensitive | kCFCompareAnchored, &maxAgeRg)) {
- CFIndex equalIdx;
- CFIndex maxCompRg = componentRange.location + componentRange.length;
- for (equalIdx = maxAgeRg.location + maxAgeRg.length; equalIdx < maxCompRg; equalIdx ++) {
- UniChar equalCh = CFStringGetCharacterFromInlineBuffer(&inlineBuf, equalIdx);
- if (equalCh == '=') {
- // Parse out max-age value
- equalIdx ++;
- while (equalIdx < maxCompRg && CFCharacterSetIsCharacterMember(whitespaceSet, CFStringGetCharacterAtIndex(cacheControlHeader, equalIdx))) {
- equalIdx ++;
- }
- if (equalIdx < maxCompRg) {
- CFReleaseNull(maxAgeValue);
- maxAgeValue = CFStringCreateWithSubstring(kCFAllocatorDefault, cacheControlHeader, CFRangeMake(equalIdx, maxCompRg-equalIdx));
- }
- } else if (!CFCharacterSetIsCharacterMember(whitespaceSet, equalCh)) {
- // Not a valid max-age header; break out doing nothing
- break;
- }
- }
- }
-
- if (!done && maxAgeValue) {
- done = true;
- }
- if (!done) {
- /* Advance to the next component; + 1 to get past the comma. */
- componentRange.location = charIndex + 1;
- }
- }
-
- return maxAgeValue;
-}
-
-static void asynchttp_complete(asynchttp_t *http) {
- secdebug("http", "http: %p", http);
- /* Shutdown streams and timer, we're about to invoke our client callback. */
- if (http->stream) {
- CFReadStreamSetClient(http->stream, kCFStreamEventNone, NULL, NULL);
- CFReadStreamSetDispatchQueue(http->stream, NULL);
- CFReadStreamClose(http->stream);
- CFReleaseNull(http->stream);
- }
- if (http->timer) {
- dispatch_source_cancel(http->timer);
- dispatch_release_null(http->timer);
- }
-
- if (http->completed) {
- /* This should probably move to our clients. */
- CFTimeInterval maxAge = NULL_TIME;
- if (http->response) {
- CFStringRef cacheControl = CFHTTPMessageCopyHeaderFieldValue(
- http->response, CFSTR("cache-control"));
- if (cacheControl) {
- CFStringRef maxAgeValue = copyParseMaxAge(cacheControl);
- CFRelease(cacheControl);
- if (maxAgeValue) {
- secdebug("http", "http header max-age: %@", maxAgeValue);
- maxAge = CFStringGetDoubleValue(maxAgeValue);
- CFRelease(maxAgeValue);
- }
- }
- }
- http->completed(http, maxAge);
- }
-}
-
-static void handle_server_response(CFReadStreamRef stream,
- CFStreamEventType type, void *info) {
- asynchttp_t *http = (asynchttp_t *)info;
- if (!http->stream) {
- secerror("Avoiding crash due to CFReadStream invoking us after we called CFReadStreamSetDispatchQueue(stream, NULL) on a different block on our serial queue");
- return;
- }
-
- switch (type) {
- case kCFStreamEventHasBytesAvailable:
- {
- UInt8 buffer[POST_BUFSIZE];
- CFIndex length;
- do {
-#if 1
- length = CFReadStreamRead(stream, buffer, sizeof(buffer));
-#else
- const UInt8 *buffer = CFReadStreamGetBuffer(stream, -1, &length);
-#endif
- secdebug("http",
- "stream: %@ kCFStreamEventHasBytesAvailable read: %lu bytes",
- stream, length);
- if (length < 0) {
- /* Negative length == error */
- asynchttp_complete(http);
- break;
- } else if (length > 0) {
- //CFHTTPMessageAppendBytes(http->response, buffer, length);
- CFDataAppendBytes(http->data, buffer, length);
- } else {
- /* Read 0 bytes. This is a no-op, but we need to keep
- reading until CFReadStreamHasBytesAvailable is false.
- */
- }
- } while (CFReadStreamHasBytesAvailable(stream));
- break;
- }
- case kCFStreamEventErrorOccurred:
- {
- CFStreamError error = CFReadStreamGetError(stream);
-
- secdebug("http",
- "stream: %@ kCFStreamEventErrorOccurred domain: %ld error: %ld",
- stream, error.domain, (long) error.error);
-
- if (error.domain == kCFStreamErrorDomainPOSIX) {
- secerror("CFReadStream posix: %s", strerror(error.error));
- } else if (error.domain == kCFStreamErrorDomainMacOSStatus) {
- secerror("CFReadStream osstatus: %"PRIstatus, error.error);
- } else {
- secerror("CFReadStream domain: %ld error: %"PRIstatus,
- error.domain, error.error);
- }
- asynchttp_complete(http);
- break;
- }
- case kCFStreamEventEndEncountered:
- {
- http->response = (CFHTTPMessageRef)CFReadStreamCopyProperty(
- stream, kCFStreamPropertyHTTPResponseHeader);
- secdebug("http", "stream: %@ kCFStreamEventEndEncountered hdr: %@",
- stream, http->response);
- CFHTTPMessageSetBody(http->response, http->data);
- asynchttp_complete(http);
- break;
- }
- default:
- secerror("handle_server_response unexpected event type: %lu",
- type);
- break;
- }
-}
-
-/* Create a URI suitable for use in an http GET request, will return NULL if
- the length would exceed 255 bytes. */
-static CFURLRef createGetURL(CFURLRef responder, CFDataRef request) {
- CFURLRef getURL = NULL;
- CFMutableDataRef base64Request = NULL;
- CFStringRef base64RequestString = NULL;
- CFStringRef peRequest = NULL;
- CFIndex base64Len;
-
- base64Len = SecBase64Encode(NULL, CFDataGetLength(request), NULL, 0);
- /* Don't bother doing all the work below if we know the end result will
- exceed 255 bytes (minus one for the '/' separator makes 254). */
- if (base64Len + CFURLGetBytes(responder, NULL, 0) > 254)
- return NULL;
-
- require(base64Request = CFDataCreateMutable(kCFAllocatorDefault,
- base64Len), errOut);
- CFDataSetLength(base64Request, base64Len);
- SecBase64Encode(CFDataGetBytePtr(request), CFDataGetLength(request),
- (char *)CFDataGetMutableBytePtr(base64Request), base64Len);
- require(base64RequestString = CFStringCreateWithBytes(kCFAllocatorDefault,
- CFDataGetBytePtr(base64Request), base64Len, kCFStringEncodingUTF8,
- false), errOut);
- /* percent-encode all reserved characters from RFC 3986 [2.2] */
- require(peRequest = CFURLCreateStringByAddingPercentEscapes(
- kCFAllocatorDefault, base64RequestString, NULL,
- CFSTR(":/?#[]@!$&'()*+,;="), kCFStringEncodingUTF8), errOut);
-#if 1
- CFStringRef urlString = CFURLGetString(responder);
- CFStringRef fullURL;
- if (CFStringHasSuffix(urlString, CFSTR("/"))) {
- fullURL = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- CFSTR("%@%@"), urlString, peRequest);
- } else {
- fullURL = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- CFSTR("%@/%@"), urlString, peRequest);
- }
- getURL = CFURLCreateWithString(kCFAllocatorDefault, fullURL, NULL);
- CFRelease(fullURL);
-#else
- getURL = CFURLCreateWithString(kCFAllocatorDefault, peRequest, responder);
-#endif
-
-errOut:
- CFReleaseSafe(base64Request);
- CFReleaseSafe(base64RequestString);
- CFReleaseSafe(peRequest);
-
- return getURL;
-}
-
-bool asyncHttpPost(CFURLRef responder, CFDataRef requestData /* , bool force_nocache */ ,
- uint64_t timeout, asynchttp_t *http) {
- bool result = true; /* True, we didn't schedule any work. */
- /* resources to release on exit */
- CFURLRef getURL = NULL;
-
-/* Interesting tidbit from rfc5019
- When sending requests that are less than or equal to 255 bytes in
- total (after encoding) including the scheme and delimiters (http://),
- server name and base64-encoded OCSPRequest structure, clients MUST
- use the GET method (to enable OCSP response caching). OCSP requests
- larger than 255 bytes SHOULD be submitted using the POST method.
-
- Interesting tidbit from rfc2616:
- Note: Servers ought to be cautious about depending on URI lengths
- above 255 bytes, because some older client or proxy
- implementations might not properly support these lengths.
-
- Given the second note I'm assuming that the note in rfc5019 is about the
- length of the URI, not the length of the entire HTTP request.
-
- If we need to consider the entire request we need to have 17 bytes less, or
- 17 + 25 = 42 if we are appending a "Cache-Control: no-cache CRLF" header
- field.
-
- The 17 and 42 above are based on the request encoding from rfc2616
- Method SP Request-URI SP HTTP-Version CRLF (header CRLF)* CRLF
- so in our case it's:
- GET SP URI SP HTTP/1.1 CRLF CRLF
- 17 + len(URI) bytes
- or
- GET SP URI SP HTTP/1.1 CRLF Cache-Control: SP no-cache CRLF CRLF
- 42 + len(URI) bytes
- */
-
- /* First let's try creating a GET request. */
- getURL = createGetURL(responder, requestData);
- if (getURL && CFURLGetBytes(getURL, NULL, 0) < 256) {
- /* Get URI is less than 256 bytes encoded, making it safe even for
- older proxy or caching servers, so let's use HTTP GET. */
- secdebug("http", "GET[%ld] %@", CFURLGetBytes(getURL, NULL, 0), getURL);
- require_quiet(http->request = CFHTTPMessageCreateRequest(kCFAllocatorDefault,
- CFSTR("GET"), getURL, kCFHTTPVersion1_1), errOut);
- } else {
- /* GET Request too big to ensure error free transmission, let's
- create a HTTP POST http->request instead. */
- secdebug("http", "POST %@ CRLF body", responder);
- require_quiet(http->request = CFHTTPMessageCreateRequest(kCFAllocatorDefault,
- CFSTR("POST"), responder, kCFHTTPVersion1_1), errOut);
- /* Set the body and required header fields. */
- CFHTTPMessageSetBody(http->request, requestData);
- CFHTTPMessageSetHeaderFieldValue(http->request, kContentType,
- kAppOcspRequest);
- }
-
-#if 0
- if (force_nocache) {
- CFHTTPMessageSetHeaderFieldValue(http->request, CFSTR("Cache-Control"),
- CFSTR("no-cache"));
- }
-#endif
-
- result = asynchttp_request(NULL, timeout, http);
-
-errOut:
- CFReleaseSafe(getURL);
-
- return result;
-}
-
-
-static void asynchttp_timer_proc(asynchttp_t *http CF_CONSUMED) {
- CFStringRef req_meth = http->request ? CFHTTPMessageCopyRequestMethod(http->request) : NULL;
- CFURLRef req_url = http->request ? CFHTTPMessageCopyRequestURL(http->request) : NULL;
- secnotice("http", "Timeout during %@ %@.", req_meth, req_url);
- CFReleaseSafe(req_url);
- CFReleaseSafe(req_meth);
- asynchttp_complete(http);
-}
-
-
-void asynchttp_free(asynchttp_t *http) {
- if (http) {
- CFReleaseNull(http->token);
- CFReleaseNull(http->request);
- CFReleaseNull(http->response);
- CFReleaseNull(http->data);
- CFReleaseNull(http->stream);
- dispatch_release_null(http->timer);
- }
-}
-
-/* Return true, iff we didn't schedule any work, return false if we did. */
-bool asynchttp_request(CFHTTPMessageRef request, uint64_t timeout, asynchttp_t *http) {
- secdebug("http", "request %@", request);
- if (request) {
- CFRetainAssign(http->request, request);
- /* Set user agent. */
- CFHTTPMessageSetHeaderFieldValue(request, kUserAgent, kAppUserAgent);
- }
-
- /* Create the stream for the request. */
- require_quiet(http->stream = CFReadStreamCreateForHTTPRequest(
- kCFAllocatorDefault, http->request), errOut);
-
- /* Set a reasonable timeout */
- require_quiet(http->timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, http->queue), errOut);
- dispatch_source_set_event_handler(http->timer, ^{
- asynchttp_timer_proc(http);
- });
- // Set the timer's fire time to now + STREAM_TIMEOUT seconds with a .5 second fuzz factor.
- uint64_t stream_timeout = timeout;
- if (timeout == 0) {
- stream_timeout = STREAM_TIMEOUT;
- }
- dispatch_source_set_timer(http->timer, dispatch_time(DISPATCH_TIME_NOW, stream_timeout),
- DISPATCH_TIME_FOREVER, (int64_t)(500 * NSEC_PER_MSEC));
- dispatch_resume(http->timer);
-
- /* Set up possible proxy info */
- CFDictionaryRef proxyDict = CFNetworkCopySystemProxySettings();
- if (proxyDict) {
- CFReadStreamSetProperty(http->stream, kCFStreamPropertyHTTPProxy, proxyDict);
- CFRelease(proxyDict);
- }
-
- /* Set source application property info */
- if (http->token) {
- CFReadStreamSetProperty(http->stream, kCFStreamPropertySourceApplication, http->token);
- }
-
- http->data = CFDataCreateMutable(kCFAllocatorDefault, 0);
-
- CFStreamClientContext stream_context = { .info = http };
- CFReadStreamSetClient(http->stream,
- (kCFStreamEventHasBytesAvailable
- | kCFStreamEventErrorOccurred
- | 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. */
-
-errOut:
- /* Deschedule timer and free anything we might have retained so far. */
- asynchttp_free(http);
- return true;
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010,2012-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@
- */
-
-/*!
- @header asynchttp
- The functions provided in asynchttp.h provide an interface to
- an asynchronous http get/post engine.
-*/
-
-#ifndef _SECURITYD_ASYNCHTTP_H_
-#define _SECURITYD_ASYNCHTTP_H_
-
-#include <stdbool.h>
-#include <CoreFoundation/CFData.h>
-#include <CoreFoundation/CFURL.h>
-#include <CoreFoundation/CFDate.h>
-#include <CFNetwork/CFHTTPMessage.h>
-#include <CFNetwork/CFHTTPStream.h>
-#include <dispatch/dispatch.h>
-
-__BEGIN_DECLS
-
-typedef struct asynchttp_s {
- void(*completed)(struct asynchttp_s *http, CFTimeInterval maxAge);
- void *info;
- CFHTTPMessageRef request;
- CFHTTPMessageRef response;
- dispatch_queue_t queue;
- uint64_t start_time;
- /* The fields below should be considered private. */
- CFMutableDataRef data;
- CFReadStreamRef stream;
- dispatch_source_t timer;
- CFDataRef token;
-} asynchttp_t;
-
-/* Return false if work was scheduled and the callback will be invoked,
- true if it wasn't or the callback was already called. */
-bool asyncHttpPost(CFURLRef cfUrl, CFDataRef postData, uint64_t timeout, asynchttp_t *http);
-
-/* Caller owns struct pointed to by http, but is responsible for calling
- asynchttp_free() when it's done with it. */
-bool asynchttp_request(CFHTTPMessageRef request, uint64_t timeout, asynchttp_t *http);
-void asynchttp_free(asynchttp_t *http);
-
-/* */
-
-
-__END_DECLS
-
-#endif /* !_SECURITYD_ASYNCHTTP_H_ */
(global-name "com.apple.system.opendirectoryd.api")
(global-name "com.apple.SystemConfiguration.configd")
(global-name "com.apple.security.cloudkeychainproxy3")
- (global-name "com.apple.security.keychainsyncingoveridsproxy")
+ (global-name "com.apple.accountsd.accountmanager")
+ (global-name "com.apple.ak.auth.xpc")
(global-name "com.apple.cdp.daemon")
(global-name "com.apple.cloudd")
(global-name "com.apple.apsd")
+ (global-name "com.apple.ak.anisette.xpc")
(global-name "com.apple.windowserver.active"))
;; Used to send logs for MoiC.
<array>
<string>securityd</string>
</array>
+ <key>com.apple.private.sqlite.sqlite-encryption</key>
+ <true/>
+ <key>com.apple.accounts.appleaccount.fullaccess</key>
+ <true/>
+ <key>com.apple.authkit.client.private</key>
+ <true/>
</dict>
</plist>
#include <Security/SecCertificateInternal.h>
#include <securityd/SecPolicyServer.h>
#include <libDER/asn1Types.h>
+#include <libDER/oids.h>
/* RFC 5280 Section 4.2.1.10:
DNS name restrictions are expressed as host.example.com. Any DNS
}
}
+static bool certAllowsSSL(SecCertificateRef certificate) {
+ CFArrayRef ekus = SecCertificateCopyExtendedKeyUsage(certificate);
+ if (!ekus) {
+ return true; // No EKU -> any purpose
+ }
+
+ const DERItem *serverEkus[] = {
+ &oidAnyExtendedKeyUsage, &oidExtendedKeyUsageServerAuth,
+ &oidExtendedKeyUsageMicrosoftSGC, &oidExtendedKeyUsageNetscapeSGC,
+ };
+
+ bool result = false;
+ for (uint8_t ix = 0; ix < sizeof(serverEkus)/sizeof(const DERItem *); ix++) {
+ CFDataRef ekuOid = CFDataCreate(NULL, serverEkus[ix]->data, serverEkus[ix]->length);
+ if (CFArrayContainsValue(ekus, CFRangeMake(0, CFArrayGetCount(ekus)), ekuOid)) {
+ result = true;
+ }
+ CFReleaseNull(ekuOid);
+ if (result) {
+ break;
+ }
+ }
+
+ CFReleaseNull(ekus);
+ return result;
+}
+
static void nc_compare_subject_to_subtrees(SecCertificateRef certificate, CFArrayRef subtrees,
bool permit, match_t *match) {
CFDataRef subject = SecCertificateCopySubjectSequence(certificate);
CFReleaseNull(subject);
update_match(permit, &x500_match, match);
- /* Compare DNSName constraints */
- match_t dns_match = { false, permit };
- CFArrayRef dnsNames = SecCertificateCopyDNSNamesFromSubject(certificate);
- if (dnsNames) {
- CFRange dnsRange = { 0, CFArrayGetCount(dnsNames) };
- nc_san_match_context_t dnsContext = { subtrees, &dns_match, permit };
- CFArrayApplyFunction(dnsNames, dnsRange, nc_compare_DNSName_to_subtrees, &dnsContext);
+ /* These checks are unnecessary if Common Names aren't used to match SSLHostnames. (<rdar://31562470>)
+ * In the meantime, this hack makes non-SSL certs with DNS-like CNs work. (<rdar://41173883>) */
+ /* Compare DNSName constraints -- if there's no DNS names in the SAN and this cert can be used for SSL Server Auth*/
+ CFArrayRef sanDnsNames = SecCertificateCopyDNSNamesFromSAN(certificate);
+ if (certAllowsSSL(certificate) && (!sanDnsNames || CFArrayGetCount(sanDnsNames) == 0)) {
+ match_t dns_match = { false, permit };
+ CFArrayRef dnsNames = SecCertificateCopyDNSNamesFromSubject(certificate);
+ if (dnsNames) {
+ CFRange dnsRange = { 0, CFArrayGetCount(dnsNames) };
+ nc_san_match_context_t dnsContext = { subtrees, &dns_match, permit };
+ CFArrayApplyFunction(dnsNames, dnsRange, nc_compare_DNSName_to_subtrees, &dnsContext);
+ }
+ CFReleaseNull(dnsNames);
+ update_match(permit, &dns_match, match);
}
- CFReleaseNull(dnsNames);
- update_match(permit, &dns_match, match);
+ CFReleaseNull(sanDnsNames);
/* Compare IPAddresss constraints */
match_t ip_match = { false, permit };
/* Walk the nodes in a tree at depth and invoke callback for each one. */
bool policy_tree_walk_depth(policy_tree_t root, int depth,
bool(*callback)(policy_tree_t, void *), void *ctx) {
- policy_tree_t stack[depth + 1];
+ policy_tree_t *stack = (policy_tree_t *)malloc(sizeof(policy_tree_t) * (depth + 1));
+ if (!stack) {
+ return false;
+ }
int stack_ix = 0;
stack[stack_ix] = root;
policy_tree_t node;
}
}
}
+ free(stack);
return match;
}
.soscc_TryUserCredentials = SOSCCTryUserCredentials_Server,
.soscc_SetUserCredentials = SOSCCSetUserCredentials_Server,
.soscc_SetUserCredentialsAndDSID = SOSCCSetUserCredentialsAndDSID_Server,
+ .soscc_SetUserCredentialsAndDSIDWithAnalytics = SOSCCSetUserCredentialsAndDSIDWithAnalytics_Server,
.soscc_CanAuthenticate = SOSCCCanAuthenticate_Server,
.soscc_PurgeUserCredentials = SOSCCPurgeUserCredentials_Server,
.soscc_ThisDeviceIsInCircle = SOSCCThisDeviceIsInCircle_Server,
.soscc_RequestToJoinCircle = SOSCCRequestToJoinCircle_Server,
.soscc_RequestToJoinCircleAfterRestore = SOSCCRequestToJoinCircleAfterRestore_Server,
+ .soscc_RequestToJoinCircleAfterRestoreWithAnalytics = SOSCCRequestToJoinCircleAfterRestoreWithAnalytics_Server,
.soscc_RequestEnsureFreshParameters = SOSCCRequestEnsureFreshParameters_Server,
.soscc_GetAllTheRings = SOSCCGetAllTheRings_Server,
.soscc_ApplyToARing = SOSCCApplyToARing_Server,
.soscc_SetToNew = SOSCCAccountSetToNew_Server,
.soscc_ResetToOffering = SOSCCResetToOffering_Server,
.soscc_ResetToEmpty = SOSCCResetToEmpty_Server,
+ .soscc_ResetToEmptyWithAnalytics = SOSCCResetToEmptyWithAnalytics_Server,
.soscc_View = SOSCCView_Server,
.soscc_ViewSet = SOSCCViewSet_Server,
- .soscc_SecurityProperty = SOSCCSecurityProperty_Server,
+ .soscc_ViewSetWithAnalytics = SOSCCViewSetWithAnalytics_Server,
.soscc_RemoveThisDeviceFromCircle = SOSCCRemoveThisDeviceFromCircle_Server,
+ .soscc_RemoveThisDeviceFromCircleWithAnalytics = SOSCCRemoveThisDeviceFromCircleWithAnalytics_Server,
.soscc_RemovePeersFromCircle = SOSCCRemovePeersFromCircle_Server,
+ .soscc_RemovePeersFromCircleWithAnalytics = SOSCCRemovePeersFromCircleWithAnalytics_Server,
.soscc_LoggedOutOfAccount = SOSCCLoggedOutOfAccount_Server,
.soscc_BailFromCircle = SOSCCBailFromCircle_Server,
.soscc_AcceptApplicants = SOSCCAcceptApplicants_Server,
.soscc_ProcessSyncWithAllPeers = SOSCCProcessSyncWithAllPeers_Server,
.soscc_EnsurePeerRegistration = SOSCCProcessEnsurePeerRegistration_Server,
.sec_roll_keys = _SecServerRollKeysGlue,
- .soscc_CopyDeviceID = SOSCCCopyDeviceID_Server,
- .soscc_SetDeviceID = SOSCCSetDeviceID_Server,
- .soscc_CheckIDSRegistration = SOSCCIDSServiceRegistrationTest_Server,
- .soscc_PingTest = SOSCCIDSPingTest_Server,
- .soscc_GetIDSIDFromIDS = SOSCCIDSDeviceIDIsAvailableTest_Server,
.sec_keychain_sync_update_message = _SecServerKeychainSyncUpdateMessage,
- .soscc_HandleIDSMessage = SOSCCHandleIDSMessage_Server,
.sec_get_log_settings = SecCopyLogSettings_Server,
.sec_set_xpc_log_settings = SecSetXPCLogSettings_Server,
.sec_set_circle_log_settings = SecSetCircleLogSettings_Server,
.soscc_SetNewPublicBackupKey = SOSCCSetNewPublicBackupKey_Server,
.soscc_RegisterSingleRecoverySecret = SOSCCRegisterSingleRecoverySecret_Server,
.soscc_WaitForInitialSync = SOSCCWaitForInitialSync_Server,
+ .soscc_WaitForInitialSyncWithAnalytics = SOSCCWaitForInitialSyncWithAnalytics_Server,
.soscc_CopyYetToSyncViewsList = SOSCCCopyYetToSyncViewsList_Server,
.soscc_SetEscrowRecords = SOSCCSetEscrowRecord_Server,
.soscc_CopyEscrowRecords = SOSCCCopyEscrowRecord_Server,
- .soscc_PeerAvailability = SOSCCCheckPeerAvailability_Server,
.sosbskb_WrapToBackupSliceKeyBagForView = SOSWrapToBackupSliceKeyBagForView_Server,
.soscc_CopyAccountState = SOSCCCopyAccountState_Server,
.soscc_DeleteAccountState = SOSCCDeleteAccountState_Server,
.sec_item_update_token_items = _SecItemUpdateTokenItems,
.sec_delete_items_with_access_groups = _SecItemServerDeleteAllWithAccessGroups,
.soscc_IsThisDeviceLastBackup = SOSCCkSecXPCOpIsThisDeviceLastBackup_Server,
- .soscc_requestSyncWithPeerOverKVS = SOSCCRequestSyncWithPeerOverKVS_Server,
- .soscc_requestSyncWithPeerOverKVSIDOnly = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server,
.soscc_SOSCCPeersHaveViewsEnabled = SOSCCPeersHaveViewsEnabled_Server,
- .socc_clearPeerMessageKeyInKVS = SOSCCClearPeerMessageKeyInKVS_Server,
.soscc_RegisterRecoveryPublicKey = SOSCCRegisterRecoveryPublicKey_Server,
.soscc_CopyRecoveryPublicKey = SOSCCCopyRecoveryPublicKey_Server,
.soscc_CopyBackupInformation = SOSCCCopyBackupInformation_Server,
ONE_TEST(si_28_sectrustsettings)
ONE_TEST(si_29_sectrust_sha1_deprecation)
ONE_TEST(si_32_sectrust_pinning_required)
+ONE_TEST(si_34_cms_timestamp)
+ONE_TEST(si_35_cms_expiration_time)
ONE_TEST(si_44_seckey_gen)
ONE_TEST(si_44_seckey_rsa)
ONE_TEST(si_44_seckey_ec)
#if TARGET_OS_IOS && !TARGET_OS_SIMULATOR
ONE_TEST(si_44_seckey_fv)
#endif
+ONE_TEST(si_44_seckey_proxy)
ONE_TEST(si_60_cms)
ONE_TEST(si_61_pkcs12)
ONE_TEST(si_62_csr)
ONE_TEST(si_85_sectrust_ssl_policy)
ONE_TEST(si_87_sectrust_name_constraints)
ONE_TEST(si_88_sectrust_valid)
+ONE_TEST(si_89_cms_hash_agility)
ONE_TEST(si_97_sectrust_path_scoring)
ONE_TEST(rk_01_recoverykey)
<dict>
<key>PolicyIdentifier</key>
<string>1.2.840.113635.100.1.33</string>
- <key>Properties</key>
- <dict>
- <key>SecPolicyName</key>
- <string>test.nosuchdomain</string>
- </dict>
</dict>
<key>Leaf</key>
<string>generic_apple_server</string>
<string>1.2.840.113635.100.1.3</string>
<key>Properties</key>
<dict>
- <key>SecPolicyName</key>
- <string>com.apple.ist.ds.appleconnect2.production.vpn.8F2B3ADCD72ED2EA08DDC26AD0255A983B1DEBEB</string>
<key>SecPolicyClient</key>
<true/>
</dict>
<key>Anchors</key>
<string>AppleRootCA</string>
<key>VerifyDate</key>
- <date>2015-04-20T19:00:00Z</date>
+ <date>2018-04-20T19:00:00Z</date>
<key>ExpectedResult</key>
<integer>4</integer>
<key>ChainLength</key>
<key>VerifyDate</key>
<date>2016-12-10T04:38:00Z</date>
</dict>
- <dict>
- <key>MajorTestName</key>
- <string>DOD</string>
- <key>MinorTestName</key>
- <string>SHA2</string>
- <key>Policies</key>
- <dict>
- <key>PolicyIdentifier</key>
- <string>1.2.840.113635.100.1.2</string>
- </dict>
- <key>Leaf</key>
- <string>ECARootCA4</string>
- <key>Intermediates</key>
- <array>
- <string>FederalBridgeCA2013</string>
- <string>DODInteroperabilityRootCA2</string>
- </array>
- <key>Anchors</key>
- <string>FederalCommonPolicyCA</string>
- <key>ExpectedResult</key>
- <integer>4</integer>
- <key>VerifyDate</key>
- <date>2016-12-10T04:38:00Z</date>
- </dict>
<dict>
<key>MajorTestName</key>
<string>DOD</string>
<key>ExpectedResult</key>
<integer>4</integer>
</dict>
+ <dict>
+ <key>MajorTestName</key>
+ <string>BAA_SCRT</string>
+ <key>MinorTestName</key>
+ <string>Positive</string>
+ <key>Policies</key>
+ <dict>
+ <key>PolicyIdentifier</key>
+ <string>1.2.840.113635.100.1.84</string>
+ </dict>
+ <key>Leaf</key>
+ <string>baa_scrt_leaf</string>
+ <key>Intermediates</key>
+ <string>baa_system_subca1</string>
+ <key>Anchors</key>
+ <string>baa_system_root</string>
+ <key>VerifyDate</key>
+ <date>2018-05-09T13:00:00Z</date>
+ <key>ExpectedResult</key>
+ <integer>4</integer>
+ </dict>
+ <dict>
+ <key>MajorTestName</key>
+ <string>AssetReceipt</string>
+ <key>MinorTestName</key>
+ <string>Positive-TemporallyValid</string>
+ <key>Policies</key>
+ <dict>
+ <key>PolicyIdentifier</key>
+ <string>1.2.840.113635.100.1.89</string>
+ </dict>
+ <key>Leaf</key>
+ <string>asset_receipt</string>
+ <key>Intermediates</key>
+ <string>AppleSystemIntegration2CA</string>
+ <key>Anchors</key>
+ <string>AppleRootCA</string>
+ <key>VerifyDate</key>
+ <date>2018-04-10T06:00:00Z</date>
+ <key>ExpectedResult</key>
+ <integer>4</integer>
+ <key>ChainLength</key>
+ <integer>3</integer>
+ </dict>
+ <dict>
+ <key>MajorTestName</key>
+ <string>AssetReceipt</string>
+ <key>MinorTestName</key>
+ <string>Positive-TemporallyInvalid</string>
+ <key>Policies</key>
+ <dict>
+ <key>PolicyIdentifier</key>
+ <string>1.2.840.113635.100.1.89</string>
+ </dict>
+ <key>Leaf</key>
+ <string>asset_receipt</string>
+ <key>Intermediates</key>
+ <string>AppleSystemIntegration2CA</string>
+ <key>Anchors</key>
+ <string>AppleRootCA</string>
+ <key>VerifyDate</key>
+ <date>2019-06-02T06:00:00Z</date>
+ <key>ExpectedResult</key>
+ <integer>4</integer>
+ <key>ChainLength</key>
+ <integer>3</integer>
+ </dict>
+ <dict>
+ <key>MajorTestName</key>
+ <string>AssetReceipt</string>
+ <key>MinorTestName</key>
+ <string>Negative</string>
+ <key>Policies</key>
+ <dict>
+ <key>PolicyIdentifier</key>
+ <string>1.2.840.113635.100.1.89</string>
+ </dict>
+ <key>Leaf</key>
+ <string>ppq_signing</string>
+ <key>Intermediates</key>
+ <string>AppleSystemIntegration2CA</string>
+ <key>Anchors</key>
+ <string>AppleRootCA</string>
+ <key>VerifyDate</key>
+ <date>2017-02-18T00:19:45Z</date>
+ <key>ExpectedResult</key>
+ <integer>5</integer>
+ </dict>
</array>
</plist>
#import <Security/SecKeyPriv.h>
#if !TARGET_OS_OSX
#import "MobileGestalt.h"
+#else
+#import <RemoteServiceDiscovery/RemoteServiceDiscovery.h>
#endif
#import "shared_regressions.h"
id sik = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeSIK, (void *)&error));
ok(sik != nil, "get SIk key: %@", error);
+ id pubSIK = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sik));
+ ok(pubSIK != nil, "get SIK pubkey");
+
error = nil;
NSData *attSIKPlain = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)uik, (void *)&error));
ok(attSIKPlain != nil, "SIK attesting UIK, no nonce: %@", error);
ok(SecKeySetParameter((__bridge SecKeyRef)sik, kSecKeyParameterSETokenAttestationNonce, (__bridge CFPropertyListRef)nonce, (void *)&error), "Set nonce to SIK: %@", error);
NSData *attSIKNonce = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)uik, (void *)&error));
ok(attSIKNonce != nil, "SIK attesting UIK, with nonce: %@", error);
-// NSRange found = [attSIKNonce rangeOfData:nonce options:0 range:NSMakeRange(0, attSIKNonce.length)];
-// ok(found.location != NSNotFound, "nonce found in SIK-attested data");
error = nil;
ok(SecKeySetParameter((__bridge SecKeyRef)uik, kSecKeyParameterSETokenAttestationNonce, (__bridge CFPropertyListRef)nonce, (void *)&error), "Set nonce to UIK: %@", error);
NSData *attUIKNonce = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)uik, (__bridge SecKeyRef)privKey, (void *)&error));
ok(attUIKNonce != nil, "SIK attesting UIK, with nonce: %@", error);
-// found = [attUIKNonce rangeOfData:nonce options:0 range:NSMakeRange(0, attUIKNonce.length)];
-// ok(found.location != NSNotFound, "nonce found in UIK-attested data");
+
+ error = nil;
+ id sysUikC = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKCommitted, (void *)&error));
+ if (sysUikC == nil) {
+ // Platform does not support system UIK, so just fake test rounds to avoid testplan counting failures.
+ for (int i = 0; i < 19; i++) {
+ ok(true);
+ }
+ } else {
+ ok(sysUikC != nil, "get UIK-committed key, error: %@", error);
+ error = nil;
+ id sysUikP = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKProposed, (void *)&error));
+ ok(sysUikP != nil, "get UIK-proposed key: %@", error);
+
+ error = nil;
+ NSData *attUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
+ ok(attUIKC != nil, "Sys-UIK-committed attesting privKey: %@", error);
+
+ error = nil;
+ NSData *attUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
+ ok(attUIKP != nil, "Sys-UIK-proposed attesting privKey: %@", error);
+
+ id pubUIKP = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP));
+ ok(pubUIKP != nil, "Sys-UIK-proposed copy public key");
+ id pubUIKC = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC));
+ ok(pubUIKC != nil, "Sys-UIK-proposed copy public key");
+ ok([pubUIKP isEqual:pubUIKC], "Sys-UIK proposed and committed are same before bump");
+
+ BOOL res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikC, kSecKeyControlLifetimeTypeBump, (void *)&error);
+ ok(res, "bumping sys-uik: %@", error);
+
+ error = nil;
+ NSData *attUIKCN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
+ ok(attUIKCN != nil, "Sys-UIK-committed attesting privKey: %@", error);
+
+ error = nil;
+ NSData *attUIKPN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
+ ok(attUIKPN != nil, "Sys-UIK-proposed attesting privKey: %@", error);
+
+ id pubUIKPN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP));
+ ok(pubUIKPN != nil, "Sys-UIK-proposed copy public key");
+ ok(![pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed differ after bump");
+
+ res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikP, kSecKeyControlLifetimeTypeCommit, (void *)&error);
+ ok(res, "committing sys-uik: %@", error);
+
+ error = nil;
+ NSData *attUIKCNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
+ ok(attUIKCNN != nil, "Sys-UIK-committed attesting privKey: %@", error);
+
+ error = nil;
+ NSData *attUIKPNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
+ ok(attUIKPNN != nil, "Sys-UIK-proposed attesting privKey: %@", error);
+
+ id pubUIKCN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC));
+ ok(pubUIKCN != nil, "Sys-UIK-committed copy public key");
+ ok([pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed same after commit");
+
+ // Attest system-UIK with SIK
+ NSData *attSIKUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikP, (void *)&error));
+ ok(attSIKUIKP != nil, "SIK attesting Sys-UIK-proposed, error: %@", error);
+
+ NSData *attSIKUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikC, (void *)&error));
+ ok(attSIKUIKC != nil, "SIK attesting Sys-UIK-committed, error: %@", error);
+ }
}
int si_44_seckey_aks(int argc, char *const *argv) {
@autoreleasepool {
BOOL testPKA = YES;
#if !TARGET_OS_OSX
- id hasPKA = (__bridge_transfer id)MGCopyAnswer(kMGQHasPKA, NULL);
- if(![hasPKA isKindOfClass:NSNumber.class] || ![(NSNumber *)hasPKA boolValue]) {
+ NSNumber *hasPKA = (__bridge_transfer id)MGCopyAnswer(kMGQHasPKA, NULL);
+ if(![hasPKA isKindOfClass:NSNumber.class] || ![hasPKA boolValue]) {
testPKA = NO;
}
#else
+ if (remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_EOS) == nil && remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_BRIDGE_COPROC) == nil) {
+ // macOS without SEP cannot run attestations at all.
+ plan_tests(1);
+ ok(true);
+ return 0;
+ }
+
testPKA = NO;
#endif
- plan_tests(testPKA ? 46 : 31);
+ plan_tests(testPKA ? 66 : 51);
secKeySepTest(testPKA);
attestationTest();
return 0;
static void testFileVaultKeyRawSign() {
id key = CFBridgingRelease(SecKeyCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey));
id certificate = CFBridgingRelease(SecCertificateCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey));
- id pubKey = CFBridgingRelease(SecCertificateCopyPublicKey((SecCertificateRef)certificate));
+ id pubKey = CFBridgingRelease(SecCertificateCopyKey((SecCertificateRef)certificate));
uint8_t hash[20] = { 0 };
uint8_t signature[256] = { 0 };
NSError *error;
id key = CFBridgingRelease(SecKeyCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey));
id certificate = CFBridgingRelease(SecCertificateCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey));
- id pubKey = CFBridgingRelease(SecCertificateCopyPublicKey((SecCertificateRef)certificate));
+ id pubKey = CFBridgingRelease(SecCertificateCopyKey((SecCertificateRef)certificate));
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1;
error = nil;
--- /dev/null
+/*
+ * 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 <Foundation/Foundation.h>
+#import <Security/SecKeyPriv.h>
+#import <Security/SecIdentityPriv.h>
+#import <Security/SecKeyProxy.h>
+
+#import "shared_regressions.h"
+
+static void test_key_proxy_connect() {
+ NSError *error;
+ id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @(256)}, (void *)&error));
+ ok(serverKey != NULL, "generated local ec256 keypair");
+ SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey];
+ SecKeyRef localKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error];
+ isnt(localKey, NULL, "connected to remote key, error %@", error);
+ ok(CFGetTypeID(localKey) == SecKeyGetTypeID(), "Connected key is really SecKey");
+
+ // Try another connection to the proxy.
+ SecKeyRef secondKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error];
+ isnt(secondKey, NULL, "2nd connection should not be refused");
+ isnt(SecKeyGetBlockSize(secondKey), (size_t)0, "2nd connections working normally");
+
+ // Even after deleting (not invalidating!) proxy, existing connections should work right.
+ NSXPCListenerEndpoint *endpoint = keyProxy.endpoint;
+ keyProxy = nil;
+
+ // However, connection to it should not be possible any more.
+ CFRelease(secondKey);
+ secondKey = [SecKeyProxy createKeyFromEndpoint:endpoint error:&error];
+ is(secondKey, NULL, "connecting to deleted proxy should not be possible");
+
+ // Create new proxy and invalidate it (idempotent, so we try invalidate multiple times).
+ keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey];
+ [keyProxy invalidate];
+ [keyProxy invalidate];
+ secondKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error];
+ is(secondKey, NULL, "connection to invalidated proxy should be refused.");
+
+ // Invalidate connected proxy, make sure that remote key does not work as expected.
+ keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey];
+ secondKey = [SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error];
+ isnt(secondKey, NULL, "connecting to proxy failed.");
+
+ is(SecKeyGetBlockSize((__bridge SecKeyRef)serverKey), SecKeyGetBlockSize(secondKey), "connected key should work fine");
+ [keyProxy invalidate];
+ is(SecKeyGetBlockSize(secondKey), (size_t)0, "disconnected key should fail");
+ CFRelease(secondKey);
+}
+static const int TestKeyProxyConnectCount = 10;
+
+static void test_key_proxy_simple_ops() {
+ NSError *error;
+ id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @(256)}, (void *)&error));
+ SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey];
+ id localKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]);
+ NSDictionary *serverAttributes = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)serverKey));
+ NSDictionary *localAttributes = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)localKey));
+ isnt(localAttributes, nil, "attributes for local remote key failed");
+ ok([serverAttributes isEqual:localAttributes], "local and remote attributes should be identical");
+
+ // Just call description, there is no sane way to test the contents, not crashing is enough.
+ CFBridgingRelease(CFCopyDescription((SecKeyRef)localKey));
+
+ is(SecKeyGetAlgorithmId((__bridge SecKeyRef)serverKey), SecKeyGetAlgorithmId((__bridge SecKeyRef)localKey), "GetAlgorithmId failed for remote");
+}
+static const int TestKeyProxySimpleOpsCount = 3;
+
+static void test_crypto_sign(id key1, id key2, SecKeyAlgorithm algorithm) {
+ id pk1 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key1));
+ isnt(pk1, nil, "failed to get pubkey from key %@", key1);
+ id pk2 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key2));
+ isnt(pk2, nil, "failed to get pubkey from key %@", key2);
+
+ NSData *message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
+ NSError *error;
+ NSData *signature1 = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key1, algorithm, (CFDataRef)message, (void *)&error));
+ isnt(signature1, nil, "failed to sign data with algorithm %@: %@", algorithm, error);
+ ok(SecKeyVerifySignature((SecKeyRef)pk2, algorithm, (CFDataRef)message, (CFDataRef)signature1, (void *)&error), "failed to verify data with algorithm %@: %@", algorithm, error);
+
+ message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
+ error = nil;
+ NSData *signature2 = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key2, algorithm, (CFDataRef)message, (void *)&error));
+ isnt(signature2, nil, "failed to sign data with algorithm %@: %@", algorithm, error);
+ ok(SecKeyVerifySignature((SecKeyRef)pk1, algorithm, (CFDataRef)message, (CFDataRef)signature1, (void *)&error), "failed to verify data with algorithm %@: %@", algorithm, error);
+}
+static const int TestKeyCryptoSignCount = 6;
+
+static void test_crypto_encrypt(id key1, id key2, SecKeyAlgorithm algorithm) {
+ id pk1 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key1));
+ isnt(pk1, nil, "failed to get pubkey from key %@", key1);
+ id pk2 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key2));
+ isnt(pk2, nil, "failed to get pubkey from key %@", key2);
+
+ NSData *message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
+ NSError *error;
+ NSData *ciphertext1 = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)pk1, algorithm, (CFDataRef)message, (void *)&error));
+ isnt(ciphertext1, nil, "failed to encrypt data with algorithm %@: %@", algorithm, error);
+ NSData *plaintext1 = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)key2, algorithm, (CFDataRef)ciphertext1, (void *)&error));
+ ok([plaintext1 isEqualToData:message], "encrypt/decrypt differs from message: %@ vs %@", message, plaintext1);
+
+ message = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
+ error = nil;
+ NSData *ciphertext2 = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)pk2, algorithm, (CFDataRef)message, (void *)&error));
+ isnt(ciphertext2, nil, "failed to encrypt data with algorithm %@: %@", algorithm, error);
+ NSData *plaintext2 = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)key1, algorithm, (CFDataRef)ciphertext2, (void *)&error));
+ ok([plaintext2 isEqualToData:message], "encrypt/decrypt differs from message: %@ vs %@", message, plaintext2);
+}
+static const int TestKeyCryptoEncryptCount = 6;
+
+static void test_crypto_kxchg(id key1, id key2, SecKeyAlgorithm algorithm) {
+ id pk1 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key1));
+ isnt(pk1, nil, "failed to get pubkey from key %@", key1);
+ id pk2 = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key2));
+ isnt(pk2, nil, "failed to get pubkey from key %@", key2);
+
+ NSError *error;
+ NSData *result1 = CFBridgingRelease(SecKeyCopyKeyExchangeResult((SecKeyRef)key1, algorithm, (SecKeyRef)pk2, (CFDictionaryRef)@{}, (void *)&error));
+ isnt(result1, nil, "failed to keyexchange data with algorithm %@: %@", algorithm, error);
+ NSData *result2 = CFBridgingRelease(SecKeyCopyKeyExchangeResult((SecKeyRef)key2, algorithm, (SecKeyRef)pk1, (CFDictionaryRef)@{}, (void *)&error));
+ isnt(result1, nil, "failed to keyexchange data with algorithm %@: %@", algorithm, error);
+ ok([result1 isEqualToData:result2], "keyexchange results differ!");
+}
+static const int TestKeyCryptoKeyExchange = 5;
+
+static void test_key_proxy_crypto_ops_RSA() {
+ NSError *error;
+ id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @(2048)}, (void *)&error));
+ ok(serverKey != NULL, "generated local rsa2048 keypair: %@", error);
+ SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey];
+ id localKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]);
+ isnt(localKey, NULL, "connected to remote key, error %@", error);
+
+ test_crypto_sign(localKey, serverKey, kSecKeyAlgorithmRSASignatureMessagePSSSHA1);
+ test_crypto_sign(serverKey, localKey, kSecKeyAlgorithmRSASignatureMessagePSSSHA256);
+
+ test_crypto_encrypt(localKey, serverKey, kSecKeyAlgorithmRSAEncryptionOAEPSHA1);
+ test_crypto_encrypt(serverKey, localKey, kSecKeyAlgorithmRSAEncryptionOAEPSHA256);
+}
+static const int TestKeyCryptoOpsRSACount = 2 + TestKeyCryptoSignCount * 2 + TestKeyCryptoEncryptCount * 2;
+
+static void test_key_proxy_crypto_ops_EC() {
+ NSError *error;
+ id serverKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @(256)}, (void *)&error));
+ ok(serverKey != NULL, "generated local ec256 keypair: %@", error);
+ SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)serverKey];
+ id localKey = CFBridgingRelease([SecKeyProxy createKeyFromEndpoint:keyProxy.endpoint error:&error]);
+ isnt(localKey, NULL, "connected to remote key, error %@", error);
+
+ test_crypto_sign(localKey, serverKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA1);
+ test_crypto_sign(serverKey, localKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256);
+
+ test_crypto_encrypt(localKey, serverKey, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM);
+ test_crypto_encrypt(serverKey, localKey, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
+
+ test_crypto_kxchg(localKey, serverKey, kSecKeyAlgorithmECDHKeyExchangeStandard);
+}
+static const int TestKeyCryptoOpsECCount = 2 + TestKeyCryptoSignCount * 2 + TestKeyCryptoEncryptCount * 2 + TestKeyCryptoKeyExchange * 1;
+
+/*
+ Bag Attributes
+ friendlyName: uranusLeaf
+ localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+ subject=/CN=uranusLeaf/emailAddress=uranus@uranus.com
+ issuer=/CN=plutoCA/emailAddress=pluto@pluto.com
+ */
+static const uint8_t _c1[] = {
+ 0x30, 0x82, 0x02, 0xe0, 0x30, 0x82, 0x01, 0xc8,
+ 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+ 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x30, 0x32, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43,
+ 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+ 0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40,
+ 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31,
+ 0x32, 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32,
+ 0x35, 0x5a, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32,
+ 0x31, 0x37, 0x30, 0x30, 0x30, 0x34, 0x32, 0x35,
+ 0x5a, 0x30, 0x37, 0x31, 0x13, 0x30, 0x11, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x75, 0x72,
+ 0x61, 0x6e, 0x75, 0x73, 0x4c, 0x65, 0x61, 0x66,
+ 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
+ 0x11, 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 0x40,
+ 0x75, 0x72, 0x61, 0x6e, 0x75, 0x73, 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, 0xa6, 0x82, 0x8e, 0xc6, 0x7e,
+ 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32, 0x35,
+ 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72, 0xa8,
+ 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80, 0x80,
+ 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93, 0x93,
+ 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b, 0xd7,
+ 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9, 0xfb,
+ 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08, 0xac,
+ 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0, 0x2a,
+ 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c, 0xc3,
+ 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde, 0x78,
+ 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e, 0x9b,
+ 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1, 0xf6,
+ 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03, 0xe7,
+ 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57, 0xdc,
+ 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64, 0xaa,
+ 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43, 0xe2,
+ 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9, 0x4f,
+ 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd, 0x04,
+ 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5, 0xb2,
+ 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e, 0x71,
+ 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23, 0x44,
+ 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1, 0x48,
+ 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5, 0x4b,
+ 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1, 0x47,
+ 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25, 0x08,
+ 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a, 0x32,
+ 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae, 0x26,
+ 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72, 0x23,
+ 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2, 0xd4,
+ 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75, 0x9e,
+ 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d, 0xf8,
+ 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x17, 0xa5, 0x22, 0xed,
+ 0xb8, 0x3e, 0x1f, 0x11, 0x99, 0xc5, 0xba, 0x28,
+ 0x3e, 0x7e, 0xa6, 0xeb, 0x02, 0x81, 0x06, 0xa1,
+ 0xc6, 0x80, 0xb9, 0x7e, 0x5c, 0x5a, 0x63, 0xe0,
+ 0x8d, 0xeb, 0xd0, 0xec, 0x9c, 0x3a, 0x94, 0x64,
+ 0x7c, 0x13, 0x54, 0x0d, 0xd6, 0xe3, 0x27, 0x88,
+ 0xa6, 0xd2, 0x4b, 0x36, 0xdd, 0x2e, 0xfa, 0x94,
+ 0xe5, 0x03, 0x27, 0xc9, 0xa6, 0x31, 0x02, 0xea,
+ 0x40, 0x77, 0x2e, 0x93, 0xc4, 0x4d, 0xe2, 0x70,
+ 0xe2, 0x67, 0x1c, 0xa8, 0x0d, 0xcd, 0x1a, 0x72,
+ 0x86, 0x2c, 0xea, 0xdc, 0x7f, 0x8c, 0x49, 0x2c,
+ 0xe7, 0x99, 0x13, 0xda, 0x3f, 0x58, 0x9e, 0xf5,
+ 0x4d, 0x3c, 0x8c, 0x1c, 0xed, 0x85, 0xa7, 0xe2,
+ 0xae, 0xda, 0x5f, 0xbe, 0x36, 0x1c, 0x9f, 0x5a,
+ 0xa0, 0xdc, 0x2a, 0xc0, 0xee, 0x71, 0x07, 0x26,
+ 0x8b, 0xe8, 0x8a, 0xf8, 0x2d, 0x36, 0x78, 0xc9,
+ 0x79, 0xfa, 0xbe, 0x98, 0x59, 0x95, 0x12, 0x24,
+ 0xf1, 0xda, 0x20, 0xc7, 0x78, 0xf9, 0x7c, 0x6a,
+ 0x24, 0x43, 0x82, 0xa8, 0x0f, 0xb1, 0x7d, 0x94,
+ 0xaa, 0x30, 0x35, 0xe5, 0x69, 0xdc, 0x0a, 0x0e,
+ 0xaf, 0x10, 0x5e, 0x1a, 0x81, 0x50, 0x5c, 0x7e,
+ 0x24, 0xb3, 0x07, 0x65, 0x4b, 0xc1, 0x7e, 0xc6,
+ 0x38, 0xdb, 0xd3, 0x6a, 0xf0, 0xd8, 0x85, 0x61,
+ 0x9a, 0x9f, 0xfe, 0x02, 0x46, 0x29, 0xb2, 0x9a,
+ 0xe2, 0x04, 0xe7, 0x72, 0xcc, 0x87, 0x46, 0xba,
+ 0x7d, 0xa8, 0xf9, 0xd0, 0x0f, 0x29, 0xfc, 0xfd,
+ 0xd1, 0xd0, 0x7f, 0x36, 0xc1, 0xd8, 0x7d, 0x88,
+ 0x03, 0x62, 0xf5, 0x8c, 0x00, 0xb5, 0xc2, 0x81,
+ 0x44, 0x67, 0x58, 0x11, 0xb4, 0x3a, 0xbb, 0xd1,
+ 0x8c, 0x94, 0x20, 0x60, 0xea, 0xa0, 0xac, 0xc1,
+ 0xf1, 0x08, 0x54, 0xb8, 0xf6, 0x5e, 0xac, 0xf1,
+ 0xec, 0x78, 0x69, 0x9d, 0x7e, 0x4d, 0x06, 0x3b,
+ 0x9b, 0x78, 0x78, 0x10
+};
+
+/*
+ Bag Attributes
+ friendlyName: uranusLeaf
+ localKeyID: 46 E0 8A 05 63 4D 17 3F CA A4 AA B6 5A DA CF BA 84 22 7C 23
+ Key Attributes: <No Attributes>
+ */
+static const uint8_t _k1[] = {
+ 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
+ 0x82, 0x01, 0x01, 0x00, 0xa6, 0x82, 0x8e, 0xc6,
+ 0x7e, 0xc9, 0x8c, 0x99, 0x6f, 0xb0, 0x62, 0x32,
+ 0x35, 0xe7, 0xdb, 0xff, 0x34, 0x84, 0xdc, 0x72,
+ 0xa8, 0xef, 0x22, 0x6f, 0x93, 0x63, 0x64, 0x80,
+ 0x80, 0x5d, 0x50, 0x7e, 0xb4, 0x2e, 0x1b, 0x93,
+ 0x93, 0x49, 0xca, 0xae, 0xcd, 0x34, 0x44, 0x4b,
+ 0xd7, 0xfa, 0x9f, 0x3c, 0xfc, 0x9e, 0x65, 0xa9,
+ 0xfb, 0x5e, 0x5d, 0x18, 0xa3, 0xf8, 0xb0, 0x08,
+ 0xac, 0x8f, 0xfd, 0x03, 0xcb, 0xbd, 0x7f, 0xa0,
+ 0x2a, 0xa6, 0xea, 0xca, 0xa3, 0x24, 0xef, 0x7c,
+ 0xc3, 0xeb, 0x95, 0xcb, 0x90, 0x3f, 0x5e, 0xde,
+ 0x78, 0xf2, 0x3d, 0x32, 0x72, 0xdb, 0x33, 0x6e,
+ 0x9b, 0x52, 0x9f, 0x0c, 0x60, 0x4a, 0x24, 0xa1,
+ 0xf6, 0x3b, 0x80, 0xbd, 0xa1, 0xdc, 0x40, 0x03,
+ 0xe7, 0xa0, 0x59, 0x1f, 0xdb, 0xb4, 0xed, 0x57,
+ 0xdc, 0x74, 0x0d, 0x99, 0x5a, 0x12, 0x74, 0x64,
+ 0xaa, 0xb6, 0xa5, 0x96, 0x75, 0xf9, 0x42, 0x43,
+ 0xe2, 0x52, 0xc2, 0x57, 0x23, 0x75, 0xd7, 0xa9,
+ 0x4f, 0x07, 0x32, 0x99, 0xbd, 0x3d, 0x44, 0xbd,
+ 0x04, 0x62, 0xe5, 0xb7, 0x2c, 0x0c, 0x11, 0xc5,
+ 0xb2, 0x2e, 0xc4, 0x12, 0x1d, 0x7f, 0x42, 0x1e,
+ 0x71, 0xaf, 0x39, 0x2b, 0x78, 0x47, 0x92, 0x23,
+ 0x44, 0xef, 0xe3, 0xc1, 0x47, 0x69, 0x5a, 0xf1,
+ 0x48, 0xaa, 0x37, 0xa4, 0x94, 0x6b, 0x96, 0xe5,
+ 0x4b, 0xfd, 0x05, 0xc7, 0x9c, 0xcc, 0x38, 0xd1,
+ 0x47, 0x85, 0x60, 0x7f, 0xef, 0xe9, 0x2e, 0x25,
+ 0x08, 0xf8, 0x7d, 0x98, 0xdd, 0x6c, 0xeb, 0x4a,
+ 0x32, 0x33, 0x44, 0x0b, 0x61, 0xb3, 0xf9, 0xae,
+ 0x26, 0x41, 0xb5, 0x38, 0xdb, 0xcf, 0x13, 0x72,
+ 0x23, 0x5b, 0x66, 0x20, 0x86, 0x4d, 0x24, 0xc2,
+ 0xd4, 0x94, 0xde, 0xe3, 0x24, 0xb7, 0xcd, 0x75,
+ 0x9e, 0x1d, 0x9f, 0xbc, 0xd0, 0x60, 0x34, 0x7d,
+ 0xf8, 0xcb, 0x41, 0x39, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0x02, 0x82, 0x01, 0x00, 0x4d, 0x27, 0xf2,
+ 0x40, 0xc8, 0x3f, 0x5c, 0x87, 0x3c, 0xd9, 0xde,
+ 0xa6, 0xa5, 0x93, 0xea, 0xbd, 0x36, 0xf8, 0xd9,
+ 0xad, 0xc7, 0xda, 0x07, 0x7a, 0xec, 0x31, 0x02,
+ 0x41, 0x09, 0x3a, 0x34, 0x32, 0x82, 0x0b, 0x5b,
+ 0x7b, 0xe6, 0xa4, 0x2a, 0xe7, 0x14, 0xef, 0x43,
+ 0x36, 0x61, 0xbe, 0x20, 0x4b, 0x82, 0x43, 0x63,
+ 0x98, 0x80, 0x82, 0x19, 0x61, 0x71, 0x99, 0xaa,
+ 0xf8, 0x59, 0xfd, 0xde, 0xa0, 0x03, 0xa8, 0xab,
+ 0x9a, 0xec, 0x28, 0xac, 0x63, 0x79, 0x75, 0x84,
+ 0x03, 0xac, 0x45, 0x5e, 0x04, 0x15, 0xb3, 0x47,
+ 0xa2, 0x8f, 0x28, 0xb0, 0x72, 0xd0, 0x06, 0x02,
+ 0xaf, 0x1e, 0x0a, 0x0a, 0xe9, 0x11, 0x35, 0x4a,
+ 0x04, 0x42, 0xb5, 0x0f, 0xd2, 0xcf, 0x4d, 0xdf,
+ 0xdb, 0xef, 0x58, 0xbd, 0xf3, 0xa5, 0x3b, 0x11,
+ 0x3f, 0xc5, 0x47, 0x81, 0x85, 0xad, 0xd7, 0x1f,
+ 0x58, 0x06, 0x42, 0xdc, 0x37, 0x3c, 0xdb, 0x98,
+ 0x33, 0xa1, 0xc6, 0x80, 0x07, 0xe0, 0x2b, 0xc5,
+ 0xf5, 0x60, 0x35, 0x6a, 0xa2, 0x06, 0x40, 0x4a,
+ 0xac, 0x64, 0x02, 0x58, 0x4d, 0x07, 0xe3, 0x69,
+ 0xd7, 0xe0, 0x8f, 0xb5, 0xf4, 0xbc, 0xfa, 0xab,
+ 0x1a, 0xb0, 0xfa, 0x29, 0xf8, 0xca, 0xde, 0x78,
+ 0xf0, 0x89, 0xe2, 0xf9, 0xb7, 0x68, 0x5b, 0x0e,
+ 0xdc, 0x4e, 0x8a, 0x56, 0x8d, 0x33, 0x20, 0x2e,
+ 0xed, 0x2e, 0xab, 0x6f, 0xba, 0x77, 0xef, 0xe6,
+ 0x12, 0x62, 0x49, 0x9e, 0x87, 0x76, 0x1c, 0x1e,
+ 0xf4, 0x0e, 0x9e, 0x78, 0x98, 0x91, 0x1a, 0xe3,
+ 0xb4, 0x51, 0x4b, 0x8c, 0x2f, 0x08, 0x97, 0x8f,
+ 0xf9, 0x68, 0x61, 0x40, 0xcd, 0xb6, 0x10, 0xb4,
+ 0xfb, 0x75, 0xb4, 0x20, 0xc1, 0x5a, 0xda, 0x64,
+ 0xfd, 0x51, 0x06, 0x85, 0x9a, 0x9e, 0x5d, 0x82,
+ 0x14, 0xd4, 0x41, 0x4e, 0x75, 0x10, 0xb5, 0x7b,
+ 0xd0, 0x4c, 0xd1, 0x00, 0x01, 0x02, 0x81, 0x81,
+ 0x00, 0xcf, 0x8e, 0x68, 0x04, 0x67, 0x09, 0xa9,
+ 0x6e, 0xff, 0x11, 0x8c, 0xe5, 0xe4, 0x16, 0xdd,
+ 0xb6, 0xa6, 0x55, 0xca, 0x4b, 0x0b, 0xbb, 0xb7,
+ 0xf5, 0xe5, 0x73, 0xf3, 0x24, 0x84, 0x29, 0xb2,
+ 0xc3, 0xbc, 0x7f, 0x2b, 0x4a, 0xc7, 0xdf, 0x46,
+ 0x8e, 0xe1, 0x35, 0x69, 0x1b, 0x8e, 0x9f, 0x6b,
+ 0x4d, 0xf3, 0x65, 0xae, 0x3d, 0x87, 0x2b, 0xc9,
+ 0xf0, 0x8c, 0xf2, 0x88, 0x2f, 0x1b, 0x79, 0x80,
+ 0xd2, 0xb2, 0x64, 0x0a, 0xcc, 0x66, 0x69, 0x4c,
+ 0xa1, 0x85, 0xc4, 0x6a, 0x94, 0x46, 0x70, 0x69,
+ 0xbc, 0x8c, 0x1c, 0x62, 0x65, 0x4d, 0x68, 0xcc,
+ 0xe3, 0x3c, 0x6c, 0xe7, 0xd1, 0x09, 0xed, 0xdd,
+ 0x42, 0x10, 0x11, 0x6b, 0xdd, 0x7c, 0xe3, 0xe1,
+ 0x3b, 0x3b, 0x0d, 0x01, 0x6d, 0xca, 0x2f, 0x4b,
+ 0x45, 0x5e, 0x76, 0x5d, 0x5c, 0x6f, 0x53, 0xa4,
+ 0x38, 0x74, 0x75, 0x94, 0x2c, 0xda, 0xf8, 0xa6,
+ 0x01, 0x02, 0x81, 0x81, 0x00, 0xcd, 0x5f, 0x9d,
+ 0x6c, 0x94, 0xf6, 0x44, 0x37, 0x72, 0xfe, 0xcf,
+ 0xbe, 0x82, 0x96, 0x24, 0x22, 0x12, 0x07, 0x6f,
+ 0xd1, 0x57, 0x7b, 0xc7, 0x63, 0x20, 0xf5, 0x93,
+ 0x79, 0x70, 0x0b, 0xe4, 0x38, 0x19, 0x62, 0x7b,
+ 0x89, 0x3e, 0x45, 0xdf, 0xd6, 0xae, 0x9d, 0x0d,
+ 0xa8, 0x76, 0xc1, 0xbd, 0x04, 0x2b, 0xaa, 0x30,
+ 0x6a, 0xac, 0x65, 0x91, 0x61, 0xf0, 0xf8, 0x5d,
+ 0xa3, 0x53, 0xa4, 0xfb, 0x99, 0xac, 0x46, 0x7a,
+ 0x12, 0x4b, 0xf7, 0xa7, 0x48, 0x41, 0x61, 0x48,
+ 0x26, 0x5c, 0x68, 0x2f, 0x73, 0x91, 0xe4, 0x74,
+ 0xcd, 0xc9, 0x8b, 0xe7, 0x26, 0xe4, 0x35, 0xde,
+ 0x32, 0x6b, 0x24, 0x49, 0xf2, 0x04, 0x67, 0x3d,
+ 0x31, 0x8f, 0x22, 0xe5, 0x49, 0xae, 0x49, 0x94,
+ 0xb3, 0x45, 0x2b, 0xed, 0x6f, 0x9c, 0xc7, 0x80,
+ 0xf0, 0x42, 0xd5, 0x8f, 0x27, 0xd6, 0xd6, 0x49,
+ 0xf2, 0x16, 0xcc, 0x4b, 0x39, 0x02, 0x81, 0x81,
+ 0x00, 0xbb, 0xb7, 0xd7, 0x59, 0xcb, 0xfb, 0x10,
+ 0x13, 0xc4, 0x7b, 0x92, 0x0c, 0x45, 0xcb, 0x6c,
+ 0x81, 0x0a, 0x55, 0x63, 0x1d, 0x96, 0xa2, 0x13,
+ 0xd2, 0x40, 0xd1, 0x2a, 0xa1, 0xe7, 0x2a, 0x73,
+ 0x74, 0xd6, 0x61, 0xc9, 0xbc, 0xdb, 0xa2, 0x93,
+ 0x85, 0x1c, 0x28, 0x9b, 0x44, 0x82, 0x2c, 0xaa,
+ 0xf7, 0x18, 0x60, 0xe9, 0x42, 0xda, 0xa2, 0xff,
+ 0x04, 0x21, 0xe6, 0x24, 0xc7, 0x3e, 0x39, 0x19,
+ 0x0a, 0xf6, 0xae, 0xc6, 0x99, 0x71, 0x32, 0x61,
+ 0x4d, 0x60, 0xd7, 0x71, 0x71, 0x63, 0x77, 0xbe,
+ 0x19, 0xfa, 0x3a, 0x9d, 0xbf, 0x73, 0x50, 0x8a,
+ 0xa6, 0x26, 0x7b, 0x74, 0xfa, 0x39, 0xd9, 0xb9,
+ 0x18, 0x4b, 0xc2, 0x05, 0xe5, 0x8f, 0x53, 0xe6,
+ 0xdc, 0x14, 0x1f, 0x42, 0x20, 0x93, 0x11, 0x4d,
+ 0x29, 0x93, 0x32, 0xc8, 0x63, 0x96, 0x88, 0x76,
+ 0x69, 0x5c, 0xe3, 0x0e, 0xbd, 0xb6, 0xd9, 0xd6,
+ 0x01, 0x02, 0x81, 0x80, 0x62, 0xa2, 0xed, 0x84,
+ 0xdc, 0xf6, 0x7a, 0x44, 0xf7, 0x62, 0x12, 0x7c,
+ 0xb9, 0x53, 0x4a, 0xff, 0x62, 0x11, 0x58, 0x4e,
+ 0xfe, 0xe9, 0x60, 0x15, 0xe8, 0x1a, 0x8a, 0x3d,
+ 0xe4, 0xe6, 0x91, 0x31, 0xb0, 0x5f, 0x70, 0x5d,
+ 0xb6, 0x1e, 0xf1, 0x26, 0xb6, 0xae, 0x8f, 0x84,
+ 0xbd, 0xa4, 0xc7, 0x17, 0x5d, 0xb1, 0x5b, 0x97,
+ 0xa0, 0x3d, 0x17, 0xda, 0x26, 0x55, 0xe3, 0x03,
+ 0x32, 0x85, 0x26, 0xa1, 0xe3, 0xef, 0xe5, 0x69,
+ 0x2c, 0x3b, 0x41, 0x88, 0x9e, 0x7e, 0x0e, 0x9c,
+ 0xfd, 0xfc, 0xbb, 0xed, 0x91, 0xc0, 0x5b, 0xa9,
+ 0x0a, 0x87, 0xba, 0xf9, 0x1e, 0xda, 0x10, 0x61,
+ 0xbe, 0xbb, 0xab, 0x18, 0x25, 0xad, 0x3f, 0xe2,
+ 0xb1, 0x90, 0x5c, 0xf7, 0x4a, 0x51, 0xe4, 0xad,
+ 0x45, 0x27, 0x97, 0xdd, 0xe7, 0x3a, 0x9a, 0x5e,
+ 0xca, 0x7a, 0xaf, 0x4a, 0xbf, 0x10, 0x24, 0x6b,
+ 0xb5, 0x2f, 0x61, 0x61, 0x02, 0x81, 0x81, 0x00,
+ 0x85, 0x7c, 0x78, 0xa5, 0x11, 0xdf, 0xc3, 0x6a,
+ 0x38, 0x48, 0xfa, 0x7e, 0x48, 0xf0, 0x5a, 0x58,
+ 0xe2, 0xc5, 0x83, 0x4e, 0x38, 0x3f, 0x4a, 0x2b,
+ 0x07, 0x57, 0x31, 0xe7, 0xbe, 0x50, 0xb1, 0xbb,
+ 0x24, 0xf3, 0x3d, 0x8b, 0x53, 0xb7, 0xd1, 0x47,
+ 0x72, 0x5e, 0xd5, 0xd6, 0x4c, 0xce, 0x2c, 0x46,
+ 0x61, 0x9a, 0xaa, 0xc3, 0x0e, 0xd4, 0x23, 0x2c,
+ 0xdd, 0xf5, 0xb7, 0xad, 0x38, 0x52, 0x17, 0xc4,
+ 0x16, 0xbb, 0xda, 0x1c, 0x61, 0xb1, 0xca, 0x8d,
+ 0xb2, 0xa0, 0xbe, 0x4f, 0x3d, 0x19, 0x0e, 0xe0,
+ 0x0e, 0x52, 0xad, 0xf3, 0xaf, 0xd9, 0xcc, 0x78,
+ 0xc2, 0xb1, 0x5e, 0x05, 0x5e, 0xf2, 0x27, 0x84,
+ 0x15, 0xe4, 0x8f, 0xca, 0xc5, 0x92, 0x43, 0xe0,
+ 0x24, 0x8d, 0xf2, 0x5d, 0x55, 0xcc, 0x9d, 0x2f,
+ 0xa9, 0xf6, 0x9b, 0x67, 0x6a, 0x87, 0x74, 0x36,
+ 0x34, 0x7c, 0xd4, 0x9d, 0xff, 0xad, 0xee, 0x69
+};
+
+static void test_key_proxy_identity() {
+ id certificate = CFBridgingRelease(SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)[NSData dataWithBytes:_c1 length:sizeof(_c1)]));
+ isnt(certificate, nil, "created certificate");
+ NSError *error;
+ id key = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)[NSData dataWithBytes:_k1 length:sizeof(_k1)], (CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate}, (void *)&error));
+ isnt(key, nil, "create key: %@", error);
+ id identity = CFBridgingRelease(SecIdentityCreate(kCFAllocatorDefault, (__bridge SecCertificateRef)certificate, (__bridge SecKeyRef)key));
+ isnt(identity, nil, "create identity");
+
+ SecKeyProxy *identityProxy = [[SecKeyProxy alloc] initWithIdentity:(SecIdentityRef)identity];
+ isnt(identityProxy, nil, "create identity proxy");
+
+ id localIdentity = CFBridgingRelease([SecKeyProxy createIdentityFromEndpoint:identityProxy.endpoint error:&error]);
+ isnt(localIdentity, nil, "create remote identity");
+
+ id localKey;
+ id localCertificate;
+ SecIdentityCopyPrivateKey((__bridge SecIdentityRef)identity, (void *)&localKey);
+ SecIdentityCopyCertificate((__bridge SecIdentityRef)identity, (void *)&localCertificate);
+ isnt(localKey, nil, "got key from localIdentity");
+ isnt(localCertificate, nil, "got certificate from localIdentity");
+
+ ok([certificate isEqual:localCertificate], "Certificates are the same");
+ is(SecKeyGetBlockSize((SecKeyRef)key), SecKeyGetBlockSize((SecKeyRef)localKey), "Keys are the same");
+
+ // Check that it is not possible to get identity from key proxy
+ SecKeyProxy *keyProxy = [[SecKeyProxy alloc] initWithKey:(SecKeyRef)key];
+ error = nil;
+ id secondIdentity = CFBridgingRelease([SecKeyProxy createIdentityFromEndpoint:keyProxy.endpoint error:&error]);
+ is(secondIdentity, nil, "connecting identity to key proxy should not be possible.");
+}
+static const int TestKeyProxyIdentityCount = 10;
+
+static const int TestCount =
+TestKeyProxyConnectCount +
+TestKeyProxySimpleOpsCount +
+TestKeyCryptoOpsRSACount +
+TestKeyCryptoOpsECCount +
+TestKeyProxyIdentityCount;
+
+int si_44_seckey_proxy(int argc, char *const *argv) {
+ plan_tests(TestCount);
+
+ @autoreleasepool {
+ test_key_proxy_connect();
+ test_key_proxy_simple_ops();
+ test_key_proxy_crypto_ops_RSA();
+ test_key_proxy_crypto_ops_EC();
+ test_key_proxy_identity();
+ }
+
+ return 0;
+}
- isnt(policy = SecPolicyCreateSSL(false, hostname), NULL, "create policy");
+ isnt(policy = SecPolicyCreateSSL(true, hostname), NULL, "create policy");
isnt(policies = CFArrayCreate(kCFAllocatorDefault, (const void **)&policy, 1, &kCFTypeArrayCallBacks), NULL, "create policies");
ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust");
static
SecCertificateRef SecCertificateCreateFromResource(NSString *name)
{
- NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".crt" subdirectory:@"si-82-sectrust-ct-data"];
+ NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"];
NSData *certData = [NSData dataWithContentsOfURL:url];
/* Case 1: coreos-ct-test embedded SCT - only 1 SCT - so not CT qualified */
isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
CFArrayAppendValue(certs, certF);
- test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307,
+ test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, NULL, date_20150307,
false, false, false, "coreos-ct-test 1");
CFReleaseNull(certs);
CFArrayAppendValue(certs, certD);
isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
CFArrayAppendValue(scts, proofD);
- test_ct_trust(certs, scts, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307,
+ test_ct_trust(certs, scts, NULL, anchors, trustedLogs, NULL, date_20150307,
false, false, false, "coreos-ct-test 2");
CFReleaseNull(certs);
CFReleaseNull(scts);
false, false, false, "digicert 2015");
CFReleaseNull(certs);
- /* case 4: paypal.com cert - not CT, but EV */
- isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
- CFArrayAppendValue(certs, www_paypal_com_cert);
- CFArrayAppendValue(certs, www_paypal_com_issuer_cert);
- test_ct_trust(certs, NULL, NULL, NULL, trustedLogs, CFSTR("www.paypal.com"), date_20150307,
- false, false, false, "paypal");
- CFReleaseNull(certs);
-
- /* Case 5: coreos-ct-test standalone SCT - 2 SCTs - CT qualified */
+ /* Case 4: coreos-ct-test standalone SCT - 2 SCTs - CT qualified */
isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
CFArrayAppendValue(certs, certA);
isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
CFArrayAppendValue(scts, proofA_1);
CFArrayAppendValue(scts, proofA_2);
- test_ct_trust(certs, scts, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307,
+ test_ct_trust(certs, scts, NULL, anchors, trustedLogs, NULL, date_20150307,
true, false, false, "coreos-ct-test 3");
CFReleaseNull(certs);
CFReleaseNull(scts);
-
- /* Case 6: Test with an invalid OCSP response */
+ /* Case 5: Test with an invalid OCSP response */
isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
CFArrayAppendValue(certs, certA);
isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
CFArrayAppendValue(scts, proofA_1);
- test_ct_trust(certs, scts, invalid_ocsp, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307,
+ test_ct_trust(certs, scts, invalid_ocsp, anchors, trustedLogs, NULL, date_20150307,
false, false, false, "coreos-ct-test 4");
CFReleaseNull(certs);
CFReleaseNull(scts);
- /* Case 7: Test with a valid OCSP response */
+ /* Case 6: Test with a valid OCSP response */
isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
CFArrayAppendValue(certs, certA);
isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
CFArrayAppendValue(scts, proofA_1);
- test_ct_trust(certs, scts, valid_ocsp, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307,
+ test_ct_trust(certs, scts, valid_ocsp, anchors, trustedLogs, NULL, date_20150307,
false, false, false, "coreos-ct-test 5");
CFReleaseNull(certs);
CFReleaseNull(scts);
- /* Case 8: Test with a bad hash OCSP response */
+ /* Case 7: Test with a bad hash OCSP response */
isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
CFArrayAppendValue(certs, certA);
isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
CFArrayAppendValue(scts, proofA_1);
- test_ct_trust(certs, scts, bad_hash_ocsp, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307,
+ test_ct_trust(certs, scts, bad_hash_ocsp, anchors, trustedLogs, NULL, date_20150307,
false, false, false, "coreos-ct-test 6");
CFReleaseNull(certs);
CFReleaseNull(scts);
- /* Case 9: Previously WhiteListed EV cert (expired in Feb 2016, so not on final whitelist)*/
- isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
- CFArrayAppendValue(certs, pilot_cert_3055998);
- CFArrayAppendValue(certs, pilot_cert_3055998_issuer);
- test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.ssbwingate.com"), date_20150307,
- false, false, false, "previously whitelisted cert");
- CFReleaseNull(certs);
-
- /* Case 10-13: WhiteListed EV cert */
- isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
- CFArrayAppendValue(certs, whitelist_00008013);
- CFArrayAppendValue(certs, whitelist_00008013_issuer);
- test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("clava.com"), date_20150307,
- false, false, false, "whitelisted cert 00008013");
- CFReleaseNull(certs);
-
- isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
- CFArrayAppendValue(certs, whitelist_5555bc4f);
- CFArrayAppendValue(certs, whitelist_5555bc4f_issuer);
- test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("lanai.dartmouth.edu"),
- date_20150307, false, false, false, "whitelisted cert 5555bc4f");
- CFReleaseNull(certs);
-
- isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
- CFArrayAppendValue(certs, whitelist_aaaae152);
- CFArrayAppendValue(certs, whitelist_5555bc4f_issuer); // Same issuer (Go Daddy) as above
- test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.falymusic.com"),
- date_20150307, false, false, false, "whitelisted cert aaaae152");
- CFReleaseNull(certs);
-
- isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
- CFArrayAppendValue(certs, whitelist_fff9b5f6);
- CFArrayAppendValue(certs, whitelist_fff9b5f6_issuer);
- test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.defencehealth.com.au"),
- date_20150307, false, false, false, "whitelisted cert fff9b5f6");
- CFReleaseNull(certs);
-
-
- /* case 14: Current (April 2016) www.digicert.com cert: 3 embedded SCTs, CT qualified */
+ /* case 8: Current (April 2016) www.digicert.com cert: 3 embedded SCTs, CT qualified */
isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
CFArrayAppendValue(certs, www_digicert_com_2016_cert);
CFArrayAppendValue(certs, digicert_sha2_ev_server_ca);
isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array for " #x); \
isnt(cfCert = SecCertificateCreateFromResource(@#x), NULL, "create cfCert from " #x); \
CFArrayAppendValue(certs, cfCert); \
- test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, CFSTR("coreos-ct-test.apple.com"), date_20150307, true, false, false, #x); \
+ test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, NULL, date_20150307, true, false, false, #x); \
CFReleaseNull(certs); \
CFReleaseNull(cfCert); \
} while (0)
int si_82_sectrust_ct(int argc, char *const *argv)
{
- plan_tests(329);
+ plan_tests(268);
tests();
#include "shared_regressions.h"
-static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, CFArrayRef anchors,
- CFDateRef date, CFIndex policyID, SecTrustResultType expected, const char *test_name)
+enum {
+ kBasicPolicy = 0,
+ kSSLServerPolicy = 1,
+};
+
+/* number of tests in the test_valid_trust function */
+#define TVT_COUNT 8
+
+static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, SecCertificateRef subca,
+ CFArrayRef anchors, CFDateRef date, CFIndex policyID,
+ SecTrustResultType expected, const char *test_name)
{
CFArrayRef policies=NULL;
SecPolicyRef policy=NULL;
if (ca) {
CFArrayAppendValue(certs, ca);
}
+ if (subca) {
+ CFArrayAppendValue(certs, subca);
+ }
}
- if (policyID == 1) {
+ if (policyID == kSSLServerPolicy) {
isnt(policy = SecPolicyCreateSSL(true, NULL), NULL, "create ssl policy");
} else {
isnt(policy = SecPolicyCreateBasicX509(), NULL, "create basic policy");
return SecCertificateCreateWithPEM(kCFAllocatorDefault, (__bridge CFDataRef)certData);
}
-static void tests()
+/* number of tests in date_constraints_tests function, plus calls to test_valid_trust */
+#define DC_COUNT (12+(TVT_COUNT*6))
+
+static void date_constraints_tests()
{
SecCertificateRef ca_na=NULL, ca_nb=NULL, root=NULL;
SecCertificateRef leaf_na_ok1=NULL, leaf_na_ok2=NULL;
/* Case 0: leaf_na_ok1 (not revoked) */
/* -- OK: cert issued 2017-10-20, before the CA not-after date of 2017-10-21 */
/* test cert has no SCT, but is expected to be OK since we now only apply the CT restriction for SSL. */
- test_valid_trust(leaf_na_ok1, ca_na, anchors, date_20180102, 0, kSecTrustResultUnspecified, "leaf_na_ok1 basic test");
+ test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102,
+ kBasicPolicy, kSecTrustResultUnspecified,
+ "leaf_na_ok1 basic");
/* Case 1: leaf_na_ok1 (not revoked) */
/* -- BAD: since a not-after date now requires CT (for SSL) and the test cert has no SCT, this is fatal. */
- test_valid_trust(leaf_na_ok1, ca_na, anchors, date_20180102, 1, kSecTrustResultFatalTrustFailure, "leaf_na_ok1 ssl test");
+ test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102,
+ kSSLServerPolicy, kSecTrustResultFatalTrustFailure,
+ "leaf_na_ok1 ssl");
/* 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, 0, kSecTrustResultFatalTrustFailure, "leaf_na_ok2 basic test");
+ test_valid_trust(leaf_na_ok2, ca_na, NULL, anchors, date_20180102,
+ kBasicPolicy, kSecTrustResultFatalTrustFailure,
+ "leaf_na_ok2 basic");
/* 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, 0, kSecTrustResultFatalTrustFailure, "leaf_nb_ok1 basic test");
+ test_valid_trust(leaf_nb_ok1, ca_nb, NULL, anchors, date_20180102,
+ kBasicPolicy, kSecTrustResultFatalTrustFailure,
+ "leaf_nb_ok1 basic");
/* 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, 0, kSecTrustResultUnspecified, "leaf_nb_ok2 basic test");
+ test_valid_trust(leaf_nb_ok2, ca_nb, NULL, anchors, date_20180102,
+ kBasicPolicy, kSecTrustResultUnspecified,
+ "leaf_nb_ok2 basic");
/* 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, 0, kSecTrustResultFatalTrustFailure, "leaf_nb_revoked1 basic test");
+ test_valid_trust(leaf_nb_revoked1, ca_nb, NULL, anchors, date_20180102,
+ kBasicPolicy, kSecTrustResultFatalTrustFailure,
+ "leaf_nb_revoked1 basic");
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(root);
CFReleaseSafe(anchors);
CFReleaseSafe(cal);
CFReleaseSafe(date_20180102);
}
+/* number of tests in known_intermediate_tests function, plus calls to test_valid_trust */
+#define KI_COUNT (10+(TVT_COUNT*3))
+
+static void known_intermediate_tests()
+{
+ SecCertificateRef ca_ki=NULL, root=NULL;
+ SecCertificateRef leaf_ki_ok1=NULL, leaf_ki_revoked1=NULL;
+ SecCertificateRef leaf_unknown=NULL, ca_unknown=NULL;
+
+ isnt(ca_ki = SecCertificateCreateFromResource(@"ca-ki"), NULL, "create ca-ki cert");
+ isnt(root = SecCertificateCreateFromResource(@"root"), NULL, "create root cert");
+ isnt(leaf_ki_ok1 = SecCertificateCreateFromResource(@"leaf-ki-ok1"), NULL, "create leaf-ki-ok1 cert");
+ isnt(leaf_ki_revoked1 = SecCertificateCreateFromResource(@"leaf-ki-revoked1"), NULL, "create leaf-ki-revoked1 cert");
+ isnt(ca_unknown = SecCertificateCreateFromResource(@"ca-unknown"), NULL, "create ca-unknown cert");
+ isnt(leaf_unknown = SecCertificateCreateFromResource(@"leaf-unknown"), NULL, "create leaf-unknown 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_20180310 = 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, 3, 10), "create verify absolute time 20180310");
+ isnt(date_20180310 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20180310");
+
+ /* Case 1: leaf_ki_ok1 */
+ /* -- OK: cert issued by a known intermediate */
+ test_valid_trust(leaf_ki_ok1, ca_ki, NULL, anchors, date_20180310,
+ kBasicPolicy, kSecTrustResultUnspecified,
+ "leaf_ki_ok1");
+
+ /* Case 2: leaf_ki_revoked1 */
+ /* -- BAD: CA specifies known-only+complete serial blocklist; this cert is on the blocklist. */
+ test_valid_trust(leaf_ki_revoked1, ca_ki, NULL, anchors, date_20180310,
+ kBasicPolicy, kSecTrustResultFatalTrustFailure,
+ "leaf_ki_revoked1");
+
+ /* Case 3: leaf_unknown */
+ /* -- BAD: ca_unknown issued from ca_ki, but is not a known intermediate.
+ * ca_ki has a path len of 0 which would normally result in kSecTrustResultRecoverableTrustFailure;
+ * however, since known-intermediates is asserted for ca_ki (non-overridable), we expect a fatal failure. */
+ test_valid_trust(leaf_unknown, ca_unknown, ca_ki, anchors, date_20180310,
+ kBasicPolicy, kSecTrustResultFatalTrustFailure,
+ "leaf_unknown test");
+
+ CFReleaseSafe(ca_ki);
+ CFReleaseSafe(leaf_ki_ok1);
+ CFReleaseSafe(leaf_ki_revoked1);
+ CFReleaseSafe(ca_unknown);
+ CFReleaseSafe(leaf_unknown);
+ CFReleaseSafe(root);
+ CFReleaseSafe(anchors);
+ CFReleaseSafe(cal);
+ CFReleaseSafe(date_20180310);
+}
+
int si_88_sectrust_valid(int argc, char *const *argv)
{
- plan_tests(12+(6*8));
+ plan_tests(DC_COUNT+KI_COUNT);
- tests();
+ date_constraints_tests();
+ known_intermediate_tests();
return 0;
}
<true/>
<key>com.apple.private.keychain.certificates</key>
<true/>
- <key>com.apple.private.read-trustd-downloads</key>
- <true/>
<key>com.apple.private.assets.accessible-asset-types</key>
<array>
<string>com.apple.MobileAsset.CertificatePinning</string>
secdebug("serverxpc", "entering");
if (type == XPC_TYPE_DICTIONARY) {
- // TODO: Find out what we're dispatching.
replyMessage = xpc_dictionary_create_reply(event);
-
uint64_t operation = xpc_dictionary_get_uint64(event, kSecXPCKeyOperation);
audit_token_t auditToken = {};
} 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);
if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) {
xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) {
- xpc_retain(connection);
- xpc_retain(event);
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- trustd_xpc_dictionary_handler(connection, event);
- xpc_release(event);
- xpc_release(connection);
- });
+ trustd_xpc_dictionary_handler(connection, event);
}
});
xpc_connection_resume(connection);
}
#endif
-static void trustd_cfstream_init() {
- CFReadStreamRef rs = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8*) "", 0, kCFAllocatorNull);
- CFReadStreamSetDispatchQueue(rs, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
- CFReadStreamSetDispatchQueue(rs, NULL);
- CFRelease(rs);
-}
-
int main(int argc, char *argv[])
{
char *wait4debugger = getenv("WAIT4DEBUGGER");
/* set up SQLite before some other component has a chance to create a database connection */
_SecDbServerSetup();
- /* <rdar://problem/33635964> Force legacy CFStream run loop initialization before any NSURLSession usage */
- trustd_cfstream_init();
-
gTrustd = &trustd_spi;
/* Initialize static content */
const char *home_var = getenv("HOME");
CFStringRef dbName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/Library/Keychains/su-40-sqldb.db"), home_var ? home_var : "");
- SecDbRef db = SecDbCreate(dbName, NULL);
+ SecDbRef db = SecDbCreate(dbName, 0600, true, true, true, true, kSecDbMaxIdleHandles, NULL);
CFReleaseNull(dbName);
ok(db, "SecDbCreate");
CFStringRef dbName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/Library/Keychains/su-41-sqldb-stress.db"), home_var ? home_var : "");
CFStringPerformWithCString(dbName, ^(const char *path) { unlink(path); });
- SecDbRef db = SecDbCreate(dbName, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool did_create, bool *callMeAgainForNextConnection, CFErrorRef *firstOpenError) {
+ SecDbRef db = SecDbCreate(dbName, 0600, true, true, true, true, kSecDbMaxIdleHandles,
+ ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool did_create, bool *callMeAgainForNextConnection, CFErrorRef *firstOpenError)
+ {
// This test will run when the database is first opened.
return ts_ok(SecDbExec(dbconn, CFSTR("CREATE TABLE tablea(key TEXT,value BLOB);"), firstOpenError),
"create table: %@", *firstOpenError);
#else
#define TARGET_HAS_KEYSTORE 1
#endif
-#elif TARGET_OS_EMBEDDED
+#elif TARGET_OS_IPHONE
#define TARGET_HAS_KEYSTORE 1
#else
#error "unknown keystore status for this platform"
--- /dev/null
+/*
+ * 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 _UTILITIES_SECAUTORELEASE_H_
+#define _UTILITIES_SECAUTORELEASE_H_
+
+/* Wrap a block with @autoreleasepool, suitable for use from C. */
+void SecAutoreleaseInvokeWithPool(os_block_t block);
+
+#endif /* !_UTILITIES_SECAUTORELEASE_H_ */
--- /dev/null
+/*
+ * 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@
+ */
+
+#include <os/base.h>
+#include "SecAutorelease.h"
+
+void
+SecAutoreleaseInvokeWithPool(os_block_t block)
+{
+ @autoreleasepool {
+ block();
+ }
+}
})
//
-// Smart comparitor for strings that matchies sorting functions
+// Smart comparator for strings that matches sorting functions
//
CFComparisonResult CFStringCompareSafe(const void *val1, const void *val2, void *context) {
return CFStringCompare(val1, val2, 0);
}
-void CFStringArrayPerfromWithDelimeterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description)) {
+void CFStringArrayPerformWithDelimiterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description)) {
if(!strings) {
action(CFSTR("null"));
} else {
}
-void CFStringArrayPerfromWithDescription(CFArrayRef strings, void (^action)(CFStringRef description)) {
- CFStringArrayPerfromWithDelimeterWithDescription(strings, CFSTR("["), CFSTR("]"), action);
+void CFStringArrayPerformWithDescription(CFArrayRef strings, void (^action)(CFStringRef description)) {
+ CFStringArrayPerformWithDelimiterWithDescription(strings, CFSTR("["), CFSTR("]"), action);
+}
+
+static void
+appendDescriptionToArray(const void *value, void *context)
+{
+ CFTypeRef obj = (CFTypeRef)value;
+ CFMutableArrayRef array = (CFMutableArrayRef)context;
+ CFStringRef desc;
+
+ if (CFGetTypeID(obj) == CFStringGetTypeID()) {
+ CFArrayAppendValue(array, obj);
+ } else {
+ desc = CFCopyDescription(obj);
+ if (desc != NULL) {
+ CFArrayAppendValue(array, desc);
+ CFRelease(desc);
+ } else {
+ CFArrayAppendValue(array, CFSTR("null"));
+ }
+ }
}
void CFStringSetPerformWithDescription(CFSetRef set, void (^action)(CFStringRef description)) {
if(!set) {
action(CFSTR("null"));
} else {
- CFMutableArrayRef keys = CFSetCopyValues(set);
+ CFMutableArrayRef keys = CFArrayCreateMutable(NULL, CFSetGetCount(set), &kCFTypeArrayCallBacks);
+ CFSetApplyFunction(set, appendDescriptionToArray, keys);
+
CFArraySortValues(keys, CFRangeMake(0, CFArrayGetCount(keys)), (CFComparatorFunction)&CFStringCompare, NULL);
- CFStringArrayPerfromWithDelimeterWithDescription(keys, CFSTR("{("), CFSTR(")}"), action);
+ CFStringArrayPerformWithDelimiterWithDescription(keys, CFSTR("{("), CFSTR(")}"), action);
CFReleaseNull(keys);
}
//
static inline CFArrayRef CFArrayCreateCountedForVC(CFAllocatorRef allocator, const CFArrayCallBacks *cbs, CFIndex entries, va_list args)
{
- const void *values[entries ? entries : 1];
- for (CFIndex currentValue = 0; currentValue < entries; ++currentValue)
- {
- values[currentValue] = va_arg(args, void*);
-
- if (values[currentValue] == NULL)
- values[currentValue] = kCFNull;
+ CFMutableArrayRef array = CFArrayCreateMutable(allocator, entries, cbs);
+ if (array == NULL) {
+ return NULL;
+ }
+ for (CFIndex currentValue = 0; currentValue < entries; ++currentValue) {
+ const void * value = va_arg(args, const void *);
+ if (value == NULL) {
+ value = kCFNull;
+ }
+ CFArrayAppendValue(array, value);
}
- return CFArrayCreate(allocator, values, entries, cbs);
+ CFArrayRef constArray = CFArrayCreateCopy(allocator, array);
+ CFRelease(array);
+ return constArray;
}
static inline CFArrayRef CFArrayCreateForVC(CFAllocatorRef allocator, const CFArrayCallBacks *cbs, va_list args)
}
return CFArrayCreateCountedForVC(allocator, cbs, entries, args);
-
}
static inline CFDictionaryRef CFDictionaryCreateCountedForCFTypesV(CFAllocatorRef allocator, CFIndex entries, va_list args)
{
- const void *keys[entries];
- const void *values[entries];
-
- for(CFIndex currentValue = 0; currentValue < entries; ++currentValue)
- {
- keys[currentValue] = va_arg(args, void*);
- values[currentValue] = va_arg(args, void*);
-
- if (values[currentValue] == NULL)
- values[currentValue] = kCFNull;
+ CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(allocator, entries,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (dictionary == NULL) {
+ return NULL;
+ }
+
+ for(CFIndex currentValue = 0; currentValue < entries; ++currentValue) {
+ CFTypeRef key = va_arg(args, CFTypeRef);
+ CFTypeRef value = va_arg(args, CFTypeRef);
+ if (value == NULL) {
+ value = kCFNull;
+ }
+ CFDictionarySetValue(dictionary, key, value);
}
- return CFDictionaryCreate(allocator, keys, values, entries,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryRef constDictionary = CFDictionaryCreateCopy(allocator, dictionary);
+ CFRelease(dictionary);
+ return constDictionary;
}
static inline CFDictionaryRef SECWRAPPER_SENTINEL CFDictionaryCreateForCFTypes(CFAllocatorRef allocator, ...)
// MARK: CFStringXxx Helpers
//
-void CFStringArrayPerfromWithDelimeterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description));
-void CFStringArrayPerfromWithDescription(CFArrayRef strings, void (^action)(CFStringRef description));
+void CFStringArrayPerformWithDelimiterWithDescription(CFArrayRef strings, CFStringRef start, CFStringRef end, void (^action)(CFStringRef description));
+void CFStringArrayPerformWithDescription(CFArrayRef strings, void (^action)(CFStringRef description));
void CFStringSetPerformWithDescription(CFSetRef set, void (^action)(CFStringRef description));
//
#include "SecIOFormat.h"
#include <stdio.h>
#include "Security/SecBase.h"
+#include "SecAutorelease.h"
//
#include <Security/SecureObjectSync/SOSDigestVector.h>
#include <Security/SecureObjectSync/SOSManifest.h>
-#define HAVE_UNLOCK_NOTIFY 0
-
struct __OpaqueSecDbStatement {
CFRuntimeBase _base;
bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error);
bool callOpenedHandlerForNextConnection;
CFMutableArrayRef notifyPhase; /* array of SecDBNotifyBlock */
- mode_t mode; /* database file permissions, default 0600 */
- bool readWrite; /* open database read-write, default true */
- bool allowRepair; /* allow database repair, default true */
- bool useWAL; /* use WAL mode, default true */
+ mode_t mode; /* database file permissions */
+ bool readWrite; /* open database read-write */
+ bool allowRepair; /* allow database repair */
+ bool useWAL; /* use WAL mode */
+ bool useRobotVacuum; /* use if SecDB should manage vacuum behind your back */
+ uint8_t maxIdleHandles;
void (^corruptionReset)(void);
};
CFGiblisFor(SecDb)
SecDbRef
-SecDbCreateWithOptions(CFStringRef dbName, mode_t mode, bool readWrite, bool allowRepair, bool useWAL,
+SecDbCreate(CFStringRef dbName, mode_t mode, bool readWrite, bool allowRepair, bool useWAL, bool useRobotVacuum, uint8_t maxIdleHandles,
bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error))
{
SecDbRef db = NULL;
db->readWrite = readWrite;
db->allowRepair = allowRepair;
db->useWAL = useWAL;
+ db->useRobotVacuum = useRobotVacuum;
+ db->maxIdleHandles = maxIdleHandles;
db->corruptionReset = NULL;
done:
return db;
}
-SecDbRef
-SecDbCreate(CFStringRef dbName,
- bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error))
-{
- return SecDbCreateWithOptions(dbName, 0600, true, true, true, opened);
-}
-
CFIndex
SecDbIdleConnectionCount(SecDbRef db) {
__block CFIndex count = 0;
}
}
-static void SecDbOnNotify(SecDbConnectionRef dbconn, void (^perform)()) {
+static void SecDbOnNotify(SecDbConnectionRef dbconn, void (^perform)(void)) {
perform();
}
return false;
}
-#if HAVE_UNLOCK_NOTIFY
-
-static void SecDbUnlockNotify(void **apArg, int nArg) {
- int i;
- for(i=0; i<nArg; i++) {
- dispatch_semaphore_t dsema = (dispatch_semaphore_t)apArg[i];
- dispatch_semaphore_signal(dsema);
- }
-}
-
-static bool SecDbWaitForUnlockNotify(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error) {
- int rc;
- dispatch_semaphore_t dsema = dispatch_semaphore_create(0);
- rc = sqlite3_unlock_notify(dbconn->handle, SecDbUnlockNotify, dsema);
- assert(rc == SQLITE_LOCKED || rc == SQLITE_OK);
- if (rc == SQLITE_OK) {
- dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER);
- }
- dispatch_release(dsema);
- return (rc == SQLITE_OK
- ? true
- : (stmt
- ? SecDbErrorWithStmt(rc, stmt, error, CFSTR("sqlite3_unlock_notify"))
- : SecDbErrorWithDb(rc, dbconn->handle, error, CFSTR("sqlite3_unlock_notify"))));
-}
-
-#endif
-
#define BUSY_TIMEOUT_MS (5 * 60 * 1000) /* 5 minutes */
-static bool SecDbBusyHandler(SecDbConnectionRef dbconn, CFErrorRef *error) {
- return SecDbErrorWithDb(sqlite3_busy_timeout(dbconn->handle, BUSY_TIMEOUT_MS), dbconn->handle, error, CFSTR("busy_handler"));
-}
-
static int sleepBackoff[] = { 10, 20, 50, 100, 250 };
static int sumBackoff[] = { 10, 30, 80, 180, 430 };
static int NumberOfSleepBackoff = sizeof(sleepBackoff)/sizeof(sleepBackoff[0]);
+// Use these as silly hacks to encode the SQLite return code in the backtrace, for hang debugging purposes
+static void __attribute__((noinline)) SecDbLockSleep(int ms) {
+ sqlite3_sleep(ms);
+}
+
+static void __attribute__((noinline)) SecDbBusySleep(int ms) {
+ sqlite3_sleep(ms);
+}
+
// Return true causes the operation to be tried again.
+// Note that we set sqlite3_busy_timeout on the connection, so anytime you're in here, it's likely due to SQLITE_LOCKED.
static bool SecDbWaitIfNeeded(SecDbConnectionRef dbconn, int s3e, sqlite3_stmt *stmt, CFStringRef desc, int nTries, CFErrorRef *error) {
-#if HAVE_UNLOCK_NOTIFY
- if (s3e == SQLITE_LOCKED) { // Optionally check for extended code being SQLITE_LOCKED_SHAREDCACHE
- return SecDbWaitForUnlockNotify(dbconn, stmt, error))
- }
-#endif
if (((0xFF & s3e) == SQLITE_BUSY) || ((0xFF & s3e) == SQLITE_LOCKED)) {
int totaltimeout, timeout;
}
if (totaltimeout < BUSY_TIMEOUT_MS) {
secinfo("#SecDB", "sqlite busy/locked: %d ntries: %d totaltimeout: %d", s3e, nTries, totaltimeout);
- sqlite3_sleep(timeout);
+ if(((0xFF & s3e) == SQLITE_LOCKED)) {
+ SecDbLockSleep(timeout);
+ } else {
+ SecDbBusySleep(timeout);
+ }
return true;
} else {
secinfo("#SecDB", "sqlite busy/locked: too long: %d ms, giving up", totaltimeout);
return ok;
}
+static int SecDBGetInteger(SecDbConnectionRef dbconn, CFStringRef sql)
+{
+ __block int number = -1;
+ __block CFErrorRef error = NULL;
+
+ (void)SecDbWithSQL(dbconn, sql, &error, ^bool(sqlite3_stmt *sqlStmt) {
+ (void)SecDbStep(dbconn, sqlStmt, &error, ^(bool *stop) {
+ number = sqlite3_column_int(sqlStmt, 0);
+ *stop = true;
+ });
+ return true;
+ });
+ CFReleaseNull(error);
+ return number;
+}
+
+
+void SecDBManagementTasks(SecDbConnectionRef dbconn)
+{
+ int64_t page_count = SecDBGetInteger(dbconn, CFSTR("pragma page_count"));
+ if (page_count <= 0) {
+ return;
+ }
+ int64_t free_count = SecDBGetInteger(dbconn, CFSTR("pragma freelist_count"));
+ if (free_count < 0) {
+ return;
+ }
+
+ int64_t max_free = 8192;
+
+ int64_t pages_in_use = page_count - free_count;
+ double loadFactor = ((double)pages_in_use/(double)page_count);
+ if (0.85 < loadFactor && free_count < max_free) {
+ /* no work yet */
+ } else {
+ int64_t pages_to_free = (int64_t)(0.2 * free_count);
+ if (0.4 > loadFactor) {
+ pages_to_free = free_count;
+ }
+
+ char *formatString = NULL;
+ asprintf(&formatString, "pragma incremental_vacuum(%d)", (int)pages_to_free);
+ if (formatString) {
+ char *sqlerror = NULL;
+ int rc = sqlite3_exec(dbconn->handle, formatString, NULL, NULL, &sqlerror);
+ if (rc) {
+ secerror("incremental_vacuum failed with: (%d) %{public}s", rc, sqlerror);
+ }
+ sqlite3_free(sqlerror);
+ free(formatString);
+ }
+ }
+}
+
+
static bool SecDbBeginTransaction(SecDbConnectionRef dbconn, SecDbTransactionType type, CFErrorRef *error)
{
bool ok = true;
SecDbNotifyPhase(dbconn, commited ? kSecDbTransactionDidCommit : kSecDbTransactionDidRollback);
secdebug("db", "SecDbEndTransaction %s %p", commited ? "kSecDbTransactionDidCommit" : "kSecDbTransactionDidRollback", dbconn);
dbconn->source = kSecDbAPITransaction;
+
+ if (commit && dbconn->db->useRobotVacuum) {
+ SecDBManagementTasks(dbconn);
+ }
};
SecDbPerformOnCommitQueue(dbconn, true, notifyAndExec);
case kSecDbRowStep:
secdebug("db", "kSecDbRowStep %@", error?*error:NULL);
if (row) {
- bool stop = false;
- row(&stop);
+ __block bool stop = false;
+ SecAutoreleaseInvokeWithPool(^{
+ row(&stop);
+ });
if (stop)
return true;
break;
return SecDbConnectionCheckCode(dbconn, sqlite3_file_control(dbconn->handle, NULL, op, arg), error, CFSTR("file_control"));
}
-static sqlite3 *_SecDbOpenV2(const char *path, int flags, CFErrorRef *error) {
-#if HAVE_UNLOCK_NOTIFY
- flags |= SQLITE_OPEN_SHAREDCACHE;
-#endif
+static sqlite3 *_SecDbOpenV2(const char *path,
+ int flags,
+ int useWAL,
+ int useRobotVacuum,
+ CFErrorRef *error) {
sqlite3 *handle = NULL;
int s3e = sqlite3_open_v2(path, &handle, flags, NULL);
if (s3e) {
} else {
SecDbError(s3e, error, CFSTR("open_v2 \"%s\" 0x%X"), path, flags);
}
+ } else if (SQLITE_OPEN_READWRITE == (flags & SQLITE_OPEN_READWRITE)) {
+ if (useRobotVacuum) {
+#define SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL 2
+ sqlite3_stmt *stmt;
+ int vacuumMode = -1;
+
+ /*
+ * Setting auto_vacuum = incremental on a database that is not empty requires
+ * a VACCUUM, so check if the vacuum mode is not INCREMENTAL, and if its not,
+ * set it to incremental and vacuum.
+ */
+
+ int s3e = sqlite3_prepare_v2(handle, "PRAGMA auto_vacuum", -1, &stmt, NULL);
+ if (s3e == 0) {
+ s3e = sqlite3_step(stmt);
+ if (s3e == SQLITE_ROW) {
+ vacuumMode = sqlite3_column_int(stmt, 0);
+ }
+ sqlite3_reset(stmt);
+ }
+
+ if (vacuumMode != SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL) {
+ (void)sqlite3_exec(handle, "PRAGMA auto_vacuum = incremental", NULL, NULL, NULL);
+ (void)sqlite3_exec(handle, "VACUUM", NULL, NULL, NULL);
+ }
+ }
+ if (useWAL) {
+ (void)sqlite3_exec(handle, "PRAGMA journal_mode = WAL", NULL, NULL, NULL);
+ }
+
+ // Let SQLite handle timeouts.
+ sqlite3_busy_timeout(handle, 5*1000);
}
return handle;
}
static bool SecDbOpenV2(SecDbConnectionRef dbconn, const char *path, int flags, CFErrorRef *error) {
- return (dbconn->handle = _SecDbOpenV2(path, flags, error)) != NULL;
+ return (dbconn->handle = _SecDbOpenV2(path, flags, dbconn->db->useWAL, dbconn->db->useRobotVacuum, error)) != NULL;
}
static bool SecDbTruncate(SecDbConnectionRef dbconn, CFErrorRef *error)
sqlite3 *corrupt_db = NULL;
char buf[PATH_MAX+1];
snprintf(buf, sizeof(buf), "%s-corrupt", db_path);
- if (dbconn->handle && (corrupt_db = _SecDbOpenV2(buf, SQLITE_OPEN_READWRITE, error))) {
+ if (dbconn->handle && (corrupt_db = _SecDbOpenV2(buf, SQLITE_OPEN_READWRITE, dbconn->db->useWAL, dbconn->db->useRobotVacuum, error))) {
int on = 1;
didRename = SecDbErrorWithDb(sqlite3_file_control(corrupt_db, NULL, SQLITE_FCNTL_PERSIST_WAL, &on), corrupt_db, error, CFSTR("persist wal"));
didRename &= SecDbErrorWithDb(sqlite3_file_control(corrupt_db, NULL, SQLITE_REPLACE_DATABASE, (void *)dbconn->handle), corrupt_db, error, CFSTR("replace database"));
dbconn);
}
}
-
- ok = ok && SecDbBusyHandler(dbconn, error);
});
return ok;
// Add back possible writable dbconn to the pool.
CFArrayInsertValueAtIndex(db->connections, readOnly ? count : 0, dbconn);
// Remove the last (probably read-only) dbconn from the pool.
- if (count >= kSecDbMaxIdleHandles) {
+ if (count >= db->maxIdleHandles) {
CFArrayRemoveValueAtIndex(db->connections, count);
}
}
});
}
-bool SecDbReplace(SecDbRef db, CFStringRef newDbPath, CFErrorRef *error) {
- // Replace the given database with the contents of the database
- // at newDbPath, as an atomic operation on db->queue.
-
- __block bool result = false;
- if (!db || !newDbPath) {
- secerror("called with NULL argument");
- return result;
- }
- dispatch_sync(db->queue, ^{
- // Explicitly close all database connections
- CFIndex idx, count = (db->connections) ? CFArrayGetCount(db->connections) : 0;
- for (idx = 0; idx < count; idx++) {
- SecDbConnectionRef dbconn = (SecDbConnectionRef) CFArrayGetValueAtIndex(db->connections, idx);
- if (dbconn->handle) {
- sqlite3_close(dbconn->handle);
- dbconn->handle = NULL;
- }
- }
- CFArrayRemoveAllValues(db->connections);
-
- __block sqlite3 *old_db = NULL;
- __block sqlite3 *new_db = NULL;
- CFStringPerformWithCString(db->db_path, ^(const char *db_path) {
- int s3e = sqlite3_open_v2(db_path, &old_db, SQLITE_OPEN_READWRITE, NULL);
- if (SQLITE_OK != s3e) {
- secerror("Unable to open db for writing: %s (error %d)", db_path, s3e);
- }
- });
- CFStringPerformWithCString(newDbPath, ^(const char *new_db_path) {
- int s3e = sqlite3_open_v2(new_db_path, &new_db, SQLITE_OPEN_READONLY, NULL);
- if (SQLITE_OK != s3e) {
- secerror("Unable to open db for reading: %s (error %d)", new_db_path, s3e);
- }
- });
- if (old_db && new_db) {
- // Replace old_db with contents of new_db
- int s3e = sqlite3_file_control(old_db, NULL, SQLITE_FCNTL_REPLACE_DATABASE, new_db);
- if (SQLITE_OK != s3e) {
- secerror("Unable to replace db: %@ (error %d)", db->db_path, s3e);
- } else {
- result = true;
- }
- }
- if (old_db) {
- sqlite3_close(old_db);
- }
- if (new_db) {
- sqlite3_close(new_db);
- }
-
- // Signal that connections are available again.
- dispatch_semaphore_signal(db->write_semaphore);
- dispatch_semaphore_signal(db->read_semaphore);
- });
-
- return result;
-}
-
bool SecDbPerformRead(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)) {
SecDbConnectionRef dbconn = SecDbConnectionAcquire(db, true, error);
bool success = false;
CFTypeID SecDbGetTypeID(void);
// Database creation
-SecDbRef SecDbCreateWithOptions(CFStringRef dbName, mode_t mode, bool readWrite, bool allowRepair, bool useWAL, bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error));
-
-SecDbRef SecDbCreate(CFStringRef dbName, bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error));
+SecDbRef
+SecDbCreate(CFStringRef dbName, mode_t mode,
+ bool readWrite, bool allowRepair, bool useWAL, bool useRobotVacuum, uint8_t maxIdleHandles,
+ 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));
// TODO: DEBUG only -> Private header
CFIndex SecDbIdleConnectionCount(SecDbRef db);
void SecDbReleaseAllConnections(SecDbRef db);
-bool SecDbReplace(SecDbRef db, CFStringRef newDbPath, CFErrorRef *error);
CFStringRef SecDbGetPath(SecDbRef db);
void SecDbRecordChange(SecDbConnectionRef dbconn, CFTypeRef deleted, CFTypeRef inserted);
void SecDbPerformOnCommitQueue(SecDbConnectionRef dbconn, bool barrier, dispatch_block_t perform);
+void SecDBManagementTasks(SecDbConnectionRef dbconn);
// MARK: -
// MARK: Bind helpers
#include <Foundation/Foundation.h>
#include "SecPLWrappers.h"
-#if TARGET_OS_EMBEDDED
+#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE
#include <PowerLog/PowerLog.h>
static typeof(PLShouldLogRegisteredEvent) *soft_PLShouldLogRegisteredEvent = NULL;
bool SecPLShouldLogRegisteredEvent(NSString *event)
{
-#if TARGET_OS_EMBEDDED
+#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE
if (setup())
return soft_PLShouldLogRegisteredEvent(PLClientIDSecurity, (__bridge CFStringRef)event);
#endif
void SecPLLogRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary)
{
-#if TARGET_OS_EMBEDDED
+#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE
if (setup())
soft_PLLogRegisteredEvent(PLClientIDSecurity,
(__bridge CFStringRef)eventName,
void SecPLLogTimeSensitiveRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary)
{
-#if TARGET_OS_EMBEDDED
+#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE
if (setup())
soft_PLLogTimeSensitiveRegisteredEvent(PLClientIDSecurity,
(__bridge CFStringRef)eventName,
<dict>
<key>TestName</key>
<string>secitemfunctionality</string>
+ <key>EnableEasyperf</key>
+ <true/>
+ <key>EasyperfArgs</key>
+ <array>
+ <string>-p</string>
+ <string>secd</string>
+ </array>
+ <key>Command</key>
+ <array>
+ <string>/AppleInternal/CoreOS/tests/Security/secitemfunctionality</string>
+ </array>
+ <key>EligibleResource</key>
+ <string>type != 'CAMEmbeddedDeviceResource'</string>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>secitemfunctionality</string>
+ <key>EnableEasyperf</key>
+ <true/>
+ <key>EasyperfArgs</key>
+ <array>
+ <string>-p</string>
+ <string>securityd</string>
+ </array>
+ <key>AsRoot</key>
+ <true/>
<key>Command</key>
<array>
<string>/AppleInternal/CoreOS/tests/Security/secitemfunctionality</string>
</array>
+ <key>EligibleResource</key>
+ <string>type == 'CAMEmbeddedDeviceResource'</string>
</dict>
<dict>
<key>TestName</key>
<string>/AppleInternal/CoreOS/tests/Security/authdtest</string>
</array>
<key>EligibleResource</key>
- <string>NOT (cpuArchitecture BEGINSWITH 'arm')</string>
- </dict>
- <dict>
- <key>TestName</key>
- <string>KeychainAnalytics</string>
- <key>Command</key>
- <array>
- <string>BATS_XCTEST_CMD</string>
- <string>/AppleInternal/XCTests/com.apple.security/KeychainAnalyticsTests.xctest</string>
- </array>
- </dict>
+ <string>type != 'CAMEmbeddedDeviceResource'</string>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>KeychainAnalyticsTests</string>
+ <key>Command</key>
+ <array>
+ <string>BATS_XCTEST_CMD</string>
+ <string>/AppleInternal/XCTests/com.apple.security/KeychainAnalyticsTests.xctest</string>
+ </array>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>KeychainMockAKSTests</string>
+ <key>Command</key>
+ <array>
+ <string>BATS_XCTEST_CMD</string>
+ <string>/AppleInternal/XCTests/com.apple.security/secdmockaks.xctest</string>
+ </array>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>MultiDeviceSimulatorTests</string>
+ <key>Command</key>
+ <array>
+ <string>BATS_XCTEST_CMD</string>
+ <string>/AppleInternal/XCTests/com.apple.security/MultiDeviceSimulatorTests.xctest</string>
+ </array>
+ <key>EligibleResource</key>
+ <string>type != 'CAMEmbeddedDeviceResource'</string>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>KeychainSecd_macOS</string>
+ <key>Command</key>
+ <array>
+ <string>BATS_XCTEST_CMD</string>
+ <string>/AppleInternal/XCTests/com.apple.security/secdxctests_mac.xctest</string>
+ </array>
+ <key>EligibleResource</key>
+ <string>type != 'CAMEmbeddedDeviceResource'</string>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>KeychainSecd_iOS</string>
+ <key>Command</key>
+ <array>
+ <string>BATS_XCTEST_CMD</string>
+ <string>/AppleInternal/XCTests/com.apple.security/secdxctests_ios.xctest</string>
+ </array>
+ <key>EligibleResource</key>
+ <string>type == 'CAMEmbeddedDeviceResource'</string>
+ </dict>
</array>
</dict>
</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>BATSConfigVersion</key>
+ <string>0.1.0</string>
+ <key>Project</key>
+ <string>Security</string>
+ <key>Condition</key>
+ <dict>
+ <key>ConditionName</key>
+ <string>LowDiskCondition</string>
+ <key>ConditionProfile</key>
+ <string>LowDiskConditionPrevailingExceedingLowThresholdNonCached</string>
+ </dict>
+ <key>Tests</key>
+ <array>
+ <dict>
+ <key>TestName</key>
+ <string>secitemstresstest</string>
+ <key>Command</key>
+ <array>
+ <string>/AppleInternal/CoreOS/tests/Security/secitemstresstest</string>
+ </array>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>secitemnotifications</string>
+ <key>Command</key>
+ <array>
+ <string>/AppleInternal/CoreOS/tests/Security/secitemnotifications</string>
+ </array>
+ </dict>
+ <dict>
+ <key>TestName</key>
+ <string>secitemfunctionality</string>
+ <key>Command</key>
+ <array>
+ <string>/AppleInternal/CoreOS/tests/Security/secitemfunctionality</string>
+ </array>
+ </dict>
+ </array>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>keychain-access-groups</key>
+ <array>
+ <string>com.apple.security.test.canary</string>
+ </array>
+</dict>
+</plist>
--- /dev/null
+#include <Foundation/Foundation.h>
+#include <Security/Security.h>
+#include <Security/SecItemPriv.h>
+#include <err.h>
+
+static void usage(void) __dead2;
+static bool create_item(NSString *acct);
+static bool verify_item(NSString *acct, bool deleteit);
+static void initial_state(void) __dead2;
+static uint64_t update_state(void);
+static void reset(void) __dead2;
+
+static NSString *kCanaryAccessGroup = @"com.apple.security.test.canary";
+static NSString *kCanaryStateAccount = @"com.apple.security.test.canaryState";
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ uint64_t iter;
+ bool success;
+
+ iter = 0;
+ while ((ch = getopt(argc, argv, "ir")) != -1) {
+ switch (ch) {
+ case 'i':
+ initial_state();
+ /*notreached*/
+ case 'r':
+ reset();
+ /*notreached*/
+ default:
+ usage();
+ /*notreached*/
+ }
+ }
+
+ iter = update_state();
+ fprintf(stderr, "iter = %llu\n\n", iter);
+
+ @autoreleasepool {
+ if (iter > 0) {
+ printf("[TEST] Verify and delete previous canary item\n");
+ success = verify_item([NSString stringWithFormat:@"canary%llu", iter - 1], true);
+ printf("[%s]\n", success ? "PASS" : "FAIL");
+ fprintf(stderr, "\n");
+ }
+
+ printf("[TEST] Create canary item\n");
+ success = create_item([NSString stringWithFormat:@"canary%llu", iter]);
+ printf("[%s]\n", success ? "PASS" : "FAIL");
+ }
+}
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, "usage: secitemcanarytest -i Generate initial state\n"
+ " secitemcanarytest Normal operation\n"
+ " secitemcanarytest -r Reset everything\n");
+ exit(1);
+}
+
+static bool
+create_item(NSString *acct)
+{
+ OSStatus status;
+ NSDictionary *attrs;
+ int nerrors = 0;
+
+ attrs = @{
+ (id)kSecClass : (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel : @"secitemcanarytest-oneItem",
+ (id)kSecAttrAccount : acct,
+ (id)kSecAttrAccessGroup : kCanaryAccessGroup,
+ (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock,
+ (id)kSecAttrNoLegacy : (id)kCFBooleanTrue,
+ (id)kSecValueData : [NSData dataWithBytes:"password" length: 8],
+ };
+ status = SecItemAdd((__bridge CFDictionaryRef)attrs, NULL);
+ if (status != 0) {
+ nerrors++;
+ fprintf(stderr, "SecItemAdd(%s): %d\n", acct.UTF8String, status);
+ } else {
+ printf("created: %s\n", acct.UTF8String);
+ }
+
+ if (!verify_item(acct, false)) {
+ nerrors++;
+ }
+
+ return (nerrors == 0);
+}
+
+static bool
+verify_item(NSString *acct, bool deleteit)
+{
+ OSStatus status;
+ NSDictionary *query;
+ CFTypeRef result;
+ int nerrors = 0;
+
+ query = @{
+ (id)kSecClass : (id)kSecClassGenericPassword,
+ (id)kSecAttrAccessGroup : kCanaryAccessGroup,
+ (id)kSecAttrAccount : acct,
+ (id)kSecReturnAttributes : @YES,
+ (id)kSecMatchLimit : (id)kSecMatchLimitAll,
+ (id)kSecAttrNoLegacy : (id)kCFBooleanTrue,
+ };
+ result = NULL;
+ status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
+ if (status != 0) {
+ nerrors++;
+ fprintf(stderr, "SecItemCopyMatching(%s): %d\n", acct.UTF8String, status);
+ } else {
+ if (CFGetTypeID(result) != CFArrayGetTypeID()) {
+ nerrors++;
+ fprintf(stderr, "SecItemCopyMatching(%s): not array\n", acct.UTF8String);
+ } else if (CFArrayGetCount(result) != 1) {
+ nerrors++;
+ fprintf(stderr, "SecItemCopyMatching(%s): incorrect number of results\n", acct.UTF8String);
+ } else {
+ printf("verified: %s\n", acct.UTF8String);
+ }
+ CFRelease(result);
+ }
+
+ if (deleteit) {
+ status = SecItemDelete((__bridge CFDictionaryRef)query);
+ if (status != 0) {
+ nerrors++;
+ fprintf(stderr, "SecItemDelete(%s): %d\n", acct.UTF8String, status);
+ } else {
+ printf("deleted: %s\n", acct.UTF8String);
+ }
+ }
+
+ return (nerrors == 0);
+}
+
+static void
+initial_state(void)
+{
+ OSStatus status;
+ uint64_t state;
+ NSDictionary *attrs;
+
+ state = 0;
+ attrs = @{
+ (id)kSecClass : (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel : @"canary test state",
+ (id)kSecAttrAccount : kCanaryStateAccount,
+ (id)kSecAttrAccessGroup : kCanaryAccessGroup,
+ (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock,
+ (id)kSecAttrNoLegacy : (id)kCFBooleanTrue,
+ (id)kSecValueData : [NSData dataWithBytes:&state length:sizeof(state)],
+ };
+ status = SecItemAdd((__bridge CFDictionaryRef)attrs, NULL);
+ switch (status) {
+ case 0:
+ exit(0);
+ /*notreached*/
+ default:
+ errx(1, "SecItemAdd: %d", status);
+ /*notreached*/
+ }
+}
+
+static uint64_t
+update_state(void)
+{
+ OSStatus status;
+ NSMutableDictionary *query;
+ NSDictionary *update;
+ CFTypeRef result;
+ uint64_t state = 0, next_state;
+
+ query = [NSMutableDictionary dictionary];
+ query[(id)kSecClass] = (id)kSecClassGenericPassword;
+ query[(id)kSecAttrAccessGroup] = kCanaryAccessGroup;
+ query[(id)kSecAttrAccount] = kCanaryStateAccount;
+ query[(id)kSecAttrNoLegacy] = (id)kCFBooleanTrue;
+ query[(id)kSecReturnData] = @YES;
+
+ status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
+ switch (status) {
+ case 0:
+ if (result != NULL && CFGetTypeID(result) == CFDataGetTypeID() && CFDataGetLength(result) == sizeof(state)) {
+ memcpy(&state, CFDataGetBytePtr(result), sizeof(state));
+ } else {
+ errx(1, "invalid state");
+ /*notreached*/
+ }
+ break;
+ default:
+ errx(1, "failed to retrieve state: SecItemCopyMatching(state): %d", status);
+ /*notreached*/
+ }
+
+ next_state = state + 1;
+
+ query[(id)kSecReturnData] = nil;
+ update = @{
+ (id)kSecValueData : [NSData dataWithBytes:&next_state length:sizeof(next_state)],
+ };
+ status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update);
+
+ if (status != 0) {
+ errx(1, "SecItemUpdate: %d", status);
+ }
+
+ return state;
+}
+
+static void
+reset(void)
+{
+ OSStatus status;
+ NSDictionary *query;
+
+ query = @{
+ (id)kSecClass : (id)kSecClassGenericPassword,
+ (id)kSecAttrAccessGroup : kCanaryAccessGroup,
+ (id)kSecAttrNoLegacy : (id)kCFBooleanTrue,
+ };
+ status = SecItemDelete((__bridge CFDictionaryRef)query);
+ switch (status) {
+ case 0:
+ case errSecItemNotFound:
+ exit(0);
+ /*notreached*/
+ default:
+ errx(1, "SecItemDelete: %d", status);
+ /*notreached*/
+ }
+}
#if !TARGET_OS_SIMULATOR
SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wstrict-prototypes"
SOFT_LINK_CLASS(AuthKit, AKAccountManager);
+#pragma clang diagnostic pop
#endif
@implementation SOSCCAuthPlugin
+static bool accountIsHSA2(ACAccount *account) {
+ bool hsa2 = false;
+
+#if !TARGET_OS_SIMULATOR
+ AKAccountManager *manager = [getAKAccountManagerClass() sharedInstance];
+ if(manager != nil) {
+#if TARGET_OS_OSX
+ ACAccount *aka = [manager authKitAccountWithAltDSID:account.icaAltDSID];
+#else
+ ACAccount *aka = [manager authKitAccountWithAltDSID:account.aa_altDSID];
+#endif
+ if (aka) {
+ AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount: aka];
+ if(securityLevel == AKAppleIDSecurityLevelHSA2) {
+ hsa2 = true;
+ }
+ }
+ }
+#endif
+ secnotice("accounts", "Account %s HSA2", (hsa2) ? "is": "isn't" );
+ return hsa2;
+}
+
- (void) didReceiveAuthenticationResponseParameters: (NSDictionary *) parameters
accountStore: (ACDAccountStore *) store
account: (ACAccount *) account
do_auth = [account aa_isPrimaryAccount];
}
-#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;
+ if(do_auth && !accountIsHSA2(account)) {
NSString *rawPassword = [account _aa_rawPassword];
if (rawPassword != NULL) {
- const char *password = [rawPassword cStringUsingEncoding:NSUTF8StringEncoding];
- CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *) password, strlen(password));
- if (passwordData) {
- secinfo("accounts", "Performing SOS circle credential set for account %@: %@", accountIdentifier, account.username);
- NSString *dsid = [account aa_personID];
- if (!SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef) account.username, passwordData, (__bridge CFStringRef) dsid, &authError)) {
- secerror("Unable to set SOS circle credentials for account %@: %@", accountIdentifier, authError);
- CFReleaseNull(authError);
- }
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ CFErrorRef asyncError = NULL;
+ NSString *dsid = [account aa_personID];
+ const char *password = [rawPassword cStringUsingEncoding:NSUTF8StringEncoding];
+ CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *) password, strlen(password));
- CFRelease(passwordData);
- }
+ if (passwordData) {
+ secinfo("accounts", "Performing async SOS circle credential set for account %@: %@", accountIdentifier, account.username);
+
+ if (!SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef) account.username, passwordData, (__bridge CFStringRef) dsid, &asyncError)) {
+ secerror("Unable to set SOS circle credentials for account %@: %@", accountIdentifier, asyncError);
+ secinfo("accounts", "Returning from failed async call to SOSCCSetUserCredentialsAndDSID");
+ CFReleaseNull(asyncError);
+ } else {
+ secinfo("accounts", "Returning from successful async call to SOSCCSetUserCredentialsAndDSID");
+ }
+ CFRelease(passwordData);
+ } else {
+ secinfo("accounts", "Failed to create string for call to SOSCCSetUserCredentialsAndDSID");
+ }
+ });
} else {
+ CFErrorRef authError = NULL;
if (!SOSCCCanAuthenticate(&authError)) {
secerror("Account %@ did not present a password and we could not authenticate the SOS circle: %@", accountIdentifier, authError);
- CFReleaseNull(authError); // CFReleaseSafe?
+ CFReleaseNull(authError);
}
}
} else {
#include <TargetConditionals.h>
+_kSecFrameworkBundleID
+
#include "Security/SecExports.exp-in"
#include "Security/SecAccessControlExports.exp-in"
#include "Security/SecureObjectSync/SOSExports.exp-in"
#endif
#if __OBJC2__ && (TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__))
-_OBJC_CLASS_$_SFTransactionMetric
+_OBJC_CLASS_$_SFSignInAnalytics
#endif //__OBJC2__ && IPHONE || OSX
_OTSetupControlProtocol
_securityd_message_with_reply_sync
_securityd_message_no_error
_securityd_send_sync_and_do
+_securityd_send_async_and_do
#if TARGET_OS_IOS
_SecSecuritySetMusrMode
#endif
_CMSEncoderSetSigningTime
_CMSEncoderSetAppleCodesigningHashAgility
_CMSEncoderSetAppleCodesigningHashAgilityV2
+_CMSEncoderSetAppleExpirationTime
_CMSEncoderSetCertificateChainMode
_CMSEncoderGetCertificateChainMode
_CMSEncoderUpdateContent
_CMSEncoderCopySignerTimestampWithPolicy
_CMSDecoderCopySignerAppleCodesigningHashAgility
_CMSDecoderCopySignerAppleCodesigningHashAgilityV2
+_CMSDecoderCopySignerAppleExpirationTime
#endif // TARGET_OS_OSX
#if TARGET_OS_OSX
_kSecCodeSignerTeamIdentifier
_kSecCodeSignerPlatformIdentifier
_kSecCodeSignerRuntimeVersion
+_kSecCodeSignerPreserveAFSC
_kSecCodeSignerTimestampServer
_kSecCodeSignerTimestampAuthentication
_kSecCodeSignerTimestampOmitCertificates
_kSecCodeInfoDiskRepVersionMin
_kSecCodeInfoDiskRepVersionSDK
_kSecCodeInfoResourceDirectory
+_kSecCodeInfoNotarizationDate
_kSecGuestAttributeCanonical
_kSecGuestAttributeDynamicCode
_kSecGuestAttributeDynamicCodeInfoPlist
_kSecRequirementKeyInfoPlist
_kSecRequirementKeyEntitlements
_kSecRequirementKeyIdentifier
+_kSecRequirementKeyPackageChecksum
+_kSecRequirementKeyChecksumAlgorithm
_kSecCFErrorArchitecture
_kSecCFErrorPath
_kSecCFErrorPattern
_SecAssessmentCopyUpdate
_SecAssessmentControl
_SecAssessmentGetTypeID
+_SecAssessmentTicketLookup
+_SecAssessmentTicketRegister
_kSecAssessmentContextKeyOperation
_kSecAssessmentOperationTypeExecute
_kSecAssessmentOperationTypeInstall
_kSecAssessmentAssessmentVerdict
_kSecAssessmentAssessmentWeakSignature
_kSecAssessmentAssessmentCodeSigningError
+_kSecAssessmentAssessmentNotarizationDate
_kSecAssessmentRuleKeyID
_kSecAssessmentRuleKeyPriority
_kSecAssessmentRuleKeyAllow
_SecCodeMapMemory
_SecCodeSetStatus
_SecCodeValidateFileResource
+#endif // TARGET_OS_IPHONE
+
_SecCopyLastError
+#if TARGET_OS_IPHONE
_SecRequirementCopyData
_SecRequirementCopyString
_SecRequirementCreateWithData
_kSecCodeInfoFormat
_kSecCodeInfoImplicitDesignatedRequirement
_kSecCodeInfoMainExecutable
+_kSecCodeInfoNotarizationDate
_kSecCodeInfoPList
_kSecCodeInfoPlatformIdentifier
_kSecCodeInfoRequirementData
_OBJC_CLASS_$_SFAnalyticsMultiSampler
_OBJC_CLASS_$_SFAnalyticsSampler
_OBJC_CLASS_$_SFAnalyticsSQLiteStore
+_OBJC_METACLASS_$_SFSignInAnalytics
_SFAnalyticsMaxEventsToReport
_SFSQLiteJournalSuffixes
_SFAnalyticsSamplerIntervalOncePerReport
_SFAnalyticsAttributeErrorUnderlyingChain
_SFAnalyticsTopicKeySync
_SFAnaltyicsTopicTrust
+_SFAnalyticsErrorDomain
_OBJC_CLASS_$_SOSAnalytics
_CKDKVSPerformanceCountersSampler
_CKDKVSPerfCounterTotalWaitTimeSynchronize
_CKDKVSPerfCounterLongestWaitTimeSynchronize
_CKDKVSPerfCounterSynchronizeFailures
+
+_OBJC_CLASS_$_LocalKeychainAnalytics
+_LKAEventUpgrade
#endif // __OBJC2__
+_LKAReportKeychainUpgradeOutcome
+_LKAReportKeychainUpgradeOutcomeWithError
+
+//
// Padding
+//
_SecPaddingCompute
//
buildPhases = (
);
dependencies = (
+ 47C2F1902059CBFC0062DE30 /* PBXTargetDependency */,
0C78CCE51FCC97E7008B4B24 /* PBXTargetDependency */,
F621D0831ED6ED5B000EA569 /* PBXTargetDependency */,
6C24EF4A1E415109000DE79F /* PBXTargetDependency */,
DC61096B1D78E60C002223DE /* PBXTargetDependency */,
EBD849361B242C8900C5FD1E /* PBXTargetDependency */,
E74583BE1BF66489001B54A4 /* PBXTargetDependency */,
- E7E7B24B1BFC0CD900B1E66B /* PBXTargetDependency */,
EB31EA831D3EF2FB008F952A /* PBXTargetDependency */,
DA30D6821DF8C93500EC6B43 /* PBXTargetDependency */,
EBC15EA91BE29AC3001C0C5B /* PBXTargetDependency */,
6CAA8D3F1F8431C9007B6E03 /* PBXTargetDependency */,
6CAA8CE91F82FD13007B6E03 /* PBXTargetDependency */,
DC5225001E40295C0021640A /* PBXTargetDependency */,
+ EB636BD320992DB400C1E21A /* PBXTargetDependency */,
+ EB11965A20A6300600BFDA1B /* PBXTargetDependency */,
6C7C38811FD88C4700DFFE68 /* PBXTargetDependency */,
);
name = Security_executables_osx;
name = Security_frameworks_ios;
productName = kernel;
};
+ 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 4809F7AC2061B697003E72D0 /* Build configuration list for PBXAggregateTarget "MultiPeerSimulatorTests" */;
+ buildPhases = (
+ );
+ dependencies = (
+ 4809F7AE2061B6AA003E72D0 /* PBXTargetDependency */,
+ 4809F7B02061B6B0003E72D0 /* PBXTargetDependency */,
+ );
+ name = MultiPeerSimulatorTests;
+ productName = MultiPeerSimulatorTests;
+ };
4C541F840F250BF500E508AE /* Security_executables_ios */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 4C541FA30F250C8C00E508AE /* Build configuration list for PBXAggregateTarget "Security_executables_ios" */;
buildPhases = (
);
dependencies = (
+ 4771D982209A76B100BA9772 /* PBXTargetDependency */,
+ 47C2F18C2059CBEA0062DE30 /* PBXTargetDependency */,
0C78CCE71FCC97F1008B4B24 /* PBXTargetDependency */,
D41257F11E941E7D00781F23 /* PBXTargetDependency */,
EB27FF281E40717400EC9E3A /* PBXTargetDependency */,
0C99B740131C984900584CF4 /* PBXTargetDependency */,
0CC827F2138712B100BD99B7 /* PBXTargetDependency */,
52D82BF616A627100078DFE5 /* PBXTargetDependency */,
- CD0637811A840C6400C81E74 /* PBXTargetDependency */,
4C52D0EE16EFCD720079966E /* PBXTargetDependency */,
BE197F631911742900BA91D1 /* PBXTargetDependency */,
BE4AC9B418B8020400B84964 /* PBXTargetDependency */,
6CAA8D3D1F8431BC007B6E03 /* PBXTargetDependency */,
6CAA8CE51F82FD08007B6E03 /* PBXTargetDependency */,
6C7C38881FD88C5A00DFFE68 /* PBXTargetDependency */,
+ EB636BCA20992D8900C1E21A /* PBXTargetDependency */,
+ EB11965C20A6301100BFDA1B /* PBXTargetDependency */,
);
name = Security_executables_ios;
productName = phase2;
buildPhases = (
);
dependencies = (
+ EB8910FE20E06DF500DE533F /* PBXTargetDependency */,
+ 47C2F1922059CC040062DE30 /* PBXTargetDependency */,
BE061EB91EE5EBA000B22118 /* PBXTargetDependency */,
EBA62C1C1EAD34CD0096B33A /* PBXTargetDependency */,
D41257F51E941E8E00781F23 /* PBXTargetDependency */,
D41AD46C1B978F28008C7270 /* PBXTargetDependency */,
D41AD46E1B978F4C008C7270 /* PBXTargetDependency */,
EB9FE0B61BFBC499004FEAAF /* PBXTargetDependency */,
+ EB636BD520992DC000C1E21A /* PBXTargetDependency */,
+ EB89FAFE20DBDAA800085498 /* PBXTargetDependency */,
+ EB89FB0020DBDAA800085498 /* PBXTargetDependency */,
+ EB89FB0220DBDAA800085498 /* PBXTargetDependency */,
+ EB8910F820E0287E00DE533F /* PBXTargetDependency */,
);
name = Security_executables_watchos;
productName = Security_executables_watchos;
buildPhases = (
);
dependencies = (
+ 47C2F18E2059CBF40062DE30 /* PBXTargetDependency */,
BE061EB71EE5EB9000B22118 /* PBXTargetDependency */,
EBA62C151EAD34C60096B33A /* PBXTargetDependency */,
D41257F31E941E8600781F23 /* PBXTargetDependency */,
D41AD44E1B978791008C7270 /* PBXTargetDependency */,
D41AD44A1B9786D8008C7270 /* PBXTargetDependency */,
EB9FE08D1BFBC48F004FEAAF /* PBXTargetDependency */,
+ EB636BD120992DA300C1E21A /* PBXTargetDependency */,
+ EBC73F52209A705A00AE3350 /* PBXTargetDependency */,
+ EB11965E20A6302100BFDA1B /* PBXTargetDependency */,
+ EBC73F5D209A739600AE3350 /* PBXTargetDependency */,
+ EBC73F64209A73A100AE3350 /* PBXTargetDependency */,
+ EBC73F66209A73A100AE3350 /* PBXTargetDependency */,
+ EB8910F120E0287600DE533F /* PBXTargetDependency */,
);
name = Security_executables_tvos;
productName = Security_executables_tvos;
EB10557F1E14DFBE0003C309 /* PBXTargetDependency */,
BE9C38D11EB115F4007E2AE1 /* PBXTargetDependency */,
DCDB29761FD8839F00B5D242 /* PBXTargetDependency */,
+ 47D991D720407F890078CAE2 /* PBXTargetDependency */,
);
name = Security_tests_osx;
productName = Security_test_macos;
EB10557D1E14DFB60003C309 /* PBXTargetDependency */,
BE9C38D31EB11605007E2AE1 /* PBXTargetDependency */,
DCDB29781FD883AB00B5D242 /* PBXTargetDependency */,
+ 47D991D020407F7E0078CAE2 /* PBXTargetDependency */,
);
name = Security_tests_ios;
productName = Security_test_ios;
buildPhases = (
);
dependencies = (
+ 47455B24205B3E2F008FE980 /* PBXTargetDependency */,
D41257F71E941E9600781F23 /* PBXTargetDependency */,
- EB6A6FB31B90F89F0045DC68 /* PBXTargetDependency */,
+ DAE40BD520CF3ED5002D5674 /* PBXTargetDependency */,
);
name = Security_executables_bridge;
productName = Security_executables_Bridge;
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
+ 091B39732063B67700ECAB6F /* RemoteServiceDiscovery.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 091B396D2063B64A00ECAB6F /* RemoteServiceDiscovery.framework */; };
+ 0927FEBC1F81338600864E07 /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; };
+ 096C647020AB1BC700D7B7D5 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; };
+ 09A3B9D81F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 09A3B9D91F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 09A3B9E11F82734400C5C324 /* si-44-seckey-proxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */; };
+ 09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; };
+ 09BFE35C20A32E0E008511E9 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; };
09CB49701F2F64E300C8E4DE /* si-44-seckey-fv.m in Sources */ = {isa = PBXBuildFile; fileRef = 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */; };
+ 0C0582AE20D9657800D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
+ 0C0582B820D9B70D00D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
0C0BDB32175685B000BC1A7E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C0BDB31175685B000BC1A7E /* main.m */; };
0C0BDB881756A51000BC1A7E /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; };
0C0BDB8D1756A66100BC1A7E /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; };
0C48990B1E0E0FF300C6CF70 /* SOSTransportCircleCK.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C48990A1E0E0FF300C6CF70 /* SOSTransportCircleCK.h */; };
0C4899121E0E105D00C6CF70 /* SOSTransportCircleCK.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C4899111E0E105D00C6CF70 /* SOSTransportCircleCK.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 */; };
+ 0C5663EC20BE2DF30035F362 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; };
+ 0C5663EF20BE2E220035F362 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
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 */; };
+ 0C7756CD209A664800268D2C /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; };
+ 0C7756CE209A694100268D2C /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.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, ); }; };
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, ); }; };
+ 0C9AEEAF20783FBB00BF6237 /* SFSignInAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */; };
+ 0C9AEEBB20783FF900BF6237 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ 0C9AEEBE207843D000BF6237 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; };
+ 0C9FB40720D872A600864612 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
+ 0C9FB40820D8731800864612 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
+ 0C9FB40920D8735500864612 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
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, ); }; };
0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; };
0CAD1E591E1C5CBD00537693 /* secd-52-offering-gencount-reset.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C4F1D8085D800865A7C /* secd-52-offering-gencount-reset.m */; };
0CAD1E5A1E1C5CD100537693 /* secd-71-engine-save.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C641D8085D800865A7C /* secd-71-engine-save.m */; };
- 0CAD1E5B1E1C5CE100537693 /* secd-76-idstransport.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C681D8085D800865A7C /* secd-76-idstransport.m */; };
- 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 */; };
+ 0CB50A0D20AA486800FE4675 /* SOSAccountTrustClassic+Expansion.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */; };
+ 0CB50A0E20AA4C2F00FE4675 /* SOSAccountTrustClassic+Circle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760491E12F30200B4381E /* SOSAccountTrustClassic+Circle.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, ); }; };
+ 0CBFEACA200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; };
+ 0CBFEACB200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; };
+ 0CBFEACC200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0CBFEACD200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.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 */; };
+ 0CC3771320A222BC00B58D2D /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; };
+ 0CC3775020ACA0DF00B58D2D /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; };
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 */; };
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 */; };
0CE7604E1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE7604D1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m */; };
0CE760501E1301DC00B4381E /* SOSAccountTrustClassic+Expansion.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE7604F1E1301DC00B4381E /* SOSAccountTrustClassic+Expansion.h */; };
0CE760521E1314F700B4381E /* SOSAccountTrustClassic+Identity.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE760511E1314F700B4381E /* SOSAccountTrustClassic+Identity.h */; };
0CE760541E13155100B4381E /* SOSAccountTrustClassic+Circle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE760531E13155100B4381E /* SOSAccountTrustClassic+Circle.h */; };
0CE760561E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CE760551E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h */; };
+ 0CF406522072E422003D6A7F /* SFSignInAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */; };
0CFC029C1D41650700E6283B /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; };
0CFC02C21D41651E00E6283B /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; };
107226D30D91DB32003CF14F /* SecTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 107226D10D91DB32003CF14F /* SecTask.h */; settings = {ATTRIBUTES = (Private, ); }; };
22A23B3E1E3AAC9800C41830 /* SecRequirement.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067931D8CDF7E007602F1 /* SecRequirement.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 */; };
+ 3DD1FF92201FC4EA0086D049 /* SecureTransportTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */; };
+ 3DD1FF93201FC4EF0086D049 /* STLegacyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */; };
+ 3DD1FF94201FC4F40086D049 /* STLegacyTests+ciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */; };
+ 3DD1FF95201FC4F70086D049 /* STLegacyTests+clientauth.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */; };
+ 3DD1FF96201FC4FE0086D049 /* STLegacyTests+crashes.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */; };
+ 3DD1FF97201FC5030086D049 /* STLegacyTests+dhe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */; };
+ 3DD1FF98201FC5080086D049 /* STLegacyTests+falsestart.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */; };
+ 3DD1FF99201FC50E0086D049 /* STLegacyTests+noconn.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */; };
+ 3DD1FF9A201FC5130086D049 /* STLegacyTests+renegotiate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */; };
+ 3DD1FF9B201FC5170086D049 /* STLegacyTests+sessioncache.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */; };
+ 3DD1FF9C201FC51B0086D049 /* STLegacyTests+sessionstate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */; };
+ 3DD1FF9E201FC53A0086D049 /* STLegacyTests+split.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */; };
+ 3DD1FF9F201FC5410086D049 /* STLegacyTests+sslciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */; };
+ 3DD1FFA0201FC5450086D049 /* STLegacyTests+tls12.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */; };
+ 3DD1FFA1201FC5660086D049 /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCA451D8B82CD00070CB0 /* ssl-utils.c */; };
+ 3DD1FFA2201FC5800086D049 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; };
+ 3DD1FFA3201FC5870086D049 /* libDiagnosticMessagesClient.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41D36701EB14D87007FA978 /* libDiagnosticMessagesClient.tbd */; };
+ 3DD1FFA4201FC58F0086D049 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
+ 3DD1FFA5201FC59D0086D049 /* libsecurity_ssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC9CF1D8B824700070CB0 /* libsecurity_ssl.a */; };
+ 3DD1FFA7201FC5B90086D049 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
+ 3DD1FFAA201FC5C30086D049 /* libcoretls.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */; };
+ 3DD1FFAB201FC5C30086D049 /* libcoretls_cfhelpers.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */; };
+ 3DD1FFB4201FDB1D0086D049 /* STLegacyTests+noconn.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */; };
+ 3DD1FFB5201FDB1D0086D049 /* STLegacyTests+falsestart.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */; };
+ 3DD1FFB6201FDB1D0086D049 /* STLegacyTests+crashes.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */; };
+ 3DD1FFB7201FDB1D0086D049 /* STLegacyTests+clientauth.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */; };
+ 3DD1FFB8201FDB1D0086D049 /* SecureTransportTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */; };
+ 3DD1FFB9201FDB1D0086D049 /* STLegacyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */; };
+ 3DD1FFBA201FDB1D0086D049 /* STLegacyTests+ciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */; };
+ 3DD1FFBB201FDB1D0086D049 /* STLegacyTests+dhe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */; };
+ 3DD1FFBC201FDB1D0086D049 /* STLegacyTests+renegotiate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */; };
+ 3DD1FFBD201FDB1D0086D049 /* STLegacyTests+sessioncache.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */; };
+ 3DD1FFBE201FDB1D0086D049 /* STLegacyTests+sessionstate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */; };
+ 3DD1FFBF201FDB1D0086D049 /* STLegacyTests+split.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */; };
+ 3DD1FFC0201FDB1D0086D049 /* STLegacyTests+sslciphers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */; };
+ 3DD1FFC1201FDB1D0086D049 /* STLegacyTests+tls12.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */; };
+ 3DD1FFC2201FDB1D0086D049 /* ssl-utils.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCA451D8B82CD00070CB0 /* ssl-utils.c */; };
+ 3DD1FFC4201FDB1D0086D049 /* libcoretls.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */; };
+ 3DD1FFC5201FDB1D0086D049 /* libcoretls_cfhelpers.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */; };
+ 3DD1FFC6201FDB1D0086D049 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
+ 3DD1FFC8201FDB1D0086D049 /* libsecurity_ssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC9CF1D8B824700070CB0 /* libsecurity_ssl.a */; };
+ 3DD1FFC9201FDB1D0086D049 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
+ 3DD1FFCB201FDB1D0086D049 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; };
+ 3DD1FFD1201FDC460086D049 /* STLegacyTests+clientauth41.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE78201AA50C0086D049 /* STLegacyTests+clientauth41.m */; };
+ 3DD1FFD2201FDCA80086D049 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; };
+ 3DD1FFD5201FF7860086D049 /* SecureTransport_iosTests.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DD1FE86201AA5120086D049 /* SecureTransport_iosTests.plist */; };
+ 3DD1FFD7201FF7B10086D049 /* SecureTransport_macosTests.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DD1FE79201AA50D0086D049 /* SecureTransport_macosTests.plist */; };
433E519E1B66D5F600482618 /* AppSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 433E519D1B66D5F600482618 /* AppSupport.framework */; };
4381603A1B4DCE8F00C54D58 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; };
4381603B1B4DCEFF00C54D58 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; };
44A655A51AA4B4C70059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
44A655A61AA4B4C80059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
470415DC1E5E1534001F3D95 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 470415DB1E5E1534001F3D95 /* main.m */; };
+ 470D96711FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; };
+ 470D96721FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; };
+ 470D96731FCDE55B0065FE90 /* SecCDKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */; };
+ 470D96741FCDE55B0065FE90 /* SecCDKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */; };
4710A6D91F34F21700745267 /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; };
+ 4718AE10205B39620068EC3F /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; };
+ 4718AE11205B39620068EC3F /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; };
+ 4718AE12205B39620068EC3F /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 790850840CA87CF00083CC4D /* server.c */; };
+ 4718AE13205B39620068EC3F /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; };
+ 4718AE14205B39620068EC3F /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; };
+ 4718AE15205B39620068EC3F /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; };
+ 4718AE16205B39620068EC3F /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; };
+ 4718AE19205B39620068EC3F /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D47CA65C1EB036450038E2BB /* libMobileGestalt.dylib */; };
+ 4718AE1A205B39620068EC3F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
+ 4718AE1B205B39620068EC3F /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
+ 4718AE1C205B39620068EC3F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; };
+ 4718AE1E205B39620068EC3F /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; };
+ 4718AE1F205B39620068EC3F /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; };
+ 4718AE20205B39620068EC3F /* libSWCAgent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC4D1D80D00800B0A59C /* libSWCAgent.a */; };
+ 4718AE21205B39620068EC3F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; };
+ 4718AE22205B39620068EC3F /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; };
+ 4718AE23205B39620068EC3F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; };
+ 4718AE24205B39620068EC3F /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
+ 4718AE25205B39620068EC3F /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; };
+ 4718AE27205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */; };
+ 4718AE29205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; };
+ 4718AE30205B39C40068EC3F /* OTAuthenticatedCiphertext.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */; };
+ 4718AE31205B39C40068EC3F /* OTPrivateKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */; };
+ 4718AE32205B39C40068EC3F /* OTBottle.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A11FD71CC800933DAC /* OTBottle.proto */; };
+ 4718AE33205B39C40068EC3F /* OTBottleContents.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A51FD720C900933DAC /* OTBottleContents.proto */; };
+ 4718AE34205B39C40068EC3F /* CKKSSerializedKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */; };
+ 4718AE35205B39C40068EC3F /* CKKSSQLDatabaseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DC797E131DD3F88300CC9E42 /* CKKSSQLDatabaseObject.m */; };
+ 4718AE36205B39C40068EC3F /* CKKSRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC185981E24E87D009657D8 /* CKKSRateLimiter.m */; };
+ 4718AE37205B39C40068EC3F /* CKKSCKAccountStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFB12C41E95A4C000510F5F /* CKKSCKAccountStateTracker.m */; };
+ 4718AE38205B39C40068EC3F /* SecCDKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */; };
+ 4718AE39205B39C40068EC3F /* CKKSPowerCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */; };
+ 4718AE3A205B39C40068EC3F /* CKKSGroupOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCCD88E71E42622200F5AA71 /* CKKSGroupOperation.m */; };
+ 4718AE3B205B39C40068EC3F /* OTContextRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */; };
+ 4718AE3C205B39C40068EC3F /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */; };
+ 4718AE3D205B39C40068EC3F /* CKKSManifestLeafRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 476D873A1E6750E200190352 /* CKKSManifestLeafRecord.m */; };
+ 4718AE3E205B39C40068EC3F /* CKKSItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDCCB8E1DF7B8D4006E840E /* CKKSItem.m */; };
+ 4718AE3F205B39C40068EC3F /* CKKSItemEncrypter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8BA1DD51883002BDCFA /* CKKSItemEncrypter.m */; };
+ 4718AE40205B39C40068EC3F /* CKKSOutgoingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9B7AE41DCBF604004E9385 /* CKKSOutgoingQueueEntry.m */; };
+ 4718AE42205B39C40068EC3F /* CKKSIncomingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B3B1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m */; };
+ 4718AE43205B39C40068EC3F /* OTLocalStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */; };
+ 4718AE44205B39C40068EC3F /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; };
+ 4718AE45205B39C40068EC3F /* OTBottledPeerSigned.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */; };
+ 4718AE46205B39C40068EC3F /* CKKSIncomingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4F11E0C86800010F836 /* CKKSIncomingQueueOperation.m */; };
+ 4718AE47205B39C40068EC3F /* CKKSOutgoingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4FD1E0C98320010F836 /* CKKSOutgoingQueueOperation.m */; };
+ 4718AE48205B39C40068EC3F /* CKKSZoneStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B371DEFADB500A3DAFA /* CKKSZoneStateEntry.m */; };
+ 4718AE49205B39C40068EC3F /* AsymKeybagBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 526965CC1E6E283100627F9D /* AsymKeybagBackup.m */; };
+ 4718AE4A205B39C40068EC3F /* RateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */; };
+ 4718AE4B205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC15F7651E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m */; };
+ 4718AE4C205B39C40068EC3F /* CKKSCurrentItemPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */; };
+ 4718AE4D205B39C40068EC3F /* CKKSLocalSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3D748B1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m */; };
+ 4718AE4E205B39C40068EC3F /* OTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0F1FCB481800580909 /* OTManager.m */; };
+ 4718AE4F205B39C40068EC3F /* OTEscrowKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */; };
+ 4718AE50205B39C40068EC3F /* CKKSCurrentKeyPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D1F41E5520550056214F /* CKKSCurrentKeyPointer.m */; };
+ 4718AE51205B39C40068EC3F /* CKKSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */; };
+ 4718AE52205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C501F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m */; };
+ 4718AE53205B39C40068EC3F /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; };
+ 4718AE54205B39C40068EC3F /* CKKSNearFutureScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */; };
+ 4718AE55205B39C40068EC3F /* CKKSMirrorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B2E1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m */; };
+ 4718AE56205B39C40068EC3F /* CloudKitCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC94BCC91F10448600E07CEB /* CloudKitCategories.m */; };
+ 4718AE57205B39C40068EC3F /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; };
+ 4718AE58205B39C40068EC3F /* CKKS.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8C51DD55476002BDCFA /* CKKS.m */; };
+ 4718AE59205B39C40068EC3F /* CKKSSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB5D93A1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m */; };
+ 4718AE5A205B39C40068EC3F /* CKKSRecordHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = DC762A9D1E57A86A00B03A2C /* CKKSRecordHolder.m */; };
+ 4718AE5B205B39C40068EC3F /* SOSChangeTracker.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D4F1D8085F200865A7C /* SOSChangeTracker.c */; };
+ 4718AE5C205B39C40068EC3F /* CKKSScanLocalItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1DA6671E4555D80094CE7F /* CKKSScanLocalItemsOperation.m */; };
+ 4718AE5D205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC18F76E1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m */; };
+ 4718AE5E205B39C40068EC3F /* CKKSNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2C5F5B1F0EB97E00FEBDA7 /* CKKSNotifier.m */; };
+ 4718AE5F205B39C40068EC3F /* SOSEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D561D8085F200865A7C /* SOSEngine.c */; };
+ 4718AE60205B39C40068EC3F /* CKKSKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4DB14F1E24692100CD6769 /* CKKSKey.m */; };
+ 4718AE61205B39C40068EC3F /* CKKSViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3BA1E57CA7A00B61300 /* CKKSViewManager.m */; };
+ 4718AE62205B39C40068EC3F /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; };
+ 4718AE63205B39C40068EC3F /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; };
+ 4718AE64205B39C40068EC3F /* CKKSReachabilityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */; };
+ 4718AE65205B39C40068EC3F /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C8E1D8085D800865A7C /* SecDbItem.c */; };
+ 4718AE66205B39C40068EC3F /* SecDbKeychainItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */; };
+ 4718AE67205B39C40068EC3F /* SecDbQuery.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C921D8085D800865A7C /* SecDbQuery.c */; };
+ 4718AE68205B39C40068EC3F /* CKKSResultOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447891F5764C600236DB4 /* CKKSResultOperation.m */; };
+ 4718AE69205B39C40068EC3F /* CKKSManifest.m in Sources */ = {isa = PBXBuildFile; fileRef = 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */; };
+ 4718AE6A205B39C40068EC3F /* SecItemBackupServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9C1D8085D800865A7C /* SecItemBackupServer.c */; };
+ 4718AE6B205B39C40068EC3F /* SecItemDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C941D8085D800865A7C /* SecItemDataSource.c */; };
+ 4718AE6C205B39C40068EC3F /* OctagonControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC124DC220059B8700BE8DAC /* OctagonControlServer.m */; };
+ 4718AE6D205B39C40068EC3F /* SecItemDb.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C961D8085D800865A7C /* SecItemDb.c */; };
+ 4718AE6E205B39C40068EC3F /* SecItemSchema.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C981D8085D800865A7C /* SecItemSchema.c */; };
+ 4718AE6F205B39C40068EC3F /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; };
+ 4718AE70205B39C40068EC3F /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5CFB37201960FF00913B9C /* OTRamping.m */; };
+ 4718AE71205B39C40068EC3F /* SecItemServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9A1D8085D800865A7C /* SecItemServer.c */; };
+ 4718AE72205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; };
+ 4718AE74205B39C40068EC3F /* OTContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE981FC9DA5A00580909 /* OTContext.m */; };
+ 4718AE75205B39C40068EC3F /* NSOperationCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447951F5766D200236DB4 /* NSOperationCategories.m */; };
+ 4718AE76205B39C40068EC3F /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; };
+ 4718AE77205B39C40068EC3F /* SecLogSettingsServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CAE1D8085D800865A7C /* SecLogSettingsServer.m */; };
+ 4718AE78205B39C40068EC3F /* CKKSDeviceStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C261F17E455007640C8 /* CKKSDeviceStateEntry.m */; };
+ 4718AE79205B39C40068EC3F /* CKKSFixups.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */; };
+ 4718AE7A205B39C40068EC3F /* OTIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */; };
+ 4718AE7C205B39C40068EC3F /* SecOTRRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB41D8085D800865A7C /* SecOTRRemote.m */; };
+ 4718AE7D205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278E71ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m */; };
+ 4718AE7E205B39C40068EC3F /* CKKSNewTLKOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD662F41E329B6800188186 /* CKKSNewTLKOperation.m */; };
+ 4718AE7F205B39C40068EC3F /* CKKSLockStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DC207EB71ED4EAB600D46873 /* CKKSLockStateTracker.m */; };
+ 4718AE80205B39C40068EC3F /* OTCloudStoreState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */; };
+ 4718AE81205B39C40068EC3F /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; };
+ 4718AE82205B39C40068EC3F /* CKKSKeychainView.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3B11E57C67500B61300 /* CKKSKeychainView.m */; };
+ 4718AE83205B39C40068EC3F /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; };
+ 4718AE84205B39C40068EC3F /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; };
+ 4718AE85205B39C40068EC3F /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; };
+ 4718AE86205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7A17EC1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m */; };
+ 4718AE87205B39C40068EC3F /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341F21F8447AB00AB9BDF /* CKKSTLKShare.m */; };
+ 4718AE88205B39C40068EC3F /* CKKSHealTLKSharesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */; };
+ 4718AE89205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D2141E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m */; };
+ 4718AE8A205B39C40068EC3F /* SecBackupKeybagEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 52AA92881E662A4A004301A6 /* SecBackupKeybagEntry.m */; };
+ 4718AE8B205B39C40068EC3F /* iCloudTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB31D8085D800865A7C /* iCloudTrace.c */; };
+ 4718AE8C205B39C40068EC3F /* CKKSAPSReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D841E2F14810089CF55 /* CKKSAPSReceiver.m */; };
+ 4718AE8D205B39C40068EC3F /* OTBottledPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */; };
+ 4718AE8F205B39C40068EC3F /* SOSEnsureBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */; };
+ 4718AE90205B39C40068EC3F /* OTBottledPeerRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */; };
+ 4718AE91205B39C40068EC3F /* OTCloudStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */; };
+ 4718AE92205B39C40068EC3F /* CKKSSIV.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */; };
+ 4718AE93205B39C40068EC3F /* OTPreflightInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */; };
+ 4718AE95205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */; };
+ 4718AE96205B39C40068EC3F /* CKKSZoneChangeFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */; };
+ 4718AE97205B39C40068EC3F /* CKKSCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C331F17ECE5007640C8 /* CKKSCondition.m */; };
+ 4718AE98205B39C40068EC3F /* CKKSZone.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D961E3014250089CF55 /* CKKSZone.m */; };
+ 4718AE99205B39C40068EC3F /* SFKeychainServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 47FF17251FD60ACA00875565 /* SFKeychainServer.m */; };
+ 4718AE9A205B39C40068EC3F /* SFECPublicKey+SPKI.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */; };
+ 4718AE9B205B39C40068EC3F /* swcagent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78EA01D80860C00865A7C /* swcagent_client.c */; };
+ 4718AE9E205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */; };
+ 4718AE9F205B39C40068EC3F /* CKKSCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C321F17ECE5007640C8 /* CKKSCondition.h */; };
+ 4718AEA0205B39C40068EC3F /* CKKSScanLocalItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1DA65C1E4554620094CE7F /* CKKSScanLocalItemsOperation.h */; };
+ 4718AEA1205B39C40068EC3F /* CKKSNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */; };
+ 4718AEA2205B39C40068EC3F /* CKKSGroupOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCCD88E61E42622200F5AA71 /* CKKSGroupOperation.h */; };
+ 4718AEA3205B39C40068EC3F /* CKKSRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC185971E24E87D009657D8 /* CKKSRateLimiter.h */; };
+ 4718AEA4205B39C40068EC3F /* SecDbKeychainSerializedItemV7.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */; };
+ 4718AEA5205B39C40068EC3F /* OTCloudStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */; };
+ 4718AEA6205B39C40068EC3F /* CKKSResultOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447881F5764C600236DB4 /* CKKSResultOperation.h */; };
+ 4718AEA7205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C4F1F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h */; };
+ 4718AEA8205B39C40068EC3F /* CKKSViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBDB3B91E57CA7A00B61300 /* CKKSViewManager.h */; };
+ 4718AEA9205B39C40068EC3F /* CKKSRecordHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC762A9C1E57A86A00B03A2C /* CKKSRecordHolder.h */; };
+ 4718AEAA205B39C40068EC3F /* CKKSOutgoingQueueOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5BB4FC1E0C98320010F836 /* CKKSOutgoingQueueOperation.h */; };
+ 4718AEAB205B39C40068EC3F /* CKKSSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB5D9391E4A9A3400BE22AB /* CKKSSynchronizeOperation.h */; };
+ 4718AEAC205B39C40068EC3F /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; };
+ 4718AEAD205B39C40068EC3F /* SOSChangeTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D501D8085F200865A7C /* SOSChangeTracker.h */; };
+ 4718AEAE205B39C40068EC3F /* CKKSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */; };
+ 4718AEAF205B39C40068EC3F /* SOSEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D571D8085F200865A7C /* SOSEngine.h */; };
+ 4718AEB0205B39C40068EC3F /* SecDbKeychainItem.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C911D8085D800865A7C /* SecDbKeychainItem.h */; };
+ 4718AEB1205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7A17EB1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h */; };
+ 4718AEB2205B39C40068EC3F /* SecDbQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C931D8085D800865A7C /* SecDbQuery.h */; };
+ 4718AEB3205B39C40068EC3F /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; };
+ 4718AEB4205B39C40068EC3F /* CKKSMirrorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B2C1DEF9DF000A3DAFA /* CKKSMirrorEntry.h */; };
+ 4718AEB5205B39C40068EC3F /* CloudKitCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC94BCC81F10448600E07CEB /* CloudKitCategories.h */; };
+ 4718AEB6205B39C40068EC3F /* CKKSDeviceStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C251F17E455007640C8 /* CKKSDeviceStateEntry.h */; };
+ 4718AEB7205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */; };
+ 4718AEB8205B39C40068EC3F /* CKKSCKAccountStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFB12C31E95A4C000510F5F /* CKKSCKAccountStateTracker.h */; };
+ 4718AEB9205B39C40068EC3F /* CKKSZoneStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B361DEFADB500A3DAFA /* CKKSZoneStateEntry.h */; };
+ 4718AEBA205B39C40068EC3F /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */; };
+ 4718AEBB205B39C40068EC3F /* SecItemDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C951D8085D800865A7C /* SecItemDataSource.h */; };
+ 4718AEBC205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC18F76D1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h */; };
+ 4718AEBD205B39C40068EC3F /* SecDbKeychainSerializedMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */; };
+ 4718AEBE205B39C40068EC3F /* CKKSZoneChangeFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */; };
+ 4718AEBF205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA4D2131E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h */; };
+ 4718AEC0205B39C40068EC3F /* SFPublicKey+SPKI.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */; };
+ 4718AEC1205B39C40068EC3F /* CKKSIncomingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B3A1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h */; };
+ 4718AEC2205B39C40068EC3F /* SecItemDb.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C971D8085D800865A7C /* SecItemDb.h */; };
+ 4718AEC3205B39C40068EC3F /* CKKSFixups.h in Headers */ = {isa = PBXBuildFile; fileRef = DCAD9B421F8D939C00C5E2AE /* CKKSFixups.h */; };
+ 4718AEC4205B39C40068EC3F /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; };
+ 4718AEC5205B39C40068EC3F /* SecItemSchema.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C991D8085D800865A7C /* SecItemSchema.h */; };
+ 4718AEC6205B39C40068EC3F /* CKKSLocalSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */; };
+ 4718AEC7205B39C40068EC3F /* SecKeybagSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C9F1D8085D800865A7C /* SecKeybagSupport.h */; };
+ 4718AEC8205B39C40068EC3F /* CKKSNewTLKOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */; };
+ 4718AEC9205B39C40068EC3F /* iCloudTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78CB21D8085D800865A7C /* iCloudTrace.h */; };
+ 4718AECA205B39C40068EC3F /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; };
+ 4718AECB205B39C40068EC3F /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; };
+ 4718AECC205B39C40068EC3F /* CKKSOutgoingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9B7AE61DCBF651004E9385 /* CKKSOutgoingQueueEntry.h */; };
+ 4718AECD205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC15F7641E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h */; };
+ 4718AECE205B39C40068EC3F /* CKKSNearFutureScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6C4B01EC5302400414FEE /* CKKSNearFutureScheduler.h */; };
+ 4718AECF205B39C40068EC3F /* OTManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF101FCB486B00580909 /* OTManager.h */; };
+ 4718AED0205B39C40068EC3F /* CKKSHealTLKSharesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */; };
+ 4718AED1205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278E61ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h */; };
+ 4718AED2205B39C40068EC3F /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; };
+ 4718AED3205B39C40068EC3F /* CKKSAPSReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D831E2F14810089CF55 /* CKKSAPSReceiver.h */; };
+ 4718AED4205B39C40068EC3F /* NSOperationCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447941F5766D200236DB4 /* NSOperationCategories.h */; };
+ 4718AED5205B39C40068EC3F /* CKKSKey.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4DB14E1E24692100CD6769 /* CKKSKey.h */; };
+ 4718AED6205B39C40068EC3F /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; };
+ 4718AED7205B39C40068EC3F /* CKKSControlServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */; };
+ 4718AED8205B39C40068EC3F /* CKKSSIV.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D531E2826DB0089CF55 /* CKKSSIV.h */; };
+ 4718AED9205B39C40068EC3F /* SFKeychainControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */; };
+ 4718AEDA205B39C40068EC3F /* SecDbKeychainSerializedSecretData.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */; };
+ 4718AEDB205B39C40068EC3F /* CKKSItem.h in Headers */ = {isa = PBXBuildFile; fileRef = DCDCCB8D1DF7B8D4006E840E /* CKKSItem.h */; };
+ 4718AEE3205B3A050068EC3F /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; };
+ 4718AEE4205B3A060068EC3F /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; };
+ 4718AEE7205B3A420068EC3F /* libsecurityd_bridge.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */; };
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 */; };
4723C9C61F152EC00082882F /* SFSQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9BD1F152EB10082882F /* SFSQLite.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
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 */; };
474B5FC81E662E79007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; };
475F37201EE8F23900248FB5 /* SFAnalytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */; };
475F37211EE8F23900248FB5 /* SFAnalytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */; };
+ 4764E9272059D866005497C9 /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; };
+ 4764E92D2059D8BF005497C9 /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; };
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 */; };
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 */; };
+ 4771D973209A755800BA9772 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; };
+ 4771D980209A75FE00BA9772 /* KeychainDataclassOwner.m in Sources */ = {isa = PBXBuildFile; fileRef = 4771D97F209A75FE00BA9772 /* KeychainDataclassOwner.m */; };
+ 4771D9A0209B7C2700BA9772 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4771D99F209B7C2600BA9772 /* Security.framework */; };
+ 4771D9A2209B7C3900BA9772 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4771D9A1209B7C3900BA9772 /* Accounts.framework */; };
+ 4771DA2520A4C33A00BA9772 /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; };
+ 4771DA2620A4C34800BA9772 /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; };
+ 4771DA2720A4C37D00BA9772 /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; };
4771ECCD1F17CD0E00840998 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; };
477A1F5220320E4A00ACD81D /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 477A1F4C20320E4900ACD81D /* Accounts.framework */; };
477A1F5320320E5100ACD81D /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; };
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 */; };
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 */; };
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 */; };
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 */; };
+ 479231E82065B31300B2718C /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; };
+ 479231EE2065B32200B2718C /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; };
+ 479231EF2065C52200B2718C /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; };
+ 479231F02065C52D00B2718C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; };
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 */; };
+ 47A91562201A43BA00FF8F46 /* SecSharedCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = BE061FE01899ECEE00C739F6 /* SecSharedCredential.h */; settings = {ATTRIBUTES = (Public, ); }; };
47B011991F17D78D0030B49F /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; };
47B90C901F350966006500BC /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; };
+ 47C2F1762059A2300062DE30 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; };
+ 47C2F1842059CB680062DE30 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; };
+ 47C2F18A2059CB820062DE30 /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; };
47C51B871EEA657D0032D9E5 /* SecurityUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 47C51B861EEA657D0032D9E5 /* SecurityUnitTests.m */; };
47C51B891EEA657D0032D9E5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
+ 47D13759209CD1A200CAD493 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; };
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 */; };
+ 47FF17261FD60ACA00875565 /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; };
+ 47FF17271FD60ACA00875565 /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; };
+ 47FF17281FD60ACA00875565 /* SFKeychainServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 47FF17251FD60ACA00875565 /* SFKeychainServer.m */; };
+ 47FF17291FD60ACA00875565 /* SFKeychainServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 47FF17251FD60ACA00875565 /* SFKeychainServer.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 */; };
+ 4885DCAD207FF0780071FB7B /* ClientInfoByNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 4885DCAB207FF0780071FB7B /* ClientInfoByNotification.m */; };
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 */; };
+ 48FE669620E6E69D00FAEF17 /* SOSAuthKitHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 48FE668F20E6E69B00FAEF17 /* SOSAuthKitHelpers.m */; };
+ 48FE669720E6E69D00FAEF17 /* SOSAuthKitHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 48FE669520E6E69C00FAEF17 /* SOSAuthKitHelpers.h */; };
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, ); }; };
4C3DD6B0179755560093F9D8 /* NSDate+TimeIntervalDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3DD6AF179755560093F9D8 /* NSDate+TimeIntervalDescription.m */; };
4C3DD6BD179760280093F9D8 /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; };
4C4296320BB0A68200491999 /* SecTrustSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C4296300BB0A68200491999 /* SecTrustSettings.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 4C47FA9320A51DC900384CB6 /* AppleFSCompression.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */; };
+ 4C47FA9420A51DD800384CB6 /* AppleFSCompression.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */; };
4C50AD0C1410679000EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFD1410671D00EE92DE /* Invalid-asterisk.google.com.crt */; };
4C50AD0D1410679000EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFE1410671D00EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt */; };
4C50AD0E1410679000EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFF1410671D00EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt */; };
5346481E173322BD00FE9172 /* KeychainSyncAccountNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 5346481D173322BD00FE9172 /* KeychainSyncAccountNotification.m */; };
5346481F17332F9C00FE9172 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; };
53C0E1FF177FB48A00F8A018 /* CloudKeychain.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53C0E1F1177FAC2C00F8A018 /* CloudKeychain.strings */; };
+ 5A4E381B207529670047F40F /* SecProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E381A207529480047F40F /* SecProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5A4E381C207529680047F40F /* SecProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E381A207529480047F40F /* SecProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5A4E52792051D7FA009D5826 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ 5A4E527B2051D857009D5826 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ 5AC6BFAB2077CD310051737D /* SecProtocolTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5AC6BFAC2077CD310051737D /* SecProtocolTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5AF762FF2051F990001557AE /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ 5AF7630920520870001557AE /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; };
+ 5AFCF32920746BC20010D4B5 /* SecProtocolOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5AFCF32A20746BC30010D4B5 /* SecProtocolOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5AFCF32B20746BC80010D4B5 /* SecProtocolMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5AFCF32C20746BC90010D4B5 /* SecProtocolMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5AFCF32E20746DA70010D4B5 /* SecProtocolObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5AFCF32F20746DA70010D4B5 /* SecProtocolObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
5E10992619A5E55800A60E2B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
5E10995119A5E5CE00A60E2B /* ISProtectedItems.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5E10994E19A5E5CE00A60E2B /* ISProtectedItems.plist */; };
5E10995219A5E5CE00A60E2B /* ISProtectedItemsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E10995019A5E5CE00A60E2B /* ISProtectedItemsController.m */; };
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 */; };
- 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 */; };
+ 6C32BB9920EAE6B00042DF59 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; };
+ 6C32BB9A20EAE6B80042DF59 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; };
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 */; };
+ 6C4F98252075833E00A3C5AB /* OCMock.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 6C53A447206AB1A6000FA611 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; };
+ 6C53A44D206AB1EF000FA611 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.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 */; };
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 */; };
+ 6C814A4C2050B4B600CB391B /* LocalKeychainAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 6C814A4D2050B4B600CB391B /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; };
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 */; };
- 6C869A7A1F54C37A00957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */; };
- 6C8CC3AB1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */; };
- 6C8CC3AC1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */; };
- 6C8CC3AD1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */; };
- 6C8CC3B31E2F913D009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */; };
- 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 */; };
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 */; };
+ 6CB420A52051FDD500FF2D44 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; };
+ 6CB420AB2051FDE000FF2D44 /* LocalKeychainAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
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 */; };
- 6CF4A0C01E45488B00ECD7B5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BF1E45488B00ECD7B5 /* Assets.xcassets */; };
- 6CF4A0C31E45488B00ECD7B5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0C11E45488B00ECD7B5 /* Main.storyboard */; };
6CF4A0E41E4549F200ECD7B5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0E31E4549F200ECD7B5 /* main.m */; };
6CF4A0E71E4549F300ECD7B5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0E61E4549F300ECD7B5 /* AppDelegate.m */; };
6CF4A0EA1E4549F300ECD7B5 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0E91E4549F300ECD7B5 /* ViewController.m */; };
- 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, ); }; };
79EF5B730D3D6AFE009F5270 /* p12import.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EF5B720D3D6AFE009F5270 /* p12import.h */; };
8E02FA6B1107BE460043545E /* pbkdf2.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E02FA691107BE460043545E /* pbkdf2.h */; settings = {ATTRIBUTES = (Private, ); }; };
8ED6F6CA110904E300D2B368 /* SecPBKDF.h in Headers */ = {isa = PBXBuildFile; fileRef = 8ED6F6C8110904E300D2B368 /* SecPBKDF.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A690B033208A75D1002FB775 /* notarization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6B1BA78207BD9D400F1E099 /* notarization.cpp */; };
+ A6B1BA81207BD9EC00F1E099 /* notarization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6B1BA78207BD9D400F1E099 /* notarization.cpp */; };
+ A6B1BA82207BDCB200F1E099 /* notarization.h in Headers */ = {isa = PBXBuildFile; fileRef = A6B1BA79207BD9D400F1E099 /* notarization.h */; };
+ AA44E0D520325150001EA371 /* SecProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D02032513F001EA371 /* SecProtocol.c */; };
+ AA44E0D620325150001EA371 /* SecProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D02032513F001EA371 /* SecProtocol.c */; };
+ AA44E0D72032515C001EA371 /* SecProtocolTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D120325140001EA371 /* SecProtocolTypes.m */; };
+ AA44E0D82032515C001EA371 /* SecProtocolTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0D120325140001EA371 /* SecProtocolTypes.m */; };
+ AA44E0DE2032519E001EA371 /* SecProtocolPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = AA44E0D920325177001EA371 /* SecProtocolPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ AA44E0DF2032519F001EA371 /* SecProtocolPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = AA44E0D920325177001EA371 /* SecProtocolPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
ACBAF6EE1E941AE00007BA2F /* transform_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = ACBAF6E31E941AE00007BA2F /* transform_regressions.h */; };
ACBAF6EF1E941AE00007BA2F /* transform_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = ACBAF6E31E941AE00007BA2F /* transform_regressions.h */; };
ACBAF6F91E941B020007BA2F /* transform-01-sigverify.m in Sources */ = {isa = PBXBuildFile; fileRef = ACBAF6E51E941AE00007BA2F /* transform-01-sigverify.m */; };
BE197F5C1911724900BA91D1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE411314471B000DE34E /* UIKit.framework */; };
BE197F5E191173A800BA91D1 /* SWCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE197F5D191173A800BA91D1 /* SWCViewController.m */; };
BE197F61191173F200BA91D1 /* entitlements.plist in Resources */ = {isa = PBXBuildFile; fileRef = BE197F60191173F200BA91D1 /* entitlements.plist */; };
- BE1F74D31F609D460068FA64 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
BE22FBC61EE0E8AB00893431 /* Monkey.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBC51EE0E8AB00893431 /* Monkey.m */; };
BE22FBCE1EE1E26600893431 /* Keychain.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBCD1EE1E26600893431 /* Keychain.m */; };
BE22FBD11EE2084100893431 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBD01EE2084100893431 /* Config.m */; };
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 */; };
BEF88C9C1EB000FD00357577 /* TPPolicyDocumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C741EB0008E00357577 /* TPPolicyDocumentTests.m */; };
BEF88C9D1EB000FD00357577 /* TPUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C751EB0008E00357577 /* TPUtilsTests.m */; };
BEF88C9E1EB000FD00357577 /* TPVoucherTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C761EB0008E00357577 /* TPVoucherTests.m */; };
- CD0637551A84060600C81E74 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; };
- CD0637561A84065F00C81E74 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; };
- CD0637571A84068F00C81E74 /* IDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD744683195A00BB00FB01C0 /* IDS.framework */; };
CD112FC51DDA31AD00C77A07 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; };
CD198F971DE27B9E00F6FB83 /* SOSAccountPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = CD9021471DE27A9E00F81DC4 /* SOSAccountPriv.h */; };
- CD23B49E1DA06EB40047EDE9 /* IDSPersistentState.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4931DA06EB30047EDE9 /* IDSPersistentState.m */; };
- CD23B4A01DA06EB40047EDE9 /* IDSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4951DA06EB30047EDE9 /* IDSProxy.m */; };
- CD23B4A11DA06EB40047EDE9 /* keychainsyncingoveridsproxy.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4961DA06EB30047EDE9 /* keychainsyncingoveridsproxy.m */; };
- CD23B4A31DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B4981DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m */; };
- CD23B4A51DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = CD23B49A1DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m */; };
- CD276C281A83F60C003226BC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
- CD51245E1DA1C67000962524 /* com.apple.private.alloy.keychainsync.plist in Install alloy plist */ = {isa = PBXBuildFile; fileRef = CD23B4A81DA06ED10047EDE9 /* com.apple.private.alloy.keychainsync.plist */; };
CD791B3C1DFC9A7600F0E5DC /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD2F99D91DFC995B00769430 /* libsqlite3.0.dylib */; };
CD791B3D1DFC9AB200F0E5DC /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; };
CD9F2AF81DF23CA600AD3577 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
D43761661EB2996C00954447 /* SecRevocationNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = D43761641EB2996C00954447 /* SecRevocationNetworking.h */; };
D43761671EB2996C00954447 /* SecRevocationNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = D43761651EB2996C00954447 /* SecRevocationNetworking.m */; };
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 */; };
+ D43D8B2C20AB8A48005BEEC4 /* Security.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = D44D08B420AB890E0023C439 /* Security.apinotes */; settings = {ATTRIBUTES = (Public, ); }; };
+ D43D8B2D20AB8A54005BEEC4 /* Security.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = D44D08B420AB890E0023C439 /* Security.apinotes */; settings = {ATTRIBUTES = (Public, ); }; };
D43DBEFC1E99D1CA00C04AEA /* nameconstraints.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED71E99D17100C04AEA /* nameconstraints.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 */; };
- D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.c */; };
+ D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.m */; };
D43DBF021E99D1CA00C04AEA /* SecCertificateServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE31E99D17200C04AEA /* SecCertificateServer.c */; };
D43DBF031E99D1CA00C04AEA /* SecCertificateSource.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE51E99D17200C04AEA /* SecCertificateSource.c */; };
D43DBF041E99D1CA00C04AEA /* SecOCSPCache.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEE71E99D17200C04AEA /* SecOCSPCache.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 */; };
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 */; };
+ D465131A2097FF2E005D93FE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EB1E4549F300ECD7B5 /* Main.storyboard */; };
+ D465131B2097FF2E005D93FE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EE1E4549F300ECD7B5 /* Assets.xcassets */; };
+ D465131C2097FF2E005D93FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0F01E4549F300ECD7B5 /* LaunchScreen.storyboard */; };
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 */; };
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 */; };
+ D48BD18D206C45F00075DDC9 /* si-89-cms-hash-agility.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */; };
+ D48BD194206C47530075DDC9 /* si-35-cms-expiration-time.m in Sources */ = {isa = PBXBuildFile; fileRef = D48BD193206C47530075DDC9 /* si-35-cms-expiration-time.m */; };
D48E4E241E42F0620011B4BA /* si-62-csr.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DDA1D8085FC00865A7C /* si-62-csr.m */; };
+ D491112C209515400066A1E4 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; };
+ D491112D209515400066A1E4 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; };
+ D491112E209515400066A1E4 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; };
+ D491112F2095154B0066A1E4 /* MainMenu.xib in Sources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; };
+ D49111302095154B0066A1E4 /* MainMenu.xib in Sources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; };
+ D49111312095154B0066A1E4 /* Main.storyboard in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0C11E45488B00ECD7B5 /* Main.storyboard */; };
+ D49111322095154B0066A1E4 /* Assets.xcassets in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BF1E45488B00ECD7B5 /* Assets.xcassets */; };
+ D49111692095593D0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D491116A2095593E0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D491116B2095593E0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D491116C2095594A0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D491116D2095594B0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D491116E209559510066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D491116F209559510066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D49111702095595B0066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D4911171209559620066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; };
+ D4911172209559630066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D4911173209559630066A1E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ D4961BC42079424200F16DA7 /* TrustURLSessionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D4961BBD2079423300F16DA7 /* TrustURLSessionDelegate.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 */; };
D4ADA32F1E2B43220031CEA3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
D4ADA3301E2B433B0031CEA3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
D4ADA3311E2B43450031CEA3 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; };
+ D4B6D57C2069D8450099FBEF /* si-34-cms-timestamp.m in Sources */ = {isa = PBXBuildFile; fileRef = D4B6D57B2069D8450099FBEF /* si-34-cms-timestamp.m */; };
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 */; };
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 */; };
+ DA5B871C2065A8440093F083 /* SecAutorelease.h in Headers */ = {isa = PBXBuildFile; fileRef = DA5B871A2065A8410093F083 /* SecAutorelease.h */; };
+ DA5B871D2065A8440093F083 /* SecAutorelease.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5B871B2065A8430093F083 /* SecAutorelease.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 */; };
+ DAE40BC920CF3E46002D5674 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; };
+ DAE40BCA20CF3E46002D5674 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
+ DAE40BD920CF3F0F002D5674 /* secitemcanarytest.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE40BD820CF3F04002D5674 /* secitemcanarytest.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 */; };
DC00ABF11D821FC400513D74 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; };
DC00ABF21D821FC800513D74 /* libSOSRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC681D80D0C400B0A59C /* libSOSRegressions.a */; };
DC00ABF31D821FCD00513D74 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; };
+ DC066DF02102563300694EAF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
DC08D1C41E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */; };
DC08D1CC1E64FCC5006237DA /* CKKSSOSTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1CB1E64FCC5006237DA /* CKKSSOSTests.m */; };
DC0950411E38271300B2C8AC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
DC0B62291D90974600D43BCB /* si-25-cms-skid.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0B62271D90973900D43BCB /* si-25-cms-skid.m */; };
DC0B622A1D9097C600D43BCB /* libsecurity_cms_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002CB1D8E19D70025549C /* libsecurity_cms_regressions.a */; };
DC0B622C1D90982C00D43BCB /* secd-201-coders.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0B622B1D90982100D43BCB /* secd-201-coders.m */; };
- DC0B622F1D909C4600D43BCB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; };
- DC0B62301D909C4600D43BCB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DC0B622D1D909C4600D43BCB /* MainMenu.xib */; };
DC0BC5611D8B6D6000070CB0 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC5461D8B6AFE00070CB0 /* main.c */; };
DC0BC5621D8B6D7000070CB0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
DC0BC5671D8B6E3D00070CB0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
DC52E8CB1D80C2FD00B0A59C /* SOSTransportCircleKVS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D7A1D8085F200865A7C /* SOSTransportCircleKVS.m */; };
DC52E8CC1D80C2FD00B0A59C /* SOSTransportKeyParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D7C1D8085F200865A7C /* SOSTransportKeyParameter.m */; };
DC52E8CE1D80C2FD00B0A59C /* SOSTransportMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D801D8085F200865A7C /* SOSTransportMessage.m */; };
- DC52E8CF1D80C2FD00B0A59C /* SOSTransportMessageIDS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D821D8085F200865A7C /* SOSTransportMessageIDS.m */; };
DC52E8D01D80C2FD00B0A59C /* SOSTransportMessageKVS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D841D8085F200865A7C /* SOSTransportMessageKVS.m */; };
DC52E8DD1D80C31F00B0A59C /* SOSCoder.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D511D8085F200865A7C /* SOSCoder.c */; };
DC52E8DE1D80C31F00B0A59C /* SOSDigestVector.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D541D8085F200865A7C /* SOSDigestVector.c */; };
DC52E90C1D80C3D900B0A59C /* SOSBackupEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D281D8085F200865A7C /* SOSBackupEvent.h */; };
DC52E9101D80C3EF00B0A59C /* SOSAccountLog.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D211D8085F200865A7C /* SOSAccountLog.h */; };
DC52E9161D80C41A00B0A59C /* SOSPeerInfoInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D6C1D8085F200865A7C /* SOSPeerInfoInternal.h */; };
- DC52E9191D80C42F00B0A59C /* SOSTransportMessageIDS.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D831D8085F200865A7C /* SOSTransportMessageIDS.h */; };
DC52E91A1D80C43500B0A59C /* SOSRing.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D391D8085F200865A7C /* SOSRing.h */; };
DC52E91C1D80C43F00B0A59C /* SOSPeerCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D5F1D8085F200865A7C /* SOSPeerCoder.h */; };
DC52E91D1D80C44400B0A59C /* SOSCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D521D8085F200865A7C /* SOSCoder.h */; };
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.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 */; };
DC52EDE21D80D5C500B0A59C /* secd-74-engine-beer-servers.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C661D8085D800865A7C /* secd-74-engine-beer-servers.m */; };
DC52EDE31D80D5C500B0A59C /* secd-75-engine-views.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C671D8085D800865A7C /* secd-75-engine-views.m */; };
DC52EDE61D80D5C500B0A59C /* secd-80-views-basic.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6A1D8085D800865A7C /* secd-80-views-basic.m */; };
- DC52EDE71D80D5C500B0A59C /* secd-82-secproperties-basic.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6B1D8085D800865A7C /* secd-82-secproperties-basic.m */; };
DC52EDE81D80D5C500B0A59C /* secd-81-item-acl-stress.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6C1D8085D800865A7C /* secd-81-item-acl-stress.m */; };
DC52EDE91D80D5C500B0A59C /* secd-81-item-acl.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6D1D8085D800865A7C /* secd-81-item-acl.m */; };
DC52EDEA1D80D5C500B0A59C /* secd-82-persistent-ref.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C6E1D8085D800865A7C /* secd-82-persistent-ref.m */; };
DC52EE611D80D79E00B0A59C /* si-71-mobile-store-policy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DFB1D8085FC00865A7C /* si-71-mobile-store-policy.c */; };
DC52EE6F1D80D83F00B0A59C /* SecPasswordGenerate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7A1D8085FC00865A7C /* SecPasswordGenerate.c */; };
DC52EE701D80D84700B0A59C /* SecItemConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */; };
- DC52EE711D80D85F00B0A59C /* SecECKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.c */; };
+ DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; };
DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; };
DC52EE731D80D86800B0A59C /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; };
DC52EE741D80D86F00B0A59C /* SecAccessControl.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.c */; };
- DC52EE761D80D87F00B0A59C /* SecCTKKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.c */; };
+ DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.m */; };
DC52EE771D80D88300B0A59C /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E461D8085FC00865A7C /* SecDH.c */; };
DC52EE781D80D88800B0A59C /* SecRSAKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E851D8085FC00865A7C /* SecRSAKey.c */; };
DC52EE791D80D88D00B0A59C /* SecItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E581D8085FC00865A7C /* SecItem.c */; };
DC52EE7A1D80D89400B0A59C /* SecCFAllocator.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E401D8085FC00865A7C /* SecCFAllocator.c */; };
- DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */; };
+ DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */; };
DC52EE7C1D80D89E00B0A59C /* SecItemBackup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5A1D8085FC00865A7C /* SecItemBackup.c */; };
DC54DD0F1EA7D9E700108E92 /* CKKSManifestLeafRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 476D873A1E6750E200190352 /* CKKSManifestLeafRecord.m */; };
DC54DD101EA7D9E800108E92 /* CKKSManifestLeafRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 476D873A1E6750E200190352 /* CKKSManifestLeafRecord.m */; };
DC5AC12A1D83555A00CF422C /* SharedMemoryServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFD21D83511A00CF422C /* SharedMemoryServer.h */; };
DC5AC12B1D83555A00CF422C /* self.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5AC0FF1D83550300CF422C /* self.h */; };
DC5AC12D1D83560100CF422C /* securityd_dtrace.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFD91D83512A00CF422C /* securityd_dtrace.h */; };
+ DC5B391720C08B38005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
+ DC5B391820C08B39005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
+ DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC5860220BF8A98005C7269 /* SecBase.c */; };
+ DC5B391B20C08BDC005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
+ DC5B391C20C08BF1005B09F6 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
DC5BB4FA1E0C90DE0010F836 /* CKKSIncomingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4F11E0C86800010F836 /* CKKSIncomingQueueOperation.m */; };
DC5BB4FB1E0C90DF0010F836 /* CKKSIncomingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4F11E0C86800010F836 /* CKKSIncomingQueueOperation.m */; };
DC5BB4FE1E0C98320010F836 /* CKKSOutgoingQueueOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5BB4FC1E0C98320010F836 /* CKKSOutgoingQueueOperation.h */; };
DC610AB11D7910C3002223DE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
DC610ABA1D7910F8002223DE /* gk_reset_check.c in Sources */ = {isa = PBXBuildFile; fileRef = DC610AB91D7910F8002223DE /* gk_reset_check.c */; };
DC63CAF81D91A15F00C03317 /* libsecurity_cms_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002CB1D8E19D70025549C /* libsecurity_cms_regressions.a */; };
+ DC63D70820B3931100D088AD /* libxar.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DC63D70220B3930700D088AD /* libxar.tbd */; };
DC6593D11ED8DAB900C19462 /* CKKSTests+CurrentPointerAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6593C91ED8DA9200C19462 /* CKKSTests+CurrentPointerAPI.m */; };
DC65E7231D8CB28900152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC65E7241D8CB29E00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC65E7271D8CB2EC00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC65E72A1D8CB2FC00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC65E7301D8CB32D00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
- DC65E7311D8CB33800152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC65E7361D8CB35E00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC65E7371D8CB37500152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC65E73C1D8CB39B00152EF0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
DC71D9D81D95BA6C0065FB93 /* secasn1d.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88343A1D8A21AA00CE0ACA /* secasn1d.c */; };
DC71D9D91D95BA6C0065FB93 /* SecAsn1Coder.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88340A1D8A21AA00CE0ACA /* SecAsn1Coder.c */; };
DC71D9DA1D95BA6C0065FB93 /* secasn1u.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88343D1D8A21AA00CE0ACA /* secasn1u.c */; };
+ DC72BCD720B3A7DF00B26495 /* libOpenScriptingUtil.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DC63D70920B3933000D088AD /* libOpenScriptingUtil.tbd */; settings = {ATTRIBUTES = (Weak, ); }; };
DC7341F31F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */; };
DC7341F41F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */; };
DC7341F51F8447AB00AB9BDF /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341F21F8447AB00AB9BDF /* CKKSTLKShare.m */; };
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 */; };
+ DC8D238D2064649400E163C8 /* CKKSAPSHandlingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8D238C2064649400E163C8 /* CKKSAPSHandlingTests.m */; };
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 */; };
DCAD9B461F8D939C00C5E2AE /* CKKSFixups.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */; };
DCAD9B471F8D939C00C5E2AE /* CKKSFixups.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */; };
DCAD9B491F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */; };
+ DCAE1DDD2073FDCC00B4F687 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; };
+ DCAE1DDE2073FDCD00B4F687 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; };
DCB221501E8B08A5001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; };
DCB221511E8B08A6001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; };
DCB221531E8B08BC001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; };
DCC0937F1D80B0B100F984E4 /* SecOTRMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF715AFB73800B9D400 /* SecOTRMath.h */; };
DCC093801D80B0B700F984E4 /* SecCFAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */; };
DCC19F711EB9151B00B7D70F /* KeychainCKKS.plist in Copy BATS Test Discovery Plist */ = {isa = PBXBuildFile; fileRef = 6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */; };
+ DCC585FF20BF8A7E005C7269 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
+ DCC5860020BF8A7E005C7269 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
+ DCC5860320BF8A98005C7269 /* SecBase.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC5860120BF8A98005C7269 /* SecBase.h */; };
DCC5BF1B1D93723A008D1E84 /* libsecurity_apple_csp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCF783141D88B4DE00E694BB /* libsecurity_apple_csp.a */; };
DCC5BF1C1D937242008D1E84 /* libsecurity_apple_cspdl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCF785E51D88B95500E694BB /* libsecurity_apple_cspdl.a */; };
DCC5BF1D1D937249008D1E84 /* libsecurity_apple_file_dl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCF7883B1D88C8C400E694BB /* libsecurity_apple_file_dl.a */; };
DCC78ED01D808A8800865A7C /* SecOTRMath.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E6E1D8085FC00865A7C /* SecOTRMath.c */; };
DCC78ED11D808A8E00865A7C /* SecOTRFullIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E6C1D8085FC00865A7C /* SecOTRFullIdentity.c */; };
DCC78ED21D808A9500865A7C /* SecOTRDHKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E691D8085FC00865A7C /* SecOTRDHKey.c */; };
- DCC78ED31D808AA000865A7C /* SecKeyAdaptors.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */; };
+ DCC78ED31D808AA000865A7C /* SecKeyAdaptors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */; };
DCC78ED41D808AA800865A7C /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; };
DCC78ED51D808AAE00865A7C /* SecItemConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */; };
DCC78ED61D808ABA00865A7C /* SecItemBackup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5A1D8085FC00865A7C /* SecItemBackup.c */; };
DCC78ED71D808AC000865A7C /* SecItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E581D8085FC00865A7C /* SecItem.c */; };
DCC78ED81D808AC600865A7C /* SecImportExport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E551D8085FC00865A7C /* SecImportExport.c */; };
DCC78ED91D808ACB00865A7C /* SecIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E521D8085FC00865A7C /* SecIdentity.c */; };
- DCC78EDA1D808AD100865A7C /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
DCC78EDB1D808ADF00865A7C /* SecEMCS.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4C1D8085FC00865A7C /* SecEMCS.m */; };
- DCC78EDC1D808AE500865A7C /* SecECKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.c */; };
+ DCC78EDC1D808AE500865A7C /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; };
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 */; };
DCC78EE11D808B0900865A7C /* SecCertificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E381D8085FC00865A7C /* SecCertificate.c */; };
- DCC78EE21D808B0E00865A7C /* SecCTKKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.c */; };
+ DCC78EE21D808B0E00865A7C /* SecCTKKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.m */; };
DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E421D8085FC00865A7C /* SecCMS.c */; };
DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E401D8085FC00865A7C /* SecCFAllocator.c */; };
DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E351D8085FC00865A7C /* SecBase64.c */; };
DCD22D9B1D8CCFCB001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; };
DCD22D9C1D8CCFD6001C9B81 /* libutilitiesRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCD481D8C694700070CB0 /* libutilitiesRegressions.a */; };
DCD3EABA1DB599B800DF59BE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; };
+ DCD45355209A5B260086CBFC /* si-cms-signing-identity-p12.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD45353209A5B260086CBFC /* si-cms-signing-identity-p12.h */; };
+ DCD45357209A5BA10086CBFC /* si-cms-signing-identity-p12.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD45354209A5B260086CBFC /* si-cms-signing-identity-p12.c */; };
+ DCD4535A209A60DD0086CBFC /* kc-keychain-file-helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD45358209A5C2D0086CBFC /* kc-keychain-file-helpers.c */; };
+ DCD504BC20CB28BE00F37D26 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
+ DCD504C220CB28BF00F37D26 /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; };
+ DCD504C320CB293700F37D26 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
DCD662F51E329B6800188186 /* CKKSNewTLKOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */; };
DCD662F61E329B6800188186 /* CKKSNewTLKOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */; };
DCD662F71E329B6800188186 /* CKKSNewTLKOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD662F41E329B6800188186 /* CKKSNewTLKOperation.m */; };
DCD66DB21D8204F500DB1393 /* SecSignatureVerificationSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E8E1D8085FC00865A7C /* SecSignatureVerificationSupport.c */; };
DCD66DB31D8204FB00DB1393 /* SecServerEncryptionSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E8A1D8085FC00865A7C /* SecServerEncryptionSupport.c */; };
DCD66DB41D82050000DB1393 /* SecRSAKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E851D8085FC00865A7C /* SecRSAKey.c */; };
- DCD66DB51D82050500DB1393 /* SecECKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.c */; };
+ DCD66DB51D82050500DB1393 /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; };
DCD66DB61D82050900DB1393 /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; };
DCD66DB71D82050E00DB1393 /* SecTrustStore.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E971D8085FC00865A7C /* SecTrustStore.c */; };
DCD66DB91D82051900DB1393 /* SecTrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E901D8085FC00865A7C /* SecTrust.c */; };
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 */; };
+ DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */; };
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 */; };
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 */; };
DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D881D8085F200865A7C /* SOSECWrapUnwrap.c */; };
DCD8A1AE1E09F0C500E4FA0A /* SOSRingDER.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D401D8085F200865A7C /* SOSRingDER.c */; };
DCD8A1AF1E09F0DC00E4FA0A /* SOSRingUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D461D8085F200865A7C /* SOSRingUtils.c */; };
DCD8A1DE1E09F74700E4FA0A /* SOSPeerInfoV2.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D681D8085F200865A7C /* SOSPeerInfoV2.h */; };
DCD8A1DF1E09F76000E4FA0A /* SOSPeerInfoCollections.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D6B1D8085F200865A7C /* SOSPeerInfoCollections.h */; };
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 */; };
DCD8A1E41E09F80B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; };
DCD8A1E71E09F85400E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; };
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 */; };
+ DCE2341720A3D4B8009766A3 /* si-cms-hash-agility-data.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE2341520A3D4B8009766A3 /* si-cms-hash-agility-data.h */; };
+ DCE2341820A3D4B8009766A3 /* si-cms-hash-agility-data.c in Sources */ = {isa = PBXBuildFile; fileRef = DCE2341620A3D4B8009766A3 /* si-cms-hash-agility-data.c */; };
DCE278DD1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; };
DCE278DE1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; };
DCE278DF1ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */; };
DCE4E8071D7A4DE200AFB96E /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 790850840CA87CF00083CC4D /* server.c */; };
DCE4E80A1D7A4E1D00AFB96E /* com.apple.secd.plist in Copy LaunchAgents files */ = {isa = PBXBuildFile; fileRef = DCE4E8091D7A4E1C00AFB96E /* com.apple.secd.plist */; };
DCE4E80E1D7A4E3B00AFB96E /* com.apple.securityd.plist in Copy Logging Files */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; };
- DCE4E80F1D7A4E4600AFB96E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
DCE4E8121D7A4E4F00AFB96E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789261D7799D300B50D50 /* IOKit.framework */; };
DCE4E8131D7A4E5300AFB96E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
DCE4E81C1D7A4E8F00AFB96E /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E81B1D7A4E8F00AFB96E /* libsqlite3.0.dylib */; };
DCE4E93D1D7F3E1600AFB96E /* AppleSystemInfo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3F1D78F2FF002223DE /* AppleSystemInfo.framework */; };
DCE4E93F1D7F3E4000AFB96E /* AOSAccounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E93E1D7F3E4000AFB96E /* AOSAccounts.framework */; };
DCE4E9401D7F3E4D00AFB96E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
- DCE4E9421D7F3E6E00AFB96E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; };
DCE4E9491D7F3E8E00AFB96E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E9441D7F3E8700AFB96E /* Localizable.strings */; };
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 */; };
DCFE1C521F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C4F1F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h */; };
DCFE1C531F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C501F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m */; };
DCFE1C541F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C501F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m */; };
+ DCFE9C8920EC1F3B00EB6BAC /* SOSControlHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ DCFE9C8F20EC1F3C00EB6BAC /* SOSControlHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
E7104A0C169E171900DB0045 /* security_tool_commands.c in Sources */ = {isa = PBXBuildFile; fileRef = E7104A0B169E171900DB0045 /* security_tool_commands.c */; };
E71454EF1C741E0800B5B20B /* KCError.h in Headers */ = {isa = PBXBuildFile; fileRef = E71454ED1C741E0800B5B20B /* KCError.h */; settings = {ATTRIBUTES = (Private, ); }; };
E71454F01C741E0800B5B20B /* KCError.m in Sources */ = {isa = PBXBuildFile; fileRef = E71454EE1C741E0800B5B20B /* KCError.m */; };
E7A5F4D21C0CFF7900F3BEBB /* CKDKVSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4C71C0CFF3200F3BEBB /* CKDKVSProxy.m */; };
E7A5F4D51C0CFF7900F3BEBB /* cloudkeychainproxy.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4CE1C0CFF3300F3BEBB /* cloudkeychainproxy.m */; };
E7A5F4D81C0D01B000F3BEBB /* SOSCloudKeychainConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4D71C0D01B000F3BEBB /* SOSCloudKeychainConstants.c */; };
- E7A5F5591C0D052600F3BEBB /* SOSCloudKeychainConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4D71C0D01B000F3BEBB /* SOSCloudKeychainConstants.c */; };
E7B00700170B581D00B27966 /* Security.exp-in in Sources */ = {isa = PBXBuildFile; fileRef = 4CB7405F0A47498100D641BB /* Security.exp-in */; };
E7B01BD2166594AB000485F1 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; };
E7B01BD3166594AB000485F1 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; };
E7FEEEF81332B7F70025EB06 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; };
E7FEEEFA1332B8210025EB06 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; };
E7FEEEFB1332B8300025EB06 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; };
+ EB056E431FE5E390000A771E /* DeviceSimulator.m in Sources */ = {isa = PBXBuildFile; fileRef = EB056E421FE5E390000A771E /* DeviceSimulator.m */; };
+ EB056E451FE5E390000A771E /* DeviceSimulatorMain.m in Sources */ = {isa = PBXBuildFile; fileRef = EB056E441FE5E390000A771E /* DeviceSimulatorMain.m */; };
+ EB05C4F41FE5E48B00D68712 /* MultiDeviceSimulatorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EB05C4F31FE5E48B00D68712 /* MultiDeviceSimulatorTests.m */; };
EB0BC93A1C3C791500785842 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
EB0BC9671C3C798600785842 /* secedumodetest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB0BC9661C3C794700785842 /* secedumodetest.m */; };
EB0DB37D1DCBC99100EAB6AE /* Keychain Circle Notification.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = EB76B75A1DCB0CDA00C43FBC /* Keychain Circle Notification.8 */; };
EB2D54AB1F02A47200E46890 /* SecAtomicFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB2D54A01F02A28200E46890 /* SecAtomicFile.cpp */; };
EB3409B01C1D627400D77661 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
EB3A8DFF1BEEC66F001A89AA /* Security_edumode.plist in Install BATS plist */ = {isa = PBXBuildFile; fileRef = EB3A8DD71BEEC4D6001A89AA /* Security_edumode.plist */; };
+ EB3D1FBA2092CB030049EF95 /* SecurityInduceLowDisk.plist in Install BATS plist */ = {isa = PBXBuildFile; fileRef = EBE202752092913500B48020 /* SecurityInduceLowDisk.plist */; };
EB413B801E663AEB00592085 /* PairingChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = EB413B761E6624A500592085 /* PairingChannel.m */; };
EB413B821E663AFA00592085 /* PairingChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = EB413B751E6624A400592085 /* PairingChannel.h */; settings = {ATTRIBUTES = (Public, ); }; };
EB425CA21C65846D000ECE53 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
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 */; };
EB75B4911E7540BF00E469CC /* libcoreauthd_test_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E8B53A41AA0B8A600345E7B /* libcoreauthd_test_client.a */; };
EB75B4951E75A44100E469CC /* SOSPiggyback.h in Headers */ = {isa = PBXBuildFile; fileRef = EB75B4931E75A44100E469CC /* SOSPiggyback.h */; };
EB75B4961E75A44100E469CC /* SOSPiggyback.m in Sources */ = {isa = PBXBuildFile; fileRef = EB75B4941E75A44100E469CC /* SOSPiggyback.m */; };
- EB76B7571DCB0C8300C43FBC /* KeychainSyncingOverIDSProxy.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = DC24B5841DA432C600330B48 /* KeychainSyncingOverIDSProxy.8 */; };
EB76B7591DCB0CA200C43FBC /* CloudKeychainProxy.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = DC24B5851DA432E900330B48 /* CloudKeychainProxy.8 */; };
EB78D3F91E600E93009AFE05 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; };
EB7AE6F81E86DACC00B80B15 /* SecPLWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7AE6F61E86D55400B80B15 /* SecPLWrappers.m */; };
EBB839B01E2968AB00853BAC /* secfuzzer.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB8399B1E295B8F00853BAC /* secfuzzer.m */; };
EBB839B11E2968B400853BAC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
EBC15B1D1DB432F800126882 /* com.apple.secd.sb in Copy Sandbox profile */ = {isa = PBXBuildFile; fileRef = EBC15B1B1DB4306C00126882 /* com.apple.secd.sb */; };
+ EBC73F2020993F8600AE3350 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; };
+ EBC73F2620993FA800AE3350 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; };
+ EBC73F2720993FC900AE3350 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; };
+ EBC73F2820993FDA00AE3350 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; };
+ EBC73F29209966AF00AE3350 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; };
+ EBC73F2A20996AD400AE3350 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; };
+ EBC73F2B2099785900AE3350 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; };
+ EBCE150E1FE6389A002E7CCC /* DeviceSimulator.xpc in Embedded XPC service */ = {isa = PBXBuildFile; fileRef = EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ EBCE16171FE6DE5A002E7CCC /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; };
+ EBCE16181FE6DE5A002E7CCC /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; };
+ EBCE16191FE6DE5A002E7CCC /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; };
+ EBCE16201FE6DE5A002E7CCC /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; };
+ EBCE16221FE6DE5A002E7CCC /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; };
+ EBCE16231FE6DE5A002E7CCC /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; };
+ EBCE162C1FE6DE5A002E7CCC /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; };
+ EBCE162D1FE6DE5A002E7CCC /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; };
+ EBCE162F1FE6DE5A002E7CCC /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; };
+ EBCE16311FE6DE5A002E7CCC /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; };
+ EBCE16321FE6DE5A002E7CCC /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; };
+ EBCE16351FE6DE5A002E7CCC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; };
+ EBCE16361FE6DE5A002E7CCC /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; };
+ EBCE16371FE6DE5A002E7CCC /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; };
+ EBCE16391FE6DE5A002E7CCC /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; };
+ EBCE163A1FE6DE5A002E7CCC /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; };
+ EBCE163D1FE6DE5A002E7CCC /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; };
+ EBCE163E1FE6DE5A002E7CCC /* AutoreleaseTest.c in Sources */ = {isa = PBXBuildFile; fileRef = DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */; };
+ EBCE163F1FE6DE5A002E7CCC /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; };
+ EBCE16401FE6DE5A002E7CCC /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; };
+ EBCE16411FE6DE5A002E7CCC /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; };
+ EBCE16421FE6DE5A002E7CCC /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; };
+ EBCE16431FE6DE5A002E7CCC /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; };
+ EBCE16451FE6DE5A002E7CCC /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; };
+ EBCE16461FE6DE5A002E7CCC /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; };
+ EBCE16471FE6DE5A002E7CCC /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; };
+ EBCE16481FE6DE5A002E7CCC /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; };
+ EBCE16491FE6DE5A002E7CCC /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; };
+ EBCE164B1FE6DE5A002E7CCC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
+ EBCE164C1FE6DE5A002E7CCC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; };
+ EBCE164E1FE6DE5A002E7CCC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; };
+ EBCE164F1FE6DE5A002E7CCC /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; };
+ EBCE16501FE6DE5A002E7CCC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
+ EBCE16511FE6DE5A002E7CCC /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
+ EBCE16521FE6DE5A002E7CCC /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
+ EBCE16531FE6DE5A002E7CCC /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+ EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; };
+ EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
+ EBCE16561FE6DE5A002E7CCC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
+ EBCE165D1FE71821002E7CCC /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; };
+ EBCE16601FE732AA002E7CCC /* MultiDeviceNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCE165F1FE7313C002E7CCC /* MultiDeviceNetworking.m */; };
+ EBCE16641FE73679002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */; };
+ EBCE16661FE736A1002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */; };
+ EBCE16671FE736A5002E7CCC /* DeviceSimulatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */; };
+ EBCE16681FE736AD002E7CCC /* DeviceSimulatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */; };
+ EBCE166B1FE74688002E7CCC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
+ EBCE166C1FE746A5002E7CCC /* SecItemConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */; };
EBCF73F71CE45F9C00BED7CA /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; };
EBCF73F81CE45F9C00BED7CA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
EBCF73FD1CE45FAC00BED7CA /* secitemfunctionality.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCF73F21CE45F8600BED7CA /* secitemfunctionality.m */; };
+ EBDD732C20A6A61E003A103A /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; };
EBE901721C2283F7007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; };
EBE9019A1C22852C007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; };
EBE9019B1C2285D4007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
+ 4718AEDE205B39C40068EC3F /* PBXBuildRule */ = {
+ isa = PBXBuildRule;
+ compilerSpec = com.apple.compilers.proxy.script;
+ filePatterns = "*.proto";
+ fileType = pattern.proxy;
+ isEditable = 1;
+ outputFiles = (
+ "$(INPUT_FILE_DIR)/source/${INPUT_FILE_BASE}.h",
+ "$(INPUT_FILE_DIR)/source/${INPUT_FILE_BASE}.m",
+ );
+ script = "set -x\n\nmkdir -p ${INPUT_FILE_DIR}/source\nprotocompiler --arc --strict --emitDeprecated=NO --generics=YES --outputDir ${INPUT_FILE_DIR}/source --proto ${INPUT_FILE_DIR}/${INPUT_FILE_NAME}\n";
+ };
DC58C36E1D77B4AD003C25A4 /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.proxy.script;
remoteGlobalIDString = 0C2BCBBD1D0648D100ED7A2F;
remoteInfo = dtlsEchoServer;
};
+ 0C3E2EA82073F5C400F5B95B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4C32C0AE0A4975F6002891BD;
+ remoteInfo = Security_ios;
+ };
+ 0C5663ED20BE2E1A0035F362 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC0BCC211D8C684F00070CB0;
+ remoteInfo = utilities;
+ };
0C664AB31759270C0092D3D9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = 0C6799F912F7C37C00712919;
remoteInfo = dtlsTests;
};
+ 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC1789031D77980500B50D50;
+ remoteInfo = Security_osx;
+ };
0CC827F1138712B100BD99B7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = DCD06AA91D8E0D53007602F1;
remoteInfo = security_utilities;
};
+ 3DD1FEF9201C07F30086D049 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC0BCC211D8C684F00070CB0;
+ remoteInfo = utilities;
+ };
+ 3DD1FF4F201C09CD0086D049 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC0BC9C81D8B824700070CB0;
+ remoteInfo = security_ssl;
+ };
+ 3DD1FFB0201FDB1D0086D049 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC0BC9C81D8B824700070CB0;
+ remoteInfo = security_ssl;
+ };
+ 3DD1FFB2201FDB1D0086D049 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC0BCC211D8C684F00070CB0;
+ remoteInfo = utilities;
+ };
438169E61B4EE4B300C54D58 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = 4381690B1B4EDCBD00C54D58;
remoteInfo = SOSCCAuthPlugin;
};
+ 4718AE04205B39620068EC3F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC0BCC211D8C684F00070CB0;
+ remoteInfo = iOSutilities;
+ };
+ 4718AE06205B39620068EC3F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D4ADA3181E2B41670031CEA3;
+ remoteInfo = libtrustd;
+ };
+ 4718AE0A205B39620068EC3F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC52E8BE1D80C25800B0A59C;
+ remoteInfo = libSecureObjectSync;
+ };
+ 4718AE0C205B39620068EC3F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A;
+ remoteInfo = SecureObjectSyncFramework;
+ };
+ 4718AE0E205B39620068EC3F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DC52EC3E1D80D00800B0A59C;
+ remoteInfo = libSWCAgent;
+ };
+ 4718AEE5205B3A350068EC3F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4718AE2E205B39C40068EC3F;
+ remoteInfo = libsecurityd_bridge;
+ };
+ 47455B23205B3E2F008FE980 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4718AE02205B39620068EC3F;
+ remoteInfo = securityd_bridge;
+ };
+ 4771D981209A76B100BA9772 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4771D971209A755800BA9772;
+ remoteInfo = KeychainDataclassOwner;
+ };
478D426E1FD72A8100CAB645 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = DC0BCBD91D8C648C00070CB0;
remoteInfo = regressionBase;
};
- 478D42721FD72A8100CAB645 /* PBXContainerItemProxy */ = {
+ 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DCC78EA81D8088E200865A7C;
+ remoteInfo = security;
+ };
+ 47A6FC69206B461700BD6C54 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = DC52E7731D80BC8000B0A59C;
remoteInfo = libsecurityd_ios;
};
- 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */ = {
+ 47A6FC6B206B462400BD6C54 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = DCC78EA81D8088E200865A7C;
- remoteInfo = security;
+ remoteGlobalIDString = DC52E7731D80BC8000B0A59C;
+ remoteInfo = libsecurityd_ios;
+ };
+ 47C2F18B2059CBEA0062DE30 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47C2F1822059CB680062DE30;
+ remoteInfo = KeychainResources;
+ };
+ 47C2F18D2059CBF40062DE30 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47C2F1822059CB680062DE30;
+ remoteInfo = KeychainResources;
+ };
+ 47C2F18F2059CBFC0062DE30 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47C2F1822059CB680062DE30;
+ remoteInfo = KeychainResources;
+ };
+ 47C2F1912059CC040062DE30 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47C2F1822059CB680062DE30;
+ remoteInfo = KeychainResources;
};
47C51B8A1EEA657D0032D9E5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
remoteGlobalIDString = DC1789031D77980500B50D50;
remoteInfo = Security_osx;
};
- 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */ = {
+ 47D991CF20407F7E0078CAE2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = DCC78EA81D8088E200865A7C;
- remoteInfo = security;
+ remoteGlobalIDString = 4727FBB61F9918580003AE36;
+ remoteInfo = secdxctests_ios;
};
- 47DE88D41FA7AD7000DD3254 /* PBXContainerItemProxy */ = {
+ 47D991D620407F890078CAE2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = DC52E7731D80BC8000B0A59C;
- remoteInfo = libsecurityd_ios;
+ remoteGlobalIDString = 478D426C1FD72A8100CAB645;
+ remoteInfo = secdxctests_mac;
+ };
+ 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DCC78EA81D8088E200865A7C;
+ remoteInfo = security;
};
47DE88D61FA7ADAC00DD3254 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
remoteGlobalIDString = DC52EDA61D80D58400B0A59C;
remoteInfo = secdRegressions;
};
+ 4809F7AD2061B6AA003E72D0 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EB056E3D1FE5E390000A771E;
+ remoteInfo = DeviceSimulator;
+ };
+ 4809F7AF2061B6B0003E72D0 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EB05C4F01FE5E48A00D68712;
+ remoteInfo = MultiDeviceSimulatorTests;
+ };
4C52D0ED16EFCD720079966E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = BEF88C271EAFFC3F00357577;
remoteInfo = TrustedPeers;
};
- CD6130EC1DA1C0CC00E1E42F /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = CD276C261A83F60C003226BC;
- remoteInfo = KeychainSyncingOverIDSProxy;
- };
- CD6130ED1DA1C0CC00E1E42F /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = CD276C261A83F60C003226BC;
- remoteInfo = KeychainSyncingOverIDSProxy;
- };
D40B6A7E1E2B5F3D00CD6EE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = DA30D6751DF8C8FB00EC6B43;
remoteInfo = KeychainSyncAccountUpdater;
};
+ DAE40BD420CF3ED5002D5674 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DAE40BC520CF3E46002D5674;
+ remoteInfo = secitemcanarytest;
+ };
DC00678F1D878132005AF8DB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = DC1789031D77980500B50D50;
remoteInfo = Security_osx;
};
+ DC193C5F20CB4C9D009C1A0F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D4C3345B1BE2A2B100D8C1EF;
+ remoteInfo = libsecurity_cms_regressions;
+ };
DC222C781E034EE700B09171 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = DC0BCC211D8C684F00070CB0;
remoteInfo = iOSutilities;
};
- DC65E7321D8CB34000152EF0 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = DC0BCC211D8C684F00070CB0;
- remoteInfo = iOSutilities;
- };
DC65E7381D8CB38300152EF0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = DC0BCC211D8C684F00070CB0;
remoteInfo = utilities;
};
+ EB11965920A6300600BFDA1B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4809F7A42061B697003E72D0;
+ remoteInfo = MultiPeerSimulatorTests;
+ };
+ EB11965B20A6301100BFDA1B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4809F7A42061B697003E72D0;
+ remoteInfo = MultiPeerSimulatorTests;
+ };
+ EB11965D20A6302100BFDA1B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4809F7A42061B697003E72D0;
+ remoteInfo = MultiPeerSimulatorTests;
+ };
EB1C4CA61E85883900404981 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = EBB839A41E29665D00853BAC;
remoteInfo = secfuzzer;
};
+ EB636BC920992D8900C1E21A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EB49B2AD202D877F003F34A0;
+ remoteInfo = secdmockaks;
+ };
+ EB636BD020992DA300C1E21A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EB49B2AD202D877F003F34A0;
+ remoteInfo = secdmockaks;
+ };
+ EB636BD220992DB400C1E21A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EB49B2AD202D877F003F34A0;
+ remoteInfo = secdmockaks;
+ };
+ EB636BD420992DC000C1E21A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EB49B2AD202D877F003F34A0;
+ remoteInfo = secdmockaks;
+ };
EB63ADE01C3E74F900C45A69 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = 0C7CFA2E14E1BA4800DF9D95;
remoteInfo = Security_frameworks_ios;
};
- EB6A6FB21B90F89F0045DC68 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 790851B50CA9859F0083CC4D;
- remoteInfo = securityd;
- };
EB6A6FB81B90F8D70045DC68 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = 4C32C0AE0A4975F6002891BD;
remoteInfo = Security;
};
+ EB8910F020E0287600DE533F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4727FBB61F9918580003AE36;
+ remoteInfo = secdxctests_ios;
+ };
+ EB8910F720E0287E00DE533F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4727FBB61F9918580003AE36;
+ remoteInfo = secdxctests_ios;
+ };
+ EB8910FD20E06DF500DE533F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 6C46056B1F882B9B001421B6;
+ remoteInfo = KeychainAnalyticsTests;
+ };
+ EB89FAFD20DBDAA800085498 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 470415CE1E5E14B5001F3D95;
+ remoteInfo = seckeychainnetworkextensionstest;
+ };
+ EB89FAFF20DBDAA800085498 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47702B1D1E5F409700B29577;
+ remoteInfo = seckeychainnetworkextensionsystemdaemontest;
+ };
+ EB89FB0120DBDAA800085498 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47702B2D1E5F492C00B29577;
+ remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest;
+ };
EB9C1DB61BDFD51800F89272 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272;
remoteInfo = SecurityBatsTests;
};
+ EBC73F51209A705A00AE3350 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 6C46056B1F882B9B001421B6;
+ remoteInfo = KeychainAnalyticsTests;
+ };
+ EBC73F5C209A739600AE3350 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 470415CE1E5E14B5001F3D95;
+ remoteInfo = seckeychainnetworkextensionstest;
+ };
+ EBC73F63209A73A100AE3350 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47702B1D1E5F409700B29577;
+ remoteInfo = seckeychainnetworkextensionsystemdaemontest;
+ };
+ EBC73F65209A73A100AE3350 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 47702B2D1E5F492C00B29577;
+ remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest;
+ };
+ EBCE150F1FE638A2002E7CCC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EB056E3D1FE5E390000A771E;
+ remoteInfo = DeviceSimulator;
+ };
EBCF743E1CE593A700BED7CA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4C35DB69094F906D002917C4 /* Project object */;
);
runOnlyForDeploymentPostprocessing = 1;
};
+ 0C9AEEB320783FBB00BF6237 /* Embed OCMock */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed OCMock";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 0CF4064A2072E3E3003D6A7F /* Embed OCMock */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed OCMock";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3DD1FFD3201FF72C0086D049 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = /AppleInternal/CoreOS/BATS/unit_tests;
+ dstSubfolderSpec = 0;
+ files = (
+ 3DD1FFD5201FF7860086D049 /* SecureTransport_iosTests.plist in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ 3DD1FFD6201FF7930086D049 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = /AppleInternal/CoreOS/BATS/unit_tests;
+ dstSubfolderSpec = 0;
+ files = (
+ 3DD1FFD7201FF7B10086D049 /* SecureTransport_macosTests.plist in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
470415CD1E5E14B5001F3D95 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 1;
};
+ 4718AE26205B39620068EC3F /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = /System/Library/LaunchDaemons;
+ dstSubfolderSpec = 0;
+ files = (
+ 4718AE27205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ 4718AE28205B39620068EC3F /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = /System/Library/Preferences/Logging/Subsystems;
+ dstSubfolderSpec = 0;
+ files = (
+ 4718AE29205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
47702B1C1E5F409700B29577 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 1;
};
- 6C0B0C4A1E253840007F95E5 /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 8;
- dstPath = /System/Library/AWD/Metadata;
- dstSubfolderSpec = 0;
- files = (
- 6C0B0C4B1E253848007F95E5 /* AwdMetadata-0x60-Keychain.bin in CopyFiles */,
- );
- runOnlyForDeploymentPostprocessing = 1;
- };
6C1520D31DCCF6F000C85C6D /* Install man8 page */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
name = "Install man8 page";
runOnlyForDeploymentPostprocessing = 1;
};
+ 6C4F981E2075831300A3C5AB /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 6C4F98252075833E00A3C5AB /* OCMock.framework in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
6C9AA79C1F7C1D8F00D08296 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 1;
};
- CDF91EA61AAE019800E88CF7 /* Install alloy plist */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 8;
- dstPath = /System/Library/IdentityServices/ServiceDefinitions;
- dstSubfolderSpec = 0;
- files = (
- CD51245E1DA1C67000962524 /* com.apple.private.alloy.keychainsync.plist in Install alloy plist */,
- );
- name = "Install alloy plist";
- runOnlyForDeploymentPostprocessing = 1;
- };
D41257CD1E9410A300781F23 /* Copy LaunchDaemon */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
);
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;
- dstPath = /usr/share/man/man8;
- dstSubfolderSpec = 0;
- files = (
- EB76B7571DCB0C8300C43FBC /* KeychainSyncingOverIDSProxy.8 in Install man8 page */,
- );
- name = "Install man8 page";
- runOnlyForDeploymentPostprocessing = 1;
- };
EB76B7581DCB0C8B00C43FBC /* Install man8 page */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
files = (
EB9C1DB51BDFD50100F89272 /* Security.plist in Install BATS plist */,
EB3A8DFF1BEEC66F001A89AA /* Security_edumode.plist in Install BATS plist */,
+ EB3D1FBA2092CB030049EF95 /* SecurityInduceLowDisk.plist in Install BATS plist */,
);
name = "Install BATS plist";
runOnlyForDeploymentPostprocessing = 1;
name = "Copy Sandbox profile";
runOnlyForDeploymentPostprocessing = 1;
};
+ EBCE150D1FE63880002E7CCC /* Embedded XPC service */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices";
+ dstSubfolderSpec = 16;
+ files = (
+ EBCE150E1FE6389A002E7CCC /* DeviceSimulator.xpc in Embedded XPC service */,
+ );
+ name = "Embedded XPC service";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
EBF374701DC055580065D840 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 091B396D2063B64A00ECAB6F /* RemoteServiceDiscovery.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RemoteServiceDiscovery.framework; path = System/Library/PrivateFrameworks/RemoteServiceDiscovery.framework; sourceTree = SDKROOT; };
+ 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecKeyProxy.h; path = keychain/SecKeyProxy.h; sourceTree = "<group>"; };
+ 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "si-44-seckey-proxy.m"; path = "OSX/shared_regressions/si-44-seckey-proxy.m"; sourceTree = SOURCE_ROOT; };
+ 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainEntitlementsTest.m; sourceTree = "<group>"; };
09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "si-44-seckey-fv.m"; path = "OSX/shared_regressions/si-44-seckey-fv.m"; sourceTree = SOURCE_ROOT; };
+ 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecKeyProxy.m; sourceTree = "<group>"; };
0C0BDB2F175685B000BC1A7E /* secdtests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secdtests; sourceTree = BUILT_PRODUCTS_DIR; };
0C0BDB31175685B000BC1A7E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
0C0BDB441756868B00BC1A7E /* testlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testlist.h; sourceTree = "<group>"; };
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 = "<group>"; };
0C0CEC9D1DA45EA200C22FBC /* recovery_key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = recovery_key.h; sourceTree = "<group>"; };
0C0CEC9E1DA45EA200C22FBC /* recovery_key.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = recovery_key.m; sourceTree = "<group>"; };
+ 0C108C4B208A677100E8CF70 /* SFSignInAnalytics+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFSignInAnalytics+Internal.h"; sourceTree = "<group>"; };
0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStoreTests.m; path = ot/tests/OTCloudStoreTests.m; sourceTree = "<group>"; };
0C2BCBA51D063F7D00ED7A2F /* dtlsEchoClient.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoClient.c; sourceTree = "<group>"; };
0C2BCBA61D063F7D00ED7A2F /* dtlsEchoServer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoServer.c; sourceTree = "<group>"; };
0C4899111E0E105D00C6CF70 /* SOSTransportCircleCK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportCircleCK.m; sourceTree = "<group>"; };
0C48991B1E0F384700C6CF70 /* SOSAccountTrustClassic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrustClassic.m; path = SecureObjectSync/SOSAccountTrustClassic.m; sourceTree = "<group>"; };
0C4899221E0F386900C6CF70 /* SOSAccountTrustClassic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrustClassic.h; path = SecureObjectSync/SOSAccountTrustClassic.h; sourceTree = "<group>"; };
- 0C4899241E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrustOctagon.m; path = SecureObjectSync/SOSAccountTrustOctagon.m; sourceTree = "<group>"; };
- 0C4899261E0F399B00C6CF70 /* SOSAccountTrustOctagon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrustOctagon.h; path = SecureObjectSync/SOSAccountTrustOctagon.h; sourceTree = "<group>"; };
0C52C1FE20003BCA003F0733 /* OTTestsBase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTTestsBase.m; path = ot/tests/OTTestsBase.m; sourceTree = "<group>"; };
0C52C20520004248003F0733 /* OTTestsBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTTestsBase.h; path = ot/tests/OTTestsBase.h; sourceTree = "<group>"; };
0C5CFB37201960FF00913B9C /* OTRamping.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTRamping.m; path = ot/OTRamping.m; sourceTree = "<group>"; };
0C5CFB3F201962FF00913B9C /* OTRamping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTRamping.h; path = ot/OTRamping.h; sourceTree = "<group>"; };
- 0C5F4FD71F952FEA00AF1616 /* secd-700-sftm.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-700-sftm.m"; sourceTree = "<group>"; };
0C664AB2175926B20092D3D9 /* secdtests-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "secdtests-entitlements.plist"; sourceTree = "<group>"; };
0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStore.m; path = ot/OTCloudStore.m; sourceTree = "<group>"; };
0C78F1C916A5E13400654E08 /* sectask_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sectask_regressions.h; sourceTree = "<group>"; };
0C78F1CA16A5E1BF00654E08 /* sectask-10-sectask.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sectask-10-sectask.c"; sourceTree = "<group>"; };
0C78F1CB16A5E1BF00654E08 /* sectask_ipc.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = sectask_ipc.defs; sourceTree = "<group>"; };
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 = "<absolute>"; };
0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTEscrowKeyTests.m; path = ot/tests/OTEscrowKeyTests.m; sourceTree = "<group>"; };
0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTLocalStoreTests.m; path = ot/tests/OTLocalStoreTests.m; sourceTree = "<group>"; };
0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerTests.m; path = ot/tests/OTBottledPeerTests.m; sourceTree = "<group>"; };
0C8BBF0E1FCB452400580909 /* OTControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTControl.m; path = ot/OTControl.m; sourceTree = "<group>"; };
0C8BBF0F1FCB481800580909 /* OTManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTManager.m; path = ot/OTManager.m; sourceTree = "<group>"; };
0C8BBF101FCB486B00580909 /* OTManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTManager.h; path = ot/OTManager.h; sourceTree = "<group>"; };
+ 0C9AEEB720783FBB00BF6237 /* SignInAnalyticsTests_osx.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SignInAnalyticsTests_osx.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0C9FB40120D8729A00864612 /* CoreCDP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreCDP.framework; path = System/Library/PrivateFrameworks/CoreCDP.framework; sourceTree = SDKROOT; };
0CA4EBF1202B8D1C002B1D96 /* CloudKitKeychainSyncingTestsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudKitKeychainSyncingTestsBase.h; sourceTree = "<group>"; };
0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudKitKeychainSyncingTestsBase.m; sourceTree = "<group>"; };
0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSPeerRateLimiter.m; sourceTree = "<group>"; };
0CCDE7161EEB08220021A946 /* secd-156-timers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-156-timers.m"; sourceTree = "<group>"; };
0CD8CB041ECA50780076F37F /* SOSPeerOTRTimer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSPeerOTRTimer.m; sourceTree = "<group>"; };
0CD8CB0C1ECA50D10076F37F /* SOSPeerOTRTimer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerOTRTimer.h; sourceTree = "<group>"; };
+ 0CD8D654207D6E65005CDBE8 /* SFAnalytics+Signin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalytics+Signin.h"; sourceTree = "<group>"; };
0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTContextRecord.m; path = ot/OTContextRecord.m; sourceTree = "<group>"; };
0CD9E8071FE05B8700F66C38 /* OTContextRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTContextRecord.h; path = ot/OTContextRecord.h; sourceTree = "<group>"; };
0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerSigned.m; path = ot/OTBottledPeerSigned.m; sourceTree = "<group>"; };
0CE760531E13155100B4381E /* SOSAccountTrustClassic+Circle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SOSAccountTrustClassic+Circle.h"; path = "SecureObjectSync/SOSAccountTrustClassic+Circle.h"; sourceTree = "<group>"; };
0CE760551E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SOSAccountTrustClassic+Retirement.h"; path = "SecureObjectSync/SOSAccountTrustClassic+Retirement.h"; sourceTree = "<group>"; };
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 = "<absolute>"; };
- 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFTransactionMetric.m; sourceTree = "<group>"; };
- 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFTransactionMetric.h; sourceTree = "<group>"; };
+ 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSignInAnalytics.m; sourceTree = "<group>"; };
+ 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFSignInAnalytics.h; sourceTree = "<group>"; };
+ 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSignInAnalyticsTests.m; sourceTree = "<group>"; };
+ 0CF405FC2072E352003D6A7F /* SFTMTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SFTMTests-Info.plist"; sourceTree = "<group>"; };
+ 0CF406502072E3E3003D6A7F /* SignInAnalyticsTests_ios.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SignInAnalyticsTests_ios.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
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 = "<group>"; };
107226D10D91DB32003CF14F /* SecTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTask.h; path = sectask/SecTask.h; sourceTree = "<group>"; };
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; };
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 = "<group>"; };
+ 3DD1FE78201AA50C0086D049 /* STLegacyTests+clientauth41.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+clientauth41.m"; sourceTree = "<group>"; };
+ 3DD1FE79201AA50D0086D049 /* SecureTransport_macosTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SecureTransport_macosTests.plist; sourceTree = "<group>"; };
+ 3DD1FE7A201AA50D0086D049 /* STLegacyTests-Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "STLegacyTests-Entitlements.plist"; sourceTree = "<group>"; };
+ 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+noconn.m"; sourceTree = "<group>"; };
+ 3DD1FE7C201AA50E0086D049 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+tls12.m"; sourceTree = "<group>"; };
+ 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecureTransportTests.m; sourceTree = "<group>"; };
+ 3DD1FE7F201AA50F0086D049 /* STLegacyTests+sni.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sni.m"; sourceTree = "<group>"; };
+ 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sessionstate.m"; sourceTree = "<group>"; };
+ 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sslciphers.m"; sourceTree = "<group>"; };
+ 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+dhe.m"; sourceTree = "<group>"; };
+ 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+crashes.m"; sourceTree = "<group>"; };
+ 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+falsestart.m"; sourceTree = "<group>"; };
+ 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+renegotiate.m"; sourceTree = "<group>"; };
+ 3DD1FE86201AA5120086D049 /* SecureTransport_iosTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SecureTransport_iosTests.plist; sourceTree = "<group>"; };
+ 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+clientauth.m"; sourceTree = "<group>"; };
+ 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+split.m"; sourceTree = "<group>"; };
+ 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+ciphers.m"; sourceTree = "<group>"; };
+ 3DD1FE8A201AA5140086D049 /* STLegacyTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STLegacyTests.h; sourceTree = "<group>"; };
+ 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+sessioncache.m"; sourceTree = "<group>"; };
+ 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STLegacyTests.m; sourceTree = "<group>"; };
+ 3DD1FF4D201C07F30086D049 /* SecureTransport_macos_tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecureTransport_macos_tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcoretls.tbd; path = usr/lib/libcoretls.tbd; sourceTree = SDKROOT; };
+ 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcoretls_cfhelpers.tbd; path = usr/lib/libcoretls_cfhelpers.tbd; sourceTree = SDKROOT; };
+ 3DD1FFD0201FDB1D0086D049 /* SecureTransport_ios_tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecureTransport_ios_tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
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; };
4381690F1B4EDCBD00C54D58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
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 = "<group>"; };
470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainItemV7.m; sourceTree = "<group>"; };
+ 470D966C1FCDE4BA0065FE90 /* KeychainModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = KeychainModel.xcdatamodel; sourceTree = "<group>"; };
+ 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCDKeychain.h; sourceTree = "<group>"; };
+ 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecCDKeychain.m; sourceTree = "<group>"; };
+ 470D96841FCE34370065FE90 /* CDKeychainTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CDKeychainTests.m; sourceTree = "<group>"; };
471024D91E79CB6D00844C09 /* CKKSTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSTests.h; sourceTree = "<group>"; };
+ 4718AE2D205B39620068EC3F /* securityd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = securityd; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_bridge.a; sourceTree = BUILT_PRODUCTS_DIR; };
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 = "<group>"; };
4723C9BD1F152EB10082882F /* SFSQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFSQLite.h; sourceTree = "<group>"; };
4723C9BE1F152EB10082882F /* SFObjCType.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFObjCType.m; sourceTree = "<group>"; };
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; };
+ 4771D972209A755800BA9772 /* KeychainDataclassOwner.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainDataclassOwner.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4771D975209A755800BA9772 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 4771D97E209A75FE00BA9772 /* KeychainDataclassOwner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainDataclassOwner.h; sourceTree = "<group>"; };
+ 4771D97F209A75FE00BA9772 /* KeychainDataclassOwner.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainDataclassOwner.m; sourceTree = "<group>"; };
+ 4771D99F209B7C2600BA9772 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
+ 4771D9A1209B7C3900BA9772 /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/System/Library/Frameworks/Accounts.framework; sourceTree = DEVELOPER_DIR; };
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 = "<group>"; };
477A1FEB2037A0E000ACD81D /* KeychainXCTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainXCTest.h; sourceTree = "<group>"; };
47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainSerializedItemV7.h; sourceTree = "<group>"; };
47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainSerializedItemV7.m; sourceTree = "<group>"; };
47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFKeychainControl.h; sourceTree = "<group>"; };
+ 47B503C5203B97A000722164 /* SFCredentialStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFCredentialStoreTests.m; sourceTree = "<group>"; };
+ 47C2F1832059CB680062DE30 /* KeychainResources.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainResources.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ 47C2F1862059CB680062DE30 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
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 = "<group>"; };
47C51B881EEA657D0032D9E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
47CEED1E1E60DE900044EAB4 /* CKKSManifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSManifest.h; sourceTree = "<group>"; };
47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSManifest.m; sourceTree = "<group>"; };
47D1838B1FB3827700CFCD89 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = Platforms/iPhoneOS.platform/Developer/AppleInternal/Library/Frameworks/OCMock.framework; sourceTree = DEVELOPER_DIR; };
+ 47FF17241FD60ACA00875565 /* SFKeychainServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFKeychainServer.h; sourceTree = "<group>"; };
+ 47FF17251FD60ACA00875565 /* SFKeychainServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFKeychainServer.m; sourceTree = "<group>"; };
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 = "<group>"; };
483E79891DC875F2005C0008 /* secd-67-prefixedKeyIDs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-67-prefixedKeyIDs.m"; sourceTree = "<group>"; };
485B64081DC16E8300B771B9 /* SOSKeyedPubKeyIdentifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSKeyedPubKeyIdentifier.c; sourceTree = "<group>"; };
48776C7C1DA5BB5F00CC09B9 /* SOSRingRecovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSRingRecovery.m; sourceTree = "<group>"; };
48776C7D1DA5BB5F00CC09B9 /* SOSRingRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSRingRecovery.h; sourceTree = "<group>"; };
48776C801DA5BC0E00CC09B9 /* SOSAccountRecovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountRecovery.m; sourceTree = "<group>"; };
+ 4885DCAB207FF0780071FB7B /* ClientInfoByNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ClientInfoByNotification.m; path = MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m; sourceTree = SOURCE_ROOT; };
48C2F9321E4BCFC30093D70C /* accountCirclesViewsPrint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = accountCirclesViewsPrint.m; sourceTree = "<group>"; };
48C2F9331E4BCFC30093D70C /* accountCirclesViewsPrint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = accountCirclesViewsPrint.h; sourceTree = "<group>"; };
48CC58971DA5FF0B00EBD9DB /* secd-66-account-recovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-66-account-recovery.m"; sourceTree = "<group>"; };
48E6171A1DBEC40D0098EAAD /* SOSBackupInformation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSBackupInformation.m; sourceTree = "<group>"; };
48E6171B1DBEC40D0098EAAD /* SOSBackupInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSBackupInformation.h; sourceTree = "<group>"; };
+ 48FE668F20E6E69B00FAEF17 /* SOSAuthKitHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAuthKitHelpers.m; sourceTree = "<group>"; };
+ 48FE669520E6E69C00FAEF17 /* SOSAuthKitHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSAuthKitHelpers.h; sourceTree = "<group>"; };
4AF7FFF315AFB73800B9D400 /* SecOTR.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecOTR.h; sourceTree = "<group>"; };
4AF7FFF415AFB73800B9D400 /* SecOTRDHKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecOTRDHKey.h; sourceTree = "<group>"; };
4AF7FFF515AFB73800B9D400 /* SecOTRErrors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecOTRErrors.h; sourceTree = "<group>"; };
4C3DD6AF179755560093F9D8 /* NSDate+TimeIntervalDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+TimeIntervalDescription.m"; sourceTree = "<group>"; };
4C4296300BB0A68200491999 /* SecTrustSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustSettings.h; path = trust/SecTrustSettings.h; sourceTree = "<group>"; };
4C465C7D13AFD82300E841AC /* SecurityDevTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SecurityDevTests-Info.plist"; sourceTree = "<group>"; };
+ 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleFSCompression.framework; path = System/Library/PrivateFrameworks/AppleFSCompression.framework; sourceTree = SDKROOT; };
4C4CB7100DDA44900026B660 /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = "<group>"; };
4C4CE9070AF81ED80056B01D /* TODO */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TODO; sourceTree = "<group>"; };
4C4CE9120AF81F0E0056B01D /* README */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
5346481C173322BD00FE9172 /* KeychainSyncAccountNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainSyncAccountNotification.h; sourceTree = "<group>"; };
5346481D173322BD00FE9172 /* KeychainSyncAccountNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainSyncAccountNotification.m; sourceTree = "<group>"; };
53C0E1F2177FAC2C00F8A018 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/CloudKeychain.strings; sourceTree = "<group>"; };
+ 5A4E381A207529480047F40F /* SecProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocol.h; path = protocol/SecProtocol.h; sourceTree = "<group>"; };
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; };
+ 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolTypes.h; path = protocol/SecProtocolTypes.h; sourceTree = "<group>"; };
+ 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolOptions.h; path = protocol/SecProtocolOptions.h; sourceTree = "<group>"; };
+ 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolMetadata.h; path = protocol/SecProtocolMetadata.h; sourceTree = "<group>"; };
+ 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolObject.h; path = protocol/SecProtocolObject.h; sourceTree = "<group>"; };
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 = "<group>"; };
5E10994E19A5E5CE00A60E2B /* ISProtectedItems.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ISProtectedItems.plist; sourceTree = "<group>"; };
6C1520CD1DCCF57A00C85C6D /* secd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = secd.8; sourceTree = "<group>"; };
6C1A29FC1F882788002312D8 /* SFAnalyticsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsTests.m; sourceTree = "<group>"; };
6C34462F1E24F6BE00F9522B /* CKKSRateLimiterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSRateLimiterTests.m; sourceTree = "<group>"; };
- 6C34464F1E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainCKKSRateLimiterAggregatedScores.h; path = analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h; sourceTree = "<group>"; };
- 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterAggregatedScores.m; path = analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.m; sourceTree = "<group>"; };
- 6C3446511E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainCKKSRateLimiterOverload.h; path = analytics/awd/AWDKeychainCKKSRateLimiterOverload.h; sourceTree = "<group>"; };
- 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterOverload.m; path = analytics/awd/AWDKeychainCKKSRateLimiterOverload.m; sourceTree = "<group>"; };
- 6C3446531E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainCKKSRateLimiterTopWriters.h; path = analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h; sourceTree = "<group>"; };
- 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterTopWriters.m; path = analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.m; sourceTree = "<group>"; };
- 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = "AwdMetadata-0x60-Keychain.bin"; path = "analytics/awd/AwdMetadata-0x60-Keychain.bin"; sourceTree = "<group>"; };
- 6C3446561E2534E800F9522B /* AWDMetricIds_Keychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDMetricIds_Keychain.h; path = analytics/awd/AWDMetricIds_Keychain.h; sourceTree = "<group>"; };
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 = "<group>"; };
6C758CB21F8826100075BD78 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
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; };
+ 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalKeychainAnalytics.h; sourceTree = "<group>"; };
+ 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocalKeychainAnalytics.m; sourceTree = "<group>"; };
6C860C741F4F63AD004100A1 /* SOSEnsureBackup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSEnsureBackup.h; sourceTree = "<group>"; };
6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSEnsureBackup.m; sourceTree = "<group>"; };
- 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainSOSKeychainBackupFailed.m; path = analytics/awd/AWDKeychainSOSKeychainBackupFailed.m; sourceTree = "<group>"; };
- 6C869A781F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainSOSKeychainBackupFailed.h; path = analytics/awd/AWDKeychainSOSKeychainBackupFailed.h; sourceTree = "<group>"; };
6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsActivityTracker+Internal.h"; sourceTree = "<group>"; };
6C8CE6C31FA24A670032ADF0 /* SFAnalyticsSampler+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsSampler+Internal.h"; sourceTree = "<group>"; };
6C9808611E788AEB00E70590 /* CKKSCloudKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKKSCloudKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
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 = "<group>"; };
- 6CD8D3B11EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainSecDbMarkedCorrupt.h; path = analytics/awd/AWDKeychainSecDbMarkedCorrupt.h; sourceTree = "<group>"; };
- 6CD8D3B21EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainSecDbMarkedCorrupt.m; path = analytics/awd/AWDKeychainSecDbMarkedCorrupt.m; sourceTree = "<group>"; };
6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsMultiSampler.m; sourceTree = "<group>"; };
6CDB5FF31FA78CB500410924 /* SFAnalyticsMultiSampler+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsMultiSampler+Internal.h"; sourceTree = "<group>"; };
6CDB5FF41FA78CB500410924 /* SFAnalyticsMultiSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsMultiSampler.h; sourceTree = "<group>"; };
8E64DB4C1C17CD3F0076C9DF /* com.apple.security.cloudkeychainproxy3.ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.cloudkeychainproxy3.ios.plist; path = KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.ios.plist; sourceTree = "<group>"; };
8E64DB4D1C17CD400076C9DF /* com.apple.security.cloudkeychainproxy3.osx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.cloudkeychainproxy3.osx.plist; path = KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist; sourceTree = "<group>"; };
8ED6F6C8110904E300D2B368 /* SecPBKDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPBKDF.h; sourceTree = "<group>"; };
+ A6B1BA78207BD9D400F1E099 /* notarization.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = notarization.cpp; sourceTree = "<group>"; };
+ A6B1BA79207BD9D400F1E099 /* notarization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = notarization.h; sourceTree = "<group>"; };
+ AA44E0D02032513F001EA371 /* SecProtocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecProtocol.c; path = protocol/SecProtocol.c; sourceTree = SOURCE_ROOT; };
+ AA44E0D120325140001EA371 /* SecProtocolTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecProtocolTypes.m; path = protocol/SecProtocolTypes.m; sourceTree = SOURCE_ROOT; };
+ AA44E0D920325177001EA371 /* SecProtocolPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecProtocolPriv.h; path = protocol/SecProtocolPriv.h; sourceTree = "<group>"; };
ACBAF6DD1E9417F40007BA2F /* libsecurity_transform_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_transform_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; };
ACBAF6E31E941AE00007BA2F /* transform_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = transform_regressions.h; path = OSX/libsecurity_transform/regressions/transform_regressions.h; sourceTree = "<group>"; };
ACBAF6E51E941AE00007BA2F /* transform-01-sigverify.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "transform-01-sigverify.m"; path = "OSX/libsecurity_transform/regressions/transform-01-sigverify.m"; sourceTree = "<group>"; };
BEF88C741EB0008E00357577 /* TPPolicyDocumentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPPolicyDocumentTests.m; path = keychain/trust/TrustedPeersTests/TPPolicyDocumentTests.m; sourceTree = SOURCE_ROOT; };
BEF88C751EB0008E00357577 /* TPUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPUtilsTests.m; path = keychain/trust/TrustedPeersTests/TPUtilsTests.m; sourceTree = SOURCE_ROOT; };
BEF88C761EB0008E00357577 /* TPVoucherTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPVoucherTests.m; path = keychain/trust/TrustedPeersTests/TPVoucherTests.m; sourceTree = SOURCE_ROOT; };
- CD23B4921DA06EB30047EDE9 /* IDSPersistentState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IDSPersistentState.h; path = KeychainSyncingOverIDSProxy/IDSPersistentState.h; sourceTree = "<group>"; };
- CD23B4931DA06EB30047EDE9 /* IDSPersistentState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = IDSPersistentState.m; path = KeychainSyncingOverIDSProxy/IDSPersistentState.m; sourceTree = "<group>"; };
- CD23B4941DA06EB30047EDE9 /* IDSProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IDSProxy.h; path = KeychainSyncingOverIDSProxy/IDSProxy.h; sourceTree = "<group>"; };
- CD23B4951DA06EB30047EDE9 /* IDSProxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = IDSProxy.m; path = KeychainSyncingOverIDSProxy/IDSProxy.m; sourceTree = "<group>"; };
- CD23B4961DA06EB30047EDE9 /* keychainsyncingoveridsproxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = keychainsyncingoveridsproxy.m; path = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m; sourceTree = "<group>"; };
- CD23B4971DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "KeychainSyncingOverIDSProxy+ReceiveMessage.h"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h"; sourceTree = "<group>"; };
- CD23B4981DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "KeychainSyncingOverIDSProxy+ReceiveMessage.m"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m"; sourceTree = "<group>"; };
- CD23B4991DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "KeychainSyncingOverIDSProxy+SendMessage.h"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h"; sourceTree = "<group>"; };
- CD23B49A1DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "KeychainSyncingOverIDSProxy+SendMessage.m"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m"; sourceTree = "<group>"; };
- CD23B4A81DA06ED10047EDE9 /* com.apple.private.alloy.keychainsync.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = com.apple.private.alloy.keychainsync.plist; path = KeychainSyncingOverIDSProxy/com.apple.private.alloy.keychainsync.plist; sourceTree = "<group>"; };
- CD276C271A83F60C003226BC /* KeychainSyncingOverIDSProxy.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainSyncingOverIDSProxy.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
CD2F99D91DFC995B00769430 /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; };
CD31F8601DCD4C1400414B46 /* SOSAccountTrust.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrust.m; path = SecureObjectSync/SOSAccountTrust.m; sourceTree = "<group>"; };
CD31F8611DCD4C1400414B46 /* SOSAccountTrust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrust.h; path = SecureObjectSync/SOSAccountTrust.h; sourceTree = "<group>"; };
- CD6130D31DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.keychainsyncingoveridsproxy.ios.plist; path = KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.ios.plist; sourceTree = "<group>"; };
- CD6130D41DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.osx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.security.keychainsyncingoveridsproxy.osx.plist; path = KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist; sourceTree = "<group>"; };
- CD6130D71DA06FC600E1E42F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = "<group>"; };
- CD6130D81DA06FC600E1E42F /* KeychainSyncingOverIDSProxy-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "KeychainSyncingOverIDSProxy-Info.plist"; path = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist"; sourceTree = "<group>"; };
- CD6130D91DA06FC600E1E42F /* keychainsyncingoveridsproxy.entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = keychainsyncingoveridsproxy.entitlements.plist; path = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist; sourceTree = "<group>"; };
CD744683195A00BB00FB01C0 /* IDS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IDS.framework; path = System/Library/PrivateFrameworks/IDS.framework; sourceTree = SDKROOT; };
CD9021471DE27A9E00F81DC4 /* SOSAccountPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSAccountPriv.h; sourceTree = "<group>"; };
CDA43D251DFCA0790038E038 /* AggregateDictionary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AggregateDictionary.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.Internal.sdk/System/Library/PrivateFrameworks/AggregateDictionary.framework; sourceTree = DEVELOPER_DIR; };
D41D36701EB14D87007FA978 /* libDiagnosticMessagesClient.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libDiagnosticMessagesClient.tbd; path = usr/lib/libDiagnosticMessagesClient.tbd; sourceTree = SDKROOT; };
D43761641EB2996C00954447 /* SecRevocationNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecRevocationNetworking.h; path = OSX/sec/securityd/SecRevocationNetworking.h; sourceTree = "<group>"; };
D43761651EB2996C00954447 /* SecRevocationNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecRevocationNetworking.m; path = OSX/sec/securityd/SecRevocationNetworking.m; sourceTree = "<group>"; };
- D43DBED51E99D17100C04AEA /* asynchttp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asynchttp.c; path = OSX/sec/securityd/asynchttp.c; sourceTree = "<group>"; };
- D43DBED61E99D17100C04AEA /* asynchttp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asynchttp.h; path = OSX/sec/securityd/asynchttp.h; sourceTree = "<group>"; };
D43DBED71E99D17100C04AEA /* nameconstraints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nameconstraints.c; path = OSX/sec/securityd/nameconstraints.c; sourceTree = "<group>"; };
D43DBED81E99D17100C04AEA /* nameconstraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nameconstraints.h; path = OSX/sec/securityd/nameconstraints.h; sourceTree = "<group>"; };
D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTATrustUtilities.m; path = OSX/sec/securityd/OTATrustUtilities.m; sourceTree = "<group>"; };
D43DBEDE1E99D17200C04AEA /* policytree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = policytree.h; path = OSX/sec/securityd/policytree.h; sourceTree = "<group>"; };
D43DBEDF1E99D17200C04AEA /* SecCAIssuerCache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCAIssuerCache.c; path = OSX/sec/securityd/SecCAIssuerCache.c; sourceTree = "<group>"; };
D43DBEE01E99D17200C04AEA /* SecCAIssuerCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCAIssuerCache.h; path = OSX/sec/securityd/SecCAIssuerCache.h; sourceTree = "<group>"; };
- D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCAIssuerRequest.c; path = OSX/sec/securityd/SecCAIssuerRequest.c; sourceTree = "<group>"; };
+ D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecCAIssuerRequest.m; path = OSX/sec/securityd/SecCAIssuerRequest.m; sourceTree = "<group>"; };
D43DBEE21E99D17200C04AEA /* SecCAIssuerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCAIssuerRequest.h; path = OSX/sec/securityd/SecCAIssuerRequest.h; sourceTree = "<group>"; };
D43DBEE31E99D17200C04AEA /* SecCertificateServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCertificateServer.c; path = OSX/sec/securityd/SecCertificateServer.c; sourceTree = "<group>"; };
D43DBEE41E99D17200C04AEA /* SecCertificateServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCertificateServer.h; path = OSX/sec/securityd/SecCertificateServer.h; sourceTree = "<group>"; };
D43DBEFA1E99D17300C04AEA /* SecTrustStoreServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustStoreServer.h; path = OSX/sec/securityd/SecTrustStoreServer.h; sourceTree = "<group>"; };
D43DDE511F620F09009742A5 /* SecPolicyChecks.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecPolicyChecks.list; sourceTree = "<group>"; };
D43DDE581F638061009742A5 /* SecPolicy.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecPolicy.list; sourceTree = "<group>"; };
+ D44D08B420AB890E0023C439 /* Security.apinotes */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Security.apinotes; path = base/Security.apinotes; sourceTree = "<group>"; };
D45068681E948A9E00FA7675 /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = entitlements.plist; path = OSX/trustd/macOS/entitlements.plist; sourceTree = "<group>"; };
D45068691E948ACE00FA7675 /* entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = entitlements.plist; path = OSX/trustd/iOS/entitlements.plist; sourceTree = "<group>"; };
D453C38A1FEC669300DE349B /* trust_update.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = trust_update.m; sourceTree = "<group>"; };
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; };
+ D46513072097954B005D93FE /* si-23-sectrust-ocsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-23-sectrust-ocsp.h"; sourceTree = "<group>"; };
D479F6E01F980F8F00388D28 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Trust.strings; sourceTree = "<group>"; };
D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib_ios_x64.xcconfig; path = xcconfig/lib_ios_x64.xcconfig; sourceTree = "<group>"; };
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 = "<group>"; };
D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCFAllocator.h; sourceTree = "<group>"; };
D487FBB71DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-29-sectrust-sha1-deprecation.m"; sourceTree = "<group>"; };
D487FBB91DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-29-sectrust-sha1-deprecation.h"; sourceTree = "<group>"; };
+ D48BD193206C47530075DDC9 /* si-35-cms-expiration-time.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-35-cms-expiration-time.m"; sourceTree = "<group>"; };
+ D48BD195206C476B0075DDC9 /* si-35-cms-expiration-time.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-35-cms-expiration-time.h"; sourceTree = "<group>"; };
D48F029B1EA1671B00ACC3C9 /* si-61-pkcs12.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-61-pkcs12.h"; sourceTree = "<group>"; };
+ D4911167209558900066A1E4 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
+ D4961BBD2079423300F16DA7 /* TrustURLSessionDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TrustURLSessionDelegate.m; path = OSX/sec/securityd/TrustURLSessionDelegate.m; sourceTree = "<group>"; };
+ D4961BC52079426000F16DA7 /* TrustURLSessionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TrustURLSessionDelegate.h; path = OSX/sec/securityd/TrustURLSessionDelegate.h; sourceTree = "<group>"; };
D4AA647C1E97144700D317ED /* si-18-certificate-parse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-18-certificate-parse.m"; sourceTree = "<group>"; };
D4AA64831E97270300D317ED /* si-18-certificate-parse */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-18-certificate-parse"; path = "OSX/shared_regressions/si-18-certificate-parse"; sourceTree = SOURCE_ROOT; };
D4ADA30E1E2B1E650031CEA3 /* trustd-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "trustd-Info.plist"; path = "OSX/trustd/trustd-Info.plist"; sourceTree = "<group>"; };
D4ADA3191E2B41670031CEA3 /* libtrustd.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtrustd.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ D4B6D57B2069D8450099FBEF /* si-34-cms-timestamp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-34-cms-timestamp.m"; sourceTree = "<group>"; };
+ D4B6D5822069D85B0099FBEF /* si-34-cms-timestamp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-34-cms-timestamp.h"; sourceTree = "<group>"; };
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 = "<group>"; };
D4C263C51F8FF2A9001317EA /* generateErrStrings.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = generateErrStrings.pl; path = OSX/lib/generateErrStrings.pl; sourceTree = "<group>"; usesTabs = 1; };
DA30D6781DF8C8FB00EC6B43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DA30D6831DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainSyncAccountUpdater.h; sourceTree = "<group>"; };
DA30D6841DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainSyncAccountUpdater.m; sourceTree = "<group>"; };
+ DA5B871A2065A8410093F083 /* SecAutorelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAutorelease.h; path = src/SecAutorelease.h; sourceTree = "<group>"; };
+ DA5B871B2065A8430093F083 /* SecAutorelease.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecAutorelease.m; path = src/SecAutorelease.m; sourceTree = "<group>"; };
DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSControlServer.m; sourceTree = "<group>"; };
DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSControlServer.h; sourceTree = "<group>"; };
DAB27ADA1FA29EB700DEBBDE /* SOSControlServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSControlServer.h; sourceTree = "<group>"; };
DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSControlServer.m; sourceTree = "<group>"; };
+ DAE40BCE20CF3E47002D5674 /* secitemcanarytest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemcanarytest; sourceTree = BUILT_PRODUCTS_DIR; };
+ DAE40BD720CF3F04002D5674 /* secitemcanarytest.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = secitemcanarytest.entitlements; sourceTree = "<group>"; };
+ DAE40BD820CF3F04002D5674 /* secitemcanarytest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secitemcanarytest.m; sourceTree = "<group>"; };
DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = AutoreleaseTest.c; sourceTree = "<group>"; };
DAEE055B1FAD3FC600DF27F3 /* AutoreleaseTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoreleaseTest.h; sourceTree = "<group>"; };
DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = macos_legacy_lib.xcconfig; path = xcconfig/macos_legacy_lib.xcconfig; sourceTree = "<group>"; };
DC24B5811DA420D700330B48 /* SOSEnginePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSEnginePriv.h; sourceTree = "<group>"; };
DC24B5821DA420D700330B48 /* SOSPersist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPersist.h; sourceTree = "<group>"; };
DC24B5831DA422BE00330B48 /* base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = base.xcconfig; path = OSX/config/base.xcconfig; sourceTree = "<group>"; };
- DC24B5841DA432C600330B48 /* KeychainSyncingOverIDSProxy.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = KeychainSyncingOverIDSProxy.8; path = KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy.8; sourceTree = SOURCE_ROOT; };
DC24B5851DA432E900330B48 /* CloudKeychainProxy.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CloudKeychainProxy.8; path = OSX/sec/CloudKeychainProxy/CloudKeychainProxy.8; sourceTree = "<group>"; };
DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; };
DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSNotifier.h; sourceTree = "<group>"; };
DC610A681D78FA87002223DE /* validation.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = validation.sh; path = OSX/codesign_tests/validation.sh; sourceTree = "<group>"; };
DC610AB71D7910C3002223DE /* gk_reset_check */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gk_reset_check; sourceTree = BUILT_PRODUCTS_DIR; };
DC610AB91D7910F8002223DE /* gk_reset_check.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gk_reset_check.c; path = OSX/gk_reset_check/gk_reset_check.c; sourceTree = "<group>"; };
+ DC63D70220B3930700D088AD /* libxar.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxar.tbd; path = usr/lib/libxar.tbd; sourceTree = SDKROOT; };
+ DC63D70920B3933000D088AD /* libOpenScriptingUtil.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libOpenScriptingUtil.tbd; path = usr/lib/libOpenScriptingUtil.tbd; sourceTree = SDKROOT; };
DC6593C91ED8DA9200C19462 /* CKKSTests+CurrentPointerAPI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CKKSTests+CurrentPointerAPI.m"; sourceTree = "<group>"; };
DC6593D21ED8DBCE00C19462 /* CKKSTests+API.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CKKSTests+API.h"; sourceTree = "<group>"; };
DC65E7BE1D8CBB1500152EF0 /* readline.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = readline.c; sourceTree = "<group>"; };
DC88344B1D8A21AA00CE0ACA /* oidsattr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oidsattr.c; sourceTree = "<group>"; };
DC88344E1D8A21AA00CE0ACA /* oidsocsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oidsocsp.c; sourceTree = "<group>"; };
DC88344F1D8A21AA00CE0ACA /* oidsocsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oidsocsp.h; sourceTree = "<group>"; };
+ DC8D238C2064649400E163C8 /* CKKSAPSHandlingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSAPSHandlingTests.m; sourceTree = "<group>"; };
DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib_ios.xcconfig; path = xcconfig/lib_ios.xcconfig; sourceTree = "<group>"; };
DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSZoneChangeFetcher.h; sourceTree = "<group>"; };
DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSZoneChangeFetcher.m; sourceTree = "<group>"; };
DCAD9B421F8D939C00C5E2AE /* CKKSFixups.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSFixups.h; sourceTree = "<group>"; };
DCAD9B431F8D939C00C5E2AE /* CKKSFixups.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSFixups.m; sourceTree = "<group>"; };
DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CloudKitKeychainSyncingFixupTests.m; sourceTree = "<group>"; };
+ DCAE1DD52073FCDE00B4F687 /* NSError+UsefulConstructors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+UsefulConstructors.h"; sourceTree = "<group>"; };
+ DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSError+UsefulConstructors.m"; sourceTree = "<group>"; };
DCB2214A1E8B0861001598BC /* server_xpc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = server_xpc.m; sourceTree = "<group>"; };
DCB2215B1E8B098D001598BC /* server_endpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = server_endpoint.h; sourceTree = "<group>"; };
DCB332361F467CC200178C30 /* macos_tapi_hacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = macos_tapi_hacks.h; path = OSX/macos_tapi_hacks.h; sourceTree = "<group>"; };
DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSHealTLKSharesOperation.h; sourceTree = "<group>"; };
DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSHealTLKSharesOperation.m; sourceTree = "<group>"; };
DCC0800D1CFF7903005C35C8 /* CSSMOID.exp-in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CSSMOID.exp-in"; sourceTree = "<group>"; };
+ DCC5860120BF8A98005C7269 /* SecBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecBase.h; sourceTree = "<group>"; };
+ DCC5860220BF8A98005C7269 /* SecBase.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecBase.c; sourceTree = "<group>"; };
DCC78C371D8085D800865A7C /* ios6_1_keychain_2_db.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ios6_1_keychain_2_db.h; sourceTree = "<group>"; };
DCC78C381D8085D800865A7C /* ios8-inet-keychain-2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ios8-inet-keychain-2.h"; sourceTree = "<group>"; };
DCC78C391D8085D800865A7C /* secd-03-corrupted-items.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-03-corrupted-items.m"; sourceTree = "<group>"; };
DCC78C651D8085D800865A7C /* secd-71-engine-save-sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "secd-71-engine-save-sample1.h"; sourceTree = "<group>"; };
DCC78C661D8085D800865A7C /* secd-74-engine-beer-servers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-74-engine-beer-servers.m"; sourceTree = "<group>"; };
DCC78C671D8085D800865A7C /* secd-75-engine-views.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-75-engine-views.m"; sourceTree = "<group>"; };
- DCC78C681D8085D800865A7C /* secd-76-idstransport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-76-idstransport.m"; sourceTree = "<group>"; };
- DCC78C691D8085D800865A7C /* secd_77_ids_messaging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = secd_77_ids_messaging.m; sourceTree = "<group>"; };
DCC78C6A1D8085D800865A7C /* secd-80-views-basic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-80-views-basic.m"; sourceTree = "<group>"; };
- DCC78C6B1D8085D800865A7C /* secd-82-secproperties-basic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-82-secproperties-basic.m"; sourceTree = "<group>"; };
DCC78C6C1D8085D800865A7C /* secd-81-item-acl-stress.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-81-item-acl-stress.m"; sourceTree = "<group>"; };
DCC78C6D1D8085D800865A7C /* secd-81-item-acl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-81-item-acl.m"; sourceTree = "<group>"; };
DCC78C6E1D8085D800865A7C /* secd-82-persistent-ref.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-82-persistent-ref.m"; sourceTree = "<group>"; };
DCC78D6C1D8085F200865A7C /* SOSPeerInfoInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfoInternal.h; sourceTree = "<group>"; };
DCC78D6D1D8085F200865A7C /* SOSPeerInfoRingState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSPeerInfoRingState.m; sourceTree = "<group>"; };
DCC78D6E1D8085F200865A7C /* SOSPeerInfoRingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfoRingState.h; sourceTree = "<group>"; };
- DCC78D6F1D8085F200865A7C /* SOSPeerInfoSecurityProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSPeerInfoSecurityProperties.m; sourceTree = "<group>"; };
- DCC78D701D8085F200865A7C /* SOSPeerInfoSecurityProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPeerInfoSecurityProperties.h; sourceTree = "<group>"; };
DCC78D721D8085F200865A7C /* SOSKVSKeys.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSKVSKeys.m; sourceTree = "<group>"; };
DCC78D731D8085F200865A7C /* SOSKVSKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSKVSKeys.h; sourceTree = "<group>"; };
DCC78D741D8085F200865A7C /* SOSTransport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransport.m; sourceTree = "<group>"; };
DCC78D7D1D8085F200865A7C /* SOSTransportKeyParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportKeyParameter.h; sourceTree = "<group>"; };
DCC78D801D8085F200865A7C /* SOSTransportMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportMessage.m; sourceTree = "<group>"; };
DCC78D811D8085F200865A7C /* SOSTransportMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportMessage.h; sourceTree = "<group>"; };
- DCC78D821D8085F200865A7C /* SOSTransportMessageIDS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportMessageIDS.m; sourceTree = "<group>"; };
- DCC78D831D8085F200865A7C /* SOSTransportMessageIDS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportMessageIDS.h; sourceTree = "<group>"; };
DCC78D841D8085F200865A7C /* SOSTransportMessageKVS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportMessageKVS.m; sourceTree = "<group>"; };
DCC78D851D8085F200865A7C /* SOSTransportMessageKVS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportMessageKVS.h; sourceTree = "<group>"; };
DCC78D871D8085F200865A7C /* SOSARCDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSARCDefines.h; sourceTree = "<group>"; };
DCC78E091D8085FC00865A7C /* si-87-sectrust-name-constraints.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-87-sectrust-name-constraints.m"; sourceTree = "<group>"; };
DCC78E0A1D8085FC00865A7C /* si-87-sectrust-name-constraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-87-sectrust-name-constraints.h"; sourceTree = "<group>"; };
DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-89-cms-hash-agility.m"; sourceTree = "<group>"; };
- DCC78E0C1D8085FC00865A7C /* si-89-cms-hash-agility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-89-cms-hash-agility.h"; sourceTree = "<group>"; };
DCC78E0D1D8085FC00865A7C /* si-90-emcs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-90-emcs.m"; sourceTree = "<group>"; };
DCC78E0E1D8085FC00865A7C /* si-95-cms-basic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-95-cms-basic.c"; sourceTree = "<group>"; };
DCC78E0F1D8085FC00865A7C /* si-95-cms-basic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-95-cms-basic.h"; sourceTree = "<group>"; };
DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCertificateRequest.c; sourceTree = "<group>"; };
DCC78E401D8085FC00865A7C /* SecCFAllocator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFAllocator.c; sourceTree = "<group>"; };
DCC78E421D8085FC00865A7C /* SecCMS.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCMS.c; sourceTree = "<group>"; };
- DCC78E441D8085FC00865A7C /* SecCTKKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCTKKey.c; sourceTree = "<group>"; };
+ DCC78E441D8085FC00865A7C /* SecCTKKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecCTKKey.m; sourceTree = "<group>"; };
DCC78E451D8085FC00865A7C /* SecCTKKeyPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCTKKeyPriv.h; sourceTree = "<group>"; };
DCC78E461D8085FC00865A7C /* SecDH.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecDH.c; sourceTree = "<group>"; };
DCC78E481D8085FC00865A7C /* SecDigest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecDigest.c; sourceTree = "<group>"; };
- DCC78E491D8085FC00865A7C /* SecECKey.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecECKey.c; sourceTree = "<group>"; };
+ DCC78E491D8085FC00865A7C /* SecECKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecECKey.m; sourceTree = "<group>"; };
DCC78E4C1D8085FC00865A7C /* SecEMCS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecEMCS.m; sourceTree = "<group>"; };
DCC78E4E1D8085FC00865A7C /* SecExports.exp-in */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SecExports.exp-in"; sourceTree = "<group>"; };
- DCC78E4F1D8085FC00865A7C /* SecFramework.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecFramework.c; sourceTree = "<group>"; };
+ DCC78E4F1D8085FC00865A7C /* SecFramework.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SecFramework.c; path = OSX/sec/Security/SecFramework.c; sourceTree = "<group>"; };
DCC78E521D8085FC00865A7C /* SecIdentity.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecIdentity.c; sourceTree = "<group>"; };
DCC78E551D8085FC00865A7C /* SecImportExport.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecImportExport.c; sourceTree = "<group>"; };
DCC78E581D8085FC00865A7C /* SecItem.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecItem.c; sourceTree = "<group>"; };
DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecItemConstants.c; sourceTree = "<group>"; };
DCC78E5F1D8085FC00865A7C /* SecItemShim.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecItemShim.h; sourceTree = "<group>"; };
DCC78E601D8085FC00865A7C /* SecKey.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecKey.c; sourceTree = "<group>"; };
- DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecKeyAdaptors.c; sourceTree = "<group>"; };
+ DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecKeyAdaptors.m; sourceTree = "<group>"; };
DCC78E651D8085FC00865A7C /* SecLogging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecLogging.c; sourceTree = "<group>"; };
DCC78E661D8085FC00865A7C /* SecLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecLogging.h; sourceTree = "<group>"; };
DCC78E671D8085FC00865A7C /* SecOnOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecOnOSX.h; sourceTree = "<group>"; };
DCD06B231D8E0D7D007602F1 /* cfutilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = cfutilities.cpp; sourceTree = "<group>"; };
DCD06BC21D8E0DC2007602F1 /* utilities_dtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utilities_dtrace.h; path = derived_src/security_utilities/utilities_dtrace.h; sourceTree = BUILT_PRODUCTS_DIR; };
DCD06BC51D8E0DD3007602F1 /* security_utilities.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = security_utilities.d; path = lib/security_utilities.d; sourceTree = "<group>"; };
+ DCD45353209A5B260086CBFC /* si-cms-signing-identity-p12.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-cms-signing-identity-p12.h"; sourceTree = "<group>"; };
+ DCD45354209A5B260086CBFC /* si-cms-signing-identity-p12.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "si-cms-signing-identity-p12.c"; sourceTree = "<group>"; };
+ DCD45358209A5C2D0086CBFC /* kc-keychain-file-helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "kc-keychain-file-helpers.c"; path = "regressions/kc-keychain-file-helpers.c"; sourceTree = "<group>"; };
DCD662F31E329B6800188186 /* CKKSNewTLKOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSNewTLKOperation.h; sourceTree = "<group>"; };
DCD662F41E329B6800188186 /* CKKSNewTLKOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSNewTLKOperation.m; sourceTree = "<group>"; };
DCD66D731D8204A700DB1393 /* libSecTrustOSX.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSecTrustOSX.a; sourceTree = BUILT_PRODUCTS_DIR; };
DCDCC7E41D9B551C006487E8 /* SOSAccountSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountSync.m; sourceTree = "<group>"; };
DCDCCB8D1DF7B8D4006E840E /* CKKSItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSItem.h; sourceTree = "<group>"; };
DCDCCB8E1DF7B8D4006E840E /* CKKSItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSItem.m; sourceTree = "<group>"; };
+ DCE2341520A3D4B8009766A3 /* si-cms-hash-agility-data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-cms-hash-agility-data.h"; sourceTree = "<group>"; };
+ DCE2341620A3D4B8009766A3 /* si-cms-hash-agility-data.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "si-cms-hash-agility-data.c"; sourceTree = "<group>"; };
DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSCurrentItemPointer.h; sourceTree = "<group>"; };
DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSCurrentItemPointer.m; sourceTree = "<group>"; };
DCE278E61ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSUpdateCurrentItemPointerOperation.h; sourceTree = "<group>"; };
DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CrashReporterSupport.framework; path = System/Library/PrivateFrameworks/CrashReporterSupport.framework; sourceTree = SDKROOT; };
DCE4E93B1D7F3E0900AFB96E /* AOSUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSUI.framework; path = System/Library/PrivateFrameworks/AOSUI.framework; sourceTree = SDKROOT; };
DCE4E93E1D7F3E4000AFB96E /* AOSAccounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSAccounts.framework; path = System/Library/PrivateFrameworks/AOSAccounts.framework; sourceTree = SDKROOT; };
- DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreCDP.framework; path = System/Library/PrivateFrameworks/CoreCDP.framework; sourceTree = SDKROOT; };
DCE4E9451D7F3E8700AFB96E /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = "OSX/Keychain Circle Notification/en.lproj/Localizable.strings"; sourceTree = SOURCE_ROOT; };
DCE4E9461D7F3E8700AFB96E /* com.apple.security.keychain-circle-notification.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "com.apple.security.keychain-circle-notification.plist"; sourceTree = "<group>"; };
DCE4E9481D7F3E8700AFB96E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = "OSX/Keychain Circle Notification/en.lproj/InfoPlist.strings"; sourceTree = SOURCE_ROOT; };
DCEA5D951E3014250089CF55 /* CKKSZone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSZone.h; sourceTree = "<group>"; };
DCEA5D961E3014250089CF55 /* CKKSZone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSZone.m; sourceTree = "<group>"; };
DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.securityd.plist; path = OSX/sec/ipc/com.apple.securityd.plist; sourceTree = SOURCE_ROOT; };
+ DCF158C52064895C00B87B6D /* CKKSAPSReceiverTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSAPSReceiverTests.h; sourceTree = "<group>"; };
DCF783141D88B4DE00E694BB /* libsecurity_apple_csp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_apple_csp.a; sourceTree = BUILT_PRODUCTS_DIR; };
DCF783151D88B60D00E694BB /* aesCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aesCommon.h; sourceTree = "<group>"; };
DCF783161D88B60D00E694BB /* aescsp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aescsp.cpp; sourceTree = "<group>"; };
E7FE40C71DC8084600F0F5B6 /* CKDSimulatedAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKDSimulatedAccount.h; path = ../../SOSCircle/Regressions/CKDSimulatedAccount.h; sourceTree = "<group>"; };
E7FE40C81DC8084600F0F5B6 /* CKDSimulatedAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDSimulatedAccount.m; path = ../../SOSCircle/Regressions/CKDSimulatedAccount.m; sourceTree = "<group>"; };
E7FEFB80169E26E200E18152 /* sub_commands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sub_commands.h; sourceTree = "<group>"; };
+ EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = DeviceSimulator.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
+ EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceSimulatorProtocol.h; sourceTree = "<group>"; };
+ EB056E411FE5E390000A771E /* DeviceSimulator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceSimulator.h; sourceTree = "<group>"; };
+ EB056E421FE5E390000A771E /* DeviceSimulator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeviceSimulator.m; sourceTree = "<group>"; };
+ EB056E441FE5E390000A771E /* DeviceSimulatorMain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeviceSimulatorMain.m; sourceTree = "<group>"; };
+ EB056E461FE5E391000A771E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ EB05C4F11FE5E48A00D68712 /* MultiDeviceSimulatorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MultiDeviceSimulatorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ EB05C4F31FE5E48B00D68712 /* MultiDeviceSimulatorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MultiDeviceSimulatorTests.m; sourceTree = "<group>"; };
+ EB05C4F51FE5E48B00D68712 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
EB0BC93E1C3C791500785842 /* secedumodetest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secedumodetest; sourceTree = BUILT_PRODUCTS_DIR; };
EB0BC9651C3C794700785842 /* secedumodetest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secedumodetest.entitlements; path = secedumodetest/secedumodetest.entitlements; sourceTree = "<group>"; };
EB0BC9661C3C794700785842 /* secedumodetest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = secedumodetest.m; path = secedumodetest/secedumodetest.m; sourceTree = "<group>"; };
EBB8399B1E295B8F00853BAC /* secfuzzer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secfuzzer.m; sourceTree = "<group>"; };
EBB839A51E29665D00853BAC /* secfuzzer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secfuzzer; sourceTree = BUILT_PRODUCTS_DIR; };
EBC15B1B1DB4306C00126882 /* com.apple.secd.sb */ = {isa = PBXFileReference; lastKnownFileType = text; path = com.apple.secd.sb; sourceTree = "<group>"; };
+ EBC73F4A209A0BEF00AE3350 /* install-test-framework.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "install-test-framework.sh"; path = "xcscripts/install-test-framework.sh"; sourceTree = "<group>"; };
+ EBCE165C1FE6F4CE002E7CCC /* DeviceSimulator-Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "DeviceSimulator-Entitlements.plist"; sourceTree = "<group>"; };
+ EBCE165E1FE7313C002E7CCC /* MultiDeviceNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MultiDeviceNetworking.h; sourceTree = "<group>"; };
+ EBCE165F1FE7313C002E7CCC /* MultiDeviceNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MultiDeviceNetworking.m; sourceTree = "<group>"; };
+ EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MultiDeviceNetworkingProtocol.h; sourceTree = "<group>"; };
EBCF01001DF501310055AF97 /* swcagent-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "swcagent-entitlements.plist"; sourceTree = "<group>"; };
EBCF73F11CE45F8600BED7CA /* secitemfunctionality.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secitemfunctionality.entitlements; path = secitemfunctionality/secitemfunctionality.entitlements; sourceTree = "<group>"; };
EBCF73F21CE45F8600BED7CA /* secitemfunctionality.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = secitemfunctionality.m; path = secitemfunctionality/secitemfunctionality.m; sourceTree = "<group>"; };
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 = "<group>"; };
+ EBE202752092913500B48020 /* SecurityInduceLowDisk.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SecurityInduceLowDisk.plist; sourceTree = "<group>"; };
EBE54D771BE33227000C4856 /* libmis.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmis.dylib; path = usr/lib/libmis.dylib; sourceTree = SDKROOT; };
EBE700FE204676E700E00A87 /* secdmock_db_version_11_1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = secdmock_db_version_11_1.h; sourceTree = "<group>"; };
EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSControlHelper.h; sourceTree = "<group>"; };
EB3409B01C1D627400D77661 /* Foundation.framework in Frameworks */,
DCD22D8B1D8CCC58001C9B81 /* libASN1_not_installed.a in Frameworks */,
DC59E9A71D91C7C7001BDDF5 /* libCMS.a in Frameworks */,
+ D491116C2095594A0066A1E4 /* CoreData.framework in Frameworks */,
DC00ABD71D821F3F00513D74 /* libsecurity.a in Frameworks */,
DC00ABD81D821F4300513D74 /* libsecdRegressions.a in Frameworks */,
DC00ABD91D821F4700513D74 /* libsecurityd_ios.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;
0C85DFF51FB38BB6000343A7 /* libaks_acl.a in Frameworks */,
0C85DFF61FB38BB6000343A7 /* libDER.a in Frameworks */,
0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */,
+ D491116E209559510066A1E4 /* CoreData.framework in Frameworks */,
0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */,
0C85DFF91FB38BB6000343A7 /* libctkclient.a in Frameworks */,
0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 0C9AEEB020783FBB00BF6237 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0C9AEEBB20783FF900BF6237 /* Security.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 0CF406342072E3E3003D6A7F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0C5663EF20BE2E220035F362 /* libutilities.a in Frameworks */,
+ 0C9AEEBE207843D000BF6237 /* Security.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
225394AF1E3080A600D3CD9B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 3DD1FF2F201C07F30086D049 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3DD1FFAA201FC5C30086D049 /* libcoretls.tbd in Frameworks */,
+ 3DD1FFAB201FC5C30086D049 /* libcoretls_cfhelpers.tbd in Frameworks */,
+ 3DD1FFA7201FC5B90086D049 /* Foundation.framework in Frameworks */,
+ 3DD1FFA5201FC59D0086D049 /* libsecurity_ssl.a in Frameworks */,
+ 3DD1FFA4201FC58F0086D049 /* libutilities.a in Frameworks */,
+ 3DD1FFA3201FC5870086D049 /* libDiagnosticMessagesClient.tbd in Frameworks */,
+ 3DD1FFA2201FC5800086D049 /* SecurityFoundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3DD1FFC3201FDB1D0086D049 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3DD1FFD2201FDCA80086D049 /* Security.framework in Frameworks */,
+ 3DD1FFC4201FDB1D0086D049 /* libcoretls.tbd in Frameworks */,
+ 3DD1FFC5201FDB1D0086D049 /* libcoretls_cfhelpers.tbd in Frameworks */,
+ 3DD1FFC6201FDB1D0086D049 /* Foundation.framework in Frameworks */,
+ 3DD1FFC8201FDB1D0086D049 /* libsecurity_ssl.a in Frameworks */,
+ 3DD1FFC9201FDB1D0086D049 /* libutilities.a in Frameworks */,
+ 3DD1FFCB201FDB1D0086D049 /* SecurityFoundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
438169091B4EDCBD00C54D58 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 4718AE17205B39620068EC3F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4718AEE7205B3A420068EC3F /* libsecurityd_bridge.a in Frameworks */,
+ 4718AE19205B39620068EC3F /* libMobileGestalt.dylib in Frameworks */,
+ 4718AE1A205B39620068EC3F /* Foundation.framework in Frameworks */,
+ 4718AE1B205B39620068EC3F /* libutilities.a in Frameworks */,
+ 4718AE1C205B39620068EC3F /* CoreFoundation.framework in Frameworks */,
+ 4718AE1E205B39620068EC3F /* libSecureObjectSyncServer.a in Frameworks */,
+ 4718AE1F205B39620068EC3F /* libSecureObjectSyncFramework.a in Frameworks */,
+ 4718AE20205B39620068EC3F /* libSWCAgent.a in Frameworks */,
+ 4718AE21205B39620068EC3F /* Security.framework in Frameworks */,
+ D491116B2095593E0066A1E4 /* CoreData.framework in Frameworks */,
+ 4718AE22205B39620068EC3F /* SystemConfiguration.framework in Frameworks */,
+ 4718AE23205B39620068EC3F /* IOKit.framework in Frameworks */,
+ 4718AE24205B39620068EC3F /* libaks_acl.a in Frameworks */,
+ 4718AE25205B39620068EC3F /* libsqlite3.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 4718AE9C205B39C40068EC3F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
4727FBB41F9918580003AE36 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 479231F02065C52D00B2718C /* Security.framework in Frameworks */,
+ 479231EF2065C52200B2718C /* libsecurity.a in Frameworks */,
+ 479231E82065B31300B2718C /* libsecurityd_ios.a in Frameworks */,
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 */,
+ D4911172209559630066A1E4 /* CoreData.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;
};
+ 4771D96F209A755800BA9772 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4771D9A2209B7C3900BA9772 /* Accounts.framework in Frameworks */,
+ 4771D9A0209B7C2700BA9772 /* Security.framework in Frameworks */,
+ 4771D973209A755800BA9772 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
478D427D1FD72A8100CAB645 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 479231EE2065B32200B2718C /* libsecurityd_ios.a in Frameworks */,
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 */,
+ D4911173209559630066A1E4 /* CoreData.framework in Frameworks */,
478D42831FD72A8100CAB645 /* ApplePushService.framework in Frameworks */,
478D42841FD72A8100CAB645 /* SharedWebCredentials.framework in Frameworks */,
478D42851FD72A8100CAB645 /* MobileKeyBag.framework in Frameworks */,
478D428C1FD72A8100CAB645 /* libSecureObjectSyncFramework.a in Frameworks */,
478D428D1FD72A8100CAB645 /* ProtocolBuffer.framework in Frameworks */,
478D428E1FD72A8100CAB645 /* CloudKit.framework in Frameworks */,
+ DC066DF02102563300694EAF /* Security.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;
};
+ 47C2F1802059CB680062DE30 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 47C2F1842059CB680062DE30 /* Foundation.framework in Frameworks */,
+ D49111702095595B0066A1E4 /* CoreData.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
47C51B811EEA657D0032D9E5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- D459A1781E9FFE60009ED74B /* CoreCDP.framework in Frameworks */,
+ 0C9FB40720D872A600864612 /* CoreCDP.framework in Frameworks */,
43DB54551BB1F8920083C3F1 /* ProtectedCloudStorage.framework in Frameworks */,
4C8A38C917B93DF10001B4C0 /* CloudServices.framework in Frameworks */,
4C7913251799A5CC00A9633E /* MobileCoreServices.framework in Frameworks */,
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 0C59605C1FB2D9280095BA29 /* libprequelite.tbd in Frameworks */,
+ 0C9FB40920D8735500864612 /* CoreCDP.framework in Frameworks */,
47D13F631E8447FB0063B6E2 /* SecurityFoundation.framework in Frameworks */,
EBE9019A1C22852C007308C6 /* AggregateDictionary.framework in Frameworks */,
438168BB1B4ED42300C54D58 /* CoreFoundation.framework in Frameworks */,
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 */,
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- D4574AA3203E68E0006D9B82 /* AuthKit.framework in Frameworks */,
- D4574AA1203E6893006D9B82 /* Accounts.framework in Frameworks */,
+ 5AF7630920520870001557AE /* AuthKit.framework in Frameworks */,
+ 5A4E527B2051D857009D5826 /* Accounts.framework in Frameworks */,
D4119E79202BDF580048587B /* libz.tbd in Frameworks */,
6CDB601B1FA93A2000410924 /* libprequelite.tbd in Frameworks */,
6CDB601A1FA93A1800410924 /* libsqlite3.tbd in Frameworks */,
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 */,
);
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 */,
);
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- D4574AA2203E68C8006D9B82 /* AuthKit.framework in Frameworks */,
- D4574AA0203E618B006D9B82 /* Accounts.framework in Frameworks */,
+ 5AF762FF2051F990001557AE /* AuthKit.framework in Frameworks */,
+ 5A4E52792051D7FA009D5826 /* Accounts.framework in Frameworks */,
D4119E78202BDF490048587B /* libz.tbd in Frameworks */,
6CAA8D3B1F8431AE007B6E03 /* Foundation.framework in Frameworks */,
6CAA8D3A1F8431A7007B6E03 /* libutilities.a in Frameworks */,
DCD8A1E71E09F85400E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */,
DC00AB831D821C9A00513D74 /* libSWCAgent.a in Frameworks */,
790851EE0CA9B3410083CC4D /* Security.framework in Frameworks */,
+ D491116A2095593E0066A1E4 /* CoreData.framework in Frameworks */,
E71F3E3116EA69A900FAF9B4 /* SystemConfiguration.framework in Frameworks */,
4CAF66190F3A6FCD0064A534 /* IOKit.framework in Frameworks */,
4432B15E1A014D37000958DC /* libaks_acl.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- CD276C241A83F60C003226BC /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DC65E7311D8CB33800152EF0 /* libutilities.a in Frameworks */,
- CD0637551A84060600C81E74 /* Security.framework in Frameworks */,
- CD0637571A84068F00C81E74 /* IDS.framework in Frameworks */,
- CD0637561A84065F00C81E74 /* IOKit.framework in Frameworks */,
- CD276C281A83F60C003226BC /* Foundation.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
D41257CC1E9410A300781F23 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ DAE40BC820CF3E46002D5674 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DAE40BC920CF3E46002D5674 /* Security.framework in Frameworks */,
+ DAE40BCA20CF3E46002D5674 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
DC0067BC1D87876F005AF8DB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 4C47FA9420A51DD800384CB6 /* AppleFSCompression.framework in Frameworks */,
CD9F2AFB1DF24BAF00AD3577 /* Foundation.framework in Frameworks */,
DCD22D4B1D8CBF54001C9B81 /* libASN1_not_installed.a in Frameworks */,
DC00AB6F1D821C3400513D74 /* libSecItemShimOSX.a in Frameworks */,
DC3502D61E02118000BC0587 /* libsecurity.a in Frameworks */,
DC3502CF1E020E2900BC0587 /* libutilities.a in Frameworks */,
DC222C351E02418100B09171 /* CFNetwork.framework in Frameworks */,
- 0C8BBF2B1FCB575800580909 /* CoreCDP.framework in Frameworks */,
+ D491116F209559510066A1E4 /* CoreData.framework in Frameworks */,
DC3502DF1E02129F00BC0587 /* Foundation.framework in Frameworks */,
DC3502D21E02113900BC0587 /* IOKit.framework in Frameworks */,
DC3502E91E02172C00BC0587 /* OCMock.framework in Frameworks */,
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 */,
);
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0C9FB40820D8731800864612 /* CoreCDP.framework in Frameworks */,
DC52EC2F1D80CFB200B0A59C /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 4C47FA9320A51DC900384CB6 /* AppleFSCompression.framework in Frameworks */,
CD9F2AFA1DF249CF00AD3577 /* Foundation.framework in Frameworks */,
EBF3745F1DBFB32A0065D840 /* libobjc.dylib in Frameworks */,
DC5AC0D61D83548300CF422C /* libDiagnosticMessagesClient.dylib in Frameworks */,
DCD22D6F1D8CC728001C9B81 /* libsecurity_cdsa_client.a in Frameworks */,
DC5AC0C91D8353D100CF422C /* libbsm.dylib in Frameworks */,
DCD22D701D8CC733001C9B81 /* libutilities.a in Frameworks */,
+ DC63D70820B3931100D088AD /* libxar.tbd in Frameworks */,
+ DC72BCD720B3A7DF00B26495 /* libOpenScriptingUtil.tbd in Frameworks */,
DC5AC0C71D8353C800CF422C /* PCSC.framework in Frameworks */,
DC5AC0C51D8353C200CF422C /* Security.framework in Frameworks */,
DC5AC0C41D8353BB00CF422C /* System.framework in Frameworks */,
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 47C2F1762059A2300062DE30 /* libprequelite.tbd in Frameworks */,
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 */,
DCD22D611D8CC2F8001C9B81 /* libbsm.dylib in Frameworks */,
DC610A2B1D78F129002223DE /* libcoreauthd_test_client.a in Frameworks */,
DC610A2F1D78F129002223DE /* libctkclient_test.a in Frameworks */,
+ D491116D2095594B0066A1E4 /* CoreData.framework in Frameworks */,
DC610A2E1D78F129002223DE /* libsqlite3.dylib in Frameworks */,
BEE523D91DACAA2500DD0AA3 /* libz.dylib in Frameworks */,
DC65E7C31D8CBBA200152EF0 /* libregressionBase.a in Frameworks */,
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 0C5960621FB2E0EC0095BA29 /* libprequelite.tbd in Frameworks */,
+ 0C0582AE20D9657800D7BD7A /* CoreCDP.framework in Frameworks */,
6C1F93111DD5E41A00585608 /* libDiagnosticMessagesClient.dylib in Frameworks */,
DCE4E6AE1D7A3C6A00AFB96E /* AppleSystemInfo.framework in Frameworks */,
DCE4E6AD1D7A3B9700AFB96E /* libaks.a in Frameworks */,
DCE4E7C61D7A468300AFB96E /* libaks.a in Frameworks */,
DCE4E75E1D7A43B500AFB96E /* CoreFoundation.framework in Frameworks */,
DCE4E7BF1D7A463400AFB96E /* Security.framework in Frameworks */,
+ 091B39732063B67700ECAB6F /* RemoteServiceDiscovery.framework in Frameworks */,
DCE4E7C11D7A463E00AFB96E /* SecurityFoundation.framework in Frameworks */,
DCE4E7541D7A43B500AFB96E /* Foundation.framework in Frameworks */,
DCE4E7681D7A43B500AFB96E /* IOKit.framework in Frameworks */,
DC00AB7C1D821C7100513D74 /* libsecurityd_ios.a in Frameworks */,
DCE4E8131D7A4E5300AFB96E /* CoreFoundation.framework in Frameworks */,
DCE4E8121D7A4E4F00AFB96E /* IOKit.framework in Frameworks */,
+ D49111692095593D0066A1E4 /* CoreData.framework in Frameworks */,
DCDCCB3C1DF25D74006E840E /* ApplePushService.framework in Frameworks */,
DCDCCB3B1DF25D69006E840E /* CloudKit.framework in Frameworks */,
DCD22D721D8CC804001C9B81 /* SystemConfiguration.framework in Frameworks */,
- DCE4E80F1D7A4E4600AFB96E /* Security.framework in Frameworks */,
+ DCD504C320CB293700F37D26 /* Security.framework in Frameworks */,
DC4DB16A1E26E9F900CD6769 /* ProtocolBuffer.framework in Frameworks */,
- 0C8BBFFD1FCE8F3300580909 /* CoreCDP.framework in Frameworks */,
DCE4E82C1D7A56FF00AFB96E /* AppleSystemInfo.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0C0582B820D9B70D00D7BD7A /* CoreCDP.framework in Frameworks */,
CD112FC51DDA31AD00C77A07 /* Accounts.framework in Frameworks */,
0CC319241DA46FBF005D42EA /* ProtectedCloudStorage.framework in Frameworks */,
DCE4E9401D7F3E4D00AFB96E /* Security.framework in Frameworks */,
DCE4E93A1D7F3DF500AFB96E /* CrashReporterSupport.framework in Frameworks */,
DCE4E9381D7F3DB500AFB96E /* Cocoa.framework in Frameworks */,
DCE4E9371D7F3DAF00AFB96E /* CloudServices.framework in Frameworks */,
- DCE4E9421D7F3E6E00AFB96E /* CoreCDP.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
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 */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ EB056E3B1FE5E390000A771E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EBCE16411FE6DE5A002E7CCC /* libDER.a in Frameworks */,
+ EBCE16421FE6DE5A002E7CCC /* SecurityFoundation.framework in Frameworks */,
+ EBCE16431FE6DE5A002E7CCC /* libASN1_not_installed.a in Frameworks */,
+ EBCE165D1FE71821002E7CCC /* libsecurityd_ios.a in Frameworks */,
+ EBCE16451FE6DE5A002E7CCC /* libSecureObjectSyncFramework.a in Frameworks */,
+ EBCE16461FE6DE5A002E7CCC /* libSecureObjectSyncServer.a in Frameworks */,
+ EBCE16471FE6DE5A002E7CCC /* libsecurity.a in Frameworks */,
+ EBCE16481FE6DE5A002E7CCC /* libutilities.a in Frameworks */,
+ EBCE16491FE6DE5A002E7CCC /* CFNetwork.framework in Frameworks */,
+ EBCE164B1FE6DE5A002E7CCC /* Foundation.framework in Frameworks */,
+ EBCE164C1FE6DE5A002E7CCC /* IOKit.framework in Frameworks */,
+ EBCE164E1FE6DE5A002E7CCC /* SystemConfiguration.framework in Frameworks */,
+ EBCE164F1FE6DE5A002E7CCC /* libACM.a in Frameworks */,
+ EBCE16501FE6DE5A002E7CCC /* libaks_acl.a in Frameworks */,
+ EBCE16511FE6DE5A002E7CCC /* libbsm.dylib in Frameworks */,
+ EBCE16521FE6DE5A002E7CCC /* libcoreauthd_client.a in Frameworks */,
+ EBCE16531FE6DE5A002E7CCC /* libctkclient.a in Frameworks */,
+ EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */,
+ EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */,
+ D4911171209559620066A1E4 /* CoreData.framework in Frameworks */,
+ EBCE16561FE6DE5A002E7CCC /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EB05C4EE1FE5E48A00D68712 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EBCE166B1FE74688002E7CCC /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
EB0BC9391C3C791500785842 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
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 */,
0CF0E2DD1F8EE37C00BD18E4 /* Signin Metrics */ = {
isa = PBXGroup;
children = (
- 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */,
- 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */,
+ 0CF405FB2072E351003D6A7F /* Resources */,
+ 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */,
+ 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */,
+ 0C108C4B208A677100E8CF70 /* SFSignInAnalytics+Internal.h */,
+ 0CF405F32072E295003D6A7F /* tests */,
);
path = "Signin Metrics";
sourceTree = "<group>";
};
+ 0CF405F32072E295003D6A7F /* tests */ = {
+ isa = PBXGroup;
+ children = (
+ 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */,
+ );
+ path = tests;
+ sourceTree = "<group>";
+ };
+ 0CF405FB2072E351003D6A7F /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 0CF405FC2072E352003D6A7F /* SFTMTests-Info.plist */,
+ );
+ path = Resources;
+ sourceTree = "<group>";
+ };
107226CF0D91DB32003CF14F /* sectask */ = {
isa = PBXGroup;
children = (
path = ../../../sectask;
sourceTree = "<group>";
};
+ 3DD1FE72201AA38A0086D049 /* SecureTransportTests */ = {
+ isa = PBXGroup;
+ children = (
+ 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */,
+ 3DD1FE7A201AA50D0086D049 /* STLegacyTests-Entitlements.plist */,
+ 3DD1FE8A201AA5140086D049 /* STLegacyTests.h */,
+ 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */,
+ 3DD1FE89201AA5140086D049 /* STLegacyTests+ciphers.m */,
+ 3DD1FE87201AA5130086D049 /* STLegacyTests+clientauth.m */,
+ 3DD1FE78201AA50C0086D049 /* STLegacyTests+clientauth41.m */,
+ 3DD1FE83201AA5110086D049 /* STLegacyTests+crashes.m */,
+ 3DD1FE82201AA5110086D049 /* STLegacyTests+dhe.m */,
+ 3DD1FE84201AA5120086D049 /* STLegacyTests+falsestart.m */,
+ 3DD1FE7B201AA50D0086D049 /* STLegacyTests+noconn.m */,
+ 3DD1FE85201AA5120086D049 /* STLegacyTests+renegotiate.m */,
+ 3DD1FE8B201AA5150086D049 /* STLegacyTests+sessioncache.m */,
+ 3DD1FE80201AA5100086D049 /* STLegacyTests+sessionstate.m */,
+ 3DD1FE7F201AA50F0086D049 /* STLegacyTests+sni.m */,
+ 3DD1FE88201AA5130086D049 /* STLegacyTests+split.m */,
+ 3DD1FE81201AA5100086D049 /* STLegacyTests+sslciphers.m */,
+ 3DD1FE7D201AA50E0086D049 /* STLegacyTests+tls12.m */,
+ 3DD1FE7C201AA50E0086D049 /* Info.plist */,
+ 3DD1FE86201AA5120086D049 /* SecureTransport_iosTests.plist */,
+ 3DD1FE79201AA50D0086D049 /* SecureTransport_macosTests.plist */,
+ );
+ path = SecureTransportTests;
+ sourceTree = "<group>";
+ };
4381690E1B4EDCBD00C54D58 /* SOSCCAuthPlugin */ = {
isa = PBXGroup;
children = (
name = seckeychainnetworkextensionstest;
sourceTree = "<group>";
};
+ 470D96651FCDE45C0065FE90 /* CoreDataKeychain */ = {
+ isa = PBXGroup;
+ children = (
+ 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */,
+ 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */,
+ 470D96701FCDE55B0065FE90 /* SecCDKeychain.m */,
+ );
+ path = CoreDataKeychain;
+ sourceTree = "<group>";
+ };
4723C9B51F152E8E0082882F /* Analytics */ = {
isa = PBXGroup;
children = (
6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */,
6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */,
6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */,
+ 0CD8D654207D6E65005CDBE8 /* SFAnalytics+Signin.h */,
);
path = Analytics;
sourceTree = "<group>";
4727FBB81F9918590003AE36 /* secdxctests */ = {
isa = PBXGroup;
children = (
- 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */,
- 4727FBBB1F9918590003AE36 /* Info.plist */,
- 477A1FE1203763A500ACD81D /* KeychainAPITests.m */,
477A1FEB2037A0E000ACD81D /* KeychainXCTest.h */,
477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */,
+ 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */,
+ 470D96841FCE34370065FE90 /* CDKeychainTests.m */,
+ 47B503C5203B97A000722164 /* SFCredentialStoreTests.m */,
+ 477A1FE1203763A500ACD81D /* KeychainAPITests.m */,
+ 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */,
+ 4727FBBB1F9918590003AE36 /* Info.plist */,
);
path = secdxctests;
sourceTree = "<group>";
name = seckeychainnetworkextensionunauthorizedaccesstest;
sourceTree = "<group>";
};
+ 4771D974209A755800BA9772 /* KeychainDataclassOwner */ = {
+ isa = PBXGroup;
+ children = (
+ 4771D975209A755800BA9772 /* Info.plist */,
+ 4771D97E209A75FE00BA9772 /* KeychainDataclassOwner.h */,
+ 4771D97F209A75FE00BA9772 /* KeychainDataclassOwner.m */,
+ );
+ path = KeychainDataclassOwner;
+ sourceTree = "<group>";
+ };
+ 47C2F1852059CB680062DE30 /* KeychainResources */ = {
+ isa = PBXGroup;
+ children = (
+ 47C2F1862059CB680062DE30 /* Info.plist */,
+ );
+ path = KeychainResources;
+ sourceTree = "<group>";
+ };
47C51B851EEA657D0032D9E5 /* SecurityUnitTests */ = {
isa = PBXGroup;
children = (
DC5AC1FF1D83650C00CF422C /* securityd */,
6C69517B1F758E1000F68F91 /* supd */,
DC0BC4E51D8B6AA600070CB0 /* applications */,
+ EB81D0CB1FE5838B00FD7F16 /* MultiDeviceSimulator */,
DC5AC2011D83663C00CF422C /* tests */,
EB2CA5311D2C30CD00AB770F /* xcconfig */,
+ EBC73F44209A0BB200AE3350 /* xcscripts */,
EBF374731DC055590065D840 /* security-sysdiagnose */,
E7FCBE401314471B000DE34E /* Frameworks */,
4C8BC620097DBC1B00C781D5 /* Libraries */,
4C4CE9120AF81F0E0056B01D /* README */,
4CAB97FD1114CC5300EFB38D /* README.keychain */,
4C4CE9070AF81ED80056B01D /* TODO */,
- 0CE98BAD1FA93AA900CF1D54 /* CKKSTests-Info.plist */,
- 0C85E0041FB38BB7000343A7 /* OTTests-Info.plist */,
);
sourceTree = "<group>";
};
BE442BC118B7FDB800F24DAE /* swcagent */,
BE197F2619116FD100BA91D1 /* SharedWebCredentialViewService.app */,
5E10992519A5E55800A60E2B /* ISACLProtectedItems.bundle */,
- CD276C271A83F60C003226BC /* KeychainSyncingOverIDSProxy.bundle */,
5EBE247A1B00CCAE0007DB0E /* secacltests */,
4381690C1B4EDCBD00C54D58 /* SOSCCAuthPlugin.bundle */,
EB9C1D7A1BDFD0E000F89272 /* secbackupntest */,
6CAA8D201F842FB3007B6E03 /* securityuploadd */,
6C4605B81F882B9B001421B6 /* KeychainAnalyticsTests.xctest */,
0C8BBF081FCB446400580909 /* otctl */,
+ EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */,
+ EB05C4F11FE5E48A00D68712 /* MultiDeviceSimulatorTests.xctest */,
478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */,
EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */,
+ 3DD1FF4D201C07F30086D049 /* SecureTransport_macos_tests.xctest */,
+ 3DD1FFD0201FDB1D0086D049 /* SecureTransport_ios_tests.xctest */,
+ 47C2F1832059CB680062DE30 /* KeychainResources.bundle */,
+ 4718AE2D205B39620068EC3F /* securityd */,
+ 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */,
+ 0CF406502072E3E3003D6A7F /* SignInAnalyticsTests_ios.xctest */,
+ 0C9AEEB720783FBB00BF6237 /* SignInAnalyticsTests_osx.xctest */,
+ DAE40BCE20CF3E47002D5674 /* secitemcanarytest */,
+ 4771D972209A755800BA9772 /* KeychainDataclassOwner.bundle */,
);
name = Products;
sourceTree = "<group>";
4C922CB2097F1984004CEEBD /* Security */ = {
isa = PBXGroup;
children = (
+ D44D08B420AB890E0023C439 /* Security.apinotes */,
DC1785981D778C5300B50D50 /* cssmapple.h */,
4C28BCD60986EBCB0020C665 /* certextensions.h */,
4C696B3709BFA94F000CBC75 /* SecBase.h */,
4CF0487F0A5F016300268236 /* SecItemPriv.h */,
4C7072840AC9EA4E007CC205 /* SecKey.h */,
4C7072D30AC9ED5A007CC205 /* SecKeyPriv.h */,
+ 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */,
4CBA0E860BB33C0000E72B55 /* SecPolicy.h */,
4C6416D40BB34F00001C83FD /* SecPolicyPriv.h */,
+ 5AFCF32D20746D9A0010D4B5 /* SecProtocolObject.h */,
+ 5AFCF32220746AD80010D4B5 /* SecProtocolOptions.h */,
+ 5A4E381A207529480047F40F /* SecProtocol.h */,
+ 5AC6BFA52077CD130051737D /* SecProtocolTypes.h */,
+ 5AFCF32820746AE90010D4B5 /* SecProtocolMetadata.h */,
+ AA44E0D920325177001EA371 /* SecProtocolPriv.h */,
4C2F81D40BF121D2003C4F77 /* SecRandom.h */,
107226D10D91DB32003CF14F /* SecTask.h */,
DCD068031D8CDF7E007602F1 /* SecTaskPriv.h */,
6C34464D1E2534C200F9522B /* Analytics */ = {
isa = PBXGroup;
children = (
- 6C34464E1E2534D200F9522B /* AWD */,
EBB407AF1EBA433A00A541A5 /* CKKSPowerCollection.h */,
EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */,
479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */,
name = Analytics;
sourceTree = "<group>";
};
- 6C34464E1E2534D200F9522B /* AWD */ = {
- isa = PBXGroup;
- children = (
- 6C869A781F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.h */,
- 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */,
- 6CD8D3B11EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.h */,
- 6CD8D3B21EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.m */,
- 6C34464F1E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.h */,
- 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */,
- 6C3446511E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.h */,
- 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */,
- 6C3446531E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.h */,
- 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */,
- 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */,
- 6C3446561E2534E800F9522B /* AWDMetricIds_Keychain.h */,
- );
- name = AWD;
- sourceTree = "<group>";
- };
6C69517B1F758E1000F68F91 /* supd */ = {
isa = PBXGroup;
children = (
children = (
6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */,
6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */,
+ 6C814A4A2050B4B600CB391B /* LocalKeychainAnalytics.h */,
+ 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */,
);
path = Clients;
sourceTree = "<group>";
path = DigicertMalaysia;
sourceTree = "<group>";
};
+ AA44E0CF2032511C001EA371 /* Protocol */ = {
+ isa = PBXGroup;
+ children = (
+ AA44E0D02032513F001EA371 /* SecProtocol.c */,
+ AA44E0D120325140001EA371 /* SecProtocolTypes.m */,
+ );
+ path = Protocol;
+ sourceTree = "<group>";
+ };
ACBAF6DF1E941A800007BA2F /* regressions */ = {
isa = PBXGroup;
children = (
0CE760511E1314F700B4381E /* SOSAccountTrustClassic+Identity.h */,
0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */,
0CE7604F1E1301DC00B4381E /* SOSAccountTrustClassic+Expansion.h */,
- 0C4899261E0F399B00C6CF70 /* SOSAccountTrustOctagon.h */,
- 0C4899241E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m */,
);
name = AccountTrust;
path = ..;
sourceTree = "<group>";
};
- CD6130CC1DA06F5700E1E42F /* KeychainSyncingOverIDSProxy */ = {
- isa = PBXGroup;
- children = (
- CD23B4961DA06EB30047EDE9 /* keychainsyncingoveridsproxy.m */,
- CD23B4971DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.h */,
- CD23B4981DA06EB30047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m */,
- CD23B4991DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.h */,
- CD23B49A1DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m */,
- CD23B4931DA06EB30047EDE9 /* IDSPersistentState.m */,
- CD23B4921DA06EB30047EDE9 /* IDSPersistentState.h */,
- CD23B4951DA06EB30047EDE9 /* IDSProxy.m */,
- CD23B4941DA06EB30047EDE9 /* IDSProxy.h */,
- CD6130D21DA06FA800E1E42F /* Supporting Files */,
- );
- name = KeychainSyncingOverIDSProxy;
- sourceTree = "<group>";
- };
- CD6130D21DA06FA800E1E42F /* Supporting Files */ = {
- isa = PBXGroup;
- children = (
- CD6130D31DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.ios.plist */,
- CD6130D41DA06FC600E1E42F /* com.apple.security.keychainsyncingoveridsproxy.osx.plist */,
- CD6130D51DA06FC600E1E42F /* en.lproj */,
- CD6130D81DA06FC600E1E42F /* KeychainSyncingOverIDSProxy-Info.plist */,
- CD6130D91DA06FC600E1E42F /* keychainsyncingoveridsproxy.entitlements.plist */,
- CD23B4A81DA06ED10047EDE9 /* com.apple.private.alloy.keychainsync.plist */,
- DC24B5841DA432C600330B48 /* KeychainSyncingOverIDSProxy.8 */,
- );
- name = "Supporting Files";
- sourceTree = "<group>";
- };
- CD6130D51DA06FC600E1E42F /* en.lproj */ = {
- isa = PBXGroup;
- children = (
- CD6130D61DA06FC600E1E42F /* InfoPlist.strings */,
- );
- name = en.lproj;
- path = KeychainSyncingOverIDSProxy/en.lproj;
- sourceTree = "<group>";
- };
DA30D6771DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */ = {
isa = PBXGroup;
children = (
path = KeychainSyncAccountUpdater;
sourceTree = "<group>";
};
+ DAE40BD620CF3F04002D5674 /* secitemcanarytest */ = {
+ isa = PBXGroup;
+ children = (
+ DAE40BD720CF3F04002D5674 /* secitemcanarytest.entitlements */,
+ DAE40BD820CF3F04002D5674 /* secitemcanarytest.m */,
+ );
+ path = secitemcanarytest;
+ sourceTree = "<group>";
+ };
DC0BC4E51D8B6AA600070CB0 /* applications */ = {
isa = PBXGroup;
children = (
DC0BCA481D8B82CD00070CB0 /* regressions */ = {
isa = PBXGroup;
children = (
+ 3DD1FE72201AA38A0086D049 /* SecureTransportTests */,
DC0BCA2F1D8B82CD00070CB0 /* test-certs */,
DC0BCA301D8B82CD00070CB0 /* cert-1.h */,
DC0BCA311D8B82CD00070CB0 /* identity-1.h */,
EBF3749B1DC064200065D840 /* SecADWrapper.h */,
DC0BCC3C1D8C68CF00070CB0 /* SecAKSWrappers.c */,
DC0BCC3D1D8C68CF00070CB0 /* SecAKSWrappers.h */,
+ DA5B871A2065A8410093F083 /* SecAutorelease.h */,
+ DA5B871B2065A8430093F083 /* SecAutorelease.m */,
DC0BCC3E1D8C68CF00070CB0 /* SecBuffer.c */,
DC0BCC3F1D8C68CF00070CB0 /* SecBuffer.h */,
DC0BCC401D8C68CF00070CB0 /* SecCoreCrypto.c */,
D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */,
DCC78E421D8085FC00865A7C /* SecCMS.c */,
79BDD3C00D60DB84000D84D3 /* SecCMS.h */,
- DCC78E441D8085FC00865A7C /* SecCTKKey.c */,
+ DCC78E441D8085FC00865A7C /* SecCTKKey.m */,
DCC78E451D8085FC00865A7C /* SecCTKKeyPriv.h */,
DCC78E381D8085FC00865A7C /* SecCertificate.c */,
4CEF4CA70C5551FE00062475 /* SecCertificateInternal.h */,
DCC78E461D8085FC00865A7C /* SecDH.c */,
7940D4110C3ACF9000FDB5D8 /* SecDH.h */,
DCC78E481D8085FC00865A7C /* SecDigest.c */,
- DCC78E491D8085FC00865A7C /* SecECKey.c */,
+ DCC78E491D8085FC00865A7C /* SecECKey.m */,
4CD3BA601106FF4D00BE8B75 /* SecECKey.h */,
78F92F10195128D70023B54B /* SecECKeyPriv.h */,
DCC78E4C1D8085FC00865A7C /* SecEMCS.m */,
EB69AB091BF4347700913AF1 /* SecEMCSPriv.h */,
- DCC78E4F1D8085FC00865A7C /* SecFramework.c */,
4C0B906C0ACCBD240077CD03 /* SecFramework.h */,
4C8E99C20FC601D50072EB4C /* SecFrameworkStrings.h */,
DCC78E521D8085FC00865A7C /* SecIdentity.c */,
4CEDF7370F3A6CFB0027C4FE /* SecItemInternal.h */,
DCC78E5F1D8085FC00865A7C /* SecItemShim.h */,
DCC78E601D8085FC00865A7C /* SecKey.c */,
- DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */,
+ DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */,
4C04A90811924BBC0020550C /* SecKeyInternal.h */,
+ 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */,
DCC78E651D8085FC00865A7C /* SecLogging.c */,
DCC78E661D8085FC00865A7C /* SecLogging.h */,
4AF7FFF315AFB73800B9D400 /* SecOTR.h */,
DCC78E9C1D8085FC00865A7C /* vmdh.c */,
4C7391770B01745000C4CBFA /* vmdh.h */,
47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */,
+ DCC5860120BF8A98005C7269 /* SecBase.h */,
+ DCC5860220BF8A98005C7269 /* SecBase.c */,
);
name = src;
sourceTree = "<group>";
DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */,
DCBF2F7C1F90084D00ED0CA4 /* CKKSTLKSharingTests.m */,
DC08D1CB1E64FCC5006237DA /* CKKSSOSTests.m */,
+ DC8D238C2064649400E163C8 /* CKKSAPSHandlingTests.m */,
DC9C750F1E4BCC5100F1CA0D /* CKKSOperationTests.m */,
DC222C891E089BAE00B09171 /* CKKSSQLTests.m */,
DC4DB15E1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m */,
DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */,
6C588D791EAA149F00D7E322 /* RateLimiterTests.m */,
4723C9D11F1531970082882F /* CKKSLoggerTests.m */,
+ DCF158C52064895C00B87B6D /* CKKSAPSReceiverTests.h */,
DCE7F2081F21726500DDB0F7 /* CKKSAPSReceiverTests.m */,
DC9C95951F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m */,
);
DC59E9AA1D91C9BE001BDDF5 /* Security.framework (Shared) */ = {
isa = PBXGroup;
children = (
+ DCC78E4F1D8085FC00865A7C /* SecFramework.c */,
+ AA44E0CF2032511C001EA371 /* Protocol */,
4723C9B51F152E8E0082882F /* Analytics */,
DCD067621D8CDE9B007602F1 /* codesigning */,
DCD06AA81D8E0D3D007602F1 /* security_utilities */,
E7D847C61C6BE9710025BB44 /* KeychainCircle.framework */,
DCE4E9121D7F3D5400AFB96E /* Keychain Circle Notification */,
DCE4E8DE1D7F39DB00AFB96E /* Cloud Keychain Utility */,
- CD6130CC1DA06F5700E1E42F /* KeychainSyncingOverIDSProxy */,
E7A5F4D11C0CFF4E00F3BEBB /* KVSKeychainSyncingProxy */,
4381690E1B4EDCBD00C54D58 /* SOSCCAuthPlugin */,
);
DC6D2C941DD3B20400BE372D /* keychain */ = {
isa = PBXGroup;
children = (
+ DCAE1DCF2073FCA400B4F687 /* categories */,
0C7CEA391FE9CE3900125C79 /* behavior */,
0C8BBEF61FCB402900580909 /* otctl */,
0C8BBE831FC9DA1700580909 /* Octagon Trust */,
6C34464D1E2534C200F9522B /* Analytics */,
BEF88C451EAFFFED00357577 /* TrustedPeers */,
DC9B7AD31DCBF336004E9385 /* CloudKit Syncing */,
+ 470D96651FCDE45C0065FE90 /* CoreDataKeychain */,
+ 47C2F1852059CB680062DE30 /* KeychainResources */,
+ 4771D974209A755800BA9772 /* KeychainDataclassOwner */,
);
path = keychain;
sourceTree = "<group>";
name = Helpers;
sourceTree = "<group>";
};
+ DCAE1DCF2073FCA400B4F687 /* categories */ = {
+ isa = PBXGroup;
+ children = (
+ DCAE1DD52073FCDE00B4F687 /* NSError+UsefulConstructors.h */,
+ DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */,
+ );
+ path = categories;
+ sourceTree = "<group>";
+ };
DCB340651D8A24CC0054D16E /* authorization */ = {
isa = PBXGroup;
children = (
DCB344421D8A35270054D16E /* kc-key-helpers.h */,
DCB344431D8A35270054D16E /* kc-identity-helpers.h */,
DCB344441D8A35270054D16E /* kc-keychain-file-helpers.h */,
+ DCD45358209A5C2D0086CBFC /* kc-keychain-file-helpers.c */,
DCB344451D8A35270054D16E /* kc-01-keychain-creation.c */,
DCB344461D8A35270054D16E /* kc-02-unlock-noui.c */,
DCB344471D8A35270054D16E /* kc-03-status.c */,
DCC78C651D8085D800865A7C /* secd-71-engine-save-sample1.h */,
DCC78C661D8085D800865A7C /* secd-74-engine-beer-servers.m */,
DCC78C671D8085D800865A7C /* secd-75-engine-views.m */,
- DCC78C681D8085D800865A7C /* secd-76-idstransport.m */,
- DCC78C691D8085D800865A7C /* secd_77_ids_messaging.m */,
7281E08B1DFD0A380021E1B7 /* secd-80-views-alwayson.m */,
DCC78C6A1D8085D800865A7C /* secd-80-views-basic.m */,
- DCC78C6B1D8085D800865A7C /* secd-82-secproperties-basic.m */,
DCC78C6C1D8085D800865A7C /* secd-81-item-acl-stress.m */,
DCC78C6D1D8085D800865A7C /* secd-81-item-acl.m */,
DCC78C6E1D8085D800865A7C /* secd-82-persistent-ref.m */,
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 */,
470ACEF21F58C3A600D1D5BD /* SecDbKeychainItemV7.h */,
470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */,
47D1837D1FB1183D00CFCD89 /* SecDbKeychainV7-protobufs */,
+ 47FF17241FD60ACA00875565 /* SFKeychainServer.h */,
+ 47FF17251FD60ACA00875565 /* SFKeychainServer.m */,
473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */,
473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */,
);
DCC78D6C1D8085F200865A7C /* SOSPeerInfoInternal.h */,
DCC78D6D1D8085F200865A7C /* SOSPeerInfoRingState.m */,
DCC78D6E1D8085F200865A7C /* SOSPeerInfoRingState.h */,
- DCC78D6F1D8085F200865A7C /* SOSPeerInfoSecurityProperties.m */,
- DCC78D701D8085F200865A7C /* SOSPeerInfoSecurityProperties.h */,
);
name = PeerInfo;
sourceTree = "<group>";
DCC78D7D1D8085F200865A7C /* SOSTransportKeyParameter.h */,
DCC78D801D8085F200865A7C /* SOSTransportMessage.m */,
DCC78D811D8085F200865A7C /* SOSTransportMessage.h */,
- DCC78D821D8085F200865A7C /* SOSTransportMessageIDS.m */,
- DCC78D831D8085F200865A7C /* SOSTransportMessageIDS.h */,
DCC78D841D8085F200865A7C /* SOSTransportMessageKVS.m */,
DCC78D851D8085F200865A7C /* SOSTransportMessageKVS.h */,
0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */,
EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */,
DAB27ADA1FA29EB700DEBBDE /* SOSControlServer.h */,
DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */,
+ 48FE669520E6E69C00FAEF17 /* SOSAuthKitHelpers.h */,
+ 48FE668F20E6E69B00FAEF17 /* SOSAuthKitHelpers.m */,
);
path = SecureObjectSync;
sourceTree = "<group>";
DCC78DBE1D8085FC00865A7C /* si-22-sectrust-iap.c */,
DCC78DBF1D8085FC00865A7C /* si-22-sectrust-iap.h */,
DCC78DC01D8085FC00865A7C /* si-23-sectrust-ocsp.c */,
+ D46513072097954B005D93FE /* si-23-sectrust-ocsp.h */,
DCC78DC11D8085FC00865A7C /* si-24-sectrust-digicert-malaysia.c */,
DCC78DC21D8085FC00865A7C /* si-24-sectrust-diginotar.c */,
DCC78DC31D8085FC00865A7C /* si-24-sectrust-itms.c */,
D4CFAA7D1E660BB3004746AA /* si-32-sectrust-pinning-required.m */,
D4C8A1511E66709800CD6DF1 /* si-32-sectrust-pinning-required.h */,
DCC78DCD1D8085FC00865A7C /* si-33-keychain-backup.c */,
+ D4B6D57B2069D8450099FBEF /* si-34-cms-timestamp.m */,
+ D4B6D5822069D85B0099FBEF /* si-34-cms-timestamp.h */,
+ D48BD193206C47530075DDC9 /* si-35-cms-expiration-time.m */,
+ D48BD195206C476B0075DDC9 /* si-35-cms-expiration-time.h */,
DCC78DCE1D8085FC00865A7C /* si-40-seckey-custom.c */,
DCC78DCF1D8085FC00865A7C /* si-40-seckey.c */,
DCC78DD01D8085FC00865A7C /* si-41-sececkey.c */,
DCC78DD61D8085FC00865A7C /* si-44-seckey-ies.m */,
5E77936E1E5EFEB20074A2D1 /* si-44-seckey-aks.m */,
09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */,
+ 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */,
DCC78DD71D8085FC00865A7C /* si-50-secrandom.c */,
DCC78DD81D8085FC00865A7C /* si-60-cms.c */,
DCC78DD91D8085FC00865A7C /* si-61-pkcs12.c */,
DCC78E0A1D8085FC00865A7C /* si-87-sectrust-name-constraints.h */,
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 */,
DCC78E0F1D8085FC00865A7C /* si-95-cms-basic.h */,
DCC78E101D8085FC00865A7C /* si-97-sectrust-path-scoring.m */,
DCC78E111D8085FC00865A7C /* si-97-sectrust-path-scoring.h */,
+ DCD45353209A5B260086CBFC /* si-cms-signing-identity-p12.h */,
+ DCD45354209A5B260086CBFC /* si-cms-signing-identity-p12.c */,
+ DCE2341520A3D4B8009766A3 /* si-cms-hash-agility-data.h */,
+ DCE2341620A3D4B8009766A3 /* si-cms-hash-agility-data.c */,
);
name = secitem;
path = Regressions/secitem;
DCD067FB1D8CDF7E007602F1 /* quarantine++.cpp */,
DCD067FC1D8CDF7E007602F1 /* dirscanner.h */,
DCD067FD1D8CDF7E007602F1 /* dirscanner.cpp */,
+ A6B1BA78207BD9D400F1E099 /* notarization.cpp */,
+ A6B1BA79207BD9D400F1E099 /* notarization.h */,
);
name = "Local Utilities";
sourceTree = "<group>";
isa = PBXGroup;
children = (
D4BEECE61E93093A00F76D1A /* trustd.c */,
- D43DBED51E99D17100C04AEA /* asynchttp.c */,
- D43DBED61E99D17100C04AEA /* asynchttp.h */,
D43DBED71E99D17100C04AEA /* nameconstraints.c */,
D43DBED81E99D17100C04AEA /* nameconstraints.h */,
D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */,
D43DBEDE1E99D17200C04AEA /* policytree.h */,
D43DBEDF1E99D17200C04AEA /* SecCAIssuerCache.c */,
D43DBEE01E99D17200C04AEA /* SecCAIssuerCache.h */,
- D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.c */,
+ D43DBEE11E99D17200C04AEA /* SecCAIssuerRequest.m */,
D43DBEE21E99D17200C04AEA /* SecCAIssuerRequest.h */,
D43DBEE31E99D17200C04AEA /* SecCertificateServer.c */,
D43DBEE41E99D17200C04AEA /* SecCertificateServer.h */,
D43DBEF81E99D17300C04AEA /* SecTrustServer.h */,
D43DBEF91E99D17300C04AEA /* SecTrustStoreServer.c */,
D43DBEFA1E99D17300C04AEA /* SecTrustStoreServer.h */,
+ D4961BBD2079423300F16DA7 /* TrustURLSessionDelegate.m */,
+ D4961BC52079426000F16DA7 /* TrustURLSessionDelegate.h */,
D4ADA30E1E2B1E650031CEA3 /* trustd-Info.plist */,
DCE4E85E1D7A585300AFB96E /* macOS */,
DCE4E85D1D7A584D00AFB96E /* iOS */,
E7FCBE401314471B000DE34E /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 0C9FB40120D8729A00864612 /* CoreCDP.framework */,
+ DC63D70920B3933000D088AD /* libOpenScriptingUtil.tbd */,
+ DC63D70220B3930700D088AD /* libxar.tbd */,
+ D4911167209558900066A1E4 /* CoreData.framework */,
+ 4771D9A1209B7C3900BA9772 /* Accounts.framework */,
+ 4771D99F209B7C2600BA9772 /* Security.framework */,
+ 4C47FA8D20A51DC700384CB6 /* AppleFSCompression.framework */,
5A94C6D4203CC2590066E391 /* AuthKit.framework */,
5A94C6D1203CC1C60066E391 /* AOSAccountsLite.framework */,
+ 091B396D2063B64A00ECAB6F /* RemoteServiceDiscovery.framework */,
477A1F4C20320E4900ACD81D /* Accounts.framework */,
EB49B2DE202DF286003F34A0 /* CoreFollowUpUI.framework */,
EB49B2DC202DF251003F34A0 /* libbsm.tbd */,
EB49B2CE202DF111003F34A0 /* CoreFollowUp.framework */,
D4119E72202BDF2B0048587B /* libz.tbd */,
- 472339681FD7156700CB6A72 /* CoreCDP.framework */,
472339611FD7155C00CB6A72 /* libprequelite.dylib */,
+ 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */,
+ 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */,
47D1838B1FB3827700CFCD89 /* OCMock.framework */,
4727FBE81F9921D00003AE36 /* libACM.a */,
4727FBE61F9921890003AE36 /* ApplePushService.framework */,
DCE4E8141D7A4E6F00AFB96E /* CFNetwork.framework */,
4C8A38C817B93DF10001B4C0 /* CloudServices.framework */,
DCE4E8FE1D7F3A2300AFB96E /* Cocoa.framework */,
- DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */,
5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */,
DC1789241D7799CD00B50D50 /* CoreFoundation.framework */,
E7FCBE451314471B000DE34E /* CoreGraphics.framework */,
name = Frameworks;
sourceTree = "<group>";
};
+ EB056E3F1FE5E390000A771E /* DeviceSimulator */ = {
+ isa = PBXGroup;
+ children = (
+ EBCE165C1FE6F4CE002E7CCC /* DeviceSimulator-Entitlements.plist */,
+ EB056E411FE5E390000A771E /* DeviceSimulator.h */,
+ EB056E421FE5E390000A771E /* DeviceSimulator.m */,
+ EB056E441FE5E390000A771E /* DeviceSimulatorMain.m */,
+ EB056E401FE5E390000A771E /* DeviceSimulatorProtocol.h */,
+ EB056E461FE5E391000A771E /* Info.plist */,
+ );
+ path = DeviceSimulator;
+ sourceTree = "<group>";
+ };
+ EB05C4F21FE5E48B00D68712 /* MultiDeviceSimulatorTests */ = {
+ isa = PBXGroup;
+ children = (
+ 4885DCAB207FF0780071FB7B /* ClientInfoByNotification.m */,
+ EB05C4F31FE5E48B00D68712 /* MultiDeviceSimulatorTests.m */,
+ EBCE165E1FE7313C002E7CCC /* MultiDeviceNetworking.h */,
+ EBCE165F1FE7313C002E7CCC /* MultiDeviceNetworking.m */,
+ EBCE16611FE73327002E7CCC /* MultiDeviceNetworkingProtocol.h */,
+ EB05C4F51FE5E48B00D68712 /* Info.plist */,
+ );
+ path = MultiDeviceSimulatorTests;
+ sourceTree = "<group>";
+ };
EB0BC9641C3C792E00785842 /* secedumodetest */ = {
isa = PBXGroup;
children = (
name = Modules;
sourceTree = "<group>";
};
+ EB81D0CB1FE5838B00FD7F16 /* MultiDeviceSimulator */ = {
+ isa = PBXGroup;
+ children = (
+ EB05C4F21FE5E48B00D68712 /* MultiDeviceSimulatorTests */,
+ EB056E3F1FE5E390000A771E /* DeviceSimulator */,
+ );
+ path = MultiDeviceSimulator;
+ sourceTree = "<group>";
+ };
EB9C1D7C1BDFD0E100F89272 /* secbackupntest */ = {
isa = PBXGroup;
children = (
isa = PBXGroup;
children = (
EB9C1DAD1BDFD49400F89272 /* Security.plist */,
+ EBE202752092913500B48020 /* SecurityInduceLowDisk.plist */,
EB3A8DD71BEEC4D6001A89AA /* Security_edumode.plist */,
EB2D549F1F02A25700E46890 /* SecAtomicFile */,
EB9C1D7C1BDFD0E100F89272 /* secbackupntest */,
EB425CCC1C6584A9000ECE53 /* secbackuptest */,
+ DAE40BD620CF3F04002D5674 /* secitemcanarytest */,
EB0BC9641C3C792E00785842 /* secedumodetest */,
EBCF73CC1CE45F3F00BED7CA /* secitemfunctionality */,
BED208E31EDF95BB00753952 /* manifeststresstest */,
name = secitemnotifications;
sourceTree = "<group>";
};
+ EBC73F44209A0BB200AE3350 /* xcscripts */ = {
+ isa = PBXGroup;
+ children = (
+ EBC73F4A209A0BEF00AE3350 /* install-test-framework.sh */,
+ );
+ name = xcscripts;
+ sourceTree = "<group>";
+ };
EBCF73CC1CE45F3F00BED7CA /* secitemfunctionality */ = {
isa = PBXGroup;
children = (
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 4718AE9D205B39C40068EC3F /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4718AE9E205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */,
+ 4718AE9F205B39C40068EC3F /* CKKSCondition.h in Headers */,
+ 4718AEA0205B39C40068EC3F /* CKKSScanLocalItemsOperation.h in Headers */,
+ 4718AEA1205B39C40068EC3F /* CKKSNotifier.h in Headers */,
+ 4718AEA2205B39C40068EC3F /* CKKSGroupOperation.h in Headers */,
+ 4718AEA3205B39C40068EC3F /* CKKSRateLimiter.h in Headers */,
+ 4718AEA4205B39C40068EC3F /* SecDbKeychainSerializedItemV7.h in Headers */,
+ 4718AEA5205B39C40068EC3F /* OTCloudStore.h in Headers */,
+ 4718AEA6205B39C40068EC3F /* CKKSResultOperation.h in Headers */,
+ 4718AEA7205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.h in Headers */,
+ 4718AEA8205B39C40068EC3F /* CKKSViewManager.h in Headers */,
+ 4718AEA9205B39C40068EC3F /* CKKSRecordHolder.h in Headers */,
+ 4718AEAA205B39C40068EC3F /* CKKSOutgoingQueueOperation.h in Headers */,
+ 4718AEAB205B39C40068EC3F /* CKKSSynchronizeOperation.h in Headers */,
+ 4718AEAC205B39C40068EC3F /* OTControl.h in Headers */,
+ 4718AEAD205B39C40068EC3F /* SOSChangeTracker.h in Headers */,
+ 4718AEAE205B39C40068EC3F /* CKKSAnalytics.h in Headers */,
+ 4718AEAF205B39C40068EC3F /* SOSEngine.h in Headers */,
+ 4718AEB0205B39C40068EC3F /* SecDbKeychainItem.h in Headers */,
+ 4718AEB1205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.h in Headers */,
+ 4718AEB2205B39C40068EC3F /* SecDbQuery.h in Headers */,
+ 4718AEB3205B39C40068EC3F /* SecCDKeychain.h in Headers */,
+ 4718AEB4205B39C40068EC3F /* CKKSMirrorEntry.h in Headers */,
+ 4718AEB5205B39C40068EC3F /* CloudKitCategories.h in Headers */,
+ 4718AEB6205B39C40068EC3F /* CKKSDeviceStateEntry.h in Headers */,
+ 4718AEB7205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.h in Headers */,
+ 4718AEB8205B39C40068EC3F /* CKKSCKAccountStateTracker.h in Headers */,
+ 4718AEB9205B39C40068EC3F /* CKKSZoneStateEntry.h in Headers */,
+ 4718AEBA205B39C40068EC3F /* CKKSTLKShare.h in Headers */,
+ 4718AEBB205B39C40068EC3F /* SecItemDataSource.h in Headers */,
+ 4718AEBC205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */,
+ 4718AEBD205B39C40068EC3F /* SecDbKeychainSerializedMetadata.h in Headers */,
+ 4718AEBE205B39C40068EC3F /* CKKSZoneChangeFetcher.h in Headers */,
+ 4718AEBF205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.h in Headers */,
+ 4718AEC0205B39C40068EC3F /* SFPublicKey+SPKI.h in Headers */,
+ 4718AEC1205B39C40068EC3F /* CKKSIncomingQueueEntry.h in Headers */,
+ 4718AEC2205B39C40068EC3F /* SecItemDb.h in Headers */,
+ 4718AEC3205B39C40068EC3F /* CKKSFixups.h in Headers */,
+ 4718AEC4205B39C40068EC3F /* CKKSControl.h in Headers */,
+ 4718AEC5205B39C40068EC3F /* SecItemSchema.h in Headers */,
+ 4718AEC6205B39C40068EC3F /* CKKSLocalSynchronizeOperation.h in Headers */,
+ 4718AEC7205B39C40068EC3F /* SecKeybagSupport.h in Headers */,
+ 4718AEC8205B39C40068EC3F /* CKKSNewTLKOperation.h in Headers */,
+ 4718AEC9205B39C40068EC3F /* iCloudTrace.h in Headers */,
+ 4718AECA205B39C40068EC3F /* CKKSControlProtocol.h in Headers */,
+ 4718AECB205B39C40068EC3F /* SFKeychainServer.h in Headers */,
+ 4718AECC205B39C40068EC3F /* CKKSOutgoingQueueEntry.h in Headers */,
+ 4718AECD205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.h in Headers */,
+ 4718AECE205B39C40068EC3F /* CKKSNearFutureScheduler.h in Headers */,
+ 4718AECF205B39C40068EC3F /* OTManager.h in Headers */,
+ 4718AED0205B39C40068EC3F /* CKKSHealTLKSharesOperation.h in Headers */,
+ 4718AED1205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.h in Headers */,
+ 4718AED2205B39C40068EC3F /* OTControlProtocol.h in Headers */,
+ 4718AED3205B39C40068EC3F /* CKKSAPSReceiver.h in Headers */,
+ 4718AED4205B39C40068EC3F /* NSOperationCategories.h in Headers */,
+ 4718AED5205B39C40068EC3F /* CKKSKey.h in Headers */,
+ 4718AED6205B39C40068EC3F /* CKKSCurrentItemPointer.h in Headers */,
+ 4718AED7205B39C40068EC3F /* CKKSControlServer.h in Headers */,
+ 4718AED8205B39C40068EC3F /* CKKSSIV.h in Headers */,
+ 4718AED9205B39C40068EC3F /* SFKeychainControlManager.h in Headers */,
+ 4718AEDA205B39C40068EC3F /* SecDbKeychainSerializedSecretData.h in Headers */,
+ 4718AEDB205B39C40068EC3F /* CKKSItem.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
4C32C0AA0A4975F6002891BD /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
4C999BA60AB5F0BB0010451D /* NtlmGenerator.h in Headers */,
4C999BA80AB5F0BB0010451D /* ntlmBlobPriv.h in Headers */,
EB5E3BCC2003C67A00F1631B /* SecSignpost.h in Headers */,
+ 09A3B9D81F8267BB00C5C324 /* SecKeyProxy.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 */,
+ 5A4E381B207529670047F40F /* SecProtocol.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 */,
4C12828D0BB4957D00985BB0 /* SecTrustSettingsPriv.h in Headers */,
+ DCD45355209A5B260086CBFC /* si-cms-signing-identity-p12.h in Headers */,
CDDE9BD11729ABFA0013B0E8 /* SecPasswordGenerate.h in Headers */,
4C7072860AC9EA4F007CC205 /* SecKey.h in Headers */,
476541651F339F6300413F65 /* SecdWatchdog.h in Headers */,
4CD3BA621106FF4D00BE8B75 /* SecECKey.h in Headers */,
4C6416F10BB357D5001C83FD /* SecInternal.h in Headers */,
443381ED18A3D83100215606 /* SecAccessControl.h in Headers */,
+ 5AFCF32E20746DA70010D4B5 /* SecProtocolObject.h in Headers */,
4723C9C61F152EC00082882F /* SFSQLite.h in Headers */,
4C1B442D0BB9CAF900461B82 /* SecTrustStore.h in Headers */,
DC3C7AB81D838C6F00F6A832 /* oidsalg.h in Headers */,
4C2F81D50BF121D2003C4F77 /* SecRandom.h in Headers */,
ACBAF6EE1E941AE00007BA2F /* transform_regressions.h in Headers */,
7940D4130C3ACF9000FDB5D8 /* SecDH.h in Headers */,
+ DCC5860320BF8A98005C7269 /* SecBase.h in Headers */,
790850F70CA88AE10083CC4D /* securityd_client.h in Headers */,
795CA9CE0D38435E00BAE6A2 /* p12pbegen.h in Headers */,
79EF5B730D3D6AFE009F5270 /* p12import.h in Headers */,
4723C9C21F152EB50082882F /* SFObjCType.h in Headers */,
4CE7EA791AEAF39C0067F5BD /* SecItemBackup.h in Headers */,
222F23A01DAC1603007ACB90 /* SecTaskPriv.h in Headers */,
+ 5AFCF32B20746BC80010D4B5 /* SecProtocolMetadata.h in Headers */,
DC3C7AB51D838C1300F6A832 /* SecAsn1Templates.h in Headers */,
6CE365511FA100FE0012F6AB /* SFAnalyticsSampler.h in Headers */,
79EF5B6E0D3D6A31009F5270 /* SecImportExport.h in Headers */,
4723C9CA1F152ECE0082882F /* SFSQLiteStatement.h in Headers */,
+ 5AFCF32920746BC20010D4B5 /* SecProtocolOptions.h in Headers */,
4CCE0ADA0D41797400DDBB21 /* SecIdentityPriv.h in Headers */,
4CCE0ADE0D4179E500DDBB21 /* SecBasePriv.h in Headers */,
DCD7EE991F4F4E03007D9804 /* ocspTemplates.h in Headers */,
4C87F3A80D611C26000E7104 /* SecTrustPriv.h in Headers */,
79BDD3C20D60DB84000D84D3 /* SecCMS.h in Headers */,
+ 5AC6BFAB2077CD310051737D /* SecProtocolTypes.h in Headers */,
DC2C5F4B1F0D935200FEBDA7 /* CKKSControlProtocol.h in Headers */,
107226D30D91DB32003CF14F /* SecTask.h in Headers */,
4C7CE5700DC7DC6600AE53FC /* SecEntitlements.h in Headers */,
DC3C7AB21D838B6D00F6A832 /* SecureTransport.h in Headers */,
6CBF65391FA147E500A68667 /* SFAnalyticsActivityTracker.h in Headers */,
4AF7FFFE15AFB73800B9D400 /* SecOTRDHKey.h in Headers */,
+ DCFE9C8920EC1F3B00EB6BAC /* SOSControlHelper.h in Headers */,
4AF7FFFF15AFB73800B9D400 /* SecOTRErrors.h in Headers */,
6C73F48F2006B910003D5D63 /* SOSAnalytics.h in Headers */,
DCD7EE9A1F4F5156007D9804 /* oidsocsp.h in Headers */,
4AF7000115AFB73800B9D400 /* SecOTRMath.h in Headers */,
4AF7000315AFB73800B9D400 /* SecOTRPacketData.h in Headers */,
DC3C7AB31D838BC300F6A832 /* CipherSuite.h in Headers */,
+ 6C814A4C2050B4B600CB391B /* LocalKeychainAnalytics.h in Headers */,
4AF7000415AFB73800B9D400 /* SecOTRPackets.h in Headers */,
6C8CE6C11FA248DA0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */,
DC3C7ABA1D838C9F00F6A832 /* sslTypes.h in Headers */,
724340BA1ED3FEC800F8F566 /* SecSMIME.h in Headers */,
22A23B3E1E3AAC9800C41830 /* SecRequirement.h in Headers */,
DC9C95BE1F79DC5F000D19E5 /* CKKSControl.h in Headers */,
- 0CBFEACC200FCD33009A60E9 /* SFTransactionMetric.h in Headers */,
+ 0CBFEACC200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */,
DC3C7AB61D838C2D00F6A832 /* SecAsn1Types.h in Headers */,
+ D43D8B2D20AB8A54005BEEC4 /* Security.apinotes in Headers */,
DC3C73551D837B2C00F6A832 /* SOSPeerInfoPriv.h in Headers */,
+ AA44E0DE2032519E001EA371 /* SecProtocolPriv.h in Headers */,
D46246A31F9AE59E00D63882 /* oids.h in Headers */,
DCD7EEA41F4F58D7007D9804 /* SecLogging.h in Headers */,
47A05B161FDB5D9E00D0816E /* SFKeychainControl.h in Headers */,
EB7AE6F91E86DAD200B80B15 /* SecPLWrappers.h in Headers */,
DC0BCD871D8C6A1E00070CB0 /* SecIOFormat.h in Headers */,
DC0BCD8A1D8C6A1E00070CB0 /* array_size.h in Headers */,
+ DA5B871C2065A8440093F083 /* SecAutorelease.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DC17877C1D77919500B50D50 /* SecBasePriv.h in Headers */,
0C8BBF231FCB4F1800580909 /* OTControlProtocol.h in Headers */,
DC1787741D77915500B50D50 /* SecBreadcrumb.h in Headers */,
+ 6CB420AB2051FDE000FF2D44 /* LocalKeychainAnalytics.h in Headers */,
DC1787761D77916600B50D50 /* SecCFAllocator.h in Headers */,
DC1787111D778FA900B50D50 /* SecCMS.h in Headers */,
DC17859F1D778C8D00B50D50 /* SecCertificate.h in Headers */,
DC1787191D778FAA00B50D50 /* SecCmsEnvelopedData.h in Headers */,
DC17871A1D778FAA00B50D50 /* SecCmsMessage.h in Headers */,
DC17871B1D778FAA00B50D50 /* SecCmsRecipientInfo.h in Headers */,
+ DCFE9C8F20EC1F3C00EB6BAC /* SOSControlHelper.h in Headers */,
DC17871C1D778FAA00B50D50 /* SecCmsSignedData.h in Headers */,
DC17871D1D778FAA00B50D50 /* SecCmsSignerInfo.h in Headers */,
DC1785891D778B8000B50D50 /* SecCode.h in Headers */,
DC1787511D7790A500B50D50 /* SecCodePriv.h in Headers */,
DC1787521D7790A500B50D50 /* SecCodeSigner.h in Headers */,
DC1785301D778A0100B50D50 /* SecCustomTransform.h in Headers */,
- 0CBFEACD200FCD33009A60E9 /* SFTransactionMetric.h in Headers */,
+ 0CBFEACD200FCD33009A60E9 /* SFSignInAnalytics.h in Headers */,
DC1787771D77916A00B50D50 /* SecDH.h in Headers */,
DC1785311D778A0100B50D50 /* SecDecodeTransform.h in Headers */,
6CE365561FA101740012F6AB /* SFAnalyticsSQLiteStore.h in Headers */,
DC1787261D778FDE00B50D50 /* SecManifest.h in Headers */,
DC1786F91D778F2500B50D50 /* SecNullTransform.h in Headers */,
DC17873D1D77903700B50D50 /* SecPassword.h in Headers */,
+ 5AFCF32F20746DA70010D4B5 /* SecProtocolObject.h in Headers */,
DC1787791D77917700B50D50 /* SecPasswordGenerate.h in Headers */,
DC1785941D778BF400B50D50 /* SecPolicy.h in Headers */,
DC17877D1D77919B00B50D50 /* SecPolicyPriv.h in Headers */,
DC1785351D778A0100B50D50 /* SecReadTransform.h in Headers */,
DC17873F1D77903700B50D50 /* SecRecoveryPassword.h in Headers */,
6CE3654C1FA100D10012F6AB /* SFAnalytics.h in Headers */,
+ 09A3B9D91F8267BB00C5C324 /* SecKeyProxy.h in Headers */,
DC17858B1D778B8000B50D50 /* SecRequirement.h in Headers */,
DC1787551D7790A500B50D50 /* SecRequirementPriv.h in Headers */,
DC17871E1D778FAA00B50D50 /* SecSMIME.h in Headers */,
DC1785361D778A0100B50D50 /* SecSignVerifyTransform.h in Headers */,
DC17858C1D778B8000B50D50 /* SecStaticCode.h in Headers */,
DC1787561D7790A500B50D50 /* SecStaticCodePriv.h in Headers */,
+ 5A4E381C207529680047F40F /* SecProtocol.h in Headers */,
DC17859E1D778C8800B50D50 /* SecTask.h in Headers */,
DC1785371D778A0100B50D50 /* SecTransform.h in Headers */,
DC1786FA1D778F2500B50D50 /* SecTransformInternal.h in Headers */,
DC17876B1D77911D00B50D50 /* certExtensionTemplates.h in Headers */,
DC1785971D778C0800B50D50 /* certextensions.h in Headers */,
DC17875C1D7790CE00B50D50 /* checkpw.h in Headers */,
+ AA44E0DF2032519F001EA371 /* SecProtocolPriv.h in Headers */,
DC17876C1D77911D00B50D50 /* csrTemplates.h in Headers */,
DC17856C1D778B4A00B50D50 /* cssm.h in Headers */,
DC17856D1D778B4A00B50D50 /* cssmaci.h in Headers */,
DC17856E1D778B4A00B50D50 /* cssmapi.h in Headers */,
DC1785991D778C5300B50D50 /* cssmapple.h in Headers */,
DC1787431D77906C00B50D50 /* cssmapplePriv.h in Headers */,
+ 5AFCF32C20746BC90010D4B5 /* SecProtocolMetadata.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 */,
+ 5AC6BFAC2077CD310051737D /* SecProtocolTypes.h in Headers */,
+ 47A91562201A43BA00FF8F46 /* SecSharedCredential.h in Headers */,
DC337B1F1EA04E2100B3A1F0 /* SecBase64.h in Headers */,
DC1785731D778B4A00B50D50 /* cssmerr.h in Headers */,
DC1785741D778B4A00B50D50 /* cssmkrapi.h in Headers */,
DC1785761D778B4A00B50D50 /* cssmspi.h in Headers */,
DC1785771D778B4A00B50D50 /* cssmtpi.h in Headers */,
DC1785781D778B4A00B50D50 /* cssmtype.h in Headers */,
+ 5AFCF32A20746BC30010D4B5 /* SecProtocolOptions.h in Headers */,
DC17877B1D77918C00B50D50 /* der_plist.h in Headers */,
DC1785791D778B4A00B50D50 /* eisl.h in Headers */,
DC17857A1D778B4A00B50D50 /* emmspi.h in Headers */,
4723C9CB1F152ECF0082882F /* SFSQLiteStatement.h in Headers */,
6CE365501FA100F20012F6AB /* SFAnalyticsDefines.h in Headers */,
6CE365521FA100FF0012F6AB /* SFAnalyticsSampler.h in Headers */,
+ D43D8B2C20AB8A48005BEEC4 /* Security.apinotes in Headers */,
4723C9C31F152EB60082882F /* SFObjCType.h in Headers */,
DCB3323C1F46833E00178C30 /* SecLogging.h in Headers */,
DC9C95BD1F79DC5A000D19E5 /* CKKSControl.h in Headers */,
DC222C681E034D1F00B09171 /* SecDbQuery.h in Headers */,
DCEA5D561E2826DB0089CF55 /* CKKSSIV.h in Headers */,
DC222C691E034D1F00B09171 /* CKKSMirrorEntry.h in Headers */,
+ 470D96721FCDE55B0065FE90 /* SecCDKeychain.h in Headers */,
DC222C6A1E034D1F00B09171 /* CKKSZoneStateEntry.h in Headers */,
DC94BCCB1F10448600E07CEB /* CloudKitCategories.h in Headers */,
DCFE1C281F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */,
DCEA5D861E2F14810089CF55 /* CKKSAPSReceiver.h in Headers */,
DC222C711E034D1F00B09171 /* CKKSOutgoingQueueEntry.h in Headers */,
DCF7A8A11F04502400CABE89 /* CKKSControlProtocol.h in Headers */,
+ 47FF17271FD60ACA00875565 /* SFKeychainServer.h in Headers */,
DCCD88E91E42622200F5AA71 /* CKKSGroupOperation.h in Headers */,
DC15F7671E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */,
DCD6C4B31EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */,
DC52E7E41D80BE6E00B0A59C /* SecDbKeychainItem.h in Headers */,
DC7A17ED1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h in Headers */,
DC52E7E31D80BDA600B0A59C /* SecDbQuery.h in Headers */,
+ 470D96711FCDE55B0065FE90 /* SecCDKeychain.h in Headers */,
DC378B2D1DEF9DF000A3DAFA /* CKKSMirrorEntry.h in Headers */,
DC94BCCA1F10448600E07CEB /* CloudKitCategories.h in Headers */,
DCFE1C271F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */,
DCD662F51E329B6800188186 /* CKKSNewTLKOperation.h in Headers */,
DC52E7EB1D80BE9B00B0A59C /* iCloudTrace.h in Headers */,
DCF7A8A01F04502400CABE89 /* CKKSControlProtocol.h in Headers */,
+ 47FF17261FD60ACA00875565 /* SFKeychainServer.h in Headers */,
DC6D2C931DD2836500BE372D /* CKKSOutgoingQueueEntry.h in Headers */,
DC15F7661E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */,
DCD6C4B21EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */,
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 48FE669720E6E69D00FAEF17 /* SOSAuthKitHelpers.h in Headers */,
DCB3325A1F478C4100178C30 /* SOSUserKeygen.h in Headers */,
DC52E9071D80C3B300B0A59C /* SOSARCDefines.h in Headers */,
0C48990B1E0E0FF300C6CF70 /* SOSTransportCircleCK.h in Headers */,
DC52E9231D80C47100B0A59C /* SOSTransportCircleKVS.h in Headers */,
DC52E92C1D80C4AF00B0A59C /* SOSTransportKeyParameter.h in Headers */,
DC52E9241D80C47900B0A59C /* SOSTransportMessage.h in Headers */,
- DC52E9191D80C42F00B0A59C /* SOSTransportMessageIDS.h in Headers */,
DC52E9321D80C4DF00B0A59C /* SOSTransportMessageKVS.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
buildActionMask = 2147483647;
files = (
DC0B62281D90974300D43BCB /* si-25-cms-skid.h in Headers */,
+ DCE2341720A3D4B8009766A3 /* si-cms-hash-agility-data.h in Headers */,
D487FBBA1DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
DCD068471D8CDF7E007602F1 /* reqparser.h in Headers */,
DCD069061D8CDFFE007602F1 /* CommonASTWithHiddenTokens.hpp in Headers */,
DCD068451D8CDF7E007602F1 /* reqinterp.h in Headers */,
+ A6B1BA82207BDCB200F1E099 /* notarization.h in Headers */,
DCD069151D8CDFFF007602F1 /* RefCount.hpp in Headers */,
DCD068431D8CDF7E007602F1 /* reqreader.h in Headers */,
DCD069191D8CDFFF007602F1 /* TokenBuffer.hpp in Headers */,
0CE760541E13155100B4381E /* SOSAccountTrustClassic+Circle.h in Headers */,
DCD8A15C1E09EE0F00E4FA0A /* SOSBackupSliceKeyBag.h in Headers */,
DCD8A15D1E09EE0F00E4FA0A /* SOSCircle.h in Headers */,
- 0C4899271E0F399B00C6CF70 /* SOSAccountTrustOctagon.h in Headers */,
DCD8A15F1E09EE0F00E4FA0A /* SOSCirclePriv.h in Headers */,
DCD8A1601E09EE0F00E4FA0A /* SOSCircleRings.h in Headers */,
DCD8A1611E09EE0F00E4FA0A /* SOSCircleV2.h in Headers */,
DCD8A1651E09EE0F00E4FA0A /* SOSCloudKeychainConstants.h in Headers */,
DCD8A1661E09EE0F00E4FA0A /* SOSRingRecovery.h in Headers */,
0C4899231E0F386900C6CF70 /* SOSAccountTrustClassic.h in Headers */,
- DCD8A1E11E09F76D00E4FA0A /* SOSPeerInfoSecurityProperties.h in Headers */,
DCD8A16C1E09EE0F00E4FA0A /* SOSFullPeerInfo.h in Headers */,
DCD8A1DD1E09F73F00E4FA0A /* SOSPeerInfoDER.h in Headers */,
DCD8A16D1E09EE0F00E4FA0A /* SOSGenCount.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ EBCE16631FE7366D002E7CCC /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EBCE16681FE736AD002E7CCC /* DeviceSimulatorProtocol.h in Headers */,
+ EBCE16641FE73679002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EBCE16651FE7368C002E7CCC /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EBCE16661FE736A1002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */,
+ EBCE16671FE736A5002E7CCC /* DeviceSimulatorProtocol.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXHeadersBuildPhase section */
/* Begin PBXLegacyTarget section */
productReference = 0C8BBF081FCB446400580909 /* otctl */;
productType = "com.apple.product-type.tool";
};
+ 0C9AEEAB20783FBB00BF6237 /* SignInAnalyticsTests_osx */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 0C9AEEB420783FBB00BF6237 /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_osx" */;
+ buildPhases = (
+ 0C9AEEAE20783FBB00BF6237 /* Sources */,
+ 0C9AEEB020783FBB00BF6237 /* Frameworks */,
+ 0C9AEEB320783FBB00BF6237 /* Embed OCMock */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 0C9AEEBA20783FE000BF6237 /* PBXTargetDependency */,
+ );
+ name = SignInAnalyticsTests_osx;
+ productName = CKKSTests;
+ productReference = 0C9AEEB720783FBB00BF6237 /* SignInAnalyticsTests_osx.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 0CF406042072E3E3003D6A7F /* SignInAnalyticsTests_ios */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 0CF4064D2072E3E3003D6A7F /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_ios" */;
+ buildPhases = (
+ 0CF406112072E3E3003D6A7F /* Sources */,
+ 0CF406342072E3E3003D6A7F /* Frameworks */,
+ 0CF4064A2072E3E3003D6A7F /* Embed OCMock */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 0C5663EE20BE2E1A0035F362 /* PBXTargetDependency */,
+ 0C3E2EA92073F5C400F5B95B /* PBXTargetDependency */,
+ );
+ name = SignInAnalyticsTests_ios;
+ productName = CKKSTests;
+ productReference = 0CF406502072E3E3003D6A7F /* SignInAnalyticsTests_ios.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
225394AC1E3080A600D3CD9B /* security_codesigning_ios */ = {
isa = PBXNativeTarget;
buildConfigurationList = 225394B11E3080A600D3CD9B /* Build configuration list for PBXNativeTarget "security_codesigning_ios" */;
productReference = 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */;
productType = "com.apple.product-type.library.static";
};
+ 3DD1FEF5201C07F30086D049 /* SecureTransport_macos_tests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_macos_tests" */;
+ buildPhases = (
+ 3DD1FF02201C07F30086D049 /* Sources */,
+ 3DD1FF2F201C07F30086D049 /* Frameworks */,
+ 3DD1FFD6201FF7930086D049 /* CopyFiles */,
+ 3DD1FF49201C07F30086D049 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 3DD1FF50201C09CD0086D049 /* PBXTargetDependency */,
+ 3DD1FEF8201C07F30086D049 /* PBXTargetDependency */,
+ );
+ name = SecureTransport_macos_tests;
+ productName = CKKSTests;
+ productReference = 3DD1FF4D201C07F30086D049 /* SecureTransport_macos_tests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 3DD1FFAC201FDB1D0086D049 /* SecureTransport_ios_tests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_ios_tests" */;
+ buildPhases = (
+ 3DD1FFB3201FDB1D0086D049 /* Sources */,
+ 3DD1FFC3201FDB1D0086D049 /* Frameworks */,
+ 3DD1FFD3201FF72C0086D049 /* CopyFiles */,
+ 3DD1FFCC201FDB1D0086D049 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 3DD1FFAF201FDB1D0086D049 /* PBXTargetDependency */,
+ 3DD1FFB1201FDB1D0086D049 /* PBXTargetDependency */,
+ );
+ name = SecureTransport_ios_tests;
+ productName = CKKSTests;
+ productReference = 3DD1FFD0201FDB1D0086D049 /* SecureTransport_ios_tests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */ = {
isa = PBXNativeTarget;
buildConfigurationList = 438169381B4EDCBD00C54D58 /* Build configuration list for PBXNativeTarget "SOSCCAuthPlugin" */;
productReference = 470415CF1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */;
productType = "com.apple.product-type.tool";
};
+ 4718AE02205B39620068EC3F /* securityd_bridge */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4718AE2A205B39620068EC3F /* Build configuration list for PBXNativeTarget "securityd_bridge" */;
+ buildPhases = (
+ 4718AE0F205B39620068EC3F /* Sources */,
+ 4718AE17205B39620068EC3F /* Frameworks */,
+ 4718AE26205B39620068EC3F /* CopyFiles */,
+ 4718AE28205B39620068EC3F /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 4718AEE6205B3A350068EC3F /* PBXTargetDependency */,
+ 4718AE03205B39620068EC3F /* PBXTargetDependency */,
+ 4718AE05205B39620068EC3F /* PBXTargetDependency */,
+ 4718AE09205B39620068EC3F /* PBXTargetDependency */,
+ 4718AE0B205B39620068EC3F /* PBXTargetDependency */,
+ 4718AE0D205B39620068EC3F /* PBXTargetDependency */,
+ );
+ name = securityd_bridge;
+ productName = securityd;
+ productReference = 4718AE2D205B39620068EC3F /* securityd */;
+ productType = "com.apple.product-type.tool";
+ };
+ 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4718AEDF205B39C40068EC3F /* Build configuration list for PBXNativeTarget "libsecurityd_bridge" */;
+ buildPhases = (
+ 4718AE2F205B39C40068EC3F /* Sources */,
+ 4718AE9C205B39C40068EC3F /* Frameworks */,
+ 4718AE9D205B39C40068EC3F /* Headers */,
+ );
+ buildRules = (
+ 4718AEDE205B39C40068EC3F /* PBXBuildRule */,
+ );
+ dependencies = (
+ );
+ name = libsecurityd_bridge;
+ productName = libsecurity;
+ productReference = 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */;
+ productType = "com.apple.product-type.library.static";
+ };
4727FBB61F9918580003AE36 /* secdxctests_ios */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4727FBC31F9918590003AE36 /* Build configuration list for PBXNativeTarget "secdxctests_ios" */;
buildPhases = (
4727FBB31F9918580003AE36 /* Sources */,
4727FBB41F9918580003AE36 /* Frameworks */,
- 4727FBB51F9918580003AE36 /* Resources */,
+ 090585D120AEF9FE00BB7490 /* Install OCMock framework */,
);
buildRules = (
);
dependencies = (
+ 47A6FC6A206B461700BD6C54 /* PBXTargetDependency */,
47DE88D91FA7ADBB00DD3254 /* PBXTargetDependency */,
47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */,
- 47DE88D51FA7AD7000DD3254 /* PBXTargetDependency */,
47DE88CE1FA7AD6200DD3254 /* PBXTargetDependency */,
);
name = secdxctests_ios;
productReference = 47702B2E1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */;
productType = "com.apple.product-type.tool";
};
+ 4771D971209A755800BA9772 /* KeychainDataclassOwner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4771D97D209A755900BA9772 /* Build configuration list for PBXNativeTarget "KeychainDataclassOwner" */;
+ buildPhases = (
+ 4771D96E209A755800BA9772 /* Sources */,
+ 4771D96F209A755800BA9772 /* Frameworks */,
+ 4771D970209A755800BA9772 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = KeychainDataclassOwner;
+ productName = KeychainDataclassOwner;
+ productReference = 4771D972209A755800BA9772 /* KeychainDataclassOwner.bundle */;
+ productType = "com.apple.product-type.bundle";
+ };
478D426C1FD72A8100CAB645 /* secdxctests_mac */ = {
isa = PBXNativeTarget;
buildConfigurationList = 478D42991FD72A8100CAB645 /* Build configuration list for PBXNativeTarget "secdxctests_mac" */;
buildPhases = (
478D42751FD72A8100CAB645 /* Sources */,
478D427D1FD72A8100CAB645 /* Frameworks */,
- 478D42981FD72A8100CAB645 /* Resources */,
+ 090585D020AEF9D300BB7490 /* Install OCMock framework */,
);
buildRules = (
);
dependencies = (
+ 47A6FC6C206B462400BD6C54 /* PBXTargetDependency */,
DC34CD3620326C3B00302481 /* PBXTargetDependency */,
DC34CD3420326C3100302481 /* PBXTargetDependency */,
DC34CD2D20326C2C00302481 /* PBXTargetDependency */,
478D426D1FD72A8100CAB645 /* PBXTargetDependency */,
478D426F1FD72A8100CAB645 /* PBXTargetDependency */,
- 478D42711FD72A8100CAB645 /* PBXTargetDependency */,
478D42731FD72A8100CAB645 /* PBXTargetDependency */,
);
name = secdxctests_mac;
productReference = 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
+ 47C2F1822059CB680062DE30 /* KeychainResources */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 47C2F1872059CB690062DE30 /* Build configuration list for PBXNativeTarget "KeychainResources" */;
+ buildPhases = (
+ 47C2F17F2059CB680062DE30 /* Sources */,
+ 47C2F1802059CB680062DE30 /* Frameworks */,
+ 47C2F1812059CB680062DE30 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = KeychainResources;
+ productName = KeychainResources;
+ productReference = 47C2F1832059CB680062DE30 /* KeychainResources.bundle */;
+ productType = "com.apple.product-type.bundle";
+ };
47C51B831EEA657D0032D9E5 /* SecurityUnitTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 47C51B931EEA657D0032D9E5 /* Build configuration list for PBXNativeTarget "SecurityUnitTests" */;
buildPhases = (
6C46057A1F882B9B001421B6 /* Sources */,
6C46059B1F882B9B001421B6 /* Frameworks */,
+ 6C4F981E2075831300A3C5AB /* CopyFiles */,
);
buildRules = (
);
productReference = BEF88C301EAFFC3F00357577 /* TrustedPeersTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
- CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = CD276C2C1A83F60C003226BC /* Build configuration list for PBXNativeTarget "KeychainSyncingOverIDSProxy" */;
- buildPhases = (
- CD276C231A83F60C003226BC /* Sources */,
- CD276C241A83F60C003226BC /* Frameworks */,
- CDF91EA61AAE019800E88CF7 /* Install alloy plist */,
- 8E64DAF81C17BA620076C9DF /* Install launchd plist */,
- EB76B7561DCB0C6900C43FBC /* Install man8 page */,
- );
- buildRules = (
- );
- dependencies = (
- DC65E7331D8CB34000152EF0 /* PBXTargetDependency */,
- );
- name = KeychainSyncingOverIDSProxy;
- productName = KeychainSyncingOverIDSProxy;
- productReference = CD276C271A83F60C003226BC /* KeychainSyncingOverIDSProxy.bundle */;
- productType = "com.apple.product-type.bundle";
- };
D41257CE1E9410A300781F23 /* trustd_ios */ = {
isa = PBXNativeTarget;
buildConfigurationList = D41257D61E9410A300781F23 /* Build configuration list for PBXNativeTarget "trustd_ios" */;
productReference = DA30D6761DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater.bundle */;
productType = "com.apple.product-type.bundle";
};
+ DAE40BC520CF3E46002D5674 /* secitemcanarytest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DAE40BCB20CF3E46002D5674 /* Build configuration list for PBXNativeTarget "secitemcanarytest" */;
+ buildPhases = (
+ DAE40BC620CF3E46002D5674 /* Sources */,
+ DAE40BC820CF3E46002D5674 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = secitemcanarytest;
+ productName = secbackupntest;
+ productReference = DAE40BCE20CF3E47002D5674 /* secitemcanarytest */;
+ productType = "com.apple.product-type.tool";
+ };
DC0067921D87876F005AF8DB /* securityd_server_macos */ = {
isa = PBXNativeTarget;
buildConfigurationList = DC0067BD1D87876F005AF8DB /* Build configuration list for PBXNativeTarget "securityd_server_macos" */;
DC52E7741D80BC8000B0A59C /* Sources */,
DC52E7AD1D80BC8000B0A59C /* Frameworks */,
DC52E7AE1D80BC8000B0A59C /* Headers */,
- 6C0B0C4A1E253840007F95E5 /* CopyFiles */,
);
buildRules = (
DC9FD3201F85818000C8AAC8 /* PBXBuildRule */,
DC65E7661D8CB4C200152EF0 /* PBXTargetDependency */,
DC65E7681D8CB4CB00152EF0 /* PBXTargetDependency */,
DCE4E7D81D7A4B3500AFB96E /* PBXTargetDependency */,
+ DC193C6020CB4C9D009C1A0F /* PBXTargetDependency */,
DC65E76A1D8CB4D300152EF0 /* PBXTargetDependency */,
);
name = sectests_macos;
productReference = E7D847CE1C6BE9720025BB44 /* KeychainCircleTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
+ EB056E3D1FE5E390000A771E /* DeviceSimulator */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = EB056E4E1FE5E391000A771E /* Build configuration list for PBXNativeTarget "DeviceSimulator" */;
+ buildPhases = (
+ EBCE16631FE7366D002E7CCC /* Headers */,
+ EB056E3A1FE5E390000A771E /* Sources */,
+ EB056E3B1FE5E390000A771E /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DeviceSimulator;
+ productName = DeviceSimulator;
+ productReference = EB056E3E1FE5E390000A771E /* DeviceSimulator.xpc */;
+ productType = "com.apple.product-type.xpc-service";
+ };
+ EB05C4F01FE5E48A00D68712 /* MultiDeviceSimulatorTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = EB05C4FD1FE5E48B00D68712 /* Build configuration list for PBXNativeTarget "MultiDeviceSimulatorTests" */;
+ buildPhases = (
+ EBCE16651FE7368C002E7CCC /* Headers */,
+ EB05C4ED1FE5E48A00D68712 /* Sources */,
+ EB05C4EE1FE5E48A00D68712 /* Frameworks */,
+ EB05C4EF1FE5E48A00D68712 /* Resources */,
+ EBCE150D1FE63880002E7CCC /* Embedded XPC service */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ EBCE15101FE638A2002E7CCC /* PBXTargetDependency */,
+ );
+ name = MultiDeviceSimulatorTests;
+ productName = MultiDeviceSimulatorTests;
+ productReference = EB05C4F11FE5E48A00D68712 /* MultiDeviceSimulatorTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
EB0BC9361C3C791500785842 /* secedumodetest */ = {
isa = PBXNativeTarget;
buildConfigurationList = EB0BC93B1C3C791500785842 /* Build configuration list for PBXNativeTarget "secedumodetest" */;
buildPhases = (
EB49B2AA202D877F003F34A0 /* Sources */,
EB49B2AB202D877F003F34A0 /* Frameworks */,
- EB49B30E202FF484003F34A0 /* Embedded OCMock */,
+ EBC73F4B209A0C3400AE3350 /* Install OCMock framework */,
);
buildRules = (
);
4C35DB69094F906D002917C4 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 1000;
TargetAttributes = {
4381690B1B4EDCBD00C54D58 = {
CreatedOnToolsVersion = 7.0;
CreatedOnToolsVersion = 9.0;
ProvisioningStyle = Automatic;
};
+ 4771D971209A755800BA9772 = {
+ CreatedOnToolsVersion = 10.0;
+ ProvisioningStyle = Automatic;
+ };
478D426C1FD72A8100CAB645 = {
ProvisioningStyle = Automatic;
};
+ 47C2F1822059CB680062DE30 = {
+ CreatedOnToolsVersion = 10.0;
+ ProvisioningStyle = Automatic;
+ };
47C51B831EEA657D0032D9E5 = {
CreatedOnToolsVersion = 9.0;
};
+ 4809F7A42061B697003E72D0 = {
+ CreatedOnToolsVersion = 10.0;
+ ProvisioningStyle = Automatic;
+ };
5EBE24791B00CCAE0007DB0E = {
CreatedOnToolsVersion = 7.0;
};
CreatedOnToolsVersion = 9.0;
ProvisioningStyle = Automatic;
};
- CD276C261A83F60C003226BC = {
- CreatedOnToolsVersion = 7.0;
- };
D41257CE1E9410A300781F23 = {
CreatedOnToolsVersion = 9.0;
ProvisioningStyle = Automatic;
E7D847CD1C6BE9720025BB44 = {
CreatedOnToolsVersion = 7.3;
};
+ EB056E3D1FE5E390000A771E = {
+ CreatedOnToolsVersion = 9.3;
+ ProvisioningStyle = Automatic;
+ };
+ EB05C4F01FE5E48A00D68712 = {
+ CreatedOnToolsVersion = 9.3;
+ ProvisioningStyle = Automatic;
+ };
EB1055741E14DF430003C309 = {
CreatedOnToolsVersion = 8.2.1;
ProvisioningStyle = Automatic;
DCE4E8931D7F34F600AFB96E /* authd */,
DCE4E7F51D7A4DA800AFB96E /* secd */,
790851B50CA9859F0083CC4D /* securityd_ios */,
+ 4718AE02205B39620068EC3F /* securityd_bridge */,
DC5AC04F1D8352D900CF422C /* securityd_macos */,
6CAA8D1F1F842FB3007B6E03 /* securityuploadd */,
D41257CE1E9410A300781F23 /* trustd_ios */,
DCE4E82D1D7A57AE00AFB96E /* trustd_macos */,
52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */,
- CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */,
DC0BC5501D8B6D2D00070CB0 /* XPCKeychainSandboxCheck */,
DC0BC5631D8B6E3D00070CB0 /* XPCTimeStampingService */,
DC8E04B11D7F6EC9006D80EB /* ======= Libraries ========= */,
DCC78EA81D8088E200865A7C /* security */,
DC52E7731D80BC8000B0A59C /* libsecurityd_ios */,
+ 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */,
DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */,
D4ADA3181E2B41670031CEA3 /* libtrustd */,
DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */,
DCE4E7311D7A43B500AFB96E /* SecurityTestsOSX */,
DC3502B41E0208BE00BC0587 /* CKKSTests */,
0C85DFD11FB38BB6000343A7 /* OTTests */,
+ 0CF406042072E3E3003D6A7F /* SignInAnalyticsTests_ios */,
+ 0C9AEEAB20783FBB00BF6237 /* SignInAnalyticsTests_osx */,
DC610AAD1D7910C3002223DE /* gk_reset_check_macos */,
DC610A551D78F9D2002223DE /* codesign_tests_macos */,
DC610A461D78F48F002223DE /* SecTaskTest_macos */,
BED208D41EDF950E00753952 /* manifeststresstest */,
EB433A201CC3243600A7EACE /* secitemstresstest */,
EBA9AA7D1CE30E58004E2B68 /* secitemnotifications */,
+ DAE40BC520CF3E46002D5674 /* secitemcanarytest */,
DCE4E7CB1D7A4AED00AFB96E /* sectests_macos */,
470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */,
47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */,
6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */,
6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */,
6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */,
+ 47C51B831EEA657D0032D9E5 /* SecurityUnitTests */,
+ 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */,
+ EB05C4F01FE5E48A00D68712 /* MultiDeviceSimulatorTests */,
+ EB056E3D1FE5E390000A771E /* DeviceSimulator */,
+ 4727FBB61F9918580003AE36 /* secdxctests_ios */,
+ 478D426C1FD72A8100CAB645 /* secdxctests_mac */,
+ EB49B2AD202D877F003F34A0 /* secdmockaks */,
+ 3DD1FEF5201C07F30086D049 /* SecureTransport_macos_tests */,
+ 3DD1FFAC201FDB1D0086D049 /* SecureTransport_ios_tests */,
DC5AC1351D835D9700CF422C /* ===== Source Gen ===== */,
DC008B451D90CE53004002A3 /* securityd_macos_mig */,
DC6BC26C1D90CFEF00DD57B3 /* securityd_macos_startup */,
E79EEDE01CD4000C00C2FBFC /* Security_executables */,
05EF68B519491512007958C3 /* Security_frameworks */,
F667EC561E96E9B100203D5C /* authdtest */,
- 47C51B831EEA657D0032D9E5 /* SecurityUnitTests */,
- 4727FBB61F9918580003AE36 /* secdxctests_ios */,
- 478D426C1FD72A8100CAB645 /* secdxctests_mac */,
- EB49B2AD202D877F003F34A0 /* secdmockaks */,
+ 47C2F1822059CB680062DE30 /* KeychainResources */,
+ 4771D971209A755800BA9772 /* KeychainDataclassOwner */,
);
};
/* End PBXProject section */
);
runOnlyForDeploymentPostprocessing = 0;
};
- 4727FBB51F9918580003AE36 /* Resources */ = {
+ 4771D970209A755800BA9772 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- 478D42981FD72A8100CAB645 /* Resources */ = {
+ 47C2F1812059CB680062DE30 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ D465131A2097FF2E005D93FE /* Main.storyboard in Resources */,
+ D465131B2097FF2E005D93FE /* Assets.xcassets in Resources */,
+ D465131C2097FF2E005D93FE /* LaunchScreen.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
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 */,
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 6CF4A0C01E45488B00ECD7B5 /* Assets.xcassets in Resources */,
- 6CF4A0C31E45488B00ECD7B5 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 6CF4A0F21E4549F300ECD7B5 /* LaunchScreen.storyboard in Resources */,
- 6CF4A0EF1E4549F300ECD7B5 /* Assets.xcassets in Resources */,
- 6CF4A0ED1E4549F300ECD7B5 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DCE4E9081D7F3A4800AFB96E /* Icon.icns in Resources */,
DCE4E90A1D7F3A4800AFB96E /* Credits.rtf in Resources */,
DCE4E9091D7F3A4800AFB96E /* InfoPlist.strings in Resources */,
- DC0B62301D909C4600D43BCB /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DCE4E9491D7F3E8E00AFB96E /* Localizable.strings in Resources */,
DCE4E94A1D7F3E8E00AFB96E /* com.apple.security.keychain-circle-notification.plist in Resources */,
DCE4E94B1D7F3E8E00AFB96E /* InfoPlist.strings in Resources */,
- DC0B622F1D909C4600D43BCB /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
);
runOnlyForDeploymentPostprocessing = 0;
};
+ EB05C4EF1FE5E48A00D68712 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
EB108F3A1E6CE4D2003B0456 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
- 0C85DFFF1FB38BB6000343A7 /* ShellScript */ = {
+ 090585D020AEF9D300BB7490 /* Install OCMock framework */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
+ name = "Install OCMock framework";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "#Disable until this places a plist in this directory\n#chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework\n";
};
- 5EE098DE1CD21661009FCA27 /* Unifdef RC_HIDE_J79/J80 */ = {
+ 090585D120AEF9FE00BB7490 /* Install OCMock framework */ = {
isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
+ buildActionMask = 8;
files = (
);
inputPaths = (
);
- name = "Unifdef RC_HIDE_J79/J80";
+ name = "Install OCMock framework";
outputPaths = (
);
- runOnlyForDeploymentPostprocessing = 0;
+ runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- 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;
+ shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework";
};
- 6CAA8D361F84317F007B6E03 /* Install launchd plist */ = {
+ 0C85DFFF1FB38BB6000343A7 /* ShellScript */ = {
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\"";
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\n#Disable until this places a plist in this directory\n#chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
};
- 6CB5F4761E402D0000DBF3F0 /* ShellScript */ = {
+ 3DD1FF49201C07F30086D049 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 8;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ };
+ 3DD1FFCC201FDB1D0086D049 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ };
+ 5EE098DE1CD21661009FCA27 /* 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\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;
};
- 8E64DAF81C17BA620076C9DF /* Install launchd plist */ = {
+ 6CAA8D361F84317F007B6E03 /* Install launchd plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
- "$(PROJECT_DIR)/KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.ios.plist",
- "$(PROJECT_DIR)/KeychainSyncingOverIDSProxy/com.apple.security.keychainsyncingoveridsproxy.osx.plist",
);
name = "Install launchd plist";
outputPaths = (
- "$(INSTALL_ROOT)/$(INSTALL_DAEMON_AGENT_DIR)/com.apple.security.keychainsyncingoveridsproxy.plist",
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "PLIST_FILE_NAME=com.apple.security.keychainsyncingoveridsproxy\nFILE_TO_COPY=${PROJECT_DIR}/KeychainSyncingOverIDSProxy/${PLIST_FILE_NAME}.ios.plist\n\nif [ ${PLATFORM_NAME} = \"macosx\" ]\nthen\n FILE_TO_COPY=${PROJECT_DIR}/KeychainSyncingOverIDSProxy/${PLIST_FILE_NAME}.osx.plist\nfi\n\ncp ${FILE_TO_COPY} ${INSTALL_ROOT}/${INSTALL_DAEMON_AGENT_DIR}/${PLIST_FILE_NAME}.plist";
+ 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;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
};
8E64DB4E1C18A5B80076C9DF /* Install launchd plist */ = {
isa = PBXShellScriptBuildPhase;
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
};
DC71D9FE1D95BB5B0065FB93 /* Why is this here? */ = {
isa = PBXShellScriptBuildPhase;
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "chown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
showEnvVarsInLog = 0;
};
EB108F3D1E6CE4D2003B0456 /* chmod BATS Tests */ = {
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "chown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
showEnvVarsInLog = 0;
};
EBC15E801BE29A8C001C0C5B /* Chown BATS plist */ = {
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "chown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
+ shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist";
showEnvVarsInLog = 0;
};
+ EBC73F4B209A0C3400AE3350 /* Install OCMock framework */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 8;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Install OCMock framework";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework\n";
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ DCD504C220CB28BF00F37D26 /* SecFramework.c in Sources */,
476541A11F33EDA500413F65 /* SecdWatchdog.m in Sources */,
DCCD33D21E3FF0D800AA4AD1 /* spi.c in Sources */,
0C0BDB32175685B000BC1A7E /* main.m in Sources */,
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0C7756CE209A694100268D2C /* SFSignInAnalytics.m in Sources */,
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 */,
+ 6C53A44D206AB1EF000FA611 /* LocalKeychainAnalytics.m in Sources */,
0C52C1FF20003BCA003F0733 /* OTTestsBase.m in Sources */,
0C1637211FD12F1500210823 /* OTCloudStoreTests.m in Sources */,
0CAEC9D81FD740CF00D1F2CA /* OTContextTests.m in Sources */,
DCDB296C1FD8820400B5D242 /* SFAnalytics.m in Sources */,
6C73F48D2006B83E003D5D63 /* SOSAnalytics.m in Sources */,
0C46A57B2035019800F17112 /* OTLockStateNetworkingTests.m in Sources */,
+ DC5B391820C08B39005B09F6 /* SecFramework.c in Sources */,
DCDB296E1FD8821400B5D242 /* SFAnalyticsActivityTracker.m in Sources */,
DCDB29701FD8821800B5D242 /* SFAnalyticsMultiSampler.m in Sources */,
DCDB29741FD8822200B5D242 /* SFAnalyticsSQLiteStore.m in Sources */,
files = (
0C8BBF1B1FCB4EC500580909 /* OTControlProtocol.m in Sources */,
0C8BBF091FCB447600580909 /* otctl.m in Sources */,
+ 4771DA2620A4C34800BA9772 /* OT.m in Sources */,
0C8BBEFF1FCB446400580909 /* SecArgParse.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 0C9AEEAE20783FBB00BF6237 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0C9AEEAF20783FBB00BF6237 /* SFSignInAnalyticsTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 0CF406112072E3E3003D6A7F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0C5663EC20BE2DF30035F362 /* SFSignInAnalytics.m in Sources */,
+ 0CF406522072E422003D6A7F /* SFSignInAnalyticsTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
225394AD1E3080A600D3CD9B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
220179EB1E3BF1F100EFB6F3 /* detachedrep.cpp in Sources */,
220179EA1E3BF16000EFB6F3 /* slcrep.cpp in Sources */,
220179E31E3BEB7100EFB6F3 /* dirscanner.cpp in Sources */,
+ A690B033208A75D1002FB775 /* notarization.cpp in Sources */,
225394B81E30820900D3CD9B /* Code.cpp in Sources */,
225394B91E30821400D3CD9B /* bundlediskrep.cpp in Sources */,
225394BA1E30821E00D3CD9B /* cdbuilder.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 3DD1FF02201C07F30086D049 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3DD1FF99201FC50E0086D049 /* STLegacyTests+noconn.m in Sources */,
+ 3DD1FF98201FC5080086D049 /* STLegacyTests+falsestart.m in Sources */,
+ 3DD1FF96201FC4FE0086D049 /* STLegacyTests+crashes.m in Sources */,
+ 3DD1FF95201FC4F70086D049 /* STLegacyTests+clientauth.m in Sources */,
+ 3DD1FF92201FC4EA0086D049 /* SecureTransportTests.m in Sources */,
+ 3DD1FF93201FC4EF0086D049 /* STLegacyTests.m in Sources */,
+ 3DD1FF94201FC4F40086D049 /* STLegacyTests+ciphers.m in Sources */,
+ 3DD1FF97201FC5030086D049 /* STLegacyTests+dhe.m in Sources */,
+ 3DD1FF9A201FC5130086D049 /* STLegacyTests+renegotiate.m in Sources */,
+ 3DD1FF9B201FC5170086D049 /* STLegacyTests+sessioncache.m in Sources */,
+ 3DD1FF9C201FC51B0086D049 /* STLegacyTests+sessionstate.m in Sources */,
+ 3DD1FF9E201FC53A0086D049 /* STLegacyTests+split.m in Sources */,
+ 3DD1FF9F201FC5410086D049 /* STLegacyTests+sslciphers.m in Sources */,
+ 3DD1FFA0201FC5450086D049 /* STLegacyTests+tls12.m in Sources */,
+ 3DD1FFA1201FC5660086D049 /* ssl-utils.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3DD1FFB3201FDB1D0086D049 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3DD1FFB4201FDB1D0086D049 /* STLegacyTests+noconn.m in Sources */,
+ 3DD1FFB5201FDB1D0086D049 /* STLegacyTests+falsestart.m in Sources */,
+ 3DD1FFB6201FDB1D0086D049 /* STLegacyTests+crashes.m in Sources */,
+ 3DD1FFB7201FDB1D0086D049 /* STLegacyTests+clientauth.m in Sources */,
+ 3DD1FFB8201FDB1D0086D049 /* SecureTransportTests.m in Sources */,
+ 3DD1FFB9201FDB1D0086D049 /* STLegacyTests.m in Sources */,
+ 3DD1FFBA201FDB1D0086D049 /* STLegacyTests+ciphers.m in Sources */,
+ 3DD1FFBB201FDB1D0086D049 /* STLegacyTests+dhe.m in Sources */,
+ 3DD1FFBC201FDB1D0086D049 /* STLegacyTests+renegotiate.m in Sources */,
+ 3DD1FFBD201FDB1D0086D049 /* STLegacyTests+sessioncache.m in Sources */,
+ 3DD1FFBE201FDB1D0086D049 /* STLegacyTests+sessionstate.m in Sources */,
+ 3DD1FFBF201FDB1D0086D049 /* STLegacyTests+split.m in Sources */,
+ 3DD1FFC0201FDB1D0086D049 /* STLegacyTests+sslciphers.m in Sources */,
+ 3DD1FFC1201FDB1D0086D049 /* STLegacyTests+tls12.m in Sources */,
+ 3DD1FFD1201FDC460086D049 /* STLegacyTests+clientauth41.m in Sources */,
+ 3DD1FFC2201FDB1D0086D049 /* ssl-utils.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
438169081B4EDCBD00C54D58 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 4718AE0F205B39620068EC3F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4718AE10205B39620068EC3F /* spi.c in Sources */,
+ 4718AE11205B39620068EC3F /* SecdWatchdog.m in Sources */,
+ 4718AE12205B39620068EC3F /* server.c in Sources */,
+ 4718AE13205B39620068EC3F /* server_entitlement_helpers.c in Sources */,
+ 4718AE14205B39620068EC3F /* server_security_helpers.c in Sources */,
+ 4718AE15205B39620068EC3F /* server_xpc.m in Sources */,
+ 4718AE16205B39620068EC3F /* server_endpoint.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 4718AE2F205B39C40068EC3F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4718AE30205B39C40068EC3F /* OTAuthenticatedCiphertext.proto in Sources */,
+ 4718AE31205B39C40068EC3F /* OTPrivateKey.proto in Sources */,
+ 4718AE32205B39C40068EC3F /* OTBottle.proto in Sources */,
+ 4718AE33205B39C40068EC3F /* OTBottleContents.proto in Sources */,
+ 4718AE34205B39C40068EC3F /* CKKSSerializedKey.proto in Sources */,
+ 4718AE35205B39C40068EC3F /* CKKSSQLDatabaseObject.m in Sources */,
+ 4718AE36205B39C40068EC3F /* CKKSRateLimiter.m in Sources */,
+ 4718AE37205B39C40068EC3F /* CKKSCKAccountStateTracker.m in Sources */,
+ 4718AE38205B39C40068EC3F /* SecCDKeychain.m in Sources */,
+ 4718AE39205B39C40068EC3F /* CKKSPowerCollection.m in Sources */,
+ 4718AE3A205B39C40068EC3F /* CKKSGroupOperation.m in Sources */,
+ 4718AE3B205B39C40068EC3F /* OTContextRecord.m in Sources */,
+ 4718AE3C205B39C40068EC3F /* OTPrivateKey+SF.m in Sources */,
+ 4718AE3D205B39C40068EC3F /* CKKSManifestLeafRecord.m in Sources */,
+ 4718AE3E205B39C40068EC3F /* CKKSItem.m in Sources */,
+ 4718AE3F205B39C40068EC3F /* CKKSItemEncrypter.m in Sources */,
+ 4718AE40205B39C40068EC3F /* CKKSOutgoingQueueEntry.m in Sources */,
+ 4718AE42205B39C40068EC3F /* CKKSIncomingQueueEntry.m in Sources */,
+ 4718AE43205B39C40068EC3F /* OTLocalStore.m in Sources */,
+ 4718AE44205B39C40068EC3F /* SFKeychainControlManager.m in Sources */,
+ 4718AE45205B39C40068EC3F /* OTBottledPeerSigned.m in Sources */,
+ 4718AE46205B39C40068EC3F /* CKKSIncomingQueueOperation.m in Sources */,
+ 4718AE47205B39C40068EC3F /* CKKSOutgoingQueueOperation.m in Sources */,
+ 4718AE48205B39C40068EC3F /* CKKSZoneStateEntry.m in Sources */,
+ 4718AE49205B39C40068EC3F /* AsymKeybagBackup.m in Sources */,
+ 4718AE4A205B39C40068EC3F /* RateLimiter.m in Sources */,
+ 4718AE4B205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.m in Sources */,
+ 4718AE4C205B39C40068EC3F /* CKKSCurrentItemPointer.m in Sources */,
+ 4718AE4D205B39C40068EC3F /* CKKSLocalSynchronizeOperation.m in Sources */,
+ 4718AE4E205B39C40068EC3F /* OTManager.m in Sources */,
+ 4718AE4F205B39C40068EC3F /* OTEscrowKeys.m in Sources */,
+ 4718AE50205B39C40068EC3F /* CKKSCurrentKeyPointer.m in Sources */,
+ 4718AE51205B39C40068EC3F /* CKKSControlServer.m in Sources */,
+ 4718AE52205B39C40068EC3F /* CKKSUpdateDeviceStateOperation.m in Sources */,
+ 4718AE53205B39C40068EC3F /* SecDbKeychainSerializedMetadata.m in Sources */,
+ 4718AE54205B39C40068EC3F /* CKKSNearFutureScheduler.m in Sources */,
+ 4718AE55205B39C40068EC3F /* CKKSMirrorEntry.m in Sources */,
+ 4718AE56205B39C40068EC3F /* CloudKitCategories.m in Sources */,
+ 4718AE57205B39C40068EC3F /* CKKSPeer.m in Sources */,
+ 4718AE58205B39C40068EC3F /* CKKS.m in Sources */,
+ 4718AE59205B39C40068EC3F /* CKKSSynchronizeOperation.m in Sources */,
+ 4718AE5A205B39C40068EC3F /* CKKSRecordHolder.m in Sources */,
+ 4718AE5B205B39C40068EC3F /* SOSChangeTracker.c in Sources */,
+ 4718AE5C205B39C40068EC3F /* CKKSScanLocalItemsOperation.m in Sources */,
+ 4718AE5D205B39C40068EC3F /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */,
+ 4718AE5E205B39C40068EC3F /* CKKSNotifier.m in Sources */,
+ 4718AE5F205B39C40068EC3F /* SOSEngine.c in Sources */,
+ 4718AE60205B39C40068EC3F /* CKKSKey.m in Sources */,
+ 4718AE61205B39C40068EC3F /* CKKSViewManager.m in Sources */,
+ 4718AE62205B39C40068EC3F /* SecDbKeychainItemV7.m in Sources */,
+ 4718AE63205B39C40068EC3F /* OTControlProtocol.m in Sources */,
+ 4718AE64205B39C40068EC3F /* CKKSReachabilityTracker.m in Sources */,
+ 4718AE65205B39C40068EC3F /* SecDbItem.c in Sources */,
+ 4718AE66205B39C40068EC3F /* SecDbKeychainItem.m in Sources */,
+ 4718AE67205B39C40068EC3F /* SecDbQuery.c in Sources */,
+ 4718AE68205B39C40068EC3F /* CKKSResultOperation.m in Sources */,
+ 4718AE69205B39C40068EC3F /* CKKSManifest.m in Sources */,
+ 4718AE6A205B39C40068EC3F /* SecItemBackupServer.c in Sources */,
+ 4718AE6B205B39C40068EC3F /* SecItemDataSource.c in Sources */,
+ 4718AE6C205B39C40068EC3F /* OctagonControlServer.m in Sources */,
+ 4718AE6D205B39C40068EC3F /* SecItemDb.c in Sources */,
+ 4718AE6E205B39C40068EC3F /* SecItemSchema.c in Sources */,
+ 4718AE6F205B39C40068EC3F /* OTConstants.m in Sources */,
+ 4718AE70205B39C40068EC3F /* OTRamping.m in Sources */,
+ 4718AE71205B39C40068EC3F /* SecItemServer.c in Sources */,
+ 4718AE72205B39C40068EC3F /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */,
+ D491112D209515400066A1E4 /* CKKSAnalytics.m in Sources */,
+ 4718AE74205B39C40068EC3F /* OTContext.m in Sources */,
+ 4718AE75205B39C40068EC3F /* NSOperationCategories.m in Sources */,
+ 4718AE76205B39C40068EC3F /* SecKeybagSupport.c in Sources */,
+ 4718AE77205B39C40068EC3F /* SecLogSettingsServer.m in Sources */,
+ 4718AE78205B39C40068EC3F /* CKKSDeviceStateEntry.m in Sources */,
+ 4718AE79205B39C40068EC3F /* CKKSFixups.m in Sources */,
+ 4718AE7A205B39C40068EC3F /* OTIdentity.m in Sources */,
+ 4718AE7C205B39C40068EC3F /* SecOTRRemote.m in Sources */,
+ 4718AE7D205B39C40068EC3F /* CKKSUpdateCurrentItemPointerOperation.m in Sources */,
+ 4718AE7E205B39C40068EC3F /* CKKSNewTLKOperation.m in Sources */,
+ 4718AE7F205B39C40068EC3F /* CKKSLockStateTracker.m in Sources */,
+ 4718AE80205B39C40068EC3F /* OTCloudStoreState.m in Sources */,
+ 4718AE81205B39C40068EC3F /* SecDbKeychainSerializedSecretData.m in Sources */,
+ 4718AE82205B39C40068EC3F /* CKKSKeychainView.m in Sources */,
+ 4718AE83205B39C40068EC3F /* SecuritydXPC.c in Sources */,
+ 4718AE84205B39C40068EC3F /* SecDbKeychainSerializedItemV7.m in Sources */,
+ 4718AE85205B39C40068EC3F /* OT.m in Sources */,
+ 4718AE86205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.m in Sources */,
+ 4718AE87205B39C40068EC3F /* CKKSTLKShare.m in Sources */,
+ 4718AE88205B39C40068EC3F /* CKKSHealTLKSharesOperation.m in Sources */,
+ 4718AE89205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.m in Sources */,
+ 4718AE8A205B39C40068EC3F /* SecBackupKeybagEntry.m in Sources */,
+ 4718AE8B205B39C40068EC3F /* iCloudTrace.c in Sources */,
+ 4718AE8C205B39C40068EC3F /* CKKSAPSReceiver.m in Sources */,
+ 4718AE8D205B39C40068EC3F /* OTBottledPeer.m in Sources */,
+ 4718AE8F205B39C40068EC3F /* SOSEnsureBackup.m in Sources */,
+ 4718AE90205B39C40068EC3F /* OTBottledPeerRecord.m in Sources */,
+ 4718AE91205B39C40068EC3F /* OTCloudStore.m in Sources */,
+ 4718AE92205B39C40068EC3F /* CKKSSIV.m in Sources */,
+ 4718AE93205B39C40068EC3F /* OTPreflightInfo.m in Sources */,
+ 4718AE95205B39C40068EC3F /* OTAuthenticatedCiphertext+SF.m in Sources */,
+ 4718AE96205B39C40068EC3F /* CKKSZoneChangeFetcher.m in Sources */,
+ 4718AE97205B39C40068EC3F /* CKKSCondition.m in Sources */,
+ 4718AE98205B39C40068EC3F /* CKKSZone.m in Sources */,
+ 4718AE99205B39C40068EC3F /* SFKeychainServer.m in Sources */,
+ 4718AE9A205B39C40068EC3F /* SFECPublicKey+SPKI.m in Sources */,
+ 4718AE9B205B39C40068EC3F /* swcagent_client.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
4727FBB31F9918580003AE36 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
477A1FED2037A0E000ACD81D /* KeychainXCTest.m in Sources */,
4727FBEB1F99227F0003AE36 /* spi.c in Sources */,
4727FBEC1F99235B0003AE36 /* SecdWatchdog.m in Sources */,
+ 4764E9272059D866005497C9 /* KeychainModel.xcdatamodeld in Sources */,
4727FBBA1F9918590003AE36 /* KeychainCryptoTests.m in Sources */,
477A1FE4203763A500ACD81D /* KeychainAPITests.m in Sources */,
4727FBED1F99249A0003AE36 /* server_endpoint.m in Sources */,
+ 096C647020AB1BC700D7B7D5 /* KeychainEntitlementsTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 4771D96E209A755800BA9772 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 47D13759209CD1A200CAD493 /* NSError+UsefulConstructors.m in Sources */,
+ 4771DA2520A4C33A00BA9772 /* OT.m in Sources */,
+ 4771D980209A75FE00BA9772 /* KeychainDataclassOwner.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
478D42751FD72A8100CAB645 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
478D42761FD72A8100CAB645 /* server_xpc.m in Sources */,
+ 4764E92D2059D8BF005497C9 /* KeychainModel.xcdatamodeld in Sources */,
478D42771FD72A8100CAB645 /* server_security_helpers.c in Sources */,
478D42781FD72A8100CAB645 /* server_entitlement_helpers.c in Sources */,
477A1FEE2037A0E000ACD81D /* KeychainXCTest.m in Sources */,
+ 09BFE35C20A32E0E008511E9 /* KeychainEntitlementsTest.m in Sources */,
478D42791FD72A8100CAB645 /* spi.c in Sources */,
478D427A1FD72A8100CAB645 /* SecdWatchdog.m in Sources */,
478D427B1FD72A8100CAB645 /* KeychainCryptoTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 47C2F17F2059CB680062DE30 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 47C2F18A2059CB820062DE30 /* KeychainModel.xcdatamodeld in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
47C51B801EEA657D0032D9E5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
6CAA8CFF1F83E800007B6E03 /* SFSQLite.m in Sources */,
6CDB5FF61FA78D1B00410924 /* SFAnalyticsMultiSampler.m in Sources */,
D46246A61F9AE61000D63882 /* oids.c in Sources */,
- 0CBFEACB200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */,
+ 0CBFEACB200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */,
0CBD55B31FE883F200A8CE21 /* SFBehavior.m in Sources */,
+ 6C814A4D2050B4B600CB391B /* LocalKeychainAnalytics.m in Sources */,
220179E91E3BF03200EFB6F3 /* dummy.cpp in Sources */,
DC926F091F33FA8D0012A315 /* CKKSControlProtocol.m in Sources */,
4723C9CC1F152ED30082882F /* SFSQLiteStatement.m in Sources */,
+ DCC5860020BF8A7E005C7269 /* SecFramework.c in Sources */,
DCA85B931E8D97E400BA7241 /* client.c in Sources */,
6CBF653A1FA147E500A68667 /* SFAnalyticsActivityTracker.m in Sources */,
DC9C95BF1F79DC88000D19E5 /* CKKSControl.m in Sources */,
0C8BBF121FCB4AAB00580909 /* OTControl.m in Sources */,
EB48C1A51E573EE400EC5E57 /* whoami.m in Sources */,
B61F67571F1FCFCB00E2FDBB /* SecPaddingConfigurations.c in Sources */,
+ AA44E0D72032515C001EA371 /* SecProtocolTypes.m in Sources */,
6CE365531FA101080012F6AB /* SFAnalyticsSampler.m in Sources */,
+ AA44E0D520325150001EA371 /* SecProtocol.c in Sources */,
6C73F48A2006B839003D5D63 /* SOSAnalytics.m in Sources */,
6CE365571FA1017D0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */,
);
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 4771DA2720A4C37D00BA9772 /* OT.m in Sources */,
5346481E173322BD00FE9172 /* KeychainSyncAccountNotification.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ D49111322095154B0066A1E4 /* Assets.xcassets in Sources */,
+ D49111312095154B0066A1E4 /* Main.storyboard in Sources */,
6CF4A0BE1E45488B00ECD7B5 /* ViewController.m in Sources */,
6CF4A0BB1E45488B00ECD7B5 /* main.m in Sources */,
6CF4A0B81E45488B00ECD7B5 /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- CD276C231A83F60C003226BC /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- CD23B49E1DA06EB40047EDE9 /* IDSPersistentState.m in Sources */,
- CD23B4A01DA06EB40047EDE9 /* IDSProxy.m in Sources */,
- 0C5D62F11E81E74800AA4D02 /* SOSInternal.m in Sources */,
- CD23B4A11DA06EB40047EDE9 /* keychainsyncingoveridsproxy.m in Sources */,
- CD23B4A31DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+ReceiveMessage.m in Sources */,
- CD23B4A51DA06EB40047EDE9 /* KeychainSyncingOverIDSProxy+SendMessage.m in Sources */,
- E7A5F5591C0D052600F3BEBB /* SOSCloudKeychainConstants.c in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
D41257CB1E9410A300781F23 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- D43DBEFB1E99D1CA00C04AEA /* asynchttp.c in Sources */,
D43DBEFC1E99D1CA00C04AEA /* nameconstraints.c in Sources */,
D43DBEFD1E99D1CA00C04AEA /* OTATrustUtilities.m in Sources */,
D43DBEFE1E99D1CA00C04AEA /* personalization.c in Sources */,
D43DBEFF1E99D1CA00C04AEA /* policytree.c in Sources */,
D43DBF001E99D1CA00C04AEA /* SecCAIssuerCache.c in Sources */,
- D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.c in Sources */,
+ D43DBF011E99D1CA00C04AEA /* SecCAIssuerRequest.m in Sources */,
D43DBF021E99D1CA00C04AEA /* SecCertificateServer.c in Sources */,
D43DBF031E99D1CA00C04AEA /* SecCertificateSource.c in Sources */,
D43DBF041E99D1CA00C04AEA /* SecOCSPCache.c in Sources */,
D43DBF091E99D1CA00C04AEA /* SecRevocationDb.c in Sources */,
D43DBF0A1E99D1CA00C04AEA /* SecRevocationServer.c in Sources */,
D43DBF0B1E99D1CA00C04AEA /* SecTrustLoggingServer.m in Sources */,
+ D4961BC42079424200F16DA7 /* TrustURLSessionDelegate.m in Sources */,
D43DBF0C1E99D1CA00C04AEA /* SecTrustServer.c in Sources */,
D43DBF0D1E99D1CA00C04AEA /* SecTrustStoreServer.c in Sources */,
D40B6A9B1E2B690E00CD6EE5 /* SecuritydXPC.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ DAE40BC620CF3E46002D5674 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DAE40BD920CF3F0F002D5674 /* secitemcanarytest.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
DC0067A81D87876F005AF8DB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
DC0BCDAB1D8C6A1F00070CB0 /* SecXPCError.c in Sources */,
DC0BCDB51D8C6A5B00070CB0 /* not_on_this_platorm.c in Sources */,
DC65E7C01D8CBB1500152EF0 /* readline.c in Sources */,
+ DA5B871D2065A8440093F083 /* SecAutorelease.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
files = (
0CBD55B91FE883F300A8CE21 /* SFBehavior.m in Sources */,
D46246A71F9AE62000D63882 /* oids.c in Sources */,
+ DCC585FF20BF8A7E005C7269 /* SecFramework.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 */,
+ AA44E0D82032515C001EA371 /* SecProtocolTypes.m in Sources */,
DCA85B941E8D97E400BA7241 /* client.c in Sources */,
DCDF0A4F1D81D76F007AF174 /* Security.exp-in in Sources */,
- 0CBFEACA200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */,
+ 0CBFEACA200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */,
+ AA44E0D620325150001EA371 /* SecProtocol.c in Sources */,
DC1789A51D779E3B00B50D50 /* dummy.cpp 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 */,
+ 6CB420A52051FDD500FF2D44 /* LocalKeychainAnalytics.m in Sources */,
0C8BBF141FCB4AFB00580909 /* OTControlProtocol.m in Sources */,
B61577E81F20151C004A3930 /* SecPaddingConfigurations.c in Sources */,
6C73F48B2006B83A003D5D63 /* SOSAnalytics.m in Sources */,
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ DCAE1DDE2073FDCD00B4F687 /* NSError+UsefulConstructors.m in Sources */,
BEE4B18D1FFD588000777D39 /* OTAuthenticatedCiphertext.proto in Sources */,
BEB0B0D81FFC3DD3007E6A83 /* OTPrivateKey.proto in Sources */,
BE3405AE1FD725EC00933DAC /* OTBottle.proto 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.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 */,
+ 470D96741FCDE55B0065FE90 /* SecCDKeychain.m in Sources */,
DC14478D1F5764C600236DB4 /* CKKSResultOperation.m in Sources */,
479DA1781EBBA8D30065C98F /* CKKSManifest.m in Sources */,
DCD662F81E329B6800188186 /* CKKSNewTLKOperation.m in Sources */,
0C5CFB392019610000913B9C /* OTRamping.m in Sources */,
DC222C4E1E034D1F00B09171 /* CKKS.m in Sources */,
DC762AA11E57A86A00B03A2C /* CKKSRecordHolder.m in Sources */,
+ 4718AEE4205B3A060068EC3F /* KeychainModel.xcdatamodeld in Sources */,
DC222C501E034D1F00B09171 /* SecOTRRemote.m in Sources */,
47922D451FAA7C2E0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */,
- 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */,
- 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */,
+ D491112E209515400066A1E4 /* CKKSAnalytics.m in Sources */,
DC1447991F5766D200236DB4 /* NSOperationCategories.m in Sources */,
DC222C511E034D1F00B09171 /* CKKSItem.m in Sources */,
DCBDB3BE1E57CA7A00B61300 /* CKKSViewManager.m in Sources */,
0CCCC7CA20261D310024405E /* OT.m in Sources */,
47922D571FAA7E0E0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */,
DC222C571E034D1F00B09171 /* SecuritydXPC.c in Sources */,
+ 47FF17291FD60ACA00875565 /* SFKeychainServer.m 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 */,
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 6C53A447206AB1A6000FA611 /* LocalKeychainAnalytics.m in Sources */,
476541A61F33EE2700413F65 /* SecdWatchdog.m in Sources */,
6CAA8CF41F83E799007B6E03 /* SFSQLite.m in Sources */,
4771ECCD1F17CD0E00840998 /* SFSQLiteStatement.m in Sources */,
6CDF8DF11F96498300140B54 /* SFAnalyticsSampler.m in Sources */,
DC222CA81E08A7D900B09171 /* CloudKitMockXCTest.m in Sources */,
DC9C75161E4BCE1800F1CA0D /* CKKSOperationTests.m in Sources */,
+ DC8D238D2064649400E163C8 /* CKKSAPSHandlingTests.m in Sources */,
DCB221561E8B08BF001598BC /* server_xpc.m in Sources */,
DC42690F1E82FD9C002B7110 /* server_security_helpers.c in Sources */,
DC4268FE1E820371002B7110 /* server_endpoint.m in Sources */,
DCFE1C3D1F17EFB5007640C8 /* CKKSConditionTests.m in Sources */,
DCCD33C91E3FE95900AA4AD1 /* spi.c in Sources */,
+ 0C7756CD209A664800268D2C /* SFSignInAnalytics.m in Sources */,
+ DC5B391720C08B38005B09F6 /* SecFramework.c in Sources */,
6CFDC4551F907D2600646DBB /* SFObjCType.m in Sources */,
DC9C95971F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m in Sources */,
DC7341FE1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m in Sources */,
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ DCAE1DDD2073FDCC00B4F687 /* NSError+UsefulConstructors.m in Sources */,
BEE4B18C1FFD585800777D39 /* OTAuthenticatedCiphertext.proto in Sources */,
BEB0B0D71FFC3D9A007E6A83 /* OTPrivateKey.proto in Sources */,
BE3405AC1FD7258900933DAC /* OTBottle.proto in Sources */,
DC797E1A1DD3F9A400CC9E42 /* CKKSSQLDatabaseObject.m in Sources */,
6CC1859F1E24E8EB009657D8 /* CKKSRateLimiter.m in Sources */,
DCFB12C71E95A4C000510F5F /* CKKSCKAccountStateTracker.m in Sources */,
+ 470D96731FCDE55B0065FE90 /* SecCDKeychain.m in Sources */,
EBB407B31EBA46B200A541A5 /* CKKSPowerCollection.m in Sources */,
DCCD88EA1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */,
0CD9E8001FE05B6600F66C38 /* OTContextRecord.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 */,
0C5CFB382019610000913B9C /* OTRamping.m in Sources */,
DC52E7D71D80BD2D00B0A59C /* SecItemServer.c in Sources */,
47922D441FAA7C2C0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */,
- 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */,
- 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */,
+ 4718AEE3205B3A050068EC3F /* KeychainModel.xcdatamodeld in Sources */,
+ D491112C209515400066A1E4 /* CKKSAnalytics.m in Sources */,
0C8BBEE61FCA6E0500580909 /* OTContext.m in Sources */,
DC1447981F5766D200236DB4 /* NSOperationCategories.m in Sources */,
DCD8A0CF1E09EA1800E4FA0A /* SecKeybagSupport.c 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 */,
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 */,
+ 47FF17281FD60ACA00875565 /* SFKeychainServer.m in Sources */,
BEE4B19A1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */,
DC52E7C51D80BCB300B0A59C /* swcagent_client.c in Sources */,
);
DC52E8F21D80C34000B0A59C /* SOSAccountTransaction.m in Sources */,
DC52E8FD1D80C34000B0A59C /* SOSAccountUpdate.m in Sources */,
DC52E9001D80C34000B0A59C /* SOSAccountViewSync.m in Sources */,
+ 0CB50A0D20AA486800FE4675 /* SOSAccountTrustClassic+Expansion.m in Sources */,
DC52E9011D80C34000B0A59C /* SOSBackupEvent.c in Sources */,
DC2670F71F3E721800816EED /* SOSAccountTrustClassic.m in Sources */,
7281E0871DFD01800021E1B7 /* SOSAccountGetSet.m in Sources */,
DC52E8E31D80C31F00B0A59C /* SOSPeerCoder.m in Sources */,
DCFAEDCF1D999859005187E4 /* SOSAccountGhost.m in Sources */,
EB6928F91D9ED5BA00062A18 /* SecRecoveryKey.m in Sources */,
+ 48FE669620E6E69D00FAEF17 /* SOSAuthKitHelpers.m in Sources */,
48776C811DA5BC0E00CC09B9 /* SOSAccountRecovery.m in Sources */,
DC52E8C91D80C2FD00B0A59C /* SOSTransportBackupPeer.m in Sources */,
+ 0CB50A0E20AA4C2F00FE4675 /* SOSAccountTrustClassic+Circle.m in Sources */,
DC52E8CA1D80C2FD00B0A59C /* SOSTransportCircle.m in Sources */,
DC52E8CB1D80C2FD00B0A59C /* SOSTransportCircleKVS.m in Sources */,
DC52E8CC1D80C2FD00B0A59C /* SOSTransportKeyParameter.m in Sources */,
DC52E8CE1D80C2FD00B0A59C /* SOSTransportMessage.m in Sources */,
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 */,
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.m in Sources */,
DC52ECDE1D80D22600B0A59C /* si-90-emcs.m in Sources */,
DC52ECDF1D80D22600B0A59C /* si-95-cms-basic.c in Sources */,
DC52EC981D80D1D100B0A59C /* vmdh-40.c in Sources */,
0CCDE7171EEB08220021A946 /* secd-156-timers.m in Sources */,
DC52EDC21D80D5C500B0A59C /* secd-32-restore-bad-backup.m in Sources */,
DC52EDC31D80D5C500B0A59C /* secd-33-keychain-ctk.m in Sources */,
- 0CAD1E5C1E1C5CEB00537693 /* secd_77_ids_messaging.m in Sources */,
DC0B622C1D90982C00D43BCB /* secd-201-coders.m in Sources */,
0CAD1E5A1E1C5CD100537693 /* secd-71-engine-save.m in Sources */,
DC52EDC41D80D5C500B0A59C /* secd-34-backup-der-parse.m in Sources */,
DC52EDD31D80D5C500B0A59C /* secd-59-account-cleanup.m in Sources */,
DC52EDD41D80D5C500B0A59C /* secd-60-account-cloud-identity.m in Sources */,
DC52EDD51D80D5C500B0A59C /* secd60-account-cloud-exposure.m in Sources */,
- 0CAD1E5B1E1C5CE100537693 /* secd-76-idstransport.m in Sources */,
DC52EDD61D80D5C500B0A59C /* secd-61-account-leave-not-in-kansas-anymore.m in Sources */,
DC52EDD71D80D5C500B0A59C /* secd-62-account-backup.m in Sources */,
DC52EDD91D80D5C500B0A59C /* secd-63-account-resurrection.m in Sources */,
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 */,
7281E0901DFD0E0A0021E1B7 /* CKDKVSProxy.m in Sources */,
DC52EDE31D80D5C500B0A59C /* secd-75-engine-views.m in Sources */,
DC52EDE61D80D5C500B0A59C /* secd-80-views-basic.m in Sources */,
- DC52EDE71D80D5C500B0A59C /* secd-82-secproperties-basic.m in Sources */,
DC52EDE81D80D5C500B0A59C /* secd-81-item-acl-stress.m in Sources */,
DC52EDE91D80D5C500B0A59C /* secd-81-item-acl.m in Sources */,
DC52EDEA1D80D5C500B0A59C /* secd-82-persistent-ref.m in Sources */,
09CB49701F2F64E300C8E4DE /* si-44-seckey-fv.m in Sources */,
DC52EE5C1D80D76300B0A59C /* si-20-sectrust-policies.m in Sources */,
DC52EE511D80D73800B0A59C /* si-15-certificate.c in Sources */,
+ D48BD18D206C45F00075DDC9 /* si-89-cms-hash-agility.m in Sources */,
BE6215BE1DB6E69100961E15 /* si-84-sectrust-allowlist.m in Sources */,
DC52EE521D80D73800B0A59C /* si-16-ec-certificate.c in Sources */,
DC52EE421D80D71900B0A59C /* si-20-sectrust.c in Sources */,
+ D4B6D57C2069D8450099FBEF /* si-34-cms-timestamp.m in Sources */,
D4096E031ED5F21C000AC459 /* si-65-cms-cert-policy.c in Sources */,
DC52EE441D80D71900B0A59C /* si-21-sectrust-asr.c in Sources */,
DC52EE451D80D71900B0A59C /* si-22-sectrust-iap.c 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 */,
+ DCE2341820A3D4B8009766A3 /* si-cms-hash-agility-data.c in Sources */,
DC52EE4B1D80D71900B0A59C /* si-24-sectrust-nist.c in Sources */,
DC52EE4C1D80D71900B0A59C /* si-24-sectrust-passbook.c in Sources */,
DC52EE4D1D80D71900B0A59C /* si-26-sectrust-copyproperties.c in Sources */,
DC52EE551D80D73800B0A59C /* si-44-seckey-ec.m in Sources */,
D4096E011ED5F0B5000AC459 /* si-60-cms.c in Sources */,
D4CFAA7E1E660BB3004746AA /* si-32-sectrust-pinning-required.m in Sources */,
+ D48BD194206C47530075DDC9 /* si-35-cms-expiration-time.m in Sources */,
D487FBB81DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m in Sources */,
DC52EE561D80D73800B0A59C /* si-44-seckey-ies.m in Sources */,
DC52EE571D80D73800B0A59C /* si-67-sectrust-blocklist.c in Sources */,
D4096E021ED5F207000AC459 /* si-64-ossl-cms.c in Sources */,
+ 09A3B9E11F82734400C5C324 /* si-44-seckey-proxy.m in Sources */,
+ DCD45357209A5BA10086CBFC /* si-cms-signing-identity-p12.c in Sources */,
DC52EE581D80D73800B0A59C /* si-70-sectrust-unified.c in Sources */,
DC52EE591D80D73800B0A59C /* si-82-seccertificate-ct.c in Sources */,
DC52EE5A1D80D73800B0A59C /* si-83-seccertificate-sighashalg.c in Sources */,
DC52EE7C1D80D89E00B0A59C /* SecItemBackup.c in Sources */,
DC4269051E82EDC4002B7110 /* SecItem.m in Sources */,
EBEEEE3E1EA31DB100E15F5C /* SOSControlHelper.m in Sources */,
- DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.c in Sources */,
+ DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.m in Sources */,
DC52EE7A1D80D89400B0A59C /* SecCFAllocator.c in Sources */,
DC52EE791D80D88D00B0A59C /* SecItem.c in Sources */,
DC52EE781D80D88800B0A59C /* SecRSAKey.c in Sources */,
+ 09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */,
DC52EE771D80D88300B0A59C /* SecDH.c in Sources */,
- DC52EE761D80D87F00B0A59C /* SecCTKKey.c in Sources */,
+ DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */,
DC52EE741D80D86F00B0A59C /* SecAccessControl.c in Sources */,
DC52EE731D80D86800B0A59C /* SecKey.c in Sources */,
DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */,
- DC52EE711D80D85F00B0A59C /* SecECKey.c in Sources */,
+ DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */,
DC52EE701D80D84700B0A59C /* SecItemConstants.c in Sources */,
DC52EE6F1D80D83F00B0A59C /* SecPasswordGenerate.c in Sources */,
);
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ DCD504BC20CB28BE00F37D26 /* SecFramework.c in Sources */,
476541A21F33EDAD00413F65 /* SecdWatchdog.m in Sources */,
DCCD33D31E3FF0D800AA4AD1 /* spi.c in Sources */,
DC610A181D78F129002223DE /* main.m in Sources */,
DCB3447A1D8A35270054D16E /* kc-01-keychain-creation.c in Sources */,
DCB3447B1D8A35270054D16E /* kc-02-unlock-noui.c in Sources */,
24CBF8751E9D4E6100F09F0E /* kc-44-secrecoverypassword.c in Sources */,
+ DCD4535A209A60DD0086CBFC /* kc-keychain-file-helpers.c in Sources */,
DCB3447D1D8A35270054D16E /* kc-03-keychain-list.c in Sources */,
DCB3447C1D8A35270054D16E /* kc-03-status.c in Sources */,
DCB3447E1D8A35270054D16E /* kc-04-is-valid.c in Sources */,
buildActionMask = 2147483647;
files = (
0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */,
+ DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */,
DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */,
DCC78EE61D808B2A00865A7C /* SecAccessControl.c in Sources */,
DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */,
DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */,
DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */,
BEEB47D91EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */,
- DCC78EE21D808B0E00865A7C /* SecCTKKey.c in Sources */,
+ DCC78EE21D808B0E00865A7C /* SecCTKKey.m in Sources */,
DCC78EE11D808B0900865A7C /* SecCertificate.c in Sources */,
DC4269041E82EDAC002B7110 /* SecItem.m in Sources */,
EBEEEE3D1EA31DB000E15F5C /* SOSControlHelper.m in Sources */,
DCC78EDF1D808AF800865A7C /* SecCertificateRequest.c in Sources */,
DCC78EDE1D808AF100865A7C /* SecDH.c in Sources */,
DCC78EDD1D808AEC00865A7C /* SecDigest.c in Sources */,
- DCC78EDC1D808AE500865A7C /* SecECKey.c in Sources */,
+ DCC78EDC1D808AE500865A7C /* SecECKey.m in Sources */,
DCC78EDB1D808ADF00865A7C /* SecEMCS.m in Sources */,
- DCC78EDA1D808AD100865A7C /* SecFramework.c in Sources */,
DCC78ED91D808ACB00865A7C /* SecIdentity.c in Sources */,
DCC78ED81D808AC600865A7C /* SecImportExport.c in Sources */,
DCC78ED71D808AC000865A7C /* SecItem.c in Sources */,
DCC78ED61D808ABA00865A7C /* SecItemBackup.c in Sources */,
DCC78ED51D808AAE00865A7C /* SecItemConstants.c in Sources */,
DCC78ED41D808AA800865A7C /* SecKey.c in Sources */,
- DCC78ED31D808AA000865A7C /* SecKeyAdaptors.c in Sources */,
+ DCC78ED31D808AA000865A7C /* SecKeyAdaptors.m in Sources */,
DCC78ED21D808A9500865A7C /* SecOTRDHKey.c in Sources */,
DCC78ED11D808A8E00865A7C /* SecOTRFullIdentity.c in Sources */,
B61577ED1F202049004A3930 /* SecPaddingConfigurations.c in Sources */,
DCC78ED01D808A8800865A7C /* SecOTRMath.c in Sources */,
+ 0927FEBC1F81338600864E07 /* SecKeyProxy.m in Sources */,
DCC78ECF1D808A8200865A7C /* SecOTRPacketData.c in Sources */,
DCC78ECE1D808A7B00865A7C /* SecOTRPackets.c in Sources */,
DCC78ECD1D808A7300865A7C /* SecOTRPublicIdentity.c in Sources */,
DCD068581D8CDF7E007602F1 /* bundlediskrep.cpp in Sources */,
DCD068381D8CDF7E007602F1 /* cdbuilder.cpp in Sources */,
DCD068361D8CDF7E007602F1 /* codedirectory.cpp in Sources */,
+ A6B1BA81207BD9EC00F1E099 /* notarization.cpp in Sources */,
DCD068281D8CDF7E007602F1 /* cs.cpp in Sources */,
DCD0686F1D8CDF7E007602F1 /* csdatabase.cpp in Sources */,
DCD068711D8CDF7E007602F1 /* cserror.cpp in Sources */,
DCD66DBF1D82053E00DB1393 /* SecDigest.c in Sources */,
BEEB47DA1EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */,
DCD66DBE1D82053700DB1393 /* SecBase64.c in Sources */,
- BE1F74D31F609D460068FA64 /* SecFramework.c in Sources */,
DCD66DB61D82050900DB1393 /* SecKey.c in Sources */,
- DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.c in Sources */,
+ DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.m in Sources */,
DCD66DBB1D82052700DB1393 /* SecPolicy.c in Sources */,
DCD66DBA1D82052000DB1393 /* SecPolicyLeafCallbacks.c in Sources */,
DCD66DB91D82051900DB1393 /* SecTrust.c in Sources */,
DCD66DB71D82050E00DB1393 /* SecTrustStore.c in Sources */,
- DCD66DB51D82050500DB1393 /* SecECKey.c in Sources */,
+ DCD66DB51D82050500DB1393 /* SecECKey.m in Sources */,
DCD66DB41D82050000DB1393 /* SecRSAKey.c in Sources */,
DCD66DB31D8204FB00DB1393 /* SecServerEncryptionSupport.c in Sources */,
D425EC231DD3FFF200DE5DEC /* SecInternalRelease.c in Sources */,
DCD8A1DB1E09F5D100E4FA0A /* SOSAccountTrust.m in Sources */,
DCD8A1A11E09EF5C00E4FA0A /* SOSCloudKeychainConstants.c in Sources */,
DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */,
- 0C4899251E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m in Sources */,
DCD8A1BD1E09F1D600E4FA0A /* SOSFullPeerInfo.m in Sources */,
DCD8A1B51E09F15400E4FA0A /* SOSGenCount.c in Sources */,
DCD8A19F1E09EF0F00E4FA0A /* SOSInternal.m in Sources */,
DCD8A1B11E09F11900E4FA0A /* SOSPeerInfoDER.m in Sources */,
0CE7604C1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m in Sources */,
DCD8A1B21E09F11900E4FA0A /* SOSPeerInfoRingState.m in Sources */,
- DCD8A1A71E09F01300E4FA0A /* SOSPeerInfoSecurityProperties.m in Sources */,
0CE7604E1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m in Sources */,
DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */,
- 0CE760481E12F2F300B4381E /* SOSAccountTrustClassic+Expansion.m in Sources */,
DCD8A1C21E09F23B00E4FA0A /* SOSRecoveryKeyBag.m in Sources */,
DCD8A1B81E09F1BB00E4FA0A /* SOSRingBackup.m in Sources */,
DCD8A1B91E09F1BB00E4FA0A /* SOSRingBasic.m in Sources */,
DCD8A1C71E09F2B400E4FA0A /* SOSTransport.m in Sources */,
DCD8A1511E09EE0F00E4FA0A /* SOSViews.m in Sources */,
DCD8A19E1E09EEDA00E4FA0A /* SecRecoveryKey.m in Sources */,
- 0CE7604A1E12F30200B4381E /* SOSAccountTrustClassic+Circle.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ D49111302095154B0066A1E4 /* MainMenu.xib in Sources */,
DCE4E8F71D7F3A1100AFB96E /* KDCirclePeer.m in Sources */,
DCE4E8F91D7F3A1100AFB96E /* KDAppDelegate.m in Sources */,
DCE4E8F81D7F3A1100AFB96E /* main.m in Sources */,
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ D491112F2095154B0066A1E4 /* MainMenu.xib in Sources */,
DCE4E92B1D7F3D7C00AFB96E /* KDSecCircle.m in Sources */,
DCE4E92C1D7F3D7C00AFB96E /* KNPersistentState.m in Sources */,
DCE4E9311D7F3D7C00AFB96E /* KDCirclePeer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ EB056E3A1FE5E390000A771E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0CC3775020ACA0DF00B58D2D /* SFSignInAnalytics.m in Sources */,
+ EBDD732C20A6A61E003A103A /* SOSAnalytics.m in Sources */,
+ EB056E451FE5E390000A771E /* DeviceSimulatorMain.m in Sources */,
+ EB056E431FE5E390000A771E /* DeviceSimulator.m in Sources */,
+ EBCE16171FE6DE5A002E7CCC /* SecdWatchdog.m in Sources */,
+ EBCE16181FE6DE5A002E7CCC /* SFSQLite.m in Sources */,
+ EBCE16191FE6DE5A002E7CCC /* SFSQLiteStatement.m in Sources */,
+ EBCE16201FE6DE5A002E7CCC /* SFAnalytics.m in Sources */,
+ EBCE16221FE6DE5A002E7CCC /* SFAnalyticsActivityTracker.m in Sources */,
+ EBCE16231FE6DE5A002E7CCC /* client_endpoint.m in Sources */,
+ EBCE162C1FE6DE5A002E7CCC /* client.c in Sources */,
+ EBCE162D1FE6DE5A002E7CCC /* SFAnalyticsSQLiteStore.m in Sources */,
+ EBCE162F1FE6DE5A002E7CCC /* SecTask.c in Sources */,
+ EBCE16311FE6DE5A002E7CCC /* SFAnalyticsMultiSampler.m in Sources */,
+ DC5B391C20C08BF1005B09F6 /* SecFramework.c in Sources */,
+ EBCE16321FE6DE5A002E7CCC /* SFAnalyticsSampler.m in Sources */,
+ EBCE16351FE6DE5A002E7CCC /* server_xpc.m in Sources */,
+ EBCE16361FE6DE5A002E7CCC /* server_security_helpers.c in Sources */,
+ 6C32BB9A20EAE6B80042DF59 /* LocalKeychainAnalytics.m in Sources */,
+ EBCE16371FE6DE5A002E7CCC /* server_endpoint.m in Sources */,
+ EBCE16391FE6DE5A002E7CCC /* spi.c in Sources */,
+ EBCE163A1FE6DE5A002E7CCC /* SFObjCType.m in Sources */,
+ EBCE163D1FE6DE5A002E7CCC /* server_entitlement_helpers.c in Sources */,
+ EBCE163E1FE6DE5A002E7CCC /* AutoreleaseTest.c in Sources */,
+ EBCE163F1FE6DE5A002E7CCC /* CKKSControl.m in Sources */,
+ EBCE16401FE6DE5A002E7CCC /* CKKSControlProtocol.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EB05C4ED1FE5E48A00D68712 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EBCE166C1FE746A5002E7CCC /* SecItemConstants.c in Sources */,
+ EB05C4F41FE5E48B00D68712 /* MultiDeviceSimulatorTests.m in Sources */,
+ 4885DCAD207FF0780071FB7B /* ClientInfoByNotification.m in Sources */,
+ EBCE16601FE732AA002E7CCC /* MultiDeviceNetworking.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
EB0BC9371C3C791500785842 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 6C32BB9920EAE6B00042DF59 /* LocalKeychainAnalytics.m in Sources */,
+ 0CC3771320A222BC00B58D2D /* SFSignInAnalytics.m in Sources */,
EB49B2E5202DFEB3003F34A0 /* mockaks.m in Sources */,
EB49B2DB202DF20F003F34A0 /* spi.c in Sources */,
EB49B2D7202DF1F7003F34A0 /* server_endpoint.m in Sources */,
+ EBC73F2020993F8600AE3350 /* SFAnalyticsSQLiteStore.m in Sources */,
+ EBC73F2720993FC900AE3350 /* SFAnalyticsMultiSampler.m in Sources */,
EB49B2D8202DF1F7003F34A0 /* server_xpc.m in Sources */,
+ EBC73F2620993FA800AE3350 /* client_endpoint.m in Sources */,
EB49B2D9202DF1F7003F34A0 /* server_security_helpers.c in Sources */,
+ EBC73F2B2099785900AE3350 /* SFObjCType.m in Sources */,
EB49B2E0202DF5D7003F34A0 /* server_entitlement_helpers.c in Sources */,
+ EBC73F2A20996AD400AE3350 /* SFSQLiteStatement.m in Sources */,
EB6667C7204CD69F000B404F /* testPlistDER.m in Sources */,
+ EBC73F29209966AF00AE3350 /* SFSQLite.m in Sources */,
EB49B2D5202DF1D8003F34A0 /* SecTask.c in Sources */,
EB49B2D4202DF1C1003F34A0 /* client.c in Sources */,
EB49B2D3202DF1AC003F34A0 /* SecdWatchdog.m in Sources */,
EB49B2B1202D8780003F34A0 /* secdmockaks.m in Sources */,
+ DC5B391B20C08BDC005B09F6 /* SecFramework.c in Sources */,
EB49B2D1202DF15F003F34A0 /* SFAnalyticsActivityTracker.m in Sources */,
EB49B2D0202DF14D003F34A0 /* SFAnalytics.m in Sources */,
+ EBC73F2820993FDA00AE3350 /* SFAnalyticsSampler.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
target = 0C2BCBBD1D0648D100ED7A2F /* dtlsEchoServer */;
targetProxy = 0C2BCBD01D0648FA00ED7A2F /* PBXContainerItemProxy */;
};
+ 0C3E2EA92073F5C400F5B95B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4C32C0AE0A4975F6002891BD /* Security_ios */;
+ targetProxy = 0C3E2EA82073F5C400F5B95B /* PBXContainerItemProxy */;
+ };
+ 0C5663EE20BE2E1A0035F362 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC0BCC211D8C684F00070CB0 /* utilities */;
+ targetProxy = 0C5663ED20BE2E1A0035F362 /* PBXContainerItemProxy */;
+ };
0C664AB41759270C0092D3D9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */;
target = 0C6799F912F7C37C00712919 /* dtlsTests */;
targetProxy = 0C99B73F131C984900584CF4 /* PBXContainerItemProxy */;
};
+ 0C9AEEBA20783FE000BF6237 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC1789031D77980500B50D50 /* Security_osx */;
+ targetProxy = 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */;
+ };
0CC827F2138712B100BD99B7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = E710C7411331946400F85568 /* SecurityTests */;
target = DCD06AA91D8E0D53007602F1 /* security_utilities */;
targetProxy = 226A8B441DEF58EE004C35E3 /* PBXContainerItemProxy */;
};
+ 3DD1FEF8201C07F30086D049 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC0BCC211D8C684F00070CB0 /* utilities */;
+ targetProxy = 3DD1FEF9201C07F30086D049 /* PBXContainerItemProxy */;
+ };
+ 3DD1FF50201C09CD0086D049 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC0BC9C81D8B824700070CB0 /* security_ssl */;
+ targetProxy = 3DD1FF4F201C09CD0086D049 /* PBXContainerItemProxy */;
+ };
+ 3DD1FFAF201FDB1D0086D049 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC0BC9C81D8B824700070CB0 /* security_ssl */;
+ targetProxy = 3DD1FFB0201FDB1D0086D049 /* PBXContainerItemProxy */;
+ };
+ 3DD1FFB1201FDB1D0086D049 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC0BCC211D8C684F00070CB0 /* utilities */;
+ targetProxy = 3DD1FFB2201FDB1D0086D049 /* PBXContainerItemProxy */;
+ };
438169E71B4EE4B300C54D58 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */;
targetProxy = 438169E61B4EE4B300C54D58 /* PBXContainerItemProxy */;
};
+ 4718AE03205B39620068EC3F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC0BCC211D8C684F00070CB0 /* utilities */;
+ targetProxy = 4718AE04205B39620068EC3F /* PBXContainerItemProxy */;
+ };
+ 4718AE05205B39620068EC3F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D4ADA3181E2B41670031CEA3 /* libtrustd */;
+ targetProxy = 4718AE06205B39620068EC3F /* PBXContainerItemProxy */;
+ };
+ 4718AE09205B39620068EC3F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */;
+ targetProxy = 4718AE0A205B39620068EC3F /* PBXContainerItemProxy */;
+ };
+ 4718AE0B205B39620068EC3F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */;
+ targetProxy = 4718AE0C205B39620068EC3F /* PBXContainerItemProxy */;
+ };
+ 4718AE0D205B39620068EC3F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC52EC3E1D80D00800B0A59C /* libSWCAgent */;
+ targetProxy = 4718AE0E205B39620068EC3F /* PBXContainerItemProxy */;
+ };
+ 4718AEE6205B3A350068EC3F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */;
+ targetProxy = 4718AEE5205B3A350068EC3F /* PBXContainerItemProxy */;
+ };
+ 47455B24205B3E2F008FE980 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4718AE02205B39620068EC3F /* securityd_bridge */;
+ targetProxy = 47455B23205B3E2F008FE980 /* PBXContainerItemProxy */;
+ };
+ 4771D982209A76B100BA9772 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4771D971209A755800BA9772 /* KeychainDataclassOwner */;
+ targetProxy = 4771D981209A76B100BA9772 /* PBXContainerItemProxy */;
+ };
478D426D1FD72A8100CAB645 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DC52EDA61D80D58400B0A59C /* secdRegressions */;
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 */;
};
+ 47A6FC6A206B461700BD6C54 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */;
+ targetProxy = 47A6FC69206B461700BD6C54 /* PBXContainerItemProxy */;
+ };
+ 47A6FC6C206B462400BD6C54 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */;
+ targetProxy = 47A6FC6B206B462400BD6C54 /* PBXContainerItemProxy */;
+ };
+ 47C2F18C2059CBEA0062DE30 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47C2F1822059CB680062DE30 /* KeychainResources */;
+ targetProxy = 47C2F18B2059CBEA0062DE30 /* PBXContainerItemProxy */;
+ };
+ 47C2F18E2059CBF40062DE30 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47C2F1822059CB680062DE30 /* KeychainResources */;
+ targetProxy = 47C2F18D2059CBF40062DE30 /* PBXContainerItemProxy */;
+ };
+ 47C2F1902059CBFC0062DE30 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47C2F1822059CB680062DE30 /* KeychainResources */;
+ targetProxy = 47C2F18F2059CBFC0062DE30 /* PBXContainerItemProxy */;
+ };
+ 47C2F1922059CC040062DE30 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47C2F1822059CB680062DE30 /* KeychainResources */;
+ targetProxy = 47C2F1912059CC040062DE30 /* PBXContainerItemProxy */;
+ };
47C51B8B1EEA657D0032D9E5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DC1789031D77980500B50D50 /* Security_osx */;
targetProxy = 47C51B8A1EEA657D0032D9E5 /* PBXContainerItemProxy */;
};
+ 47D991D020407F7E0078CAE2 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4727FBB61F9918580003AE36 /* secdxctests_ios */;
+ targetProxy = 47D991CF20407F7E0078CAE2 /* PBXContainerItemProxy */;
+ };
+ 47D991D720407F890078CAE2 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 478D426C1FD72A8100CAB645 /* secdxctests_mac */;
+ targetProxy = 47D991D620407F890078CAE2 /* 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 */;
target = DC52EDA61D80D58400B0A59C /* secdRegressions */;
targetProxy = 47DE88D81FA7ADBB00DD3254 /* PBXContainerItemProxy */;
};
+ 4809F7AE2061B6AA003E72D0 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EB056E3D1FE5E390000A771E /* DeviceSimulator */;
+ targetProxy = 4809F7AD2061B6AA003E72D0 /* PBXContainerItemProxy */;
+ };
+ 4809F7B02061B6B0003E72D0 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EB05C4F01FE5E48A00D68712 /* MultiDeviceSimulatorTests */;
+ targetProxy = 4809F7AF2061B6B0003E72D0 /* PBXContainerItemProxy */;
+ };
4C52D0EE16EFCD720079966E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4C52D0B316EFC61E0079966E /* CircleJoinRequested */;
target = BEF88C271EAFFC3F00357577 /* TrustedPeers */;
targetProxy = BEF88C321EAFFC3F00357577 /* PBXContainerItemProxy */;
};
- CD0637811A840C6400C81E74 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */;
- targetProxy = CD6130ED1DA1C0CC00E1E42F /* PBXContainerItemProxy */;
- };
D40B6A7F1E2B5F3D00CD6EE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D4ADA3181E2B41670031CEA3 /* libtrustd */;
target = DA30D6751DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */;
targetProxy = DA30D6811DF8C93500EC6B43 /* PBXContainerItemProxy */;
};
+ DAE40BD520CF3ED5002D5674 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DAE40BC520CF3E46002D5674 /* secitemcanarytest */;
+ targetProxy = DAE40BD420CF3ED5002D5674 /* PBXContainerItemProxy */;
+ };
DC0067901D878132005AF8DB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DC6A82911D87749900418608 /* securityd_client_macos */;
target = DC1789031D77980500B50D50 /* Security_osx */;
targetProxy = DC178BF21D77ABE300B50D50 /* PBXContainerItemProxy */;
};
+ DC193C6020CB4C9D009C1A0F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = libsecurity_cms_regressions;
+ targetProxy = DC193C5F20CB4C9D009C1A0F /* PBXContainerItemProxy */;
+ };
DC222C791E034EE700B09171 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */;
target = DC0BCC211D8C684F00070CB0 /* utilities */;
targetProxy = DC65E72E1D8CB32400152EF0 /* PBXContainerItemProxy */;
};
- DC65E7331D8CB34000152EF0 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = DC0BCC211D8C684F00070CB0 /* utilities */;
- targetProxy = DC65E7321D8CB34000152EF0 /* PBXContainerItemProxy */;
- };
DC65E7391D8CB38300152EF0 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DCB3417B1D8A2B860054D16E /* security_cdsa_utilities */;
target = E7D847C41C6BE9710025BB44 /* KeychainCircle */;
targetProxy = E7D847D01C6BE9720025BB44 /* PBXContainerItemProxy */;
};
- E7E7B24B1BFC0CD900B1E66B /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = CD276C261A83F60C003226BC /* KeychainSyncingOverIDSProxy */;
- targetProxy = CD6130EC1DA1C0CC00E1E42F /* PBXContainerItemProxy */;
- };
EB0D30FA1EF12BFB00C3C17D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = E79EEDD21CD3F8AB00C2FBFC /* Security_tests_ios */;
target = DC0BCC211D8C684F00070CB0 /* utilities */;
targetProxy = EB108F201E6CE4D2003B0456 /* PBXContainerItemProxy */;
};
+ EB11965A20A6300600BFDA1B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */;
+ targetProxy = EB11965920A6300600BFDA1B /* PBXContainerItemProxy */;
+ };
+ EB11965C20A6301100BFDA1B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */;
+ targetProxy = EB11965B20A6301100BFDA1B /* PBXContainerItemProxy */;
+ };
+ EB11965E20A6302100BFDA1B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4809F7A42061B697003E72D0 /* MultiPeerSimulatorTests */;
+ targetProxy = EB11965D20A6302100BFDA1B /* PBXContainerItemProxy */;
+ };
EB1C4CA71E85883900404981 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */;
target = EBB839A41E29665D00853BAC /* secfuzzer */;
targetProxy = EB58A0611E74C8E4009C10D7 /* PBXContainerItemProxy */;
};
+ EB636BCA20992D8900C1E21A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EB49B2AD202D877F003F34A0 /* secdmockaks */;
+ targetProxy = EB636BC920992D8900C1E21A /* PBXContainerItemProxy */;
+ };
+ EB636BD120992DA300C1E21A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EB49B2AD202D877F003F34A0 /* secdmockaks */;
+ targetProxy = EB636BD020992DA300C1E21A /* PBXContainerItemProxy */;
+ };
+ EB636BD320992DB400C1E21A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EB49B2AD202D877F003F34A0 /* secdmockaks */;
+ targetProxy = EB636BD220992DB400C1E21A /* PBXContainerItemProxy */;
+ };
+ EB636BD520992DC000C1E21A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EB49B2AD202D877F003F34A0 /* secdmockaks */;
+ targetProxy = EB636BD420992DC000C1E21A /* PBXContainerItemProxy */;
+ };
EB63ADE11C3E74F900C45A69 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = EB0BC9361C3C791500785842 /* secedumodetest */;
target = 0C7CFA2E14E1BA4800DF9D95 /* Security_frameworks_ios */;
targetProxy = EB6A6FAC1B90F84D0045DC68 /* PBXContainerItemProxy */;
};
- EB6A6FB31B90F89F0045DC68 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 790851B50CA9859F0083CC4D /* securityd_ios */;
- targetProxy = EB6A6FB21B90F89F0045DC68 /* PBXContainerItemProxy */;
- };
EB6A6FB91B90F8D70045DC68 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4C541F840F250BF500E508AE /* Security_executables_ios */;
target = 4C32C0AE0A4975F6002891BD /* Security_ios */;
targetProxy = EB6A6FBC1B90F9170045DC68 /* PBXContainerItemProxy */;
};
+ EB8910F120E0287600DE533F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4727FBB61F9918580003AE36 /* secdxctests_ios */;
+ targetProxy = EB8910F020E0287600DE533F /* PBXContainerItemProxy */;
+ };
+ EB8910F820E0287E00DE533F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4727FBB61F9918580003AE36 /* secdxctests_ios */;
+ targetProxy = EB8910F720E0287E00DE533F /* PBXContainerItemProxy */;
+ };
+ EB8910FE20E06DF500DE533F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */;
+ targetProxy = EB8910FD20E06DF500DE533F /* PBXContainerItemProxy */;
+ };
+ EB89FAFE20DBDAA800085498 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */;
+ targetProxy = EB89FAFD20DBDAA800085498 /* PBXContainerItemProxy */;
+ };
+ EB89FB0020DBDAA800085498 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */;
+ targetProxy = EB89FAFF20DBDAA800085498 /* PBXContainerItemProxy */;
+ };
+ EB89FB0220DBDAA800085498 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */;
+ targetProxy = EB89FB0120DBDAA800085498 /* PBXContainerItemProxy */;
+ };
EB9C1DB71BDFD51800F89272 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */;
target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */;
targetProxy = EBC15EA81BE29AC3001C0C5B /* PBXContainerItemProxy */;
};
+ EBC73F52209A705A00AE3350 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */;
+ targetProxy = EBC73F51209A705A00AE3350 /* PBXContainerItemProxy */;
+ };
+ EBC73F5D209A739600AE3350 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */;
+ targetProxy = EBC73F5C209A739600AE3350 /* PBXContainerItemProxy */;
+ };
+ EBC73F64209A73A100AE3350 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */;
+ targetProxy = EBC73F63209A73A100AE3350 /* PBXContainerItemProxy */;
+ };
+ EBC73F66209A73A100AE3350 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */;
+ targetProxy = EBC73F65209A73A100AE3350 /* PBXContainerItemProxy */;
+ };
+ EBCE15101FE638A2002E7CCC /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EB056E3D1FE5E390000A771E /* DeviceSimulator */;
+ targetProxy = EBCE150F1FE638A2002E7CCC /* PBXContainerItemProxy */;
+ };
EBCF743F1CE593A700BED7CA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = EBCF73F31CE45F9C00BED7CA /* secitemfunctionality */;
name = SharedWebCredentials.strings;
sourceTree = "<group>";
};
- CD6130D61DA06FC600E1E42F /* InfoPlist.strings */ = {
- isa = PBXVariantGroup;
- children = (
- CD6130D71DA06FC600E1E42F /* en */,
- );
- name = InfoPlist.strings;
- sourceTree = "<group>";
- };
D479F6DF1F980F8F00388D28 /* Trust.strings */ = {
isa = PBXVariantGroup;
children = (
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist";
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_MOBILEASSET)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
"-framework",
CrashReporterSupport,
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist";
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_MOBILEASSET)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
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 = (
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
"$(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 = "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_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_IDENTITY = "";
GCC_PREPROCESSOR_DEFINITIONS = (
"NO_SERVER=1",
"$(inherited)",
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;
+ };
+ 0C9AEEB520783FBB00BF6237 /* 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 = "";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-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_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SFTMTests;
PRODUCT_NAME = "$(TARGET_NAME)";
USE_XCTRUNNER = YES;
};
name = Debug;
};
- 0C85E0021FB38BB6000343A7 /* Release */ = {
+ 0C9AEEB620783FBB00BF6237 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
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";
+ INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-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";
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SFTMTests;
PRODUCT_NAME = "$(TARGET_NAME)";
USE_XCTRUNNER = YES;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
- 0C8BBF061FCB446400580909 /* Debug */ = {
+ 0CF4064E2072E3E3003D6A7F /* 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;
+ CODE_SIGN_IDENTITY = "";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- INSTALL_PATH = /usr/local/bin;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-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.SFTMTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ USE_XCTRUNNER = YES;
};
name = Debug;
};
- 0C8BBF071FCB446400580909 /* Release */ = {
+ 0CF4064F2072E3E3003D6A7F /* 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;
+ CODE_SIGN_IDENTITY = "";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- INSTALL_PATH = /usr/local/bin;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ INFOPLIST_FILE = "keychain/Signin Metrics/Resources/SFTMTests-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.SFTMTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ USE_XCTRUNNER = YES;
+ VALIDATE_PRODUCT = YES;
};
name = Release;
};
};
name = Release;
};
+ 3DD1FF4B201C07F30086D049 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_IDENTITY = "";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
+ GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ HEADER_SEARCH_PATHS = (
+ "$(PROJECT_DIR)",
+ "$(HEADER_SYMLINKS)",
+ "$(SDKROOT)/usr/local/include/security_libDER",
+ "$(PROJECT_DIR)/OSX/libsecurity_asn1",
+ "$(inherited)",
+ );
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework",
+ );
+ MTL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 3DD1FF4C201C07F30086D049 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_IDENTITY = "";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
+ GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ HEADER_SEARCH_PATHS = (
+ "$(PROJECT_DIR)",
+ "$(HEADER_SYMLINKS)",
+ "$(SDKROOT)/usr/local/include/security_libDER",
+ "$(PROJECT_DIR)/OSX/libsecurity_asn1",
+ "$(inherited)",
+ );
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework",
+ );
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 3DD1FFCE201FDB1D0086D049 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_IDENTITY = "";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
+ GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ HEADER_SEARCH_PATHS = (
+ "$(PROJECT_DIR)",
+ "$(HEADER_SYMLINKS)",
+ "$(SDKROOT)/usr/local/include/security_libDER",
+ "$(PROJECT_DIR)/OSX/libsecurity_asn1",
+ "$(inherited)",
+ );
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework",
+ );
+ MTL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 3DD1FFCF201FDB1D0086D049 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_IDENTITY = "";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
+ GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ HEADER_SEARCH_PATHS = (
+ "$(PROJECT_DIR)",
+ "$(HEADER_SYMLINKS)",
+ "$(SDKROOT)/usr/local/include/security_libDER",
+ "$(PROJECT_DIR)/OSX/libsecurity_asn1",
+ "$(inherited)",
+ );
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework",
+ );
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecureTransportTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
438169101B4EDCBD00C54D58 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
+ 4718AE2B205B39620068EC3F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ENABLE_MODULES = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "SECD_SERVER=1",
+ "$(inherited)",
+ );
+ 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_IMCORE)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ );
+ "OTHER_LDFLAGS[sdk=embedded][arch=*]" = (
+ "$(OTHER_LDFLAGS)",
+ "-framework",
+ MobileKeyBag,
+ "-laks",
+ "-lACM",
+ "-ObjC",
+ "-lSystem",
+ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
+ "$(OTHER_LDFLAGS_APS)",
+ "$(OTHER_LDFLAGS_CLOUDKIT)",
+ "$(OTHER_LDFLAGS_PROTOBUF)",
+ "$(OTHER_LDFLAGS_PREQUELITE)",
+ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
+ "-framework",
+ CrashReporterSupport,
+ "$(OTHER_LDFLAGS_PREQUELITE)",
+ "$(OTHER_LDFLAGS_IMCORE)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ );
+ "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
+ "$(inherited)",
+ "-ObjC",
+ );
+ PRODUCT_NAME = securityd;
+ STRIP_STYLE = debugging;
+ USE_HEADERMAP = NO;
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-error=modules-ambiguous-internal-linkage",
+ );
+ };
+ name = Debug;
+ };
+ 4718AE2C205B39620068EC3F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ENABLE_MODULES = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "SECD_SERVER=1",
+ "$(inherited)",
+ );
+ 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_IMCORE)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ );
+ "OTHER_LDFLAGS[sdk=embedded][arch=*]" = (
+ "$(OTHER_LDFLAGS)",
+ "-framework",
+ MobileKeyBag,
+ "-laks",
+ "-lACM",
+ "-lSystem",
+ "-ObjC",
+ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
+ "$(OTHER_LDFLAGS_APS)",
+ "$(OTHER_LDFLAGS_CLOUDKIT)",
+ "$(OTHER_LDFLAGS_PROTOBUF)",
+ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
+ "$(OTHER_LDFLAGS_PREQUELITE)",
+ "-framework",
+ CrashReporterSupport,
+ "$(OTHER_LDFLAGS_PREQUELITE)",
+ "$(OTHER_LDFLAGS_IMCORE)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ );
+ "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
+ "$(inherited)",
+ "-ObjC",
+ );
+ PRODUCT_NAME = securityd;
+ STRIP_STYLE = debugging;
+ USE_HEADERMAP = NO;
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-error=modules-ambiguous-internal-linkage",
+ );
+ };
+ name = Release;
+ };
+ 4718AEE0205B39C40068EC3F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ 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_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ EXECUTABLE_PREFIX = "";
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 4718AEE1205B39C40068EC3F /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ 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_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ EXECUTABLE_PREFIX = "";
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
4727FBBC1F9918590003AE36 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
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";
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
+ "OTHER_LDFLAGS[sdk=iphoneos*]" = (
+ "-L$(SDKROOT)/usr/local/lib",
+ "-laks",
+ "-laks_acl",
+ "-framework",
+ MobileKeyBag,
+ );
+ "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
+ "-L$(SDKROOT)/usr/local/lib",
+ "-laks_acl",
+ );
PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos.internal;
- TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
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";
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
+ "OTHER_LDFLAGS[sdk=iphoneos*]" = (
+ "-L$(SDKROOT)/usr/local/lib",
+ "-laks",
+ "-laks_acl",
+ "-framework",
+ MobileKeyBag,
+ );
+ "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
+ "-L$(SDKROOT)/usr/local/lib",
+ "-laks_acl",
+ );
PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos.internal;
- TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
name = Release;
};
+ 4771D976209A755800BA9772 /* 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_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_DOCUMENTATION_COMMENTS = YES;
+ 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;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ INFOPLIST_FILE = keychain/KeychainDataclassOwner/Info.plist;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Accounts/DataclassOwners";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainDataclassOwner;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos.internal;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Debug;
+ };
+ 4771D977209A755800BA9772 /* 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_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_DOCUMENTATION_COMMENTS = YES;
+ 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;
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ INFOPLIST_FILE = keychain/KeychainDataclassOwner/Info.plist;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Accounts/DataclassOwners";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainDataclassOwner;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos.internal;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Release;
+ };
478D429A1FD72A8100CAB645 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
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";
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_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;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
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";
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_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;
};
+ 47C2F1882059CB690062DE30 /* 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_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_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_STYLE = Automatic;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ INFOPLIST_FILE = keychain/KeychainResources/Info.plist;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Keychain";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainResources;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Debug;
+ };
+ 47C2F1892059CB690062DE30 /* 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_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_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_STYLE = Automatic;
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ INFOPLIST_FILE = keychain/KeychainResources/Info.plist;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Keychain";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainResources;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Release;
+ };
47C51B8C1EEA657D0032D9E5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
};
name = Release;
};
+ 4809F7A52061B697003E72D0 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 4809F7A62061B697003E72D0 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
4C52D0BE16EFC61E0079966E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)",
);
PRODUCT_NAME = "$(TARGET_NAME)";
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Debug;
};
"$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)",
);
PRODUCT_NAME = "$(TARGET_NAME)";
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
VALIDATE_PRODUCT = YES;
};
name = Release;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist";
COMBINE_HIDPI_IMAGES = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist";
COMBINE_HIDPI_IMAGES = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "secacltests/secacltests-entitlements.plist";
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
INSTALL_PATH = /usr/local/bin;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "secacltests/secacltests-entitlements.plist";
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
INSTALL_PATH = /usr/local/bin;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
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/;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_LDFLAGS = (
"-ObjC",
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/;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = (
"-ObjC",
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)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"NO_SERVER=1",
"NO_LIBTRUSTD=1",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
"-framework",
CrashReporterSupport,
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
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)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"NO_SERVER=1",
"NO_LIBTRUSTD=1",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
"-framework",
CrashReporterSupport,
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
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)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"NO_SERVER=1",
"NO_LIBTRUSTD=1",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
"-framework",
CrashReporterSupport,
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
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)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"NO_SERVER=1",
"NO_LIBTRUSTD=1",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
"-framework",
CrashReporterSupport,
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
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";
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";
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;
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";
DEBUG_INFORMATION_FORMAT = dwarf;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
- "$(SDKROOT)/../../Library/Frameworks",
- "$(SDKROOT)/../../AppleInternal/Library/Frameworks",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ "$(PLATFORM_DIR)/Developer/AppleInternal/Library/Frameworks",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
ENABLE_NS_ASSERTIONS = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
- "$(SDKROOT)/../../Library/Frameworks",
- "$(SDKROOT)/../../AppleInternal/Library/Frameworks",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ "$(PLATFORM_DIR)/Developer/AppleInternal/Library/Frameworks",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
INFOPLIST_FILE = "Security-Info.plist";
INSTALLHDRS_SCRIPT_PHASE = YES;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+ IS_ZIPPERED = YES;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(SDKROOT)/usr/local/lib/security_libDER",
INFOPLIST_FILE = "Security-Info.plist";
INSTALLHDRS_SCRIPT_PHASE = YES;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+ IS_ZIPPERED = YES;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(SDKROOT)/usr/local/lib/security_libDER",
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
PRODUCT_NAME = security;
STRIP_STYLE = debugging;
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Debug;
};
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_PREQUELITE)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
PRODUCT_NAME = security;
STRIP_STYLE = debugging;
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Release;
};
CLANG_ENABLE_MODULES = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"SECD_SERVER=1",
"$(inherited)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"-framework",
CrashReporterSupport,
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
CLANG_ENABLE_MODULES = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"SECD_SERVER=1",
"$(inherited)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"-framework",
CrashReporterSupport,
"$(OTHER_LDFLAGS_PREQUELITE)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_STATIC_ANALYZER_MODE = shallow;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
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_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
+ EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = "$(SRCROOT)/sslViewer/ecc-secp256r1-client.pfx";
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = NO;
INSTALL_DAEMON_AGENT_DIR = "$(SYSTEM_LIBRARY_DIR)/LaunchDaemons";
"INSTALL_DAEMON_AGENT_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/LaunchAgents";
+ LLVM_LTO = YES_THIN;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "";
RUN_CLANG_STATIC_ANALYZER = YES;
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_STATIC_ANALYZER_MODE = shallow;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
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_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = "$(SRCROOT)/sslViewer/ecc-secp256r1-client.pfx";
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = s;
HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = NO;
INSTALL_DAEMON_AGENT_DIR = "$(SYSTEM_LIBRARY_DIR)/LaunchDaemons";
"INSTALL_DAEMON_AGENT_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/LaunchAgents";
+ LLVM_LTO = YES;
OTHER_LDFLAGS = "";
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx.internal;
};
name = Release;
};
- CD276C2D1A83F60C003226BC /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_ENTITLEMENTS = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist;
- COMBINE_HIDPI_IMAGES = YES;
- COPY_PHASE_STRIP = NO;
- "DEBUG_INFORMATION_FORMAT[sdk=macosx*]" = "dwarf-with-dsym";
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_SYMBOLS_PRIVATE_EXTERN = NO;
- GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- HEADER_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/OSX/sec/SOSCircle/CKBridge",
- );
- INFOPLIST_FILE = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist";
- INSTALL_PATH = "$(SECURITY_FRAMEWORK_RESOURCES_DIR)";
- MACH_O_TYPE = mh_execute;
- ONLY_ACTIVE_ARCH = YES;
- OTHER_LDFLAGS = (
- "-laks",
- "-ObjC",
- );
- "OTHER_LDFLAGS[sdk=embeddedsimulator*]" = "-ObjC";
- PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.keychainsyncingoveridsproxy;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SKIP_INSTALL = NO;
- STRIP_INSTALLED_PRODUCT = NO;
- STRIP_STYLE = all;
- WRAPPER_EXTENSION = bundle;
- };
- name = Debug;
- };
- CD276C2E1A83F60C003226BC /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_ENTITLEMENTS = KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.entitlements.plist;
- COMBINE_HIDPI_IMAGES = YES;
- COPY_PHASE_STRIP = NO;
- "DEBUG_INFORMATION_FORMAT[sdk=macosx*]" = "dwarf-with-dsym";
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
- HEADER_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/OSX/sec/SOSCircle/CKBridge",
- );
- INFOPLIST_FILE = "KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy-Info.plist";
- INSTALL_PATH = "$(SECURITY_FRAMEWORK_RESOURCES_DIR)";
- MACH_O_TYPE = mh_execute;
- OTHER_LDFLAGS = (
- "-laks",
- "-ObjC",
- );
- "OTHER_LDFLAGS[sdk=embeddedsimulator*]" = "-ObjC";
- PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.keychainsyncingoveridsproxy;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SKIP_INSTALL = NO;
- STRIP_STYLE = all;
- VALIDATE_PRODUCT = YES;
- WRAPPER_EXTENSION = bundle;
- };
- name = Release;
- };
D41257D71E9410A300781F23 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
+ DAE40BCC20CF3E46002D5674 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ 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_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemcanarytest/secitemcanarytest.entitlements;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ 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 = /AppleInternal/CoreOS/tests/Security;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
+ };
+ name = Debug;
+ };
+ DAE40BCD20CF3E46002D5674 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ 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_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemcanarytest/secitemcanarytest.entitlements;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ 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 = /AppleInternal/CoreOS/tests/Security;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
DC0067BE1D87876F005AF8DB /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */;
"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_OBJC_ARC = NO;
+ CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_OBJC_ARC = NO;
+ CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_ENUM_CONVERSION = NO;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_ENUM_CONVERSION = NO;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ );
GCC_DYNAMIC_NO_PIC = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_LDFLAGS = (
- "-laks",
- "-lCrashReporterClient",
- "-Wl,-upward_framework,Foundation",
"$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)",
+ "$(inherited)",
);
SUPPORTS_TEXT_BASED_API = YES;
TAPI_VERIFY_MODE = ErrorsAndWarnings;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ );
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = (
- "-laks",
- "-lCrashReporterClient",
- "-Wl,-upward_framework,Foundation",
"$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)",
+ "$(inherited)",
);
SUPPORTS_TEXT_BASED_API = YES;
TAPI_VERIFY_MODE = ErrorsAndWarnings;
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_INT_CONVERSION = 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_INT_CONVERSION = YES;
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)",
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)",
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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
MTL_ENABLE_DEBUG_INFO = YES;
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Debug;
};
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_INT_CONVERSION = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
MTL_ENABLE_DEBUG_INFO = NO;
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Release;
};
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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ );
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+ );
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = NO;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = NO;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = NO;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = NO;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
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_INT_CONVERSION = 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_INT_CONVERSION = YES;
buildSettings = {
"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_ANALYZER_NONNULL = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
buildSettings = {
"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_ANALYZER_NONNULL = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = 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_INT_CONVERSION = YES;
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
PRODUCT_NAME = security2;
SUPPORTED_PLATFORMS = macosx;
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Debug;
};
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
PRODUCT_NAME = security2;
SUPPORTED_PLATFORMS = macosx;
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Release;
};
CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist;
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"SECD_SERVER=1",
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Debug;
};
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
};
name = Release;
};
APPLY_RULES_IN_COPY_FILES = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
APPLY_RULES_IN_COPY_FILES = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist";
COMBINE_HIDPI_IMAGES = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"-framework",
CrashReporterSupport,
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist";
COMBINE_HIDPI_IMAGES = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
GCC_PREPROCESSOR_DEFINITIONS = (
"LIBTRUSTD=1",
"$(inherited)",
"$(OTHER_LDFLAGS_PROTOBUF)",
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"$(OTHER_LDFLAGS_SECURITYFOUNDATION)",
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
"$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
"-framework",
CrashReporterSupport,
- "$(OTHER_LDFLAGS_CORECDP)",
"$(OTHER_LDFLAGS_IMCORE)",
"$(OTHER_LDFLAGS_ACCOUNTS)",
);
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
INFOPLIST_FILE = KeychainCircle/Info.plist;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ IS_ZIPPERED = YES;
MODULEMAP_FILE = Modules/KeychainCircle.modulemap;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
INFOPLIST_FILE = KeychainCircle/Info.plist;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ IS_ZIPPERED = YES;
MODULEMAP_FILE = Modules/KeychainCircle.modulemap;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEGESTALT)";
};
name = Release;
};
+ EB056E471FE5E391000A771E /* 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_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 = "MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ INFOPLIST_FILE = MultiDeviceSimulator/DeviceSimulator/Info.plist;
+ 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_WIRELESSDIAGNOSTICS)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ "$(OTHER_LDFLAGS_APPLEACCOUNT)",
+ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ "$(OTHER_LDFLAGS_APPLEACCOUNT)",
+ "-ObjC",
+ );
+ "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)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ "$(OTHER_LDFLAGS_APPLEACCOUNT)",
+ "-ObjC",
+ "-framework",
+ CrashReporterSupport,
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.DeviceSimulator;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ };
+ name = Debug;
+ };
+ EB056E481FE5E391000A771E /* 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_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 = "MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "NO_SERVER=1",
+ "$(inherited)",
+ );
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ INFOPLIST_FILE = MultiDeviceSimulator/DeviceSimulator/Info.plist;
+ 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_ACCOUNTS)",
+ "$(OTHER_LDFLAGS_APPLEACCOUNT)",
+ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)",
+ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ "$(OTHER_LDFLAGS_APPLEACCOUNT)",
+ "-ObjC",
+ );
+ "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)",
+ "$(OTHER_LDFLAGS_ACCOUNTS)",
+ "$(OTHER_LDFLAGS_APPLEACCOUNT)",
+ "-ObjC",
+ "-framework",
+ CrashReporterSupport,
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.DeviceSimulator;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+ EB05C4F61FE5E48B00D68712 /* 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_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)/../../AppleInternal/Library/Frameworks",
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ INFOPLIST_FILE = MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist;
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks";
+ MTL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.MultiDeviceSimulatorTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = NO;
+ };
+ name = Debug;
+ };
+ EB05C4F71FE5E48B00D68712 /* 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_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)/../../AppleInternal/Library/Frameworks",
+ );
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ INFOPLIST_FILE = MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist;
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks";
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.MultiDeviceSimulatorTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = NO;
+ };
+ name = Release;
+ };
EB0BC93C1C3C791500785842 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */;
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";
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_LDFLAGS = (
"$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)",
);
PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = NO;
};
name = Debug;
};
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";
+ INSTALL_PATH = /AppleInternal/XCTests/com.apple.security;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = (
"$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)",
);
PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = NO;
};
name = Release;
};
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 0C9AEEB420783FBB00BF6237 /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_osx" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 0C9AEEB520783FBB00BF6237 /* Debug */,
+ 0C9AEEB620783FBB00BF6237 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 0CF4064D2072E3E3003D6A7F /* Build configuration list for PBXNativeTarget "SignInAnalyticsTests_ios" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 0CF4064E2072E3E3003D6A7F /* Debug */,
+ 0CF4064F2072E3E3003D6A7F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
225394B11E3080A600D3CD9B /* Build configuration list for PBXNativeTarget "security_codesigning_ios" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_macos_tests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3DD1FF4B201C07F30086D049 /* Debug */,
+ 3DD1FF4C201C07F30086D049 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_ios_tests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3DD1FFCE201FDB1D0086D049 /* Debug */,
+ 3DD1FFCF201FDB1D0086D049 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
438169381B4EDCBD00C54D58 /* Build configuration list for PBXNativeTarget "SOSCCAuthPlugin" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 4718AE2A205B39620068EC3F /* Build configuration list for PBXNativeTarget "securityd_bridge" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4718AE2B205B39620068EC3F /* Debug */,
+ 4718AE2C205B39620068EC3F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4718AEDF205B39C40068EC3F /* Build configuration list for PBXNativeTarget "libsecurityd_bridge" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4718AEE0205B39C40068EC3F /* Debug */,
+ 4718AEE1205B39C40068EC3F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
4727FBC31F9918590003AE36 /* Build configuration list for PBXNativeTarget "secdxctests_ios" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 4771D97D209A755900BA9772 /* Build configuration list for PBXNativeTarget "KeychainDataclassOwner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4771D976209A755800BA9772 /* Debug */,
+ 4771D977209A755800BA9772 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
478D42991FD72A8100CAB645 /* Build configuration list for PBXNativeTarget "secdxctests_mac" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 47C2F1872059CB690062DE30 /* Build configuration list for PBXNativeTarget "KeychainResources" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 47C2F1882059CB690062DE30 /* Debug */,
+ 47C2F1892059CB690062DE30 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
47C51B931EEA657D0032D9E5 /* Build configuration list for PBXNativeTarget "SecurityUnitTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 4809F7AC2061B697003E72D0 /* Build configuration list for PBXAggregateTarget "MultiPeerSimulatorTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4809F7A52061B697003E72D0 /* Debug */,
+ 4809F7A62061B697003E72D0 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
4C32C0B10A4975F7002891BD /* Build configuration list for PBXNativeTarget "Security_ios" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- CD276C2C1A83F60C003226BC /* Build configuration list for PBXNativeTarget "KeychainSyncingOverIDSProxy" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CD276C2D1A83F60C003226BC /* Debug */,
- CD276C2E1A83F60C003226BC /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
D41257D61E9410A300781F23 /* Build configuration list for PBXNativeTarget "trustd_ios" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ DAE40BCB20CF3E46002D5674 /* Build configuration list for PBXNativeTarget "secitemcanarytest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DAE40BCC20CF3E46002D5674 /* Debug */,
+ DAE40BCD20CF3E46002D5674 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
DC0067BD1D87876F005AF8DB /* Build configuration list for PBXNativeTarget "securityd_server_macos" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ EB056E4E1FE5E391000A771E /* Build configuration list for PBXNativeTarget "DeviceSimulator" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EB056E471FE5E391000A771E /* Debug */,
+ EB056E481FE5E391000A771E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ EB05C4FD1FE5E48B00D68712 /* Build configuration list for PBXNativeTarget "MultiDeviceSimulatorTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EB05C4F61FE5E48B00D68712 /* Debug */,
+ EB05C4F71FE5E48B00D68712 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
EB0BC93B1C3C791500785842 /* Build configuration list for PBXNativeTarget "secedumodetest" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
+
+/* Begin XCVersionGroup section */
+ 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */ = {
+ isa = XCVersionGroup;
+ children = (
+ 470D966C1FCDE4BA0065FE90 /* KeychainModel.xcdatamodel */,
+ );
+ currentVersion = 470D966C1FCDE4BA0065FE90 /* KeychainModel.xcdatamodel */;
+ path = KeychainModel.xcdatamodeld;
+ sourceTree = "<group>";
+ versionGroupType = wrapper.xcdatamodel;
+ };
+/* End XCVersionGroup section */
};
rootObject = 4C35DB69094F906D002917C4 /* Project object */;
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>classNames</key>
+ <dict>
+ <key>ClientInfoByNotification</key>
+ <dict>
+ <key>testMaster2</key>
+ <dict>
+ <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
+ <dict>
+ <key>baselineAverage</key>
+ <real>1.2728</real>
+ <key>baselineIntegrationDisplayName</key>
+ <string>Local Baseline</string>
+ </dict>
+ </dict>
+ <key>testSOSIsThisDeviceInCircle</key>
+ <dict>
+ <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
+ <dict>
+ <key>baselineAverage</key>
+ <real>0.33445</real>
+ <key>baselineIntegrationDisplayName</key>
+ <string>Local Baseline</string>
+ </dict>
+ </dict>
+ <key>testSOSMultiView</key>
+ <dict>
+ <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
+ <dict>
+ <key>baselineAverage</key>
+ <real>1.2679</real>
+ <key>baselineIntegrationDisplayName</key>
+ <string>Local Baseline</string>
+ </dict>
+ </dict>
+ <key>testSOSViews2</key>
+ <dict>
+ <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
+ <dict>
+ <key>baselineAverage</key>
+ <real>0.319</real>
+ <key>baselineIntegrationDisplayName</key>
+ <string>Local Baseline</string>
+ </dict>
+ </dict>
+ </dict>
+ </dict>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>runDestinationsByUUID</key>
+ <dict>
+ <key>B3656633-AB83-4153-B404-DE14DBDC5ED6</key>
+ <dict>
+ <key>localComputer</key>
+ <dict>
+ <key>busSpeedInMHz</key>
+ <integer>100</integer>
+ <key>cpuCount</key>
+ <integer>1</integer>
+ <key>cpuKind</key>
+ <string>Intel Core i7</string>
+ <key>cpuSpeedInMHz</key>
+ <integer>2600</integer>
+ <key>logicalCPUCoresPerPackage</key>
+ <integer>8</integer>
+ <key>modelCode</key>
+ <string>MacBookPro13,3</string>
+ <key>physicalCPUCoresPerPackage</key>
+ <integer>4</integer>
+ <key>platformIdentifier</key>
+ <string>com.apple.platform.macosx</string>
+ </dict>
+ <key>targetArchitecture</key>
+ <string>x86_64</string>
+ </dict>
+ </dict>
+</dict>
+</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
- shouldUseLaunchSchemeArgsEnv = "YES"
- codeCoverageEnabled = "YES">
+ codeCoverageEnabled = "YES"
+ shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "1.7">
<BuildAction
parallelizeBuildables = "NO"
argument = "si_33_keychain_backup"
isEnabled = "NO">
</CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_34_cms_timestamp"
+ isEnabled = "NO">
+ </CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_35_cms_expiration_time"
+ isEnabled = "NO">
+ </CommandLineArgument>
<CommandLineArgument
argument = "si_40_seckey"
isEnabled = "NO">
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
- argument = "si_44_seckey_fv"
+ argument = "si_44_seckey_skv"
+ isEnabled = "NO">
+ </CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_44_seckey_proxy"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
argument = "si_33_keychain_backup"
isEnabled = "NO">
</CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_34_cms_timestamp"
+ isEnabled = "NO">
+ </CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_35_cms_expiration_time"
+ isEnabled = "NO">
+ </CommandLineArgument>
<CommandLineArgument
argument = "si_40_seckey"
isEnabled = "NO">
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
ReferencedContainer = "container:Security.xcodeproj">
</BuildableReference>
</TestableReference>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "EB49B2AD202D877F003F34A0"
+ BuildableName = "secdmockaks.xctest"
+ BlueprintName = "secdmockaks"
+ ReferencedContainer = "container:Security.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "EB05C4F01FE5E48A00D68712"
+ BuildableName = "MultiDeviceSimulatorTests.xctest"
+ BlueprintName = "MultiDeviceSimulatorTests"
+ ReferencedContainer = "container:Security.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
argument = "cms_01_basic"
isEnabled = "NO">
</CommandLineArgument>
- <CommandLineArgument
- argument = "cms_hash_agility_test"
- isEnabled = "NO">
- </CommandLineArgument>
<CommandLineArgument
argument = "cms_trust_settings_test"
isEnabled = "NO">
argument = "si_32_sectrust_pinning_required"
isEnabled = "NO">
</CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_34_cms_timestamp"
+ isEnabled = "NO">
+ </CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_35_cms_expiration_time"
+ isEnabled = "NO">
+ </CommandLineArgument>
<CommandLineArgument
argument = "si_44_seckey_gen"
isEnabled = "NO">
argument = "si_44_seckey_aks"
isEnabled = "NO">
</CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_44_seckey_proxy"
+ isEnabled = "NO">
+ </CommandLineArgument>
<CommandLineArgument
argument = "si_60_cms"
isEnabled = "NO">
argument = "si_88_sectrust_valid"
isEnabled = "NO">
</CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_89_cms_hash_agility"
+ isEnabled = "NO">
+ </CommandLineArgument>
+ <CommandLineArgument
+ argument = "si_97_sectrust_path_scoring"
+ isEnabled = "NO">
+ </CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
<EnvironmentVariable
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
argument = "secd_36_ks_encrypt"
isEnabled = "NO">
</CommandLineArgument>
- <CommandLineArgument
- argument = "secd_66_account_recovery"
- isEnabled = "NO">
- </CommandLineArgument>
<CommandLineArgument
argument = "secd_20_keychain_upgrade"
isEnabled = "NO">
argument = "secd_62_account_backup"
isEnabled = "NO">
</CommandLineArgument>
+ <CommandLineArgument
+ argument = "secd_66_account_recovery"
+ isEnabled = "NO">
+ </CommandLineArgument>
<CommandLineArgument
argument = "secd_200_logstate"
isEnabled = "NO">
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0900"
+ LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIEUDCCAzigAwIBAgIEGThNuTANBgkqhkiG9w0BAQsFADCBhzEeMBwGA1UEAwwV
+VmFsaWQgVGVzdCBDQSBSb290IFYyMSIwIAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRl
+c3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRp
+bm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzAgFw0xNzA1MDEyMzE4MzBaGA8y
+MTE3MDQwNzIzMTgzMFowgZ8xNjA0BgNVBAMMLUNBIHNlcmlhbCBpbnZhbGlkIGtu
+b3duaW50ZXJtZWRpYXRlcyBjb21wbGV0ZTEiMCAGA1UECwwZVmFsaWQgUHJvamVj
+dCBUZXN0IENBcyBWMjETMBEGA1UECgwKQXBwbGUgSW5jLjESMBAGA1UEBwwJQ3Vw
+ZXJ0aW5vMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDJIAUwIWx3drEgTsVk2S8oLyB/Hg6TkFW8A2HlxnsO
+RSrPaWLKsoU3jVWhwO2qZ8H98fknl32GJ71/zyWfJkNu3Rs7Nu2SpyG3nvdWCMOF
+bLe5Zx2DOiYtjSC7LEAHLE4jL6GZcN9kGf8Rl4IjZnOTm/bEzQwLSuIlRPe6Dni5
+LkUj8Nk4EiN6QcJKZtFX2UUrYS3wvj+YOv3VzkaghhOiqpoFCnm3RuZnBo5+4wHV
+lpG6NgHl4rnFmvwi3Vb6w1qevkf9uY2Q6SpXeTKz2J8l0hxaJ+Nti6wsaLXzag4h
+fSpBf1BHXURHuuiI9UkaHQRO4eftsWxyhjgjLPDjCkqvAgMBAAGjgacwgaQwDgYD
+VR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFBwLKWM0
+c67hVQOiXKrmAHltFX5VMB8GA1UdIwQYMBaAFLpW2Fdmvfxb4hDyObOvsnLtVQ8c
+MD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly92YWxpZHRlc3QuYXBwbGUuZ2VvZmZr
+Lm5ldC92Mi1yb290LmNybDANBgkqhkiG9w0BAQsFAAOCAQEAmOE9d6b0sU/y9mtM
+NQF45CFyz1JXBMZTJ3ZxUW6LgG2L9DJFq684BmqcG0TAHFX9qOx3v45QZxWcGLZ5
+Ft8UeNqjDfTb2OM8weTY06d1TYY9XLK2utEnejxG0vp+UrKn7dsg/yPmoj/ffX5Z
+qXSZUBxkhKwm0SVbtFSM2LM5VGmTcuOKYyJ/dNcx8/t/ccj2DhRR4K/2TKPjWUQH
+sgh4jGZtXYVcjIsRBAbX8ZsdyvVQnLSB0bLdEH883OmFCo52wr9J53HMxQr6SdBE
+RqUhDED847/nRqIRVLKLrfdZ6sBuXtpy1yIodbIfuYo7Ho0qgLyd/NruZebLRCPU
+Sd4/DQ==
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIID1DCCArygAwIBAgIDEtaHMA0GCSqGSIb3DQEBCwUAMIGfMTYwNAYDVQQDDC1D
+QSBzZXJpYWwgaW52YWxpZCBrbm93bmludGVybWVkaWF0ZXMgY29tcGxldGUxIjAg
+BgNVBAsMGVZhbGlkIFByb2plY3QgVGVzdCBDQXMgVjIxEzARBgNVBAoMCkFwcGxl
+IEluYy4xEjAQBgNVBAcMCUN1cGVydGlubzELMAkGA1UECAwCQ0ExCzAJBgNVBAYT
+AlVTMB4XDTE4MDMwOTIwNTc1OVoXDTM2MDYwODIwNTc1OVowfTEXMBUGA1UEAwwO
+VW5rbm93biBTdWIgQ0ExEzARBgNVBAoMCkFwcGxlIEluYy4xHzAdBgNVBAsMFlZh
+bGlkIFByb2plY3QgVGVzdCBDQXMxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzES
+MBAGA1UEBwwJQ3VwZXJ0aW5vMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAxnuV6JsM+4D8ScDqgtfG2wDA3QTyAC9uc222LNo72Qgn4QbGiuGSVCAUbL9v
+pbms80InEPDwdOlBak645fPui9F7mtOqtyfhXZEdi7gpQ2UABusYfLf6jGwBhNY5
+uytGuE68RrIwUgAiOeNbCouM8+49vFCKby6O6VC6Cd6eKDVBDC3NQ84pWrCrc/tk
+xDPEkZKmveRSKRoVFbl4auZ6sIFDI9sCPtZoUDIFBKtu3ViuP8HqL4BIRtaxeSZc
+hm2ot46YkETdCkpCBWbpgZId9dNV85AzO7kasqnSDmCy7xWO2OOnlHRoCAYGbMZs
+0RXEwsb0VOW/6TjF093isg6WowIDAQABozowODASBgNVHRMBAf8ECDAGAQH/AgEB
+MA4GA1UdDwEB/wQEAwIBhjASBgNVHSUBAf8ECDAGBgRVHSUAMA0GCSqGSIb3DQEB
+CwUAA4IBAQBga32SiOdPlLHJ2DyDX6MSJ9rW4Rak+xFyQFRbNdBqZNw16mAzifnD
+W2HiLdZeXTUvHTNiJ9nXjtvdYzKcKlmYHxroF8P5E+MxrobNvrc+5ZEg+IDFnGEP
+S3EwyfQp3Z3/Dkwy7gE/GTSo/G33vYydJY7jf9uSegoAViwRammXRLgr06Zp8/Jb
+JJcrk806isUJcHkR/hUHMKUQehRWjMQ2/gdhlqf5/CsHU1DgQCQWent9Auo7WnRK
+uOnptpx6cxSbBSmOoJz4242PvhH4rPNKV3+8crcZmz0IHE64Iv2qUc0ahe6I1Lg3
+t8Y/sPm9Hj3vzWQDgrAOTdaiKQIAGs8l
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIEqjCCA5KgAwIBAgIEVFmpmjANBgkqhkiG9w0BAQsFADCBnzE2MDQGA1UEAwwt
+Q0Egc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBsZXRlMSIw
+IAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBs
+ZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQG
+EwJVUzAgFw0xNzA1MDEyMzE4MzFaGA8yMTE3MDQwNzIzMTgzMVowgaUxPDA6BgNV
+BAMMM0xlYWYgc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBs
+ZXRlIG9rMTEiMCAGA1UECwwZVmFsaWQgUHJvamVjdCBUZXN0IENBcyBWMjETMBEG
+A1UECgwKQXBwbGUgSW5jLjESMBAGA1UEBwwJQ3VwZXJ0aW5vMQswCQYDVQQIDAJD
+QTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCu
+cW/2bddC4ZOKKgn65zNufVK/wCM/ebnprHdB9tgEsu5Z8BEGO8ixWMr/5EdRp9TW
+3tWUm93ckntuVBoOsHESyBEker3RnBWpAyHJkxwrgBCuBOep/idABD3Aqn0dzsh2
+UXQWwZS2ZL1Azs3BYijbxspRx5SLVg8kwfOSPVrfAWdv3VZUNJkBcKvQBchAdqCb
+MK2K1UeRsAcsNJHqUHrCcGNoJNsi99JumHoUd0r39PdiI2LSFlxfQn8nkRFI6Z0v
+L+b37KvvPlRqQgIaYtjHfUP8N0PSBMm+dJyOXYWBTO0a4WRYsedjq6GoKRCutfgK
+KPGAZdObZTjXH8NMhK7jAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgeAMAwGA1Ud
+EwEB/wQCMAAwHwYDVR0jBBgwFoAUHAspYzRzruFVA6JcquYAeW0VflUwZAYDVR0f
+BF0wWzBZoFegVYZTaHR0cDovL3ZhbGlkdGVzdC5hcHBsZS5nZW9mZmsubmV0L3Yy
+LXNlcmlhbC1pbnZhbGlkLWtub3duaW50ZXJtZWRpYXRlcy1jb21wbGV0ZS5jcmww
+OQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzABhh1odHRwOi8va25vd24tYW5zd2Vy
+LW9jc3Avb2NzcDANBgkqhkiG9w0BAQsFAAOCAQEAt/3xiKm+WlVXOuD/N9Tq/P0S
+Q56j+pKki0w8RgPSgihRjgyxxAAIcWURvRejCVkP6VkX0eS0dv3UQc8Wy3kYu8lt
+IZgpnZNwptlGSd0sweyjN20d4tpt969aSPUIYLlgSby9fQ7TI/sadYfsFrlWyQth
+xXg5pTqnqQpUGlDDHYmihTepqx0gk0Az+0z+vXPozbfO9x7whfUUTNC4jvFyUEuP
+82/M7KbjicwvDVu6Jyc8ZfLTw1laE4+w3KOrn5Ynm8sDh7gj66gV0L1IgSl3IO8h
+7EhzaUJxXDpm21iPNTh21EbC1KmCa4oYUMENyp/Ec3x6m2qayMAmg7sEcoTX/A==
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIErzCCA5egAwIBAgIESpPvUDANBgkqhkiG9w0BAQsFADCBnzE2MDQGA1UEAwwt
+Q0Egc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBsZXRlMSIw
+IAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBs
+ZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQG
+EwJVUzAgFw0xNzA1MDEyMzE4MzFaGA8yMTE3MDQwNzIzMTgzMVowgaoxQTA/BgNV
+BAMMOExlYWYgc2VyaWFsIGludmFsaWQga25vd25pbnRlcm1lZGlhdGVzIGNvbXBs
+ZXRlIHJldm9rZWQxMSIwIAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYy
+MRMwEQYDVQQKDApBcHBsZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNV
+BAgMAkNBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKayI84lr4zpbmuAf0URoM7QMRWjPF5eTtXbdz20yiWyQwYV6YWh7A9IEy5H
+5pMwdZUoYcZhmFToP9EAZe67VHP/qIxB3IwRGy4OCsc/o+q0nIOkNSvXpgDtDuPD
+u+mlVIE0wsxJ1VH9kP8RiX15KNG+yINVSypTAq2lelGub/gG+2Kx3HtprFnBBtU9
+ND9uAd2CaXJrzOnstc7gp78lJIvgPbhvGEydsToULCn0q3f05ix2zPCE1Eb+McuW
+qaSdJvZUExIyVLy23wUlfAg+RMvdjZQk1KXqhAt5YsgYAd1jk6IMs4elN1RGPjfL
+u5Hvixu4UmcGMXkxS5Wg+tSpxU8CAwEAAaOB4zCB4DAOBgNVHQ8BAf8EBAMCB4Aw
+DAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQcCyljNHOu4VUDolyq5gB5bRV+VTBk
+BgNVHR8EXTBbMFmgV6BVhlNodHRwOi8vdmFsaWR0ZXN0LmFwcGxlLmdlb2Zmay5u
+ZXQvdjItc2VyaWFsLWludmFsaWQta25vd25pbnRlcm1lZGlhdGVzLWNvbXBsZXRl
+LmNybDA5BggrBgEFBQcBAQQtMCswKQYIKwYBBQUHMAGGHWh0dHA6Ly9rbm93bi1h
+bnN3ZXItb2NzcC9vY3NwMA0GCSqGSIb3DQEBCwUAA4IBAQAT4czdt+80U/vnc1YT
+66FDELYBfSCcJPtOHeBUWnpgHj0HEL4qpwC4rZeYi2SwnvfZuIIRMOnsH+HlhsHI
+CXboHIj4kgay3AH5SohpdrdB5UOSiuBFW/Be0/6hvTI9pPz8k/SPFTGuFu9CWcaA
+BDJy3+NyZi/FWbkVi+GbmZ+T9o/2Gf1ttzuiAbocvP8qC80VsSK1KcN5hgbj24bC
+OUZ6ntHWoNtpW3rH9QtVa6DsMRJyhsotuAu3jLwwjqKp7DmBOIDmh24k+ZX0J/N+
+8TB3QLT0VMKxP8oBBl+H6DlcsrOV9xMNqxARHtt7mVmqDhqqUiY7USBpNA9SXy2n
+HjA+
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIDAbIHMA0GCSqGSIb3DQEBCwUAMH0xFzAVBgNVBAMMDlVu
+a25vd24gU3ViIENBMRMwEQYDVQQKDApBcHBsZSBJbmMuMR8wHQYDVQQLDBZWYWxp
+ZCBQcm9qZWN0IFRlc3QgQ0FzMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMxEjAQ
+BgNVBAcMCUN1cGVydGlubzAeFw0xODAzMDkyMTAwMjBaFw0zNjA2MDYyMTAwMjBa
+MIGHMSEwHwYDVQQDDBhMZWFmIGZyb20gVW5rbm93biBTdWIgQ0ExEzARBgNVBAoM
+CkFwcGxlIEluYy4xHzAdBgNVBAsMFlZhbGlkIFByb2plY3QgVGVzdCBDQXMxCzAJ
+BgNVBAgMAkNBMQswCQYDVQQGEwJVUzESMBAGA1UEBwwJQ3VwZXJ0aW5vMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxDNtFGlFe98xSVT+9RRYeOWp2ppi
+yBloDCrxKegtm/jE8TrK3tCr0Bc2eTUn7uWHDuPlTSChdQ9Ty7ieYujx+7RIdPdp
+BLCfSPxjyxKeqTnoUzYj7fZYKO9HGwS/VcTib/H6ucdTsF1qBdEKuXgPS21XH6HM
+P50bfkyEhP7rWd479GIfzB3vVC36q5qk60oVadntOmFw2rNm8Oxw3XfI6rYhbIJv
+Mz9M+buXKS0wA5TCHBPYHZkF2W2IWzPPppE7Kg+skKUD+tz990dCt1/yU4iyFWlc
+1F79VFx+SAa8pMMpMPKmJjEArtH5Vndgf/9+G95XJpcqhuaPz0PrlGhXKQIDAQAB
+oyYwJDAOBgNVHQ8BAf8EBAMCB4AwEgYDVR0lAQH/BAgwBgYEVR0lADANBgkqhkiG
+9w0BAQsFAAOCAQEAsaWTLZo0Xm4xa0zdRshyuYAT/NiRFnmxcRjcGlPIPfaqAmPE
+faz42DhIBOWQu/yC17VommNm8SSLNRmlCKSw0kuJLWvxyw1nYKJnAmJNboiQH5V4
+Rg6qMMm/uCfx1kkZBG5NyF589JMpJ/p1Fd7uI9BDBvolG5wDzRHmCe509F/La2Lw
+Kw9xBHCe2yFn4QnZt/S3ZWB8ObHK2/jyFNlMhSsdXr9KmhNxnI0SZqE7guQ6CeEa
+FBd6KbEqLXiUyQyZifKIiGOiDyinDNEJ6bHRuhdE4JNw3R7YF/dBcZgcgHoBJ4JC
+U7/3SY9cxAXc4p6Y/pSs7eISTcXKivgbn4Arow==
+-----END CERTIFICATE-----
authorize(int argc, char * const *argv)
{
int ch;
+ int retval = 1;
OSStatus status;
Boolean user_interaction_allowed = FALSE, extend_rights = TRUE;
(least_privileged ? kAuthorizationFlagLeastPrivileged : 0);
// set up AuthorizationRightSet
- AuthorizationItem rights[argc];
+ AuthorizationItem *rights = malloc(argc * sizeof(AuthorizationItem));
+ if (!rights) {
+ fprintf(stderr, "Out of memory\n");
+ retval = 1;
+ goto bail;
+ }
memset(rights, '\0', argc * sizeof(AuthorizationItem));
AuthorizationItemSet rightset = { argc, rights };
while (argc > 0)
if (internalize)
{
auth_ref = read_auth_ref_from_stdin();
- if (!auth_ref)
- return 1;
+ if (!auth_ref) {
+ retval = 1;
+ goto bail;
+ }
}
if (!auth_ref && AuthorizationCreate(NULL, NULL,
(least_privileged ? kAuthorizationFlagLeastPrivileged : 0),
- &auth_ref))
- return -1;
+ &auth_ref)) {
+ retval = -1;
+ goto bail;
+ }
// prepare environment if needed
AuthorizationEnvironment *envp = NULL;
if (!login)
login = getlogin();
char *pass = getpass("Password:");
- if (!(login && pass))
- return 1;
+ if (!(login && pass)) {
+ retval = 1;
+ goto bail;
+ }
static AuthorizationItem authenv[] = {
{ kAuthorizationEnvironmentUsername },
{ kAuthorizationEnvironmentPassword },
if (auth_ref)
AuthorizationFree(auth_ref, destroy_rights ? kAuthorizationFlagDestroyRights : 0);
- return (status ? -1 : 0);
+ retval = (status ? -1 : 0);
+bail:
+ if (rights)
+ free(rights);
+
+ return retval;
}
SecKeychainItemRef itemRef = NULL;
void *passwordData = NULL;
+ if (!itemCreator && !itemType && !kind && !value && !comment && !label && !serviceName && !accountName) {
+ return SHOW_USAGE_MESSAGE;
+ }
+
itemRef = find_first_generic_password(keychainOrArray,
itemCreator,
itemType,
SecKeychainItemRef itemRef = NULL;
void *passwordData = NULL;
+ if (!itemCreator && !itemType && !kind && !comment && !label && !serverName && !securityDomain && !accountName && !path && !port && !protocol && !authenticationType) {
+ return SHOW_USAGE_MESSAGE;
+ }
+
itemRef = find_first_internet_password(keychainOrArray,
itemCreator,
itemType,
CSSM_CC_HANDLE ccHand;
CSSM_DATA keyLabelData;
- keyLabelData.Data = (uint8 *)keyLabel,
+ keyLabelData.Data = (uint8 *)keyLabel;
keyLabelData.Length = keyLabelLen;
memset(pubKey, 0, sizeof(CSSM_KEY));
memset(privKey, 0, sizeof(CSSM_KEY));
void srPrintError(const char *op, CSSM_RETURN err);
/* Init CSSM; returns CSSM_FALSE on error. Reusable. */
-extern CSSM_BOOL srCssmStartup();
+extern CSSM_BOOL srCssmStartup(void);
/* Attach to CSP. Returns zero on error. */
extern CSSM_CSP_HANDLE srCspStartup(
CSSM_BOOL bareCsp); // true ==> CSP, false ==> CSP/DL
/* Attach to DL side of CSPDL. */
-extern CSSM_DL_HANDLE srDlStartup();
+extern CSSM_DL_HANDLE srDlStartup(void);
/* Attach to CL, TP */
-extern CSSM_CL_HANDLE srClStartup();
-extern CSSM_TP_HANDLE srTpStartup();
+extern CSSM_CL_HANDLE srClStartup(void);
+extern CSSM_TP_HANDLE srTpStartup(void);
/*
* Derive symmetric key using PBE.
// Truth table for following declarations:
//
-// TARGET_OS_OSX TARGET_OS_OSX TARGET_OS_IPHONE TARGET_OS_IPHONE
-// SEC_IOS_ON_OSX SEC_IOS_ON_OSX
-// ===================================================================================================
-// SEC_OS_IPHONE 0 1 1 1
-// SEC_OS_IPHONE_INCLUDES 0 0 1 1
-// SEC_OS_OSX 1 0 0 0
-// SEC_OS_OSX_INCLUDES 1 1 0 0
+// TARGET_OS_OSX TARGET_OS_OSX TARGET_OS_IPHONE TARGET_OS_IPHONE TARGET_OS_IOSMAC
+// SEC_IOS_ON_OSX SEC_IOS_ON_OSX
+// =================================================================================================================
+// SEC_OS_IPHONE 0 1 1 1 1
+// SEC_OS_OSX 1 0 0 0 0
+// SEC_OS_OSX_INCLUDES 1 1 0 0 0
#if TARGET_OS_OSX
#ifdef SEC_IOS_ON_OSX
#define SEC_OS_IPHONE 1
- #define SEC_OS_IPHONE_INCLUDES 0
#define SEC_OS_OSX 0
#define SEC_OS_OSX_INCLUDES 1
#endif // SEC_IOS_ON_OSX
#endif // TARGET_OS_OSX
+#if TARGET_OS_IOSMAC
+ #define SEC_OS_IPHONE 1
+
+ #define SEC_OS_OSX 0
+ #define SEC_OS_OSX_INCLUDES 0
+#endif // TARGET_OS_IOSMAC
+
#ifndef SEC_OS_IPHONE
// block above did not fire; set flags to current platform
#define SEC_OS_IPHONE TARGET_OS_IPHONE
- #define SEC_OS_IPHONE_INCLUDES TARGET_OS_IPHONE
#define SEC_OS_OSX TARGET_OS_OSX
#define SEC_OS_OSX_INCLUDES TARGET_OS_OSX
*/
typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccessControl) *SecAccessControlRef;
-#if SEC_OS_OSX_INCLUDES
-
/*!
@typedef SecKeychainRef
@abstract Contains information about a keychain.
*/
-typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychain) *SecKeychainRef;
+typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychain) *SecKeychainRef
+ API_AVAILABLE(macos(10.0)) SPI_AVAILABLE(ios(1.0), tvos(9.0), watchos(1.0));
/*!
@typedef SecKeychainItemRef
@abstract Contains information about a keychain item.
*/
-typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainItem) *SecKeychainItemRef;
+typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainItem) *SecKeychainItemRef API_UNAVAILABLE(ios);
/*!
@typedef SecKeychainSearchRef
@abstract Contains information about a keychain search.
*/
-typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainSearch) *SecKeychainSearchRef;
+typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainSearch) *SecKeychainSearchRef API_UNAVAILABLE(ios);
/*!
@typedef SecKeychainAttrType
@abstract Represents a keychain attribute type.
*/
-typedef OSType SecKeychainAttrType;
+typedef OSType SecKeychainAttrType API_UNAVAILABLE(ios);
/*!
@struct SecKeychainAttribute
@field length The length of the buffer pointed to by data.
@field data A pointer to the attribute data.
*/
-struct SecKeychainAttribute
+struct API_UNAVAILABLE(ios) SecKeychainAttribute
{
SecKeychainAttrType tag;
UInt32 length;
void * __nullable data;
};
-typedef struct SecKeychainAttribute SecKeychainAttribute;
+typedef struct SecKeychainAttribute SecKeychainAttribute API_UNAVAILABLE(ios);
/*!
@typedef SecKeychainAttributePtr
@abstract Represents a pointer to a keychain attribute structure.
*/
-typedef SecKeychainAttribute *SecKeychainAttributePtr;
+typedef SecKeychainAttribute *SecKeychainAttributePtr API_UNAVAILABLE(ios);
/*!
@typedef SecKeychainAttributeList
@field count An unsigned 32-bit integer that represents the number of keychain attributes in the array.
@field attr A pointer to the first keychain attribute in the array.
*/
-struct SecKeychainAttributeList
+struct API_UNAVAILABLE(ios) SecKeychainAttributeList
{
UInt32 count;
SecKeychainAttribute * __nullable attr;
};
-typedef struct SecKeychainAttributeList SecKeychainAttributeList;
+typedef struct SecKeychainAttributeList SecKeychainAttributeList API_UNAVAILABLE(ios);
/*!
@typedef SecKeychainStatus
@abstract Represents the status of a keychain.
*/
-typedef UInt32 SecKeychainStatus;
+typedef UInt32 SecKeychainStatus API_UNAVAILABLE(ios);
/*!
@typedef SecTrustedApplicationRef
@abstract Contains information about a trusted application.
*/
-typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrustedApplication) *SecTrustedApplicationRef;
+typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrustedApplication) *SecTrustedApplicationRef API_UNAVAILABLE(ios);
/*!
@typedef SecAccessRef
@abstract Contains information about an access.
*/
-typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccess) *SecAccessRef;
+typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccess) *SecAccessRef API_UNAVAILABLE(ios);
/*!
@typedef SecACLRef
@abstract Contains information about an access control list (ACL) entry.
*/
-typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrust) *SecACLRef;
+typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrust) *SecACLRef API_UNAVAILABLE(ios);
/*!
@typedef SecPasswordRef
@abstract Contains information about a password.
*/
-typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPassword) *SecPasswordRef;
+typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPassword) *SecPasswordRef API_UNAVAILABLE(ios);
/*!
@typedef SecKeychainAttributeInfo
@field format A pointer to the first CSSM_DB_ATTRIBUTE_FORMAT in the array.
@discussion Each tag and format item form a pair.
*/
-struct SecKeychainAttributeInfo
+struct API_UNAVAILABLE(ios) SecKeychainAttributeInfo
{
UInt32 count;
UInt32 *tag;
UInt32 * __nullable format;
};
-typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo;
-
-#endif // SEC_OS_OSX_INCLUDES
+typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo API_UNAVAILABLE(ios);
/*!
@function SecCopyErrorMessageString
errSecAuthNeeded = -25330, /* Auth is needed before the requested action can be performed. An array of
constraints to be fulfilled is passed inside error.userInfo's 'cons' key. */
+
+ errSecPeersNotAvailable = -25336, /* No peers in the circle are available/online. */
+ errSecErrorStringNotAvailable= -25337, /* Unable to load error string for error */
+
+ /* UNUSED enums */
errSecDeviceIDNeeded = -25332, /* Cannot send IDS messages without having our own IDS ID. */
errSecIDSNotRegistered = -25333, /* IDS is not set up or devices are not registered/available within an IDS account. */
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 */
+ errSecTimedOut = -25336, /* Timed out waiting for task */
};
// Guard for CFNetwork
*
* This only apply to MacOS where background session exists.
*/
-void _SecSetSecuritydTargetUID(uid_t uid);
+void _SecSetSecuritydTargetUID(uid_t uid)
+ API_AVAILABLE(macos(10.13.5)) API_UNAVAILABLE(ios, iosmac, watchos, tvos, bridgeos);
+
__END_DECLS
/*!
@function SecRandomCopyBytes
- @abstract Return count random bytes in *bytes, allocated by the caller.
- It is critical to check the return value for error
+
+ @abstract
+ Return count random bytes in *bytes, allocated by the caller. It
+ is critical to check the return value for error.
+
+ @param rnd
+ Only @p kSecRandomDefault is supported.
+
+ @param count
+ The number of bytes to generate.
+
+ @param bytes
+ A buffer to fill with random output.
+
@result Return 0 on success, any other value on failure.
+
+ @discussion
+ If @p rnd is unrecognized or unsupported, @p kSecRandomDefault is
+ used.
*/
int SecRandomCopyBytes(SecRandomRef __nullable rnd, size_t count, void *bytes)
__attribute__ ((warn_unused_result))
--- /dev/null
+Name: Security
+SwiftVersions:
+ - Version: 4
+ Functions:
+ - Name: SecTrustEvaluate
+ Parameters:
+ - Position: 1
+ Nullability: O
#include <Security/SecRandom.h>
#include <Security/SecImportExport.h>
#include <Security/SecTrust.h>
-
-#if SEC_OS_IPHONE_INCLUDES
#include <Security/SecSharedCredential.h>
-#endif
+#include <Security/SecProtocolOptions.h>
+#include <Security/SecProtocolMetadata.h>
#if SEC_OS_OSX_INCLUDES
#include <Security/AuthSession.h>
CSSM_CERT_STATUS_TRUST_SETTINGS_IGNORED_ERROR = 0x00000800
};
-typedef struct {
+typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER {
CSSM_TP_APPLE_CERT_STATUS StatusBits;
uint32 NumStatusCodes;
CSSM_RETURN *StatusCodes;
/* CRLReason code if cert is revoked */
sint32 CrlReason;
#endif /* SEC_OS_IPHONE */
-} CSSM_TP_APPLE_EVIDENCE_INFO;
+} CSSM_TP_APPLE_EVIDENCE_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
#if SEC_OS_OSX
--- /dev/null
+./../keychain/ot/OTConstants.h
\ No newline at end of file
--- /dev/null
+./../keychain/Signin Metrics/SFSignInAnalytics.h
\ No newline at end of file
--- /dev/null
+./../keychain/SecKeyProxy.h
\ No newline at end of file
--- /dev/null
+./../protocol/SecProtocol.h
\ No newline at end of file
--- /dev/null
+./../protocol/SecProtocolMetadata.h
\ No newline at end of file
--- /dev/null
+./../protocol/SecProtocolObject.h
\ No newline at end of file
--- /dev/null
+./../protocol/SecProtocolOptions.h
\ No newline at end of file
--- /dev/null
+./../protocol/SecProtocolTypes.h
\ No newline at end of file
--- /dev/null
+./../keychain/SecSharedCredential.h
\ No newline at end of file
+++ /dev/null
-./../../keychain/SecSharedCredential.h
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14205.1" systemVersion="17E183" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
+ <entity name="AccessControlEntity" representedClassName="SecCDKeychainManagedAccessControlEntity" syncable="YES" codeGenerationType="class">
+ <attribute name="stringRepresentation" attributeType="String" minValueString="1" syncable="YES"/>
+ <attribute name="type" attributeType="Integer 32" minValueString="0" usesScalarValueType="YES" syncable="YES"/>
+ <relationship name="accessedItems" toMany="YES" deletionRule="Deny" destinationEntity="Item" inverseName="accessControlList" inverseEntity="Item" syncable="YES"/>
+ <relationship name="ownedItems" toMany="YES" deletionRule="Deny" destinationEntity="Item" inverseName="owner" inverseEntity="Item" syncable="YES"/>
+ </entity>
+ <entity name="Item" representedClassName="SecCDKeychainManagedItem" syncable="YES" codeGenerationType="class">
+ <attribute name="data" attributeType="Binary" syncable="YES"/>
+ <attribute name="metadata" attributeType="Binary" syncable="YES"/>
+ <attribute name="persistentID" attributeType="UUID" usesScalarValueType="NO" syncable="YES"/>
+ <relationship name="accessControlList" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="AccessControlEntity" inverseName="accessedItems" inverseEntity="AccessControlEntity" syncable="YES"/>
+ <relationship name="itemType" maxCount="1" deletionRule="Nullify" destinationEntity="ItemType" inverseName="items" inverseEntity="ItemType" syncable="YES"/>
+ <relationship name="lookupEntries" toMany="YES" deletionRule="Nullify" destinationEntity="LookupEntry" inverseName="matchingItems" inverseEntity="LookupEntry" syncable="YES"/>
+ <relationship name="owner" maxCount="1" deletionRule="Nullify" destinationEntity="AccessControlEntity" inverseName="ownedItems" inverseEntity="AccessControlEntity" syncable="YES"/>
+ </entity>
+ <entity name="ItemType" representedClassName="SecCDKeychainManagedItemType" syncable="YES" codeGenerationType="class">
+ <attribute name="name" attributeType="String" syncable="YES"/>
+ <attribute name="primaryKeys" attributeType="Binary" syncable="YES"/>
+ <attribute name="syncableKeys" attributeType="Binary" syncable="YES"/>
+ <attribute name="version" attributeType="Integer 32" minValueString="1" usesScalarValueType="YES" syncable="YES"/>
+ <relationship name="items" optional="YES" toMany="YES" deletionRule="Deny" destinationEntity="Item" inverseName="itemType" inverseEntity="Item" syncable="YES"/>
+ </entity>
+ <entity name="LookupEntry" representedClassName="SecCDKeychainManagedLookupEntry" syncable="YES" codeGenerationType="class">
+ <attribute name="itemTypeName" attributeType="String" minValueString="4" syncable="YES"/>
+ <attribute name="lookupKey" attributeType="String" minValueString="1" syncable="YES"/>
+ <attribute name="lookupValue" attributeType="String" minValueString="1" syncable="YES"/>
+ <attribute name="lookupValueType" attributeType="String" syncable="YES"/>
+ <attribute name="systemEntry" optional="YES" attributeType="Boolean" usesScalarValueType="YES" syncable="YES"/>
+ <relationship name="matchingItems" optional="YES" toMany="YES" deletionRule="Deny" destinationEntity="Item" inverseName="lookupEntries" inverseEntity="Item" syncable="YES"/>
+ </entity>
+ <elements>
+ <element name="AccessControlEntity" positionX="-54" positionY="63" width="128" height="105"/>
+ <element name="Item" positionX="-63" positionY="-18" width="128" height="150"/>
+ <element name="ItemType" positionX="-63" positionY="54" width="128" height="120"/>
+ <element name="LookupEntry" positionX="-54" positionY="27" width="128" height="135"/>
+ </elements>
+</model>
\ No newline at end of file
--- /dev/null
+/*
+ * 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"
+
+#if !TARGET_OS_BRIDGE
+
+#if USE_KEYSTORE
+#import <libaks.h>
+#import <libaks_ref_key.h>
+#endif
+
+#import <Foundation/Foundation.h>
+#import <CoreData/CoreData.h>
+#import <SecurityFoundation/APIMacros.h>
+
+@class SecCDKeychainItemMetadata;
+@class SecCDKeychainLookupTuple;
+@class SecCDKeychainManagedItemType;
+@class SecCDKeychainAccessControlEntity;
+@class SFKeychainServerConnection;
+@class SFAESKey;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class SecCDKeychainItem;
+
+@protocol SecCDKeychainLookupValueType <NSObject>
+@end
+typedef NSString<SecCDKeychainLookupValueType> SecCDKeychainLookupValueType;
+
+extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeString;
+extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeData;
+extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeNumber;
+extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate;
+extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeArray;
+extern SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDictionary;
+
+@interface SecCDKeychain : NSObject
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase;
+
+- (void)insertItems:(NSArray<SecCDKeychainItem*>*)items withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* _Nullable error))completionHandler;
+
+- (void)fetchItemForPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* _Nullable item, NSError* _Nullable error))completionHandler;
+- (void)fetchItemsWithValue:(NSString*)value forLookupKey:(NSString*)lookupKey ofType:(SecCDKeychainLookupValueType*)lookupValueType withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(NSArray<SecCDKeychainItemMetadata*>* items, NSError* error))completionHandler;
+
+- (void)deleteItemWithPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* _Nullable error))completionHandler;
+
+@end
+
+@interface SecCDKeychainItemType : NSObject
+
+@property (readonly, copy) NSString* name;
+@property (readonly) int32_t version;
+
+// for both primaryKeys and syncableKeys, nil means "all the attributes"
+@property (readonly, copy, nullable) NSArray* primaryKeys;
+@property (readonly, copy, nullable) NSArray* syncableKeys;
+
+@property (readonly) SecCDKeychainManagedItemType* managedItemType;
+
+// subclasses must override
++ (nullable instancetype)itemType;
++ (nullable instancetype)itemTypeForVersion:(int32_t)version;
+
+// to be called only by subclass implementations of +itemType
+- (instancetype)_initWithName:(NSString*)name version:(int32_t)version primaryKeys:(nullable NSArray*)primaryKeys syncableKeys:(nullable NSArray*)syncableKeys;
+
+@end
+
+@interface SecCDKeychainItemMetadata : NSObject
+
+@property (readonly) SecCDKeychainItemType* itemType;
+@property (readonly) SecCDKeychainAccessControlEntity* owner;
+@property (readonly) NSUUID* persistentID;
+@property (readonly, copy) NSDictionary* attributes;
+@property (readonly, copy) NSArray<SecCDKeychainLookupTuple*>* lookupAttributes;
+@property (readonly) keyclass_t keyclass;
+
+- (instancetype)init NS_UNAVAILABLE;
+- (void)fetchFullItemWithKeychain:(SecCDKeychain*)keychain withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* _Nullable item, NSError* _Nullable error))completionHandler;
+
+@end
+
+@interface SecCDKeychainItem : NSObject
+
+@property (readonly) SecCDKeychainItemType* itemType;
+@property (readonly) SecCDKeychainAccessControlEntity* owner;
+@property (readonly) NSUUID* persistentID;
+@property (readonly) NSDictionary* attributes;
+@property (readonly) NSArray<SecCDKeychainLookupTuple*>* lookupAttributes;
+@property (readonly) keyclass_t keyclass;
+@property (readonly) NSDictionary* secrets;
+
+@property (readonly) SecCDKeychainItemMetadata* metadata;
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initItemType:(SecCDKeychainItemType*)itemType withPersistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(nullable NSArray<SecCDKeychainLookupTuple*>*)lookupAttributes secrets:(NSDictionary*)secrets owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass;
+
+@end
+
+@interface SecCDKeychainLookupTuple : NSObject
+
+@property (readonly, copy) NSString* key;
+@property (readonly, copy) id<NSCopying, NSObject> value;
+@property (readonly, copy) SecCDKeychainLookupValueType* valueType;
+@property (readonly, copy) NSString* stringRepresentation;
+
++ (instancetype)lookupTupleWithKey:(NSString*)key value:(id<NSCopying, NSObject>)value;
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithKey:(NSString*)key value:(id<NSCopying, NSObject>)value;
+
+@end
+
+typedef NS_ENUM(NSInteger, SecCDKeychainAccessControlEntityType) {
+ SecCDKeychainAccessControlEntityTypeAccessGroup = 0,
+};
+
+@interface SecCDKeychainAccessControlEntity : NSObject
+
+@property (nonatomic, readonly) SecCDKeychainAccessControlEntityType entityType;
+@property (nonatomic, readonly) NSString* stringRepresentation;
+
++ (instancetype)accessControlEntityWithType:(SecCDKeychainAccessControlEntityType)type stringRepresentation:(NSString*)stringRepresentation;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+#if USE_KEYSTORE
+
+@protocol SecAKSRefKey <NSObject>
+
+@property (readonly) NSData* refKeyBlob;
+
+- (instancetype)initWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass;
+- (instancetype)initWithBlob:(NSData*)blob keybag:(keybag_handle_t)keybag;
+
+- (nullable NSData*)wrappedDataForKey:(SFAESKey*)key;
+- (nullable SFAESKey*)keyWithWrappedData:(NSData*)wrappedKeyData;
+
+@end
+
+@interface SecAKSRefKey : NSObject <SecAKSRefKey>
+@end
+
+#endif // USE_KEYSTORE
+
+NS_ASSUME_NONNULL_END
+
+#endif // !TARGET_OS_BRIDGE
--- /dev/null
+/*
+ * 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 <TargetConditionals.h>
+
+#if !TARGET_OS_BRIDGE
+
+#import "SecCDKeychain.h"
+#import "SecCDKeychainManagedItem+CoreDataClass.h"
+#import "SecCDKeychainManagedLookupEntry+CoreDataClass.h"
+#import "SecCDKeychainManagedItemType+CoreDataClass.h"
+#import "SecCDKeychainManagedAccessControlEntity+CoreDataClass.h"
+#import "SecFileLocations.h"
+#import "SecItemServer.h"
+#import "SecItem.h"
+#import "SecItemPriv.h"
+#import "SecBase.h"
+#import "SFKeychainServer.h"
+#import "CloudKitCategories.h"
+#import "securityd_client.h"
+#import "SecKeybagSupport.h"
+#import "SecKeybagSupport.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
+#import <SecurityFoundation/SFKeychain.h>
+#import <SecurityFoundation/SFDigestOperation.h>
+#import <SecurityFoundation/SFKey.h>
+#import <SecurityFoundation/SFEncryptionOperation.h>
+#import <CoreData/NSPersistentStoreCoordinator_Private.h>
+#if USE_KEYSTORE
+#import <libaks_ref_key.h>
+#endif
+#import <Foundation/NSData_Private.h>
+#import <notify.h>
+
+static NSString* const SecCDKeychainErrorDomain = @"com.apple.security.cdkeychain";
+
+static NSString* const SecCDKeychainEntityLookupEntry = @"LookupEntry";
+static NSString* const SecCDKeychainEntityItem = @"Item";
+static NSString* const SecCDKeychainEntityItemType = @"ItemType";
+static NSString* const SecCDKeychainEntityTypeAccessControlEntity = @"AccessControlEntity";
+
+static NSString* const SecCDKeychainItemMetadataSHA256 = @"SecCDKeychainItemMetadataSHA256";
+
+static const NSInteger SecCDKeychainErrorDeserializing = 1;
+static const NSInteger SecCDKeychainErrorInternal = 2;
+//static const NSInteger SecCDKeychainErrorMetadataDoesNotMatch = 3;
+
+SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeString = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeString";
+SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeData = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeData";
+SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeNumber = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeNumber";
+SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate = (SecCDKeychainLookupValueType*)@"SecCDKeychainLookupValueTypeDate";
+
+@interface SecCDKeychainItem ()
+
+- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error;
+
+- (NSString*)primaryKeyStringRepresentationWithError:(NSError**)error;
+- (NSData*)encryptedSecretDataWithAttributeData:(NSData*)attributeData keybag:(keybag_handle_t)keybag error:(NSError**)error;
+
+@end
+
+@interface SecCDKeychainItemMetadata ()
+
+@property (readonly, copy) NSSet<SecCDKeychainLookupTuple*>* lookupAttributesSet;
+@property (readonly, copy) NSData* managedDataBlob;
+
+- (instancetype)initWithItemType:(SecCDKeychainItemType*)itemType persistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(NSArray<SecCDKeychainLookupTuple*>*)lookupAttributes owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass;
+- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error;
+
+@end
+
+@interface SecCDKeychainLookupTuple ()
+
++ (instancetype)lookupTupleWithManagedLookupEntry:(SecCDKeychainManagedLookupEntry*)lookupEntry;
+
+@end
+
+@interface SecCDKeychainItemType ()
+
+- (SecCDKeychainManagedItemType*)managedItemTypeWithContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error;
+
+@end
+
+@interface SecCDKeychainAccessControlEntity ()
+
+- (instancetype)initWithManagedEntity:(SecCDKeychainManagedAccessControlEntity*)managedAccessControlEntity;
+
+@end
+
+@interface SecCDKeychainItemWrappedSecretData : NSObject <NSSecureCoding>
+
+@property (readonly) SFAuthenticatedCiphertext* ciphertext;
+@property (readonly) NSData* wrappedKeyData;
+@property (readonly) NSData* refKeyBlob;
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKeyData:(NSData*)wrappedKeyData refKeyBlob:(NSData*)refKeyBlob;
+
+@end
+
+@implementation SecCDKeychainItemWrappedSecretData {
+ SFAuthenticatedCiphertext* _ciphertext;
+ NSData* _wrappedKeyData;
+ NSData* _refKeyBlob;
+}
+
+@synthesize ciphertext = _ciphertext;
+@synthesize wrappedKeyData = _wrappedKeyData;
+@synthesize refKeyBlob = _refKeyBlob;
+
++ (BOOL)supportsSecureCoding
+{
+ return YES;
+}
+
+- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKeyData:(NSData*)wrappedKeyData refKeyBlob:(NSData*)refKeyBlob
+{
+ if (self = [super init]) {
+ _ciphertext = ciphertext;
+ _wrappedKeyData = wrappedKeyData.copy;
+ _refKeyBlob = refKeyBlob.copy;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithCoder:(NSCoder*)coder
+{
+ if (self = [super init]) {
+ _ciphertext = [coder decodeObjectOfClass:[SFAuthenticatedCiphertext class] forKey:@"SecCDKeychainItemCiphertext"];
+ _wrappedKeyData = [coder decodeObjectOfClass:[NSData class] forKey:@"SecCDKeychainItemWrappedKey"];
+ _refKeyBlob = [coder decodeObjectOfClass:[NSData class] forKey:@"SecCDKeychainItemRefKeyBlob"];
+
+ if (!_ciphertext || !_wrappedKeyData || !_refKeyBlob) {
+ self = nil;
+ secerror("SecCDKeychain: failed to deserialize wrapped secret data");
+ [coder failWithError:[NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorDeserializing userInfo:@{NSLocalizedDescriptionKey : @"failed to deserialize wrapped secret data"}]];
+ }
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder*)coder
+{
+ [coder encodeObject:_ciphertext forKey:@"SecCDKeychainItemCiphertext"];
+ [coder encodeObject:_wrappedKeyData forKey:@"SecCDKeychainItemWrappedKey"];
+ [coder encodeObject:_refKeyBlob forKey:@"SecCDKeychainItemRefKeyBlob"];
+}
+
+@end
+
+#if USE_KEYSTORE
+
+@implementation SecAKSRefKey {
+ aks_ref_key_t _refKey;
+}
+
+- (instancetype)initWithKeybag:(keyclass_t)keybag keyclass:(keyclass_t)keyclass
+{
+ if (self = [super init]) {
+ if (aks_ref_key_create(keybag, keyclass, key_type_sym, NULL, 0, &_refKey) != kAKSReturnSuccess) {
+ self = nil;
+ }
+ }
+
+ return self;
+}
+
+- (instancetype)initWithBlob:(NSData*)blob keybag:(keybag_handle_t)keybag
+{
+ if (self = [super init]) {
+ if (aks_ref_key_create_with_blob(keybag, blob.bytes, blob.length, &_refKey) != kAKSReturnSuccess) {
+ self = nil;
+ }
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ aks_ref_key_free(&_refKey);
+}
+
+- (NSData*)wrappedDataForKey:(SFAESKey*)key
+{
+ void* wrappedKeyBytes = NULL;
+ size_t wrappedKeyLength = 0;
+ if (aks_ref_key_wrap(_refKey, NULL, 0, key.keyData.bytes, key.keyData.length, &wrappedKeyBytes, &wrappedKeyLength) == kAKSReturnSuccess) {
+ return [NSData dataWithBytesNoCopy:wrappedKeyBytes length:wrappedKeyLength];
+ }
+
+ return nil;
+}
+
+- (SFAESKey*)keyWithWrappedData:(NSData*)wrappedKeyData
+{
+ void* unwrappedKeyBytes = NULL;
+ size_t unwrappedKeyLength = 0;
+ int aksResult = aks_ref_key_unwrap(_refKey, NULL, 0, wrappedKeyData.bytes, wrappedKeyData.length, &unwrappedKeyBytes, &unwrappedKeyLength);
+ if (aksResult != kAKSReturnSuccess || !unwrappedKeyBytes) {
+ return nil;
+ }
+
+ NSData* keyData = [NSData dataWithBytesNoCopy:unwrappedKeyBytes length:unwrappedKeyLength];
+ NSError* error = nil;
+ SFAESKey* key = [[SFAESKey alloc] initWithData:keyData specifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:&error];
+ if (!key) {
+ secerror("SecCDKeychain: error creating AES key from unwrapped item key data with error: %@", error);
+ }
+
+ return key;
+}
+
+- (NSData*)refKeyBlob
+{
+ size_t refKeyBlobLength = 0;
+ const uint8_t* refKeyBlobBytes = aks_ref_key_get_blob(_refKey, &refKeyBlobLength);
+ return [NSData dataWithBytes:refKeyBlobBytes length:refKeyBlobLength];
+}
+
+@end
+
+#endif // USE_KEYSTORE
+
+@implementation SecCDKeychain {
+ NSURL* _persistentStoreBaseURL;
+ NSPersistentStoreCoordinator* _persistentStoreCoordinator;
+ NSManagedObjectContext* _managedObjectContext;
+ NSMutableDictionary* _managedItemTypeDict;
+ NSMutableDictionary* _itemTypeDict;
+ bool _encryptDatabase;
+ dispatch_queue_t _queue;
+ NSArray* _classAPersistentStores;
+}
+
++ (SecCDKeychainLookupValueType*)lookupValueTypeForObject:(id)object
+{
+ if ([object isKindOfClass:[NSString class]]) {
+ return SecCDKeychainLookupValueTypeString;
+ }
+ else if ([object isKindOfClass:[NSData class]]) {
+ return SecCDKeychainLookupValueTypeData;
+ }
+ else if ([object isKindOfClass:[NSDate class]]) {
+ return SecCDKeychainLookupValueTypeDate;
+ }
+ else if ([object isKindOfClass:[NSNumber class]]) {
+ return SecCDKeychainLookupValueTypeNumber;
+ }
+ else {
+ return nil;
+ }
+}
+
+- (instancetype)initWithStorageURL:(NSURL*)persistentStoreURL modelURL:(NSURL*)managedObjectURL encryptDatabase:(bool)encryptDatabase
+{
+ if (!persistentStoreURL) {
+ secerror("SecCDKeychain: no persistent store URL, so we can't create or open a database");
+ return nil;
+ }
+ if (!managedObjectURL) {
+ secerror("SecCDKeychain: no managed object model URL, so we can't create or open a database");
+ return nil;
+ }
+
+ if (self = [super init]) {
+ _queue = dispatch_queue_create("SecCDKeychain", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+
+ _persistentStoreBaseURL = persistentStoreURL.copy;
+ _encryptDatabase = encryptDatabase;
+
+ NSManagedObjectModel* managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:managedObjectURL];
+ _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
+ }
+
+ return self;
+}
+
+- (NSData*)_onQueueGetDatabaseKeyDataWithError:(NSError**)error
+{
+ NSData* keyData = nil;
+ NSDictionary* databaseKeyQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword,
+ (id)kSecAttrAccessGroup : @"com.apple.security.securityd",
+ (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked,
+ (id)kSecAttrNoLegacy : @(YES),
+ (id)kSecAttrService : @"com.apple.security.keychain.ak",
+ (id)kSecReturnData : @(YES) };
+
+ CFTypeRef result = NULL;
+ OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)databaseKeyQuery, &result);
+
+ if (status == errSecItemNotFound) {
+ NSMutableDictionary* addKeyQuery = databaseKeyQuery.mutableCopy;
+ [addKeyQuery removeObjectForKey:(id)kSecReturnData];
+
+ uint8_t* keyBytes = malloc(16);
+ if (SecRandomCopyBytes(NULL, 16, keyBytes) != 0) {
+ secerror("SecCDKeychain: failed to create random key for CD database encryption - this means we won't be able to create a database");
+ if (error) {
+ *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"failed to create random key for CD database encryption"}];
+ }
+ return nil;
+ }
+
+ keyData = [NSData _newZeroingDataWithBytesNoCopy:keyBytes length:16 deallocator:nil];
+ addKeyQuery[(id)kSecValueData] = keyData;
+ status = SecItemAdd((__bridge CFDictionaryRef)addKeyQuery, NULL);
+ if (status == errSecSuccess) {
+ return keyData;
+ }
+ else {
+ secerror("SecCDKeychain: failed to save encryption key to keychain, so bailing on database creation; status: %d", (int)status);
+ CFErrorRef cfError = NULL;
+ SecError(status, &cfError, CFSTR("failed to save encryption key to keychain, so bailing on database creation"));
+ if (error) {
+ *error = CFBridgingRelease(cfError);
+ cfError = NULL;
+ }
+ else {
+ CFReleaseNull(cfError);
+ }
+ return nil;
+ }
+ }
+ else if (status == errSecInteractionNotAllowed) {
+ //// <rdar://problem/38972671> add SFKeychainErrorDeviceLocked
+
+ secerror("SecCDKeychain: can't create a class A store right now because the keychain is locked");
+ CFErrorRef cfError = NULL;
+ SecError(status, &cfError, CFSTR("can't create a class A store right now because the keychain is locked"));
+ if (error) {
+ *error = CFBridgingRelease(cfError);
+ cfError = NULL;
+ }
+ else {
+ CFReleaseNull(cfError);
+ }
+ return nil;
+ }
+ else if (status == errSecSuccess) {
+ if ([(__bridge id)result isKindOfClass:[NSData class]]) {
+ return (__bridge_transfer NSData*)result;
+ }
+ else {
+ if (error) {
+ *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"result of keychain query for database key is wrong kind of class: %@", [(__bridge id)result class]]}];
+ }
+
+ CFReleaseNull(result);
+ return nil;
+ }
+ }
+ else {
+ secerror("failed to save or retrieve key for CD database encryption - this means we won't be able to create a database; status: %d", (int)status);
+ if (error) {
+ *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:@{NSLocalizedDescriptionKey : @"failed to save or retrieve key for CD database encryption"}];
+ }
+
+ CFReleaseNull(result);
+ return nil;
+ }
+}
+
+- (NSManagedObjectContext*)_onQueueGetManagedObjectContextWithError:(NSError* __autoreleasing *)error
+{
+ dispatch_assert_queue(_queue);
+
+ if (!_managedObjectContext) {
+ NSURL* akStoreURL = [_persistentStoreBaseURL URLByAppendingPathExtension:@"ak"];
+
+ NSData* keyData = [self _onQueueGetDatabaseKeyDataWithError:error];
+ if (!keyData) {
+ return nil;
+ }
+
+ if (_encryptDatabase) {
+ NSPersistentStore* classAStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:akStoreURL options:@{NSSQLiteSEEKeychainItemOption : keyData} error:error];
+ _classAPersistentStores = @[classAStore];
+ }
+ else {
+ NSPersistentStore* classAStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:akStoreURL options:nil error:error];
+ _classAPersistentStores = @[classAStore];
+ }
+
+ NSManagedObjectContext* managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
+ managedObjectContext.persistentStoreCoordinator = _persistentStoreCoordinator;
+
+ // the first time around, setup our items types; grab old ones from the database and register any new ones
+ // we can skip for subsequent loads of the store in the same run of securityd
+ if (!_managedItemTypeDict || !_itemTypeDict) {
+ _managedItemTypeDict = [NSMutableDictionary dictionary];
+ _itemTypeDict = [NSMutableDictionary dictionary];
+ [managedObjectContext performBlockAndWait:^{
+ NSFetchRequest* managedItemTypeFetchRequest = [SecCDKeychainManagedItemType fetchRequest];
+ NSArray<SecCDKeychainManagedItemType*>* managedItemTypes = [managedObjectContext executeFetchRequest:managedItemTypeFetchRequest error:error];
+ if (managedItemTypes.count == 0) {
+ // TODO do some error handling here
+ }
+ else {
+ for (SecCDKeychainManagedItemType* managedItemType in managedItemTypes) {
+ NSMutableDictionary* itemTypeVersionDict = self->_managedItemTypeDict[managedItemType.name];
+ if (!itemTypeVersionDict) {
+ itemTypeVersionDict = [NSMutableDictionary dictionary];
+ self->_managedItemTypeDict[managedItemType.name] = itemTypeVersionDict;
+ }
+ itemTypeVersionDict[@(managedItemType.version)] = managedItemType;
+ }
+ }
+
+ [self registerItemType:[SecCDKeychainItemTypeCredential itemType] withManagedObjectContext:managedObjectContext];
+ }];
+ }
+
+ _managedObjectContext = managedObjectContext;
+
+ int token = 0;
+ __weak __typeof(self) weakSelf = self;
+ notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int token) {
+ bool locked = true;
+ CFErrorRef error = NULL;
+ if (!SecAKSGetIsLocked(&locked, &error)) {
+ secerror("SecDbKeychainMetadataKeyStore: error getting lock state: %@", error);
+ CFReleaseNull(error);
+ }
+
+ if (locked) {
+ [weakSelf _onQueueDropClassAPersistentStore];
+ }
+ });
+ }
+
+ return _managedObjectContext;
+}
+
+- (void)_onQueueDropClassAPersistentStore
+{
+ for (NSPersistentStore* store in _classAPersistentStores) {
+ NSError* error = nil;
+ if (![_persistentStoreCoordinator removePersistentStore:store error:&error]) {
+ secerror("SecCDKeychain: failed to remove persistent store with error: %@", error);
+ }
+ }
+
+ _classAPersistentStores = nil;
+ _managedObjectContext = nil;
+ _persistentStoreCoordinator = nil;
+}
+
+- (dispatch_queue_t)_queue
+{
+ return _queue;
+}
+
+- (void)performOnManagedObjectQueue:(void (^)(NSManagedObjectContext* context, NSError* error))block
+{
+ __weak __typeof(self) weakSelf = self;
+ dispatch_async(_queue, ^{
+ NSError* error = nil;
+ NSManagedObjectContext* context = [weakSelf _onQueueGetManagedObjectContextWithError:&error];
+ if (context) {
+ [context performBlock:^{
+ block(context, nil);
+ }];
+ }
+ else {
+ if (!error) {
+ error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal description:@"unknown error retrieving managed object context"];
+ }
+ block(nil, error);
+ }
+ });
+}
+
+- (void)performOnManagedObjectQueueAndWait:(void (^)(NSManagedObjectContext* context, NSError* error))block
+{
+ dispatch_sync(_queue, ^{
+ NSError* error = nil;
+ NSManagedObjectContext* context = [self _onQueueGetManagedObjectContextWithError:&error];
+ if (context) {
+ [context performBlockAndWait:^{
+ block(context, nil);
+ }];
+ }
+ else {
+ block(nil, error);
+ }
+ });
+}
+
+- (NSString*)primaryKeyNameForItemTypeName:(NSString*)itemTypeName
+{
+ return [NSString stringWithFormat:@"SecCDKeychain-PrimaryKey-%@", itemTypeName];
+}
+
+- (bool)validateItemOwner:(SecCDKeychainAccessControlEntity*)owner withConnection:(SFKeychainServerConnection*)connection withError:(NSError**)error
+{
+ // in the future we may support more owner types than just an access group, but for now, access group or bust
+
+ NSError* localError = nil;
+ NSString* accessGroup = owner.entityType == SecCDKeychainAccessControlEntityTypeAccessGroup ? owner.stringRepresentation : nil;
+ if (accessGroup) {
+ if ([connection.clientAccessGroups containsObject:accessGroup]) {
+ return true;
+ }
+ else {
+ localError = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInvalidAccessGroup userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"client not in access group: %@", accessGroup]}];
+ }
+ }
+ else {
+ localError = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorMissingAccessGroup userInfo:@{NSLocalizedDescriptionKey : @"keychain item missing access group"}];
+ }
+
+ if (error) {
+ *error = localError;
+ }
+ secerror("SecCDKeychain: failed to validate item owner with error: %@", localError);
+ return false;
+}
+
+- (void)insertItems:(NSArray<SecCDKeychainItem*>*)items withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* error))completionHandler
+{
+ __weak __typeof(self) weakSelf = self;
+ [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) {
+ __strong __typeof(self) strongSelf = weakSelf;
+ if (!strongSelf) {
+ secerror("SecCDKeychain: attempt to insert items into deallocated keychain instance");
+ completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to insert items into deallocated keychain instance"}]);
+ return;
+ }
+
+ if (!managedObjectContext) {
+ secerror("SecCDKeychain: insertItems: could not get managed object context");
+ completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"insertItems: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]);
+ return;
+ }
+
+ __block NSError* error = nil;
+ __block bool success = true;
+ for (SecCDKeychainItem* item in items) {
+ if (![self validateItemOwner:item.owner withConnection:connection withError:&error]) {
+ success = false;
+ break;
+ }
+
+ NSString* itemTypeName = item.itemType.name;
+ NSString* primaryKeyValue = [item primaryKeyStringRepresentationWithError:&error];
+ if (primaryKeyValue) {
+ NSFetchRequest* primaryKeyFetchRequest = [SecCDKeychainManagedLookupEntry fetchRequest];
+ primaryKeyFetchRequest.predicate = [NSPredicate predicateWithFormat:@"lookupKey == %@ AND lookupValue == %@", [self primaryKeyNameForItemTypeName:itemTypeName], primaryKeyValue];
+ SecCDKeychainManagedLookupEntry* managedLookupEntry = [[managedObjectContext executeFetchRequest:primaryKeyFetchRequest error:&error] firstObject];
+ if (managedLookupEntry) {
+ secerror("SecCDKeychain: failed to unique item (%@) using primary keys: %@", item, item.itemType.primaryKeys);
+ success = false;
+ error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorDuplicateItem userInfo:@{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"failed to unique item (%@) using primary keys: %@", item, item.itemType.primaryKeys] }];
+ break;
+ }
+ }
+ else {
+ secerror("SecCDKeychain: error creating primary key string representation for item: %@; error: %@", item, error);
+ success = false;
+ break;
+ }
+
+ SecCDKeychainManagedItem* managedItem = [self managedItemWithItem:item withManagedObjectContext:managedObjectContext error:&error];
+ if (!managedItem) {
+ secerror("SecCDKeychain: error creating managed item for insertion: %@; item: %@", error, item);
+ success = false;
+ break;
+ }
+
+ // add a lookup entry for the primary key
+ SecCDKeychainManagedLookupEntry* primaryKeyLookupEntry = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityLookupEntry inManagedObjectContext:managedObjectContext];
+ primaryKeyLookupEntry.itemTypeName = itemTypeName;
+ primaryKeyLookupEntry.lookupKey = [self primaryKeyNameForItemTypeName:itemTypeName];
+ primaryKeyLookupEntry.lookupValue = primaryKeyValue;
+ primaryKeyLookupEntry.lookupValueType = SecCDKeychainLookupValueTypeString;
+ primaryKeyLookupEntry.systemEntry = YES;
+ [primaryKeyLookupEntry addMatchingItemsObject:managedItem];
+ secdebug("SecCDKeychain", "added primary key: %@ value: %@", primaryKeyLookupEntry.lookupKey, primaryKeyLookupEntry.lookupValue);
+
+ // and add lookup entries for all the things we're supposed to be able to lookup on
+ for (SecCDKeychainLookupTuple* lookupTuple in item.lookupAttributes) {
+ NSFetchRequest* lookupEntryFetchRequest = [SecCDKeychainManagedLookupEntry fetchRequest];
+ lookupEntryFetchRequest.predicate = [NSPredicate predicateWithFormat:@"lookupKey == %@ AND lookupValueType == %@ AND lookupValue == %@", lookupTuple.key, lookupTuple.valueType, lookupTuple.value];
+ SecCDKeychainManagedLookupEntry* lookupEntry = [[managedObjectContext executeFetchRequest:lookupEntryFetchRequest error:&error] firstObject];
+ if (error) {
+ secerror("SecCDKeychain: error fetching lookup entry during item insertion: %@", (__bridge CFErrorRef)error);
+ success = false;
+ break;
+ }
+ else if (!lookupEntry) {
+ // we didn't get an error, but we didn't find a lookup entry
+ // that means there simply wasn't one in the db, so we should create one
+ lookupEntry = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityLookupEntry inManagedObjectContext:managedObjectContext];
+ lookupEntry.itemTypeName = itemTypeName;
+ lookupEntry.lookupKey = lookupTuple.key;
+ lookupEntry.lookupValue = lookupTuple.stringRepresentation;
+ lookupEntry.lookupValueType = lookupTuple.valueType;
+ secdebug("SecCDKeychain", "added item for key (%@) : value (%@)", lookupEntry.lookupKey, lookupEntry.lookupValue);
+ }
+
+ [lookupEntry addMatchingItemsObject:managedItem];
+ }
+
+ if (!success) {
+ break;
+ }
+ }
+
+ if (success) {
+ secnotice("SecCDKeychain", "saving managed object context for items: %@", items);
+ success = [managedObjectContext save:&error];
+ if (error) {
+ secerror("SecCDKeychain: saving managed object context failed with error: %@", error);
+ }
+ else {
+ secnotice("SecCDKeychain", "saving managed object context succeeded");
+ }
+ }
+
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
+ completionHandler(success, error);
+ });
+ }];
+}
+
+- (SecCDKeychainManagedItem*)fetchManagedItemForPersistentID:(NSUUID*)persistentID withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error
+{
+ NSError* localError = nil;
+ NSFetchRequest* lookupEntryFetchRequest = [SecCDKeychainManagedItem fetchRequest];
+ lookupEntryFetchRequest.predicate = [NSPredicate predicateWithFormat:@"persistentID == %@", persistentID];
+ SecCDKeychainManagedItem* managedItem = [[managedObjectContext executeFetchRequest:lookupEntryFetchRequest error:&localError] firstObject];
+
+ if (error) {
+ *error = localError;
+ }
+
+ return managedItem;
+}
+
+- (void)fetchItemForPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* item, NSError* error))completionHandler
+{
+ __weak __typeof(self) weakSelf = self;
+ [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) {
+ __strong __typeof(self) strongSelf = weakSelf;
+ if (!strongSelf) {
+ secerror("SecCDKeychain: attempt to fetch item from deallocated keychain instance");
+ completionHandler(false, [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to fetch item from deallocated keychain instance"}]);
+ return;
+ }
+
+ if (!managedObjectContext) {
+ secerror("SecCDKeychain: fetchItemForPersistentID: could not get managed object context");
+ completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"fetchItemForPersistentID: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]);
+ return;
+ }
+
+ NSError* error = nil;
+ SecCDKeychainItem* fetchedItem = nil;
+ SecCDKeychainManagedItem* managedItem = [self fetchManagedItemForPersistentID:persistentID withManagedObjectContext:managedObjectContext error:&error];
+ if (error) {
+ secerror("SecCDKeychain: error fetching item for persistent id: %@; error: %@", persistentID, error);
+ }
+ else if (!managedItem) {
+ // we didn't get an error, but we didn't find an item
+ // that means there simply wasn't one in the db, so this lookup finds nothing
+ error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemNotFound userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"did not find any keychain items matching persistent ID: %@", persistentID.UUIDString]}];
+ }
+ else {
+ fetchedItem = [[SecCDKeychainItem alloc] initWithManagedItem:managedItem keychain:self error:&error];
+ if (!fetchedItem || error) {
+ secerror("SecCDKeychain: failed to create SecCDKeychainItem from managed item with error: %@", error);
+ fetchedItem = nil;
+ }
+ else if (![self validateItemOwner:fetchedItem.owner withConnection:connection withError:nil]) { // if we fail owner validation, we don't return an error; we pretend it didn't exist
+ fetchedItem = nil;
+ error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemNotFound userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"did not find any keychain items matching persistent ID: %@", persistentID.UUIDString]}];
+ }
+ }
+
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
+ completionHandler(fetchedItem, error);
+ });
+ }];
+}
+
+- (void)fetchItemsWithValue:(NSString*)value forLookupKey:(NSString*)lookupKey ofType:(SecCDKeychainLookupValueType*)lookupValueType withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(NSArray<SecCDKeychainItemMetadata*>* items, NSError* error))completionHandler
+{
+ __weak __typeof(self) weakSelf = self;
+ [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) {
+ __strong __typeof(self) strongSelf = weakSelf;
+ if (!strongSelf) {
+ secerror("SecCDKeychain: attempt to fetch items from deallocated keychain instance");
+ completionHandler(false, [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to lookup items from deallocated keychain instance"}]);
+ return;
+ }
+
+ if (!managedObjectContext) {
+ secerror("SecCDKeychain: fetchItemsWithValue: could not get managed object context");
+ completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"fetchItemsWithValue: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]);
+ return;
+ }
+
+ NSError* error = nil;
+ NSMutableArray* fetchedItems = [[NSMutableArray alloc] init];
+ NSFetchRequest* lookupEntryFetchRequest = [SecCDKeychainManagedLookupEntry fetchRequest];
+ lookupEntryFetchRequest.predicate = [NSPredicate predicateWithFormat:@"lookupKey == %@ AND lookupValueType == %@ AND lookupValue == %@", lookupKey, lookupValueType, value];
+ NSArray* lookupEntries = [managedObjectContext executeFetchRequest:lookupEntryFetchRequest error:&error];
+ if (error) {
+ secerror("SecCDKeychain: error fetching lookup entry during item lookup: %@", error);
+ fetchedItems = nil;
+ }
+ else if (lookupEntries.count == 0) {
+ // we didn't get an error, but we didn't find a lookup entry
+ // that means there simply wasn't one in the db, so this lookup finds nothing
+ CFErrorRef cfError = NULL;
+ SecError(errSecItemNotFound, &cfError, CFSTR("did not find any keychain items matching query"));
+ error = CFBridgingRelease(cfError);
+ }
+ else {
+ for (SecCDKeychainManagedLookupEntry* lookupEntry in lookupEntries) {
+ for (SecCDKeychainManagedItem* item in lookupEntry.matchingItems) {
+ SecCDKeychainItemMetadata* fetchedItem = [[SecCDKeychainItemMetadata alloc] initWithManagedItem:item keychain:self error:&error];
+ if (!fetchedItem || error) {
+ secerror("SecCDKeychain: failed to create SecCDKeychainItemMetadata from managed item with error: %@", error);
+ fetchedItems = nil;
+ break;
+ }
+ else if (![self validateItemOwner:fetchedItem.owner withConnection:connection withError:nil]) { // not an error; just pretend it's not there
+ continue;
+ }
+
+ [fetchedItems addObject:fetchedItem];
+ }
+ }
+ }
+
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
+ completionHandler(fetchedItems, error);
+ });
+ }];
+}
+
+- (void)deleteItemWithPersistentID:(NSUUID*)persistentID withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(bool success, NSError* _Nullable error))completionHandler
+{
+ __weak __typeof(self) weakSelf = self;
+ [self performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) {
+ __strong __typeof(self) strongSelf = weakSelf;
+ if (!strongSelf) {
+ secerror("SecCDKeychain: attempt to fetch items from deallocated keychain instance");
+ completionHandler(false, [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"attempt to insert items into deallocated keychain instance"}]);
+ return;
+ }
+
+ if (!managedObjectContext) {
+ secerror("SecCDKeychain: deleteItemWithPersistentID: could not get managed object context");
+ completionHandler(false, [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorInternal userInfo:@{ NSLocalizedDescriptionKey : @"deleteItemWIthPersistentID: could not get managed object context", NSUnderlyingErrorKey : managedObjectError }]);
+ return;
+ }
+
+ NSError* error = nil;
+ SecCDKeychainManagedItem* managedItem = [self fetchManagedItemForPersistentID:persistentID withManagedObjectContext:managedObjectContext error:&error];
+ bool success = false;
+ if (managedItem && !error) {
+ SecCDKeychainAccessControlEntity* owner = [[SecCDKeychainAccessControlEntity alloc] initWithManagedEntity:managedItem.owner];
+ if ([self validateItemOwner:owner withConnection:connection withError:nil]) { // don't pass error here because we will treat it below as simply "item could not be found"
+ for (SecCDKeychainManagedLookupEntry* lookupEntry in managedItem.lookupEntries.copy) {
+ [lookupEntry removeMatchingItemsObject:managedItem];
+ if (lookupEntry.matchingItems.count == 0) {
+ [managedObjectContext deleteObject:lookupEntry];
+ }
+ }
+
+ SecCDKeychainManagedAccessControlEntity* managedOwner = managedItem.owner;
+ [managedOwner removeOwnedItemsObject:managedItem];
+ [managedOwner removeAccessedItemsObject:managedItem];
+ if (managedOwner.ownedItems.count == 0 && managedOwner.accessedItems == 0) {
+ [managedObjectContext deleteObject:managedOwner];
+ }
+
+ for (SecCDKeychainManagedAccessControlEntity* accessControlEntity in managedItem.accessControlList) {
+ [accessControlEntity removeAccessedItemsObject:managedItem];
+ if (accessControlEntity.ownedItems.count == 0 && accessControlEntity.accessedItems == 0) {
+ [managedObjectContext deleteObject:accessControlEntity];
+ }
+ }
+
+ [managedObjectContext deleteObject:managedItem];
+ success = [managedObjectContext save:&error];
+ }
+ else {
+ success = false;
+ }
+ }
+
+ if (!success && !error) {
+ secerror("SecCDKeychain: attempt to delete item with persistant identifier that could not be found: %@", persistentID);
+ error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemNotFound userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"attempt to delete item with persistant identifier that could not be found: %@", persistentID]}];
+ }
+
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
+ completionHandler(success, error);
+ });
+ }];
+}
+
+- (void)registerItemType:(SecCDKeychainItemType*)itemType withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext
+{
+ _itemTypeDict[itemType.name] = itemType;
+
+ NSMutableDictionary* itemTypeVersionDict = _managedItemTypeDict[itemType.name];
+ if (!itemTypeVersionDict) {
+ itemTypeVersionDict = [NSMutableDictionary dictionary];
+ _managedItemTypeDict[itemType.name] = itemTypeVersionDict;
+ }
+
+ if (!itemTypeVersionDict[@(itemType.version)]) {
+ NSError* error = nil;
+ SecCDKeychainManagedItemType* managedItemType = [itemType managedItemTypeWithContext:managedObjectContext error:&error];
+ if (managedItemType) {
+ itemTypeVersionDict[@(itemType.version)] = managedItemType;
+ [managedObjectContext save:&error];
+ }
+
+ if (!managedItemType || error) {
+ secerror("SecCDKeychain: error registering managedItemType for for itemType: %@", itemType);
+ }
+ }
+}
+
+// this method is only for use by tests because built-in types should get registered at initial store setup
+- (void)_registerItemTypeForTesting:(SecCDKeychainItemType*)itemType
+{
+ [self performOnManagedObjectQueueAndWait:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) {
+ if (!managedObjectContext) {
+ secerror("SecCDKeychain: _registerItemTypeForTesting: could not get managed object context");
+ return;
+ }
+
+ [self registerItemType:itemType withManagedObjectContext:managedObjectContext];
+ }];
+}
+
+- (SecCDKeychainItemType*)itemTypeForItemTypeName:(NSString*)itemTypeName
+{
+ return _itemTypeDict[itemTypeName];
+}
+
+- (SecCDKeychainManagedItem*)managedItemWithItem:(SecCDKeychainItem*)item withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error
+{
+ NSError* localError = nil;
+ SecCDKeychainManagedItem* managedItem = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityItem inManagedObjectContext:managedObjectContext];
+ managedItem.itemType = [[_managedItemTypeDict valueForKey:item.itemType.name] objectForKey:@(item.itemType.version)];
+ managedItem.persistentID = item.metadata.persistentID;
+
+ NSData* attributeData = [NSPropertyListSerialization dataWithPropertyList:item.attributes format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError];
+ managedItem.metadata = attributeData;
+
+ SecCDKeychainManagedAccessControlEntity* owner = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityTypeAccessControlEntity inManagedObjectContext:managedObjectContext];
+ owner.type = item.owner.entityType;
+ owner.stringRepresentation = item.owner.stringRepresentation;
+ managedItem.owner = owner;
+ [owner addOwnedItemsObject:managedItem];
+ [owner addAccessedItemsObject:managedItem];
+
+ // today, we only support the device keybag
+ // someday, that will have to change
+ managedItem.data = [item encryptedSecretDataWithAttributeData:attributeData keybag:KEYBAG_DEVICE error:&localError];
+
+ if (error) {
+ *error = localError;
+ }
+
+ return localError ? nil : managedItem;
+}
+
+@end
+
+@implementation SecCDKeychainItemMetadata {
+ SecCDKeychainItemType* _itemType;
+ SecCDKeychainAccessControlEntity* _owner;
+ NSUUID* _persistentID;
+ NSDictionary* _attributes;
+ NSSet<SecCDKeychainLookupTuple*>* _lookupAttributes;
+ NSData* _managedDataBlob; // hold onto this to verify metadata been tampered with
+ keyclass_t _keyclass;
+}
+
+@synthesize itemType = _itemType;
+@synthesize owner = _owner;
+@synthesize persistentID = _persistentID;
+@synthesize attributes = _attributes;
+@synthesize lookupAttributesSet = _lookupAttributes;
+@synthesize managedDataBlob = _managedDataBlob;
+@synthesize keyclass = _keyclass;
+
+- (instancetype)initWithItemType:(SecCDKeychainItemType*)itemType persistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(NSArray<SecCDKeychainLookupTuple*>*)lookupAttributes owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass
+{
+ if (self = [super init]) {
+ _itemType = itemType;
+ _owner = owner;
+ _persistentID = persistentID.copy;
+ _attributes = attributes.copy;
+ _keyclass = keyclass;
+
+ if (lookupAttributes) {
+ _lookupAttributes = [NSSet setWithArray:lookupAttributes];
+ }
+ else {
+ NSMutableSet* lookupAttributes = [[NSMutableSet alloc] init];
+ [_attributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id value, BOOL* stop) {
+ SecCDKeychainLookupTuple* lookupTuple = [SecCDKeychainLookupTuple lookupTupleWithKey:key value:value];
+ [lookupAttributes addObject:lookupTuple];
+ }];
+ _lookupAttributes = lookupAttributes.copy;
+ }
+ }
+
+ return self;
+}
+
+- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error
+{
+ if (self = [super init]) {
+ _itemType = [keychain itemTypeForItemTypeName:managedItem.itemType.name];
+ _persistentID = managedItem.persistentID.copy;
+ _managedDataBlob = managedItem.metadata;
+ _attributes = [NSPropertyListSerialization propertyListWithData:_managedDataBlob options:NSPropertyListImmutable format:NULL error:error];
+ _owner = [[SecCDKeychainAccessControlEntity alloc] initWithManagedEntity:managedItem.owner];
+
+ NSMutableSet* lookupAttributes = [NSMutableSet set];
+ for (SecCDKeychainManagedLookupEntry* lookupEntry in managedItem.lookupEntries) {
+ if (!lookupEntry.systemEntry) {
+ [lookupAttributes addObject:[SecCDKeychainLookupTuple lookupTupleWithManagedLookupEntry:lookupEntry]];
+ }
+ }
+ _lookupAttributes = lookupAttributes.copy;
+
+ if (!_itemType || !_persistentID || !_owner || ![_attributes isKindOfClass:[NSDictionary class]]) {
+ if (error) {
+ *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorDeserializing userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"failed to deserialize SecCDKeychainItemMetadata with item type (%@) persistentID: %@ owner: %@", _itemType, _persistentID, _owner]}];
+ }
+ self = nil;;
+ }
+ }
+
+ return self;
+}
+
+- (BOOL)isEqual:(SecCDKeychainItemMetadata*)object
+{
+ return [_itemType isEqual:object.itemType] &&
+ [_owner isEqual:object.owner] &&
+ [_persistentID isEqual:object.persistentID] &&
+ [_attributes isEqual:object.attributes] &&
+ [_lookupAttributes isEqual:object.lookupAttributesSet];
+}
+
+- (NSString*)description
+{
+ return [NSString stringWithFormat:@"%@: itemType:(%@) owner:(%@) persistentID:(%@)\n attributes: %@\n lookup attributes: %@", [super description], self.itemType, self.owner, self.persistentID, self.attributes, self.lookupAttributes];
+}
+
+- (void)fetchFullItemWithKeychain:(SecCDKeychain*)keychain withConnection:(SFKeychainServerConnection*)connection completionHandler:(void (^)(SecCDKeychainItem* _Nullable item, NSError* _Nullable error))completionHandler
+{
+ [keychain fetchItemForPersistentID:_persistentID withConnection:connection completionHandler:completionHandler];
+}
+
+- (NSArray<SecCDKeychainLookupTuple*>*)lookupAttributes
+{
+ return _lookupAttributes.allObjects;
+}
+
+- (NSArray*)primaryKeys
+{
+ return _itemType.primaryKeys;
+}
+
+@end
+
+@implementation SecCDKeychainItem {
+ SecCDKeychainItemMetadata* _metadata;
+ NSData* _encryptedSecretData;
+ NSDictionary* _secrets;
+}
+
+@synthesize metadata = _metadata;
+@synthesize secrets = _secrets;
+
+- (instancetype)initItemType:(SecCDKeychainItemType*)itemType withPersistentID:(NSUUID*)persistentID attributes:(NSDictionary*)attributes lookupAttributes:(NSArray<SecCDKeychainLookupTuple*>*)lookupAttributes secrets:(NSDictionary*)secrets owner:(SecCDKeychainAccessControlEntity*)owner keyclass:(keyclass_t)keyclass
+{
+ if (self = [super init]) {
+ _secrets = secrets.copy;
+ _metadata = [[SecCDKeychainItemMetadata alloc] initWithItemType:itemType persistentID:persistentID attributes:attributes lookupAttributes:lookupAttributes owner:owner keyclass:keyclass];
+ if (!_metadata) {
+ self = nil;
+ }
+ }
+
+ return self;
+}
+
+- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error
+{
+ if (self = [super init]) {
+ NSError* localError;
+ _metadata = [[SecCDKeychainItemMetadata alloc] initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:keychain error:&localError];
+ if (!_metadata) {
+ if (error) {
+ // TODO: add a negative unit test
+
+ *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorDeserializing userInfo:@{NSLocalizedDescriptionKey : @"could not create SecCDKeychainItem from managed item - managed item was malformed"}];
+ }
+ return nil;
+ }
+
+ _secrets = [self secretsFromEncryptedData:managedItem.data withKeybag:KEYBAG_DEVICE error:&localError];
+ if (!_secrets) {
+ if (error) {
+ *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorItemDecryptionFailed userInfo:@{ NSLocalizedDescriptionKey : @"could not decrypt secrets for item", NSUnderlyingErrorKey : localError }];
+ }
+ return nil;
+ }
+ }
+
+ return self;
+}
+
+- (BOOL)isEqual:(SecCDKeychainItem*)object
+{
+ return [object isKindOfClass:[SecCDKeychainItem class]]
+ && [_metadata isEqual:object.metadata]
+ && [_secrets isEqual:object.secrets];
+}
+
+- (NSString*)description
+{
+ return [NSString stringWithFormat:@"%@: itemType:(%@) persistentID:(%@)\n owner: %@\n attributes: %@\n lookup attributes: %@\nprimaryKeys: %@", [super description], self.itemType, self.persistentID, self.owner, self.attributes, self.lookupAttributes, self.primaryKeys];
+}
+
+- (SecCDKeychainItemType*)itemType
+{
+ return _metadata.itemType;
+}
+
+- (SecCDKeychainAccessControlEntity*)owner
+{
+ return _metadata.owner;
+}
+
+- (NSUUID*)persistentID
+{
+ return _metadata.persistentID;
+}
+
+- (NSDictionary*)attributes
+{
+ return _metadata.attributes;
+}
+
+- (NSArray<SecCDKeychainLookupTuple*>*)lookupAttributes
+{
+ return _metadata.lookupAttributes;
+}
+
+- (NSArray*)primaryKeys
+{
+ return _metadata.primaryKeys;
+}
+
+- (NSString*)primaryKeyStringRepresentationWithError:(NSError**)error
+{
+ NSDictionary* attributes = _metadata.attributes;
+ NSArray* primaryKeys = _metadata.primaryKeys.count > 0 ? _metadata.primaryKeys : attributes.allKeys;
+ NSArray* sortedPrimaryKeys = [primaryKeys sortedArrayUsingComparator:^NSComparisonResult(NSString* firstKey, NSString* secondKey) {
+ return [firstKey compare:secondKey options:NSForcedOrderingSearch];
+ }];
+
+ SFSHA256DigestOperation* digest = [[SFSHA256DigestOperation alloc] init];
+ [digest addData:[_metadata.owner.stringRepresentation dataUsingEncoding:NSUTF8StringEncoding]];
+
+ for (NSString* key in sortedPrimaryKeys) {
+ [digest addData:[key dataUsingEncoding:NSUTF8StringEncoding]];
+
+ id value = attributes[key];
+ if ([value isKindOfClass:[NSData class]]) {
+ [digest addData:value];
+ }
+ else if ([value isKindOfClass:[NSString class]]) {
+ [digest addData:[value dataUsingEncoding:NSUTF8StringEncoding]];
+ }
+ else {
+ NSData* valueData = [NSKeyedArchiver archivedDataWithRootObject:value requiringSecureCoding:YES error:error];
+ if (valueData) {
+ [digest addData:valueData];
+ }
+ else {
+ return nil;
+ }
+ }
+ }
+
+ return [[digest hashValue] base64EncodedStringWithOptions:0];
+}
+
+- (NSData*)encryptedSecretDataWithAttributeData:(NSData*)attributeData keybag:(keybag_handle_t)keybag error:(NSError**)error
+{
+#if USE_KEYSTORE
+ NSError* localError = nil;
+ NSString* errorDescription = nil;
+
+ SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256];
+ SFAESKey* randomKey = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:&localError];
+ if (!randomKey) {
+ secerror("SecCDKeychain: failed to create random key for encrypting item with error: %@", localError);
+ errorDescription = @"failed to create random key for encrypting item";
+ }
+
+ NSData* itemSecrets = [NSPropertyListSerialization dataWithPropertyList:_secrets format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError];
+ if (!itemSecrets) {
+ secerror("SecCDKeychain: failed to serialize item secrets dictionary with error: %@", localError);
+ errorDescription = @"failed to serialize item secrets dictionary";
+ }
+
+ SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:keySpecifier];
+ SFAuthenticatedCiphertext* ciphertext = nil;
+ if (randomKey && itemSecrets) {
+ NSData* attributeDataSHA256 = [SFSHA256DigestOperation digest:attributeData];
+ ciphertext = [encryptionOperation encrypt:itemSecrets withKey:randomKey additionalAuthenticatedData:attributeDataSHA256 error:&localError];
+ if (!ciphertext) {
+ secerror("SecCDKeychain: failed to encrypt item secret data with error: %@", localError);
+ errorDescription = @"failed to encrypt item secret data";
+ }
+ }
+
+ SecAKSRefKey* refKey = nil;
+ NSData* refKeyBlobData = nil;
+
+ if (ciphertext) {
+ refKey = [[SecAKSRefKey alloc] initWithKeybag:keybag keyclass:_metadata.keyclass];
+ refKeyBlobData = refKey.refKeyBlob;
+ if (!refKey || !refKeyBlobData) {
+ secerror("SecCDKeychain: failed to create refKey");
+ errorDescription = @"failed to create refKey";
+ }
+ }
+
+ NSData* wrappedKeyData = nil;
+ if (refKey && refKeyBlobData) {
+ wrappedKeyData = [refKey wrappedDataForKey:randomKey];
+ if (!wrappedKeyData) {
+ secerror("SecCDKeychain: failed to encrypt item");
+ errorDescription = @"failed to encrypt item";
+ }
+ }
+
+ if (wrappedKeyData) {
+ SecCDKeychainItemWrappedSecretData* wrappedSecretData = [[SecCDKeychainItemWrappedSecretData alloc] initWithCiphertext:ciphertext wrappedKeyData:wrappedKeyData refKeyBlob:refKeyBlobData];
+ NSData* wrappedSecretDataBlob = [NSKeyedArchiver archivedDataWithRootObject:wrappedSecretData requiringSecureCoding:YES error:&localError];
+ if (wrappedSecretDataBlob) {
+ return wrappedSecretDataBlob;
+ }
+ else {
+ secerror("SecCDKeychain: failed to serialize item secret data blob with error: %@", localError);
+ errorDescription = @"failed to serialize item secret data blob";
+ }
+ }
+
+ if (error) {
+ NSDictionary* userInfo = localError ? @{ NSUnderlyingErrorKey : localError, NSLocalizedDescriptionKey : errorDescription } : @{NSLocalizedDescriptionKey : errorDescription};
+ *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:userInfo];
+ }
+
+#endif
+ return nil;
+}
+
+- (NSDictionary*)secretsFromEncryptedData:(NSData*)secretData withKeybag:(keybag_handle_t)keybag error:(NSError**)error
+{
+#if USE_KEYSTORE
+ SecCDKeychainItemWrappedSecretData* wrappedSecretData = [NSKeyedUnarchiver unarchivedObjectOfClass:[SecCDKeychainItemWrappedSecretData class] fromData:secretData error:error];
+ if (!wrappedSecretData) {
+ secerror("SecCDKeychain: failed to deserialize item wrapped secret data");
+ return nil;
+ }
+
+ SecAKSRefKey* refKey = [[SecAKSRefKey alloc] initWithBlob:wrappedSecretData.refKeyBlob keybag:keybag];
+ if (!refKey) {
+ secerror("SecCDKeychain: failed to create refKey for unwrapping item secrets");
+ if (error) {
+ *error = [NSError errorWithDomain:SecCDKeychainErrorDomain code:SecCDKeychainErrorInternal userInfo:@{NSLocalizedDescriptionKey : @"failed to create refKey for unwrapping item secrets"}];
+ }
+ return nil;
+ }
+
+ SFAESKey* key = [refKey keyWithWrappedData:wrappedSecretData.wrappedKeyData];
+ if (!key) {
+ secerror("SecCDKeychain: failed to create item key for decryption");
+ return nil;
+ }
+
+ SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256];
+ SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:keySpecifier];
+ NSData* metadataSHA256 = [SFSHA256DigestOperation digest:_metadata.managedDataBlob];
+ NSData* decryptedSecretData = [encryptionOperation decrypt:wrappedSecretData.ciphertext withKey:key additionalAuthenticatedData:metadataSHA256 error:error];
+ if (!decryptedSecretData) {
+ secerror("SecCDKeychain: failed to decrypt item secret data");
+ return nil;
+ }
+
+ NSDictionary* secrets = [NSPropertyListSerialization propertyListWithData:decryptedSecretData options:0 format:NULL error:error];
+ if (![secrets isKindOfClass:[NSDictionary class]]) {
+ secerror("SecCDKeychain: failed to deserialize item decrypted secret data");
+ return nil;
+ }
+
+ return secrets;
+#else
+ return nil;
+#endif
+}
+
+// TODO: get back to this as part of CKKS integration work
+
+//- (NSDictionary*)attributesPropertyListWithError:(NSError**)error
+//{
+// __block NSDictionary* (^dictionaryToPropertyList)(NSDictionary*) = NULL;
+// __block NSArray* (^arrayToPropertyList)(NSArray*) = NULL;
+//
+// dictionaryToPropertyList = ^(NSDictionary* dict) {
+// NSMutableDictionary* propertyList = [NSMutableDictionary dictionary];
+// [dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, id object, BOOL* stop) {
+// Class objectClass = [object class];
+// if ([objectClass isKindOfClass:[NSString class]] || [objectClass isKindOfClass:[NSData class]] || [objectClass isKindOfClass:[NSDate class]] || [objectClass isKindOfClass:[NSNumber class]]) {
+// propertyList[key] = object;
+// }
+// else if ([objectClass isKindOfClass:[NSDictionary class]]){
+// NSDictionary* objectAsPropertyList = dictionaryToPropertyList(object);
+// if (objectAsPropertyList) {
+// propertyList[key] = objectAsPropertyList;
+// }
+// else {
+// *stop = YES;
+// }
+// }
+// else if ([objectClass isKindOfClass:[NSArray class]]) {
+// NSArray* objectAsPropertyList = arrayToPropertyList(object);
+// if (objectAsPropertyList) {
+// propertyList[key] = objectAsPropertyList;
+// }
+// else {
+// *stop = YES;
+// }
+// }
+// else if ([object conformsToProtocol:@protocol(NSSecureCoding)]) {
+// NSData*
+// }
+// }];
+// }
+//}
+
+@end
+
+@implementation SecCDKeychainLookupTuple {
+ NSString* _key;
+ id<NSCopying, NSObject> _value;
+ SecCDKeychainLookupValueType* _valueType;
+}
+
+@synthesize key = _key;
+@synthesize value = _value;
+@synthesize valueType = _valueType;
+
++ (instancetype)lookupTupleWithKey:(NSString*)key value:(id<NSCopying, NSObject>)value
+{
+ return [[self alloc] initWithKey:key value:value];
+}
+
++ (instancetype)lookupTupleWithManagedLookupEntry:(SecCDKeychainManagedLookupEntry*)lookupEntry
+{
+ NSString* valueString = lookupEntry.lookupValue;
+ id value;
+ NSString* valueType = lookupEntry.lookupValueType;
+ if ([valueType isEqualToString:SecCDKeychainLookupValueTypeString]) {
+ value = valueString;
+ }
+ else {
+ NSData* valueData = [[NSData alloc] initWithBase64EncodedString:valueString options:0];
+
+ if ([valueType isEqualToString:SecCDKeychainLookupValueTypeData]) {
+ value = valueData;
+ }
+ else if ([valueType isEqualToString:SecCDKeychainLookupValueTypeDate]) {
+ // TODO: error parameter
+ value = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSDate class] fromData:valueData error:nil];
+ }
+ else if ([valueType isEqualToString:SecCDKeychainLookupValueTypeNumber]) {
+ value = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSNumber class] fromData:valueData error:nil];
+ }
+ else {
+ // TODO: error here
+ value = nil;
+ }
+ }
+
+ return value ? [[self alloc] initWithKey:lookupEntry.lookupKey value:value] : nil;
+}
+
+- (instancetype)initWithKey:(NSString*)key value:(id<NSCopying, NSObject>)value
+{
+ if (self = [super init]) {
+ SecCDKeychainLookupValueType* valueType = [SecCDKeychain lookupValueTypeForObject:value];
+ BOOL zeroLengthValue = ([valueType isEqualToString:SecCDKeychainLookupValueTypeString] && [(NSString*)value length] == 0) || ([valueType isEqualToString:SecCDKeychainLookupValueTypeData] && [(NSData*)value length] == 0);
+ if (valueType && !zeroLengthValue) {
+ _key = key.copy;
+ _value = [value copyWithZone:nil];
+ _valueType = valueType.copy;
+ }
+ else {
+ // TODO: add an error parameter to this method
+ self = nil;
+ }
+ }
+
+ return self;
+}
+
+- (BOOL)isEqual:(SecCDKeychainLookupTuple*)object
+{
+ return [_key isEqualToString:object.key] && [_value isEqual:object.value] && [_valueType isEqualToString:object.valueType];
+}
+
+- (NSUInteger)hash
+{
+ return _key.hash ^ _value.hash ^ _valueType.hash;
+}
+
+- (NSString*)description
+{
+ return [NSString stringWithFormat:@"%@ : %@ [%@]", _key, _value, _valueType];
+}
+
+- (NSString*)stringRepresentation
+{
+ if ([_valueType isEqualToString:SecCDKeychainLookupValueTypeString]) {
+ return (NSString*)_value;
+ }
+ else if ([_valueType isEqualToString:SecCDKeychainLookupValueTypeData]) {
+ return [(NSData*)_value base64EncodedStringWithOptions:0];
+ }
+ else {
+ return [[NSKeyedArchiver archivedDataWithRootObject:_value requiringSecureCoding:YES error:nil] base64EncodedStringWithOptions:0];
+ }
+}
+
+@end
+
+@implementation SecCDKeychainItemType {
+ NSString* _name;
+ int32_t _version;
+ NSSet* _primaryKeys;
+ NSSet* _syncableKeys;
+ SecCDKeychainManagedItemType* _managedItemType;
+}
+
+@synthesize name = _name;
+@synthesize version = _version;
+
++ (instancetype)itemType
+{
+ return nil;
+}
+
++ (nullable instancetype)itemTypeForVersion:(int32_t)version
+{
+ return [self itemType];
+}
+
+- (instancetype)_initWithName:(NSString*)name version:(int32_t)version primaryKeys:(NSArray*)primaryKeys syncableKeys:(NSArray*)syncableKeys
+{
+ if (self = [super init]) {
+ _name = name.copy;
+ _version = version;
+ _primaryKeys = [NSSet setWithArray:primaryKeys];
+ _syncableKeys = [NSSet setWithArray:syncableKeys];
+ }
+
+ return self;
+}
+
+- (BOOL)isEqual:(SecCDKeychainItemType*)object
+{
+ return [object isKindOfClass:[SecCDKeychainItemType class]] &&
+ [_name isEqualToString:object.name] &&
+ _version == object.version &&
+ [_primaryKeys isEqualToSet:object->_primaryKeys] &&
+ [_syncableKeys isEqualToSet:object->_syncableKeys];
+}
+
+- (NSString*)description
+{
+ return [NSString stringWithFormat:@"%@ | %d", _name, _version];
+}
+
+- (NSString*)debugDescription
+{
+ return [NSString stringWithFormat:@"%@\n name: %@\n version: %d\n primaryKeys: %@\n syncableKeys: %@", [super debugDescription], _name, _version, _primaryKeys, _syncableKeys];
+}
+
+- (NSArray*)primaryKeys
+{
+ return _primaryKeys.allObjects;
+}
+
+- (NSArray*)syncableKeys
+{
+ return _syncableKeys.allObjects;
+}
+
+- (SecCDKeychainManagedItemType*)managedItemTypeWithContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error
+{
+ NSError* localError = nil;
+ SecCDKeychainManagedItemType* managedItemType = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityItemType inManagedObjectContext:managedObjectContext];
+ managedItemType.name = _name;
+ managedItemType.version = _version;
+ managedItemType.primaryKeys = [NSPropertyListSerialization dataWithPropertyList:_primaryKeys.allObjects format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError];
+ managedItemType.syncableKeys = [NSPropertyListSerialization dataWithPropertyList:_syncableKeys.allObjects format:NSPropertyListBinaryFormat_v1_0 options:0 error:&localError];
+
+ if (error) {
+ *error = localError;
+ }
+
+ return localError ? nil : managedItemType;
+}
+
+@end
+
+@implementation SecCDKeychainAccessControlEntity {
+ SecCDKeychainAccessControlEntityType _entityType;
+ NSString* _stringRepresentation;
+}
+
+@synthesize entityType = _entityType;
+@synthesize stringRepresentation = _stringRepresentation;
+
++ (instancetype)accessControlEntityWithType:(SecCDKeychainAccessControlEntityType)type stringRepresentation:(NSString*)stringRepresentation
+{
+ return [[self alloc] _initWithEntityType:type stringRepresentation:stringRepresentation];
+}
+
+- (instancetype)_initWithEntityType:(SecCDKeychainAccessControlEntityType)type stringRepresentation:(NSString*)stringRepresentation
+{
+ if (self = [super init]) {
+ _entityType = type;
+ _stringRepresentation = stringRepresentation.copy;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithManagedEntity:(SecCDKeychainManagedAccessControlEntity*)managedAccessControlEntity
+{
+ return [self _initWithEntityType:managedAccessControlEntity.type stringRepresentation:managedAccessControlEntity.stringRepresentation];
+}
+
+- (BOOL)isEqual:(SecCDKeychainAccessControlEntity*)object
+{
+ return _entityType == object.entityType && [_stringRepresentation isEqualToString:object.stringRepresentation];
+}
+
+@end
+
+#endif // TARGET_OS_BRIDGE
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>NSPrincipalClass</key>
+ <string>KeychainDataclassOwner</string>
+</dict>
+</plist>
--- /dev/null
+/*
+ * 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 <Foundation/Foundation.h>
+#import <AccountsDaemon/ACDDataclassOwnerProtocol.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KeychainDataclassOwner : NSObject <ACDDataclassOwnerProtocol>
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+/*
+ * 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 "KeychainDataclassOwner.h"
+#import "NSError+UsefulConstructors.h"
+#import "OTControl.h"
+#import "SecCFRelease.h"
+#import "SOSCloudCircle.h"
+#import "debugging.h"
+#import "OT.h"
+#import <Accounts/Accounts.h>
+#import <Accounts/ACDataclassAction.h>
+#import <Accounts/ACConstants.h>
+#import <Security/Security.h>
+#import <Security/SecItemPriv.h>
+
+@implementation KeychainDataclassOwner
+
+static NSString* const KeychainDataclass = @"KeychainDataclass";
+
++ (NSArray*)dataclasses
+{
+ return @[kAccountDataclassKeychainSync];
+}
+
+- (NSArray*)actionsForDeletingAccount:(ACAccount*)account forDataclass:(NSString*)dataclass
+{
+ if (![dataclass isEqual:kAccountDataclassKeychainSync]) {
+ return nil;
+ }
+
+ ACDataclassAction* cancelAction = [ACDataclassAction actionWithType:ACDataclassActionCancel];
+ ACDataclassAction* deleteAction = [ACDataclassAction actionWithType:ACDataclassActionDeleteSyncData];
+ ACDataclassAction* keepAction = [ACDataclassAction actionWithType:ACDataclassActionMergeSyncDataIntoLocalData];
+
+ return @[cancelAction, deleteAction, keepAction];
+}
+
+- (NSArray*)actionsForDisablingDataclassOnAccount:(ACAccount*)account forDataclass:(NSString*)dataclass
+{
+ return [self actionsForDeletingAccount:account forDataclass:dataclass];
+}
+
+
+- (BOOL)performAction:(ACDataclassAction*)action forAccount:(ACAccount*)account withChildren:(NSArray*)childAccounts forDataclass:(NSString*)dataclass withError:(NSError**)error
+{
+ // if the user asked us to delete their data, do that now
+ // we should rejigger this implementation to send a new custom message to security with an entitlement specifically for the signout case
+ // then we can do all the things we need to in securityd without having to entitlement the dataclass owners manager to read keychain items
+ // <rdar://problem/42436575> redo KeychainDataclassOwner to remove Safari items from DataclassOwnerManager's entitlements
+ if (action.type == ACDataclassActionDeleteSyncData) {
+ NSDictionary* baseQuery = @{ (id)kSecAttrSynchronizable : @(YES),
+ (id)kSecAttrAccessGroup : @"com.apple.cfnetwork",
+ (id)kSecAttrNoLegacy : @(YES),
+ (id)kSecAttrTombstone : @(NO) };
+ NSMutableDictionary* inetQuery = baseQuery.mutableCopy;
+ inetQuery[(id)kSecClass] = (id)kSecClassInternetPassword;
+ OSStatus inetResult = SecItemDelete((__bridge CFDictionaryRef)inetQuery);
+
+ NSMutableDictionary* genpQuery = baseQuery.mutableCopy;
+ genpQuery[(id)kSecClass] = (id)kSecClassGenericPassword;
+ OSStatus genpResult = SecItemDelete((__bridge CFDictionaryRef)genpQuery);
+
+ NSMutableDictionary* certQuery = baseQuery.mutableCopy;
+ certQuery[(id)kSecClass] = (id)kSecClassCertificate;
+ OSStatus certResult = SecItemDelete((__bridge CFDictionaryRef)certQuery);
+
+ NSMutableDictionary* keyQuery = baseQuery.mutableCopy;
+ keyQuery[(id)kSecClass] = (id)kSecClassKey;
+ OSStatus keyResult = SecItemDelete((__bridge CFDictionaryRef)keyQuery);
+
+ NSMutableDictionary* creditCardsQuery = baseQuery.mutableCopy;
+ creditCardsQuery[(id)kSecClass] = (id)kSecClassGenericPassword;
+ creditCardsQuery[(id)kSecAttrAccessGroup] = @"com.apple.safari.credit-cards";
+ OSStatus creditCardsResult = SecItemDelete((__bridge CFDictionaryRef)creditCardsQuery);
+
+ if (inetResult != errSecSuccess) {
+ secwarning("failed to delete synchronizable passwords from table inet: %d", (int)inetResult);
+ }
+ if (genpResult != errSecSuccess) {
+ secwarning("failed to delete synchronizable passwords from table genp: %d", (int)genpResult);
+ }
+ if (certResult != errSecSuccess) {
+ secwarning("failed to delete synchronizable passwords from table cert: %d", (int)certResult);
+ }
+ if (keyResult != errSecSuccess) {
+ secwarning("failed to delete synchronizable passwords from table keys: %d", (int)keyResult);
+ }
+ if (creditCardsResult != errSecSuccess) {
+ secwarning("failed to delete credit cards from table genp: %d", (int)creditCardsResult);
+ }
+ }
+
+ return YES;
+}
+
+@end
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
keychain operations.
*/
extern const CFStringRef kSecUseItemList
- API_AVAILABLE(macos(10.6), ios(2.0));
+ API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(ios, tvos, watchos);
extern const CFStringRef kSecUseKeychain
API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA));
extern const CFStringRef kSecUseOperationPrompt
extern const CFStringRef kSecAttrViewHintAutoUnlock;
extern const CFStringRef kSecAttrViewHintHealth;
extern const CFStringRef kSecAttrViewHintApplePay;
+extern const CFStringRef kSecAttrViewHintHome;
-#if SEC_OS_IPHONE
extern const CFStringRef kSecUseSystemKeychain
__TVOS_AVAILABLE(9.2)
__WATCHOS_AVAILABLE(3.0)
__WATCHOS_AVAILABLE(3.0)
__OSX_AVAILABLE(10.11.4)
__IOS_AVAILABLE(9.3);
-#endif /* SEC_OS_IPHONE */
/*!
@enum Other Constants (Private)
which have non-empty kSecAttrTokenID are not going through client-side
postprocessing, only raw form stored in the database is listed. This
flag is ignored in other operations than SecItemCopyMatching().
+ @constant kSecUseCertificatesWithMatchIssuers If set to true,
+ SecItemCopyMatching allows to return certificates when kSecMatchIssuers is specified.
*/
extern const CFStringRef kSecUseTombstones
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
__OSX_AVAILABLE(10.11.4) __IOS_AVAILABLE(9.3) __TVOS_AVAILABLE(9.3) __WATCHOS_AVAILABLE(2.3);
extern const CFStringRef kSecUseTokenRawItems
__OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0);
+extern const CFStringRef kSecUseCertificatesWithMatchIssuers
+ __OSX_AVAILABLE(10.14) __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE;
extern const CFStringRef kSOSInternalAccessGroup
__OSX_AVAILABLE(10.9) __IOS_AVAILABLE(7.0) __TVOS_AVAILABLE(9.3) __WATCHOS_AVAILABLE(2.3);
void _SecItemFetchDigests(NSString *itemClass, NSString *accessGroup, void (^complete)(NSArray *, NSError *));
#endif
-#if SEC_OS_IPHONE
/*!
@function SecItemDeleteAllWithAccessGroups
@abstract Deletes all items for each class for the given access groups
Requires entitlement "com.apple.private.uninstall.deletion"
*/
bool SecItemDeleteAllWithAccessGroups(CFArrayRef accessGroups, CFErrorRef *error);
-#endif /* SEC_OS_IPHONE */
/*
Ensure the escrow keybag has been used to unlock the system keybag before
CFDictionaryRef _SecSecuritydCopyWhoAmI(CFErrorRef *error);
XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyCKKSEndpoint(CFErrorRef *error);
+XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopySFKeychainEndpoint(CFErrorRef* error);
XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyKeychainControlEndpoint(CFErrorRef* error);
#if SEC_OS_IPHONE
#endif /* SEC_OS_IPHONE */
bool _SecSystemKeychainTransfer(CFErrorRef *error);
-#if SEC_OS_IPHONE
bool _SecSyncDeleteUserViews(uid_t uid, CFErrorRef *error);
-#endif /* SEC_OS_IPHONE */
CFTypeRef SecItemCreateFromAttributeDictionary_osx(CFDictionaryRef refAttributes);
#endif
-#if SEC_OS_IPHONE
/*!
* @function SecCopyLastError
* @abstract return the last CFErrorRef for this thread
__TVOS_AVAILABLE(10.0)
__WATCHOS_AVAILABLE(3.0)
__IOS_AVAILABLE(10.0);
-#endif // SEC_OS_IPHONE
#if SEC_OS_OSX
/*!
__BEGIN_DECLS
-#if SEC_OS_IPHONE
typedef struct __SecDERKey {
uint8_t *oid;
CFIndex oidLength;
uint8_t *key;
CFIndex keyLength;
} SecDERKey;
-#endif // SEC_OS_IPHONE
typedef struct SecRSAPublicKeyParams {
uint8_t *modulus; /* modulus */
#endif
} SecKeyDescriptor;
-#if SEC_OS_IPHONE
struct __SecKey {
CFRuntimeBase _base;
const SecKeyDescriptor *key_class;
-#if !TARGET_OS_IPHONE
+#if TARGET_OS_OSX
// On OSX, keep optional SecKeyRef which holds dynamically, on-demand created CSSM-based key with the same
// key material. It is used to implement SecKeyGetCSSMKey().
SecKeyRef cdsaKey;
/* The actual key handled by class. */
void *key;
};
-#endif
/* Create a public key from a CFData containing a SubjectPublicKeyInfo in DER format. */
SecKeyRef SecKeyCreateFromSubjectPublicKeyInfoData(CFAllocatorRef allocator,
CFDataRef SecKeyCopySubjectPublicKeyInfo(SecKeyRef key);
-#if SEC_OS_IPHONE
/*!
@function SecKeyCreate
@abstract Given a private key and data to sign, generate a digital signature.
/* 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);
in a keychain. */
SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes);
+// SecAsn1AlgId is deprecated, but we still need to use it.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
OSStatus SecKeyDigestAndVerify(
SecKeyRef key, /* Public key */
const SecAsn1AlgId *algId, /* algorithm oid/params */
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);
uint8_t *sig, /* signature, RETURNED */
size_t *sigLen); /* IN/OUT */
+#pragma clang diagnostic pop
+
OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* serializedPublic);
SecKeyRef SecKeyCreateFromPublicBytes(CFAllocatorRef allocator, CFIndex algorithmID, const uint8_t *keyData, CFIndex keyDataLength);
SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef serialized);
CFDataRef privateBlob);
CF_RETURNS_RETAINED
CFDictionaryRef SecKeyGeneratePublicAttributeDictionary(SecKeyRef key, CFTypeRef keyType);
-#endif // SEC_OS_IPHONE
enum {
kSecNullAlgorithmID = 0,
kSecECDSAAlgorithmID = 3,
};
-#if SEC_OS_IPHONE_INCLUDES
+/*!
+ @function SecKeyGetAlgorithmId
+ @abstract Returns an enumerated constant value which identifies the algorithm for the given key.
+ @param key A key reference.
+ @result An algorithm identifier.
+ */
+CFIndex SecKeyGetAlgorithmId(SecKeyRef key)
+API_AVAILABLE(macos(10.8), ios(9.0));
+
+#if TARGET_OS_IPHONE
/*!
@function SecKeyGetAlgorithmID
@abstract Returns an enumerated constant value which identifies the algorithm for the given key.
For compatibility, your code should migrate to use SecKeyGetAlgorithmId instead.
*/
CFIndex SecKeyGetAlgorithmID(SecKeyRef key)
- __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_8, __IPHONE_5_0, __IPHONE_9_0);
+API_DEPRECATED_WITH_REPLACEMENT("SecKeyGetAlgorithmId", ios(5.0, 9.0)) API_UNAVAILABLE(iosmac);
+#endif // TARGET_OS_IPHONE
+#if TARGET_OS_OSX
/*!
- @function SecKeyGetAlgorithmId
- @abstract Returns an enumerated constant value which identifies the algorithm for the given key.
- @param key A key reference.
- @result An algorithm identifier.
-*/
-CFIndex SecKeyGetAlgorithmId(SecKeyRef key)
- __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_9_0);
-#endif //#SEC_OS_IPHONE_INCLUDES
+ @function SecKeyGetAlgorithmID
+ @abstract Returns a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure for the given key.
+ @param key A key reference.
+ @param algid On return, a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure.
+ @result A result code. See "Security Error Codes" (SecBase.h).
+ @discussion Deprecated in OS X 10.8 and later. Continued use is strongly discouraged,
+ since there is a naming conflict with a similar function (also deprecated) on iOS that
+ had different arguments and a different return value. Use SecKeyGetAlgorithmId instead.
+ */
+OSStatus SecKeyGetAlgorithmID(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER **algid)
+API_DEPRECATED_WITH_REPLACEMENT("SecKeyGetAlgorithmId", macos(10.2, 10.8)) API_UNAVAILABLE(ios);
+#endif
-#if SEC_OS_IPHONE
-typedef enum {
+#if !SEC_OS_OSX
+typedef CF_ENUM(int, SecKeySize) {
kSecKeyKeySizeInBits = 0,
kSecKeySignatureSize = 1,
kSecKeyEncryptedDataSize = 2,
// More might belong here, but we aren't settled on how
// to take into account padding and/or digest types.
-} SecKeySize;
+};
/*!
@function SecKeyGetSize
*/
size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize)
__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
-
#endif
-#if SEC_OS_IPHONE
-
/*!
@function SecKeyLookupPersistentRef
@abstract Looks up a SecKeyRef via persistent ref.
*/
OSStatus SecKeyFindWithPersistentRef(CFDataRef persistentRef, SecKeyRef* lookedUpData)
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
-#endif // SEC_OS_IPHONE
/*!
@function SecKeyCopyPersistentRef
OSStatus SecKeyCopyPersistentRef(SecKeyRef key, CFDataRef* persistentRef)
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
-#if SEC_OS_IPHONE
-
-/*
- *
- */
-
extern const CFStringRef _kSecKeyWrapPGPSymAlg; /* CFNumber */
extern const CFStringRef _kSecKeyWrapPGPFingerprint; /* CFDataRef, at least 20 bytes */
extern const CFStringRef _kSecKeyWrapPGPWrapAlg; /* kSecKeyWrapRFC6637WrapNNN, or any of the other PGP wrap algs */
_SecKeyCopyUnwrapKey(SecKeyRef key, SecKeyWrapType type, CFDataRef wrappedKey, CFDictionaryRef parameters, CFDictionaryRef *outParam, CFErrorRef *error)
__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
-#endif // SEC_OS_IPHONE
-
-
#if SEC_OS_OSX_INCLUDES
-/*!
- @function SecKeyGetAlgorithmID
- @abstract Returns a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure for the given key.
- @param key A key reference.
- @param algid On return, a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure.
- @result A result code. See "Security Error Codes" (SecBase.h).
- @discussion Deprecated in OS X 10.8 and later. Continued use is strongly discouraged,
- since there is a naming conflict with a similar function (also deprecated) on iOS that
- had different arguments and a different return value. Use SecKeyGetAlgorithmId instead.
-*/
-OSStatus SecKeyGetAlgorithmID(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER **algid)
- DEPRECATED_IN_MAC_OS_X_VERSION_10_8_AND_LATER;
-
-/*!
- @function SecKeyGetAlgorithmId
- @abstract Returns an enumerated constant value which identifies the algorithm for the given key.
- @param key A key reference.
- @result An algorithm identifier.
-*/
-CFIndex SecKeyGetAlgorithmId(SecKeyRef key)
- __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_9_0);
-
/*!
@function SecKeyGetStrengthInBits
@abstract Returns key strength in bits for the given key.
@param strength On return, the key strength in bits.
@result A result code. See "Security Error Codes" (SecBase.h).
*/
-OSStatus SecKeyGetStrengthInBits(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER *algid, unsigned int *strength);
+OSStatus SecKeyGetStrengthInBits(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER *algid, unsigned int *strength) API_DEPRECATED("CSSM_X509_ALGORITHM_IDENTIFIER is deprecated", macos(10.4, 10.14));
/*!
@function SecKeyImportPair
@result A result code. See "Security Error Codes" (SecBase.h).
@discussion Warning: this function is NOT intended for use outside the Security stack in its current state. <rdar://3201885>
*/
-OSStatus SecKeyCreateWithCSSMKey(const CSSM_KEY *key, SecKeyRef* keyRef);
+OSStatus SecKeyCreateWithCSSMKey(const CSSM_KEY *key, SecKeyRef* keyRef) API_DEPRECATED("CSSM_KEY is deprecated", macos(10.11, 10.14));
/*!
uint8_t *plainText,
size_t *plainTextLen); /* IN/OUT */
+// SecAsn1AlgId is deprecated, but we still need to use it.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
OSStatus SecKeyVerifyDigest(
SecKeyRef key, /* Private key */
const SecAsn1AlgId *algId, /* algorithm oid/params */
size_t digestDataLen, /* length of digestData */
uint8_t *sig, /* signature, RETURNED */
size_t *sigLen); /* IN/OUT */
+#pragma clang diagnostic pop
+
+#endif // SEC_OS_OSX_INCLUDES
/* These are the named curves we support. These values come from RFC 4492
*/
SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes);
+#if SEC_OS_OSX_INCLUDES
OSStatus SecKeyRawVerifyOSX(
SecKeyRef key,
SecPadding padding,
*/
typedef CF_ENUM(uint32_t, SecKeyAttestationKeyType)
{
- kSecKeyAttestationKeyTypeSIK = 0,
- kSecKeyAttestationKeyTypeGID
-} __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
+ kSecKeyAttestationKeyTypeSIK = 0,
+ kSecKeyAttestationKeyTypeGID = 1,
+ kSecKeyAttestationKeyTypeUIKCommitted API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 2,
+ kSecKeyAttestationKeyTypeUIKProposed API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 3,
+} API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
/*!
@function SecKeyCopyAttestationKey
@result On success a SecKeyRef containing the requested key is returned, on failure it returns NULL.
*/
SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef *error)
-__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
/*!
@function SecKeyCreateAttestation
@discussion Key attestation only works for CTK SEP keys, i.e. keys created with kSecAttrTokenID=kSecAttrTokenIDSecureEnclave.
*/
CFDataRef SecKeyCreateAttestation(SecKeyRef key, SecKeyRef keyToAttest, CFErrorRef *error)
-__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
/*!
@function SecKeySetParameter
SecKey user (application) and backend and in this case are not interpreted by SecKey layer in any way.
*/
Boolean SecKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error)
-__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
extern const CFStringRef kSecKeyParameterSETokenAttestationNonce
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
+/*!
+ Available lifetime operations for SEP system keys.
+ */
+typedef CF_ENUM(int, SecKeyControlLifetimeType) {
+ kSecKeyControlLifetimeTypeBump = 0,
+ kSecKeyControlLifetimeTypeCommit = 1,
+} API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
+
+/*!
+ @function SecKeyControlLifetime
+ @abstract Performs key lifetime control operations for SEP system keys.
+
+ @param key Key to be controlled, currently must be either proposed or committed system UIK.
+ @param type Type of the control operation to be performed.
+ @param error Error which gathers more information when something went wrong.
+ */
+Boolean SecKeyControlLifetime(SecKeyRef key, SecKeyControlLifetimeType type, CFErrorRef *error)
+API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
+
/*!
@function SecKeyCreateDuplicate
@abstract Creates duplicate fo the key.
If the key is immutable (i.e. does not support SecKeySetParameter), calling this method is identical to calling CFRetain().
*/
SecKeyRef SecKeyCreateDuplicate(SecKeyRef key)
-__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
/*!
Algorithms for converting between bigendian and core-crypto ccunit data representation.
--- /dev/null
+/*
+ * Copyright (c) 2006-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,
+ * 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 SecKeyProxy
+ Declaration of SecKey proxy object allowing SecKeyRef to be accessed remotely through XPC.
+ */
+
+#ifndef _SECURITY_SECKEYPROXY_H_
+#define _SECURITY_SECKEYPROXY_H_
+
+#import <Foundation/Foundation.h>
+#include <Security/SecBase.h>
+#include <Security/SecKey.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SecKeyProxy : NSObject {
+@private
+ id _key;
+ NSData * _Nullable _certificate;
+ NSXPCListener *_listener;
+}
+
+// Creates new proxy instance. Proxy holds reference to the target key or identity and allows remote access to that target key as long as the proxy instance is kept alive.
+- (instancetype)initWithKey:(SecKeyRef)key;
+- (instancetype)initWithIdentity:(SecIdentityRef)identity;
+
+// Retrieve endpoint to this proxy instance. Endpoint can be transferred over NSXPCConnection and passed to +[createKeyFromEndpoint:error:] method.
+@property (readonly, nonatomic) NSXPCListenerEndpoint *endpoint;
+
+// Invalidates all connections to this proxy.
+- (void)invalidate;
+
+// Creates new SecKey/SecIdentity object which forwards all operations to the target SecKey identified by endpoint. Returned SecKeyRef can be used as long as target SecKeyProxy instance is kept alive.
++ (nullable SecKeyRef)createKeyFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError **)error;
++ (nullable SecIdentityRef)createIdentityFromEndpoint:(NSXPCListenerEndpoint *)endpoint error:(NSError **)error;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+#endif /* !_SECURITY_SECKEYPROXY_H_ */
shared password. You use this key to get a value of type CFStringRef
that contains a password.
*/
-extern const CFStringRef kSecSharedPassword
- __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;
+extern const CFStringRef kSecSharedPassword API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos);
/*!
@function SecAddSharedWebCredential
Note: since a request involving shared web credentials may potentially require user interaction or other verification to be approved, this function is dispatched asynchronously; your code provides a completion handler that will be called once the results (if any) are available.
*/
void SecAddSharedWebCredential(CFStringRef fqdn, CFStringRef account, CFStringRef __nullable password,
- void (^completionHandler)(CFErrorRef __nullable error))
- __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;
+ void (^completionHandler)(CFErrorRef __nullable error)) API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos);
/*!
@function SecRequestSharedWebCredential
Note: since a request involving shared web credentials may potentially require user interaction or other verification to be approved, this function is dispatched asynchronously; your code provides a completion handler that will be called once the results (if any) are available.
*/
void SecRequestSharedWebCredential(CFStringRef __nullable fqdn, CFStringRef __nullable account,
- void (^completionHandler)(CFArrayRef __nullable credentials, CFErrorRef __nullable error))
- __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;
+ void (^completionHandler)(CFArrayRef __nullable credentials, CFErrorRef __nullable error)) API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos);
/*!
@function SecCreateSharedWebCredentialPassword
@return CFStringRef password in the form xxx-xxx-xxx-xxx where x is taken from the sets "abcdefghkmnopqrstuvwxy", "ABCDEFGHJKLMNPQRSTUVWXYZ", "3456789" with at least one character from each set being present.
*/
__nullable
-CFStringRef SecCreateSharedWebCredentialPassword(void)
- __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;
+CFStringRef SecCreateSharedWebCredentialPassword(void) API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macos, iosmac, tvos, watchos);
#endif /* __BLOCKS__ */
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
--- /dev/null
+/*
+ * 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 SFSignInAnalytics_Internal_h
+#define SFSignInAnalytics_Internal_h
+
+#import "SFSignInAnalytics.h"
+
+@interface SFSignInAnalytics (Internal)
+@property (readonly) NSString *signin_uuid;
+@property (readonly) NSString *my_uuid;
+-(instancetype) initChildWithSignInUUID:(NSString*)signin_uuid andCategory:(NSString*)category andEventName:(NSString*)eventName;
+@end
+
+@interface SFSIALoggerObject : SFAnalytics
++ (instancetype)logger;
+- (instancetype)init NS_UNAVAILABLE;
+@end
+
+#endif /* SFSignInAnalytics+Internal_h */
+#endif
--- /dev/null
+/*
+ * 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 SignInAnalytics_h
+#define SignInAnalytics_h
+
+#import <Foundation/Foundation.h>
+#import <Security/SFAnalytics.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SFSignInAnalytics : NSObject <NSSecureCoding>
+
+@property (readonly) NSString* eventName;
+@property (readonly) NSString* category;
+@property (readonly) BOOL stopped;
+
+/*
+ abstract: creates a new SignInAnalytics object, automatically starts a timer for this task.
+ uuid: iCloud sign in transaction UUID
+ category: name of client subsystem. This will be used as the category name when logging
+ eventName: name of the event we are measuring
+ */
+- (instancetype _Nullable)initWithSignInUUID:(NSString *)uuid category:(NSString *)category eventName:(NSString*)eventName;
+- (instancetype)init NS_UNAVAILABLE;
+
+/*
+ abstract: creates a new SignInAnalytics that starts a timer for the subtask.
+ ideal for fine grained timing of sub events and automatically creates a dependency chain.
+ eventNmae: name of the event being timed
+ */
+- (SFSignInAnalytics* _Nullable)newSubTaskForEvent:(NSString*)eventName;
+
+/*
+ abstract: call to log when a recoverable error occurs during sign in
+ error: error that occured during iCloud Sign in
+ */
+- (void)logRecoverableError:(NSError*)error;
+
+/*
+ abstract: call to log when a unrecoverable error occurs during sign in
+ error: error that occured during iCloud Sign in
+ */
+- (void)logUnrecoverableError:(NSError*)error;
+
+/*
+ abstract: call to cancel the timer object.
+ */
+- (void)cancel;
+
+/*
+ abstract: call to stop a timer and log the time spent.
+ eventName: subsystem name
+ attributes: a dictionary containing event attributes
+ */
+- (void)stopWithAttributes:(NSDictionary<NSString*, id>* _Nullable)attributes;
+
+/*
+ abstract: call to signal iCloud sign in has finished.
+ */
+- (void)signInCompleted;
+
+@end
+NS_ASSUME_NONNULL_END
+#endif /* SignInAnalytics_h */
+#endif
--- /dev/null
+/*
+ * 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 "SFSignInAnalytics.h"
+#import "SFSignInAnalytics+Internal.h"
+
+#import <Analytics/SFAnalytics+Signin.h>
+#import "SFAnalyticsDefines.h"
+#import "SFAnalyticsSQLiteStore.h"
+#import "SFAnalytics.h"
+
+#import <os/log_private.h>
+#import <mach/mach_time.h>
+#import <utilities/SecFileLocations.h>
+#import <utilities/debugging.h>
+#import <utilities/SecCFWrappers.h>
+
+//metrics database location
+NSString* signinMetricsDatabase = @"signin_metrics";
+
+//defaults write results location
+static NSString* const SFSignInAnalyticsDumpLoggedResultsToLocation = @"/tmp/signin_results.txt";
+static NSString* const SFSignInAnalyticsPersistedEventList = @"/tmp/signin_eventlist";
+
+//analytics constants
+static NSString* const SFSignInAnalyticsAttributeRecoverableError = @"recoverableError";
+static NSString* const SFSignInAnalyticsAttributeErrorDomain = @"errorDomain";
+static NSString* const SFSignInAnalyticsAttributeErrorCode = @"errorCode";
+static NSString* const SFSignInAnalyticsAttributeErrorChain = @"errorChain";
+static NSString* const SFSignInAnalyticsAttributeParentUUID = @"parentUUID";
+static NSString* const SFSignInAnalyticsAttributeMyUUID = @"myUUID";
+static NSString* const SFSignInAnalyticsAttributeSignInUUID = @"signinUUID";
+static NSString* const SFSignInAnalyticsAttributeEventName = @"eventName";
+static NSString* const SFSignInAnalyticsAttributeSubsystemName = @"subsystemName";
+static NSString* const SFSignInAnalyticsAttributeBuiltDependencyChains = @"dependencyChains";
+
+@implementation SFSIALoggerObject
++ (NSString*)databasePath {
+ return [SFSIALoggerObject defaultAnalyticsDatabasePath:signinMetricsDatabase];
+}
+
++ (instancetype)logger
+{
+ return [super logger];
+}
+@end
+
+
+@interface SFSignInAnalytics ()
+@property (nonatomic, copy) NSString *signin_uuid;
+@property (nonatomic, copy) NSString *my_uuid;
+@property (nonatomic, copy) NSString *parent_uuid;
+@property (nonatomic, copy) NSString *category;
+@property (nonatomic, copy) NSString *eventName;
+@property (nonatomic, copy) NSString *persistencePath;
+
+@property (nonatomic, strong) NSURL *persistedEventPlist;
+@property (nonatomic, strong) NSMutableDictionary *eventDependencyList;
+@property (nonatomic, strong) NSMutableArray *builtDependencyChains;
+
+@property (nonatomic) BOOL canceled;
+@property (nonatomic) BOOL stopped;
+
+@property (nonatomic, strong) os_log_t logObject;
+
+@property (nonatomic, strong) NSNumber *measurement;
+
+@property (nonatomic, strong) dispatch_queue_t queue;
+
+@property (nonatomic, strong) SFSignInAnalytics *root;
+@property (nonatomic, strong) SFAnalyticsActivityTracker *tracker;
+
+-(os_log_t) newLogForCategoryName:(NSString*) category;
+-(os_log_t) logForCategoryName:(NSString*) category;
+
+@end
+
+static NSMutableDictionary *logObjects;
+static const NSString* signInLogSpace = @"com.apple.security.wiiss";
+
+@implementation SFSignInAnalytics
+
++ (BOOL)supportsSecureCoding {
+ return YES;
+}
+
+-(os_log_t) logForCategoryName:(NSString*) category
+{
+ return logObjects[category];
+}
+
+-(os_log_t) newLogForCategoryName:(NSString*) category
+{
+ return os_log_create([signInLogSpace UTF8String], [category UTF8String]);
+}
+
+- (BOOL)writeDependencyList:(NSError**)error
+{
+ NSError *localError = nil;
+ if (![NSPropertyListSerialization propertyList: self.root.eventDependencyList isValidForFormat: NSPropertyListXMLFormat_v1_0]){
+ os_log_error(self.logObject, "can't save PersistentState as XML");
+ return false;
+ }
+
+ NSData *data = [NSPropertyListSerialization dataWithPropertyList: self.root.eventDependencyList
+ format: NSPropertyListXMLFormat_v1_0 options: 0 error: &localError];
+ if (data == nil){
+ os_log_error(self.logObject, "error serializing PersistentState to xml: %@", localError);
+ return false;
+ }
+
+ BOOL writeStatus = [data writeToURL:self.root.persistedEventPlist options: NSDataWritingAtomic error: &localError];
+ if (!writeStatus){
+ os_log_error(self.logObject, "error writing PersistentState to file: %@", localError);
+ }
+ if(localError && error){
+ *error = localError;
+ }
+
+ return writeStatus;
+}
+
+- (instancetype)initWithSignInUUID:(NSString *)uuid category:(NSString *)category eventName:(NSString*)eventName
+{
+ self = [super init];
+ if (self) {
+ _signin_uuid = uuid;
+
+ _my_uuid = uuid;
+ _parent_uuid = uuid;
+ _eventName = eventName;
+ _category = category;
+ _root = self;
+ _canceled = NO;
+ _stopped = NO;
+ _builtDependencyChains = [NSMutableArray array];
+
+ //make plist file containing uuid parent/child
+ _persistencePath = [NSString stringWithFormat:@"%@-%@.plist", SFSignInAnalyticsPersistedEventList, eventName];
+ _persistedEventPlist = [NSURL fileURLWithPath:_persistencePath isDirectory:NO];
+
+ _eventDependencyList = [NSMutableDictionary dictionary];
+ [_eventDependencyList setObject:[NSMutableArray array] forKey:_signin_uuid];
+
+ _tracker = [[SFSIALoggerObject logger] logSystemMetricsForActivityNamed:eventName withAction:nil];
+ [_tracker start];
+
+ NSError* error = nil;
+ if(![self writeDependencyList:&error]){
+ os_log(self.logObject, "attempting to write dependency list: %@", error);
+ }
+
+ _queue = dispatch_queue_create("com.apple.security.SignInAnalytics", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ logObjects = [NSMutableDictionary dictionary];
+ });
+ @synchronized(logObjects){
+ if(category){
+ _logObject = [self logForCategoryName:category];
+
+ if(!_logObject){
+ _logObject = [self newLogForCategoryName:category];
+ [logObjects setObject:_logObject forKey:category];
+ }
+ }
+ }
+ }
+ return self;
+}
+
+-(instancetype) initChildWithSignInUUID:(NSString*)uuid andCategory:(NSString*)category andEventName:(NSString*)eventName
+{
+ self = [super init];
+ if (self) {
+ _signin_uuid = uuid;
+
+ _my_uuid = uuid;
+ _parent_uuid = uuid;
+ _eventName = eventName;
+ _category = category;
+ _canceled = NO;
+ }
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+ [coder encodeObject:_signin_uuid forKey:@"UUID"];
+ [coder encodeObject:_category forKey:@"category"];
+ [coder encodeObject:_parent_uuid forKey:@"parentUUID"];
+ [coder encodeObject:_my_uuid forKey:@"myUUID"];
+ [coder encodeObject:_measurement forKey:@"measurement"];
+ [coder encodeObject:_eventName forKey:@"eventName"];
+}
+
+- (nullable instancetype)initWithCoder:(NSCoder *)decoder
+{
+ self = [super init];
+ if (self) {
+ _signin_uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"UUID"];
+ _category = [decoder decodeObjectOfClass:[NSString class] forKey:@"category"];
+ _parent_uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"parentUUID"];
+ _my_uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"myUUID"];
+ _measurement = [decoder decodeObjectOfClass:[NSString class] forKey:@"measurement"];
+ _eventName = [decoder decodeObjectOfClass:[NSString class] forKey:@"eventName"];
+ _queue = dispatch_queue_create("com.apple.security.SignInAnalytics", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+
+ if(_signin_uuid == nil ||
+ _category == nil ||
+ _parent_uuid == nil){
+ [decoder failWithError:[NSError errorWithDomain:@"securityd" code:errSecDecode userInfo:@{NSLocalizedDescriptionKey: @"Failed to decode SignInAnalytics object"}]];
+ return nil;
+ }
+ }
+ return self;
+}
+
+- (SFSignInAnalytics*)newSubTaskForEvent:(NSString*)eventName
+{
+ SFSignInAnalytics *newSubTask = [[SFSignInAnalytics alloc] initChildWithSignInUUID:self.signin_uuid andCategory:self.category andEventName:self.eventName];
+ if(newSubTask){
+ newSubTask.my_uuid = [NSUUID UUID].UUIDString;
+ newSubTask.parent_uuid = self.my_uuid;
+ newSubTask.signin_uuid = self.signin_uuid;
+
+ newSubTask.category = self.category;
+ newSubTask.eventName = [eventName copy];
+ newSubTask.root = self.root;
+ newSubTask.canceled = NO;
+ newSubTask.stopped = NO;
+
+ newSubTask.queue = dispatch_queue_create("com.apple.security.SignInAnalytics", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
+ newSubTask.tracker = [[SFSIALoggerObject logger] logSystemMetricsForActivityNamed:eventName withAction:nil];
+ [newSubTask.tracker start];
+
+ @synchronized(_eventDependencyList){
+ NSMutableArray *parentEntry = [newSubTask.root.eventDependencyList objectForKey:newSubTask.parent_uuid];
+
+ //add new subtask entry to parent event's list
+ [parentEntry addObject:newSubTask.my_uuid];
+ [newSubTask.root.eventDependencyList setObject:parentEntry forKey:newSubTask.parent_uuid];
+
+ //create new array list for this new subtask incase it has subtasks
+ [newSubTask.root.eventDependencyList setObject:[NSMutableArray array] forKey:newSubTask.my_uuid];
+ NSError* error = nil;
+ if(![newSubTask writeDependencyList:&error]){
+ os_log(self.logObject, "attempting to write dependency list: %@", error);
+ }
+ }
+ }
+
+ return newSubTask;
+}
+
+- (void)logRecoverableError:(NSError*)error
+{
+
+ if (error == nil){
+ os_log_error(self.logObject, "attempting to log a nil error for event:%@", self.eventName);
+ return;
+ }
+
+ os_log_error(self.logObject, "%@", error);
+
+ NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary];
+
+ [eventAttributes setValuesForKeysWithDictionary:@{
+ SFSignInAnalyticsAttributeRecoverableError : @(YES),
+ SFSignInAnalyticsAttributeErrorDomain : error.domain,
+ SFSignInAnalyticsAttributeErrorCode : @(error.code),
+ SFSignInAnalyticsAttributeMyUUID : self.my_uuid,
+ SFSignInAnalyticsAttributeParentUUID : self.parent_uuid,
+ SFSignInAnalyticsAttributeSignInUUID : self.signin_uuid,
+ SFSignInAnalyticsAttributeEventName : self.eventName,
+ SFSignInAnalyticsAttributeSubsystemName : self.category
+ }];
+
+ [[SFSIALoggerObject logger] logSoftFailureForEventNamed:self.eventName withAttributes:eventAttributes];
+
+}
+
+- (void)logUnrecoverableError:(NSError*)error
+{
+ if (error == nil){
+ os_log_error(self.logObject, "attempting to log a nil error for event:%@", self.eventName);
+ return;
+ }
+
+ os_log_error(self.logObject, "%@", error);
+
+ NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary];
+
+ [eventAttributes setValuesForKeysWithDictionary:@{
+ SFSignInAnalyticsAttributeRecoverableError : @(NO),
+ SFSignInAnalyticsAttributeErrorDomain : error.domain,
+ SFSignInAnalyticsAttributeErrorCode : @(error.code),
+ SFSignInAnalyticsAttributeMyUUID : self.my_uuid,
+ SFSignInAnalyticsAttributeParentUUID : self.parent_uuid,
+ SFSignInAnalyticsAttributeSignInUUID : self.signin_uuid,
+ SFSignInAnalyticsAttributeEventName : self.eventName,
+ SFSignInAnalyticsAttributeSubsystemName : self.category
+ }];
+
+ [[SFSIALoggerObject logger] logHardFailureForEventNamed:self.eventName withAttributes:eventAttributes];
+}
+
+-(void)cancel
+{
+ dispatch_sync(self.queue, ^{
+ [self.tracker cancel];
+ self.canceled = YES;
+ os_log(self.logObject, "canceled timer for %@", self.eventName);
+ });
+}
+
+- (void)stopWithAttributes:(NSDictionary<NSString*, id>*)attributes
+{
+ dispatch_sync(self.queue, ^{
+
+ if(self.canceled || self.stopped){
+ return;
+ }
+
+ self.stopped = YES;
+
+ [self.tracker stop];
+
+ NSMutableDictionary *mutableAttributes = nil;
+
+ if(attributes){
+ mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
+ }
+ else{
+ mutableAttributes = [NSMutableDictionary dictionary];
+ }
+ mutableAttributes[SFSignInAnalyticsAttributeMyUUID] = self.my_uuid;
+ mutableAttributes[SFSignInAnalyticsAttributeParentUUID] = self.parent_uuid;
+ mutableAttributes[SFSignInAnalyticsAttributeSignInUUID] = self.signin_uuid;
+ mutableAttributes[SFSignInAnalyticsAttributeEventName] = self.eventName;
+ mutableAttributes[SFSignInAnalyticsAttributeSubsystemName] = self.category;
+
+ [mutableAttributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id obj, BOOL * stop) {
+ os_log(self.logObject, "event: %@, %@ : %@", self.eventName, key, obj);
+ }];
+
+ [[SFSIALoggerObject logger] logSuccessForEventNamed:self.eventName];
+ [[SFSIALoggerObject logger] logSoftFailureForEventNamed:self.eventName withAttributes:mutableAttributes];
+ });
+}
+
+-(BOOL) writeResultsToTmp {
+
+ bool shouldWriteResultsToTemp = NO;
+ CFBooleanRef toTmp = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("DumpResultsToTemp"),
+ CFSTR("com.apple.security"),
+ kCFPreferencesAnyUser, kCFPreferencesAnyHost);
+ if(toTmp && CFGetTypeID(toTmp) == CFBooleanGetTypeID()){
+ if(toTmp == kCFBooleanFalse){
+ os_log(self.logObject, "writing results to splunk");
+ shouldWriteResultsToTemp = NO;
+ }
+ if(toTmp == kCFBooleanTrue){
+ os_log(self.logObject, "writing results to /tmp");
+ shouldWriteResultsToTemp = YES;
+ }
+ }
+
+ CFReleaseNull(toTmp);
+ return shouldWriteResultsToTemp;
+}
+
+- (void)processEventChainForUUID:(NSString*)uuid dependencyChain:(NSString*)dependencyChain
+{
+ NSString* newChain = dependencyChain;
+
+ NSArray* children = [self.root.eventDependencyList objectForKey:uuid];
+ for (NSString* child in children) {
+ newChain = [NSString stringWithFormat:@"%@, %@", dependencyChain, child];
+ [self processEventChainForUUID:child dependencyChain:newChain];
+ }
+ if([children count] == 0){
+ [self.root.builtDependencyChains addObject:newChain];
+ os_log(self.logObject, "current dependency chain list: %@", newChain);
+ }
+}
+
+- (void)signInCompleted
+{
+ //print final
+ os_log(self.logObject, "sign in complete");
+ NSError* error = nil;
+
+ //create dependency chains and log them
+ [self processEventChainForUUID:self.root.my_uuid dependencyChain:self.root.signin_uuid];
+ //write to database
+ if([self.root.builtDependencyChains count] > 0){
+ NSDictionary* eventAttributes = @{SFSignInAnalyticsAttributeBuiltDependencyChains : self.root.builtDependencyChains};
+ [[SFSIALoggerObject logger] logSoftFailureForEventNamed:SFSignInAnalyticsAttributeBuiltDependencyChains withAttributes:eventAttributes];
+ }
+
+ BOOL writingToTmp = [self writeResultsToTmp];
+ if(writingToTmp){ //writing sign in analytics to /tmp
+ os_log(self.logObject, "logging to /tmp");
+
+ NSData* eventData = [NSKeyedArchiver archivedDataWithRootObject:[[SFSIALoggerObject logger].database allEvents] requiringSecureCoding:YES error:&error];
+ if(eventData){
+ [eventData writeToFile:SFSignInAnalyticsDumpLoggedResultsToLocation options:0 error:&error];
+
+ if(error){
+ os_log_error(self.logObject, "error writing to file [%@], error:%@", SFSignInAnalyticsDumpLoggedResultsToLocation, error);
+ }else{
+ os_log(self.logObject, "successfully wrote sign in analytics to:%@", SFSignInAnalyticsDumpLoggedResultsToLocation);
+ }
+ }else{
+ os_log_error(self.logObject, "collected no data");
+ }
+ }else{ //writing to splunk
+ os_log(self.logObject, "logging to splunk");
+ }
+
+ //remove dependency list
+ BOOL removedPersistedDependencyList = [[NSFileManager defaultManager] removeItemAtPath:self.persistencePath error:&error];
+
+ if(!removedPersistedDependencyList || error){
+ os_log(self.logObject, "encountered error when attempting to remove persisted event list: %@", error);
+ }
+
+}
+
+@end
+#endif
+
+++ /dev/null
-/*
- * 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 <Foundation/Foundation.h>
-
-@interface SFTransactionMetric : NSObject <NSSecureCoding>
-
-/*
- 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<NSString*, id>*)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
+++ /dev/null
-/*
- * 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 <os/log_private.h>
-
-@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<NSString*, id>*)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
--- /dev/null
+/*
+ * 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 <XCTest/XCTest.h>
+#import "keychain/Signin Metrics/SFSignInAnalytics.h"
+#import "keychain/Signin Metrics/SFSignInAnalytics+Internal.h"
+#import "keychain/ot/OTDefines.h"
+#import "SFAnalytics+Signin.h"
+#import <Security/SecureObjectSync/SOSCloudCircle.h>
+
+static NSInteger _testnum;
+static NSString* _path;
+
+@interface SFSignInAnalyticsTester : SFSignInAnalytics
+-(instancetype)init;
+@end
+
+@implementation SFSignInAnalyticsTester
+
++ (NSString*)databasePath {
+ return _path;
+}
+
+-(instancetype)init
+{
+ self = [super initWithSignInUUID:[NSUUID UUID].UUIDString category:@"CoreCDP" eventName:@"signin"];
+
+ return self;
+}
+
+@end
+
+
+@interface SignInAnalyticsTests : XCTestCase
+@property (nonatomic) SFSignInAnalyticsTester *metric;
+@end
+
+@implementation SignInAnalyticsTests
+
+
+- (void)setUp {
+ [super setUp];
+ _testnum = 0;
+ self.continueAfterFailure = NO;
+ _path = [@"/tmp" stringByAppendingFormat:@"/test_%ld.db", (long)++_testnum];
+ _metric = [[SFSignInAnalyticsTester alloc] init];
+ XCTAssertNotNil(_metric, "SignInAnalyticsTester object should not be nil");
+}
+
+- (void)tearDown
+{
+ dispatch_async([SFSIALoggerObject logger].queue, ^{
+ [[SFSIALoggerObject logger].database executeSQL:@"delete from all_events"];
+ [[SFSIALoggerObject logger].database executeSQL:@"delete from soft_failures"];
+ [[SFSIALoggerObject logger].database executeSQL:@"delete from hard_failures"];
+ });
+
+ [[SFSIALoggerObject logger] removeState];
+ _metric = nil;
+ [super tearDown];
+}
+
+- (void)testStop
+{
+ sleep(2);
+ NSDictionary *attributes = @{@"success": @YES,
+ @"takenFlow" : @"restore",
+ };
+ XCTAssertNotNil(attributes, "attributes dictionary should exist");
+
+ [_metric stopWithAttributes:attributes];
+
+ NSArray* results = [[SFSIALoggerObject logger].database allEvents];
+
+ XCTAssertEqual([results count], 2, @"should have 2 results");
+
+}
+
+- (void)testCancel
+{
+ [_metric cancel];
+}
+
+- (void)testLogError
+{
+ NSError* error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}];
+ [_metric logRecoverableError:error];
+ NSArray* results = [[SFSIALoggerObject logger].database softFailures];
+ XCTAssertEqual([results count], 1, @"should have 1 results");
+}
+
+- (void)testCreateNewSubtask
+{
+ SFSignInAnalytics* child = [_metric newSubTaskForEvent:@"restore"];
+ XCTAssertNotNil(child, "child should be created");
+ [[SFSIALoggerObject logger] removeState];
+ child = nil;
+}
+
+
+- (void)testCreateNewSubtaskAndStop
+{
+ SFSignInAnalytics* child = [_metric newSubTaskForEvent:@"restore"];
+
+ sleep(2);
+ NSDictionary *attributes = @{@"success": @YES,
+ @"takenFlow" : @"piggyback",
+ };
+
+ [child stopWithAttributes:attributes];
+
+ XCTAssertNotNil(child, "child should be created");
+
+ NSArray* results = [[SFSIALoggerObject logger].database allEvents];
+
+ XCTAssertEqual([results count], 2, @"should have 2 results");
+
+ [[SFSIALoggerObject logger] removeState];
+ child = nil;
+}
+
+- (void)testStopAfterCancel
+{
+ sleep(2);
+ NSDictionary *attributes = @{@"success": @YES,
+ @"takenFlow" : @"piggyback",
+ };
+ XCTAssertNotNil(attributes, "attributes dictionary should exist");
+
+ [_metric cancel];
+
+ [_metric stopWithAttributes:attributes];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+
+ XCTAssertEqual([allEvents count], 0, @"should have 0 things logged");
+}
+
+- (void)testStopAfterStop
+{
+ sleep(2);
+ NSDictionary *attributes = @{@"success": @YES,
+ @"takenFlow" : @"piggyback",
+ };
+ XCTAssertNotNil(attributes, "attributes dictionary should exist");
+
+ [_metric stopWithAttributes:attributes];
+
+ [_metric stopWithAttributes:attributes];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+
+ XCTAssertEqual([allEvents count], 2, @"should have 2 things logged");
+}
+
+-(void)testSignInComplete
+{
+ NSDictionary* attributes = [NSDictionary dictionary];
+ [_metric stopWithAttributes:attributes];
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array should not be nil");
+ XCTAssertTrue(allEvents && [allEvents count] > 0, "array should not be nil and contain an entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ XCTAssertTrue(dependencyEntry && [dependencyEntry count] > 0, "dictionary should not be nil and contain an entry");
+
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+
+ XCTAssertEqual([chains count], 1, "should be one list");
+
+ XCTAssertTrue([chains containsObject:_metric.signin_uuid], "should contain 1 uuid");
+}
+
+-(void)testSingleChainDependencyList
+{
+ SFSignInAnalytics* child1 = [_metric newSubTaskForEvent:@"piggyback"];
+ XCTAssertNotNil(child1, "child1 should be created");
+
+ SFSignInAnalytics* child2 = [child1 newSubTaskForEvent:@"initialsync"];
+ XCTAssertNotNil(child2, "child2 should be created");
+
+ SFSignInAnalytics* child3 = [child2 newSubTaskForEvent:@"backup"];
+ XCTAssertNotNil(child3, "child3 should be created");
+
+ SFSignInAnalytics* child4 = [child3 newSubTaskForEvent:@"processing one ring"];
+ XCTAssertNotNil(child4, "child4 should be created");
+
+ [_metric signInCompleted];
+
+ NSString *expectedChain = [NSString stringWithFormat:@"%@, %@, %@, %@, %@", child1.signin_uuid, child1.my_uuid, child2.my_uuid, child3.my_uuid, child4.my_uuid];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "should not be nil");
+ XCTAssertTrue([allEvents count] > 0, "should be events");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+
+ XCTAssertEqual([chains count], 1, "should be one list");
+ XCTAssertTrue([expectedChain isEqualToString:[chains objectAtIndex:0]], "chains should be the same");
+
+ child1 = nil;
+ child2 = nil;
+ child3 = nil;
+ child4 = nil;
+
+ child1 = nil;
+ child2 = nil;
+ child3 = nil;
+ child4 = nil;
+}
+
+-(void)testMultipleChildrenPerEvent
+{
+ SFSignInAnalytics* child1 = [_metric newSubTaskForEvent:@"piggyback"];
+ XCTAssertNotNil(child1, "child1 should be created");
+
+ SFSignInAnalytics* child2 = [child1 newSubTaskForEvent:@"initialsync"];
+ XCTAssertNotNil(child2, "child2 should be created");
+
+ SFSignInAnalytics* child3 = [child1 newSubTaskForEvent:@"backup"];
+ XCTAssertNotNil(child3, "child3 should be created");
+
+ SFSignInAnalytics* child4 = [child1 newSubTaskForEvent:@"processing one ring"];
+ XCTAssertNotNil(child4, "child4 should be created");
+
+ SFSignInAnalytics* child5 = [child2 newSubTaskForEvent:@"processing second ring"];
+ XCTAssertNotNil(child5, "child5 should be created");
+
+ SFSignInAnalytics* child6 = [child2 newSubTaskForEvent:@"processing third ring"];
+ XCTAssertNotNil(child6, "child6 should be created");
+
+ SFSignInAnalytics* child7 = [child2 newSubTaskForEvent:@"processing fourth ring"];
+ XCTAssertNotNil(child7, "child7 should be created");
+
+ SFSignInAnalytics* child8 = [child7 newSubTaskForEvent:@"processing fifth ring"];
+ XCTAssertNotNil(child8, "child8 should be created");
+
+ SFSignInAnalytics* child9 = [child7 newSubTaskForEvent:@"processing one ring"];
+ XCTAssertNotNil(child9, "child9 should be created");
+
+ NSString *expectedChain = [NSString stringWithFormat:@"%@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child5.my_uuid];
+
+ NSString *expectedChain1 = [NSString stringWithFormat:@"%@, %@, %@", _metric.signin_uuid, child1.my_uuid, child3.my_uuid];
+
+ NSString *expectedChain2 = [NSString stringWithFormat:@"%@, %@, %@", _metric.signin_uuid, child1.my_uuid, child4.my_uuid];
+
+ NSString *expectedChain3 = [NSString stringWithFormat:@"%@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child5.my_uuid];
+
+ NSString *expectedChain4 = [NSString stringWithFormat:@"%@, %@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child7.my_uuid, child8.my_uuid];
+
+ NSString *expectedChain5 = [NSString stringWithFormat:@"%@, %@, %@, %@, %@", _metric.signin_uuid, child1.my_uuid, child2.my_uuid, child7.my_uuid, child9.my_uuid];
+
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertTrue([allEvents count] > 0, "array should not be empty");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+
+ XCTAssertEqual([chains count], 6, "should be one list");
+
+ XCTAssertTrue([chains containsObject:expectedChain], "chains should contain expectedChain");
+ XCTAssertTrue([chains containsObject:expectedChain1], "chains should contain expectedChain1");
+ XCTAssertTrue([chains containsObject:expectedChain2], "chains should contain expectedChain2");
+ XCTAssertTrue([chains containsObject:expectedChain3], "chains should contain expectedChain3");
+ XCTAssertTrue([chains containsObject:expectedChain4], "chains should contain expectedChain4");
+ XCTAssertTrue([chains containsObject:expectedChain5], "chains should contain expectedChain5");
+
+ [[SFSIALoggerObject logger] removeState];
+
+ child1 = nil;
+ child2 = nil;
+ child3 = nil;
+ child4 = nil;
+ child5 = nil;
+ child6 = nil;
+ child7 = nil;
+ child8 = nil;
+ child9 = nil;
+
+}
+
+-(void)testSOSCCWaitForInitialSync
+{
+ CFErrorRef error = nil;
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ bool worked = SOSCCWaitForInitialSyncWithAnalytics(parentData, &error);
+ XCTAssertTrue(worked, "should have worked");
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+-(void)testSOSCCRemoveThisDeviceFromCircle
+{
+ CFErrorRef error = nil;
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ bool worked = SOSCCRemoveThisDeviceFromCircleWithAnalytics(parentData, &error);
+ XCTAssertTrue(worked, "should have worked");
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+-(void)testSOSCCRequestToJoinCircle
+{
+ CFErrorRef error = nil;
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ SOSCCRequestToJoinCircleWithAnalytics(parentData, &error);
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+-(void)testSOSCCRequestToJoinCircleAfterRestore
+{
+ CFErrorRef error = nil;
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(parentData, &error);
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+-(void)testSOSCCRemovePeersFromCircle
+{
+ CFErrorRef error = nil;
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ NSArray* peers = [NSArray array];
+ SOSCCRemovePeersFromCircleWithAnalytics((__bridge CFArrayRef)peers, parentData, &error);
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+
+-(void)testSOSCCViewSet
+{
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ CFSetRef enabledViews = nil;
+ CFSetRef disabledViews = nil;
+ SOSCCViewSetWithAnalytics(enabledViews, disabledViews, parentData);
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+-(void)testSOSCCSetUserCredentialsAndDSID
+{
+ CFErrorRef error = nil;
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ CFStringRef label = nil;
+ CFDataRef password = nil;
+ CFStringRef dsid = nil;
+ SOSCCSetUserCredentialsAndDSIDWithAnalytics(label, password, dsid, parentData, &error);
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+-(void)testSOSCCResetToEmpty
+{
+ CFErrorRef error = nil;
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
+ XCTAssertNotNil(archiver, "should not be nil");
+ [_metric encodeWithCoder:archiver];
+ CFDataRef parentData = (__bridge CFDataRef)archiver.encodedData;
+ XCTAssertNotNil((__bridge NSData*)parentData, "should not be nil");
+ SOSCCResetToEmptyWithAnalytics(parentData, &error);
+
+ [_metric signInCompleted];
+
+ NSArray *allEvents = [[SFSIALoggerObject logger].database allEvents];
+ XCTAssertNotNil(allEvents, "array is not nil");
+ XCTAssertEqual([allEvents count], 1, "array should not contain 1 entry");
+
+ NSDictionary *dependencyEntry = [allEvents objectAtIndex:[allEvents count]-1];
+ NSArray *chains = [dependencyEntry objectForKey:@"dependencyChains"];
+ XCTAssertNotNil(chains, "chains is not nil");
+ XCTAssertEqual([chains count], 1, "array should not contain 1 entry");
+}
+
+- (void)testMultipleDBConnections
+{
+ NSError* error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}];
+ dispatch_queue_t test_queue = dispatch_queue_create("com.apple.security.signin.tests", DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL);
+
+ for(int i = 0; i < 1000; i++){
+ SFSignInAnalytics *test1 = [_metric newSubTaskForEvent:@"connection1"];
+ SFSignInAnalytics *test2 = [_metric newSubTaskForEvent:@"connection2"];
+
+ dispatch_async(test_queue, ^{
+ [test1 logRecoverableError:error];
+ });
+ dispatch_async(test_queue, ^{
+ [test2 stopWithAttributes:nil];
+ });
+ dispatch_async(test_queue, ^{
+ [self->_metric logRecoverableError:error];
+ });
+ }
+}
+@end
+ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone;
+ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone count:(NSUInteger)count;
++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation count:(NSUInteger)count;
+
+ (void)OTPowerEvent:(NSString *)operation;
- (void)storedOQE:(CKKSOutgoingQueueEntry *)oqe;
});
}
++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation count:(NSUInteger)count
+{
+ SecPLLogRegisteredEvent(@"CKKSSyncing", @{
+ @"operation" : operation,
+ @"count" : @(count)
+ });
+}
+
+ (void)OTPowerEvent:(NSString *)operation
{
SecPLLogRegisteredEvent(@"OctagonTrust", @{
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <Foundation/Foundation.h>
-#import <ProtocolBuffer/PBCodable.h>
-
-#ifdef __cplusplus
-#define AWDKEYCHAINCKKSRATELIMITERAGGREGATEDSCORES_FUNCTION extern "C"
-#else
-#define AWDKEYCHAINCKKSRATELIMITERAGGREGATEDSCORES_FUNCTION extern
-#endif
-
-@interface AWDKeychainCKKSRateLimiterAggregatedScores : PBCodable <NSCopying>
-{
- PBRepeatedUInt32 _datas;
- uint64_t _timestamp;
- NSString *_ratelimitertype;
- struct {
- int timestamp:1;
- } _has;
-}
-
-
-@property (nonatomic) BOOL hasTimestamp;
-@property (nonatomic) uint64_t timestamp;
-
-@property (nonatomic, readonly) NSUInteger datasCount;
-@property (nonatomic, readonly) uint32_t *datas;
-- (void)clearDatas;
-- (void)addData:(uint32_t)i;
-- (uint32_t)dataAtIndex:(NSUInteger)idx;
-- (void)setDatas:(uint32_t *)list count:(NSUInteger)count;
-
-@property (nonatomic, readonly) BOOL hasRatelimitertype;
-@property (nonatomic, retain) NSString *ratelimitertype;
-
-// Performs a shallow copy into other
-- (void)copyTo:(AWDKeychainCKKSRateLimiterAggregatedScores *)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:(AWDKeychainCKKSRateLimiterAggregatedScores *)other;
-
-AWDKEYCHAINCKKSRATELIMITERAGGREGATEDSCORES_FUNCTION BOOL AWDKeychainCKKSRateLimiterAggregatedScoresReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterAggregatedScores *self, __unsafe_unretained PBDataReader *reader);
-
-@end
-
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <TargetConditionals.h>
-#if !TARGET_OS_BRIDGE
-
-#import "AWDKeychainCKKSRateLimiterAggregatedScores.h"
-#import <ProtocolBuffer/PBConstants.h>
-#import <ProtocolBuffer/PBHashUtil.h>
-#import <ProtocolBuffer/PBDataReader.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 AWDKeychainCKKSRateLimiterAggregatedScores
-
-- (void)dealloc
-{
- PBRepeatedUInt32Clear(&(self->_datas));
-}
-
-@synthesize timestamp = _timestamp;
-- (void)setTimestamp:(uint64_t)v
-{
- _has.timestamp = YES;
- _timestamp = v;
-}
-- (void)setHasTimestamp:(BOOL)f
-{
- _has.timestamp = f;
-}
-- (BOOL)hasTimestamp
-{
- return _has.timestamp;
-}
-- (NSUInteger)datasCount
-{
- return _datas.count;
-}
-- (uint32_t *)datas
-{
- return _datas.list;
-}
-- (void)clearDatas
-{
- PBRepeatedUInt32Clear(&_datas);
-}
-- (void)addData:(uint32_t)i
-{
- PBRepeatedUInt32Add(&_datas, i);
-}
-- (uint32_t)dataAtIndex:(NSUInteger)idx
-{
- if (_datas.count <= idx)
- {
- [[NSException exceptionWithName:NSRangeException reason:[NSString stringWithFormat:@"idx (%tu) is out of range (%tu)", idx, _datas.count] userInfo:nil] raise];
- }
- return _datas.list[idx];
-}
-- (void)setDatas:(uint32_t *)list count:(NSUInteger)count
-{
- PBRepeatedUInt32Set(&_datas, list, count);
-}
-- (BOOL)hasRatelimitertype
-{
- return _ratelimitertype != nil;
-}
-@synthesize ratelimitertype = _ratelimitertype;
-
-- (NSString *)description
-{
- return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]];
-}
-
-- (NSDictionary *)dictionaryRepresentation
-{
- NSMutableDictionary *dict = [NSMutableDictionary dictionary];
- if (self->_has.timestamp)
- {
- [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"];
- }
- [dict setObject:PBRepeatedUInt32NSArray(&(self->_datas)) forKey:@"data"];
- if (self->_ratelimitertype)
- {
- [dict setObject:self->_ratelimitertype forKey:@"ratelimitertype"];
- }
- return dict;
-}
-
-BOOL AWDKeychainCKKSRateLimiterAggregatedScoresReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterAggregatedScores *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 /* timestamp */:
- {
- self->_has.timestamp = YES;
- self->_timestamp = PBReaderReadUint64(reader);
- }
- break;
- case 2 /* datas */:
- {
- if (TYPE_LENGTH_DELIMITED == aType)
- {
- PBDataReaderMark mark_data;
- BOOL markError = !PBReaderPlaceMark(reader, &mark_data);
- if (markError)
- {
- return NO;
- }
- while (PBReaderHasMoreData(reader))
- {
- uint32_t new_data = PBReaderReadUint32(reader);
- PBRepeatedUInt32Add(&(self->_datas), new_data);
- }
- PBReaderRecallMark(reader, &mark_data);
- }
- else
- {
- PBRepeatedUInt32Add(&(self->_datas), PBReaderReadUint32(reader));
- }
- }
- break;
- case 3 /* ratelimitertype */:
- {
- NSString *new_ratelimitertype = PBReaderReadString(reader);
- self->_ratelimitertype = new_ratelimitertype;
- }
- break;
- default:
- if (!PBReaderSkipValueWithTag(reader, tag, aType))
- return NO;
- break;
- }
- }
- return !PBReaderHasError(reader);
-}
-
-- (BOOL)readFrom:(PBDataReader *)reader
-{
- return AWDKeychainCKKSRateLimiterAggregatedScoresReadFrom(self, reader);
-}
-- (void)writeTo:(PBDataWriter *)writer
-{
- /* timestamp */
- {
- if (self->_has.timestamp)
- {
- PBDataWriterWriteUint64Field(writer, self->_timestamp, 1);
- }
- }
- /* datas */
- {
- if (self->_datas.count)
- {
- NSUInteger i_datas;
- for (i_datas = 0; i_datas < self->_datas.count; i_datas++)
- {
- PBDataWriterWriteUint32Field(writer, self->_datas.list[i_datas], 2);
- }
- }
- }
- /* ratelimitertype */
- {
- if (self->_ratelimitertype)
- {
- PBDataWriterWriteStringField(writer, self->_ratelimitertype, 3);
- }
- }
-}
-
-- (void)copyTo:(AWDKeychainCKKSRateLimiterAggregatedScores *)other
-{
- if (self->_has.timestamp)
- {
- other->_timestamp = _timestamp;
- other->_has.timestamp = YES;
- }
- if ([self datasCount])
- {
- [other clearDatas];
- NSUInteger datasCnt = [self datasCount];
- for (NSUInteger i = 0; i < datasCnt; i++)
- {
- [other addData:[self dataAtIndex:i]];
- }
- }
- if (_ratelimitertype)
- {
- other.ratelimitertype = _ratelimitertype;
- }
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
- AWDKeychainCKKSRateLimiterAggregatedScores *copy = [[[self class] allocWithZone:zone] init];
- if (self->_has.timestamp)
- {
- copy->_timestamp = _timestamp;
- copy->_has.timestamp = YES;
- }
- PBRepeatedUInt32Copy(&(copy->_datas), &_datas);
- copy->_ratelimitertype = [_ratelimitertype copyWithZone:zone];
- return copy;
-}
-
-- (BOOL)isEqual:(id)object
-{
- AWDKeychainCKKSRateLimiterAggregatedScores *other = (AWDKeychainCKKSRateLimiterAggregatedScores *)object;
- return [other isMemberOfClass:[self class]]
- &&
- ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp))
- &&
- PBRepeatedUInt32IsEqual(&(self->_datas), &(other->_datas))
- &&
- ((!self->_ratelimitertype && !other->_ratelimitertype) || [self->_ratelimitertype isEqual:other->_ratelimitertype])
- ;
-}
-
-- (NSUInteger)hash
-{
- return 0
- ^
- (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0)
- ^
- PBRepeatedUInt32Hash(&(self->_datas))
- ^
- [self->_ratelimitertype hash]
- ;
-}
-
-- (void)mergeFrom:(AWDKeychainCKKSRateLimiterAggregatedScores *)other
-{
- if (other->_has.timestamp)
- {
- self->_timestamp = other->_timestamp;
- self->_has.timestamp = YES;
- }
- NSUInteger datasCnt = [other datasCount];
- for (NSUInteger i = 0; i < datasCnt; i++)
- {
- [self addData:[other dataAtIndex:i]];
- }
- if (other->_ratelimitertype)
- {
- [self setRatelimitertype:other->_ratelimitertype];
- }
-}
-
-@end
-#endif
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <Foundation/Foundation.h>
-#import <ProtocolBuffer/PBCodable.h>
-
-#ifdef __cplusplus
-#define AWDKEYCHAINCKKSRATELIMITEROVERLOAD_FUNCTION extern "C"
-#else
-#define AWDKEYCHAINCKKSRATELIMITEROVERLOAD_FUNCTION extern
-#endif
-
-@interface AWDKeychainCKKSRateLimiterOverload : PBCodable <NSCopying>
-{
- int64_t _durationMsec;
- uint64_t _timestamp;
- NSString *_ratelimitertype;
- struct {
- int durationMsec:1;
- int timestamp:1;
- } _has;
-}
-
-
-@property (nonatomic) BOOL hasTimestamp;
-@property (nonatomic) uint64_t timestamp;
-
-@property (nonatomic) BOOL hasDurationMsec;
-@property (nonatomic) int64_t durationMsec;
-
-@property (nonatomic, readonly) BOOL hasRatelimitertype;
-@property (nonatomic, retain) NSString *ratelimitertype;
-
-// Performs a shallow copy into other
-- (void)copyTo:(AWDKeychainCKKSRateLimiterOverload *)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:(AWDKeychainCKKSRateLimiterOverload *)other;
-
-AWDKEYCHAINCKKSRATELIMITEROVERLOAD_FUNCTION BOOL AWDKeychainCKKSRateLimiterOverloadReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterOverload *self, __unsafe_unretained PBDataReader *reader);
-
-@end
-
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <TargetConditionals.h>
-#if !TARGET_OS_BRIDGE
-
-#import "AWDKeychainCKKSRateLimiterOverload.h"
-#import <ProtocolBuffer/PBConstants.h>
-#import <ProtocolBuffer/PBHashUtil.h>
-#import <ProtocolBuffer/PBDataReader.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 AWDKeychainCKKSRateLimiterOverload
-
-@synthesize timestamp = _timestamp;
-- (void)setTimestamp:(uint64_t)v
-{
- _has.timestamp = YES;
- _timestamp = v;
-}
-- (void)setHasTimestamp:(BOOL)f
-{
- _has.timestamp = f;
-}
-- (BOOL)hasTimestamp
-{
- return _has.timestamp;
-}
-@synthesize durationMsec = _durationMsec;
-- (void)setDurationMsec:(int64_t)v
-{
- _has.durationMsec = YES;
- _durationMsec = v;
-}
-- (void)setHasDurationMsec:(BOOL)f
-{
- _has.durationMsec = f;
-}
-- (BOOL)hasDurationMsec
-{
- return _has.durationMsec;
-}
-- (BOOL)hasRatelimitertype
-{
- return _ratelimitertype != nil;
-}
-@synthesize ratelimitertype = _ratelimitertype;
-
-- (NSString *)description
-{
- return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]];
-}
-
-- (NSDictionary *)dictionaryRepresentation
-{
- NSMutableDictionary *dict = [NSMutableDictionary dictionary];
- if (self->_has.timestamp)
- {
- [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"];
- }
- if (self->_has.durationMsec)
- {
- [dict setObject:[NSNumber numberWithLongLong:self->_durationMsec] forKey:@"durationMsec"];
- }
- if (self->_ratelimitertype)
- {
- [dict setObject:self->_ratelimitertype forKey:@"ratelimitertype"];
- }
- return dict;
-}
-
-BOOL AWDKeychainCKKSRateLimiterOverloadReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterOverload *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 /* timestamp */:
- {
- self->_has.timestamp = YES;
- self->_timestamp = PBReaderReadUint64(reader);
- }
- break;
- case 2 /* durationMsec */:
- {
- self->_has.durationMsec = YES;
- self->_durationMsec = PBReaderReadInt64(reader);
- }
- break;
- case 3 /* ratelimitertype */:
- {
- NSString *new_ratelimitertype = PBReaderReadString(reader);
- self->_ratelimitertype = new_ratelimitertype;
- }
- break;
- default:
- if (!PBReaderSkipValueWithTag(reader, tag, aType))
- return NO;
- break;
- }
- }
- return !PBReaderHasError(reader);
-}
-
-- (BOOL)readFrom:(PBDataReader *)reader
-{
- return AWDKeychainCKKSRateLimiterOverloadReadFrom(self, reader);
-}
-- (void)writeTo:(PBDataWriter *)writer
-{
- /* timestamp */
- {
- if (self->_has.timestamp)
- {
- PBDataWriterWriteUint64Field(writer, self->_timestamp, 1);
- }
- }
- /* durationMsec */
- {
- if (self->_has.durationMsec)
- {
- PBDataWriterWriteInt64Field(writer, self->_durationMsec, 2);
- }
- }
- /* ratelimitertype */
- {
- if (self->_ratelimitertype)
- {
- PBDataWriterWriteStringField(writer, self->_ratelimitertype, 3);
- }
- }
-}
-
-- (void)copyTo:(AWDKeychainCKKSRateLimiterOverload *)other
-{
- if (self->_has.timestamp)
- {
- other->_timestamp = _timestamp;
- other->_has.timestamp = YES;
- }
- if (self->_has.durationMsec)
- {
- other->_durationMsec = _durationMsec;
- other->_has.durationMsec = YES;
- }
- if (_ratelimitertype)
- {
- other.ratelimitertype = _ratelimitertype;
- }
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
- AWDKeychainCKKSRateLimiterOverload *copy = [[[self class] allocWithZone:zone] init];
- if (self->_has.timestamp)
- {
- copy->_timestamp = _timestamp;
- copy->_has.timestamp = YES;
- }
- if (self->_has.durationMsec)
- {
- copy->_durationMsec = _durationMsec;
- copy->_has.durationMsec = YES;
- }
- copy->_ratelimitertype = [_ratelimitertype copyWithZone:zone];
- return copy;
-}
-
-- (BOOL)isEqual:(id)object
-{
- AWDKeychainCKKSRateLimiterOverload *other = (AWDKeychainCKKSRateLimiterOverload *)object;
- return [other isMemberOfClass:[self class]]
- &&
- ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp))
- &&
- ((self->_has.durationMsec && other->_has.durationMsec && self->_durationMsec == other->_durationMsec) || (!self->_has.durationMsec && !other->_has.durationMsec))
- &&
- ((!self->_ratelimitertype && !other->_ratelimitertype) || [self->_ratelimitertype isEqual:other->_ratelimitertype])
- ;
-}
-
-- (NSUInteger)hash
-{
- return 0
- ^
- (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0)
- ^
- (self->_has.durationMsec ? PBHashInt((NSUInteger)self->_durationMsec) : 0)
- ^
- [self->_ratelimitertype hash]
- ;
-}
-
-- (void)mergeFrom:(AWDKeychainCKKSRateLimiterOverload *)other
-{
- if (other->_has.timestamp)
- {
- self->_timestamp = other->_timestamp;
- self->_has.timestamp = YES;
- }
- if (other->_has.durationMsec)
- {
- self->_durationMsec = other->_durationMsec;
- self->_has.durationMsec = YES;
- }
- if (other->_ratelimitertype)
- {
- [self setRatelimitertype:other->_ratelimitertype];
- }
-}
-
-@end
-#endif
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <Foundation/Foundation.h>
-#import <ProtocolBuffer/PBCodable.h>
-
-#ifdef __cplusplus
-#define AWDKEYCHAINCKKSRATELIMITERTOPWRITERS_FUNCTION extern "C"
-#else
-#define AWDKEYCHAINCKKSRATELIMITERTOPWRITERS_FUNCTION extern
-#endif
-
-@interface AWDKeychainCKKSRateLimiterTopWriters : PBCodable <NSCopying>
-{
- uint64_t _timestamp;
- NSString *_ratelimitertype;
- NSMutableArray<NSString *> *_writers;
- struct {
- int timestamp:1;
- } _has;
-}
-
-
-@property (nonatomic) BOOL hasTimestamp;
-@property (nonatomic) uint64_t timestamp;
-
-@property (nonatomic, retain) NSMutableArray<NSString *> *writers;
-- (void)clearWriters;
-- (void)addWriter:(NSString *)i;
-- (NSUInteger)writersCount;
-- (NSString *)writerAtIndex:(NSUInteger)idx;
-+ (Class)writerType;
-
-@property (nonatomic, readonly) BOOL hasRatelimitertype;
-@property (nonatomic, retain) NSString *ratelimitertype;
-
-// Performs a shallow copy into other
-- (void)copyTo:(AWDKeychainCKKSRateLimiterTopWriters *)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:(AWDKeychainCKKSRateLimiterTopWriters *)other;
-
-AWDKEYCHAINCKKSRATELIMITERTOPWRITERS_FUNCTION BOOL AWDKeychainCKKSRateLimiterTopWritersReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterTopWriters *self, __unsafe_unretained PBDataReader *reader);
-
-@end
-
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <TargetConditionals.h>
-#if !TARGET_OS_BRIDGE
-
-#import "AWDKeychainCKKSRateLimiterTopWriters.h"
-#import <ProtocolBuffer/PBConstants.h>
-#import <ProtocolBuffer/PBHashUtil.h>
-#import <ProtocolBuffer/PBDataReader.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 AWDKeychainCKKSRateLimiterTopWriters
-
-@synthesize timestamp = _timestamp;
-- (void)setTimestamp:(uint64_t)v
-{
- _has.timestamp = YES;
- _timestamp = v;
-}
-- (void)setHasTimestamp:(BOOL)f
-{
- _has.timestamp = f;
-}
-- (BOOL)hasTimestamp
-{
- return _has.timestamp;
-}
-@synthesize writers = _writers;
-- (void)clearWriters
-{
- [_writers removeAllObjects];
-}
-- (void)addWriter:(NSString *)i
-{
- if (!_writers)
- {
- _writers = [[NSMutableArray alloc] init];
- }
- [_writers addObject:i];
-}
-- (NSUInteger)writersCount
-{
- return [_writers count];
-}
-- (NSString *)writerAtIndex:(NSUInteger)idx
-{
- return [_writers objectAtIndex:idx];
-}
-+ (Class)writerType
-{
- return [NSString class];
-}
-- (BOOL)hasRatelimitertype
-{
- return _ratelimitertype != nil;
-}
-@synthesize ratelimitertype = _ratelimitertype;
-
-- (NSString *)description
-{
- return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]];
-}
-
-- (NSDictionary *)dictionaryRepresentation
-{
- NSMutableDictionary *dict = [NSMutableDictionary dictionary];
- if (self->_has.timestamp)
- {
- [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"];
- }
- if (self->_writers)
- {
- [dict setObject:self->_writers forKey:@"writer"];
- }
- if (self->_ratelimitertype)
- {
- [dict setObject:self->_ratelimitertype forKey:@"ratelimitertype"];
- }
- return dict;
-}
-
-BOOL AWDKeychainCKKSRateLimiterTopWritersReadFrom(__unsafe_unretained AWDKeychainCKKSRateLimiterTopWriters *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 /* timestamp */:
- {
- self->_has.timestamp = YES;
- self->_timestamp = PBReaderReadUint64(reader);
- }
- break;
- case 2 /* writers */:
- {
- NSString *new_writers = PBReaderReadString(reader);
- if (new_writers)
- {
- [self addWriter:new_writers];
- }
- }
- break;
- case 3 /* ratelimitertype */:
- {
- NSString *new_ratelimitertype = PBReaderReadString(reader);
- self->_ratelimitertype = new_ratelimitertype;
- }
- break;
- default:
- if (!PBReaderSkipValueWithTag(reader, tag, aType))
- return NO;
- break;
- }
- }
- return !PBReaderHasError(reader);
-}
-
-- (BOOL)readFrom:(PBDataReader *)reader
-{
- return AWDKeychainCKKSRateLimiterTopWritersReadFrom(self, reader);
-}
-- (void)writeTo:(PBDataWriter *)writer
-{
- /* timestamp */
- {
- if (self->_has.timestamp)
- {
- PBDataWriterWriteUint64Field(writer, self->_timestamp, 1);
- }
- }
- /* writers */
- {
- for (NSString *s_writers in self->_writers)
- {
- PBDataWriterWriteStringField(writer, s_writers, 2);
- }
- }
- /* ratelimitertype */
- {
- if (self->_ratelimitertype)
- {
- PBDataWriterWriteStringField(writer, self->_ratelimitertype, 3);
- }
- }
-}
-
-- (void)copyTo:(AWDKeychainCKKSRateLimiterTopWriters *)other
-{
- if (self->_has.timestamp)
- {
- other->_timestamp = _timestamp;
- other->_has.timestamp = YES;
- }
- if ([self writersCount])
- {
- [other clearWriters];
- NSUInteger writersCnt = [self writersCount];
- for (NSUInteger i = 0; i < writersCnt; i++)
- {
- [other addWriter:[self writerAtIndex:i]];
- }
- }
- if (_ratelimitertype)
- {
- other.ratelimitertype = _ratelimitertype;
- }
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
- AWDKeychainCKKSRateLimiterTopWriters *copy = [[[self class] allocWithZone:zone] init];
- if (self->_has.timestamp)
- {
- copy->_timestamp = _timestamp;
- copy->_has.timestamp = YES;
- }
- for (NSString *v in _writers)
- {
- NSString *vCopy = [v copyWithZone:zone];
- [copy addWriter:vCopy];
- }
- copy->_ratelimitertype = [_ratelimitertype copyWithZone:zone];
- return copy;
-}
-
-- (BOOL)isEqual:(id)object
-{
- AWDKeychainCKKSRateLimiterTopWriters *other = (AWDKeychainCKKSRateLimiterTopWriters *)object;
- return [other isMemberOfClass:[self class]]
- &&
- ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp))
- &&
- ((!self->_writers && !other->_writers) || [self->_writers isEqual:other->_writers])
- &&
- ((!self->_ratelimitertype && !other->_ratelimitertype) || [self->_ratelimitertype isEqual:other->_ratelimitertype])
- ;
-}
-
-- (NSUInteger)hash
-{
- return 0
- ^
- (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0)
- ^
- [self->_writers hash]
- ^
- [self->_ratelimitertype hash]
- ;
-}
-
-- (void)mergeFrom:(AWDKeychainCKKSRateLimiterTopWriters *)other
-{
- if (other->_has.timestamp)
- {
- self->_timestamp = other->_timestamp;
- self->_has.timestamp = YES;
- }
- for (NSString *iter_writers in other->_writers)
- {
- [self addWriter:iter_writers];
- }
- if (other->_ratelimitertype)
- {
- [self setRatelimitertype:other->_ratelimitertype];
- }
-}
-
-@end
-#endif
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <Foundation/Foundation.h>
-#import <ProtocolBuffer/PBCodable.h>
-
-#ifdef __cplusplus
-#define AWDKEYCHAINSOSKEYCHAINBACKUPFAILED_FUNCTION extern "C"
-#else
-#define AWDKEYCHAINSOSKEYCHAINBACKUPFAILED_FUNCTION extern
-#endif
-
-@interface AWDKeychainSOSKeychainBackupFailed : PBCodable <NSCopying>
-{
- uint64_t _timestamp;
- struct {
- int timestamp:1;
- } _has;
-}
-
-
-@property (nonatomic) BOOL hasTimestamp;
-@property (nonatomic) uint64_t timestamp;
-
-// Performs a shallow copy into other
-- (void)copyTo:(AWDKeychainSOSKeychainBackupFailed *)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:(AWDKeychainSOSKeychainBackupFailed *)other;
-
-AWDKEYCHAINSOSKEYCHAINBACKUPFAILED_FUNCTION BOOL AWDKeychainSOSKeychainBackupFailedReadFrom(__unsafe_unretained AWDKeychainSOSKeychainBackupFailed *self, __unsafe_unretained PBDataReader *reader);
-
-@end
-
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <TargetConditionals.h>
-#if !TARGET_OS_BRIDGE
-
-#import "AWDKeychainSOSKeychainBackupFailed.h"
-#import <ProtocolBuffer/PBConstants.h>
-#import <ProtocolBuffer/PBHashUtil.h>
-#import <ProtocolBuffer/PBDataReader.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 AWDKeychainSOSKeychainBackupFailed
-
-@synthesize timestamp = _timestamp;
-- (void)setTimestamp:(uint64_t)v
-{
- _has.timestamp = YES;
- _timestamp = v;
-}
-- (void)setHasTimestamp:(BOOL)f
-{
- _has.timestamp = f;
-}
-- (BOOL)hasTimestamp
-{
- return _has.timestamp;
-}
-
-- (NSString *)description
-{
- return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]];
-}
-
-- (NSDictionary *)dictionaryRepresentation
-{
- NSMutableDictionary *dict = [NSMutableDictionary dictionary];
- if (self->_has.timestamp)
- {
- [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"];
- }
- return dict;
-}
-
-BOOL AWDKeychainSOSKeychainBackupFailedReadFrom(__unsafe_unretained AWDKeychainSOSKeychainBackupFailed *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 /* timestamp */:
- {
- self->_has.timestamp = YES;
- self->_timestamp = PBReaderReadUint64(reader);
- }
- break;
- default:
- if (!PBReaderSkipValueWithTag(reader, tag, aType))
- return NO;
- break;
- }
- }
- return !PBReaderHasError(reader);
-}
-
-- (BOOL)readFrom:(PBDataReader *)reader
-{
- return AWDKeychainSOSKeychainBackupFailedReadFrom(self, reader);
-}
-- (void)writeTo:(PBDataWriter *)writer
-{
- /* timestamp */
- {
- if (self->_has.timestamp)
- {
- PBDataWriterWriteUint64Field(writer, self->_timestamp, 1);
- }
- }
-}
-
-- (void)copyTo:(AWDKeychainSOSKeychainBackupFailed *)other
-{
- if (self->_has.timestamp)
- {
- other->_timestamp = _timestamp;
- other->_has.timestamp = YES;
- }
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
- AWDKeychainSOSKeychainBackupFailed *copy = [[[self class] allocWithZone:zone] init];
- if (self->_has.timestamp)
- {
- copy->_timestamp = _timestamp;
- copy->_has.timestamp = YES;
- }
- return copy;
-}
-
-- (BOOL)isEqual:(id)object
-{
- AWDKeychainSOSKeychainBackupFailed *other = (AWDKeychainSOSKeychainBackupFailed *)object;
- return [other isMemberOfClass:[self class]]
- &&
- ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp))
- ;
-}
-
-- (NSUInteger)hash
-{
- return 0
- ^
- (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0)
- ;
-}
-
-- (void)mergeFrom:(AWDKeychainSOSKeychainBackupFailed *)other
-{
- if (other->_has.timestamp)
- {
- self->_timestamp = other->_timestamp;
- self->_has.timestamp = YES;
- }
-}
-
-@end
-#endif
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <Foundation/Foundation.h>
-#import <ProtocolBuffer/PBCodable.h>
-
-#ifdef __cplusplus
-#define AWDKEYCHAINSECDBMARKEDCORRUPT_FUNCTION extern "C"
-#else
-#define AWDKEYCHAINSECDBMARKEDCORRUPT_FUNCTION extern
-#endif
-
-@interface AWDKeychainSecDbMarkedCorrupt : PBCodable <NSCopying>
-{
- uint64_t _timestamp;
- uint32_t _reason;
- uint32_t _sqlitecode;
- struct {
- int timestamp:1;
- int reason:1;
- int sqlitecode:1;
- } _has;
-}
-
-
-@property (nonatomic) BOOL hasTimestamp;
-@property (nonatomic) uint64_t timestamp;
-
-@property (nonatomic) BOOL hasReason;
-@property (nonatomic) uint32_t reason;
-
-@property (nonatomic) BOOL hasSqlitecode;
-@property (nonatomic) uint32_t sqlitecode;
-
-// Performs a shallow copy into other
-- (void)copyTo:(AWDKeychainSecDbMarkedCorrupt *)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:(AWDKeychainSecDbMarkedCorrupt *)other;
-
-AWDKEYCHAINSECDBMARKEDCORRUPT_FUNCTION BOOL AWDKeychainSecDbMarkedCorruptReadFrom(__unsafe_unretained AWDKeychainSecDbMarkedCorrupt *self, __unsafe_unretained PBDataReader *reader);
-
-@end
-
+++ /dev/null
-// This file was automatically generated by protocompiler
-// DO NOT EDIT!
-// Compiled from stdin
-
-#import <TargetConditionals.h>
-#if !TARGET_OS_BRIDGE
-
-#import "AWDKeychainSecDbMarkedCorrupt.h"
-#import <ProtocolBuffer/PBConstants.h>
-#import <ProtocolBuffer/PBHashUtil.h>
-#import <ProtocolBuffer/PBDataReader.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 AWDKeychainSecDbMarkedCorrupt
-
-@synthesize timestamp = _timestamp;
-- (void)setTimestamp:(uint64_t)v
-{
- _has.timestamp = YES;
- _timestamp = v;
-}
-- (void)setHasTimestamp:(BOOL)f
-{
- _has.timestamp = f;
-}
-- (BOOL)hasTimestamp
-{
- return _has.timestamp;
-}
-@synthesize reason = _reason;
-- (void)setReason:(uint32_t)v
-{
- _has.reason = YES;
- _reason = v;
-}
-- (void)setHasReason:(BOOL)f
-{
- _has.reason = f;
-}
-- (BOOL)hasReason
-{
- return _has.reason;
-}
-@synthesize sqlitecode = _sqlitecode;
-- (void)setSqlitecode:(uint32_t)v
-{
- _has.sqlitecode = YES;
- _sqlitecode = v;
-}
-- (void)setHasSqlitecode:(BOOL)f
-{
- _has.sqlitecode = f;
-}
-- (BOOL)hasSqlitecode
-{
- return _has.sqlitecode;
-}
-
-- (NSString *)description
-{
- return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]];
-}
-
-- (NSDictionary *)dictionaryRepresentation
-{
- NSMutableDictionary *dict = [NSMutableDictionary dictionary];
- if (self->_has.timestamp)
- {
- [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestamp] forKey:@"timestamp"];
- }
- if (self->_has.reason)
- {
- [dict setObject:[NSNumber numberWithUnsignedInt:self->_reason] forKey:@"reason"];
- }
- if (self->_has.sqlitecode)
- {
- [dict setObject:[NSNumber numberWithUnsignedInt:self->_sqlitecode] forKey:@"sqlitecode"];
- }
- return dict;
-}
-
-BOOL AWDKeychainSecDbMarkedCorruptReadFrom(__unsafe_unretained AWDKeychainSecDbMarkedCorrupt *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 /* timestamp */:
- {
- self->_has.timestamp = YES;
- self->_timestamp = PBReaderReadUint64(reader);
- }
- break;
- case 2 /* reason */:
- {
- self->_has.reason = YES;
- self->_reason = PBReaderReadUint32(reader);
- }
- break;
- case 3 /* sqlitecode */:
- {
- self->_has.sqlitecode = YES;
- self->_sqlitecode = PBReaderReadUint32(reader);
- }
- break;
- default:
- if (!PBReaderSkipValueWithTag(reader, tag, aType))
- return NO;
- break;
- }
- }
- return !PBReaderHasError(reader);
-}
-
-- (BOOL)readFrom:(PBDataReader *)reader
-{
- return AWDKeychainSecDbMarkedCorruptReadFrom(self, reader);
-}
-- (void)writeTo:(PBDataWriter *)writer
-{
- /* timestamp */
- {
- if (self->_has.timestamp)
- {
- PBDataWriterWriteUint64Field(writer, self->_timestamp, 1);
- }
- }
- /* reason */
- {
- if (self->_has.reason)
- {
- PBDataWriterWriteUint32Field(writer, self->_reason, 2);
- }
- }
- /* sqlitecode */
- {
- if (self->_has.sqlitecode)
- {
- PBDataWriterWriteUint32Field(writer, self->_sqlitecode, 3);
- }
- }
-}
-
-- (void)copyTo:(AWDKeychainSecDbMarkedCorrupt *)other
-{
- if (self->_has.timestamp)
- {
- other->_timestamp = _timestamp;
- other->_has.timestamp = YES;
- }
- if (self->_has.reason)
- {
- other->_reason = _reason;
- other->_has.reason = YES;
- }
- if (self->_has.sqlitecode)
- {
- other->_sqlitecode = _sqlitecode;
- other->_has.sqlitecode = YES;
- }
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
- AWDKeychainSecDbMarkedCorrupt *copy = [[[self class] allocWithZone:zone] init];
- if (self->_has.timestamp)
- {
- copy->_timestamp = _timestamp;
- copy->_has.timestamp = YES;
- }
- if (self->_has.reason)
- {
- copy->_reason = _reason;
- copy->_has.reason = YES;
- }
- if (self->_has.sqlitecode)
- {
- copy->_sqlitecode = _sqlitecode;
- copy->_has.sqlitecode = YES;
- }
- return copy;
-}
-
-- (BOOL)isEqual:(id)object
-{
- AWDKeychainSecDbMarkedCorrupt *other = (AWDKeychainSecDbMarkedCorrupt *)object;
- return [other isMemberOfClass:[self class]]
- &&
- ((self->_has.timestamp && other->_has.timestamp && self->_timestamp == other->_timestamp) || (!self->_has.timestamp && !other->_has.timestamp))
- &&
- ((self->_has.reason && other->_has.reason && self->_reason == other->_reason) || (!self->_has.reason && !other->_has.reason))
- &&
- ((self->_has.sqlitecode && other->_has.sqlitecode && self->_sqlitecode == other->_sqlitecode) || (!self->_has.sqlitecode && !other->_has.sqlitecode))
- ;
-}
-
-- (NSUInteger)hash
-{
- return 0
- ^
- (self->_has.timestamp ? PBHashInt((NSUInteger)self->_timestamp) : 0)
- ^
- (self->_has.reason ? PBHashInt((NSUInteger)self->_reason) : 0)
- ^
- (self->_has.sqlitecode ? PBHashInt((NSUInteger)self->_sqlitecode) : 0)
- ;
-}
-
-- (void)mergeFrom:(AWDKeychainSecDbMarkedCorrupt *)other
-{
- if (other->_has.timestamp)
- {
- self->_timestamp = other->_timestamp;
- self->_has.timestamp = YES;
- }
- if (other->_has.reason)
- {
- self->_reason = other->_reason;
- self->_has.reason = YES;
- }
- if (other->_has.sqlitecode)
- {
- self->_sqlitecode = other->_sqlitecode;
- self->_has.sqlitecode = YES;
- }
-}
-
-@end
-#endif
+++ /dev/null
-//
-// AWDMetricIds_Keychain.h
-// AppleWirelessDiagnostics
-//
-// WARNING :: DO NOT MODIFY THIS FILE!
-//
-// This file is auto-generated! Do not modify it or your changes will get overwritten!
-//
-
-#ifndef AWD_MetricId_HeaderGuard_Keychain
-#define AWD_MetricId_HeaderGuard_Keychain
-
-// Component Id:
-// ---------------
-// Use this value for any API requesting the "component id" for your component.
-enum {
- AWDComponentId_Keychain = 0x60
-};
-
-
-// Simple Metrics:
-// ---------------
-// The following metrics are compatible with the 'simple metric' API:
-enum {
-
- AWDMetricId_Keychain_SOSKeychainBackupFailed = 0x600004
-};
-
-// General Metrics:
-// ----------------
-enum {
- AWDMetricId_Keychain_CKKSRateLimiterOverload = 0x600000,
- AWDMetricId_Keychain_CKKSRateLimiterTopWriters = 0x600001,
- AWDMetricId_Keychain_CKKSRateLimiterAggregatedScores = 0x600002,
- AWDMetricId_Keychain_SecDbMarkedCorrupt = 0x600003
-};
-
-#endif // AWD_MetricId_HeaderGuard_Keychain
--- /dev/null
+/*
+ * 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 <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NSError (UsefulConstructors)
+
+// Every error should have a description
++ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description;
+
+// Sometimes you also want to have an underlying error (which might be null)
++ (instancetype)errorWithDomain:(NSErrorDomain)domain
+ code:(NSInteger)code
+ description:(NSString*)description
+ underlying:(NSError* _Nullable)underlying;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+/*
+ * 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 "NSError+UsefulConstructors.h"
+
+@implementation NSError (UsefulConstructors)
+
++ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description {
+ return [NSError errorWithDomain:domain code:code description:description underlying:nil];
+}
+
++ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description underlying:(NSError*)underlying {
+ // Obj-C throws a fit if there's nulls in dictionaries, so we can't use a dictionary literal here.
+ // Use the null-assignment semantics of NSMutableDictionary to make a dictionary either with either, both, or neither key.
+ NSMutableDictionary* mut = [[NSMutableDictionary alloc] init];
+ mut[NSLocalizedDescriptionKey] = description;
+ mut[NSUnderlyingErrorKey] = underlying;
+
+ return [NSError errorWithDomain:domain code:code userInfo:mut];
+}
+
+@end
extern CKKSKeyClass* const SecCKKSKeyClassC;
/* Useful CloudKit configuration */
-extern NSString* const SecCKKSContainerName;
+extern NSString* SecCKKSContainerName;
extern bool SecCKKSContainerUsePCS;
extern NSString* const SecCKKSSubscriptionID;
extern NSString* const SecCKKSAPSNamedPort;
extern CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKSharesFailed;
// The key hierarchy state machine needs to wait for the fixup operation to complete
extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForFixupOperation;
+// The key hierarchy state machine is responding to a key state reprocess request
+extern CKKSZoneKeyState* const SecCKKSZoneKeyStateProcess;
// CKKS is resetting the remote zone, due to key hierarchy reasons. Will not proceed until the local reset occurs.
extern CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone;
CKKSNotHSA2 = 40,
CKKSiCloudGreyMode = 41,
+
+ CKKSNoFetchesRequested = 50,
};
typedef CF_ENUM(CFIndex, CKKSResultDescriptionErrorCode) {
CKKSKeyClass* const SecCKKSKeyClassA = (CKKSKeyClass*) @"classA";
CKKSKeyClass* const SecCKKSKeyClassC = (CKKSKeyClass*) @"classC";
-NSString* const SecCKKSContainerName = @"com.apple.security.keychain";
+NSString* SecCKKSContainerName = @"com.apple.security.keychain";
bool SecCKKSContainerUsePCS = false;
NSString* const SecCKKSSubscriptionID = @"keychain-changes";
CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingLocalData = (CKKSZoneKeyState*) @"resetlocal";
CKKSZoneKeyState* const SecCKKSZoneKeyStateLoggedOut = (CKKSZoneKeyState*) @"loggedout";
CKKSZoneKeyState* const SecCKKSZoneKeyStateZoneCreationFailed = (CKKSZoneKeyState*) @"zonecreationfailed";
+CKKSZoneKeyState* const SecCKKSZoneKeyStateProcess = (CKKSZoneKeyState*) @"process";
NSDictionary<CKKSZoneKeyState*, NSNumber*>* CKKSZoneKeyStateMap(void) {
static NSDictionary<CKKSZoneKeyState*, NSNumber*>* map = nil;
#import "keychain/ckks/CKKSCondition.h"
#import "keychain/ckks/CloudKitDependencies.h"
+
NS_ASSUME_NONNULL_BEGIN
+// APS is giving us a tracingUUID and a tracingEnabled bool, but our interfaces take a CKRecordZoneNotification. Add them to that class, then.
+@interface CKRecordZoneNotification (CKKSPushTracing)
+@property (nonatomic, assign) BOOL ckksPushTracingEnabled;
+@property (nonatomic, strong, nullable) NSString* ckksPushTracingUUID;
+@property (nonatomic, strong, nullable) NSDate* ckksPushReceivedDate;
+@end
+
@protocol CKKSZoneUpdateReceiver <NSObject>
- (void)notifyZoneChange:(CKRecordZoneNotification* _Nullable)notification;
@end
#import <CloudKit/CloudKit_Private.h>
#include <utilities/debugging.h>
+@implementation CKRecordZoneNotification (CKKSPushTracing)
+- (void)setCkksPushTracingEnabled:(BOOL)ckksPushTracingEnabled {
+ objc_setAssociatedObject(self, "ckksPushTracingEnabled", ckksPushTracingEnabled ? @YES : @NO, OBJC_ASSOCIATION_RETAIN);
+}
+
+- (BOOL)ckksPushTracingEnabled {
+ return !![objc_getAssociatedObject(self, "ckksPushTracingEnabled") boolValue];
+}
+
+- (void)setCkksPushTracingUUID:(NSString*)ckksPushTracingUUID {
+ objc_setAssociatedObject(self, "ckksPushTracingUUID", ckksPushTracingUUID, OBJC_ASSOCIATION_RETAIN);
+}
+
+- (NSString*)ckksPushTracingUUID {
+ return objc_getAssociatedObject(self, "ckksPushTracingUUID");
+}
+
+- (void)setCkksPushReceivedDate:(NSDate*)ckksPushReceivedDate {
+ objc_setAssociatedObject(self, "ckksPushReceivedDate", ckksPushReceivedDate, OBJC_ASSOCIATION_RETAIN);
+}
+
+- (NSDate*)ckksPushReceivedDate {
+ return objc_getAssociatedObject(self, "ckksPushReceivedDate");
+}
+@end
+
+
@interface CKKSAPSReceiver()
// If we receive >0 notifications for a CKRecordZoneID that hasn't been registered yet, give them a fake update when they register
@property NSMutableSet<CKRecordZoneID*>* undeliveredUpdates;
- (void)connection:(APSConnection *)connection didReceiveIncomingMessage:(APSIncomingMessage *)message {
secnotice("ckkspush", "CKKSAPSDelegate received a message: %@ on connection %@", message, connection);
+ // Report back through APS that we received a message
+ if(message.tracingEnabled) {
+ [connection confirmReceiptForMessage:message];
+ }
+
CKNotification* notification = [CKNotification notificationFromRemoteNotificationDictionary:message.userInfo];
if(notification.notificationType == CKNotificationTypeRecordZone) {
CKRecordZoneNotification* rznotification = (CKRecordZoneNotification*) notification;
+ rznotification.ckksPushTracingEnabled = message.tracingEnabled;
+ rznotification.ckksPushTracingUUID = message.tracingUUID ? [[[NSUUID alloc] initWithUUIDBytes:message.tracingUUID.bytes] UUIDString] : nil;
+ rznotification.ckksPushReceivedDate = [NSDate date];
// Find receiever in map
id<CKKSZoneUpdateReceiver> recv = [self.zoneMap objectForKey:rznotification.recordZoneID];
} else {
secerror("ckks: received push for unregistered zone: %@", rznotification);
if(rznotification.recordZoneID) {
+ // TODO: save the rznofication itself
[self.undeliveredUpdates addObject: rznotification.recordZoneID];
}
}
#import "keychain/ckks/CKKS.h"
#import "keychain/ckks/CKKSViewManager.h"
#import "keychain/ckks/CKKSKeychainView.h"
-#import "Analytics/SFAnalytics.h"
#include <utilities/SecFileLocations.h>
#include <sys/stat.h>
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];
+ return [CKKSAnalytics defaultAnalyticsDatabasePath:@"ckks_analytics"];
}
+ (instancetype)logger
CKKSAccountStatusNoAccount = 3,
};
+@interface SOSAccountStatus : NSObject
+@property SOSCCStatus status;
+@property (nullable) NSError* error;
+- (instancetype)init:(SOSCCStatus)status error:error;
+@end
+
@protocol CKKSAccountStateListener <NSObject>
- (void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus;
@end
// If you use these, please be aware they could change out from under you at any time
@property (nullable) CKAccountInfo* currentCKAccountInfo;
-@property SOSCCStatus currentCircleStatus;
+@property (nullable) SOSAccountStatus* currentCircleStatus;
@property (readonly,atomic) CKKSAccountStatus currentComputedAccountStatus;
@property (nullable,readonly,atomic) NSError* currentAccountError;
- (dispatch_group_t _Nullable)checkForAllDeliveries;
-+ (SOSCCStatus)getCircleStatus;
++ (SOSAccountStatus*)getCircleStatus;
+ (void)fetchCirclePeerID:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))callback;
+ (NSString*)stringFromAccountStatus:(CKKSAccountStatus)status;
#import "keychain/ckks/CloudKitCategories.h"
#import "keychain/ckks/CKKSCKAccountStateTracker.h"
#import "keychain/ckks/CKKSAnalytics.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
@interface CKKSCKAccountStateTracker ()
@property (readonly) Class<CKKSNSNotificationCenter> nsnotificationCenterClass;
_nsnotificationCenterClass = nsnotificationCenterClass;
_changeListeners = [NSMapTable strongToWeakObjectsMapTable]; // Backwards from how we'd like, but it's the best way to have weak pointers to CKKSAccountStateListener.
_currentCKAccountInfo = nil;
- _currentCircleStatus = kSOSCCError;
+ _currentCircleStatus = [[SOSAccountStatus alloc] init:kSOSCCError error:nil];
_currentComputedAccountStatus = CKKSAccountStatusUnknown;
_currentComputedAccountStatusValid = [[CKKSCondition alloc] init];
selfString,
[self currentStatus],
self.currentCKAccountInfo,
- SOSCCGetStatusDescription(self.currentCircleStatus),
+ self.currentCircleStatus,
self.currentAccountError ?: @""];
}
-(dispatch_semaphore_t)notifyCircleChange:(__unused id)object {
dispatch_semaphore_t finishedSema = dispatch_semaphore_create(0);
- SOSCCStatus circleStatus = [CKKSCKAccountStateTracker getCircleStatus];
+ SOSAccountStatus* circleStatus = [CKKSCKAccountStateTracker getCircleStatus];
dispatch_sync(self.queue, ^{
self.firstSOSCircleFetch = true;
}
// Takes the new ckAccountInfo we're moving to
--(void)_onqueueUpdateCirclePeerID: (SOSCCStatus)sosccstatus {
+-(void)_onqueueUpdateCirclePeerID: (SOSAccountStatus*)sosstatus {
dispatch_assert_queue(self.queue);
__weak __typeof(self) weakSelf = self;
// If we're in a circle, fetch the peer id
- if(sosccstatus == kSOSCCInCircle) {
+ if(sosstatus.status == kSOSCCInCircle) {
[CKKSCKAccountStateTracker fetchCirclePeerID:^(NSString* peerID, NSError* error) {
__strong __typeof(self) strongSelf = weakSelf;
if(!strongSelf) {
dispatch_async(strongSelf.queue, ^{
__strong __typeof(self) innerstrongSelf = weakSelf;
- if(innerstrongSelf.currentCircleStatus == kSOSCCInCircle) {
+ if(innerstrongSelf.currentCircleStatus && innerstrongSelf.currentCircleStatus.status == kSOSCCInCircle) {
secnotice("ckksaccount", "Circle peerID is: %@ %@", peerID, error);
// Still in circle. Proceed.
innerstrongSelf.accountCirclePeerID = peerID;
}];
} else {
// Not in-circle, reset circle ID
- secnotice("ckksaccount", "out of circle(%d): resetting peer ID", sosccstatus);
+ secnotice("ckksaccount", "out of circle(%@): resetting peer ID", sosstatus);
self.accountCirclePeerID = nil;
self.accountCirclePeerIDError = nil;
self.accountCirclePeerIDInitialized = [[CKKSCondition alloc] init];
return false;
}
- if(self.currentCircleStatus != kSOSCCInCircle) {
+ if(self.currentCircleStatus.status != kSOSCCInCircle) {
if(error) {
*error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain
code:kSOSErrorNotInCircle
return true;
}
--(void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo circle:(SOSCCStatus)sosccstatus deliveredSemaphore:(dispatch_semaphore_t)finishedSema {
+-(void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo circle:(SOSAccountStatus*)sosstatus deliveredSemaphore:(dispatch_semaphore_t)finishedSema {
dispatch_assert_queue(self.queue);
- if([self.currentCKAccountInfo isEqual: ckAccountInfo] && self.currentCircleStatus == sosccstatus) {
+ if([self.currentCKAccountInfo isEqual: ckAccountInfo] && self.currentCircleStatus.status == sosstatus.status) {
// no-op.
- secinfo("ckksaccount", "received another notification of CK Account State %@ and Circle status %d", ckAccountInfo, (int)sosccstatus);
+ secinfo("ckksaccount", "received another notification of CK Account State %@ and Circle status %d", ckAccountInfo, (int)sosstatus);
dispatch_semaphore_signal(finishedSema);
return;
}
[self _onqueueUpdateCKDeviceID: ckAccountInfo];
}
- if(self.currentCircleStatus != sosccstatus) {
- secnotice("ckksaccount", "moving to circle status: %@", SOSCCGetStatusDescription(sosccstatus));
- self.currentCircleStatus = sosccstatus;
- if (sosccstatus == kSOSCCInCircle) {
+ if(self.currentCircleStatus.status != sosstatus.status) {
+ secnotice("ckksaccount", "moving to circle status: %@", sosstatus);
+ self.currentCircleStatus = sosstatus;
+ if (sosstatus.status == kSOSCCInCircle) {
[[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastInCircle];
}
- [self _onqueueUpdateCirclePeerID: sosccstatus];
+ [self _onqueueUpdateCirclePeerID: sosstatus];
}
if(!self.firstSOSCircleFetch || !self.firstCKAccountFetch) {
return;
}
+ if(self.currentCircleStatus.status == kSOSCCError &&
+ [self.currentCircleStatus.error.domain isEqualToString:(__bridge id)kSOSErrorDomain] &&
+ self.currentCircleStatus.error.code == kSOSErrorNotReady &&
+ self.currentComputedAccountStatus == CKKSAccountStatusUnknown) {
+ secnotice("ckksaccount", "Device not unlocked yet; can't determine account status. Not passing update along: %@", self);
+ dispatch_semaphore_signal(finishedSema);
+ return;
+ }
+
CKKSAccountStatus oldComputedStatus = self.currentComputedAccountStatus;
NSError* error = nil;
secnotice("ckksaccount", "No change in computed account status: %@ (%@ %@)",
[self currentStatus],
self.currentCKAccountInfo,
- SOSCCGetStatusDescription(self.currentCircleStatus));
+ self.currentCircleStatus);
dispatch_semaphore_signal(finishedSema);
return;
}
secnotice("ckksaccount", "New computed account status: %@ (%@ %@)",
[self currentStatus],
self.currentCKAccountInfo,
- SOSCCGetStatusDescription(self.currentCircleStatus));
+ self.currentCircleStatus);
[self _onqueueDeliverStateChanges:oldComputedStatus deliveredSemaphore:finishedSema];
}
}
// This is its own function to allow OCMock to swoop in and replace the result during testing.
-+(SOSCCStatus)getCircleStatus {
++ (SOSAccountStatus*)getCircleStatus {
CFErrorRef cferror = NULL;
SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror);
if(cferror) {
secerror("ckksaccount: error getting circle status: %@", cferror);
- CFReleaseNull(cferror);
- return kSOSCCError;
+ return [[SOSAccountStatus alloc] init:kSOSCCError error:CFBridgingRelease(cferror)];
}
- return status;
+
+ return [[SOSAccountStatus alloc] init:status error:nil];
}
-(NSString*)currentStatus {
@end
+@implementation SOSAccountStatus
+- (instancetype)init:(SOSCCStatus)status error:(NSError*)error
+{
+ if((self = [super init])) {
+ _status = status;
+ _error = error;
+ }
+ return self;
+}
+
+- (NSString*)description
+{
+ return [NSString stringWithFormat:@"<SOSStatus: %@ (%@)>", SOSCCGetStatusDescription(self.status), self.error];
+}
+@end
+
#endif // OCTAGON
- (void)rpcStatus:(NSString* _Nullable)viewName
reply:(void (^)(NSArray<NSDictionary*>* _Nullable result, NSError* _Nullable error))reply;
- (void)rpcResetLocal:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply;
-- (void)rpcResetCloudKit:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply;
+- (void)rpcResetCloudKit:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply __deprecated_msg("use rpcResetCloudKit:reason:reply:");
+- (void)rpcResetCloudKit:(NSString* _Nullable)viewName reason:(NSString *)reason reply:(void (^)(NSError* _Nullable error))reply;
- (void)rpcResync:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply;
- (void)rpcFetchAndProcessChanges:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply;
- (void)rpcFetchAndProcessClassAChanges:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply;
- (void)rpcResetCloudKit:(NSString*)viewName reply:(void(^)(NSError* error))reply {
[[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) {
reply(error);
- }] rpcResetCloudKit:viewName reply:^(NSError* error){
+ }] rpcResetCloudKit:viewName reason:[NSString stringWithFormat:@"%s", getprogname()] reply:^(NSError* error){
reply(error);
}];
}
+- (void)rpcResetCloudKit:(NSString*)viewName reason:(NSString *)reason reply:(void(^)(NSError* error))reply {
+ [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) {
+ reply(error);
+ }] rpcResetCloudKit:viewName reason:reason reply:^(NSError* error){
+ reply(error);
+ }];
+}
+
+
- (void)rpcResync:(NSString*)viewName reply:(void(^)(NSError* error))reply {
[[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) {
reply(error);
@protocol CKKSControlProtocol <NSObject>
- (void)performanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply;
- (void)rpcResetLocal: (NSString*)viewName reply: (void(^)(NSError* result)) reply;
-- (void)rpcResetCloudKit: (NSString*)viewName reply: (void(^)(NSError* result)) reply;
+- (void)rpcResetCloudKit: (NSString*)viewName reply: (void(^)(NSError* result)) reply __deprecated_msg("use rpcResetCloudKit:reason:reply");
+
+/**
+ * Reset CloudKit zone with a caller provided reason, the reason will be logged in the operation group
+ * name so that the reason for reset can be summarized server side.
+ */
+- (void)rpcResetCloudKit: (NSString*)viewName reason:(NSString *)reason reply: (void(^)(NSError* result)) reply;
- (void)rpcResync:(NSString*)viewName reply: (void(^)(NSError* result)) reply;
- (void)rpcResyncLocal:(NSString*)viewName reply:(void(^)(NSError* result))reply;
- (void)rpcStatus:(NSString*)viewName reply: (void(^)(NSArray<NSDictionary*>* result, NSError* error)) reply;
@try {
[interface setClasses:errClasses forSelector:@selector(rpcResetLocal:reply:) argumentIndex:0 ofReply:YES];
[interface setClasses:errClasses forSelector:@selector(rpcResetCloudKit:reply:) argumentIndex:0 ofReply:YES];
+ [interface setClasses:errClasses forSelector:@selector(rpcResetCloudKit:reason:reply:) argumentIndex:0 ofReply:YES];
[interface setClasses:errClasses forSelector:@selector(rpcResync:reply:) argumentIndex:0 ofReply:YES];
[interface setClasses:errClasses forSelector:@selector(rpcStatus:reply:) argumentIndex:0 ofReply:YES];
[interface setClasses:errClasses forSelector:@selector(rpcStatus:reply:) argumentIndex:1 ofReply:YES];
#if OCTAGON
@class CKKSKeychainView;
#import "keychain/ckks/CKKSGroupOperation.h"
-#import "keychain/ckks/CKKSZoneChangeFetcher.h"
+#import "keychain/ckks/CloudKitDependencies.h"
NS_ASSUME_NONNULL_BEGIN
+/* Fetch Reasons */
+@protocol CKKSFetchBecauseProtocol <NSObject>
+@end
+typedef NSString<CKKSFetchBecauseProtocol> CKKSFetchBecause;
+extern CKKSFetchBecause* const CKKSFetchBecauseAPNS;
+extern CKKSFetchBecause* const CKKSFetchBecauseAPIFetchRequest;
+extern CKKSFetchBecause* const CKKSFetchBecauseCurrentItemFetchRequest;
+extern CKKSFetchBecause* const CKKSFetchBecauseInitialStart;
+extern CKKSFetchBecause* const CKKSFetchBecauseSecuritydRestart;
+extern CKKSFetchBecause* const CKKSFetchBecausePreviousFetchFailed;
+extern CKKSFetchBecause* const CKKSFetchBecauseKeyHierarchy;
+extern CKKSFetchBecause* const CKKSFetchBecauseTesting;
+extern CKKSFetchBecause* const CKKSFetchBecauseResync;
+
+/* Clients that register to use fetches */
+@interface CKKSCloudKitFetchRequest : NSObject
+@property bool participateInFetch;
+@property (nullable) CKServerChangeToken* changeToken;
+@end
+
+@class CKKSCloudKitDeletion;
+@protocol CKKSChangeFetcherClient <NSObject>
+- (CKRecordZoneID*)zoneID;
+- (CKKSCloudKitFetchRequest*)participateInFetch;
+- (bool)notifyFetchError:(NSError*)error;
+- (void)changesFetched:(NSArray<CKRecord*>*)changedRecords
+ deletedRecordIDs:(NSArray<CKKSCloudKitDeletion*>*)deleted
+ oldChangeToken:(CKServerChangeToken* _Nullable)oldChangeToken
+ newChangeToken:(CKServerChangeToken*)changeToken;
+@end
+
+// I don't understand why recordType isn't part of record ID, but deletions come in as both things
+@interface CKKSCloudKitDeletion : NSObject
+@property CKRecordID* recordID;
+@property NSString* recordType;
+- (instancetype)initWithRecordID:(CKRecordID*)recordID recordType:(NSString*)recordType;
+@end
+
+
@interface CKKSFetchAllRecordZoneChangesOperation : CKKSGroupOperation
+@property (readonly) Class<CKKSFetchRecordZoneChangesOperation> fetchRecordZoneChangesOperationClass;
+@property (readonly) CKContainer* container;
// Set this to true before starting this operation if you'd like resync behavior:
// Fetching everything currently in CloudKit and comparing to local copy
@property bool resync;
-@property (nullable, weak) CKKSKeychainView* ckks;
-@property CKRecordZoneID* zoneID;
+@property NSDictionary<CKRecordZoneID*, id<CKKSChangeFetcherClient>>* clientMap;
+@property (nullable) NSMutableArray<CKRecordZoneID*>* fetchedZoneIDs;
@property NSSet<CKKSFetchBecause*>* fetchReasons;
+@property NSSet<CKRecordZoneNotification*>* apnsPushes;
@property NSMutableDictionary<CKRecordID*, CKRecord*>* modifications;
-@property NSMutableDictionary<CKRecordID*, NSString*>* deletions;
-
-@property (nullable) CKServerChangeToken* serverChangeToken;
+@property NSMutableDictionary<CKRecordID*, CKKSCloudKitDeletion*>* deletions;
+@property NSMutableDictionary<CKRecordID*, CKServerChangeToken*>* changeTokens;
- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks
- fetchReasons:(NSSet<CKKSFetchBecause*>*)fetchReasons
- ckoperationGroup:(CKOperationGroup*)ckoperationGroup;
+- (instancetype)initWithContainer:(CKContainer*)container
+ fetchClass:(Class<CKKSFetchRecordZoneChangesOperation>)fetchRecordZoneChangesOperationClass
+ clients:(NSArray<id<CKKSChangeFetcherClient>>*)clients
+ fetchReasons:(NSSet<CKKSFetchBecause*>*)fetchReasons
+ apnsPushes:(NSSet<CKRecordZoneNotification*>* _Nullable)apnsPushes
+ forceResync:(bool)forceResync
+ ckoperationGroup:(CKOperationGroup*)ckoperationGroup;
@end
#if OCTAGON
+#import <CloudKit/CloudKit.h>
+#import <CloudKit/CloudKit_Private.h>
+
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import "keychain/ckks/CloudKitDependencies.h"
+#import "keychain/ckks/CloudKitCategories.h"
#import "keychain/ckks/CKKS.h"
#import "keychain/ckks/CKKSKeychainView.h"
#import "keychain/ckks/CKKSZoneStateEntry.h"
#import "keychain/ckks/CKKSMirrorEntry.h"
#import "keychain/ckks/CKKSManifest.h"
#import "keychain/ckks/CKKSManifestLeafRecord.h"
+#import "NSError+UsefulConstructors.h"
#import "CKKSPowerCollection.h"
#include <securityd/SecItemServer.h>
+@implementation CKKSCloudKitFetchRequest
+@end
+
+@implementation CKKSCloudKitDeletion
+- (instancetype)initWithRecordID:(CKRecordID*)recordID recordType:(NSString*)recordType
+{
+ if((self = [super init])) {
+ _recordID = recordID;
+ _recordType = recordType;
+ }
+ return self;
+}
+@end
+
@interface CKKSFetchAllRecordZoneChangesOperation()
@property CKDatabaseOperation<CKKSFetchRecordZoneChangesOperation>* fetchRecordZoneChangesOperation;
+@property NSMutableDictionary<CKRecordZoneID*, CKFetchRecordZoneChangesConfiguration*>* allClientOptions;
+
@property CKOperationGroup* ckoperationGroup;
@property (assign) NSUInteger fetchedItems;
+@property bool forceResync;
@end
@implementation CKKSFetchAllRecordZoneChangesOperation
return nil;
}
-- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks
- fetchReasons:(NSSet<CKKSFetchBecause*>*)fetchReasons
- ckoperationGroup:(CKOperationGroup*)ckoperationGroup {
-
+- (instancetype)initWithContainer:(CKContainer*)container
+ fetchClass:(Class<CKKSFetchRecordZoneChangesOperation>)fetchRecordZoneChangesOperationClass
+ clients:(NSArray<id<CKKSChangeFetcherClient>>*)clients
+ fetchReasons:(NSSet<CKKSFetchBecause*>*)fetchReasons
+ apnsPushes:(NSSet<CKRecordZoneNotification*>*)apnsPushes
+ forceResync:(bool)forceResync
+ ckoperationGroup:(CKOperationGroup*)ckoperationGroup
+{
if(self = [super init]) {
- _ckks = ckks;
+ _container = container;
+ _fetchRecordZoneChangesOperationClass = fetchRecordZoneChangesOperationClass;
+
+ NSMutableDictionary* clientMap = [NSMutableDictionary dictionary];
+ for(id<CKKSChangeFetcherClient> client in clients) {
+ clientMap[client.zoneID] = client;
+ }
+ _clientMap = [clientMap copy];
+
_ckoperationGroup = ckoperationGroup;
+ _forceResync = forceResync;
_fetchReasons = fetchReasons;
- _zoneID = ckks.zoneID;
-
- _resync = false;
+ _apnsPushes = apnsPushes;
_modifications = [[NSMutableDictionary alloc] init];
_deletions = [[NSMutableDictionary alloc] init];
-
- // Can't fetch unless the zone is created.
- [self addNullableDependency:ckks.zoneSetupOperation];
}
return self;
}
-- (void)_onqueueRecordsChanged:(NSArray*)records
-{
- for (CKRecord* record in records) {
- [self.ckks _onqueueCKRecordChanged:record resync:self.resync];
- }
-}
-
-- (void)_updateLatestTrustedManifest
-{
- CKKSKeychainView* ckks = self.ckks;
- NSError* error = nil;
- NSArray* pendingManifests = [CKKSPendingManifest all:&error];
- NSUInteger greatestKnownManifestGeneration = [CKKSManifest greatestKnownGenerationCount];
- for (CKKSPendingManifest* manifest in pendingManifests) {
- if (manifest.generationCount >= greatestKnownManifestGeneration) {
- [manifest commitToDatabaseWithError:&error];
- }
- else {
- // if this is an older generation, just get rid of it
- [manifest deleteFromDatabase:&error];
- }
- }
-
- if (![ckks _onqueueUpdateLatestManifestWithError:&error]) {
- self.error = error;
- ckkserror("ckksfetch", ckks, "failed to get latest manifest");
- }
-}
-
-- (void)_onqueueProcessRecordDeletions
-{
- CKKSKeychainView* ckks = self.ckks;
- [self.deletions enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, NSString * _Nonnull recordType, BOOL * _Nonnull stop) {
- ckksinfo("ckksfetch", ckks, "Processing record deletion(%@): %@", recordType, recordID);
-
- // <rdar://problem/32475600> CKKS: Check Current Item pointers in the Manifest
- // TODO: check that these deletions match a manifest upload
- // Delegate these back up into the CKKS object for processing
- [ckks _onqueueCKRecordDeleted:recordID recordType:recordType resync:self.resync];
- }];
-}
-
-- (void)_onqueueScanForExtraneousLocalItems
-{
- // TODO: must scan through all CKMirrorEntries and determine if any exist that CloudKit didn't tell us about
- CKKSKeychainView* ckks = self.ckks;
- NSError* error = nil;
- if(self.resync) {
- ckksnotice("ckksresync", ckks, "Comparing local UUIDs against the CloudKit list");
- NSMutableArray<NSString*>* uuids = [[CKKSMirrorEntry allUUIDs:ckks.zoneID error:&error] mutableCopy];
-
- for(NSString* uuid in uuids) {
- if([self.modifications objectForKey: [[CKRecordID alloc] initWithRecordName: uuid zoneID: ckks.zoneID]]) {
- ckksnotice("ckksresync", ckks, "UUID %@ is still in CloudKit; carry on.", uuid);
- } else {
- CKKSMirrorEntry* ckme = [CKKSMirrorEntry tryFromDatabase:uuid zoneID:ckks.zoneID error: &error];
- if(error != nil) {
- ckkserror("ckksresync", ckks, "Couldn't read an item from the database, but it used to be there: %@ %@", uuid, error);
- self.error = error;
- continue;
- }
- if(!ckme) {
- ckkserror("ckksresync", ckks, "Couldn't read ckme(%@) from database; continuing", uuid);
- continue;
- }
-
- ckkserror("ckksresync", ckks, "BUG: Local item %@ not found in CloudKit, deleting", uuid);
- [ckks _onqueueCKRecordDeleted:ckme.item.storedCKRecord.recordID recordType:ckme.item.storedCKRecord.recordType resync:self.resync];
- }
- }
- }
-}
-
- (void)groupStart {
__weak __typeof(self) weakSelf = self;
- CKKSKeychainView* ckks = self.ckks;
- if(!ckks) {
- ckkserror("ckksresync", ckks, "no CKKS object");
- return;
- }
+ // Ask all our clients for their change tags
+ self.allClientOptions = [NSMutableDictionary dictionary];
+ self.fetchedZoneIDs = [NSMutableArray array];
- [ckks dispatchSync: ^bool{
- ckks.lastRecordZoneChangesOperation = self;
+ // Unused until [<rdar://problem/38725728> Changes to discretionary-ness (explicit or derived from QoS) should be "live"] has happened and we can determine network
+ // discretionaryness.
+ //bool nilChangeTag = false;
- NSError* error = nil;
- NSQualityOfService qos = NSQualityOfServiceUtility;
+ for(CKRecordZoneID* clientZoneID in self.clientMap) {
+ id<CKKSChangeFetcherClient> client = self.clientMap[clientZoneID];
- CKFetchRecordZoneChangesOptions* options = [[CKFetchRecordZoneChangesOptions alloc] init];
- if(self.resync) {
- ckksnotice("ckksresync", ckks, "Beginning resync fetch!");
+ CKKSCloudKitFetchRequest* clientPreference = [client participateInFetch];
+ if(clientPreference.participateInFetch) {
+ [self.fetchedZoneIDs addObject:client.zoneID];
- options.previousServerChangeToken = nil;
+ CKFetchRecordZoneChangesConfiguration* options = [[CKFetchRecordZoneChangesConfiguration alloc] init];
- // currently, resyncs are user initiated (or the key hierarchy is upset, which is implicitly user initiated)
- qos = NSQualityOfServiceUserInitiated;
- } else {
- // This is the normal case: fetch only the delta since the last fetch
- CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: ckks.zoneName];
- if(error || !ckse) {
- ckkserror("ckksfetch", ckks, "couldn't fetch zone status for %@: %@", ckks.zoneName, error);
- self.error = error;
- return false;
+ if(!self.forceResync) {
+ options.previousServerChangeToken = clientPreference.changeToken;
}
- // If this is the first sync, or an API fetch, use QoS userInitated
- if(ckse.changeToken == nil || [self.fetchReasons containsObject:CKKSFetchBecauseAPIFetchRequest]) {
- qos = NSQualityOfServiceUserInitiated;
- }
+ //if(options.previousServerChangeToken == nil) {
+ // nilChangeTag = true;
+ //}
- options.previousServerChangeToken = ckse.changeToken;
+ self.allClientOptions[client.zoneID] = options;
}
+ }
- 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;
- self.fetchRecordZoneChangesOperation.qualityOfService = qos;
- self.fetchRecordZoneChangesOperation.group = self.ckoperationGroup;
- ckksnotice("ckksfetch", ckks, "Operation group is %@", self.ckoperationGroup);
+ if(self.fetchedZoneIDs.count == 0) {
+ // No clients actually want to fetch right now, so quit
+ self.error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSNoFetchesRequested description:@"No clients want a fetch right now"];
+ secnotice("ckksfetch", "Cancelling fetch: %@", self.error);
+ return;
+ }
- self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) {
- __strong __typeof(weakSelf) strongSelf = weakSelf;
- __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks;
- if(!strongSelf) {
- ckkserror("ckksfetch", strongCKKS, "received callback for released object");
- return;
- }
+ // Compute the network discretionary approach this fetch will take.
+ // For now, everything is nondiscretionary, because we can't afford to block a nondiscretionary request later.
+ // Once [<rdar://problem/38725728> Changes to discretionary-ness (explicit or derived from QoS) should be "live"] happens, we can come back through and make things
+ // discretionary, but boost them later.
+ //
+ // Rules:
+ // If there's a nil change tag, go to nondiscretionary. This is likely a zone bringup (which happens during iCloud sign-in) or a resync (which happens due to user input)
+ // If the fetch reasons include an API fetch, an initial start or a key hierarchy fetch, become nondiscretionary as well.
+
+ CKOperationDiscretionaryNetworkBehavior networkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+ //if(nilChangeTag ||
+ // [self.fetchReasons containsObject:CKKSFetchBecauseAPIFetchRequest] ||
+ // [self.fetchReasons containsObject:CKKSFetchBecauseInitialStart] ||
+ // [self.fetchReasons containsObject:CKKSFetchBecauseKeyHierarchy]) {
+ // networkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+ //}
+
+ secnotice("ckks", "Beginning fetch with discretionary network (%d): %@", (int)networkBehavior, self.allClientOptions);
+ self.fetchRecordZoneChangesOperation = [[self.fetchRecordZoneChangesOperationClass alloc] initWithRecordZoneIDs:self.fetchedZoneIDs
+ configurationsByRecordZoneID:self.allClientOptions];
+
+ self.fetchRecordZoneChangesOperation.fetchAllChanges = YES;
+ self.fetchRecordZoneChangesOperation.configuration.discretionaryNetworkBehavior = networkBehavior;
+ self.fetchRecordZoneChangesOperation.group = self.ckoperationGroup;
+ secnotice("ckksfetch", "Operation group is %@", self.ckoperationGroup);
+
+ self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) {
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
+ secinfo("ckksfetch", "CloudKit notification: record changed(%@): %@", [record recordType], record);
+
+ // Add this to the modifications, and remove it from the deletions
+ strongSelf.modifications[record.recordID] = record;
+ [strongSelf.deletions removeObjectForKey:record.recordID];
+ strongSelf.fetchedItems++;
+ };
+
+ self.fetchRecordZoneChangesOperation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID, NSString *recordType) {
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
+ secinfo("ckksfetch", "CloudKit notification: deleted record(%@): %@", recordType, recordID);
+
+ // Add to the deletions, and remove any pending modifications
+ [strongSelf.modifications removeObjectForKey: recordID];
+ strongSelf.deletions[recordID] = [[CKKSCloudKitDeletion alloc] initWithRecordID:recordID recordType:recordType];
+ strongSelf.fetchedItems++;
+ };
+
+ self.fetchRecordZoneChangesOperation.recordZoneChangeTokensUpdatedBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData) {
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
+
+ secinfo("ckksfetch", "Received a new server change token for %@: %@ %@", recordZoneID, serverChangeToken, clientChangeTokenData);
+ strongSelf.changeTokens[recordZoneID] = serverChangeToken;
+ };
+
+ self.fetchRecordZoneChangesOperation.recordZoneFetchCompletionBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData, BOOL moreComing, NSError * recordZoneError) {
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
+ if(!strongSelf) {
+ secerror("ckksfetch: received callback for released object");
+ return;
+ }
- ckksinfo("ckksfetch", strongCKKS, "CloudKit notification: record changed(%@): %@", [record recordType], record);
+ id<CKKSChangeFetcherClient> client = strongSelf.clientMap[recordZoneID];
+ if(!client) {
+ secerror("ckksfetch: no client registered for %@, so why did we get any data?", recordZoneID);
+ return;
+ }
- // Add this to the modifications, and remove it from the deletions
- [strongSelf.modifications setObject: record forKey: record.recordID];
- [strongSelf.deletions removeObjectForKey: record.recordID];
- strongSelf.fetchedItems++;
- };
+ // First, filter the modifications and deletions for this zone
+ NSMutableArray<CKRecord*>* zoneModifications = [NSMutableArray array];
+ NSMutableArray<CKKSCloudKitDeletion*>* zoneDeletions = [NSMutableArray array];
- self.fetchRecordZoneChangesOperation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID, NSString *recordType) {
- __strong __typeof(weakSelf) strongSelf = weakSelf;
- __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks;
- if(!strongSelf) {
- ckkserror("ckksfetch", strongCKKS, "received callback for released object");
- return;
+ [strongSelf.modifications enumerateKeysAndObjectsUsingBlock:^(CKRecordID* _Nonnull recordID,
+ CKRecord* _Nonnull record,
+ BOOL* stop) {
+ if([recordID.zoneID isEqual:recordZoneID]) {
+ ckksinfo("ckksfetch", recordZoneID, "Sorting record modification %@: %@", recordID, record);
+ [zoneModifications addObject:record];
}
-
- ckksinfo("ckksfetch", strongCKKS, "CloudKit notification: deleted record(%@): %@", recordType, recordID);
-
- // Add to the deletions, and remove any pending modifications
- [strongSelf.modifications removeObjectForKey: recordID];
- [strongSelf.deletions setObject: recordType forKey: recordID];
- strongSelf.fetchedItems++;
- };
-
- // This class only supports fetching from a single zone, so we can ignore recordZoneID
- self.fetchRecordZoneChangesOperation.recordZoneChangeTokensUpdatedBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData) {
- __strong __typeof(weakSelf) strongSelf = weakSelf;
- __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks;
- if(!strongSelf) {
- ckkserror("ckksfetch", strongCKKS, "received callback for released object");
- return;
+ }];
+
+ [strongSelf.deletions enumerateKeysAndObjectsUsingBlock:^(CKRecordID* _Nonnull recordID,
+ CKKSCloudKitDeletion* _Nonnull deletion,
+ BOOL* _Nonnull stop) {
+ if([recordID.zoneID isEqual:recordZoneID]) {
+ ckksinfo("ckksfetch", recordZoneID, "Sorting record deletion %@: %@", recordID, deletion);
+ [zoneDeletions addObject:deletion];
}
+ }];
+
+ ckksnotice("ckksfetch", recordZoneID, "Record zone fetch complete: changeToken=%@ clientChangeTokenData=%@ changed=%lu deleted=%lu error=%@", serverChangeToken, clientChangeTokenData,
+ (unsigned long)zoneModifications.count,
+ (unsigned long)zoneDeletions.count,
+ recordZoneError);
+
+ if(recordZoneError == nil) {
+ // Tell the client about these changes!
+ [client changesFetched:zoneModifications
+ deletedRecordIDs:zoneDeletions
+ oldChangeToken:strongSelf.allClientOptions[recordZoneID].previousServerChangeToken
+ newChangeToken:serverChangeToken];
+ ckksnotice("ckksfetch", recordZoneID, "Finished processing fetch");
+ }
+ };
+
+ // Completion blocks don't count for dependencies. Use this intermediate operation hack instead.
+ CKKSResultOperation* recordZoneChangesCompletedOperation = [CKKSResultOperation named:@"record-zone-changes-completed" withBlock:^{}];
+
+ // Called with overall operation success. As I understand it, this block will be called for every operation.
+ // In the case of, e.g., network failure, the recordZoneFetchCompletionBlock will not be called, but this one will.
+ self.fetchRecordZoneChangesOperation.fetchRecordZoneChangesCompletionBlock = ^(NSError * _Nullable operationError) {
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
+ if(!strongSelf) {
+ secerror("ckksfetch: received callback for released object");
+ return;
+ }
- ckksinfo("ckksfetch", strongCKKS, "Received a new server change token: %@ %@", serverChangeToken, clientChangeTokenData);
- strongSelf.serverChangeToken = serverChangeToken;
- };
-
- // Completion blocks don't count for dependencies. Use this intermediate operation hack instead.
- NSBlockOperation* recordZoneChangesCompletedOperation = [[NSBlockOperation alloc] init];
- recordZoneChangesCompletedOperation.name = @"record-zone-changes-completed";
+ secnotice("ckksfetch", "Record zone changes fetch complete: error=%@", operationError);
+ if(operationError) {
+ strongSelf.error = operationError;
+ }
- self.fetchRecordZoneChangesOperation.recordZoneFetchCompletionBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData, BOOL moreComing, NSError * recordZoneError) {
- __strong __typeof(weakSelf) strongSelf = weakSelf;
- __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks;
+ [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventFetchAllChanges
+ count:strongSelf.fetchedItems];
- if(!strongSelf) {
- ckkserror("ckksfetch", blockCKKS, "received callback for released object");
- return;
- }
+ // Count record changes per zone
+ NSMutableDictionary<CKRecordZoneID*,NSNumber*>* recordChangesPerZone = [NSMutableDictionary dictionary];
+ NSNumber* totalModifications = [NSNumber numberWithUnsignedLong:strongSelf.modifications.count];
+ NSNumber* totalDeletions = [NSNumber numberWithUnsignedLong:strongSelf.deletions.count];
- if(!blockCKKS) {
- ckkserror("ckksfetch", blockCKKS, "no CKKS object");
- return;
- }
-
- ckksnotice("ckksfetch", blockCKKS, "Record zone fetch complete: changeToken=%@ clientChangeTokenData=%@ changed=%lu deleted=%lu error=%@", serverChangeToken, clientChangeTokenData,
- (unsigned long)strongSelf.modifications.count,
- (unsigned long)strongSelf.deletions.count,
- recordZoneError);
+ for(CKRecordID* recordID in strongSelf.modifications) {
+ NSNumber* last = recordChangesPerZone[recordID.zoneID];
+ recordChangesPerZone[recordID.zoneID] = [NSNumber numberWithUnsignedLong:1+(last ? [last unsignedLongValue] : 0)];
+ }
+ for(CKRecordID* recordID in strongSelf.deletions) {
+ NSNumber* last = recordChangesPerZone[recordID.zoneID];
+ recordChangesPerZone[recordID.zoneID] = [NSNumber numberWithUnsignedLong:1+(last ? [last unsignedLongValue] : 0)];
+ }
- // Completion! Mark these down.
- if(recordZoneError) {
- strongSelf.error = recordZoneError;
- }
- strongSelf.serverChangeToken = serverChangeToken;
-
- if(recordZoneError != nil) {
- // An error occurred. All our fetches are useless. Skip to the end.
- } else {
- // Commit these changes!
- __block NSError* error = nil;
-
- NSMutableDictionary<NSString*, NSMutableArray*>* changedRecordsDict = [[NSMutableDictionary alloc] init];
-
- [blockCKKS dispatchSyncWithAccountKeys:^bool{
- // let's process records in a specific order by type
- // 1. Manifest leaf records, without which the manifest master records are meaningless
- // 2. Manifest master records, which will be used to validate incoming items
- // 3. Intermediate key records
- // 4. Current key records
- // 5. Item records
-
- [strongSelf.modifications enumerateKeysAndObjectsUsingBlock:^(CKRecordID* _Nonnull recordID, CKRecord* _Nonnull record, BOOL* stop) {
- ckksinfo("ckksfetch", blockCKKS, "Sorting record modification %@: %@", recordID, record);
- NSMutableArray* changedRecordsByType = changedRecordsDict[record.recordType];
- if(!changedRecordsByType) {
- changedRecordsByType = [[NSMutableArray alloc] init];
- changedRecordsDict[record.recordType] = changedRecordsByType;
- };
-
- [changedRecordsByType addObject:record];
- }];
-
- if ([CKKSManifest shouldSyncManifests]) {
- if (!strongSelf.resync) {
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordManifestLeafType]];
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordManifestType]];
- }
-
- [strongSelf _updateLatestTrustedManifest];
- }
+ for(CKRecordZoneNotification* rz in strongSelf.apnsPushes) {
+ if(rz.ckksPushTracingEnabled) {
+ secnotice("ckksfetch", "Submitting post-fetch CKEventMetric due to notification %@", rz);
+
+ // Schedule submitting this metric on another operation, so hopefully CK will have marked this fetch as done by the time that fires?
+ CKEventMetric *metric = [[CKEventMetric alloc] initWithEventName:@"APNSPushMetrics"];
+ metric.isPushTriggerFired = true;
+ metric[@"push_token_uuid"] = rz.ckksPushTracingUUID;
+ metric[@"push_received_date"] = rz.ckksPushReceivedDate;
+ metric[@"push_event_name"] = @"CKKS Push";
+
+ metric[@"fetch_error"] = operationError ? @1 : @0;
+ metric[@"fetch_error_domain"] = operationError.domain;
+ metric[@"fetch_error_code"] = [NSNumber numberWithLong:operationError.code];
+
+ metric[@"total_modifications"] = totalModifications;
+ metric[@"total_deletions"] = totalDeletions;
+ for(CKRecordZoneID* zoneID in recordChangesPerZone) {
+ metric[zoneID.zoneName] = recordChangesPerZone[zoneID];
+ }
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordIntermediateKeyType]];
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordCurrentKeyType]];
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordItemType]];
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordCurrentItemType]];
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordDeviceStateType]];
- [strongSelf _onqueueRecordsChanged:changedRecordsDict[SecCKRecordTLKShareType]];
-
- [strongSelf _onqueueProcessRecordDeletions];
- [strongSelf _onqueueScanForExtraneousLocalItems];
-
- CKKSZoneStateEntry* state = [CKKSZoneStateEntry state: blockCKKS.zoneName];
- state.lastFetchTime = [NSDate date]; // The last fetch happened right now!
- if(strongSelf.serverChangeToken) {
- ckksdebug("ckksfetch", blockCKKS, "Zone change fetch complete: saving new server change token: %@", strongSelf.serverChangeToken);
- state.changeToken = strongSelf.serverChangeToken;
- }
- [state saveToDatabase:&error];
- if(error) {
- ckkserror("ckksfetch", blockCKKS, "Couldn't save new server change token: %@", error);
- strongSelf.error = error;
- }
+ // Okay, we now have this metric. But, it's unclear if calling associateWithCompletedOperation in this block will work. So, do something silly with operation scheduling.
+ // Grab pointers to these things
+ CKContainer* container = strongSelf.container;
+ CKDatabaseOperation<CKKSFetchRecordZoneChangesOperation>* rzcOperation = strongSelf.fetchRecordZoneChangesOperation;
- if(error) {
- ckkserror("ckksfetch", blockCKKS, "horrible error occurred: %@", error);
- strongSelf.error = error;
- return false;
+ CKKSResultOperation* launchMetricOp = [CKKSResultOperation named:@"submit-metric" withBlock:^{
+ if(![metric associateWithCompletedOperation:rzcOperation]) {
+ secerror("ckksfetch: Couldn't associate metric with operation: %@ %@", metric, rzcOperation);
}
-
- ckksnotice("ckksfetch", blockCKKS, "Finished processing fetch for %@", recordZoneID);
-
- return true;
+ [container submitEventMetric:metric];
+ secnotice("ckksfetch", "Metric submitted: %@", metric);
}];
- }
- };
-
- // Called with overall operation success. As I understand it, this block will be called for every operation.
- // In the case of, e.g., network failure, the recordZoneFetchCompletionBlock will not be called, but this one will.
- self.fetchRecordZoneChangesOperation.fetchRecordZoneChangesCompletionBlock = ^(NSError * _Nullable operationError) {
- __strong __typeof(weakSelf) strongSelf = weakSelf;
- __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks;
- if(!strongSelf) {
- ckkserror("ckksfetch", strongCKKS, "received callback for released object");
- return;
- }
+ [launchMetricOp addSuccessDependency:recordZoneChangesCompletedOperation];
- ckksnotice("ckksfetch", strongCKKS, "Record zone changes fetch complete: error=%@", operationError);
- if(operationError) {
- strongSelf.error = operationError;
+ [strongSelf.operationQueue addOperation:launchMetricOp];
}
+ }
- [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventFetchAllChanges zone:ckks.zoneName count:strongSelf.fetchedItems];
+ // Don't need these any more; save some memory
+ [strongSelf.modifications removeAllObjects];
+ [strongSelf.deletions removeAllObjects];
+ // Trigger the fake 'we're done' operation.
+ [strongSelf runBeforeGroupFinished: recordZoneChangesCompletedOperation];
+ };
- // Trigger the fake 'we're done' operation.
- [strongSelf runBeforeGroupFinished: recordZoneChangesCompletedOperation];
- };
+ [self dependOnBeforeGroupFinished:recordZoneChangesCompletedOperation];
+ [self dependOnBeforeGroupFinished:self.fetchRecordZoneChangesOperation];
- [self dependOnBeforeGroupFinished: recordZoneChangesCompletedOperation];
- [self dependOnBeforeGroupFinished: self.fetchRecordZoneChangesOperation];
- [ckks.database addOperation: self.fetchRecordZoneChangesOperation];
- return true;
- }];
+ [self.container.privateCloudDatabase addOperation:self.fetchRecordZoneChangesOperation];
}
- (void)cancel {
#import "keychain/ckks/CloudKitCategories.h"
#import "keychain/ckks/CKKSCurrentItemPointer.h"
#import "keychain/ckks/CKKSZoneStateEntry.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
@implementation CKKSFixups
+(CKKSGroupOperation*)fixup:(CKKSFixup)lastfixup for:(CKKSKeychainView*)keychainView
#import "CKKSGroupOperation.h"
#import "CKKSAnalytics.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#if OCTAGON
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.qualityOfService = NSQualityOfServiceUserInitiated; // This needs to happen for CKKS to be usable by PCS/cloudd. Make it happen.
+
+ // This needs to happen for CKKS to be usable by PCS/cloudd. Make it happen.
+ modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO;
+ modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+
modifyRecordsOp.group = self.ckoperationGroup;
ckksnotice("ckksheal", ckks, "Operation group is %@", self.ckoperationGroup);
return false;
} else {
// Everything is groovy. HOWEVER, we might still not have processed the keys. Ask for that!
- [strongCKKS _onqueueKeyStateMachineRequestProcess];
- [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateReady withError: nil];
+ [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateProcess withError: nil];
}
} else {
// ERROR. This isn't a total-failure error state, but one that should kick off a healing process.
#if OCTAGON
+#import <CloudKit/CloudKit.h>
+#import <CloudKit/CloudKit_Private.h>
+
#import "keychain/ckks/CKKSKeychainView.h"
#import "keychain/ckks/CKKSCurrentKeyPointer.h"
#import "keychain/ckks/CKKSKey.h"
recordIDsToDelete:recordIDsToDelete];
modifyRecordsOp.atomic = YES;
modifyRecordsOp.longLived = NO;
- modifyRecordsOp.qualityOfService = NSQualityOfServiceUserInitiated; // very important: get the TLKShares off-device ASAP
+
+ // very important: get the TLKShares off-device ASAP
+ modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO;
+ modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+
modifyRecordsOp.group = self.ckoperationGroup;
ckksnotice("ckksshare", ckks, "Operation group is %@", self.ckoperationGroup);
NSError* error = nil;
for(CKKSCurrentItemPointer* p in queueEntries) {
- if ([CKKSManifest shouldSyncManifests]) {
- if (![manifest validateCurrentItem:p withError:&error]) {
- ckkserror("ckksincoming", ckks, "Unable to validate current item pointer (%@) against manifest (%@)", p, manifest);
- if ([CKKSManifest shouldEnforceManifests]) {
- return false;
+ @autoreleasepool {
+ if ([CKKSManifest shouldSyncManifests]) {
+ if (![manifest validateCurrentItem:p withError:&error]) {
+ ckkserror("ckksincoming", ckks, "Unable to validate current item pointer (%@) against manifest (%@)", p, manifest);
+ if ([CKKSManifest shouldEnforceManifests]) {
+ return false;
+ }
}
}
- }
- p.state = SecCKKSProcessedStateLocal;
+ p.state = SecCKKSProcessedStateLocal;
- [p saveToDatabase:&error];
- ckksnotice("ckkspointer", ckks, "Saving new current item pointer: %@", p);
- if(error) {
- ckkserror("ckksincoming", ckks, "Error saving new current item pointer: %@ %@", error, p);
- }
+ [p saveToDatabase:&error];
+ ckksnotice("ckkspointer", ckks, "Saving new current item pointer: %@", p);
+ if(error) {
+ ckkserror("ckksincoming", ckks, "Error saving new current item pointer: %@ %@", error, p);
+ }
- // Schedule a view change notification
- [ckks.notifyViewChangedScheduler trigger];
+ // Schedule a view change notification
+ [ckks.notifyViewChangedScheduler trigger];
+ }
}
if(queueEntries.count > 0) {
NSMutableArray* deletedRecordIDs = [[NSMutableArray alloc] init];
for(id entry in queueEntries) {
- if(self.cancelled) {
- ckksnotice("ckksincoming", ckks, "CKKSIncomingQueueOperation cancelled, quitting");
- return false;
- }
+ @autoreleasepool {
+ if(self.cancelled) {
+ ckksnotice("ckksincoming", ckks, "CKKSIncomingQueueOperation cancelled, quitting");
+ return false;
+ }
- NSError* error = nil;
-
- CKKSIncomingQueueEntry* iqe = (CKKSIncomingQueueEntry*) entry;
- ckksnotice("ckksincoming", ckks, "ready to process an incoming queue entry: %@ %@ %@", iqe, iqe.uuid, iqe.action);
-
- // Note that we currently unencrypt the item before deleting it, instead of just deleting it
- // This finds the class, which is necessary for the deletion process. We could just try to delete
- // across all classes, though...
- NSMutableDictionary* attributes = [[CKKSItemEncrypter decryptItemToDictionary: iqe.item error:&error] mutableCopy];
- if(!attributes || error) {
- if([ckks.lockStateTracker isLockedError:error]) {
- NSError* localerror = nil;
- ckkserror("ckksincoming", ckks, "Keychain is locked; can't decrypt IQE %@", iqe);
- CKKSKey* key = [CKKSKey tryFromDatabase:iqe.item.parentKeyUUID zoneID:ckks.zoneID error:&localerror];
- if(localerror || ([key.keyclass isEqualToString:SecCKKSKeyClassA] && self.errorOnClassAFailure)) {
- self.error = error;
- }
+ NSError* error = nil;
+
+ CKKSIncomingQueueEntry* iqe = (CKKSIncomingQueueEntry*) entry;
+ ckksnotice("ckksincoming", ckks, "ready to process an incoming queue entry: %@ %@ %@", iqe, iqe.uuid, iqe.action);
+
+ // Note that we currently unencrypt the item before deleting it, instead of just deleting it
+ // This finds the class, which is necessary for the deletion process. We could just try to delete
+ // across all classes, though...
+ NSMutableDictionary* attributes = [[CKKSItemEncrypter decryptItemToDictionary: iqe.item error:&error] mutableCopy];
+ if(!attributes || error) {
+ if([ckks.lockStateTracker isLockedError:error]) {
+ NSError* localerror = nil;
+ ckkserror("ckksincoming", ckks, "Keychain is locked; can't decrypt IQE %@", iqe);
+ CKKSKey* key = [CKKSKey tryFromDatabase:iqe.item.parentKeyUUID zoneID:ckks.zoneID error:&localerror];
+ if(localerror || ([key.keyclass isEqualToString:SecCKKSKeyClassA] && self.errorOnClassAFailure)) {
+ self.error = error;
+ }
- // If this isn't an error, make sure it gets processed later.
- if([key.keyclass isEqualToString:SecCKKSKeyClassA] && !self.errorOnClassAFailure) {
- self.pendingClassAEntries = true;
- }
+ // If this isn't an error, make sure it gets processed later.
+ if([key.keyclass isEqualToString:SecCKKSKeyClassA] && !self.errorOnClassAFailure) {
+ self.pendingClassAEntries = true;
+ }
- } else if ([error.domain isEqualToString:@"securityd"] && error.code == errSecItemNotFound) {
- ckkserror("ckksincoming", ckks, "Coudn't find key in keychain; will attempt to poke key hierarchy: %@", error)
- self.missingKey = true;
+ } else if ([error.domain isEqualToString:@"securityd"] && error.code == errSecItemNotFound) {
+ 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);
- self.error = error;
+ } else {
+ ckkserror("ckksincoming", ckks, "Couldn't decrypt IQE %@ for some reason: %@", iqe, error);
+ self.error = error;
+ }
+ self.errorItemsProcessed += 1;
+ continue;
}
- self.errorItemsProcessed += 1;
- continue;
- }
- // Add the UUID (which isn't stored encrypted)
- [attributes setValue: iqe.item.uuid forKey: (__bridge NSString*) kSecAttrUUID];
+ // Add the UUID (which isn't stored encrypted)
+ [attributes setValue: iqe.item.uuid forKey: (__bridge NSString*) kSecAttrUUID];
- // Add the PCS plaintext fields, if they exist
- if(iqe.item.plaintextPCSServiceIdentifier) {
- [attributes setValue: iqe.item.plaintextPCSServiceIdentifier forKey: (__bridge NSString*) kSecAttrPCSPlaintextServiceIdentifier];
- }
- if(iqe.item.plaintextPCSPublicKey) {
- [attributes setValue: iqe.item.plaintextPCSPublicKey forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicKey];
- }
- if(iqe.item.plaintextPCSPublicIdentity) {
- [attributes setValue: iqe.item.plaintextPCSPublicIdentity forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicIdentity];
- }
-
- // This item is also synchronizable (by definition)
- [attributes setValue: @(YES) forKey: (__bridge NSString*) kSecAttrSynchronizable];
-
- NSString* classStr = [attributes objectForKey: (__bridge NSString*) kSecClass];
- if(![classStr isKindOfClass: [NSString class]]) {
- self.error = [NSError errorWithDomain:@"securityd"
- code:errSecInternalError
- userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Item did not have a reasonable class: %@", classStr]}];
- ckkserror("ckksincoming", ckks, "Synced item seems wrong: %@", self.error);
- self.errorItemsProcessed += 1;
- continue;
- }
+ // Add the PCS plaintext fields, if they exist
+ if(iqe.item.plaintextPCSServiceIdentifier) {
+ [attributes setValue: iqe.item.plaintextPCSServiceIdentifier forKey: (__bridge NSString*) kSecAttrPCSPlaintextServiceIdentifier];
+ }
+ if(iqe.item.plaintextPCSPublicKey) {
+ [attributes setValue: iqe.item.plaintextPCSPublicKey forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicKey];
+ }
+ if(iqe.item.plaintextPCSPublicIdentity) {
+ [attributes setValue: iqe.item.plaintextPCSPublicIdentity forKey: (__bridge NSString*) kSecAttrPCSPlaintextPublicIdentity];
+ }
- const SecDbClass * classP = !classStr ? NULL : kc_class_with_name((__bridge CFStringRef) classStr);
+ // This item is also synchronizable (by definition)
+ [attributes setValue: @(YES) forKey: (__bridge NSString*) kSecAttrSynchronizable];
- if(!classP) {
- ckkserror("ckksincoming", ckks, "unknown class in object: %@ %@", classStr, iqe);
- iqe.state = SecCKKSStateError;
- [iqe saveToDatabase:&error];
- if(error) {
- ckkserror("ckksincoming", ckks, "Couldn't save errored IQE to database: %@", error);
- self.error = error;
+ NSString* classStr = [attributes objectForKey: (__bridge NSString*) kSecClass];
+ if(![classStr isKindOfClass: [NSString class]]) {
+ self.error = [NSError errorWithDomain:@"securityd"
+ code:errSecInternalError
+ userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Item did not have a reasonable class: %@", classStr]}];
+ ckkserror("ckksincoming", ckks, "Synced item seems wrong: %@", self.error);
+ self.errorItemsProcessed += 1;
+ continue;
}
- self.errorItemsProcessed += 1;
- continue;
- }
- if([iqe.action isEqualToString: SecCKKSActionAdd] || [iqe.action isEqualToString: SecCKKSActionModify]) {
- BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests];
- BOOL manifestValidatesItem = [manifest validateItem:iqe.item withError:&error];
+ const SecDbClass * classP = !classStr ? NULL : kc_class_with_name((__bridge CFStringRef) classStr);
- if (!requireManifestValidation || manifestValidatesItem) {
- [self _onqueueHandleIQEChange: iqe attributes:attributes class:classP];
- [newOrChangedRecords addObject:[iqe.item CKRecordWithZoneID:ckks.zoneID]];
- }
- else {
- ckkserror("ckksincoming", ckks, "could not validate incoming item against manifest with error: %@", error);
- if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) {
- ckkserror("ckksincoming", ckks, "failed to save incoming item back to database in unauthenticated state with error: %@", error);
- return false;
+ if(!classP) {
+ ckkserror("ckksincoming", ckks, "unknown class in object: %@ %@", classStr, iqe);
+ iqe.state = SecCKKSStateError;
+ [iqe saveToDatabase:&error];
+ if(error) {
+ ckkserror("ckksincoming", ckks, "Couldn't save errored IQE to database: %@", error);
+ self.error = error;
}
self.errorItemsProcessed += 1;
continue;
}
- } else if ([iqe.action isEqualToString: SecCKKSActionDelete]) {
- BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests];
- BOOL manifestValidatesDelete = ![manifest itemUUIDExistsInManifest:iqe.uuid];
-
- if (!requireManifestValidation || manifestValidatesDelete) {
- // if the item does not exist in the latest manifest, we're good to delete it
- [self _onqueueHandleIQEDelete: iqe class:classP];
- [deletedRecordIDs addObject:[[CKRecordID alloc] initWithRecordName:iqe.uuid zoneID:ckks.zoneID]];
- }
- else {
- // if the item DOES exist in the manifest, we can't trust the deletion
- ckkserror("ckksincoming", ckks, "could not validate incoming item deletion against manifest");
- if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) {
- ckkserror("ckksincoming", ckks, "failed to save incoming item deletion back to database in unauthenticated state with error: %@", error);
+ if([iqe.action isEqualToString: SecCKKSActionAdd] || [iqe.action isEqualToString: SecCKKSActionModify]) {
+ BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests];
+ BOOL manifestValidatesItem = [manifest validateItem:iqe.item withError:&error];
+
+ if (!requireManifestValidation || manifestValidatesItem) {
+ [self _onqueueHandleIQEChange: iqe attributes:attributes class:classP];
+ [newOrChangedRecords addObject:[iqe.item CKRecordWithZoneID:ckks.zoneID]];
+ }
+ else {
+ ckkserror("ckksincoming", ckks, "could not validate incoming item against manifest with error: %@", error);
+ if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) {
+ ckkserror("ckksincoming", ckks, "failed to save incoming item back to database in unauthenticated state with error: %@", error);
+ return false;
+ }
self.errorItemsProcessed += 1;
- return false;
+ continue;
+ }
+ } else if ([iqe.action isEqualToString: SecCKKSActionDelete]) {
+ BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests];
+ BOOL manifestValidatesDelete = ![manifest itemUUIDExistsInManifest:iqe.uuid];
+
+ if (!requireManifestValidation || manifestValidatesDelete) {
+ // if the item does not exist in the latest manifest, we're good to delete it
+ [self _onqueueHandleIQEDelete: iqe class:classP];
+ [deletedRecordIDs addObject:[[CKRecordID alloc] initWithRecordName:iqe.uuid zoneID:ckks.zoneID]];
+ }
+ else {
+ // if the item DOES exist in the manifest, we can't trust the deletion
+ ckkserror("ckksincoming", ckks, "could not validate incoming item deletion against manifest");
+ if (![self _onqueueUpdateIQE:iqe withState:SecCKKSStateUnauthenticated error:&error]) {
+ ckkserror("ckksincoming", ckks, "failed to save incoming item deletion back to database in unauthenticated state with error: %@", error);
+
+ self.errorItemsProcessed += 1;
+ return false;
+ }
}
}
}
}
// Process other queues: CKKSCurrentItemPointers
- ckksnotice("ckksincoming", ckks, "Processed %lu items in incoming queue (%lu errors)", self.successfulItemsProcessed, self.errorItemsProcessed);
+ ckksnotice("ckksincoming", ckks, "Processed %lu items in incoming queue (%lu errors)", (unsigned long)self.successfulItemsProcessed, (unsigned long)self.errorItemsProcessed);
NSArray<CKKSCurrentItemPointer*>* newCIPs = [CKKSCurrentItemPointer remoteItemPointers:ckks.zoneID error:&error];
if(error || !newCIPs) {
if (![self processNewCurrentItemPointers:newCIPs withManifest:ckks.latestManifest egoManifest:ckks.egoManifest]) {
return false;
}
- ckksnotice("ckksincoming", ckks, "Processed %lu items in CIP queue", newCIPs.count);
+ ckksnotice("ckksincoming", ckks, "Processed %lu items in CIP queue", (unsigned long)newCIPs.count);
}
if(self.newOutgoingEntries) {
return @{@"UUID": self.uuid, @"ckzone":self.zoneID.zoneName};
}
-- (NSDictionary<NSString*,NSString*>*)sqlValues {
+- (NSDictionary<NSString*,id>*)sqlValues {
return @{@"UUID": self.uuid,
@"parentKeyUUID": self.parentKeyUUID,
@"ckzone": CKKSNilToNSNull(self.zoneID.zoneName),
#import "CKKSKeychainView.h"
#import "CKKSCurrentKeyPointer.h"
#import "CKKSKey.h"
-#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#include <securityd/SecItemSchema.h>
#include <Security/SecItem.h>
#include <Security/SecItemPriv.h>
@class CKKSOutgoingQueueEntry;
@class CKKSZoneChangeFetcher;
-@interface CKKSKeychainView : CKKSZone <CKKSZoneUpdateReceiver, CKKSChangeFetcherErrorOracle, CKKSPeerUpdateListener>
+@interface CKKSKeychainView : CKKSZone <CKKSZoneUpdateReceiver, CKKSChangeFetcherClient, CKKSPeerUpdateListener>
{
CKKSZoneKeyState* _keyHierarchyState;
}
@property CKKSNewTLKOperation* lastNewTLKOperation;
@property CKKSOutgoingQueueOperation* lastOutgoingQueueOperation;
@property CKKSProcessReceivedKeysOperation* lastProcessReceivedKeysOperation;
-@property CKKSFetchAllRecordZoneChangesOperation* lastRecordZoneChangesOperation;
@property CKKSReencryptOutgoingItemsOperation* lastReencryptOutgoingItemsOperation;
@property CKKSScanLocalItemsOperation* lastScanLocalItemsOperation;
@property CKKSSynchronizeOperation* lastSynchronizeOperation;
accountTracker:(CKKSCKAccountStateTracker*)accountTracker
lockStateTracker:(CKKSLockStateTracker*)lockStateTracker
reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker
+ changeFetcher:(CKKSZoneChangeFetcher*)fetcher
savedTLKNotifier:(CKKSNearFutureScheduler*)savedTLKNotifier
peerProvider:(id<CKKSPeerProvider>)peerProvider
fetchRecordZoneChangesOperationClass:(Class<CKKSFetchRecordZoneChangesOperation>)fetchRecordZoneChangesOperationClass
// Schedules a process queueoperation to happen after the next device unlock. This may be Immediately, if the device is unlocked.
- (void)processIncomingQueueAfterNextUnlock;
+// This operation will complete directly after the next ProcessIncomingQueue, and should supply that IQO's result. Used mainly for testing; otherwise you'd just kick off a IQO directly.
+- (CKKSResultOperation*)resultsOfNextProcessIncomingQueueOperation;
+
// Schedules an operation to update this device's state record in CloudKit
// If rateLimit is true, the operation will abort if it's updated the record in the past 3 days
- (CKKSUpdateDeviceStateOperation*)updateDeviceState:(bool)rateLimit
- (CKKSDeviceStateEntry* _Nullable)_onqueueCurrentDeviceStateEntry:(NSError* __autoreleasing*)error;
-// Called by the CKKSZoneChangeFetcher
-- (bool)isFatalCKFetchError:(NSError*)error;
-
// Please don't use these unless you're an Operation in this package
@property NSHashTable<CKKSIncomingQueueOperation*>* incomingQueueOperations;
@property NSHashTable<CKKSOutgoingQueueOperation*>* outgoingQueueOperations;
#import "keychain/ckks/CKKSTLKShare.h"
#import "keychain/ckks/CKKSHealTLKSharesOperation.h"
#import "keychain/ckks/CKKSLocalSynchronizeOperation.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#include <utilities/SecCFWrappers.h>
#include <utilities/SecDb.h>
@property bool keyStateFetchRequested;
@property bool keyStateFullRefetchRequested;
@property bool keyStateProcessRequested;
+@property bool trustedPeersSetChanged;
@property bool keyStateCloudKitDeleteRequested;
@property NSHashTable<CKKSResultOperation*>* cloudkitDeleteZoneOperations;
@property CKKSNearFutureScheduler* outgoingQueueOperationScheduler;
@property CKKSResultOperation* processIncomingQueueAfterNextUnlockOperation;
+@property CKKSResultOperation* resultsOfNextIncomingQueueOperationOperation;
@property NSMutableDictionary<NSString*, SecBoolNSErrorCallback>* pendingSyncCallbacks;
accountTracker:(CKKSCKAccountStateTracker*) accountTracker
lockStateTracker:(CKKSLockStateTracker*) lockStateTracker
reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker
+ changeFetcher:(CKKSZoneChangeFetcher*)fetcher
savedTLKNotifier:(CKKSNearFutureScheduler*) savedTLKNotifier
peerProvider:(id<CKKSPeerProvider>)peerProvider
fetchRecordZoneChangesOperationClass: (Class<CKKSFetchRecordZoneChangesOperation>) fetchRecordZoneChangesOperationClass
_outgoingQueueOperations = [NSHashTable weakObjectsHashTable];
_cloudkitDeleteZoneOperations = [NSHashTable weakObjectsHashTable];
_localResetOperations = [NSHashTable weakObjectsHashTable];
- _zoneChangeFetcher = [[CKKSZoneChangeFetcher alloc] initWithCKKSKeychainView: self];
+
+ _zoneChangeFetcher = fetcher;
+ [fetcher registerClient:self];
_notifierClass = notifierClass;
_notifyViewChangedScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-notify-scheduler", self.zoneName]
// 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;
+ __weak __typeof(self) weakSelf = self;
+ CKKSGroupOperation* resetOperationGroup = [CKKSGroupOperation named:@"local-reset" withBlockTakingSelf:^(CKKSGroupOperation *strongOp) {
+ __strong __typeof(self) strongSelf = weakSelf;
+
+ __block CKKSResultOperation* resetOperation = nil;
+
+ [strongSelf dispatchSyncWithAccountKeys:^bool {
+ strongSelf.keyStateLocalResetRequested = true;
+ resetOperation = [strongSelf createPendingResetLocalDataOperation];
+ [strongSelf _onqueueAdvanceKeyStateMachineToState:nil withError:nil];
+ return true;
+ }];
+
+ [strongOp dependOnBeforeGroupFinished:resetOperation];
}];
+ [self scheduleOperationWithoutDependencies:resetOperationGroup];
- __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
[strongOp runBeforeGroupFinished:waitOp];
}];
- [viewReset addSuccessDependency:resetOperation];
+ [viewReset addSuccessDependency:resetOperationGroup];
[self scheduleOperationWithoutDependencies:viewReset];
return viewReset;
if(self.keyStateProcessRequested || [remoteKeys count] > 0) {
// We've either received some remote keys from the last fetch, or someone has requested a reprocess.
ckksnotice("ckkskey", self, "Kicking off a key reprocess based on request:%d and remote key count %lu", self.keyStateProcessRequested, (unsigned long)[remoteKeys count]);
- [self _onqueueKeyHierarchyProcess];
- // Stay in state 'ready': this reprocess might not change anything. If it does, cleanup code elsewhere will
- // reencode items that arrive during this ready
+ nextState = SecCKKSZoneKeyStateProcess;
} else if(self.keyStateFullRefetchRequested) {
// In ready, but someone has requested a full fetch. Kick it off.
// We're in a hold state: waiting for the TLK bytes to arrive.
if(self.keyStateProcessRequested) {
- // 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];
+ // Someone has requsted a reprocess! Go to the correct state.
+ ckksnotice("ckkskey", self, "Received a nudge that our TLK might be here! Reprocessing.");
+ nextState = SecCKKSZoneKeyStateProcess;
+
+ } else if(self.trustedPeersSetChanged) {
+ // Hmm, maybe this trust set change will cause us to recover this TLK (due to a previously-untrusted share becoming trusted). Worth a shot!
+ ckksnotice("ckkskey", self, "Received a nudge that the trusted peers set might have changed! Reprocessing.");
+ nextState = SecCKKSZoneKeyStateProcess;
+ self.trustedPeersSetChanged = false;
+
} else {
// Should we nuke this zone?
if([self _onqueueOtherDevicesReportHavingTLKs:keyset]) {
self.keyStateMachineOperation = [[CKKSHealTLKSharesOperation alloc] initWithCKKSKeychainView:self
ckoperationGroup:self.keyHierarchyOperationGroup];
+ } else if([state isEqualToString:SecCKKSZoneKeyStateProcess]) {
+ ckksnotice("ckksshare", self, "Launching key state process");
+ self.keyStateMachineOperation = [[CKKSProcessReceivedKeysOperation alloc] initWithCKKSKeychainView: self];
+
+ // Since we're starting a reprocess, this is answering all previous requests.
+ self.keyStateProcessRequested = false;
+
} else {
ckkserror("ckks", self, "asked to advance state machine to unknown state: %@", state);
self.keyHierarchyState = state;
// Check keyset
if(!set.tlk || !set.classA || !set.classC) {
- ckkserror("ckkskey", self, "Error examining existing key hierarchy: %@", set);
+ ckkserror("ckkskey", self, "Error examining existing key hierarchy (missing at least one key): %@", set);
if(error) {
*error = set.error;
}
}];
self.keyStateMachineOperation.name = @"waiting-for-refetch";
- NSOperation* fetchOp = [self.zoneChangeFetcher requestSuccessfulResyncFetch: CKKSFetchBecauseKeyHierarchy];
+ NSOperation* fetchOp = [self.zoneChangeFetcher requestSuccessfulFetchForManyReasons:[NSSet setWithObjects:CKKSFetchBecauseKeyHierarchy, CKKSFetchBecauseResync, nil]];
[self.keyStateMachineOperation addDependency: fetchOp];
self.keyStateMachineRefetched = true;
self.keyStateFetchRequested = false;
}
-
-- (void)_onqueueKeyHierarchyProcess {
- dispatch_assert_queue(self.queue);
-
- self.keyStateMachineOperation = [[CKKSProcessReceivedKeysOperation alloc] initWithCKKSKeychainView: self];
-
- // Since we're starting a reprocess, this is answering all previous requests.
- self.keyStateProcessRequested = false;
-}
-
- (void) handleKeychainEventDbConnection: (SecDbConnectionRef) dbconn
added: (SecDbItemRef) added
deleted: (SecDbItemRef) deleted
}
}
+- (CKKSResultOperation*)resultsOfNextProcessIncomingQueueOperation {
+ if(self.resultsOfNextIncomingQueueOperationOperation && [self.resultsOfNextIncomingQueueOperationOperation isPending]) {
+ return self.resultsOfNextIncomingQueueOperationOperation;
+ }
+
+ // Else, make a new one.
+ self.resultsOfNextIncomingQueueOperationOperation = [CKKSResultOperation named:[NSString stringWithFormat:@"wait-for-next-incoming-queue-operation-%@", self.zoneName] withBlock:^{}];
+ return self.resultsOfNextIncomingQueueOperationOperation;
+}
+
- (CKKSIncomingQueueOperation*)processIncomingQueue:(bool)failOnClassA {
return [self processIncomingQueue:failOnClassA after: nil];
}
if(after) {
[incomingop addNullableDependency: after];
}
+
// check (again) for race condition; if the op has started we need to add another (for the dependency)
if([incomingop isPending]) {
incomingop.errorOnClassAFailure |= failOnClassA;
}
}
- CKKSIncomingQueueOperation* op = [[CKKSIncomingQueueOperation alloc] initWithCKKSKeychainView:self errorOnClassAFailure:failOnClassA];
+ CKKSIncomingQueueOperation* op = [[CKKSIncomingQueueOperation alloc] initWithCKKSKeychainView:self errorOnClassAFailure:failOnClassA];
op.name = @"incoming-queue-operation";
if(after != nil) {
[op addSuccessDependency: after];
}
+ if(self.resultsOfNextIncomingQueueOperationOperation) {
+ [self.resultsOfNextIncomingQueueOperationOperation addSuccessDependency:op];
+ [self scheduleOperation:self.resultsOfNextIncomingQueueOperationOperation];
+ }
+
[self scheduleOperation: op];
return op;
}
osVersion:SecCKKSHostOSVersion()
lastUnlockTime:lastUnlockDay
circlePeerID:accountTracker.accountCirclePeerID
- circleStatus:accountTracker.currentCircleStatus
+ circleStatus:accountTracker.currentCircleStatus.status
keyState:self.keyHierarchyState
currentTLKUUID:suggestedTLK.uuid
currentClassAUUID:suggestedClassAKey.uuid
return [self processIncomingQueue:false after:[self.zoneChangeFetcher requestSuccessfulFetch:because]];
}
+- (CKKSResultOperation*)fetchAndProcessCKChangesDueToAPNS:(CKRecordZoneNotification*)notification {
+ if(!SecCKKSIsEnabled()) {
+ ckksinfo("ckks", self, "Skipping fetchAndProcessCKChanges due to disabled CKKS");
+ return nil;
+ }
+
+ // We fetched some changes; try to process them!
+ return [self processIncomingQueue:false after:[self.zoneChangeFetcher requestSuccessfulFetchDueToAPNS:notification]];
+}
+
// Lets the view know about a failed CloudKit write. If the error is "already have one of these records", it will
// store the new records and kick off the new processing
//
- (bool)_onqueueCKRecordChanged:(CKRecord*)record resync:(bool)resync {
dispatch_assert_queue(self.queue);
- ckksinfo("ckksfetch", self, "Processing record modification(%@): %@", record.recordType, record);
+ @autoreleasepool {
+ ckksnotice("ckksfetch", self, "Processing record modification(%@): %@", record.recordType, record);
- if([[record recordType] isEqual: SecCKRecordItemType]) {
- [self _onqueueCKRecordItemChanged:record resync:resync];
- return true;
- } else if([[record recordType] isEqual: SecCKRecordCurrentItemType]) {
- [self _onqueueCKRecordCurrentItemPointerChanged:record resync:resync];
- return true;
- } else if([[record recordType] isEqual: SecCKRecordIntermediateKeyType]) {
- [self _onqueueCKRecordKeyChanged:record resync:resync];
- return true;
- } else if ([[record recordType] isEqual: SecCKRecordTLKShareType]) {
- [self _onqueueCKRecordTLKShareChanged:record resync:resync];
- return true;
- } else if([[record recordType] isEqualToString: SecCKRecordCurrentKeyType]) {
- [self _onqueueCKRecordCurrentKeyPointerChanged:record resync:resync];
- return true;
- } else if ([[record recordType] isEqualToString:SecCKRecordManifestType]) {
- [self _onqueueCKRecordManifestChanged:record resync:resync];
- return true;
- } else if ([[record recordType] isEqualToString:SecCKRecordManifestLeafType]) {
- [self _onqueueCKRecordManifestLeafChanged:record resync:resync];
- return true;
- } else if ([[record recordType] isEqualToString:SecCKRecordDeviceStateType]) {
- [self _onqueueCKRecordDeviceStateChanged:record resync:resync];
- return true;
- } else {
- ckkserror("ckksfetch", self, "unknown record type: %@ %@", [record recordType], record);
- return false;
+ if([[record recordType] isEqual: SecCKRecordItemType]) {
+ [self _onqueueCKRecordItemChanged:record resync:resync];
+ return true;
+ } else if([[record recordType] isEqual: SecCKRecordCurrentItemType]) {
+ [self _onqueueCKRecordCurrentItemPointerChanged:record resync:resync];
+ return true;
+ } else if([[record recordType] isEqual: SecCKRecordIntermediateKeyType]) {
+ [self _onqueueCKRecordKeyChanged:record resync:resync];
+ return true;
+ } else if ([[record recordType] isEqual: SecCKRecordTLKShareType]) {
+ [self _onqueueCKRecordTLKShareChanged:record resync:resync];
+ return true;
+ } else if([[record recordType] isEqualToString: SecCKRecordCurrentKeyType]) {
+ [self _onqueueCKRecordCurrentKeyPointerChanged:record resync:resync];
+ return true;
+ } else if ([[record recordType] isEqualToString:SecCKRecordManifestType]) {
+ [self _onqueueCKRecordManifestChanged:record resync:resync];
+ return true;
+ } else if ([[record recordType] isEqualToString:SecCKRecordManifestLeafType]) {
+ [self _onqueueCKRecordManifestLeafChanged:record resync:resync];
+ return true;
+ } else if ([[record recordType] isEqualToString:SecCKRecordDeviceStateType]) {
+ [self _onqueueCKRecordDeviceStateChanged:record resync:resync];
+ return true;
+ } else {
+ ckkserror("ckksfetch", self, "unknown record type: %@ %@", [record recordType], record);
+ return false;
+ }
}
}
- (void)notifyZoneChange: (CKRecordZoneNotification*) notification {
ckksnotice("ckks", self, "received a zone change notification for %@ %@", self, notification);
- [self fetchAndProcessCKChanges:CKKSFetchBecauseAPNS];
+ [self fetchAndProcessCKChangesDueToAPNS:notification];
}
- (void)superHandleCKLogin {
});
}
-#pragma mark - CKKSChangeFetcherErrorOracle
+#pragma mark - CKKSChangeFetcherClient
-- (bool) isFatalCKFetchError: (NSError*) error {
+- (CKKSCloudKitFetchRequest*)participateInFetch
+{
+ __block CKKSCloudKitFetchRequest* request = [[CKKSCloudKitFetchRequest alloc] init];
+ [self dispatchSync: ^bool {
+ if(self.accountStatus != CKKSAccountStatusAvailable) {
+ ckksnotice("ckksfetch", self, "Not participating in fetch: not logged in");
+ request.participateInFetch = false;
+ return false;
+ }
+
+ if(!self.zoneCreated) {
+ ckksnotice("ckksfetch", self, "Not participating in fetch: zone not created yet");
+ request.participateInFetch = false;
+ return false;
+ }
+
+ request.participateInFetch = true;
+
+ if([self.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateNeedFullRefetch]) {
+ // We want to return a nil change tag (to force a resync)
+ ckksnotice("ckksfetch", self, "Beginning refetch");
+ request.changeToken = nil;
+ } else {
+ CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.zoneName];
+ if(!ckse) {
+ ckkserror("ckksfetch", self, "couldn't fetch zone change token for %@", self.zoneName);
+ return false;
+ }
+ request.changeToken = ckse.changeToken;
+ }
+ return true;
+ }];
+
+ return request;
+}
+
+- (void)changesFetched:(NSArray<CKRecord*>*)changedRecords
+ deletedRecordIDs:(NSArray<CKKSCloudKitDeletion*>*)deletedRecords
+ oldChangeToken:(CKServerChangeToken*)oldChangeToken
+ newChangeToken:(CKServerChangeToken*)newChangeToken
+{
+ [self dispatchSyncWithAccountKeys:^bool{
+ // This is a resync if we already have a change token, but this fetch didn't have one
+ CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName];
+ bool resync = ckse.changeToken && (oldChangeToken == nil);
+
+ for (CKRecord* record in changedRecords) {
+ [self _onqueueCKRecordChanged:record resync:resync];
+ }
+
+ for (CKKSCloudKitDeletion* deletion in deletedRecords) {
+ [self _onqueueCKRecordDeleted:deletion.recordID recordType:deletion.recordType resync:resync];
+ }
+
+ NSError* error = nil;
+ if(resync) {
+ // Scan through all CKMirrorEntries and determine if any exist that CloudKit didn't tell us about
+ ckksnotice("ckksresync", self, "Comparing local UUIDs against the CloudKit list");
+ NSMutableArray<NSString*>* uuids = [[CKKSMirrorEntry allUUIDs:self.zoneID error:&error] mutableCopy];
+
+ for(NSString* uuid in uuids) {
+ CKRecord* record = nil;
+ CKRecordID* recordID = [[CKRecordID alloc] initWithRecordName:uuid zoneID:self.zoneID];
+ for(CKRecord* r in changedRecords) {
+ if([r.recordID isEqual:recordID]) {
+ record = r;
+ break;
+ }
+ }
+
+ if(record) {
+ ckksnotice("ckksresync", self, "UUID %@ is still in CloudKit; carry on.", uuid);
+ } else {
+ CKKSMirrorEntry* ckme = [CKKSMirrorEntry tryFromDatabase:uuid zoneID:self.zoneID error:&error];
+ if(error != nil) {
+ ckkserror("ckksresync", self, "Couldn't read an item from the database, but it used to be there: %@ %@", uuid, error);
+ continue;
+ }
+ if(!ckme) {
+ ckkserror("ckksresync", self, "Couldn't read ckme(%@) from database; continuing", uuid);
+ continue;
+ }
+
+ ckkserror("ckksresync", self, "BUG: Local item %@ not found in CloudKit, deleting", uuid);
+ [self _onqueueCKRecordDeleted:ckme.item.storedCKRecord.recordID recordType:ckme.item.storedCKRecord.recordType resync:resync];
+ }
+ }
+ }
+
+ error = nil;
+
+ CKKSZoneStateEntry* state = [CKKSZoneStateEntry state:self.zoneName];
+ state.lastFetchTime = [NSDate date]; // The last fetch happened right now!
+ state.changeToken = newChangeToken;
+ [state saveToDatabase:&error];
+ if(error) {
+ ckkserror("ckksfetch", self, "Couldn't save new server change token: %@", error);
+ }
+
+ // Might as well kick off a IQO!
+ [self processIncomingQueue:false];
+
+ ckksnotice("ckksfetch", self, "Finished processing changes for %@", self.zoneID);
+
+ return true;
+ }];
+}
+
+// Return false if this is a 'fatal' error and we don't want another fetch to be tried
+- (bool)notifyFetchError: (NSError*) error {
__weak __typeof(self) weakSelf = self;
- // Again, note that this handles exactly one zone. Mutli-zone errors are not supported.
bool isChangeTokenExpiredError = false;
if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorChangeTokenExpired)) {
isChangeTokenExpiredError = true;
} else if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorPartialFailure)) {
NSDictionary* partialErrors = error.userInfo[CKPartialErrorsByItemIDKey];
- for(NSError* partialError in partialErrors.allValues) {
- if([partialError.domain isEqualToString:CKErrorDomain] && (partialError.code == CKErrorChangeTokenExpired)) {
+ for(CKRecordZoneID* zoneID in partialErrors) {
+ NSError* partialError = partialErrors[zoneID];
+ if([zoneID isEqual:self.zoneID] && [partialError.domain isEqualToString:CKErrorDomain] && (partialError.code == CKErrorChangeTokenExpired)) {
isChangeTokenExpiredError = true;
}
}
}
if(isChangeTokenExpiredError) {
- ckkserror("ckks", self, "Received notice that our change token is out of date. Resetting local data...");
+ ckkserror("ckks", self, "Received notice that our change token is out of date (for %@). Resetting local data...", self.zoneID);
CKKSResultOperation* resetOp = [self resetLocalData];
CKKSResultOperation* resetHandler = [CKKSResultOperation named:@"local-reset-handler" withBlock:^{
__strong __typeof(self) strongSelf = weakSelf;
[resetHandler addDependency:resetOp];
[self scheduleOperation:resetHandler];
- return true;
+ return false;
}
bool isDeletedZoneError = false;
isDeletedZoneError = true;
} else if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorPartialFailure)) {
NSDictionary* partialErrors = error.userInfo[CKPartialErrorsByItemIDKey];
- for(NSError* partialError in partialErrors.allValues) {
- if([partialError.domain isEqualToString:CKErrorDomain] && ((partialError.code == CKErrorUserDeletedZone) || (partialError.code == CKErrorZoneNotFound))) {
+ for(CKRecordZoneID* zoneID in partialErrors) {
+ NSError* partialError = partialErrors[zoneID];
+ if([self.zoneID isEqual:zoneID] && [partialError.domain isEqualToString:CKErrorDomain] && ((partialError.code == CKErrorUserDeletedZone) || (partialError.code == CKErrorZoneNotFound))) {
isDeletedZoneError = true;
}
}
}
if(isDeletedZoneError) {
- ckkserror("ckks", self, "Received notice that our zone does not exist. Resetting local data.");
+ ckkserror("ckks", self, "Received notice that our zone(%@) does not exist. Resetting local data.", self.zoneID);
CKKSResultOperation* resetOp = [self resetLocalData];
CKKSResultOperation* resetHandler = [CKKSResultOperation named:@"reset-handler" withBlock:^{
__strong __typeof(self) strongSelf = weakSelf;
[resetHandler addDependency:resetOp];
[self scheduleOperation:resetHandler];
- return true;
+ return false;
}
if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorBadContainer)) {
ckkserror("ckks", self, "Received notice that our container does not exist. Nothing to do.");
- return true;
+ return false;
}
- return false;
+ return true;
}
#pragma mark CKKSPeerUpdateListener
// We might need to share the TLK to some new people, or we might now trust the TLKs we have.
// The key state machine should handle that, so poke it.
ckkserror("ckks", self, "Received update that the trust set has changed");
- [self keyStateMachineRequestProcess];
+
+ self.trustedPeersSetChanged = true;
+ [self.pokeKeyStateMachineScheduler trigger];
}
#pragma mark - Test Support
@"lastIncomingQueueOperation": stringify(self.lastIncomingQueueOperation),
@"lastNewTLKOperation": stringify(self.lastNewTLKOperation),
@"lastOutgoingQueueOperation": stringify(self.lastOutgoingQueueOperation),
- @"lastRecordZoneChangesOperation": stringify(self.lastRecordZoneChangesOperation),
@"lastProcessReceivedKeysOperation": stringify(self.lastProcessReceivedKeysOperation),
@"lastReencryptOutgoingItemsOperation":stringify(self.lastReencryptOutgoingItemsOperation),
@"lastScanLocalItemsOperation": stringify(self.lastScanLocalItemsOperation),
#import "keychain/ckks/CKKSMirrorEntry.h"
#import "keychain/ckks/CKKSIncomingQueueEntry.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#if OCTAGON
return sqlValues;
}
-- (NSDictionary<NSString*, NSString*>*)whereClauseToFindSelf
+- (NSDictionary<NSString*, id>*)whereClauseToFindSelf
{
return @{ @"ckzone" : CKKSNilToNSNull(_zoneName),
@"gencount" : [NSNumber numberWithUnsignedInteger:_generationCount],
return [self.item whereClauseToFindSelf];
}
-- (NSDictionary<NSString*,NSString*>*)sqlValues {
+- (NSDictionary<NSString*,id>*)sqlValues {
NSMutableDictionary* values = [[self.item sqlValues] mutableCopy];
values[@"wascurrent"] = [NSNumber numberWithUnsignedLongLong:self.wasCurrent];
return values;
// Don't trigger again until at least this much time has passed.
- (void)waitUntil:(uint64_t)delay;
+- (void)changeDelays:(dispatch_time_t)initialDelay continuingDelay:(dispatch_time_t)continuingDelay;
+
@end
NS_ASSUME_NONNULL_END
return self;
}
+- (void)changeDelays:(dispatch_time_t)initialDelay continuingDelay:(dispatch_time_t)continuingDelay
+{
+ dispatch_sync(self.queue, ^{
+ self.initialDelay = initialDelay;
+ self.continuingDelay = continuingDelay;
+ });
+}
+
- (CKKSResultOperation*)makeOperationDependency {
CKKSResultOperation* op = [CKKSResultOperation named:[NSString stringWithFormat:@"nfs-%@", self.name] withBlock:^{}];
op.descriptionErrorCode = self.operationDependencyDescriptionCode;
#import "CKKSGroupOperation.h"
#import "CKKSNearFutureScheduler.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#if OCTAGON
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.qualityOfService = NSQualityOfServiceUserInitiated; // This needs to happen before CKKS is available for PCS/CloudKit use.
+
+ // This needs to happen before CKKS is available for PCS/CloudKit use.
+ modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO;
+ modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+
modifyRecordsOp.group = self.ckoperationGroup;
ckksnotice("ckkstlk", ckks, "Operation group is %@", self.ckoperationGroup);
#import "CKKSItemEncrypter.h"
#import "CKKSKey.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
@implementation CKKSOutgoingQueueEntry
* @APPLE_LICENSE_HEADER_END@
*/
+#if OCTAGON
+
+#import <CloudKit/CloudKit.h>
+#import <CloudKit/CloudKit_Private.h>
+
#import "CKKSKeychainView.h"
#import "CKKSCurrentKeyPointer.h"
#import "CKKSOutgoingQueueOperation.h"
#include <utilities/SecADWrapper.h>
#import "CKKSPowerCollection.h"
-#if OCTAGON
-
@interface CKKSOutgoingQueueOperation()
@property CKModifyRecordsOperation* modifyRecordsOperation;
@end
return;
}
- [ckks dispatchSyncWithAccountKeys: ^bool{
+ [ckks dispatchSync: ^bool{
ckks.lastOutgoingQueueOperation = self;
if(self.cancelled) {
ckksnotice("ckksoutgoing", ckks, "CKKSOutgoingQueueOperation cancelled, quitting");
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];
return true;
}];
-
[strongSelf.operationQueue addOperation: modifyComplete];
// Kick off another queue process. We expect it to exit instantly, but who knows!
- [strongCKKS processOutgoingQueue:strongSelf.ckoperationGroup];
+ // If we think the network is iffy, though, wait for it to come back
+ CKKSResultOperation* possibleNetworkDependency = nil;
+ CKKSReachabilityTracker* reachabilityTracker = strongCKKS.reachabilityTracker;
+ if(ckerror && [reachabilityTracker isNetworkError:ckerror]) {
+ possibleNetworkDependency = reachabilityTracker.reachabilityDependency;
+ }
+
+ [strongCKKS processOutgoingQueueAfter:possibleNetworkDependency ckoperationGroup:strongSelf.ckoperationGroup];
};
ckksinfo("ckksoutgoing", ckks, "Current keys to update: %@", currentKeysToSave);
self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave.allValues recordIDsToDelete:recordIDsToDelete];
self.modifyRecordsOperation.atomic = TRUE;
- self.modifyRecordsOperation.qualityOfService = uploadingPCSEntries ? NSQualityOfServiceUserInitiated : NSQualityOfServiceUtility; // PCS items are needed for CloudKit to work, so they might be user-initiated
+
+ // Until <rdar://problem/38725728> Changes to discretionary-ness (explicit or derived from QoS) should be "live", all requests should be nondiscretionary
+ self.modifyRecordsOperation.configuration.automaticallyRetryNetworkFailures = NO;
+ self.modifyRecordsOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+
self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged;
self.modifyRecordsOperation.group = self.ckoperationGroup;
ckksnotice("ckksoutgoing", ckks, "QoS: %d; operation group is %@", (int)self.modifyRecordsOperation.qualityOfService, self.modifyRecordsOperation.group);
#import "CKKSKey.h"
#import "CKKSProcessReceivedKeysOperation.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#if OCTAGON
#import <utilities/debugging.h>
#import <TargetConditionals.h>
-#if !TARGET_OS_BRIDGE
-#import <WirelessDiagnostics/WirelessDiagnostics.h>
-#import "keychain/analytics/awd/AWDMetricIds_Keychain.h"
-#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h"
-#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h"
-#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h"
-#endif
-
typedef NS_ENUM(int, BucketType) {
All,
Group,
@property (readwrite) NSDictionary<NSString *, NSNumber *> *config;
@property NSMutableDictionary<NSString *, NSDate *> *buckets;
@property NSDate *overloadUntil;
-#if !TARGET_OS_BRIDGE
-@property NSMutableArray<NSNumber *> *badnessData;
-@property AWDServerConnection *awdConnection;
-#define CKKSRateLimiterName @"ckks-original"
-#endif
@end
@implementation CKKSRateLimiter
@250 , @"trimSize",
@3600, @"trimTime",
@1800, @"overloadDuration", nil];
-#if !TARGET_OS_BRIDGE
- _badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, @0, nil];
- _awdConnection = [[AWDServerConnection alloc] initWithComponentId:AWDComponentId_Keychain];
- [self setUpAwdMetrics];
-#endif
}
return self;
}
badness = 4;
}
-#if !TARGET_OS_BRIDGE
- self.badnessData[badness] = @([self.badnessData[badness] intValue] + 1);
-#endif
-
*limitTime = sendTime;
return badness;
}
// Nothing to remove means everybody keeps being noisy. Tell them to go away.
if ([toRemove count] == 0) {
self.overloadUntil = [self.buckets[@"All"] dateByAddingTimeInterval:[self.config[@"overloadDuration"] intValue]];
-#if !TARGET_OS_BRIDGE
- AWDKeychainCKKSRateLimiterOverload *metric = [AWDKeychainCKKSRateLimiterOverload new];
- metric.durationMsec = [self.overloadUntil timeIntervalSinceDate:time];
- metric.ratelimitertype = CKKSRateLimiterName;
- AWDPostMetric(AWDComponentId_Keychain, metric);
-#endif
seccritical("RateLimiter overloaded until %@", self.overloadUntil);
} else {
self.overloadUntil = nil;
}
}
-#if !TARGET_OS_BRIDGE
-- (void)setUpAwdMetrics {
- [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterTopWriters callback:^(UInt32 metricId) {
- AWDKeychainCKKSRateLimiterTopWriters *metric = [AWDKeychainCKKSRateLimiterTopWriters new];
- NSArray *offenders = [self topOffendingAccessGroups:3];
- if (offenders) {
- for (NSString *offender in offenders) {
- [metric addWriter:offender];
- }
- }
- metric.ratelimitertype = CKKSRateLimiterName;
- AWDPostMetric(metricId, metric);
- }];
-
- [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterAggregatedScores callback:^(UInt32 metricId) {
- AWDKeychainCKKSRateLimiterAggregatedScores *metric = [AWDKeychainCKKSRateLimiterAggregatedScores new];
- for (NSNumber *num in self.badnessData) {
- [metric addData:[num unsignedIntValue]];
- }
- metric.ratelimitertype = CKKSRateLimiterName;
- AWDPostMetric(metricId, metric);
- self.badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, @0, nil];
- }];
-}
-#endif
-
+ (BOOL)supportsSecureCoding {
return YES;
}
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
+@class CKKSResultOperation;
+
@interface CKKSReachabilityTracker : NSObject
-@property NSOperation* reachablityDependency;
+@property CKKSResultOperation* reachabilityDependency;
@property (readonly) bool currentReachability; // get current reachability value w/o recheck
- (instancetype)init;
#import "keychain/ckks/CKKS.h"
#import "keychain/ckks/CKKSGroupOperation.h"
+#import "keychain/ckks/CKKSResultOperation.h"
#import "keychain/ckks/CKKSReachabilityTracker.h"
#import "keychain/ckks/CKKSAnalytics.h"
return currentReachability;
}
--(void)_onQueueRunReachablityDependency
+-(void)_onQueueRunreachabilityDependency
{
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.reachabilityDependency) {
+ [self.operationQueue addOperation: self.reachabilityDependency];
+ self.reachabilityDependency = nil;
}
if (self.timer) {
dispatch_source_cancel(self.timer);
-(void)_onQueueResetReachabilityDependency {
dispatch_assert_queue(self.queue);
- if(self.reachablityDependency == nil || ![self.reachablityDependency isPending]) {
+ if(self.reachabilityDependency == nil || ![self.reachabilityDependency isPending]) {
__weak __typeof(self) weakSelf = self;
- self.reachablityDependency = [NSBlockOperation blockOperationWithBlock: ^{
+ secnotice("ckksnetwork", "Network unavailable");
+ self.reachabilityDependency = [CKKSResultOperation named:@"network-available-dependency" withBlock: ^{
__typeof(self) strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}
if (strongSelf.haveNetwork) {
- secinfo("ckks", "Network available");
+ secnotice("ckksnetwork", "Network available");
} else {
- secinfo("ckks", "Network still not available, retrying after waiting %2.1f hours",
+ secnotice("ckksnetwork", "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
}
if (strongSelf.timer) {
[[CKKSAnalytics logger] noteEvent:CKKSEventReachabilityTimerExpired];
- [strongSelf _onQueueRunReachablityDependency];
+ [strongSelf _onQueueRunreachabilityDependency];
}
});
if(hadNetwork != self.haveNetwork) {
if(self.haveNetwork) {
// We're have network now
- [self _onQueueRunReachablityDependency];
+ [self _onQueueRunreachabilityDependency];
} else {
[self _onQueueResetReachabilityDependency];
}
#import "keychain/ckks/CKKSReencryptOutgoingItemsOperation.h"
#import "keychain/ckks/CKKSItemEncrypter.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#if OCTAGON
#import "keychain/ckks/CKKSResultOperation.h"
#import "keychain/ckks/NSOperationCategories.h"
#import "keychain/ckks/CKKSCondition.h"
-#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#include <utilities/debugging.h>
@interface CKKSResultOperation()
#include <corecrypto/ccaes.h>
#include <corecrypto/ccmode_siv.h>
-#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
@implementation CKKSBaseAESSIVKey
- (instancetype)init {
if(len != CKKSWrappedKeySize) {
@throw [NSException
exceptionWithName:@"WrongKeySizeException"
- reason:[NSString stringWithFormat: @"length (%lu) was not %d", len, CKKSWrappedKeySize]
+ reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)len, CKKSWrappedKeySize]
userInfo:nil];
}
if(self = [super initWithBytes: bytes len: len]) {
if(self->size != CKKSWrappedKeySize) {
@throw [NSException
exceptionWithName:@"WrongKeySizeException"
- reason:[NSString stringWithFormat: @"length (%lu) was not %d", self->size, CKKSWrappedKeySize]
+ reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)self->size, CKKSWrappedKeySize]
userInfo:nil];
}
}
if(len != CKKSKeySize) {
@throw [NSException
exceptionWithName:@"WrongKeySizeException"
- reason:[NSString stringWithFormat: @"length (%lu) was not %d", len, CKKSKeySize]
+ reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)len, CKKSKeySize]
userInfo:nil];
}
if(self = [super initWithBytes: bytes len: len]) {
if(self->size != CKKSKeySize) {
@throw [NSException
exceptionWithName:@"WrongKeySizeException"
- reason:[NSString stringWithFormat: @"length (%lu) was not %d", self->size, CKKSKeySize]
+ reason:[NSString stringWithFormat: @"length (%lu) was not %d", (unsigned long)self->size, CKKSKeySize]
userInfo:nil];
}
}
// 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);
+ ckksnotice("ckksscan", ckks, "keychain missing %lu items from mirror, proceeding with queue scanning", (unsigned long)mirrorUUIDs.count);
[mirrorUUIDs minusSet:[NSSet setWithArray:[CKKSIncomingQueueEntry allUUIDs:ckks.zoneID error:&error]]];
if (error) {
ckkserror("ckksscan", ckks, "unable to inspect incoming queue: %@", error);
}
if (mirrorUUIDs.count > 0) {
- ckkserror("ckksscan", ckks, "BUG: keychain missing %lu items from mirror and/or queues: %@", mirrorUUIDs.count, mirrorUUIDs);
+ ckkserror("ckksscan", ckks, "BUG: keychain missing %lu items from mirror and/or queues: %@", (unsigned long)mirrorUUIDs.count, mirrorUUIDs);
self.missingLocalItemsFound = mirrorUUIDs.count;
[[CKKSAnalytics logger] logMetric:[NSNumber numberWithUnsignedInteger:mirrorUUIDs.count] withName:CKKSEventMissingLocalItemsFound];
#import "CKKSFetchAllRecordZoneChangesOperation.h"
#import "CKKSScanLocalItemsOperation.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#if OCTAGON
[self dependOnBeforeGroupFinished:outgoingOp];
// Step 2
- CKKSFetchAllRecordZoneChangesOperation* fetchOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks
- fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync]
- ckoperationGroup:operationGroup];
+ CKKSFetchAllRecordZoneChangesOperation* fetchOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithContainer:ckks.container
+ fetchClass:ckks.fetchRecordZoneChangesOperationClass
+ clients:@[ckks]
+ fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync]
+ apnsPushes:nil
+ forceResync:true
+ ckoperationGroup:operationGroup];
fetchOp.name = [NSString stringWithFormat: @"resync-step%u-fetch", self.restartCount * steps + 2];
[fetchOp addSuccessDependency: outgoingOp];
[self runBeforeGroupFinished: fetchOp];
// Now, get serious:
// Step 4
- CKKSFetchAllRecordZoneChangesOperation* fetchAllOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks
- fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync]
- ckoperationGroup:operationGroup];
+ CKKSFetchAllRecordZoneChangesOperation* fetchAllOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithContainer:ckks.container
+ fetchClass:ckks.fetchRecordZoneChangesOperationClass
+ clients:@[ckks]
+ fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync]
+ apnsPushes:nil
+ forceResync:true
+ ckoperationGroup:operationGroup];
fetchAllOp.resync = true;
fetchAllOp.name = [NSString stringWithFormat: @"resync-step%u-fetchAll", self.restartCount * steps + 4];
[fetchAllOp addSuccessDependency: incomingOp];
#import "keychain/ckks/CKKSTLKShare.h"
#import "keychain/ckks/CKKSPeer.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import <SecurityFoundation/SFKey.h>
#import <SecurityFoundation/SFEncryptionOperation.h>
#import "keychain/ckks/CKKSUpdateCurrentItemPointerOperation.h"
#import "keychain/ckks/CKKSManifest.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#include <securityd/SecItemServer.h>
#include <securityd/SecItemSchema.h>
self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave.allValues recordIDsToDelete:nil];
self.modifyRecordsOperation.atomic = TRUE;
- self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUserInitiated; // We're likely rolling a PCS identity, or creating a new one. User cares.
+ // We're likely rolling a PCS identity, or creating a new one. User cares.
+ self.modifyRecordsOperation.configuration.automaticallyRetryNetworkFailures = NO;
+ self.modifyRecordsOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+
self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged;
self.modifyRecordsOperation.group = self.ckoperationGroup;
#import "keychain/ckks/CKKSPeer.h"
#import "keychain/ckks/CKKSRateLimiter.h"
#import "keychain/ckks/CloudKitDependencies.h"
+#import "keychain/ckks/CKKSZoneChangeFetcher.h"
#import "keychain/ot/OTDefines.h"
NS_ASSUME_NONNULL_BEGIN
@property CKKSCKAccountStateTracker* accountTracker;
@property CKKSLockStateTracker* lockStateTracker;
@property CKKSReachabilityTracker *reachabilityTracker;
+@property CKKSZoneChangeFetcher* zoneChangeFetcher;
@property bool initializeNewZones;
// Signaled when SecCKKSInitialize is complete, as it's async and likes to fire after tests are complete
#import "keychain/ckks/CKKSNotifier.h"
#import "keychain/ckks/CKKSCondition.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import "keychain/ot/OTDefines.h"
[_lockStateTracker addLockStateObserver:self];
_reachabilityTracker = [[CKKSReachabilityTracker alloc] init];
+ _zoneChangeFetcher = [[CKKSZoneChangeFetcher alloc] initWithContainer:_container
+ fetchClass:fetchRecordZoneChangesOperationClass
+ reachabilityTracker:_reachabilityTracker];
+
_operationQueue = [[NSOperationQueue alloc] init];
// Backwards from how we'd like, but it's the best way to have weak pointers to CKKSPeerUpdateListener.
[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;
+ /* only synced recently if between [0...7, ie withing 7 days */
+ BOOL syncedClassARecently = fuzzyDaysSinceClassASync >= 0 && fuzzyDaysSinceClassASync < 7;
+ BOOL syncedClassCRecently = fuzzyDaysSinceClassCSync >= 0 && fuzzyDaysSinceClassCSync < 7;
BOOL incomingQueueIsErrorFree = view.lastIncomingQueueOperation.error == nil;
BOOL outgoingQueueIsErrorFree = view.lastOutgoingQueueOperation.error == nil;
accountTracker: self.accountTracker
lockStateTracker: self.lockStateTracker
reachabilityTracker: self.reachabilityTracker
+ changeFetcher:self.zoneChangeFetcher
savedTLKNotifier: self.savedTLKNotifier
peerProvider:self
fetchRecordZoneChangesOperationClass: self.fetchRecordZoneChangesOperationClass
CKKSKeychainView* view = [self findView: keyViewName];
if(!SecCKKSTestDisableKeyNotifications()) {
- ckksnotice("ckks", view, "Potential new key material from %@ (source %lu)", keyViewName, txionSource);
+ ckksnotice("ckks", view, "Potential new key material from %@ (source %lu)",
+ keyViewName, (unsigned long)txionSource);
[view keyStateMachineRequestProcess];
} else {
- ckksnotice("ckks", view, "Ignoring potential new key material from %@ (source %lu)", keyViewName, txionSource);
+ ckksnotice("ckks", view, "Ignoring potential new key material from %@ (source %lu)",
+ keyViewName, (unsigned long)txionSource);
}
return;
}
secnotice("ckks", "Received a %@ request for all zones: %@", opName, actualViews);
}
}
+ actualViews = [actualViews sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"zoneName" ascending:YES]]];
return actualViews;
}
[self.operationQueue addOperation: op];
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void)rpcResetCloudKit:(NSString*)viewName reply: (void(^)(NSError* result)) reply {
+ [self rpcResetCloudKit:viewName reason:@"unknown" reply:reply];
+}
+#pragma clang diagnostic pop
+
+- (void)rpcResetCloudKit:(NSString*)viewName reason:(NSString *)reason reply:(void(^)(NSError* result)) reply {
NSError* localError = nil;
NSArray* actualViews = [self views:viewName operation:@"CloudKit reset" error:&localError];
if(localError) {
}];
for(CKKSKeychainView* view in actualViews) {
- ckksnotice("ckksreset", view, "Beginning CloudKit reset for %@", view);
- [op addSuccessDependency:[view resetCloudKitZone:[CKOperationGroup CKKSGroupWithName:@"api-reset"]]];
+ NSString *operationGroupName = [NSString stringWithFormat:@"api-reset-%@", reason];
+ ckksnotice("ckksreset", view, "Beginning CloudKit reset for %@: %@", view, reason);
+ [op addSuccessDependency:[view resetCloudKitZone:[CKOperationGroup CKKSGroupWithName:operationGroupName]]];
}
[op timeout:120*NSEC_PER_SEC];
#import "CloudKitDependencies.h"
#import "keychain/ckks/CKKSCKAccountStateTracker.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import <CloudKit/CloudKit.h>
#import <CloudKit/CloudKit_Private.h>
self.zoneCreated = zoneCreated;
self.zoneSubscribed = zoneSubscribed;
- // Zone setups and teardowns are due to either 1) first CKKS launch or 2) the user logging in to iCloud.
- // Therefore, they're QoS UserInitiated.
- self.zoneSetupOperation.queuePriority = NSOperationQueuePriorityNormal;
- self.zoneSetupOperation.qualityOfService = NSQualityOfServiceUserInitiated;
-
ckksnotice("ckkszone", self, "Setting up zone %@", self.zoneName);
__weak __typeof(self) weakSelf = self;
if(!zoneCreated) {
ckksnotice("ckkszone", strongSelf, "Creating CloudKit zone '%@'", strongSelf.zoneName);
CKDatabaseOperation<CKKSModifyRecordZonesOperation>* zoneCreationOperation = [[strongSelf.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave: @[strongSelf.zone] recordZoneIDsToDelete: nil];
- zoneCreationOperation.queuePriority = NSOperationQueuePriorityNormal;
- zoneCreationOperation.qualityOfService = NSQualityOfServiceUserInitiated;
+ zoneCreationOperation.configuration.automaticallyRetryNetworkFailures = NO;
+ zoneCreationOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
zoneCreationOperation.database = strongSelf.database;
zoneCreationOperation.name = @"zone-creation-operation";
zoneCreationOperation.group = strongSelf.zoneSetupOperationGroup ?: [CKOperationGroup CKKSGroupWithName:@"zone-creation"];;
};
if (strongSelf.zoneCreateNetworkFailure) {
- [zoneCreationOperation addNullableDependency:reachabilityTracker.reachablityDependency];
+ [zoneCreationOperation addNullableDependency:reachabilityTracker.reachabilityDependency];
strongSelf.zoneCreateNetworkFailure = false;
}
ckksnotice("ckkszone", strongSelf, "Adding CKKSModifyRecordZonesOperation: %@ %@", zoneCreationOperation, zoneCreationOperation.dependencies);
CKDatabaseOperation<CKKSModifySubscriptionsOperation>* zoneSubscriptionOperation = [[strongSelf.modifySubscriptionsOperationClass alloc] initWithSubscriptionsToSave: @[subscription] subscriptionIDsToDelete: nil];
- zoneSubscriptionOperation.queuePriority = NSOperationQueuePriorityNormal;
- zoneSubscriptionOperation.qualityOfService = NSQualityOfServiceUserInitiated;
+ zoneSubscriptionOperation.configuration.automaticallyRetryNetworkFailures = NO;
+ zoneSubscriptionOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
zoneSubscriptionOperation.database = strongSelf.database;
zoneSubscriptionOperation.name = @"zone-subscription-operation";
};
if (strongSelf.zoneSubscriptionNetworkFailure) {
- [zoneSubscriptionOperation addNullableDependency:reachabilityTracker.reachablityDependency];
+ [zoneSubscriptionOperation addNullableDependency:reachabilityTracker.reachabilityDependency];
strongSelf.zoneSubscriptionNetworkFailure = false;
}
[zoneSubscriptionOperation addNullableDependency:modifyRecordZonesCompleteOperation];
// Step 2: Try to delete the zone
CKDatabaseOperation<CKKSModifyRecordZonesOperation>* zoneDeletionOperation = [[self.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave: nil recordZoneIDsToDelete: @[self.zoneID]];
- zoneDeletionOperation.queuePriority = NSOperationQueuePriorityNormal;
- zoneDeletionOperation.qualityOfService = NSQualityOfServiceUserInitiated;
+ zoneDeletionOperation.configuration.automaticallyRetryNetworkFailures = NO;
+ zoneDeletionOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
zoneDeletionOperation.database = self.database;
zoneDeletionOperation.group = ckoperationGroup;
#import <CloudKit/CloudKit.h>
#import <Foundation/Foundation.h>
#import "keychain/ckks/CKKSResultOperation.h"
+#import "keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h"
NS_ASSUME_NONNULL_BEGIN
-/* Fetch Reasons */
-@protocol SecCKKSFetchBecause <NSObject>
-@end
-typedef NSString<SecCKKSFetchBecause> CKKSFetchBecause;
-extern CKKSFetchBecause* const CKKSFetchBecauseAPNS;
-extern CKKSFetchBecause* const CKKSFetchBecauseAPIFetchRequest;
-extern CKKSFetchBecause* const CKKSFetchBecauseCurrentItemFetchRequest;
-extern CKKSFetchBecause* const CKKSFetchBecauseInitialStart;
-extern CKKSFetchBecause* const CKKSFetchBecauseSecuritydRestart;
-extern CKKSFetchBecause* const CKKSFetchBecausePreviousFetchFailed;
-extern CKKSFetchBecause* const CKKSFetchBecauseKeyHierarchy;
-extern CKKSFetchBecause* const CKKSFetchBecauseTesting;
-extern CKKSFetchBecause* const CKKSFetchBecauseResync;
-
-@protocol CKKSChangeFetcherErrorOracle <NSObject>
-- (bool)isFatalCKFetchError:(NSError*)error;
-@end
-
/*
* This class implements a CloudKit-fetch-with-retry.
* In the case of network or other failures, it'll issue retries.
*/
@class CKKSKeychainView;
+@class CKKSReachabilityTracker;
+@class CKKSNearFutureScheduler;
@interface CKKSZoneChangeFetcher : NSObject
+@property (readonly) Class<CKKSFetchRecordZoneChangesOperation> fetchRecordZoneChangesOperationClass;
+@property (readonly) CKContainer* container;
+@property CKKSReachabilityTracker* reachabilityTracker;
-@property (nullable, weak) CKKSKeychainView* ckks;
@property (readonly) NSError* lastCKFetchError;
-@property CKRecordZoneID* zoneID;
- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks;
+- (instancetype)initWithContainer:(CKContainer*)container
+ fetchClass:(Class<CKKSFetchRecordZoneChangesOperation>)fetchRecordsOperationClass
+ reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker;
+
+- (void)registerClient:(id<CKKSChangeFetcherClient>)client;
- (CKKSResultOperation*)requestSuccessfulFetch:(CKKSFetchBecause*)why;
-- (CKKSResultOperation*)requestSuccessfulResyncFetch:(CKKSFetchBecause*)why;
+- (CKKSResultOperation*)requestSuccessfulFetchForManyReasons:(NSSet<CKKSFetchBecause*>*)why;
+- (CKKSResultOperation*)requestSuccessfulFetchDueToAPNS:(CKRecordZoneNotification*)notification;
// We don't particularly care what this does, as long as it finishes
- (void)holdFetchesUntil:(CKKSResultOperation* _Nullable)holdOperation;
- (void)cancel;
+
+// I don't recommend using these unless you're a test.
+@property CKKSNearFutureScheduler* fetchScheduler;
@end
NS_ASSUME_NONNULL_END
#import "keychain/ckks/CKKSKeychainView.h"
#import "keychain/ckks/CKKSNearFutureScheduler.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/ckks/CKKSReachabilityTracker.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
CKKSFetchBecause* const CKKSFetchBecauseAPNS = (CKKSFetchBecause*) @"apns";
CKKSFetchBecause* const CKKSFetchBecauseAPIFetchRequest = (CKKSFetchBecause*) @"api";
#pragma mark - CKKSZoneChangeFetchDependencyOperation
@interface CKKSZoneChangeFetchDependencyOperation : CKKSResultOperation
@property CKKSZoneChangeFetcher* owner;
+@property NSMutableArray<CKKSZoneChangeFetchDependencyOperation*>* chainDependents;
+- (void)chainDependency:(CKKSZoneChangeFetchDependencyOperation*)newDependency;
@end
@implementation CKKSZoneChangeFetchDependencyOperation
+- (instancetype)init {
+ if((self = [super init])) {
+ _chainDependents = [NSMutableArray array];
+ }
+ return self;
+}
+
- (NSError* _Nullable)descriptionError {
return [NSError errorWithDomain:CKKSResultDescriptionErrorDomain
code:CKKSResultDescriptionPendingSuccessfulFetch
description:@"Fetch failed"
underlying:self.owner.lastCKFetchError];
}
+
+- (void)chainDependency:(CKKSZoneChangeFetchDependencyOperation*)newDependency {
+ [self addSuccessDependency:newDependency];
+
+ // There's no need to build a chain more than two links long. Move all our children up to depend on the new dependency.
+ for(CKKSZoneChangeFetchDependencyOperation* op in self.chainDependents) {
+ [newDependency.chainDependents addObject:op];
+ [op addSuccessDependency:newDependency];
+ [op removeDependency:self];
+ }
+ [self.chainDependents removeAllObjects];
+}
@end
#pragma mark - CKKSZoneChangeFetcher
@interface CKKSZoneChangeFetcher ()
@property NSString* name;
+@property NSOperationQueue* operationQueue;
@property dispatch_queue_t queue;
@property NSError* lastCKFetchError;
+@property NSMapTable<CKRecordZoneID*, id<CKKSChangeFetcherClient>>* clientMap;
+
@property CKKSFetchAllRecordZoneChangesOperation* currentFetch;
@property CKKSResultOperation* currentProcessResult;
@property NSMutableSet<CKKSFetchBecause*>* currentFetchReasons;
+@property NSMutableSet<CKRecordZoneNotification*>* apnsPushes;
@property bool newRequests; // true if there's someone pending on successfulFetchDependency
-@property bool newResyncRequests; // true if someone asked for a refetch operation
-@property CKKSResultOperation* successfulFetchDependency;
-
-@property CKKSNearFutureScheduler* fetchScheduler;
+@property CKKSZoneChangeFetchDependencyOperation* successfulFetchDependency;
@property CKKSResultOperation* holdOperation;
@end
@implementation CKKSZoneChangeFetcher
-- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks {
+- (instancetype)initWithContainer:(CKContainer*)container
+ fetchClass:(Class<CKKSFetchRecordZoneChangesOperation>)fetchRecordZoneChangesOperationClass
+ reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker
+{
if((self = [super init])) {
- _ckks = ckks;
- _zoneID = ckks.zoneID;
+ _container = container;
+ _fetchRecordZoneChangesOperationClass = fetchRecordZoneChangesOperationClass;
+ _reachabilityTracker = reachabilityTracker;
_currentFetchReasons = [[NSMutableSet alloc] init];
+ _apnsPushes = [[NSMutableSet alloc] init];
+
+ _clientMap = [NSMapTable strongToWeakObjectsMapTable];
- _name = [NSString stringWithFormat:@"zone-change-fetcher-%@", _zoneID.zoneName];
+ _name = @"zone-change-fetcher";
_queue = dispatch_queue_create([_name UTF8String], DISPATCH_QUEUE_SERIAL);
+ _operationQueue = [[NSOperationQueue alloc] init];
_successfulFetchDependency = [self createSuccesfulFetchDependency];
_newRequests = false;
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]
+ _fetchScheduler = [[CKKSNearFutureScheduler alloc] initWithName:@"zone-change-fetch-scheduler"
initialDelay:initialDelay
continuingDelay:continuingDelay
keepProcessAlive:false
}
}
+- (void)registerClient:(id<CKKSChangeFetcherClient>)client
+{
+ @synchronized(self.clientMap) {
+ [self.clientMap setObject:client forKey:client.zoneID];
+ }
+}
+
+
- (CKKSResultOperation*)requestSuccessfulFetch:(CKKSFetchBecause*)why {
- return [self requestSuccessfulFetch:why resync:false];
+ return [self requestSuccessfulFetchForManyReasons:[NSSet setWithObject:why]];
+}
+
+- (CKKSResultOperation*)requestSuccessfulFetchForManyReasons:(NSSet<CKKSFetchBecause*>*)why
+{
+ return [self requestSuccessfulFetchForManyReasons:why apns:nil];
}
-- (CKKSResultOperation*)requestSuccessfulResyncFetch:(CKKSFetchBecause*)why {
- return [self requestSuccessfulFetch:why resync:true];
+- (CKKSResultOperation*)requestSuccessfulFetchDueToAPNS:(CKRecordZoneNotification*)notification
+{
+ return [self requestSuccessfulFetchForManyReasons:[NSSet setWithObject:CKKSFetchBecauseAPNS] apns:notification];
}
-- (CKKSResultOperation*)requestSuccessfulFetch:(CKKSFetchBecause*)why resync:(bool)resync {
+- (CKKSResultOperation*)requestSuccessfulFetchForManyReasons:(NSSet<CKKSFetchBecause*>*)why apns:(CKRecordZoneNotification*)notification
+{
__block CKKSResultOperation* dependency = nil;
dispatch_sync(self.queue, ^{
dependency = self.successfulFetchDependency;
self.newRequests = true;
- self.newResyncRequests |= resync;
- [self.currentFetchReasons addObject: why];
+ [self.currentFetchReasons unionSet:why];
+ if(notification) {
+ [self.apnsPushes addObject:notification];
+
+ if(notification.ckksPushTracingEnabled) {
+ // Report that we saw this notification before doing anything else
+ secnotice("ckksfetch", "Submitting initial CKEventMetric due to notification %@", notification);
+
+ CKEventMetric *metric = [[CKEventMetric alloc] initWithEventName:@"APNSPushMetrics"];
+ metric.isPushTriggerFired = true;
+ metric[@"push_token_uuid"] = notification.ckksPushTracingUUID;
+ metric[@"push_received_date"] = notification.ckksPushReceivedDate;
+ metric[@"push_event_name"] = @"CKKS APNS Push Received";
+
+ [self.container submitEventMetric:metric];
+ }
+
+ }
[self.fetchScheduler trigger];
});
__weak __typeof(self) weakSelf = self;
- CKKSResultOperation* dependency = self.successfulFetchDependency;
-
- CKKSKeychainView* ckks = self.ckks; // take a strong reference
- if(!ckks) {
- secerror("ckksfetcher: received a null CKKSKeychainView pointer; strange.");
- return;
- }
+ CKKSZoneChangeFetchDependencyOperation* dependency = self.successfulFetchDependency;
- ckksnotice("ckksfetcher", self.zoneID, "Starting a new fetch for %@", self.zoneID.zoneName);
+ secnotice("ckksfetcher", "Starting a new fetch");
NSMutableSet<CKKSFetchBecause*>* lastFetchReasons = self.currentFetchReasons;
self.currentFetchReasons = [[NSMutableSet alloc] init];
- if(self.newResyncRequests) {
- [lastFetchReasons addObject:CKKSFetchBecauseResync];
- }
+
+ NSMutableSet<CKRecordZoneNotification*>* lastAPNSPushes = self.apnsPushes;
+ self.apnsPushes = [[NSMutableSet alloc] init];
CKOperationGroup* operationGroup = [CKOperationGroup CKKSGroupWithName: [[lastFetchReasons sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES]]] componentsJoinedByString:@","]];
- CKKSFetchAllRecordZoneChangesOperation* fetchAllChanges = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks
- fetchReasons:lastFetchReasons
- ckoperationGroup:operationGroup];
+ NSMutableArray<id<CKKSChangeFetcherClient>>* clients = [NSMutableArray array];
+ @synchronized(self.clientMap) {
+ for(id<CKKSChangeFetcherClient> client in [self.clientMap objectEnumerator]) {
+ if(client != nil) {
+ [clients addObject:client];
+ }
+ }
+ }
+
+ if(clients.count == 0u) {
+ // Nothing to do, really.
+ }
+
+ CKKSFetchAllRecordZoneChangesOperation* fetchAllChanges = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithContainer:self.container
+ fetchClass:self.fetchRecordZoneChangesOperationClass
+ clients:clients
+ fetchReasons:lastFetchReasons
+ apnsPushes:lastAPNSPushes
+ forceResync:false
+ ckoperationGroup:operationGroup];
+
if ([lastFetchReasons containsObject:CKKSFetchBecauseNetwork]) {
- [fetchAllChanges addNullableDependency: ckks.reachabilityTracker.reachablityDependency]; // wait on network, if its unavailable
+ [fetchAllChanges addNullableDependency: self.reachabilityTracker.reachabilityDependency]; // wait on network, if its unavailable
}
[fetchAllChanges addNullableDependency: self.holdOperation];
- fetchAllChanges.resync = self.newResyncRequests;
- self.newResyncRequests = false;
-
- // Can't fetch until the zone is setup.
- [fetchAllChanges addNullableDependency:ckks.zoneSetupOperation];
self.currentProcessResult = [CKKSResultOperation operationWithBlock: ^{
__strong __typeof(self) strongSelf = weakSelf;
return;
}
- CKKSKeychainView* blockckks = strongSelf.ckks; // take a strong reference
- if(!blockckks) {
- secerror("ckksfetcher: Received a null CKKSKeychainView pointer; strange.");
- return;
- }
-
dispatch_sync(strongSelf.queue, ^{
self.lastCKFetchError = fetchAllChanges.error;
if(!fetchAllChanges.error) {
// success! notify the listeners.
- [blockckks scheduleOperation: dependency];
+ [self.operationQueue addOperation: dependency];
// Did new people show up and want another fetch?
if(strongSelf.newRequests) {
}
} else {
// The operation errored. Chain the dependency on the current one...
- [dependency addSuccessDependency: strongSelf.successfulFetchDependency];
- [blockckks scheduleOperation: dependency];
+ [dependency chainDependency:strongSelf.successfulFetchDependency];
+ [strongSelf.operationQueue addOperation: dependency];
+
+ // Check in with clients: should we keep fetching for them?
+ bool attemptAnotherFetch = false;
+ @synchronized(self.clientMap) {
+ for(CKRecordZoneID* zoneID in fetchAllChanges.fetchedZoneIDs) {
+ id<CKKSChangeFetcherClient> client = [self.clientMap objectForKey:zoneID];
+ if(client) {
+ attemptAnotherFetch |= [client notifyFetchError:fetchAllChanges.error];
+ }
+ }
+ }
- if([blockckks isFatalCKFetchError: fetchAllChanges.error]) {
- ckkserror("ckksfetcher", strongSelf.zoneID, "Notified that %@ is a fatal error. Not restarting fetch.", fetchAllChanges.error);
+ if(!attemptAnotherFetch) {
+ secerror("ckksfetcher: All clients thought %@ is a fatal error. Not restarting fetch.", fetchAllChanges.error);
return;
}
-
// And in a bit, try the fetch again.
NSNumber* delaySeconds = fetchAllChanges.error.userInfo[CKErrorRetryAfterKey];
if([fetchAllChanges.error.domain isEqual: CKErrorDomain] && delaySeconds) {
- ckksnotice("ckksfetcher", strongSelf.zoneID, "Fetch failed with rate-limiting error, restarting in %@ seconds: %@", delaySeconds, fetchAllChanges.error);
+ secnotice("ckksfetcher", "Fetch failed with rate-limiting error, restarting in %@ seconds: %@", delaySeconds, fetchAllChanges.error);
[strongSelf.fetchScheduler waitUntil: NSEC_PER_SEC * [delaySeconds unsignedLongValue]];
} else {
- ckksnotice("ckksfetcher", strongSelf.zoneID, "Fetch failed with error, restarting soon: %@", fetchAllChanges.error);
+ secnotice("ckksfetcher", "Fetch failed with error, restarting soon: %@", fetchAllChanges.error);
}
// Add the failed fetch reasons to the new fetch reasons
[strongSelf.currentFetchReasons unionSet:lastFetchReasons];
+ [strongSelf.apnsPushes unionSet:lastAPNSPushes];
+
// If its a network error, make next try depend on network availability
- if ([blockckks.reachabilityTracker isNetworkError:fetchAllChanges.error]) {
+ if ([self.reachabilityTracker isNetworkError:fetchAllChanges.error]) {
[strongSelf.currentFetchReasons addObject:CKKSFetchBecauseNetwork];
} else {
[strongSelf.currentFetchReasons addObject:CKKSFetchBecausePreviousFetchFailed];
}
strongSelf.newRequests = true;
- strongSelf.newResyncRequests |= fetchAllChanges.resync;
[strongSelf.fetchScheduler trigger];
}
});
self.currentProcessResult.name = @"zone-change-fetcher-worker";
[self.currentProcessResult addDependency: fetchAllChanges];
- [ckks scheduleOperation: self.currentProcessResult];
+ [self.operationQueue addOperation:self.currentProcessResult];
self.currentFetch = fetchAllChanges;
- [ckks scheduleOperation: self.currentFetch];
+ [self.operationQueue addOperation:self.currentFetch];
// creata a new fetch dependency, for all those who come in while this operation is executing
self.newRequests = false;
-(CKKSZoneChangeFetchDependencyOperation*)createSuccesfulFetchDependency {
CKKSZoneChangeFetchDependencyOperation* dep = [[CKKSZoneChangeFetchDependencyOperation alloc] init];
- __weak __typeof(dep) weakDep = dep;
-
- // Since these dependencies might chain, when one runs, break the chain.
- [dep addExecutionBlock:^{
- __strong __typeof(dep) strongDep = weakDep;
- // Remove all dependencies
- NSArray* deps = [strongDep.dependencies copy];
- for(NSOperation* op in deps) {
- [strongDep removeDependency: op];
- }
- }];
dep.name = @"successful-fetch-dependency";
dep.descriptionErrorCode = CKKSResultDescriptionPendingSuccessfulFetch;
dep.owner = self;
return @{@"ckzone": self.ckzone};
}
-- (NSDictionary<NSString*,NSString*>*) sqlValues {
+- (NSDictionary<NSString*,id>*) sqlValues {
NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init];
return @{@"ckzone": self.ckzone,
@end
@interface NSError (CKKS)
-
-// More useful constructor
-+ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description;
-
-+ (instancetype)errorWithDomain:(NSErrorDomain)domain
- code:(NSInteger)code
- description:(NSString*)description
- underlying:(NSError* _Nullable)underlying;
-
// Returns true if this is a CloudKit error where
// 1) An atomic write failed
// 2) Every single suberror is either CKErrorServerRecordChanged or CKErrorUnknownItem
- (bool)ckksIsCKErrorRecordChangedError;
@end
-
// Ensure we don't print addresses
@interface CKAccountInfo (CKKS)
- (NSString*)description;
@implementation NSError (CKKS)
-+ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description {
- return [NSError errorWithDomain:domain code:code description:description underlying:nil];
-}
-
-+ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code description:(NSString*)description underlying:(NSError*)underlying {
- // Obj-C throws a fit if there's nulls in dictionaries, so we can't use a dictionary literal here.
- // Use the null-assignment semantics of NSMutableDictionary to make a dictionary either with either, both, or neither key.
- NSMutableDictionary* mut = [[NSMutableDictionary alloc] init];
- mut[NSLocalizedDescriptionKey] = description;
- mut[NSUnderlyingErrorKey] = underlying;
-
- return [NSError errorWithDomain:domain code:code userInfo:mut];
-}
-
-(bool) ckksIsCKErrorRecordChangedError {
NSDictionary<CKRecordID*,NSError*>* partialErrors = self.userInfo[CKPartialErrorsByItemIDKey];
if([self.domain isEqualToString:CKErrorDomain] && self.code == CKErrorPartialFailure && partialErrors) {
@property NSOperationQueuePriority queuePriority;
@property NSQualityOfService qualityOfService;
@property (nonatomic, strong, nullable) CKOperationGroup* group;
+@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration;
@property (nonatomic, copy, nullable) void (^modifyRecordZonesCompletionBlock)
(NSArray<CKRecordZone*>* _Nullable savedRecordZones, NSArray<CKRecordZoneID*>* _Nullable deletedRecordZoneIDs, NSError* _Nullable operationError);
@property NSOperationQueuePriority queuePriority;
@property NSQualityOfService qualityOfService;
@property (nonatomic, strong, nullable) CKOperationGroup* group;
+@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration;
@property (nonatomic, copy, nullable) void (^modifySubscriptionsCompletionBlock)
(NSArray<CKSubscription*>* _Nullable savedSubscriptions, NSArray<NSString*>* _Nullable deletedSubscriptionIDs, NSError* _Nullable operationError);
@protocol CKKSFetchRecordZoneChangesOperation <NSObject>
+ (instancetype)alloc;
- (instancetype)initWithRecordZoneIDs:(NSArray<CKRecordZoneID*>*)recordZoneIDs
- optionsByRecordZoneID:(nullable NSDictionary<CKRecordZoneID*, CKFetchRecordZoneChangesOptions*>*)optionsByRecordZoneID;
+ configurationsByRecordZoneID:(nullable NSDictionary<CKRecordZoneID*, CKFetchRecordZoneChangesConfiguration*>*)configurationsByRecordZoneID;
+@property (nonatomic, strong, nullable) CKDatabase *database;
@property (nonatomic, copy, nullable) NSArray<CKRecordZoneID*>* recordZoneIDs;
-@property (nonatomic, copy, nullable) NSDictionary<CKRecordZoneID*, CKFetchRecordZoneChangesOptions*>* optionsByRecordZoneID;
+@property (nonatomic, copy, nullable) NSDictionary<CKRecordZoneID*, CKFetchRecordZoneChangesConfiguration*>* configurationsByRecordZoneID;
@property (nonatomic, assign) BOOL fetchAllChanges;
@property (nonatomic, copy, nullable) void (^recordChangedBlock)(CKRecord* record);
@property (nonatomic, copy, nullable) void (^fetchRecordZoneChangesCompletionBlock)(NSError* _Nullable operationError);
@property (nonatomic, strong, nullable) CKOperationGroup* group;
+@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration;
+
+@property (nonatomic, copy) NSString *operationID;
+@property (nonatomic, readonly, strong, nullable) CKOperationConfiguration *resolvedConfiguration;
@end
@interface CKFetchRecordZoneChangesOperation () <CKKSFetchRecordZoneChangesOperation>
-;
@end
/* CKFetchRecordsOperation */
- (instancetype)init;
- (instancetype)initWithRecordIDs:(NSArray<CKRecordID*>*)recordIDs;
+@property (nonatomic, strong, nullable) CKDatabase *database;
@property (nonatomic, copy, nullable) NSArray<CKRecordID*>* recordIDs;
@property (nonatomic, copy, nullable) NSArray<NSString*>* desiredKeys;
@property (nonatomic, copy, nullable) CKOperationConfiguration* configuration;
<!-- Load config stored in this MobileAsset (ignored if inited with config or plist directly) -->
<key>MAType</key>
<string></string>
- <!-- Use this property for AWD's topWriters metric -->
- <key>topOffendersPropertyIndex</key>
- <integer></integer>
</dict>
<!-- Each property you want to ratelimit on must have its own group dictionary -->
<key>groups</key>
#import "sec_action.h"
#import <CoreFoundation/CFPreferences.h> // For clarity. Also included in debugging.h
-#if !TARGET_OS_BRIDGE
-#import <WirelessDiagnostics/WirelessDiagnostics.h>
-#import "keychain/analytics/awd/AWDMetricIds_Keychain.h"
-#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterOverload.h"
-#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.h"
-#import "keychain/analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h"
-#endif
-
@interface RateLimiter()
@property (readwrite, nonatomic) NSDictionary *config;
@property (nonatomic) NSArray<NSMutableDictionary<NSString *, NSDate *> *> *groups;
@property (nonatomic) NSDate *lastJudgment;
@property (nonatomic) NSDate *overloadUntil;
@property (nonatomic) NSString *assetType;
-#if !TARGET_OS_BRIDGE
-@property (nonatomic) NSMutableArray<NSNumber *> *badnessData;
-@property (nonatomic) AWDServerConnection *awdConnection;
-#endif
@end
@implementation RateLimiter
_config = config;
_assetType = nil;
[self reset];
- [self setUpAwdMetrics];
}
return self;
}
}
_assetType = nil;
[self reset];
- [self setUpAwdMetrics];
}
return self;
}
_overloadUntil = [coder decodeObjectOfClass:[NSDate class] forKey:@"RLoverLoadedUntil"];
_lastJudgment = [coder decodeObjectOfClass:[NSDate class] forKey:@"RLlastJudgment"];
_assetType = [coder decodeObjectOfClass:[NSString class] forKey:@"RLassetType"];
-#if !TARGET_OS_BRIDGE
- _badnessData = [coder decodeObjectOfClasses:[NSSet setWithObjects: [NSArray class],
- [NSNumber class],
- nil]
- forKey:@"RLbadnessData"];
-#endif
if (!_assetType) {
// This list of types might be wrong. Be careful.
_config = [coder decodeObjectOfClasses:[NSSet setWithObjects: [NSMutableArray class],
nil]
forKey:@"RLconfig"];
}
- [self setUpAwdMetrics];
}
return self;
}
}
if (badness != RateLimiterBadnessClear) {
-#if !TARGET_OS_BRIDGE
- self.badnessData[badness] = @(self.badnessData[badness].intValue + 1);
-#endif
return badness;
}
}
}
-#if !TARGET_OS_BRIDGE
- self.badnessData[badness] = @(self.badnessData[badness].intValue + 1);
-#endif
*limitTime = badness == RateLimiterBadnessClear ? nil : resultTime;
self.lastJudgment = time;
return badness;
self.groups = newgroups;
self.lastJudgment = [NSDate distantPast]; // will cause extraneous trim on first judgment but on empty groups
self.overloadUntil = nil;
-#if !TARGET_OS_BRIDGE
- // Corresponds to the number of RateLimiterBadness enum values
- self.badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, nil];
-#endif
}
- (void)trim:(NSDate *)time {
(unsigned long)[self stateSize],
[self.config[@"general"][@"maxStateSize"] unsignedLongValue],
self.overloadUntil);
-#if !TARGET_OS_BRIDGE
- AWDKeychainCKKSRateLimiterOverload *metric = [AWDKeychainCKKSRateLimiterOverload new];
- metric.ratelimitertype = self.config[@"general"][@"name"];
- AWDPostMetric(AWDComponentId_Keychain, metric);
-#endif
} else {
self.overloadUntil = nil;
}
if (!_assetType) {
[coder encodeObject:_config forKey:@"RLconfig"];
}
-#if !TARGET_OS_BRIDGE
- [coder encodeObject:_badnessData forKey:@"RLbadnessData"];
-#endif
}
+ (BOOL)supportsSecureCoding {
return [[[contenders keysSortedByValueUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects];
}
-- (void)setUpAwdMetrics {
-#if !TARGET_OS_BRIDGE
- self.awdConnection = [[AWDServerConnection alloc] initWithComponentId:AWDComponentId_Keychain];
-
- [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterTopWriters callback:^(UInt32 metricId) {
- AWDKeychainCKKSRateLimiterTopWriters *metric = [AWDKeychainCKKSRateLimiterTopWriters new];
- NSArray *offenders = [self topOffenders:3];
- for (NSString *offender in offenders) {
- [metric addWriter:offender];
- }
- metric.ratelimitertype = self.config[@"general"][@"name"];
- AWDPostMetric(metricId, metric);
- }];
-
- [self.awdConnection registerQueriableMetric:AWDMetricId_Keychain_CKKSRateLimiterAggregatedScores callback:^(UInt32 metricId) {
- AWDKeychainCKKSRateLimiterAggregatedScores *metric = [AWDKeychainCKKSRateLimiterAggregatedScores new];
- for (NSNumber *num in self.badnessData) {
- [metric addData:[num unsignedIntValue]];
- }
- metric.ratelimitertype = self.config[@"general"][@"name"];
- AWDPostMetric(metricId, metric);
- // Corresponds to the number of RateLimiterBadness enum values
- self.badnessData = [[NSMutableArray alloc] initWithObjects:@0, @0, @0, @0, @0, nil];
- }];
-#endif
-}
-
@end
--- /dev/null
+/*
+ * 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 <CloudKit/CloudKit.h>
+#import <XCTest/XCTest.h>
+#import <OCMock/OCMock.h>
+#import <SecurityFoundation/SFKey.h>
+#import <SecurityFoundation/SFKey_Private.h>
+#import <SecurityFoundation/SFDigestOperation.h>
+
+#import "keychain/ckks/tests/CloudKitMockXCTest.h"
+#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h"
+#import "keychain/ckks/CKKS.h"
+#import "keychain/ckks/CKKSAPSReceiver.h"
+#import "keychain/ckks/CKKSKey.h"
+#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"
+
+#import "keychain/ckks/tests/CKKSAPSReceiverTests.h"
+
+@interface CKKSAPSHandlingTests : CloudKitKeychainSyncingTestsBase
+@property CKRecordZoneID* manateeZoneID;
+@property CKKSKeychainView* manateeView;
+@property FakeCKZone* manateeZone;
+@property (readonly) ZoneKeys* manateeZoneKeys;
+@end
+
+
+@implementation CKKSAPSHandlingTests
+// We really just want two views here
+- (NSSet*)managedViewList {
+ return [NSSet setWithObjects:@"keychain", @"Manatee", nil];
+}
+
+- (void)setUp {
+ [super setUp];
+
+ // Wait for the ViewManager to be brought up
+ XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize");
+
+ self.manateeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Manatee" ownerName:CKCurrentUserDefaultName];
+ [self.ckksZones addObject:self.manateeZoneID];
+ self.manateeZone = [[FakeCKZone alloc] initZone: self.manateeZoneID];
+ self.zones[self.manateeZoneID] = self.manateeZone;
+ self.manateeView = [[CKKSViewManager manager] findView:@"Manatee"];
+ [self.ckksViews addObject:self.manateeView];
+ XCTAssertNotNil(self.manateeView, "CKKSViewManager created the Manatee view");
+}
+
+- (void)tearDown {
+ // If the test didn't already do this, allow each zone to spin up
+ self.accountStatus = CKAccountStatusNoAccount;
+ [self startCKKSSubsystem];
+
+ [self.manateeView halt];
+ [self.manateeView waitUntilAllOperationsAreFinished];
+ self.manateeView = nil;
+
+ [super tearDown];
+}
+
+- (void)testSendPushMetricUponRequest {
+ for(CKRecordZoneID* zoneID in self.ckksZones) {
+ [self putFakeKeyHierarchyInCloudKit:zoneID];
+ [self saveTLKMaterialToKeychain:zoneID];
+ [self expectCKKSTLKSelfShareUpload:zoneID];
+ }
+
+ [self startCKKSSubsystem];
+
+ for(CKKSKeychainView* view in self.ckksViews) {
+ XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view);
+ }
+
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+
+ CKRecord* keychainRecord = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"keychain-view"];
+ [self.keychainZone addToZone: keychainRecord];
+
+ // Manatee gets one too!
+ CKRecord* manateeRecord = [self createFakeRecord:self.manateeZoneID recordName:@"7B598D31-F9C5-481E-98AC-000000000000" withAccount:@"manatee-view"];
+ [self.manateeZone addToZone:manateeRecord];
+
+ // Trigger a notification just for keychain zone. Both keychain and Manatee should process their incoming queues, and receive their items.
+ CKKSResultOperation* keychainProcessOp = [self.keychainView resultsOfNextProcessIncomingQueueOperation];
+ XCTAssertNotNil(keychainProcessOp, "Should have gotten a promise operation from Keychain");
+ CKKSResultOperation* manateeProcessOp = [self.manateeView resultsOfNextProcessIncomingQueueOperation];
+ XCTAssertNotNil(manateeProcessOp, "Should have gotten a promise operation from Manatee");
+
+ // But if something goes wrong, don't block the whole test. Only way to do that is to make more operations, since there's no guarantee that the process ops above will ever be added
+ // to a queue (and thus become 'finished')
+ CKKSResultOperation* keychainProcessTimeoutOp = [CKKSResultOperation named:@"keychain-timeout" withBlock:^{}];
+ [keychainProcessTimeoutOp timeout:20*NSEC_PER_SEC];
+ [keychainProcessTimeoutOp addSuccessDependency:keychainProcessOp];
+ [self.operationQueue addOperation:keychainProcessTimeoutOp];
+
+ CKKSResultOperation* manateeProcessTimeoutOp = [CKKSResultOperation named:@"manatee-timeout" withBlock:^{}];
+ [manateeProcessTimeoutOp timeout:20*NSEC_PER_SEC];
+ [manateeProcessTimeoutOp addSuccessDependency:manateeProcessOp];
+ [self.operationQueue addOperation:manateeProcessTimeoutOp];
+
+ APSIncomingMessage* apsMessage = [CKKSAPSReceiverTests messageForZoneID:self.keychainZoneID];
+ NSUUID* nsuuid = [NSUUID UUID];
+ uuid_t uuid = {0};
+ [nsuuid getUUIDBytes:(unsigned char*)&uuid];
+ NSData* uuidData = [NSData dataWithBytes:&uuid length:sizeof(uuid)];
+
+ apsMessage.tracingUUID = uuidData;
+ apsMessage.tracingEnabled = YES;
+
+ // Inject a message at the APS layer
+ // Because we can only make APS receivers once iCloud tells us the push environment after sign-in, we can't use our normal injection strategy, and fell back on global state.
+ CKKSAPSReceiver* apsReceiver = [CKKSAPSReceiver receiverForEnvironment:self.apsEnvironment
+ namedDelegatePort:SecCKKSAPSNamedPort
+ apsConnectionClass:[FakeAPSConnection class]];
+ XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver");
+
+ // Also, CKKS should handle this in one single fetch
+ self.silentFetchesAllowed = false;
+ [self expectCKFetch];
+
+ // Expect two metric pushes, one from receiving the push and one from after we finish the fetch
+ // AFAICT there's no way to introspect a metric object to ensure we did it right
+ OCMExpect([self.mockContainerExpectations submitEventMetric:[OCMArg any]]);
+ OCMExpect([self.mockContainerExpectations submitEventMetric:[OCMArg any]]);
+
+ // Launch!
+ [apsReceiver connection:nil didReceiveIncomingMessage:apsMessage];
+
+ OCMVerifyAllWithDelay(self.mockContainerExpectations, 16);
+
+ // Now, wait for both views to run their processing
+ [keychainProcessTimeoutOp waitUntilFinished];
+ XCTAssertNil(keychainProcessTimeoutOp.error, "Shouldn't have been any error processing incoming queue (keychain)");
+
+ [manateeProcessTimeoutOp waitUntilFinished];
+ XCTAssertNil(manateeProcessTimeoutOp.error, "Shouldn't have been any error processing incoming queue (manatee)");
+
+ [self findGenericPassword:@"keychain-view" expecting:errSecSuccess];
+ [self findGenericPassword:@"manatee-view" expecting:errSecSuccess];
+}
+
+- (void)testDoNotSendPushMetricWithoutRequest {
+ for(CKRecordZoneID* zoneID in self.ckksZones) {
+ [self putFakeKeyHierarchyInCloudKit:zoneID];
+ [self saveTLKMaterialToKeychain:zoneID];
+ [self expectCKKSTLKSelfShareUpload:zoneID];
+ }
+
+ [self startCKKSSubsystem];
+
+ for(CKKSKeychainView* view in self.ckksViews) {
+ XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view);
+ }
+
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+
+ CKRecord* keychainRecord = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"keychain-view"];
+ [self.keychainZone addToZone: keychainRecord];
+
+ // Trigger a notification just for keychain zone. Both keychain and Manatee should process their incoming queues, and receive their items.
+ CKKSResultOperation* keychainProcessOp = [self.keychainView resultsOfNextProcessIncomingQueueOperation];
+ XCTAssertNotNil(keychainProcessOp, "Should have gotten a promise operation from Keychain");
+
+ // But if something goes wrong, don't block the whole test. Only way to do that is to make more operations, since there's no guarantee that the process ops above will ever be added
+ // to a queue (and thus become 'finished')
+ CKKSResultOperation* keychainProcessTimeoutOp = [CKKSResultOperation named:@"keychain-timeout" withBlock:^{}];
+ [keychainProcessTimeoutOp timeout:20*NSEC_PER_SEC];
+ [keychainProcessTimeoutOp addSuccessDependency:keychainProcessOp];
+ [self.operationQueue addOperation:keychainProcessTimeoutOp];
+
+ APSIncomingMessage* apsMessage = [CKKSAPSReceiverTests messageForZoneID:self.keychainZoneID];
+ NSUUID* nsuuid = [NSUUID UUID];
+ uuid_t uuid = {0};
+ [nsuuid getUUIDBytes:(unsigned char*)&uuid];
+ NSData* uuidData = [NSData dataWithBytes:&uuid length:sizeof(uuid)];
+
+ apsMessage.tracingUUID = uuidData;
+ apsMessage.tracingEnabled = NO;
+
+ // Inject a message at the APS layer
+ // Because we can only make APS receivers once iCloud tells us the push environment after sign-in, we can't use our normal injection strategy, and fell back on global state.
+ CKKSAPSReceiver* apsReceiver = [CKKSAPSReceiver receiverForEnvironment:self.apsEnvironment
+ namedDelegatePort:SecCKKSAPSNamedPort
+ apsConnectionClass:[FakeAPSConnection class]];
+ XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver");
+
+ // Also, CKKS should handle this in one single fetch
+ self.silentFetchesAllowed = false;
+ [self expectCKFetch];
+
+ // Any metric push is verboten
+ OCMReject([self.mockContainerExpectations submitEventMetric:[OCMArg any]]);
+
+ // Launch!
+ [apsReceiver connection:nil didReceiveIncomingMessage:apsMessage];
+ OCMVerifyAllWithDelay(self.mockContainerExpectations, 16);
+
+ // Now, wait for both views to run their processing
+ [keychainProcessTimeoutOp waitUntilFinished];
+ XCTAssertNil(keychainProcessTimeoutOp.error, "Shouldn't have been any error processing incoming queue (keychain)");
+
+ [self findGenericPassword:@"keychain-view" expecting:errSecSuccess];
+}
+
+@end
+
+#endif
--- /dev/null
+/*
+ * 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
+
+@interface CKKSAPSReceiverTests : XCTestCase
+@property CKRecordZoneID* testZoneID;
+
++ (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID;
+@end
+
+#endif
#import <CloudKit/CloudKit_Private.h>
#import "keychain/ckks/CKKS.h"
#import "keychain/ckks/CKKSAPSReceiver.h"
+#import "keychain/ckks/tests/CKKSAPSReceiverTests.h"
#import "keychain/ckks/tests/MockCloudKit.h"
#import "keychain/ckks/CKKSCondition.h"
@end
-
-@interface CKKSAPSReceiverTests : XCTestCase
-@property CKRecordZoneID* testZoneID;
-@end
-
@implementation CKKSAPSReceiverTests
-- (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID {
++ (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID {
// reverse engineered from source code. Ugly.
NSMutableDictionary* zoneInfo = [[NSMutableDictionary alloc] init];
self.testZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"testzone" ownerName:CKCurrentUserDefaultName];
// Make sure our helpers work properly
- APSIncomingMessage* message = [self messageForZoneID:self.testZoneID];
+ APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID];
XCTAssertNotNil(message, "Should have received a APSIncomingMessage");
CKNotification* notification = [CKNotification notificationFromRemoteNotificationDictionary:message.userInfo];
CKKSCondition* registered = [apsr registerReceiver:anr forZoneID:self.testZoneID];
XCTAssertEqual(0, [registered wait:1*NSEC_PER_SEC], "Registration should have completed within a second");
- APSIncomingMessage* message = [self messageForZoneID:self.testZoneID];
+ APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID];
XCTAssertNotNil(message, "Should have received a APSIncomingMessage");
[apsr connection:apsr.apsConnection didReceiveIncomingMessage:message];
XCTAssertEqual(0, [registered wait:1*NSEC_PER_SEC], "Registration should have completed within a second");
XCTAssertEqual(0, [registered2 wait:1*NSEC_PER_SEC], "Registration should have completed within a second");
- [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[self messageForZoneID:self.testZoneID]];
- [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[self messageForZoneID:otherZoneID]];
+ [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[CKKSAPSReceiverTests messageForZoneID:self.testZoneID]];
+ [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[CKKSAPSReceiverTests messageForZoneID:otherZoneID]];
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
XCTAssertNotNil(apsr, "Should have received a CKKSAPSReceiver");
// Receives a notification for the test zone
- APSIncomingMessage* message = [self messageForZoneID:self.testZoneID];
+ APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID];
XCTAssertNotNil(message, "Should have received a APSIncomingMessage");
[apsr connection:apsr.apsConnection didReceiveIncomingMessage:message];
#import "keychain/ckks/CKKSMirrorEntry.h"
#import "keychain/ckks/CKKSItemEncrypter.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import "keychain/ckks/tests/MockCloudKit.h"
@interface CKKSCloudKitTests : XCTestCase
}
- (NSMutableDictionary *)fetchRemoteItems {
- CKFetchRecordZoneChangesOptions *options = [CKFetchRecordZoneChangesOptions new];
+ CKFetchRecordZoneChangesConfiguration *options = [CKFetchRecordZoneChangesConfiguration new];
options.previousServerChangeToken = nil;
- CKFetchRecordZoneChangesOperation *op = [[CKFetchRecordZoneChangesOperation alloc] initWithRecordZoneIDs:@[self.zoneID] optionsByRecordZoneID:@{self.zoneID : options}];
- op.qualityOfService = NSQualityOfServiceUserInitiated;
+ CKFetchRecordZoneChangesOperation *op = [[CKFetchRecordZoneChangesOperation alloc] initWithRecordZoneIDs:@[self.zoneID] configurationsByRecordZoneID:@{self.zoneID : options}];
+ op.configuration.automaticallyRetryNetworkFailures = NO;
+ op.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
op.configuration.container = self.container;
__block NSMutableDictionary *data = [NSMutableDictionary new];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
// These are new, fresh zones for each test. There should not be old keys yet.
- if (synckeys != 3) {XCTFail(@"Unexpected number of synckeys: %lu", synckeys);}
- if (currkeys != 3) {XCTFail(@"Unexpected number of current keys: %lu", currkeys);}
+ if (synckeys != 3) {XCTFail(@"Unexpected number of synckeys: %lu", (unsigned long)synckeys);}
+ if (currkeys != 3) {XCTFail(@"Unexpected number of current keys: %lu", (unsigned long)currkeys);}
self.remoteItems = data;
return data;
- (BOOL)uploadRecords:(NSArray<CKRecord*>*)records {
CKModifyRecordsOperation *op = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:records recordIDsToDelete:nil];
- op.qualityOfService = NSQualityOfServiceUserInitiated;
+ op.configuration.automaticallyRetryNetworkFailures = NO;
+ op.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
op.configuration.container = self.container;
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeviceStateUploadRateLimited {
runAfterModification:nil];
CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[op waitUntilFinished];
// Check that an immediate rate-limited retry doesn't upload anything
checkModifiedRecord:nil
runAfterModification:nil];
op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[op waitUntilFinished];
// And now, if the update is old enough, that'll work too
checkModifiedRecord:nil
runAfterModification:nil];
op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 12);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[op waitUntilFinished];
}
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword:@"password" account:@"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Check that an immediate rate-limited retry doesn't upload anything
CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil];
// And allow the key state to progress
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeviceStateUploadWaitsForKeyHierarchyWaitForTLK {
// 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);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeviceStateReceive {
return false;
}];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeviceStateUploadBadKeyState {
[self putFakeDeviceStatusInCloudKit:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk");
__weak __typeof(self) weakSelf = self;
[self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeviceStateUploadWaitForUnlockKeyState {
"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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], "CKKS entered waitforunlock");
__weak __typeof(self) weakSelf = self;
[self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]}
[self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeviceStateUploadBadKeyStateAfterRestart {
[self putFakeDeviceStatusInCloudKit:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk");
__weak __typeof(self) weakSelf = self;
[self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeviceStateUploadBadCircleState {
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];;
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
// This test has stuff in CloudKit, but no TLKs.
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered logged out");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered logged out");
XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateLoggedOut, "CKKS thinks it's logged out");
__weak __typeof(self) weakSelf = self;
runAfterModification:nil];
CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[op waitUntilFinished];
XCTAssertNil(op.error, "No error uploading 'out of circle' device state");
[self startCKKSSubsystem];
// we should be stuck in fetch
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:8*NSEC_PER_SEC], "Key state should become fetch");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:20*NSEC_PER_SEC], "Key state should become fetch");
__weak __typeof(self) weakSelf = self;
[self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]}
XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateFetch, "CKKS re-entered fetch");
[self releaseCloudKitFetchHold];
- OCMVerifyAllWithDelay(self.mockDatabase, 16);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
[[NSFileManager defaultManager] setAttributes:@{NSFilePosixPermissions : @(400), NSFileImmutable : @(YES)} ofItemAtPath:tablePath error:&error];
XCTAssertNil(error, @"encountered error setting database file attributes: %@", error);
XCTAssertNoThrow([sqlTable openWithError:&error]);
- XCTAssertNotNil(error, @"failed to generate error when opening file without permissions");
- error = nil;
+ XCTAssertNil(error, @"encounterd error when opening file without permissions: %@", error);
+
+ XCTAssertFalse([sqlTable executeSQL:@"insert or replace into test (test_column) VALUES (1)"],
+ @"writing to read-only database succeeded");
[[NSFileManager defaultManager] setAttributes:originalAttributes ofItemAtPath:tablePath error:&error];
XCTAssertNil(error, @"encountered error setting database file attributes back to original attributes: %@", error);
[self.keychainView waitForKeyHierarchyReadiness];
// Wait for uploads to happen
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
int tlkshares = 1;
int extraDeviceStates = 1;
NSArray* knownItems = [self mirrorItemsForExistingItems];
[self addGenericPassword:@"data" account:@"unknown_account"];
[self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
NSArray* newItems = [self mirrorItemsForExistingItems];
[self addGenericPassword:@"data" account:@"GenerationCountIncrease"];
[self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
NSInteger postUpdateGenerationCount = [[CKKSEgoManifest tryCurrentEgoManifestForZone:self.keychainZoneID.zoneName] generationCount];
[self waitForExpectations: @[first] timeout:0.5];
}
+- (void)testChangeDelay {
+ XCTestExpectation *first = [self expectationWithDescription:@"FutureScheduler fired (one)"];
+ first.assertForOverFulfill = NO;
+
+ XCTestExpectation *second = [self expectationWithDescription:@"FutureScheduler fired (two)"];
+ second.expectedFulfillmentCount = 2;
+ second.assertForOverFulfill = YES;
+
+ CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_SEC keepProcessAlive:false
+ dependencyDescriptionCode:CKKSResultDescriptionNone
+ block:^{
+ [first fulfill];
+ [second fulfill];
+ }];
+
+ [scheduler changeDelays:100*NSEC_PER_MSEC continuingDelay:100*NSEC_PER_MSEC];
+ [scheduler trigger];
+
+ [self waitForExpectations: @[first] timeout:0.4];
+
+ [scheduler trigger];
+ [scheduler trigger];
+ [scheduler trigger];
+
+ [self waitForExpectations: @[second] timeout:0.4];
+}
+
@end
#endif /* OCTAGON */
@property FakeCKZone* applepayZone;
@property (readonly) ZoneKeys* applepayZoneKeys;
+@property CKRecordZoneID* homeZoneID;
+@property CKKSKeychainView* homeView;
+@property FakeCKZone* homeZone;
+@property (readonly) ZoneKeys* homeZoneKeys;
+
@end
@implementation CloudKitKeychainSyncingSOSIntegrationTests
SecCKKSTestSetDisableSOS(false);
// Wait for the ViewManager to be brought up
- XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:4*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize");
+ XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize");
self.engramZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Engram" ownerName:CKCurrentUserDefaultName];
self.engramZone = [[FakeCKZone alloc] initZone: self.engramZoneID];
self.zones[self.engramZoneID] = self.engramZone;
self.engramView = [[CKKSViewManager manager] findView:@"Engram"];
+ [self.ckksViews addObject:self.engramView];
XCTAssertNotNil(self.engramView, "CKKSViewManager created the Engram view");
[self.ckksZones addObject:self.engramZoneID];
self.manateeZone = [[FakeCKZone alloc] initZone: self.manateeZoneID];
self.zones[self.manateeZoneID] = self.manateeZone;
self.manateeView = [[CKKSViewManager manager] findView:@"Manatee"];
+ [self.ckksViews addObject:self.manateeView];
XCTAssertNotNil(self.manateeView, "CKKSViewManager created the Manatee view");
[self.ckksZones addObject:self.manateeZoneID];
self.autoUnlockZone = [[FakeCKZone alloc] initZone: self.autoUnlockZoneID];
self.zones[self.autoUnlockZoneID] = self.autoUnlockZone;
self.autoUnlockView = [[CKKSViewManager manager] findView:@"AutoUnlock"];
+ [self.ckksViews addObject:self.autoUnlockView];
XCTAssertNotNil(self.autoUnlockView, "CKKSViewManager created the AutoUnlock view");
[self.ckksZones addObject:self.autoUnlockZoneID];
self.healthZone = [[FakeCKZone alloc] initZone: self.healthZoneID];
self.zones[self.healthZoneID] = self.healthZone;
self.healthView = [[CKKSViewManager manager] findView:@"Health"];
+ [self.ckksViews addObject:self.healthView];
XCTAssertNotNil(self.healthView, "CKKSViewManager created the Health view");
[self.ckksZones addObject:self.healthZoneID];
self.applepayZone = [[FakeCKZone alloc] initZone: self.healthZoneID];
self.zones[self.applepayZoneID] = self.applepayZone;
self.applepayView = [[CKKSViewManager manager] findView:@"ApplePay"];
+ [self.ckksViews addObject:self.applepayView];
XCTAssertNotNil(self.applepayView, "CKKSViewManager created the ApplePay view");
[self.ckksZones addObject:self.applepayZoneID];
+
+ self.homeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Home" ownerName:CKCurrentUserDefaultName];
+ self.homeZone = [[FakeCKZone alloc] initZone: self.healthZoneID];
+ self.zones[self.homeZoneID] = self.homeZone;
+ self.homeView = [[CKKSViewManager manager] findView:@"Home"];
+ XCTAssertNotNil(self.homeView, "CKKSViewManager created the Home view");
+ [self.ckksZones addObject:self.homeZoneID];
}
+ (void)tearDown {
[self.applepayView waitUntilAllOperationsAreFinished];
self.applepayView = nil;
+ [self.homeView halt];
+ [self.homeView waitUntilAllOperationsAreFinished];
+ self.homeView = nil;
+
[super tearDown];
}
}
}
+-(void)testAllViewsMakeNewKeyHierarchies {
+ // Test starts with nothing anywhere
+
+ // Due to our new cross-zone fetch system, CKKS should only issue one fetch for all zones
+ // Since the tests can sometimes be slow, slow down the fetcher to normal speed
+ [self.injectedManager.zoneChangeFetcher.fetchScheduler changeDelays:2*NSEC_PER_SEC continuingDelay:30*NSEC_PER_SEC];
+ self.silentFetchesAllowed = false;
+ [self expectCKFetch];
+
+ [self startCKKSSubsystem];
+
+ // All zones should upload a key hierarchy
+ for(CKRecordZoneID* zoneID in self.ckksZones) {
+ [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:zoneID];
+ }
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+
+ for(CKKSKeychainView* view in self.ckksViews) {
+ XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view);
+ }
+}
+
+-(void)testAllViewsAcceptExistingKeyHierarchies {
+ for(CKRecordZoneID* zoneID in self.ckksZones) {
+ [self putFakeKeyHierarchyInCloudKit:zoneID];
+ [self saveTLKMaterialToKeychain:zoneID];
+ [self expectCKKSTLKSelfShareUpload:zoneID];
+ }
+
+ [self.injectedManager.zoneChangeFetcher.fetchScheduler changeDelays:2*NSEC_PER_SEC continuingDelay:30*NSEC_PER_SEC];
+ self.silentFetchesAllowed = false;
+ [self expectCKFetch];
+
+ [self startCKKSSubsystem];
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+
+ for(CKKSKeychainView* view in self.ckksViews) {
+ XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should enter 'ready' for view %@", view);
+ }
+}
+
-(void)testAddEngramManateeItems {
[self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-manatee" viewHint:(NSString*) kSecAttrViewHintManatee];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectations:@[manateeChanged] timeout:1];
[self waitForExpectations:@[pcsChanged] timeout:1];
}
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.autoUnlockZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintAutoUnlock];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectations:@[autoUnlockChanged] timeout:1];
[self waitForExpectations:@[pcsChanged] timeout:0.2];
}
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.healthZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintHealth];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectations:@[healthChanged] timeout:1];
[self waitForExpectations:@[pcsChanged] timeout:0.2];
}
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.applepayZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintApplePay];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectations:@[applepayChanged] timeout:1];
[self waitForExpectations:@[pcsChanged] timeout:0.2];
}
+-(void)testAddHomeItems {
+ [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test.
+
+ [self startCKKSSubsystem];
+
+ XCTestExpectation* homeChanged = [self expectChangeForView:self.homeZoneID.zoneName];
+ // Home is NOT a PCS view, so it should not send the fake 'PCS' view notification
+ XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"];
+ pcsChanged.inverted = YES;
+
+ // We expect a single record to be uploaded to the ApplePay view.
+ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.homeZoneID];
+ [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintHome];
+
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ [self waitForExpectations:@[homeChanged] timeout:1];
+ [self waitForExpectations:@[pcsChanged] timeout:0.2];
+}
-(void)testAddOtherViewHintItem {
[self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test.
[self addGenericPassword: @"data" account: @"account-delete-me-password" viewHint:(NSString*) kSOSViewAutofillPasswords];
sleep(1);
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testReceiveItemInView {
[self.applepayZoneKeys.tlk loadKeyMaterialFromKeychain:&error];
XCTAssertNil(error, "No error loading ApplePay tlk from piggy contents");
+
+ [self.homeZoneKeys.tlk loadKeyMaterialFromKeychain:&error];
+ XCTAssertNil(error, "No error loading Home tlk from piggy contents");
}
-(NSString*)fileForStorage
[self waitForKeyHierarchyReadinesses];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
/*
* Pull data from keychain and view manager
XCTAssertNotNil(result, "Initial not set");
NSArray *copiedTLKs = result[@"tlks"];
XCTAssertNotNil(copiedTLKs, "tlks not set");
- XCTAssertEqual([copiedTLKs count], [tlks count], "tlks count not same");
+ XCTAssertEqual([copiedTLKs count], 5u, "piggybacking should have gotten 5 TLKs across (but we have more than that elsewhere)");
NSArray *copiediCloudidentities = result[@"idents"];
XCTAssertNotNil(copiediCloudidentities, "idents not set");
@"v_Data" : [NSData dataWithBytes:key length:sizeof(key)],
@"auth" : @YES,
},
+ @{
+ @"acct" : @"66666666",
+ @"srvr" : @"Home",
+ @"v_Data" : [NSData dataWithBytes:key length:sizeof(key)],
+ @"auth" : @YES,
+ },
];
NSArray<NSDictionary *>* sortedTLKs = SOSAccountSortTLKS(tlks);
XCTAssertNotNil(sortedTLKs, "sortedTLKs not set");
- NSArray<NSString *> *expectedOrder = @[ @"11111111", @"22222222", @"33333333", @"44444444", @"55555555"];
+ // Home gets sorted into the middle, as the other Health and Manatee TLKs aren't 'authoritative'
+ NSArray<NSString *> *expectedOrder = @[ @"11111111", @"22222222", @"33333333", @"66666666", @"44444444", @"55555555"];
[sortedTLKs enumerateObjectsUsingBlock:^(NSDictionary *tlk, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *uuid = tlk[@"acct"];
XCTAssertEqualObjects(uuid, expectedOrder[idx], "wrong order");
[self.manateeView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Verify that there are three local keys, and three local current key records
__weak __typeof(self) weakSelf = self;
[self putFakeDeviceStatusInCloudKit: self.autoUnlockZoneID];
[self putFakeDeviceStatusInCloudKit: self.healthZoneID];
[self putFakeDeviceStatusInCloudKit: self.applepayZoneID];
+ [self putFakeDeviceStatusInCloudKit: self.homeZoneID];
}
-(void)putFakeKeyHierachiesInCloudKit{
[self putFakeKeyHierarchyInCloudKit: self.autoUnlockZoneID];
[self putFakeKeyHierarchyInCloudKit: self.healthZoneID];
[self putFakeKeyHierarchyInCloudKit: self.applepayZoneID];
+ [self putFakeKeyHierarchyInCloudKit: self.homeZoneID];
}
-(void)saveTLKsToKeychain{
[self saveTLKMaterialToKeychain:self.engramZoneID];
[self saveTLKMaterialToKeychain:self.autoUnlockZoneID];
[self saveTLKMaterialToKeychain:self.healthZoneID];
[self saveTLKMaterialToKeychain:self.applepayZoneID];
+ [self saveTLKMaterialToKeychain:self.homeZoneID];
}
-(void)deleteTLKMaterialsFromKeychain{
[self deleteTLKMaterialFromKeychain: self.engramZoneID];
[self deleteTLKMaterialFromKeychain: self.autoUnlockZoneID];
[self deleteTLKMaterialFromKeychain: self.healthZoneID];
[self deleteTLKMaterialFromKeychain: self.applepayZoneID];
+ [self deleteTLKMaterialFromKeychain: self.homeZoneID];
}
-(void)waitForKeyHierarchyReadinesses {
[self.autoUnlockView waitForKeyHierarchyReadiness];
[self.healthView waitForKeyHierarchyReadiness];
[self.applepayView waitForKeyHierarchyReadiness];
+ [self.homeView waitForKeyHierarchyReadiness];
}
-(void)testAcceptExistingAndUsePiggyKeyHierarchy {
[self startCKKSSubsystem];
// The CKKS subsystem should not try to write anything to the CloudKit database.
- XCTAssertEqual(0, [self.manateeView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:400*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.manateeView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now, save the TLKs to the keychain (to simulate them coming in later via piggybacking).
for(CKRecordZoneID* zoneID in self.ckksZones) {
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID checkItem: [self checkClassCBlock:self.manateeZoneID message:@"Object was encrypted under class C key in hierarchy"]];
[self addGenericPassword: @"data" account: @"account-delete-me-manatee" viewHint:(id)kSecAttrViewHintManatee];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID checkItem: [self checkClassABlock:self.manateeZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
@end
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertEqualObjects(newClassAKey, self.keychainZone.currentDatabase[self.keychainZoneKeys.currentClassAPointer.storedCKRecord.recordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class A key reference");
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[self.keychainZoneKeys.currentClassCPointer.storedCKRecord.recordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference");
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Break the key hierarchy
[self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID];
// CKKS should then fix the pointers and give itself a new TLK share record, but not update any keys
[self expectCKModifyKeyRecords:0 currentKeyPointerRecords:1 tlkShareRecords:1 zoneID:self.keychainZoneID];
[self.keychainView notifyZoneChange:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And then upload the item as usual
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[self.keychainZoneKeys.currentClassCPointer.storedCKRecord.recordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference");
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
- // Break the key hierarchy
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready");
+ [self waitForCKModifications];
+
+ // Break the key hierarchy. The TLK will arrive via SOS later in this test.
[self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID];
- [self saveTLKMaterialToKeychain:self.keychainZoneID];
CKReference* newClassCKey = self.keychainZone.currentDatabase[classCPointerRecordID][SecCKRecordParentKeyRefKey];
CKRecord* classCPointer = self.keychainZone.currentDatabase[classCPointerRecordID];
// It should not try to modify the pointers again, but it should give itself the new TLK
[self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID];
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
+
+ [self saveTLKMaterialToKeychain:self.keychainZoneID];
[self.keychainView notifyZoneChange:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And then use the 'new' key as it should
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[classCPointerRecordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference");
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Now, break the class C pointer, but don't tell CKKS
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertEqualObjects(newClassCKey, self.keychainZone.currentDatabase[classCPointerRecordID][SecCKRecordParentKeyRefKey], "CKKS should have fixed up the broken class C key reference");
#import "keychain/ckks/CKKSTLKShare.h"
#import "keychain/ckks/CKKSViewManager.h"
#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import "keychain/ckks/tests/MockCloudKit.h"
#import "keychain/ckks/tests/CKKSTests.h"
// 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];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Verify that there are three local keys, and three local current key records
__weak __typeof(self) weakSelf = self;
return TRUE;
}];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Verify that there are three local keys, and three local current key records
__weak __typeof(self) weakSelf = self;
// CKKS should enter 'waitfortlk' without crashing
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk");
}
- (void)testAcceptExistingTLKSharedKeyHierarchyAndUse {
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testNewTLKSharesHaveChangeTags {
// 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];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Verify that making a new share will have the old share's change tag
XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
// The CKKS subsystem should not try to write anything to the CloudKit database while it's accepting the keys
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Make another share, but from an untrusted peer to some other peer. local shouldn't necessarily care.
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testReceiveTLKShareWhileLocked {
[self startCKKSSubsystem];
// The CKKS subsystem should not try to write anything to the CloudKit database, but it should enter waitforunlock
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:10*NSEC_PER_SEC], "Key state should become waitforunlock");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], "Key state should become waitforunlock");
// Now unlock things. We expect a TLKShare upload.
[self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID];
self.aksLockState = false;
[self.lockStateTracker recheck];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testUploadTLKSharesForExistingHierarchy {
[self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testUploadTLKSharesForExistingHierarchyOnRestart {
[self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Now, delete all the TLK Shares, so CKKS will upload them again
[self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID];
self.keychainView = [self.injectedManager restartZone: self.keychainZoneID.zoneName];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
}
- (void)testHandleExternalSharedTLKRoll {
[self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Now the external peer rolls the TLK and updates the shares
// Trigger a notification
[self.keychainView notifyZoneChange:nil];
[self.keychainView waitForFetchAndIncomingQueueProcessing];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// We expect a single record to be uploaded.
checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]];
[self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testUploadTLKSharesForExternalTLKRollWithoutShares {
[self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now, an old (Tigris) peer rolls the TLK, but doesn't share it
// CKKS should get excited and throw 3 new share records up
// Trigger a notification
[self.keychainView notifyZoneChange:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 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 addGenericPassword: @"data" account: @"account-delete-me-rolled-key"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromTLKShareUploadFailure {
}];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
}
- (void)testFillInMissingPeerShares {
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDontAcceptTLKFromUntrustedPeer {
// The CKKS subsystem should now accept the key, and share the TLK back to itself
[self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
// And use it as well
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testSendNewTLKSharesOnTrustSetAddition {
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Cool! New peer arrives!
[self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID];
[self.currentPeers addObject:self.remotePeer1];
[self.injectedManager sendTrustedPeerSetChangedUpdate];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// step 2: add a new peer who already has a share; no share should be created
[self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become '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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now, lock.
self.aksLockState = true;
[self.injectedManager sendTrustedPeerSetChangedUpdate];
// CKKS should notice that it has things to do...
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
// And do them.
[self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID];
self.aksLockState = false;
[self.lockStateTracker recheck];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// and return to ready
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
}
- (void)testAddItemDuringNewTLKSharesOnTrustSetAddition {
[self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Hold the TLK share modification
[self.currentPeers addObject:self.remotePeer1];
[self.injectedManager sendTrustedPeerSetChangedUpdate];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// While CloudKit is hanging the write, add an item
[self addGenericPassword: @"data" account: @"account-delete-me"];
checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]];
[self releaseCloudKitModificationHold];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testSendNewTLKSharesOnTrustSetRemoval {
// 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);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testSendNewTLKShareToPeerOnPeerEncryptionKeyChange {
[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");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
// Remote peer rolls its encryption key...
[self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID
self.remotePeer1.encryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]];
[self.injectedManager sendTrustedPeerSetChangedUpdate];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
}
- (void)testRecoverFromBrokenSignatureOnTLKShareDuetoSignatureKeyChange {
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become waitfortlk");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*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
[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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
}
// 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");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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
self.remotePeer1.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]];
[self.injectedManager sendTrustedPeerSetChangedUpdate];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
}
- (void)testSendNewTLKShareToPeerOnDisappearanceOfPeerKeys {
// 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");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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.currentPeers addObject:brokenRemotePeer1];
[self.injectedManager sendTrustedPeerSetChangedUpdate];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
}
- (void)testSendNewTLKShareToPeerOnDisappearanceOfPeerSigningKey {
// 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");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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
[self.currentPeers addObject:brokenRemotePeer1];
[self.injectedManager sendTrustedPeerSetChangedUpdate];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self waitForExpectations:@[peer1Share, peer2Share] timeout:5];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
}
- (void)testSendNewTLKShareToSelfOnSelfKeyChanges {
// 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");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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
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");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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
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");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
}
- (void)testDoNotResetCloudKitZoneFromWaitForTLKDueToRecentTLKShare {
self.keychainZone.flag = true;
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortlk'");
XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false");
}
self.keychainZone.flag = true;
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*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'
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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*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'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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");
// 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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become 'waitfortlk'");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Fetching status should be quick
XCTAssertNil(error, "should be no error fetching status for keychain");
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:1.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
// But, if by some miracle those keys come back, CKKS should be able to recover
// It'll also upload itself a TLK share
self.currentSelfPeerError = nil;
[self.injectedManager sendSelfPeerChangedUpdate];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become 'ready''");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready''");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
}
#include <ipc/server_security_helpers.h>
#import <Foundation/NSXPCConnection_Private.h>
+#import "keychain/categories/NSError+UsefulConstructors.h"
+
#import "keychain/ckks/tests/CloudKitMockXCTest.h"
#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h"
#import "keychain/ckks/CKKS.h"
}), @"_SecItemAddAndNotifyOnSync succeeded");
// Verify that the item was written to CloudKit
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// In real code, you'd need to wait for the _SecItemAddAndNotifyOnSync callback to succeed before proceeding
- [self waitForExpectations:@[syncExpectation] timeout:8.0];
+ [self waitForExpectations:@[syncExpectation] timeout:20];
return (NSDictionary*) CFBridgingRelease(result);
}
self.silentFetchesAllowed = false;
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.loggedOut wait:2*NSEC_PER_SEC], "CKKS should positively log out");
+ XCTAssertEqual(0, [self.keychainView.loggedOut wait:20*NSEC_PER_SEC], "CKKS should positively log out");
NSMutableDictionary* query = [@{
(id)kSecClass : (id)kSecClassGenericPassword,
// And now, allow CKKS to discover we're logged out
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.loggedOut wait:2*NSEC_PER_SEC], "CKKS should positively log out");
+ XCTAssertEqual(0, [self.keychainView.loggedOut wait:20*NSEC_PER_SEC], "CKKS should positively log out");
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
[self holdCloudKitFetches];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.loggedIn wait:2*NSEC_PER_SEC], "CKKS should log in");
+ XCTAssertEqual(0, [self.keychainView.loggedIn wait:20*NSEC_PER_SEC], "CKKS should log in");
[self.keychainView.zoneSetupOperation waitUntilFinished];
NSMutableDictionary* query = [@{
}), @"_SecItemAddAndNotifyOnSync succeeded");
// 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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:20*NSEC_PER_SEC], @"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];
[self releaseCloudKitFetchHold];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], @"Should have reached key state 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Should have reached key state 'ready'");
// Verify that the item was written to CloudKit
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
XCTAssertEqual(errSecSuccess, SecItemAdd((__bridge CFDictionaryRef) query, NULL), @"SecItemAdd succeeded");
// Verify that the item is written to CloudKit
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
CFTypeRef item = NULL;
query[(id)kSecValueData] = nil;
XCTAssertEqual(errSecSuccess, SecItemAdd((__bridge CFDictionaryRef) query, NULL), @"SecItemAdd succeeded");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
query[(id)kSecValueData] = nil;
PCSPublicIdentity:newPublicIdentity]];
XCTAssertEqual(errSecSuccess, SecItemUpdate((__bridge CFDictionaryRef) query, (__bridge CFDictionaryRef) update), @"SecItemUpdate succeeded");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
CFTypeRef item = NULL;
query[(id)kSecValueData] = nil;
XCTAssertEqual(errSecSuccess, SecItemAdd((__bridge CFDictionaryRef) query, NULL), @"SecItemAdd succeeded");
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Find the item record in CloudKit. Since we're using kSecAttrDeriveSyncIDFromItemAttributes,
PCSPublicIdentity:publicIdentity]];
[self updateGenericPassword:@"different password" account:@"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
CKRecord* newRecord = self.keychainZone.currentDatabase[recordID];
// 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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// After the local reset, we expect: a fetch, then nothing
self.silentFetchesAllowed = false;
XCTAssertNil(result, "no error resetting local");
[resetExpectation fulfill];
}];
- [self waitForExpectations:@[resetExpectation] timeout:8.0];
+ [self waitForExpectations:@[resetExpectation] timeout:20];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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"
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
-(void)testResetLocalWhileLoggedOut {
// We're "logged in to" cloudkit but not in circle.
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
self.silentFetchesAllowed = false;
[resetExpectation fulfill];
}];
- [self waitForExpectations:@[resetExpectation] timeout:1.0];
+ [self waitForExpectations:@[resetExpectation] timeout:20];
[self.keychainView dispatchSync: ^bool{
CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.keychainView.zoneName];
// Now log in, and see what happens! It should re-fetch, pick up the old key hierarchy, and use it
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
self.silentFetchesAllowed = true;
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];;
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
-(void)testResetLocalMultipleTimes {
[self startCKKSSubsystem];
// We expect a single record to be uploaded
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// We're going to request a bunch of CloudKit resets, but hold them from finishing
// 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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID
checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
-(void)testResetCloudKitZone {
// 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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// After the reset, we expect a key hierarchy upload, and then the class C item upload
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]];
XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"];
- [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) {
+ [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) {
XCTAssertNil(result, "no error resetting cloudkit");
secnotice("ckks", "Received a resetCloudKit callback");
[resetExpectation fulfill];
}];
- [self waitForExpectations:@[resetExpectation] timeout:8.0];
+ [self waitForExpectations:@[resetExpectation] timeout:20];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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"
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testResetCloudKitZoneDuringWaitForTLK {
// No records should be uploaded
[self addGenericPassword: @"data" account: @"account-delete-me"];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS should have entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS should have entered waitfortlk");
// Restart CKKS to really get in the spirit of waitfortlk (and get a pending processOutgoingQueue operation going)
self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
CKKSOutgoingQueueOperation* outgoingOp = [self.keychainView processOutgoingQueue:nil];
XCTAssertTrue([outgoingOp isPending], "outgoing queue processing should be on hold");
checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]];
XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"];
- [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) {
+ [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) {
XCTAssertNil(result, "no error resetting cloudkit");
[resetExpectation fulfill];
}];
- [self waitForExpectations:@[resetExpectation] timeout:8.0];
+ [self waitForExpectations:@[resetExpectation] timeout:20];
XCTAssertTrue([outgoingOp isCancelled], "old stuck ProcessOutgoingQueue should be cancelled");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And adding another item works too
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
/*
// No records should be uploaded
[self addGenericPassword: @"data" account: @"account-delete-me"];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS should have entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS should have entered waitfortlk");
// Restart CKKS to really get in the spirit of waitfortlk (and get a pending processOutgoingQueue operation going)
self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
CKKSOutgoingQueueOperation* outgoingOp = [self.keychainView processOutgoingQueue:nil];
XCTAssertTrue([outgoingOp isPending], "outgoing queue processing should be on hold");
XCTAssertNil(result, "no error resetting local");
[resetExpectation fulfill];
}];
- [self waitForExpectations:@[resetExpectation] timeout:8.0];
+ [self waitForExpectations:@[resetExpectation] timeout:20];
XCTAssertTrue([outgoingOp isCancelled], "old stuck ProcessOutgoingQueue should be cancelled");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And adding another item works too
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}*/
-(void)testResetCloudKitZoneWhileLoggedOut {
self.silentZoneDeletesAllowed = true;
// We're "logged in to" cloudkit but not in circle.
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];;
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
self.silentFetchesAllowed = false;
XCTAssertNotNil(self.keychainZone.currentDatabase[ckr.recordID], "An item exists in the fake zone");
XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"];
- [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) {
+ [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) {
XCTAssertNil(result, "no error resetting cloudkit");
secnotice("ckks", "Received a resetCloudKit callback");
[resetExpectation fulfill];
}];
- [self waitForExpectations:@[resetExpectation] timeout:1.0];
+ [self waitForExpectations:@[resetExpectation] timeout:20];
XCTAssertNil(self.keychainZone.currentDatabase, "No zone anymore!");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now log in, and see what happens! It should create the zone again and upload a whole new key hierarchy
self.silentFetchesAllowed = true;
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];;
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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"
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testResetCloudKitZoneMultipleTimes {
[self startCKKSSubsystem];
// We expect a single record to be uploaded
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// We're going to request a bunch of CloudKit resets, but hold them from finishing
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) {
+ [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" 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) {
+ [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" 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) {
+ [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) {
XCTAssertNil(result, "should receive no error resetting cloudkit");
secnotice("ckksreset", "Received a resetCloudKit(2) callback");
[resetExpectation2 fulfill];
// 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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID
checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
[self holdCloudKitFetches];
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:20.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
[self releaseCloudKitFetchHold];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
[self.keychainZone failNextFetchWith:[[CKPrettyError alloc] initWithDomain:CKErrorDomain
code:CKErrorRequestRateLimited
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:20.0];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRPCFetchAndProcessWhileInWaitForTLK {
[self putFakeDeviceStatusInCloudKit:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[self.ckksControl rpcFetchAndProcessChanges:nil reply:^(NSError * _Nullable error) {
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:20.0];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRPCTLKMissingWhenMissing {
[self putFakeDeviceStatusInCloudKit:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:5.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRPCTLKMissingWhenFound {
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready''");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready''");
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:5.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRPCKnownBadStateWhenTLKsMissing {
[self putFakeDeviceStatusInCloudKit:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk");
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:5.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRPCKnownBadStateWhenInWaitForUnlock {
[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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock");
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:5.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready''");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready''");
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:5.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRpcStatus {
[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'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should return to 'ready'");
[self waitForCKModifications];
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:5.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
}
- (void)testRpcStatusWaitsForAccountDetermination {
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:8.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
}
- (void)testRpcStatusIsFastDuringError {
// Let CKKS come up; it should enter 'error'
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateError] wait:8*NSEC_PER_SEC], "CKKS entered 'error'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateError] wait:20*NSEC_PER_SEC], "CKKS entered 'error'");
// Fire off the status RPC; it should return immediately
XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"];
[callbackOccurs fulfill];
}];
- [self waitForExpectations:@[callbackOccurs] timeout:1.0];
+ [self waitForExpectations:@[callbackOccurs] timeout:20];
}
@end
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testCoalesceAddModifyModifyItem {
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testCoalesceAddModifyDeleteItem {
// We expect no uploads.
[self startCKKSSubsystem];
[self.keychainView waitUntilAllOperationsAreFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testCoalesceDeleteAddItem {
// We expect a single record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Okay, now the delete/add. Note that this is not a coalescing operation, since the new item
checkModifiedRecord:nil
runAfterModification:nil];
self.keychainView.operationQueue.suspended = NO;
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
@end
// And ensure that global queries do.
[self expectCKFetch];
[self fetchCurrentPointerExpectingError:true];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
SecResetLocalSecuritydXPCFakeEntitlements();
}
[setCurrentExpectation fulfill];
});
TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices);
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectations:@[keychainChanged] timeout:8];
[self waitForCKModifications];
XCTAssertNil(error, "No error setting current item");
[otherSetCurrentExpectation fulfill];
});
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectations:@[keychainChanged] timeout:8];
[self waitForCKModifications];
[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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
[self fetchCurrentPointerExpectingError:false];
[setCurrentExpectation fulfill];
});
TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices);
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self waitForExpectationsWithTimeout:8.0 handler:nil];
[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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
[self fetchCurrentPointerExpectingError:false];
[setCurrentExpectation fulfill];
});
TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices);
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
- [self waitForExpectations:@[keychainChanged] timeout:8];
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
- [self waitForExpectationsWithTimeout:8.0 handler:nil];
+ [self waitForExpectations:@[setCurrentExpectation] timeout:8];
SecResetLocalSecuritydXPCFakeEntitlements();
}
// Entirely signed out of iCloud. all current record writes should fail.
self.accountStatus = CKAccountStatusNoAccount;
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
self.silentFetchesAllowed = false;
}), @"_SecItemAddAndNotifyOnSync succeeded");
// We don't expect this callback to fire, so give it a second or so
- [self waitForExpectations:@[syncExpectation] timeout:2.0];
+ [self waitForExpectations:@[syncExpectation] timeout:20];
NSDictionary* result = CFBridgingRelease(cfresult);
[setCurrentExpectation fulfill];
});
- [self waitForExpectations:@[setCurrentExpectation] timeout:8.0];
+ [self waitForExpectations:@[setCurrentExpectation] timeout:20];
SecResetLocalSecuritydXPCFakeEntitlements();
}
XCTAssertNotNil(error, "Should have received an error setting current item (because of conflict)");
[setCurrentExpectation fulfill];
});
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self waitForExpectationsWithTimeout:8.0 handler:nil];
XCTAssertNil(error, "No error setting current item");
[setCurrentExpectation fulfill];
});
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectationsWithTimeout:8.0 handler:nil];
[self waitForCKModifications];
XCTAssertNotNil(error, "Error setting current item when the write fails");
[setCurrentExpectation fulfill];
});
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectationsWithTimeout:8.0 handler:nil];
XCTAssertNil(error, "No error setting current item");
[setCurrentExpectation fulfill];
});
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self waitForExpectationsWithTimeout:8.0 handler:nil];
(id)kSecAttrAccount:@"testaccount",
(id)kSecAttrSynchronizable : (id)kCFBooleanTrue,
}), "Should receive no error deleting item");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now, fetch the current pointer: we should get an error
[self fetchCurrentPointerExpectingError:false];
XCTAssertNil(error, "No error setting current item");
[setCurrentExpectation fulfill];
});
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self waitForExpectationsWithTimeout:8.0 handler:nil];
[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 have become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready");
[self.keychainView waitUntilAllOperationsAreFinished];
// Before CKKS can add the item, shove a conflicting one into CloudKit
[setCurrentExpectation fulfill];
});
- [self waitForExpectations:@[setCurrentExpectation] timeout:8.0];
+ [self waitForExpectations:@[setCurrentExpectation] timeout:20];
// Now, release the incoming queue processing and retry the failure
[self.operationQueue addOperation:self.keychainView.holdIncomingQueueOperation];
[setCurrentExpectation fulfill];
});
- [self waitForExpectations:@[setCurrentExpectation] timeout:8.0];
+ [self waitForExpectations:@[setCurrentExpectation] timeout:20];
// Reissue a fetch and find the new persistent ref and sha1 for the item at this UUID
[self.keychainView waitForFetchAndIncomingQueueProcessing];
[newSetCurrentExpectation fulfill];
});
- [self waitForExpectations:@[newSetCurrentExpectation] timeout:8.0];
+ [self waitForExpectations:@[newSetCurrentExpectation] timeout:20];
SecResetLocalSecuritydXPCFakeEntitlements();
}
#import "keychain/ckks/CKKSAnalytics.h"
#import "keychain/ckks/CKKSHealKeyHierarchyOperation.h"
#import "keychain/ckks/CKKSZoneChangeFetcher.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import "keychain/ckks/tests/MockCloudKit.h"
[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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready");
}
- (void)testAddItem {
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should have arrived at ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready");
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testActiveTLKS {
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
NSDictionary<NSString *,NSString *>* tlks = [[CKKSViewManager manager] activeTLKs];
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-2"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-3"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testAddItemWithoutUUID {
// We then expect an upload of the added item
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testModifyItem {
// We expect a single record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And then modified.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self updateGenericPassword: @"otherdata" account:account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testModifyItemImmediately {
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"data"]];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Right now, the write in CloudKit is pending. Make the local modification...
[self updateGenericPassword: @"otherdata" account:account];
checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"otherdata"]];
[self releaseCloudKitModificationHold];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testModifyItemPrimaryKey {
// We expect a single record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And then modified. Since we're changing the "primary key", we expect to delete the old record and upload a new one.
[self expectCKModifyItemRecords:1 deletedRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:nil];
[self updateAccountOfGenericPassword: @"new-account-delete-me" account:account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testModifyItemDuringReencrypt {
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"data"]];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Right now, the write in CloudKit is pending. Make the local modification...
[self updateGenericPassword: @"otherdata" account:account];
[self.operationQueue addOperation: self.keychainView.holdOutgoingQueueOperation];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView waitUntilAllOperationsAreFinished];
[self waitForCKModifications];
}
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"data"]];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Right now, the write in CloudKit is pending. Make the local modification...
[self updateGenericPassword: @"otherdata" account:account];
[self updateGenericPassword: @"third" account:account];
// Item should upload.
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Run the reencrypt items operation to completion.
[self.operationQueue addOperation: self.keychainView.holdReencryptOutgoingItemsOperation];
[self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Right now, the write in CloudKit is pending. Make the local modification...
[self updateGenericPassword: @"otherdata" account:account];
[self releaseCloudKitModificationHold];
// Item should upload.
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView waitUntilAllOperationsAreFinished];
[self waitForCKModifications];
self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testOutgoingQueueRecoverFromNetworkFailure {
[self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID blockAfterReject:nil withError:greyMode];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And then schedule the retried update
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
// The cloudkit operation finishes, letting the next OQO proceed (and set up uploading the new item)
[self releaseCloudKitModificationHold];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView waitUntilAllOperationsAreFinished];
[self waitForCKModifications];
// We expect a single record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// We expect a single record to be deleted.
[self expectCKDeleteItemRecords: 1 zoneID:self.keychainZoneID];
[self deleteGenericPassword:@"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeleteItemImmediatelyAfterModify {
// We expect a single record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now, hold the modify
[self holdCloudKitModifications];
checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"otherdata"]];
[self updateGenericPassword: @"otherdata" account:account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Right now, the write in CloudKit is pending. Make the local deletion...
[self deleteGenericPassword:account];
[self expectCKDeleteItemRecords:1 zoneID:self.keychainZoneID];
[self releaseCloudKitModificationHold];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testDeleteItemAfterFetchAfterModify {
// We expect a single record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now, hold the modify
//[self holdCloudKitModifications];
checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"otherdata"]];
[self updateGenericPassword: @"otherdata" account:account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Right now, the write in CloudKit is pending. Place a hold on outgoing queue processing
// Place a hold on processing the outgoing queue.
[self.operationQueue addOperation:blockOutgoing];
[outgoingQueueOperation waitUntilFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
// Trigger a notification (with hilariously fake data)
[self.keychainView notifyZoneChange:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 6);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef) query, &item), "item should exist now");
[self waitForCKModifications];
// Allow the outgoing queue operation to proceed
[self.operationQueue addOperation:self.keychainView.holdOutgoingQueueOperation];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView waitUntilAllOperationsAreFinished];
[self checkGenericPassword:@"data" account:@"account-delete-me"];
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self updateGenericPassword:@"different password" account:@"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
CKRecord* newRecord = self.keychainZone.currentDatabase[recordID];
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self updateGenericPassword:@"different password" account:@"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
CKRecord* newRecord = self.keychainZone.currentDatabase[recordID];
[self expectCKModifyItemRecords: SecCKKSOutgoingQueueItemsAtOnce currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self expectCKModifyItemRecords: 50 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 160);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testUploadInitialKeyHierarchy {
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testUploadInitialKeyHierarchyAfterLockedStart {
[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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock");
// After unlock, the key hierarchy should be created.
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
self.aksLockState = false;
[self.lockStateTracker recheck];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// 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"]];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testLockImmediatelyAfterUploadingInitialKeyHierarchy {
[self startCKKSSubsystem];
// Should enter 'ready'
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now, lock and allow fetches again
self.aksLockState = true;
CKKSResultOperation* op = [self.keychainView.zoneChangeFetcher requestSuccessfulFetch:CKKSFetchBecauseTesting];
[op waitUntilFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Wait for CKKS to shake itself out...
[self.keychainView waitForOperationsOfClass:[CKKSProcessReceivedKeysOperation class]];
// Should be in ReadyPendingUnlock
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
// 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"]];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testReceiveKeyHierarchyAfterLockedStart {
[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[SecCKKSZoneKeyStateFetchComplete] wait:8*NSEC_PER_SEC], @"Key state should get stuck in fetchcomplete");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetchComplete] wait:20*NSEC_PER_SEC], @"Key state should get stuck in fetchcomplete");
// Now, another device comes along and creates the hierarchy; we download it; and it and sends us the TLK
[self putFakeKeyHierarchyInCloudKit: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 addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testLoadKeyHierarchyAfterLockedStart {
[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[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
self.aksLockState = false;
[self.lockStateTracker recheck];
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testUploadAndUseKeyHierarchy {
CFTypeRef item = NULL;
XCTAssertEqual(errSecItemNotFound, SecItemCopyMatching((__bridge CFDictionaryRef) query, &item), "item should not exist");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// 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"]];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// now, expect a single class A record to be uploaded
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
(id)kSecAttrSynchronizable : (id)kCFBooleanTrue,
(id)kSecValueData : (id) [@"asdf" dataUsingEncoding:NSUTF8StringEncoding],
}, NULL), @"Adding class A item");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testUploadInitialKeyHierarchyTriggersBackup {
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
OCMVerifyAllWithDelay(self.mockCKKSViewManager, 10);
}
[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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*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'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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");
[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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*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'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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");
[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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*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'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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");
self.keychainZone.flag = true;
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortlk'");
XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false");
}
self.keychainZone.flag = true;
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*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'
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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*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'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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");
[self startCKKSSubsystem];
// The CKKS subsystem should only upload its TLK share
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Verify that there are three local keys, and three local current key records
__weak __typeof(self) weakSelf = self;
self.keychainZone.flag = true;
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:5*NSEC_PER_SEC], "Key state should have become waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should have become waitfortlk");
// Now, save the TLK to the keychain (to simulate it coming in later via SOS). We'll create a TLK share for ourselves.
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
// Wait for the key hierarchy to sort itself out, to make it easier on this test; see testOnboardOldItemsWithExistingKeyHierarchy for the other test.
// The CKKS subsystem should write its TLK share, but nothing else
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have 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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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"
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
XCTAssertTrue(self.keychainZone.flag, "Keychain zone shouldn't have been reset");
}
- (void)testAcceptExistingKeyHierarchyDespiteLocked {
// 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)
- // However, the CKKSKeychainView's "_onqueueWithAccountKeysCheckTLK" method should return a keychain error the first time through, indicating that the keybag is locked
+
[self putFakeKeyHierarchyInCloudKit:self.keychainZoneID];
[self saveTLKMaterialToKeychain:self.keychainZoneID];
self.aksLockState = true;
[self.lockStateTracker recheck];
- id partialKVMock = OCMPartialMock(self.keychainView);
- OCMExpect([partialKVMock _onqueueWithAccountKeysCheckTLK: [OCMArg any] error: [OCMArg setTo:[[NSError alloc] initWithDomain:@"securityd" code:errSecInteractionNotAllowed userInfo:nil]]]).andReturn(false);
-
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(partialKVMock, 4);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:20*NSEC_PER_SEC], "Key state should have become waitforunlock");
// CKKS will give itself a TLK Share
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
self.aksLockState = false;
[self.lockStateTracker recheck];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 4);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready");
// Verify that there are three local keys, and three local current key records
__weak __typeof(self) weakSelf = self;
return false;
}];
-
- [partialKVMock stopMocking];
}
- (void)testReceiveClassCWhileALocked {
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
[self.keychainView waitForFetchAndIncomingQueueProcessing];
[self findGenericPassword:@"classCItem" expecting:errSecItemNotFound];
}];
// And ensure we end up back in 'readypendingunlock': we have the keys, we're just locked now
[self.keychainView waitForOperationsOfClass:[CKKSProcessReceivedKeysOperation class]];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
[self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"classCItem" key:self.keychainZoneKeys.classC]];
[self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-FFFF-FFFF-FFFF-5A507ACB2D85" withAccount:@"classAItem" key:self.keychainZoneKeys.classA]];
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
// 'Lock' the keybag
self.aksLockState = true;
[self.keychainView halt];
self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:8*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'");
self.aksLockState = false;
[self.lockStateTracker recheck];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
}
- (void)testExternalKeyRoll {
[self startCKKSSubsystem];
// The CKKS subsystem should not try to write anything to the CloudKit database.
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
__weak __typeof(self) weakSelf = self;
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID];
return true;
}];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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{
[self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testAcceptKeyConflictAndUploadReencryptedItem {
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID];
[self expectCKAtomicModifyItemRecordsUpdateFailure: self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under rolled class C key in hierarchy"]];
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
[self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testAcceptKeyConflictAndUploadReencryptedItems {
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID];
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID
checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under rolled class C key in hierarchy"]];
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
[self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromRequestKeyRefetchWithoutRolling {
// Items should upload.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
return true;
}];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:5*NSEC_PER_SEC], "Key state should have returned to ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromIncrementedCurrentKeyPointerEtag {
// Items should upload.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID];
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me-2"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverMultipleItemsFromIncrementedCurrentKeyPointerEtag {
// Items should upload.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self addGenericPassword: @"data" account: @"account-delete-me-3"];
[self.operationQueue addOperation: self.keychainView.holdOutgoingQueueOperation];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testOnboardOldItemsCreatingKeyHierarchy {
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testOnboardOldItemsWithExistingKeyHierarchy {
[self addGenericPassword: @"data" account: @"account-delete-me"];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testOnboardOldItemsWithExistingKeyHierarchyExtantTLK {
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testOnboardOldItemsWithExistingKeyHierarchyLateTLK {
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:5*NSEC_PER_SEC], "Key state should have become waitfortlk");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should have become waitfortlk");
// Now, save the TLK to the keychain (to simulate it coming in via SOS).
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
// We expect a single record to be uploaded.
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
XCTAssertTrue(self.keychainZone.flag, "Keychain zone shouldn't have been reset");
}
[self startCKKSSubsystem];
// Wait for uploads to happen
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// One TLK share record
XCTAssertEqual(self.keychainZone.currentDatabase.count, SYSTEM_DB_RECORD_COUNT+passwordCount+1, "Have SYSTEM_DB_RECORD_COUNT+passwordCount+1 objects in cloudkit");
[self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self.keychainView waitForFetchAndIncomingQueueProcessing];
[self holdCloudKitModifications];
[self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID];
[self addGenericPassword:@"data" account:@"third"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// For the fourth, add a new record but prevent incoming queue processing
self.keychainView.holdIncomingQueueOperation = [CKKSResultOperation named:@"hold-incoming" withBlock:^{}];
[self releaseCloudKitModificationHold];
[self.operationQueue addOperation:self.keychainView.holdIncomingQueueOperation];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]];
// And ensure that all four items are present again
[self startCKKSSubsystem];
// Wait for uploads to happen
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Local resyncs shouldn't fetch clouds.
[self startCKKSSubsystem];
// Wait for uploads to happen
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// o no
// We expect a single record to be uploaded to the 'keychain' view
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// We expect a single record to be uploaded to the 'atv' view
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:appleTVZoneID];
access:(id)kSecAttrAccessibleAfterFirstUnlock
expecting:errSecSuccess message:@"AppleTV view-hinted object"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
OCMVerifyAllWithDelay(self.mockCKKSViewManager, 10);
}
// We expect a single record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Bring up a new zone: we expect a key hierarchy and an item.
[self.injectedManager findOrCreateView:(id)kSecAttrViewHintAppleTV];
access:(id)kSecAttrAccessibleAfterFirstUnlock
expecting:errSecSuccess
message:@"AppleTV view-hinted object"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// We expect a single record to be deleted from the ATV zone
[self expectCKDeleteItemRecords: 1 zoneID:appleTVZoneID];
[self deleteGenericPassword:@"tvaccount"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now we expect a single record to be deleted from the test zone
[self expectCKDeleteItemRecords: 1 zoneID:self.keychainZoneID];
[self deleteGenericPassword:@"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRestartWithoutRefetch {
[self.keychainView waitForKeyHierarchyReadiness];
[self waitForCKModifications];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Tear down the CKKS object and disallow fetches
[self.keychainView halt];
self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Okay, cool, rad, now let's set the date to be very long ago and check that there's positively a fetch
[self.keychainView halt];
[self expectCKFetch];
self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromZoneCreationFailure {
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
XCTAssertNil(self.zones[self.keychainZoneID].creationError, "Creation error was unset (and so CKKS probably dealt with the error");
}
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
XCTAssertNil(self.zones[self.keychainZoneID].subscriptionError, "Subscription error was unset (and so CKKS probably dealt with the error");
}
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
XCTAssertFalse(self.zones[self.keychainZoneID].flag, "Zone flag was reset");
XCTAssertNil(self.zones[self.keychainZoneID].subscriptionError, "Subscription error was unset (and so CKKS probably dealt with the error");
[self startCKKSSubsystem];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// CKKS should recreate the syncable TLK.
[self checkNSyncableTLKsInKeychain: 1];
self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// CKKS should recreate the syncable TLK.
[self checkNSyncableTLKsInKeychain: 1];
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// A network failure creating new TLKs shouldn't delete the 'failed' syncable one.
[self checkNSyncableTLKsInKeychain: 2];
// The first TLK write should fail, and then our fake TLKs should be there in CloudKit.
// It shouldn't write anything back up to CloudKit.
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now the TLKs arrive from the other device...
[self expectCKKSTLKSelfShareUpload: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 addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// A race failure creating new TLKs should delete the old syncable one.
[self checkNSyncableTLKsInKeychain: 1];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromNoCurrentKeyPointers {
// The CKKS subsystem should figure out the issue, and fix it.
[self expectCKModifyKeyRecords:0 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromBadChangeTag {
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 16);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// CKKS should then happily use the keys in CloudKit
[self createClassCItemAndWaitForUpload:self.keychainZoneID account:@"account-delete-me"];
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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self.keychainView waitUntilAllOperationsAreFinished];
checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]];
[self addGenericPassword: @"datadata" account: @"account-no-keys"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// We expect a single class A record to be uploaded.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromDeletedKeysReceive {
[self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"account0"];
[self.keychainView waitForFetchAndIncomingQueueProcessing];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should return to 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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 expectCKKSTLKSelfShareUpload:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]];
[self expectCKKSTLKSelfShareUpload:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]];
// 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:8*NSEC_PER_SEC], "Key state should have become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromIncorrectCurrentTLKPointer {
// 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");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertEqualObjects(self.keychainZoneKeys.currentTLKPointer,
// 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, 12);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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"
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromCloudKitFetchNetworkFailAfterReady {
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered ready");
XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateReady, "CKKS entered ready");
// Network is unavailable
// Spin up CKKS subsystem.
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitializing] wait:8*NSEC_PER_SEC], "CKKS entered initializing");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitializing] wait:20*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.reachabilityTracker recheck];
[self.keychainView waitUntilAllOperationsAreFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self findGenericPassword:@"account-delete-me" expecting:errSecSuccess];
}
+- (void)testWaitAfterCloudKitNetworkFailDuringOutgoingQueueOperation {
+ [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");
+
+ // Network is now unavailable
+ self.reachabilityFlags = 0;
+ [self.reachabilityTracker recheck];
+
+ NSError* noNetwork = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNetworkUnavailable userInfo:@{}];
+ [self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID blockAfterReject:nil withError:noNetwork];
+ [self addGenericPassword: @"data" account: @"account-delete-me"];
+
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ sleep(2);
+
+ // Once network is available again, the write should happen
+ [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID
+ checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]];
+
+ self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable;
+ [self.reachabilityTracker recheck];
+
+ [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess];
+
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+}
- (void)testRecoverFromCloudKitFetchFailWithDelay {
// Test starts with nothing in database, but one in our fake CloudKit.
// 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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromCloudKitOldChangeToken {
// 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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Delete all old database states, to destroy the change tag validity
[self.keychainZone.pastDatabases removeAllObjects];
// Trigger a fake change notification
[self.keychainView notifyZoneChange:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And check that a new upload happens just fine.
[self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromCloudKitUnknownDeviceStateRecord {
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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromCloudKitUnknownItemRecord {
// Expect a failed upload when we modify the item
[self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID];
[self updateGenericPassword:@"never seen again" account:@"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// 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.keychainView notifyZoneChange:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// 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"]];
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromCloudKitZoneNotFoundWithoutZoneDeletion {
// 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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS should enter 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS should enter 'ready'");
[self waitForCKModifications];
[self.keychainView waitForOperationsOfClass:[CKKSScanLocalItemsOperation 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.keychainView notifyZoneChange:nil];
- OCMVerifyAllWithDelay(self.mockDatabase, 80);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// And check that a new upload occurs.
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)testRecoverFromCloudKitZoneNotFoundFetchBeforeSigninOccurs {
[self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS should enter 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*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 addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// The fetch should have come back by now
[self waitForExpectations: @[fetchReturns] timeout:5];
- (void)testNoCloudKitAccount {
// Test starts with nothing in database and the user logged out of CloudKit. We expect no CKKS operations.
self.accountStatus = CKAccountStatusNoAccount;
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];;
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
self.silentFetchesAllowed = false;
[self startCKKSSubsystem];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self addGenericPassword: @"data" account: @"account-delete-me"];
[self.keychainView waitUntilAllOperationsAreFinished];
[self addGenericPassword: @"data" account: @"account-delete-me-3"];
[self.keychainView waitUntilAllOperationsAreFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Test that there are no items in the database (since we never logged in)
[self checkNoCKKSData: self.keychainView];
- (void)testSACloudKitAccount {
// Test starts with nothing in database and the user logged into CloudKit and in circle, but the account is not HSA2.
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
self.accountStatus = CKAccountStatusAvailable;
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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// There should be no uploads, even when we save keychain items and enter/exit circle
[self addGenericPassword: @"data" account: @"account-delete-me"];
[self.keychainView waitUntilAllOperationsAreFinished];
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
[self addGenericPassword: @"data" account: @"account-delete-me-2"];
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
[self addGenericPassword: @"data" account: @"account-delete-me-3"];
[self.keychainView waitUntilAllOperationsAreFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Test that there are no items in the database (since we never were in an HSA2 account)
[self checkNoCKKSData: self.keychainView];
- (void)testNoCircle {
// Test starts with nothing in database and the user logged into CloudKit, but out of Circle.
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
self.accountStatus = CKAccountStatusAvailable;
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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self addGenericPassword: @"data" account: @"account-delete-me"];
[self.keychainView waitUntilAllOperationsAreFinished];
[self addGenericPassword: @"data" account: @"account-delete-me-3"];
[self.keychainView waitUntilAllOperationsAreFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Test that there are no items in the database (since we never logged in)
[self checkNoCKKSData: self.keychainView];
- (void)testCloudKitLogin {
// Test starts with nothing in database and the user logged out of CloudKit. We expect no CKKS operations.
self.accountStatus = CKAccountStatusNoAccount;
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[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");
+ XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*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");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
[self.keychainView waitUntilAllOperationsAreFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
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");
// No writes yet, since we're not in circle
[self.keychainView waitUntilAllOperationsAreFinished];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// 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];
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[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");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// 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"]];
[self addGenericPassword: @"data" account: @"account-delete-me"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
}
// 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");
+ XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*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");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// simulate a cloudkit logout and NSNotification callback
self.accountStatus = CKAccountStatusNoAccount;
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account");
// 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.accountStateKnown wait:50*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
[self.keychainView waitUntilAllOperationsAreFinished];
OCMVerifyAllWithDelay(self.mockDatabase, 20);
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered 'logged out'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*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
self.accountStatus = CKAccountStatusAvailable;
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[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");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Let everything settle...
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
[self waitForCKModifications];
// Logout again
self.accountStatus = CKAccountStatusNoAccount;
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
// 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.accountStateKnown wait:50*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
self.accountStatus = CKAccountStatusAvailable;
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
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");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
// Logout again
self.accountStatus = CKAccountStatusNoAccount;
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- self.circleStatus = kSOSCCNotInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
// 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'");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'");
[self checkNoCKKSData: self.keychainView];
// Force zone into error state
self.accountStatus = CKAccountStatusAvailable;
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
XCTestExpectation *operationRun = [self expectationWithDescription:@"operation run"];
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");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForExpectations: @[operationRun] timeout:5];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
}
- (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");
+ XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK shouldn't know the account state");
[self startCKKSSubsystem];
- 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");
+ XCTAssertEqual(0, [self.keychainView.loggedIn wait:20*NSEC_PER_SEC], "Should have been told of a 'login'");
+ XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:50*NSEC_PER_MSEC], "'logout' event should be reset");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSiCloudGreyMode, "Account tracker error should be upset about grey mode");
// 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");
+ XCTAssertEqual(0, [self.keychainView.loggedOut wait:20*NSEC_PER_SEC], "Should have been told of a 'logout'");
+ XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:50*NSEC_PER_MSEC], "'login' event should be reset");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*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'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'");
// There should be no further uploads, even when we save keychain items
[self addGenericPassword: @"data" account: @"account-delete-me-2"];
XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account");
- 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");
+ XCTAssertEqual(0, [self.keychainView.loggedIn wait:20*NSEC_PER_SEC], "Should have been told of a 'login'");
+ XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:50*NSEC_PER_MSEC], "'logout' event should be reset");
+ XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state");
OCMVerifyAllWithDelay(self.mockDatabase, 20);
// And fetching still works!
[self.keychainView notifyZoneChange:nil];
[self.keychainView waitForFetchAndIncomingQueueProcessing];
[self findGenericPassword: @"account0" expecting:errSecSuccess];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'");
}
- (void)testCloudKitLoginRace {
OCMReject([partialKVMock handleCKLogout]);
// note: don't unblock the ck account state object yet...
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
// 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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Now that we're here (and handleCKLogout hasn't been called), bring the account up
// simulate another NSNotification callback
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[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);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView waitUntilAllOperationsAreFinished];
[self waitForCKModifications];
[partialKVMock stopMocking];
}
+- (void)testDontLogOutIfBeforeFirstUnlock {
+ // test starts as if a previously logged-in device has just rebooted
+ self.aksLockState = true;
+ self.accountStatus = CKAccountStatusAvailable;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCError error:[NSError errorWithDomain:(__bridge id)kSOSErrorDomain code:kSOSErrorNotReady description:@"fake error: device is locked, so SOS doesn't know if it's in-circle"]];
+
+ [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
+
+ XCTAssertNil(self.accountStateTracker.currentAccountError, "Account tracker error should not yet exist");
+ XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSAccountStatusUnknown, "Account tracker error should just be 'no account'");
+
+ XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS shouldn't know the account state yet");
+
+ [self startCKKSSubsystem];
+
+ XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "Shouldn't 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");
+ XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS shouldn't know the account state yet");
+
+ [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID];
+
+ self.aksLockState = false;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
+ [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:50*NSEC_PER_MSEC], "CKK should know the account state");
+
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ [self waitForCKModifications];
+
+ // 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"]];
+ [self addGenericPassword: @"data" account: @"account-delete-me"];
+
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
+ [self waitForCKModifications];
+}
+
- (void)testSyncableItemsAddedWhileLoggedOut {
// Test that once CKKS is up and 'logged out', nothing happens when syncable items are added
self.accountStatus = CKAccountStatusNoAccount;
[self startCKKSSubsystem];
- [self waitForExpectations: @[operationRun] timeout:80];
+ [self waitForExpectations: @[operationRun] timeout:20];
}
- (void)testCKKSControlBringup {
[self.keychainView waitForKeyHierarchyReadiness];
[self waitForCKModifications];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[mockFixups verify];
[mockFixups stopMocking];
[self.keychainView waitForKeyHierarchyReadiness];
[self waitForCKModifications];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Tear down the CKKS object
[self.keychainView halt];
self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName];
[self.keychainView waitForKeyHierarchyReadiness];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[mockFixups verify];
[mockFixups stopMocking];
[self.keychainView waitForKeyHierarchyReadiness];
[self waitForCKModifications];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Add some current item pointers. They don't necessarily need to point to anything...
[self.keychainView waitForKeyHierarchyReadiness];
[self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView dispatchSync: ^bool {
// The zone state entry should be up the most recent fixup level
[self.keychainView waitForKeyHierarchyReadiness];
[self waitForCKModifications];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
// Tear down the CKKS object
[self.keychainView halt];
self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:8*NSEC_PER_SEC], "Key state should become waitforfixup");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:20*NSEC_PER_SEC], "Key state should become waitforfixup");
[self releaseCloudKitFetchHold];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self.keychainView.lastFixupOperation waitUntilFinished];
XCTAssertNil(self.keychainView.lastFixupOperation.error, "Shouldn't have been any error performing fixup");
[self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID];
[self startCKKSSubsystem];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'");
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'");
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
[self addGenericPassword: @"data" account: @"first"];
[self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
// Add another record to mock up early CKKS record saving
[secondRecordIDFilled fulfill];
return TRUE;
}];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
[self waitForCKModifications];
XCTAssertNotNil(secondRecordID, "Should have filled in secondRecordID");
- XCTAssertEqual(0, [secondRecordIDFilled wait:8*NSEC_PER_SEC], "Should have filled in secondRecordID within enough time");
+ XCTAssertEqual(0, [secondRecordIDFilled wait:20*NSEC_PER_SEC], "Should have filled in secondRecordID within enough time");
// Tear down the CKKS object
[self.keychainView halt];
self.accountStatus = CKAccountStatusAvailable;
[self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:8*NSEC_PER_SEC], "Key state should become waitforfixup");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:20*NSEC_PER_SEC], "Key state should become waitforfixup");
[self.operationQueue addOperation: self.keychainView.holdFixupOperation];
- XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should become ready");
+ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
[self.keychainView.lastFixupOperation waitUntilFinished];
XCTAssertNil(self.keychainView.lastFixupOperation.error, "Shouldn't have been any error performing fixup");
// A single trusted SOSPeer, but without any CKKS keys
@property CKKSSOSPeer* remoteSOSOnlyPeer;
+@property NSMutableSet<CKKSKeychainView*>* ckksViews;
@property NSMutableSet<CKRecordZoneID*>* ckksZones;
@property (nullable) NSMutableDictionary<CKRecordZoneID*, ZoneKeys*>* keys;
[super setUp];
self.ckksZones = [NSMutableSet set];
+ self.ckksViews = [NSMutableSet set];
self.keys = [[NSMutableDictionary alloc] init];
// Fake out whether class A keys can be loaded from the keychain.
[self.mockCKKSKey stopMocking];
self.mockCKKSKey = nil;
+ // Make sure the key state machine won't be poked after teardown
+ for(CKKSKeychainView* view in self.ckksViews) {
+ [view.pokeKeyStateMachineScheduler cancel];
+ }
+
[super tearDown];
self.keys = nil;
zoneID:zoneID
checkItem:[self checkClassCBlock:zoneID message:@"Object was encrypted under class C key in hierarchy"]];
[self addGenericPassword: @"data" account: account];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
- (void)createClassAItemAndWaitForUpload:(CKRecordZoneID*)zoneID account:(NSString*)account {
access:(id)kSecAttrAccessibleWhenUnlocked
expecting:errSecSuccess
message:@"Adding class A item"];
- OCMVerifyAllWithDelay(self.mockDatabase, 8);
+ OCMVerifyAllWithDelay(self.mockDatabase, 20);
}
// Helpers to handle 'locked' keychain loading and saving
- (void)putFakeKeyHierarchyInCloudKit: (CKRecordZoneID*)zoneID {
ZoneKeys* zonekeys = [self createFakeKeyHierarchy: zoneID oldTLK:nil];
- [self.zones[zoneID] addToZone: zonekeys.tlk zoneID: zoneID];
- [self.zones[zoneID] addToZone: zonekeys.classA zoneID: zoneID];
- [self.zones[zoneID] addToZone: zonekeys.classC zoneID: zoneID];
+ FakeCKZone* zone = self.zones[zoneID];
- [self.zones[zoneID] addToZone: zonekeys.currentTLKPointer zoneID: zoneID];
- [self.zones[zoneID] addToZone: zonekeys.currentClassAPointer zoneID: zoneID];
- [self.zones[zoneID] addToZone: zonekeys.currentClassCPointer zoneID: zoneID];
+ dispatch_sync(zone.queue, ^{
+ [zone _onqueueAddToZone:zonekeys.tlk zoneID:zoneID];
+ [zone _onqueueAddToZone:zonekeys.classA zoneID:zoneID];
+ [zone _onqueueAddToZone:zonekeys.classC zoneID:zoneID];
- if(zonekeys.rolledTLK) {
- [self.zones[zoneID] addToZone: zonekeys.rolledTLK zoneID: zoneID];
- }
+ [zone _onqueueAddToZone:zonekeys.currentTLKPointer zoneID:zoneID];
+ [zone _onqueueAddToZone:zonekeys.currentClassAPointer zoneID:zoneID];
+ [zone _onqueueAddToZone:zonekeys.currentClassCPointer zoneID:zoneID];
+
+ if(zonekeys.rolledTLK) {
+ [zone _onqueueAddToZone:zonekeys.rolledTLK zoneID:zoneID];
+ }
+ });
}
- (void)rollFakeKeyHierarchyInCloudKit: (CKRecordZoneID*)zoneID {
deletedRecordTypeCounts:(NSDictionary<NSString*, NSNumber*>*)expectedDeletedRecordTypeCounts
zoneID:(CKRecordZoneID*)zoneID
checkModifiedRecord:(BOOL (^)(CKRecord*))checkRecord
- runAfterModification:(void (^) ())afterModification
+ runAfterModification:(void (^) (void))afterModification
{
- void (^newAfterModification)() = afterModification;
+ void (^newAfterModification)(void) = afterModification;
if([self.ckksZones containsObject:zoneID]) {
__weak __typeof(self) weakSelf = self;
newAfterModification = ^{
XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef) query, &result), "Should have found TLKs");
NSArray* items = (NSArray*) CFBridgingRelease(result);
- XCTAssertEqual(items.count, n, "Should have received %lu items", n);
+ XCTAssertEqual(items.count, n, "Should have received %lu items", (unsigned long)n);
}
}
[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");
+ XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize");
self.keychainView = [[CKKSViewManager manager] findView:@"keychain"];
+ [self.ckksViews addObject:self.keychainView];
XCTAssertNotNil(self.keychainView, "CKKSViewManager created the keychain view");
// Check that your environment is set up correctly
@property (nullable) id mockDatabase;
@property (nullable) id mockDatabaseExceptionCatcher;
@property (nullable) id mockContainer;
+@property (nullable) id mockContainerExpectations;
@property (nullable) id mockFakeCKModifyRecordZonesOperation;
@property (nullable) id mockFakeCKModifySubscriptionsOperation;
@property (nullable) id mockFakeCKFetchRecordZoneChangesOperation;
@property CKAccountStatus accountStatus;
@property BOOL supportsDeviceToDeviceEncryption;
@property BOOL iCloudHasValidCredentials;
-@property SOSCCStatus circleStatus;
+@property SOSAccountStatus* circleStatus;
@property (readonly) NSString* ckDeviceID;
@property (readonly) CKKSCKAccountStateTracker* accountStateTracker;
+@property NSString* apsEnvironment;
+
@property NSString* circlePeerID;
@property bool aksLockState; // The current 'AKS lock state'
deletedRecordTypeCounts:(NSDictionary<NSString*, NSNumber*>* _Nullable)expectedDeletedRecordTypeCounts
zoneID:(CKRecordZoneID*)zoneID
checkModifiedRecord:(BOOL (^_Nullable)(CKRecord*))checkRecord
- runAfterModification:(void (^_Nullable)())afterModification;
+ runAfterModification:(void (^_Nullable)(void))afterModification;
- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID;
- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID
- blockAfterReject:(void (^_Nullable)())blockAfterReject;
+ blockAfterReject:(void (^_Nullable)(void))blockAfterReject;
- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID
- blockAfterReject:(void (^_Nullable)())blockAfterReject
+ blockAfterReject:(void (^_Nullable)(void))blockAfterReject
withError:(NSError* _Nullable)error;
- (void)expectCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID;
// Use this to 1) assert that a fetch occurs and 2) cause a block to run _after_ all changes have been delivered but _before_ the fetch 'completes'.
// This way, you can modify the CK zone to cause later collisions.
-- (void)expectCKFetchAndRunBeforeFinished:(void (^_Nullable)())blockAfterFetch;
+- (void)expectCKFetchAndRunBeforeFinished:(void (^_Nullable)(void))blockAfterFetch;
// Use this to assert that a FakeCKFetchRecordsOperation occurs.
- (void)expectCKFetchByRecordID;
self.zones = [[NSMutableDictionary alloc] init];
+ self.apsEnvironment = @"fake APS push string";
+
self.mockDatabaseExceptionCatcher = OCMStrictClassMock([CKDatabase class]);
self.mockDatabase = OCMStrictClassMock([CKDatabase class]);
+ self.mockContainerExpectations = OCMStrictClassMock([CKContainer class]);
self.mockContainer = OCMClassMock([CKContainer class]);
OCMStub([self.mockContainer containerWithIdentifier:[OCMArg isKindOfClass:[NSString class]]]).andReturn(self.mockContainer);
OCMStub([self.mockContainer defaultContainer]).andReturn(self.mockContainer);
OCMStub([self.mockContainer containerIdentifier]).andReturn(SecCKKSContainerName);
OCMStub([self.mockContainer initWithContainerID: [OCMArg any] options: [OCMArg any]]).andReturn(self.mockContainer);
OCMStub([self.mockContainer privateCloudDatabase]).andReturn(self.mockDatabaseExceptionCatcher);
- OCMStub([self.mockContainer serverPreferredPushEnvironmentWithCompletionHandler: ([OCMArg invokeBlockWithArgs:@"fake APS push string", [NSNull null], nil])]);
+ OCMStub([self.mockContainer serverPreferredPushEnvironmentWithCompletionHandler: ([OCMArg invokeBlockWithArgs:self.apsEnvironment, [NSNull null], nil])]);
+ OCMStub([self.mockContainer submitEventMetric:[OCMArg any]]).andCall(self, @selector(ckcontainerSubmitEventMetric:));
// Use two layers of mockDatabase here, so we can both add Expectations and catch the exception (instead of crash) when one fails.
OCMStub([self.mockDatabaseExceptionCatcher addOperation:[OCMArg any]]).andCall(self, @selector(ckdatabaseAddOperation:));
return NO;
}]]);
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
self.mockAccountStateTracker = OCMClassMock([CKKSCKAccountStateTracker class]);
OCMStub([self.mockAccountStateTracker getCircleStatus]).andCall(self, @selector(circleStatus));
NSError * error)) {
__strong __typeof(self) strongSelf = weakSelf;
if(passedBlock && strongSelf) {
- if(strongSelf.circleStatus == kSOSCCInCircle) {
+ if(strongSelf.circleStatus.status == kSOSCCInCircle) {
passedBlock(strongSelf.circlePeerID, nil);
} else {
passedBlock(nil, [NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey:@"no account, no circle id"}]);
kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; });
}
+- (void)ckcontainerSubmitEventMetric:(CKEventMetric*)metric {
+ @try {
+ [self.mockContainerExpectations submitEventMetric:metric];
+ } @catch (NSException *exception) {
+ XCTFail("Received an container exception when trying to add a metric: %@", exception);
+ }
+}
+
- (void)ckdatabaseAddOperation:(NSOperation*)op {
@try {
[self.mockDatabase addOperation:op];
[self expectCKFetchAndRunBeforeFinished: nil];
}
--(void)expectCKFetchAndRunBeforeFinished: (void (^)())blockAfterFetch {
+-(void)expectCKFetchAndRunBeforeFinished: (void (^)(void))blockAfterFetch {
// Create an object for the block to retain and modify
BoolHolder* runAlready = [[BoolHolder alloc] init];
if(runAlready.state) {
return NO;
}
+
+ secnotice("fakecloudkit", "Received an operation (%@), checking if it's a fetch changes", obj);
BOOL matches = NO;
if ([obj isKindOfClass: [FakeCKFetchRecordZoneChangesOperation class]]) {
matches = YES;
runAlready.state = true;
+ secnotice("fakecloudkit", "Running fetch changes: %@", obj);
FakeCKFetchRecordZoneChangesOperation *frzco = (FakeCKFetchRecordZoneChangesOperation *)obj;
frzco.blockAfterFetch = blockAfterFetch;
[frzco addNullableDependency: strongSelf.ckFetchHoldOperation];
deletedRecordTypeCounts:(NSDictionary<NSString*, NSNumber*>*) expectedDeletedRecordTypeCounts
zoneID:(CKRecordZoneID*) zoneID
checkModifiedRecord:(BOOL (^)(CKRecord*)) checkModifiedRecord
- runAfterModification:(void (^) ())afterModification
+ runAfterModification:(void (^) (void))afterModification
{
__weak __typeof(self) weakSelf = self;
expectedRecordTypeCounts, expectedDeletedRecordTypeCounts);
[[self.mockDatabase expect] addOperation:[OCMArg checkWithBlock:^BOOL(id obj) {
- secnotice("fakecloudkit", "Received an operation, checking");
+ secnotice("fakecloudkit", "Received an operation (%@), checking if it's a modification", obj);
__block bool matches = false;
if(runAlready.state) {
secnotice("fakecloudkit", "Run already, skipping");
FakeCKZone* zone = strongSelf.zones[zoneID];
XCTAssertNotNil(zone, "Have a zone for these records");
- for(CKRecord* record in op.recordsToSave) {
- if(![record.recordID.zoneID isEqual: zoneID]) {
- secnotice("fakecloudkit", "Modified record zone ID mismatch: %@ %@", zoneID, record.recordID.zoneID);
- return NO;
- }
-
- NSError* recordError = [zone errorFromSavingRecord: record];
- if(recordError) {
- secnotice("fakecloudkit", "Record zone rejected record write: %@ %@", recordError, record);
- XCTFail(@"Record zone rejected record write: %@ %@", recordError, record);
- return NO;
- }
+ __block BOOL result = YES;
+ dispatch_sync(zone.queue, ^{
- NSNumber* currentCountNumber = modifiedRecordTypeCounts[record.recordType];
- NSUInteger currentCount = currentCountNumber ? [currentCountNumber unsignedIntegerValue] : 0;
- modifiedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1];
- }
+ for(CKRecord* record in op.recordsToSave) {
+ if(![record.recordID.zoneID isEqual: zoneID]) {
+ secnotice("fakecloudkit", "Modified record zone ID mismatch: %@ %@", zoneID, record.recordID.zoneID);
+ result = NO;
+ return;
+ }
- for(CKRecordID* recordID in op.recordIDsToDelete) {
- if(![recordID.zoneID isEqual: zoneID]) {
- matches = false;
- secnotice("fakecloudkit", "Deleted record zone ID mismatch: %@ %@", zoneID, recordID.zoneID);
- }
+ NSError* recordError = [zone errorFromSavingRecord: record];
+ if(recordError) {
+ secnotice("fakecloudkit", "Record zone rejected record write: %@ %@", recordError, record);
+ XCTFail(@"Record zone rejected record write: %@ %@", recordError, record);
+ result = NO;
+ return;
+ }
- // Find the object in CloudKit, and record its type
- CKRecord* record = strongSelf.zones[zoneID].currentDatabase[recordID];
- if(record) {
- NSNumber* currentCountNumber = deletedRecordTypeCounts[record.recordType];
+ NSNumber* currentCountNumber = modifiedRecordTypeCounts[record.recordType];
NSUInteger currentCount = currentCountNumber ? [currentCountNumber unsignedIntegerValue] : 0;
- deletedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1];
+ modifiedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1];
}
- }
- NSMutableDictionary* filteredExpectedRecordTypeCounts = [expectedRecordTypeCounts mutableCopy];
- for(NSString* key in filteredExpectedRecordTypeCounts.allKeys) {
- if([filteredExpectedRecordTypeCounts[key] isEqual: [NSNumber numberWithInt:0]]) {
- filteredExpectedRecordTypeCounts[key] = nil;
- }
- }
- filteredExpectedRecordTypeCounts[SecCKRecordManifestType] = modifiedRecordTypeCounts[SecCKRecordManifestType];
- filteredExpectedRecordTypeCounts[SecCKRecordManifestLeafType] = modifiedRecordTypeCounts[SecCKRecordManifestLeafType];
-
- // Inspect that we have exactly the same records as we expect
- if(expectedRecordTypeCounts) {
- matches &= !![modifiedRecordTypeCounts isEqual: filteredExpectedRecordTypeCounts];
- if(!matches) {
- secnotice("fakecloudkit", "Record number mismatch: %@ %@", modifiedRecordTypeCounts, filteredExpectedRecordTypeCounts);
- return NO;
- }
- } else {
- matches &= op.recordsToSave.count == 0u;
- if(!matches) {
- secnotice("fakecloudkit", "Record number mismatch: %@ 0", modifiedRecordTypeCounts);
- return NO;
- }
- }
- if(expectedDeletedRecordTypeCounts) {
- matches &= !![deletedRecordTypeCounts isEqual: expectedDeletedRecordTypeCounts];
- if(!matches) {
- secnotice("fakecloudkit", "Deleted record number mismatch: %@ %@", deletedRecordTypeCounts, expectedDeletedRecordTypeCounts);
- return NO;
+ for(CKRecordID* recordID in op.recordIDsToDelete) {
+ if(![recordID.zoneID isEqual: zoneID]) {
+ matches = false;
+ secnotice("fakecloudkit", "Deleted record zone ID mismatch: %@ %@", zoneID, recordID.zoneID);
+ }
+
+ // Find the object in CloudKit, and record its type
+ CKRecord* record = strongSelf.zones[zoneID].currentDatabase[recordID];
+ if(record) {
+ NSNumber* currentCountNumber = deletedRecordTypeCounts[record.recordType];
+ NSUInteger currentCount = currentCountNumber ? [currentCountNumber unsignedIntegerValue] : 0;
+ deletedRecordTypeCounts[record.recordType] = [NSNumber numberWithUnsignedInteger: currentCount + 1];
+ }
}
- } else {
- matches &= op.recordIDsToDelete.count == 0u;
- if(!matches) {
- secnotice("fakecloudkit", "Deleted record number mismatch: %@ 0", deletedRecordTypeCounts);
- return NO;
+
+ NSMutableDictionary* filteredExpectedRecordTypeCounts = [expectedRecordTypeCounts mutableCopy];
+ for(NSString* key in filteredExpectedRecordTypeCounts.allKeys) {
+ if([filteredExpectedRecordTypeCounts[key] isEqual: [NSNumber numberWithInt:0]]) {
+ filteredExpectedRecordTypeCounts[key] = nil;
+ }
}
- }
+ filteredExpectedRecordTypeCounts[SecCKRecordManifestType] = modifiedRecordTypeCounts[SecCKRecordManifestType];
+ filteredExpectedRecordTypeCounts[SecCKRecordManifestLeafType] = modifiedRecordTypeCounts[SecCKRecordManifestLeafType];
- // We have the right number of things, and their etags match. Ensure that they have the right etags
- if(matches && checkModifiedRecord) {
- // Clearly we have the right number of things. Call checkRecord on them...
- for(CKRecord* record in op.recordsToSave) {
- matches &= !!(checkModifiedRecord(record));
+ // Inspect that we have exactly the same records as we expect
+ if(expectedRecordTypeCounts) {
+ matches &= !![modifiedRecordTypeCounts isEqual: filteredExpectedRecordTypeCounts];
if(!matches) {
- secnotice("fakecloudkit", "Check record reports NO: %@ 0", record);
- return NO;
+ secnotice("fakecloudkit", "Record number mismatch: %@ %@", modifiedRecordTypeCounts, filteredExpectedRecordTypeCounts);
+ result = NO;
+ return;
+ }
+ } else {
+ matches &= op.recordsToSave.count == 0u;
+ if(!matches) {
+ secnotice("fakecloudkit", "Record number mismatch: %@ 0", modifiedRecordTypeCounts);
+ result = NO;
+ return;
+ }
+ }
+ if(expectedDeletedRecordTypeCounts) {
+ matches &= !![deletedRecordTypeCounts isEqual: expectedDeletedRecordTypeCounts];
+ if(!matches) {
+ secnotice("fakecloudkit", "Deleted record number mismatch: %@ %@", deletedRecordTypeCounts, expectedDeletedRecordTypeCounts);
+ result = NO;
+ return;
+ }
+ } else {
+ matches &= op.recordIDsToDelete.count == 0u;
+ if(!matches) {
+ secnotice("fakecloudkit", "Deleted record number mismatch: %@ 0", deletedRecordTypeCounts);
+ result = NO;
+ return;
}
}
- }
-
- if(matches) {
- // Emulate cloudkit and schedule the operation for execution. Be sure to wait for this operation
- // if you'd like to read the data from this write.
- NSBlockOperation* ckop = [NSBlockOperation named:@"cloudkit-write" withBlock: ^{
- @synchronized(zone.currentDatabase) {
- NSMutableArray* savedRecords = [[NSMutableArray alloc] init];
- for(CKRecord* record in op.recordsToSave) {
- CKRecord* reflectedRecord = [record copy];
- reflectedRecord.modificationDate = [NSDate date];
-
- [zone addToZone: reflectedRecord];
- [savedRecords addObject:reflectedRecord];
- op.perRecordCompletionBlock(reflectedRecord, nil);
- }
- for(CKRecordID* recordID in op.recordIDsToDelete) {
- // I don't believe CloudKit fails an operation if you delete a record that's not there, so:
- [zone deleteCKRecordIDFromZone: recordID];
+ // We have the right number of things, and their etags match. Ensure that they have the right etags
+ if(matches && checkModifiedRecord) {
+ // Clearly we have the right number of things. Call checkRecord on them...
+ for(CKRecord* record in op.recordsToSave) {
+ matches &= !!(checkModifiedRecord(record));
+ if(!matches) {
+ secnotice("fakecloudkit", "Check record reports NO: %@ 0", record);
+ result = NO;
+ return;
}
+ }
+ }
- if(afterModification) {
- afterModification();
+ if(matches) {
+ // Emulate cloudkit and schedule the operation for execution. Be sure to wait for this operation
+ // if you'd like to read the data from this write.
+ NSBlockOperation* ckop = [NSBlockOperation named:@"cloudkit-write" withBlock: ^{
+ @synchronized(zone.currentDatabase) {
+ NSMutableArray* savedRecords = [[NSMutableArray alloc] init];
+ for(CKRecord* record in op.recordsToSave) {
+ CKRecord* reflectedRecord = [record copy];
+ reflectedRecord.modificationDate = [NSDate date];
+
+ [zone addToZone: reflectedRecord];
+
+ [savedRecords addObject:reflectedRecord];
+ op.perRecordCompletionBlock(reflectedRecord, nil);
+ }
+ for(CKRecordID* recordID in op.recordIDsToDelete) {
+ // I don't believe CloudKit fails an operation if you delete a record that's not there, so:
+ [zone deleteCKRecordIDFromZone: recordID];
+ }
+
+ if(afterModification) {
+ afterModification();
+ }
+
+ op.modifyRecordsCompletionBlock(savedRecords, op.recordIDsToDelete, nil);
+ op.isFinished = YES;
}
-
- op.modifyRecordsCompletionBlock(savedRecords, op.recordIDsToDelete, nil);
- op.isFinished = YES;
- }
- }];
- [ckop addNullableDependency:strongSelf.ckModifyHoldOperation];
- [strongSelf.operationQueue addOperation: ckop];
+ }];
+ [ckop addNullableDependency:strongSelf.ckModifyHoldOperation];
+ [strongSelf.operationQueue addOperation: ckop];
+ }
+ });
+ if(result != YES) {
+ return result;
}
}
if(matches) {
[self failNextCKAtomicModifyItemRecordsUpdateFailure:zoneID blockAfterReject:nil];
}
-- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)())blockAfterReject {
+- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)(void))blockAfterReject {
[self failNextCKAtomicModifyItemRecordsUpdateFailure:zoneID blockAfterReject:blockAfterReject withError:nil];
}
-- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)())blockAfterReject withError:(NSError*)error {
+- (void)failNextCKAtomicModifyItemRecordsUpdateFailure:(CKRecordZoneID*)zoneID blockAfterReject: (void (^)(void))blockAfterReject withError:(NSError*)error {
__weak __typeof(self) weakSelf = self;
[[self.mockDatabase expect] addOperation:[OCMArg checkWithBlock:^BOOL(id obj) {
[self.operationQueue cancelAllOperations];
[self waitForCKModifications];
- XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:2*NSEC_PER_SEC],
+ XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC],
"Timeout did not occur waiting for SecCKKSInitialize");
// Ensure that we can fetch zone status for all zones
XCTAssertNil(error, "Should be no error fetching status");
[statusReturned fulfill];
}];
- [self waitForExpectations: @[statusReturned] timeout:5];
+ [self waitForExpectations: @[statusReturned] timeout:20];
}
// Make sure this happens before teardown.
- XCTAssertEqual(0, [self.accountStateTracker.finishedInitialDispatches wait:1*NSEC_PER_SEC], "Account state tracker initialized itself");
+ XCTAssertEqual(0, [self.accountStateTracker.finishedInitialDispatches wait:20*NSEC_PER_SEC], "Account state tracker initialized itself");
dispatch_group_t accountChangesDelivered = [self.accountStateTracker checkForAllDeliveries];
- XCTAssertEqual(0, dispatch_group_wait(accountChangesDelivered, dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC)), "Account state tracker finished delivering everything");
+ XCTAssertEqual(0, dispatch_group_wait(accountChangesDelivered, dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC)), "Account state tracker finished delivering everything");
}
[super tearDown];
typedef NSMutableDictionary<CKRecordZoneID*, FakeCKZone*> FakeCKDatabase;
-@interface FakeCKModifyRecordZonesOperation : NSBlockOperation <CKKSModifyRecordZonesOperation>
+@interface FakeCKModifyRecordZonesOperation : NSBlockOperation <CKKSModifyRecordZonesOperation> {
+ CKOperationConfiguration* _configuration;
+}
@property (nullable) NSError* creationError;
@property (nonatomic, nullable) NSMutableArray<CKRecordZone*>* recordZonesSaved;
@property (nonatomic, nullable) NSMutableArray<CKRecordZoneID*>* recordZoneIDsDeleted;
+@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration;
+
+ (FakeCKDatabase*)ckdb;
+(void)ensureZoneDeletionAllowed:(FakeCKZone*)zone;
@end
-@interface FakeCKModifySubscriptionsOperation : NSBlockOperation <CKKSModifySubscriptionsOperation>
+@interface FakeCKModifySubscriptionsOperation : NSBlockOperation <CKKSModifySubscriptionsOperation> {
+ CKOperationConfiguration* _configuration;
+}
@property (nullable) NSError* subscriptionError;
@property (nonatomic, nullable) NSMutableArray<CKSubscription*>* subscriptionsSaved;
@property (nonatomic, nullable) NSMutableArray<NSString*>* subscriptionIDsDeleted;
+@property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration;
+ (FakeCKDatabase*)ckdb;
@end
-@interface FakeCKFetchRecordZoneChangesOperation : NSOperation <CKKSFetchRecordZoneChangesOperation>
+@interface FakeCKFetchRecordZoneChangesOperation : NSOperation <CKKSFetchRecordZoneChangesOperation> {
+ CKOperationConfiguration* _configuration;
+}
+
+ (FakeCKDatabase*)ckdb;
-@property (nullable) void (^blockAfterFetch)();
+@property (nonatomic, copy) NSString *operationID;
+@property (nonatomic, readonly, strong, nullable) CKOperationConfiguration *resolvedConfiguration;
+@property (nullable) void (^blockAfterFetch)(void);
@end
@interface FakeCKFetchRecordsOperation : NSBlockOperation <CKKSFetchRecordsOperation>
// Usually nil. If set, trying to subscribe to this zone should fail.
@property (nullable) NSError* subscriptionError;
-- (instancetype)initZone:(CKRecordZoneID*)zoneID;
+// Serial queue. Use this for transactionality.
+@property dispatch_queue_t queue;
-- (void)rollChangeToken;
+- (instancetype)initZone:(CKRecordZoneID*)zoneID;
// Always Succeed
- (void)addToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID;
- (void)addToZone:(CKRecord*)record;
+// If you want a transaction of adding, use these
+- (void)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID;
+- (void)_onqueueAddToZone:(CKRecord*)record;
+
// Removes this record from all versions of the CK database, without changing the change tag
- (void)deleteFromHistory:(CKRecordID*)recordID;
@synthesize modifyRecordZonesCompletionBlock = _modifyRecordZonesCompletionBlock;
@synthesize group = _group;
+- (CKOperationConfiguration*)configuration {
+ return _configuration;
+}
+
+- (void)setConfiguration:(CKOperationConfiguration*)configuration {
+ if(configuration) {
+ _configuration = configuration;
+ } else {
+ _configuration = [[CKOperationConfiguration alloc] init];
+ }
+}
+
- (instancetype)initWithRecordZonesToSave:(nullable NSArray<CKRecordZone *> *)recordZonesToSave recordZoneIDsToDelete:(nullable NSArray<CKRecordZoneID *> *)recordZoneIDsToDelete {
if(self = [super init]) {
_recordZonesToSave = recordZonesToSave;
@synthesize subscriptionIDsToDelete = _subscriptionIDsToDelete;
@synthesize modifySubscriptionsCompletionBlock = _modifySubscriptionsCompletionBlock;
+- (CKOperationConfiguration*)configuration {
+ return _configuration;
+}
+
+- (void)setConfiguration:(CKOperationConfiguration*)configuration {
+ if(configuration) {
+ _configuration = configuration;
+ } else {
+ _configuration = [[CKOperationConfiguration alloc] init];
+ }
+}
+
- (instancetype)initWithSubscriptionsToSave:(nullable NSArray<CKSubscription *> *)subscriptionsToSave subscriptionIDsToDelete:(nullable NSArray<NSString *> *)subscriptionIDsToDelete {
if(self = [super init]) {
_subscriptionsToSave = subscriptionsToSave;
@end
@implementation FakeCKFetchRecordZoneChangesOperation
+@synthesize database = _database;
@synthesize recordZoneIDs = _recordZoneIDs;
-@synthesize optionsByRecordZoneID = _optionsByRecordZoneID;
+@synthesize configurationsByRecordZoneID = _configurationsByRecordZoneID;
@synthesize fetchAllChanges = _fetchAllChanges;
@synthesize recordChangedBlock = _recordChangedBlock;
@synthesize recordZoneFetchCompletionBlock = _recordZoneFetchCompletionBlock;
@synthesize fetchRecordZoneChangesCompletionBlock = _fetchRecordZoneChangesCompletionBlock;
+@synthesize operationID = _operationID;
+@synthesize resolvedConfiguration = _resolvedConfiguration;
@synthesize group = _group;
-- (instancetype)initWithRecordZoneIDs:(NSArray<CKRecordZoneID *> *)recordZoneIDs optionsByRecordZoneID:(nullable NSDictionary<CKRecordZoneID *, CKFetchRecordZoneChangesOptions *> *)optionsByRecordZoneID {
+- (CKOperationConfiguration*)configuration {
+ return _configuration;
+}
+
+- (void)setConfiguration:(CKOperationConfiguration*)configuration {
+ if(configuration) {
+ _configuration = configuration;
+ } else {
+ _configuration = [[CKOperationConfiguration alloc] init];
+ }
+}
+
+- (instancetype)initWithRecordZoneIDs:(NSArray<CKRecordZoneID *> *)recordZoneIDs configurationsByRecordZoneID:(nullable NSDictionary<CKRecordZoneID *, CKFetchRecordZoneChangesConfiguration *> *)configurationsByRecordZoneID {
if(self = [super init]) {
_recordZoneIDs = recordZoneIDs;
- _optionsByRecordZoneID = optionsByRecordZoneID;
+ _configurationsByRecordZoneID = configurationsByRecordZoneID;
+
+ _operationID = @"fake-operation-ID";
}
return self;
}
- (void)main {
// iterate through database, and return items that aren't in lastDatabase
FakeCKDatabase* ckdb = [FakeCKFetchRecordZoneChangesOperation ckdb];
+ if(self.recordZoneIDs.count == 0) {
+ secerror("fakeck: No zones to fetch. Likely a bug?");
+ }
for(CKRecordZoneID* zoneID in self.recordZoneIDs) {
FakeCKZone* zone = ckdb[zoneID];
}
// Extract the database at the last time they asked
- CKServerChangeToken* token = self.optionsByRecordZoneID[zoneID].previousServerChangeToken;
- NSMutableDictionary<CKRecordID*, CKRecord*>* lastDatabase = token ? zone.pastDatabases[token] : nil;
+ CKServerChangeToken* fetchToken = self.configurationsByRecordZoneID[zoneID].previousServerChangeToken;
+ __block NSMutableDictionary<CKRecordID*, CKRecord*>* lastDatabase = nil;
+ __block NSDictionary<CKRecordID*, CKRecord*>* currentDatabase = nil;
+ __block CKServerChangeToken* currentChangeToken = nil;
- // You can fetch with the current change token; that's fine
- if([token isEqual:zone.currentChangeToken]) {
- lastDatabase = zone.currentDatabase;
- }
+ dispatch_sync(zone.queue, ^{
+ lastDatabase = fetchToken ? zone.pastDatabases[fetchToken] : nil;
+
+ // You can fetch with the current change token; that's fine
+ if([fetchToken isEqual:zone.currentChangeToken]) {
+ lastDatabase = zone.currentDatabase;
+ }
- ckksnotice("fakeck", zone.zoneID, "FakeCKFetchRecordZoneChangesOperation(%@): database is currently %@ change token %@ database then: %@", zone.zoneID, zone.currentDatabase, token, lastDatabase);
+ currentDatabase = zone.currentDatabase;
+ currentChangeToken = zone.currentChangeToken;
+ });
- if(!lastDatabase && token) {
+ ckksnotice("fakeck", zone.zoneID, "FakeCKFetchRecordZoneChangesOperation(%@): database is currently %@ change token %@ database then: %@", zone.zoneID, currentDatabase, fetchToken, lastDatabase);
+
+ if(!lastDatabase && fetchToken) {
ckksnotice("fakeck", zone.zoneID, "no database for this change token: failing fetch with 'CKErrorChangeTokenExpired'");
self.fetchRecordZoneChangesCompletionBlock([[CKPrettyError alloc]
initWithDomain:CKErrorDomain
return;
}
- [zone.currentDatabase enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, CKRecord * _Nonnull record, BOOL * _Nonnull stop) {
-
+ [currentDatabase enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, CKRecord * _Nonnull record, BOOL * _Nonnull stop) {
id last = [lastDatabase objectForKey: recordID];
if(!last || ![record isEqual:last]) {
self.recordChangedBlock(record);
// iterate through lastDatabase, and delete items that aren't in database
[lastDatabase enumerateKeysAndObjectsUsingBlock:^(CKRecordID * _Nonnull recordID, CKRecord * _Nonnull record, BOOL * _Nonnull stop) {
- id current = [zone.currentDatabase objectForKey: recordID];
+ id current = [currentDatabase objectForKey: recordID];
if(current == nil) {
self.recordWithIDWasDeletedBlock(recordID, [record recordType]);
}
}];
- self.recordZoneChangeTokensUpdatedBlock(zoneID, zone.currentChangeToken, nil);
- self.recordZoneFetchCompletionBlock(zoneID, zone.currentChangeToken, nil, NO, nil);
+ self.recordZoneChangeTokensUpdatedBlock(zoneID, currentChangeToken, nil);
+ self.recordZoneFetchCompletionBlock(zoneID, currentChangeToken, nil, NO, nil);
if(self.blockAfterFetch) {
self.blockAfterFetch();
}
- self.fetchRecordZoneChangesCompletionBlock(nil);
}
+
+ self.fetchRecordZoneChangesCompletionBlock(nil);
}
+(FakeCKDatabase*) ckdb {
@end
@implementation FakeCKFetchRecordsOperation
+@synthesize database = _database;
@synthesize recordIDs = _recordIDs;
@synthesize desiredKeys = _desiredKeys;
@synthesize configuration = _configuration;
_fetchErrors = [[NSMutableArray alloc] init];
- [self rollChangeToken];
+ _queue = dispatch_queue_create("fake-ckzone", DISPATCH_QUEUE_SERIAL);
+
+ dispatch_sync(_queue, ^{
+ [self _onqueueRollChangeToken];
+ });
}
return self;
}
-- (void)rollChangeToken {
+- (void)_onqueueRollChangeToken {
+ dispatch_assert_queue(self.queue);
+
NSData* changeToken = [[[NSUUID UUID] UUIDString] dataUsingEncoding:NSUTF8StringEncoding];
self.currentChangeToken = [[CKServerChangeToken alloc] initWithData: changeToken];
}
- (void)addToZone: (CKKSCKRecordHolder*) item zoneID: (CKRecordZoneID*) zoneID {
+ dispatch_sync(self.queue, ^{
+ [self _onqueueAddToZone:item zoneID:zoneID];
+ });
+}
+
+- (void)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID {
+ dispatch_assert_queue(self.queue);
+
CKRecord* record = [item CKRecordWithZoneID: zoneID];
- [self addToZone: record];
+ [self _onqueueAddToZone: record];
// Save off the etag
item.storedCKRecord = record;
}
- (void)addToZone: (CKRecord*) record {
+ dispatch_sync(self.queue, ^{
+ [self _onqueueAddToZone:record];
+ });
+}
+
+- (void)_onqueueAddToZone:(CKRecord*)record {
+ dispatch_assert_queue(self.queue);
+
// Save off this current databse
self.pastDatabases[self.currentChangeToken] = [self.currentDatabase mutableCopy];
- [self rollChangeToken];
+ [self _onqueueRollChangeToken];
record.etag = [self.currentChangeToken description];
ckksnotice("fakeck", self.zoneID, "change tag: %@ %@", record.recordChangeTag, record.recordID);
- (NSError*)deleteCKRecordIDFromZone:(CKRecordID*) recordID {
// todo: fail somehow
+ dispatch_sync(self.queue, ^{
+ self.pastDatabases[self.currentChangeToken] = [self.currentDatabase mutableCopy];
+ [self _onqueueRollChangeToken];
- self.pastDatabases[self.currentChangeToken] = [self.currentDatabase mutableCopy];
- [self rollChangeToken];
-
- [self.currentDatabase removeObjectForKey: recordID];
+ [self.currentDatabase removeObjectForKey: recordID];
+ });
return nil;
}
printf("Beginning CloudKit reset for %s...\n", view ? [[view description] UTF8String] : "all zones");
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
- [self.control rpcResetCloudKit:view reply:^(NSError* error){
+ [self.control rpcResetCloudKit:view reason:@"ckksctl" reply:^(NSError* error){
if(error == NULL) {
printf("CloudKit Reset complete.\n");
ret = 0;
NSString* lastIncomingQueueOperation = pop(status,@"lastIncomingQueueOperation");
NSString* lastNewTLKOperation = pop(status,@"lastNewTLKOperation");
NSString* lastOutgoingQueueOperation = pop(status,@"lastOutgoingQueueOperation");
- NSString* lastRecordZoneChangesOperation = pop(status,@"lastRecordZoneChangesOperation");
NSString* lastProcessReceivedKeysOperation = pop(status,@"lastProcessReceivedKeysOperation");
NSString* lastReencryptOutgoingItemsOperation = pop(status,@"lastReencryptOutgoingItemsOperation");
NSString* lastScanLocalItemsOperation = pop(status,@"lastScanLocalItemsOperation");
printf("lastIncomingQueueOperation: %s\n", [lastIncomingQueueOperation isEqual: [NSNull null]] ? "never" : [lastIncomingQueueOperation UTF8String]);
printf("lastNewTLKOperation: %s\n", [lastNewTLKOperation isEqual: [NSNull null]] ? "never" : [lastNewTLKOperation UTF8String]);
printf("lastOutgoingQueueOperation: %s\n", [lastOutgoingQueueOperation isEqual: [NSNull null]] ? "never" : [lastOutgoingQueueOperation UTF8String]);
- printf("lastRecordZoneChangesOperation: %s\n", [lastRecordZoneChangesOperation isEqual: [NSNull null]] ? "never" : [lastRecordZoneChangesOperation UTF8String]);
printf("lastProcessReceivedKeysOperation: %s\n", [lastProcessReceivedKeysOperation isEqual: [NSNull null]] ? "never" : [lastProcessReceivedKeysOperation UTF8String]);
printf("lastReencryptOutgoingItemsOperation: %s\n", [lastReencryptOutgoingItemsOperation isEqual: [NSNull null]] ? "never" : [lastReencryptOutgoingItemsOperation UTF8String]);
printf("lastScanLocalItemsOperation: %s\n", [lastScanLocalItemsOperation isEqual: [NSNull null]] ? "never" : [lastScanLocalItemsOperation UTF8String]);
#import <Foundation/Foundation.h>
#import <Foundation/NSKeyedArchiver_Private.h>
+#import <CloudKit/CloudKit.h>
+#import <CloudKit/CloudKit_Private.h>
#import "keychain/ot/OTCloudStore.h"
#import "keychain/ot/OTCloudStoreState.h"
OTCloudStoreState* state = [OTCloudStoreState state: self.zoneName];
- CKFetchRecordZoneChangesOptions* options = [[CKFetchRecordZoneChangesOptions alloc] init];
+ CKFetchRecordZoneChangesConfiguration* options = [[CKFetchRecordZoneChangesConfiguration alloc] init];
options.previousServerChangeToken = state.changeToken;
- self.fetchRecordZoneChangesOperation = [[[self.fetchRecordZoneChangesOperationClass class] alloc] initWithRecordZoneIDs:@[self.zoneID] optionsByRecordZoneID:@{self.zoneID : options}];
+ self.fetchRecordZoneChangesOperation = [[[self.fetchRecordZoneChangesOperationClass class] alloc] initWithRecordZoneIDs:@[self.zoneID] configurationsByRecordZoneID:@{self.zoneID : options}];
self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) {
secinfo("octagon", "CloudKit notification: record changed(%@): %@", [record recordType], record);
[op waitUntilFinished];
if(op.error != nil) {
- secerror("octagon: failed to fetch changes error:%@", op.error);
- if(error){
- *error = op.error;
- }
- return nil;
+ secnotice("octagon", "failed to fetch changes error:%@", op.error);
}
+
+ secnotice("octagon", "checking local store for bottles");
+
+ //check localstore for bottles
NSArray* localStoreBottledPeerRecords = [self.localStore readAllLocalBottledPeerRecords:&localError];
if(!localStoreBottledPeerRecords)
{
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.
+
+ // Currently done during buddy. User is waiting.
+ self.modifyRecordsOperation.configuration.automaticallyRetryNetworkFailures = NO;
+ self.modifyRecordsOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary;
+
self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged;
self.modifyRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) {
return @{@"ckzone": self.ckzone};
}
-- (NSDictionary<NSString*,NSString*>*) sqlValues {
+- (NSDictionary<NSString*,id>*) sqlValues {
NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init];
return @{@"ckzone": self.ckzone,
error:(NSError**)error;
-(OctagonBottleCheckState)doesThisDeviceHaveABottle:(NSError**)error;
--(void) postFollowUp;
@end
NS_ASSUME_NONNULL_END
#import "keychain/ckks/CKKSViewManager.h"
#import "keychain/ckks/CKKSAnalytics.h"
-#import "CoreCDP/CDPFollowUpController.h"
-#import "CoreCDP/CDPFollowUpContext.h"
#import <CoreCDP/CDPAccount.h>
NSString* OTCKContainerName = @"com.apple.security.keychain";
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
#include <security_utilities/debugging.h>
+#if OCTAGON
+#import <SecurityFoundation/SFKey.h>
+#endif
+
@interface OTControl ()
@property NSXPCConnection *connection;
@end
*/
#import <Foundation/Foundation.h>
+
NS_ASSUME_NONNULL_BEGIN
+@class SFECKeyPair;
+
@protocol OTControlProtocol <NSObject>
- (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;;
#import <CloudKit/CloudKit_Private.h>
#import <utilities/debugging.h>
#include <dlfcn.h>
+#import <SecurityFoundation/SFKey.h>
#endif // OCTAGON
NSXPCInterface* OTSetupControlProtocol(NSXPCInterface* interface) {
#import "keychain/ot/OT.h"
#import "keychain/ot/OTConstants.h"
-#import "keychain/ckks/CloudKitCategories.h"
+#import "keychain/categories/NSError+UsefulConstructors.h"
#import "keychain/ckks/CKKSAnalytics.h"
#import "keychain/ckks/CKKSNearFutureScheduler.h"
#import "keychain/ckks/CKKS.h"
}
NSInteger retryDelayInSeconds = 0;
- BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error];
+ BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error];
//got an error from ramp check, we should log it
if(error){
}
NSInteger retryDelayInSeconds = 0;
- BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error];
+ BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error];
//got an error from ramp check, we should log it
if(error){
}
NSInteger retryDelayInSeconds = 0;
- BOOL isFeatureOn = [self.restoreRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error];
+ BOOL isFeatureOn = [self.restoreRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error];
//got an error from ramp check, we should log it
if(error){
[tracker start];
NSInteger retryDelayInSeconds = 0;
- BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error];
+ BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error];
//got an error from ramp check, we should log it
if(error){
{
NSError* error = nil;
+ if(!self.context || !self.localStore){
+ if(![self initializeManagerPropertiesForContext:nil error:&error]){
+ secerror("octagon: could not init manager obejcts: %@", error);
+ reply(NO,error);
+ return;
+ }
+ }
+
if(self.context.lockStateTracker.isLocked){
secnotice("octagon","device is locked! can't check ramp state");
error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain
- (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* listOfRecords, NSError *))reply
{
NSError* error = nil;
+ if(!self.context || !self.localStore){
+ if(![self initializeManagerPropertiesForContext:nil error:&error]){
+ secerror("octagon: could not init manager obejcts: %@", error);
+ reply(nil,error);
+ return;
+ }
+ }
if(self.context.lockStateTracker.isLocked){
secnotice("octagon","device is locked! can't check ramp state");
CKKSAnalytics* logger = [CKKSAnalytics logger];
if(self.cfuRamp){
- BOOL canCFU = [self.cfuRamp checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError];
+ BOOL canCFU = [self.cfuRamp checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError];
if(localError){
secerror("octagon: checking ramp state for CFU error'd: %@", localError);
//time to post a follow up!
secnotice("octagon", "device does not have a bottle, posting a follow up");
if(!SecCKKSTestsEnabled()){
- [self.context postFollowUp];
+ //40347954 removing cfu invocations until we can add CDP without creating a cycle.
+ //[self.context postFollowUp];
+ secnotice("octagon", "would have posted a follow up");
}
NSInteger timeDiff = -1;
#define OTRamping_h
#if OCTAGON
+#import <CloudKit/CloudKit.h>
+#import <CloudKit/CloudKit_Private.h>
#import "keychain/ckks/CKKSNearFutureScheduler.h"
#import "keychain/ckks/CloudKitDependencies.h"
#import "keychain/ckks/CKKSLockStateTracker.h"
reachabilityTracker:(CKKSReachabilityTracker*) reachabilityTracker
fetchRecordRecordsOperationClass:(Class<CKKSFetchRecordsOperation>) fetchRecordRecordsOperationClass;
--(void) fetchRampRecord:(NSQualityOfService)qos
+-(void) fetchRampRecord:(CKOperationDiscretionaryNetworkBehavior)networkBehavior
reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock;
--(BOOL) checkRampState:(NSInteger*)retryAfter qos:(NSQualityOfService)qos error:(NSError**)error;
+-(BOOL) checkRampState:(NSInteger*)retryAfter networkBehavior:(CKOperationDiscretionaryNetworkBehavior)networkBehavior error:(NSError**)error;
@end
NS_ASSUME_NONNULL_END
#endif /* OCTAGON */
return self;
}
--(void) fetchRampRecord:(NSQualityOfService)qos reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock
+-(void) fetchRampRecord:(CKOperationDiscretionaryNetworkBehavior)networkBehavior 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;
+ opConfig.discretionaryNetworkBehavior = networkBehavior;
_recordID = [[CKRecordID alloc] initWithRecordName:_recordName zoneID:_zoneID];
CKFetchRecordsOperation *operation = [[[self.fetchRecordRecordsOperationClass class] alloc] initWithRecordIDs:@[ _recordID]];
secnotice("octagon", "Attempting to fetch ramp state from CloudKit");
}
--(BOOL) checkRampState:(NSInteger*)retryAfter qos:(NSQualityOfService)qos error:(NSError**)error
+-(BOOL) checkRampState:(NSInteger*)retryAfter networkBehavior:(CKOperationDiscretionaryNetworkBehavior)networkBehavior error:(NSError**)error
{
__block BOOL isFeatureEnabled = NO;
__block NSError* localError = nil;
[tracker start];
- [self fetchRampRecord:qos reply:^(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError) {
+ [self fetchRampRecord:networkBehavior 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;
[tracker stop];
if(localRetryAfter > 0){
- secnotice("octagon", "cloud kit asked security to retry: %ld", localRetryAfter);
+ secnotice("octagon", "cloud kit asked security to retry: %lu", (unsigned long)localRetryAfter);
*retryAfter = localRetryAfter;
}
[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal];
- [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error];
+ [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error];
XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error");
self.reachabilityFlags = 0;
[self.reachabilityTracker recheck];
- [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error];
+ [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error];
XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error");
}
self.aksLockState = true;
[self.lockStateTracker recheck];
- [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error];
+ [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error];
XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error");
}
[self setUpRampRecordsInCloudKitWithFeatureOn];
- XCTAssertTrue([self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be true");
+ XCTAssertTrue([self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be true");
}
-(void)testCFUWithRampOff
NSInteger retryAfterInSeconds = 0;
[self setUpRampRecordsInCloudKitWithFeatureOff];
- XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be false");
+ XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be false");
XCTAssertTrue(retryAfterInSeconds != 0, @"should be asked to retry later");
}
{
NSError* localError = nil;
NSInteger retryAfterInSeconds = 0;
- XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be false");
+ XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be false");
}
@end
[self startCKKSSubsystem];
self.accountStatus = CKAccountStatusAvailable;
- self.circleStatus = kSOSCCInCircle;
+ self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];
[self.cfu.accountTracker notifyCKAccountStatusChangeAndWaitForSignal];
[self.context.accountTracker notifyCKAccountStatusChangeAndWaitForSignal];
#import <Security/SecItemPriv.h>
#import <xpc/xpc.h>
#import <err.h>
+#import "OT.h"
#import <utilities/debugging.h>
#import "keychain/ot/OTControl.h"
#import "keychain/ot/OTConstants.h"
@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;
}
return status;
}
+
+/*
+ * Obtain the expiration time of signer 'signerIndex' of a CMS message, if
+ * present. This is part of the signed attributes of the message.
+ *
+ * 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 CMSDecoderCopySignerAppleExpirationTime(
+ CMSDecoderRef cmsDecoder,
+ size_t signerIndex,
+ CFAbsoluteTime *expirationTime) /* RETURNED */
+{
+ OSStatus status = errSecParam;
+ SecCmsMessageRef cmsg = NULL;
+ int numContentInfos = 0;
+ SecCmsSignedDataRef signedData = NULL;
+
+ require(cmsDecoder && expirationTime, xit);
+ require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
+ 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 = SecCmsSignerInfoGetAppleExpirationTime(signerInfo, expirationTime);
+ break;
+ }
+ }
+ }
+ }
+xit:
+ return status;
+}
OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility(
CMSDecoderRef cmsDecoder,
size_t signerIndex, /* usually 0 */
- CFDataRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValue); /* RETURNED */
-
+ CFDataRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValue) /* RETURNED */
+API_AVAILABLE(macos(10.12.4), ios(11.0));
/*
* Obtain the Hash Agility v2 attribute value of signer 'signerIndex'
OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2(
CMSDecoderRef cmsDecoder,
size_t signerIndex, /* usually 0 */
- CFDictionaryRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValues); /* RETURNED */
+ CFDictionaryRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValues) /* RETURNED */
+API_AVAILABLE(macos(10.13.4), ios(11.3));
+
+/*
+ * Obtain the expiration time of signer 'signerIndex' of a CMS message, if
+ * present. This is part of the signed attributes of the message.
+ *
+ * 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 CMSDecoderCopySignerAppleExpirationTime(
+ CMSDecoderRef cmsDecoder,
+ size_t signerIndex,
+ CFAbsoluteTime *expirationTime) /* RETURNED */
+API_AVAILABLE(macos(10.14), ios(12.0));
CF_ASSUME_NONNULL_END
CMSCertificateChainMode chainMode;
CFDataRef hashAgilityAttrValue;
CFDictionaryRef hashAgilityV2AttrValues;
+ CFAbsoluteTime expirationTime;
};
static void cmsEncoderInit(CFTypeRef enc);
// CFStringRef: OID representation is a dotted-decimal string
CFStringRef inStr = (CFStringRef)inRef;
CFIndex max = CFStringGetLength(inStr) * 3;
- char buf[max];
- if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII))
+ char *buf = (char *)malloc(max);
+ if (!buf) {
+ return errSecMemoryError;
+ }
+ if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII)) {
+ free(buf);
return errSecParam;
+ }
- if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0)
+ if (encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) {
+ free(buf);
return errSecParam;
+ }
+ free(buf);
}
else if (CFGetTypeID(inRef) == CFDataGetTypeID()) {
// CFDataRef: OID representation is in binary DER format
break;
}
}
+ if (cmsEncoder->signedAttributes & kCMSAttrAppleExpirationTime) {
+ ortn = SecCmsSignerInfoAddAppleExpirationTime(signerInfo, cmsEncoder->expirationTime);
+ if(ortn) {
+ ortn = cmsRtnToOSStatus(ortn);
+ CSSM_PERROR("SecCmsSignerInfoAddAppleExpirationTime", ortn);
+ break;
+ }
+ }
CFRELEASE(ourCert);
ourCert = NULL;
return errSecSuccess;
}
+/*
+ * Set the expiration time for a CMSEncoder.
+ * This is only used if the kCMSAttrAppleExpirationTime attribute is included.
+ */
+OSStatus CMSEncoderSetAppleExpirationTime(
+ CMSEncoderRef cmsEncoder,
+ CFAbsoluteTime time)
+{
+ if(cmsEncoder == NULL) {
+ return errSecParam;
+ }
+ if(cmsEncoder->encState != ES_Init) {
+ return errSecParam;
+ }
+ cmsEncoder->expirationTime = time;
+ return errSecSuccess;
+}
+
OSStatus CMSEncoderSetCertificateChainMode(
CMSEncoderRef cmsEncoder,
CMSCertificateChainMode chainMode)
*/
kCMSAttrAppleCodesigningHashAgility = 0x0010,
kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020,
+ /*
+ * Include the expiration time.
+ */
+ kCMSAttrAppleExpirationTime = 0x0040,
};
/*
CFDataRef * __nullable CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_11_0);
-#if TIMESTAMPING_SUPOORTED
+#if TIMESTAMPING_SUPPORTED
OSStatus CMSEncoderCopySignerTimestamp(
CMSEncoderRef cmsEncoder,
size_t signerIndex, /* usually 0 */
void
CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext);
-#endif
+#endif // TIMESTAMPING_SUPPORTED
/*
* Obtain the SecCmsMessageRef associated with a CMSEncoderRef. Intended
CMSEncoderRef cmsEncoder,
CFDictionaryRef hashAgilityV2AttrValues);
+/*
+ * Set the expiration time for a CMSEncoder.
+ * This is only used if the kCMSAttrAppleExpirationTime attribute is included.
+ */
+OSStatus CMSEncoderSetAppleExpirationTime(
+ CMSEncoderRef cmsEncoder,
+ CFAbsoluteTime time);
+
CF_ASSUME_NONNULL_END
#include <Security/SecKey.h>
#include <Security/SecAsn1Types.h>
-#if !SEC_OS_OSX_INCLUDES
-#if !USE_CDSA_CRYPTO
-typedef CFTypeRef SecKeychainRef;
-#endif
-#endif // ! SEC_OS_OSX_INCLUDES
-
#if defined(__cplusplus)
extern "C" {
#endif
@typedef
@discussion XXX We might want to get rid of this alltogether.
*/
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
typedef SecAsn1AlgId SECAlgorithmID;
+#pragma clang diagnostic pop
/*!
@typedef
@typedef
@discussion Type of function passed to SecCmsDecode or SecCmsDecoderStart to retrieve the decryption key. This function is intended to be used for EncryptedData content info's which do not have a key available in a certificate, etc.
*/
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
typedef SecSymmetricKeyRef(*SecCmsGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid);
+#pragma clang diagnostic pop
/*!
@enum SecCmsVerificationStatus
SEC_OID_APPLE_HASH_AGILITY = 214,
SEC_OID_APPLE_HASH_AGILITY_V2 = 215,
+ /* Apple Expiration Time Attribute */
+ SEC_OID_APPLE_EXPIRATION_TIME = 216,
+
SEC_OID_TOTAL
} SECOidTag;
extern OSStatus
SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict);
+/*!
+ @function SecCmsSignerInfoGetAppleExpirationTime
+ @abstract Return the expriation time, in CFAbsoluteTime, of a CMS signerInfo.
+ @param sinfo SignerInfo data for this signer.
+ @discussion Returns a CFAbsoluteTime
+ @result A return value of SECFailure is an error.
+ */
+extern OSStatus
+SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime);
+
/*!
@function
@abstract Return the signing cert of a CMS signerInfo.
OSStatus
SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues);
+/*!
+ @function SecCmsSignerInfoAddAppleExpirationTime
+ @abstract Add the expiration time to the authenticated (i.e. signed) attributes of "signerinfo".
+ @discussion This is expected to be included in outgoing signed messages for Asset Receipts but is likely
+ useful in other situations. This should only be added once; a second call will do nothing.
+ @result A result of SECFailure indicates an error adding the attribute.
+ */
+extern OSStatus
+SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t);
+
/*!
@function
@abstract The following needs to be done in the S/MIME layer code after signature of a signerinfo has been verified.
CFArrayRef certChain = NULL;
CSSM_TP_APPLE_EVIDENCE_INFO *statusChain;
OSStatus status = 0;
+ SecTrustResultType trustResult = kSecTrustResultInvalid;
if (!cert)
goto loser;
if (status)
goto loser;
- status = SecTrustEvaluate(trust, NULL);
+ status = SecTrustEvaluate(trust, &trustResult);
if (status)
goto loser;
theTemplate = SEC_ASN1_GET(kSecAsn1OctetStringTemplate);
break;
case SEC_OID_PKCS9_SIGNING_TIME:
+ case SEC_OID_APPLE_EXPIRATION_TIME:
encoded = PR_FALSE;
theTemplate = SEC_ASN1_GET(kSecAsn1UTCTimeTemplate); // @@@ This should be a choice between UTCTime and GeneralizedTime -- mb
break;
#else
{
size_t keysize = (cinfo->keysize + 7)/8;
- uint8_t key_material[keysize];
+ uint8_t *key_material = (uint8_t *)malloc(keysize);
+ if (!key_material) {
+ goto loser;
+ }
require_noerr(SecRandomCopyBytes(kSecRandomDefault, keysize, key_material), loser);
- bulkkey = (SecSymmetricKeyRef)CFDataCreate(kCFAllocatorDefault, key_material, keysize);
+ bulkkey = (SecSymmetricKeyRef)CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, key_material, keysize, kCFAllocatorMalloc);
}
#endif
SecAsn1Item * encKey)
{
OSStatus rv;
- SecPublicKeyRef publickey;
-#if TARGET_OS_MAC && !TARGET_OS_IPHONE
- rv = SecCertificateCopyPublicKey(cert,&publickey);
-#else
- publickey = SecCertificateCopyPublicKey(cert);
-#endif
+ SecPublicKeyRef publickey = SecCertificateCopyKey(cert);
if (publickey == NULL)
return SECFailure;
encKey->Length = 0;
/* Copy the recipient's static public ECDH key */
-#if TARGET_OS_IPHONE
- theirPubKey = SecCertificateCopyPublicKey(cert);
-#else
- rv = SecCertificateCopyPublicKey(cert, &theirPubKey);
-#endif
+ theirPubKey = SecCertificateCopyKey(cert);
if (rv || !theirPubKey) {
dprintf("SecCmsUtilEncryptSymKeyECDH: failed to get public key from cert, %d\n", (int)rv);
goto out;
if (SecCmsSignerInfoGetSigningTime(signerinfo, &stime) != SECSuccess)
stime = CFAbsoluteTimeGetCurrent();
+
#if USE_CDSA_CRYPTO
rv = CERT_VerifyCert(keychainOrArray, cert, policies, stime, trustRef);
#else
goto loser;
}
-#if USE_CDSA_CRYPTO
- if (SecCertificateCopyPublicKey(cert, &publickey)) {
- vs = SecCmsVSProcessingError;
- goto loser;
- }
-#else
- publickey = SecCertificateCopyPublicKey(cert);
+ publickey = SecCertificateCopyKey(cert);
if (publickey == NULL)
goto loser;
-#endif
if (!SecCmsArrayIsEmpty((void **)signerinfo->authAttr)) {
if (contentType) {
return errSecAllocate;
}
+/*
+ * SecCmsSignerInfoGetAppleExpirationTime - return the expiration time,
+ * in UTCTime format, of a CMS signerInfo.
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to XXXX (what?)
+ * A return value of NULL is an error.
+ */
+OSStatus
+SecCmsSignerInfoGetAppleExpirationTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *etime)
+{
+ SecCmsAttribute *attr = NULL;
+ SecAsn1Item * value = NULL;
+
+ if (sinfo == NULL || etime == NULL) {
+ return SECFailure;
+ }
+
+ if (sinfo->expirationTime != 0) {
+ *etime = sinfo->expirationTime; /* cached copy */
+ return SECSuccess;
+ }
+
+ attr = SecCmsAttributeArrayFindAttrByOidTag(sinfo->authAttr, SEC_OID_APPLE_EXPIRATION_TIME, PR_TRUE);
+ if (attr == NULL || (value = SecCmsAttributeGetValue(attr)) == NULL) {
+ return SECFailure;
+ }
+ if (DER_UTCTimeToCFDate(value, etime) != SECSuccess) {
+ return SECFailure;
+ }
+ sinfo->expirationTime = *etime; /* make cached copy */
+ return SECSuccess;
+}
+
/*
* Return the signing cert of a CMS signerInfo.
*
return status;
}
+/*
+ * SecCmsSignerInfoAddAppleExpirationTime - add the expiration time to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed
+ * messages for Asset Receipts but is likely useful in other situations.
+ *
+ * This should only be added once; a second call will do nothing.
+ */
+OSStatus
+SecCmsSignerInfoAddAppleExpirationTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t)
+{
+ SecCmsAttribute *attr = NULL;
+ PLArenaPool *poolp = signerinfo->signedData->contentInfo.cmsg->poolp;
+ void *mark = PORT_ArenaMark(poolp);
+
+ /* create new expiration time attribute */
+ SecAsn1Item etime;
+ if (DER_CFDateToUTCTime(t, &etime) != SECSuccess) {
+ goto loser;
+ }
+
+ if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_APPLE_EXPIRATION_TIME, &etime, PR_FALSE)) == NULL) {
+ SECITEM_FreeItem (&etime, PR_FALSE);
+ goto loser;
+ }
+
+ SECITEM_FreeItem(&etime, PR_FALSE);
+
+ if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) {
+ goto loser;
+ }
+
+ PORT_ArenaUnmark(poolp, mark);
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease(poolp, mark);
+ return SECFailure;
+}
+
SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo) {
SecCertificateRef cert = NULL;
SecCmsAttribute *attr;
SecPublicKeyRef pubKey;
CFDataRef hashAgilityAttrValue;
CFDictionaryRef hashAgilityV2AttrValues;
+ CFAbsoluteTime expirationTime;
};
#define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */
#define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */
// Extract a public key object from a SubjectPublicKeyInfo
SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert)
{
- return SecCertificateCopyPublicKey(cert);
+ return SecCertificateCopyKey(cert);
}
// Extract the issuer and serial number from a certificate
CFDataRef issuer_data = SecCertificateCopyIssuerSequence(cert);
if (!issuer_data)
goto loser;
- serial_data = SecCertificateCopySerialNumber(cert);
+ serial_data = SecCertificateCopySerialNumberData(cert, NULL);
if (!serial_data)
goto loser;
encKey->Data, &encKey->Length);
}
+#define MAX_KEY_SIZE 8192/8
SecSymmetricKeyRef
WRAP_PubUnwrapSymKey(SecPrivateKeyRef privkey, const SecAsn1Item *encKey, SECOidTag bulkalgtag)
{
size_t bulkkey_size = encKey->Length;
- if (bulkkey_size > 16384) {
+ if (bulkkey_size > MAX_KEY_SIZE) {
return NULL;
}
- uint8_t bulkkey_buffer[bulkkey_size];
- if (SecKeyDecrypt(privkey, kSecPaddingPKCS1,
- encKey->Data, encKey->Length, bulkkey_buffer, &bulkkey_size))
- return NULL;
+ uint8_t *bulkkey_buffer = (uint8_t *)malloc(bulkkey_size);
+ if (!bulkkey_buffer) {
+ return NULL;
+ }
+ if (SecKeyDecrypt(privkey, kSecPaddingPKCS1, encKey->Data, encKey->Length, bulkkey_buffer, &bulkkey_size)) {
+ return NULL;
+ }
- CFDataRef bulkkey = CFDataCreate(kCFAllocatorDefault, bulkkey_buffer, bulkkey_size);
+ CFDataRef bulkkey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bulkkey_buffer, bulkkey_size, kCFAllocatorMalloc);
return (SecSymmetricKeyRef)bulkkey;
}
break;
}
CFRelease(cert_issuer);
- CFDataRef cert_serial = SecCertificateCopySerialNumber(cert);
+ CFDataRef cert_serial = SecCertificateCopySerialNumberData(cert, NULL);
if (!cert_serial)
break;
if ((serial->Length != (size_t)CFDataGetLength(cert_serial)) ||
CONST_OID appleHashAgility[] = {APPLE_CMS_ATTRIBUTES, 1};
CONST_OID appleHashAgilityV2[] = {APPLE_CMS_ATTRIBUTES, 2};
+/* Apple Expiration Time */
+CONST_OID appleExpirationTime[] = {APPLE_CMS_ATTRIBUTES, 3};
+
/* a special case: always associated with a caller-specified OID */
CONST_OID noOid[] = { 0 };
"appleCodesigningHashAgilityAttributeV2", CSSM_ALGID_NONE,
INVALID_CERT_EXTENSION),
+ /* Apple Expiration Time */
+ OD( appleExpirationTime, SEC_OID_APPLE_EXPIRATION_TIME,
+ "appleExpirationTimeAttribute", CSSM_ALGID_NONE,
+ INVALID_CERT_EXTENSION),
+
};
/*
4C2741E803E9FBAF00A80181 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 1000;
TargetAttributes = {
D447C4DB1D31C9DD0082FC1D = {
CreatedOnToolsVersion = 8.0;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
debug,
profile,
);
+ CLANG_ENABLE_OBJC_WEAK = YES;
CURRENT_PROJECT_VERSION = 8;
- FRAMEWORK_SEARCH_PATHS = (
- /usr/local/SecurityPieces/Frameworks,
- /usr/local/SecurityPieces/Components/Security,
- );
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(BUILT_PRODUCTS_DIR)/SecurityPieces/Headers",
79BDD2B00D60CA06000D84D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
FRAMEWORK_VERSION = A;
INSTALL_PATH = /usr/local/SecurityPieces/Components/Security;
PRODUCT_NAME = security_smime;
79BDD2B10D60CA06000D84D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COPY_PHASE_STRIP = NO;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
HEADER_SEARCH_PATHS = (
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
debug,
profile,
);
+ CLANG_ENABLE_OBJC_WEAK = YES;
CURRENT_PROJECT_VERSION = 8;
- FRAMEWORK_SEARCH_PATHS = (
- /usr/local/SecurityPieces/Frameworks,
- /usr/local/SecurityPieces/Components/Security,
- );
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = (
"$(BUILT_PRODUCTS_DIR)/SecurityPieces/Headers",
79BDD2BC0D60CA0A000D84D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
FRAMEWORK_VERSION = A;
INSTALL_PATH = /usr/local/SecurityPieces/Components/Security;
PRODUCT_NAME = security_smime;
79BDD2BD0D60CA0A000D84D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COPY_PHASE_STRIP = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
HEADER_SEARCH_PATHS = (
D447C4DC1D31C9DD0082FC1D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
D447C4DD1D31C9DD0082FC1D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
*flat = (unsigned char *)malloc(len+1);
*flatLen = (unsigned)len;
memmove(*flat, hostname, len);
- flat[len] = '\0'; // ensure null terminator
+ flat[len] = NULL; // ensure null terminator
return errSecSuccess;
}
}
--- /dev/null
+//
+// SecProtocol.c
+// Security
+//
+
+#include <Security/SecProtocolOptions.h>
+#include <Security/SecProtocolMetadata.h>
+#include <Security/SecProtocolPriv.h>
+
+#include <Security/SecureTransportPriv.h>
+
+#include <xpc/xpc.h>
+#include <os/log.h>
+#include <dlfcn.h>
+#include <sys/param.h>
+
+#define CFReleaseSafe(value) \
+ if (value != NULL) { \
+ CFRelease(value); \
+ }
+
+typedef bool (^sec_access_block_t)(void *handle);
+
+static bool
+sec_protocol_options_access_handle(sec_protocol_options_t options,
+ sec_access_block_t access_block)
+{
+ static void *libnetworkImage = NULL;
+ static dispatch_once_t onceToken;
+ static bool (*_nw_protocol_options_access_handle)(void *, sec_access_block_t) = NULL;
+
+ dispatch_once(&onceToken, ^{
+ libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL);
+ if (NULL != libnetworkImage) {
+ _nw_protocol_options_access_handle = (__typeof(_nw_protocol_options_access_handle))dlsym(libnetworkImage,
+ "nw_protocol_options_access_handle");
+ if (NULL == _nw_protocol_options_access_handle) {
+ os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_options_access_handle");
+ }
+ } else {
+ os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork");
+ }
+ });
+
+ if (_nw_protocol_options_access_handle == NULL) {
+ return false;
+ }
+
+ return _nw_protocol_options_access_handle(options, access_block);
+}
+
+static bool
+sec_protocol_metadata_access_handle(sec_protocol_metadata_t options,
+ sec_access_block_t access_block)
+{
+ static void *libnetworkImage = NULL;
+ static dispatch_once_t onceToken;
+ static bool (*_nw_protocol_metadata_access_handle)(void *, sec_access_block_t) = NULL;
+
+ dispatch_once(&onceToken, ^{
+ libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL);
+ if (NULL != libnetworkImage) {
+ _nw_protocol_metadata_access_handle = (__typeof(_nw_protocol_metadata_access_handle))dlsym(libnetworkImage,
+ "nw_protocol_metadata_access_handle");
+ if (NULL == _nw_protocol_metadata_access_handle) {
+ os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork _nw_protocol_metadata_access_handle");
+ }
+ } else {
+ os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork");
+ }
+ });
+
+ if (_nw_protocol_metadata_access_handle == NULL) {
+ return false;
+ }
+
+ return _nw_protocol_metadata_access_handle(options, access_block);
+}
+
+#define SEC_PROTOCOL_OPTIONS_VALIDATE(o,r) \
+if (o == NULL) { \
+return r; \
+}
+
+#define SEC_PROTOCOL_METADATA_VALIDATE(m,r) \
+if (((void *)m == NULL) || ((size_t)m == 0)) { \
+return r; \
+}
+
+void
+sec_protocol_options_set_local_identity(sec_protocol_options_t options, sec_identity_t identity)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->identity != NULL) {
+ sec_release(content->identity);
+ }
+ content->identity = sec_retain(identity);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCipherSuite ciphersuite)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->ciphersuites == NULL) {
+ content->ciphersuites = xpc_array_create(NULL, 0);
+ }
+ xpc_array_set_uint64(content->ciphersuites, XPC_ARRAY_APPEND, (uint64_t)ciphersuite);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, SSLCiphersuiteGroup group)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->ciphersuites == NULL) {
+ content->ciphersuites = xpc_array_create(NULL, 0);
+ }
+
+ // Fetch the list of ciphersuites associated with the ciphersuite group
+ size_t ciphersuite_count = 0;
+ const SSLCipherSuite *list = SSLCiphersuiteGroupToCiphersuiteList(group, &ciphersuite_count);
+ if (list != NULL) {
+ for (size_t i = 0; i < ciphersuite_count; i++) {
+ SSLCipherSuite ciphersuite = list[i];
+ xpc_array_set_uint64(content->ciphersuites, XPC_ARRAY_APPEND, (uint64_t)ciphersuite);
+ }
+ }
+
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProtocol version)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->min_version = version;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_max_version(sec_protocol_options_t options, SSLProtocol version)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->max_version = version;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options, const char *application_protocol)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(application_protocol,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->application_protocols == NULL) {
+ content->application_protocols = xpc_array_create(NULL, 0);
+ }
+ xpc_array_set_string(content->application_protocols, XPC_ARRAY_APPEND, application_protocol);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_server_name(sec_protocol_options_t options, const char *server_name)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(server_name,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->server_name != NULL) {
+ free(content->server_name);
+ }
+ content->server_name = strdup(server_name);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options, dispatch_data_t params)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(params,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->dh_params) {
+ dispatch_release(content->dh_params);
+ }
+ content->dh_params = params;
+ dispatch_retain(params);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options, dispatch_data_t psk, dispatch_data_t psk_identity)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(psk,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->pre_shared_keys == NULL) {
+ content->pre_shared_keys = xpc_array_create(NULL, 0);
+ }
+
+ xpc_object_t psk_data = xpc_data_create_with_dispatch_data(psk);
+ xpc_object_t psk_identity_data = xpc_data_create_with_dispatch_data(psk_identity);
+
+ xpc_object_t tuple = xpc_array_create(NULL, 0);
+ xpc_array_set_value(tuple, XPC_ARRAY_APPEND, psk_data);
+ xpc_array_set_value(tuple, XPC_ARRAY_APPEND, psk_identity_data);
+ xpc_release(psk_data);
+ xpc_release(psk_identity_data);
+
+ xpc_array_set_value(content->pre_shared_keys, XPC_ARRAY_APPEND, tuple);
+ xpc_release(tuple);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options, bool fallback_attempt)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_fallback_attempt = fallback_attempt;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options, bool tickets_enabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_tickets = tickets_enabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options, bool resumption_enabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_resumption = resumption_enabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options, bool false_start_enabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_false_start = false_start_enabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, bool early_data_enabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_early_data = early_data_enabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options, bool sni_disabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->disable_sni = sni_disabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce_ev)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enforce_ev = enforce_ev;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options, bool ocsp_enabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_ocsp = ocsp_enabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options, bool sct_enabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_sct = sct_enabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options, bool renegotiation_enabled)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->enable_renegotiation = renegotiation_enabled;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options, bool peer_authentication_required)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ content->peer_authentication_required = peer_authentication_required;
+ content->peer_authentication_override = true;
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_key_update_block(sec_protocol_options_t options, sec_protocol_key_update_t update_block, dispatch_queue_t update_queue)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->key_update_block != NULL) {
+ Block_release(content->key_update_block);
+ }
+ if (content->key_update_queue != NULL) {
+ dispatch_release(content->key_update_queue);
+ }
+
+ content->key_update_block = Block_copy(update_block);
+ content->key_update_queue = Block_copy(update_queue);
+ dispatch_retain(content->key_update_queue);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_challenge_block(sec_protocol_options_t options, sec_protocol_challenge_t challenge_block, dispatch_queue_t challenge_queue)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(challenge_queue,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->challenge_block != NULL) {
+ Block_release(content->challenge_block);
+ }
+ if (content->challenge_queue != NULL) {
+ dispatch_release(content->challenge_queue);
+ }
+
+ content->challenge_block = Block_copy(challenge_block);
+ content->challenge_queue = challenge_queue;
+ dispatch_retain(content->challenge_queue);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_set_verify_block(sec_protocol_options_t options, sec_protocol_verify_t verify_block, dispatch_queue_t verify_queue)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(verify_queue,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->verify_block != NULL) {
+ Block_release(content->verify_block);
+ }
+ if (content->verify_queue != NULL) {
+ dispatch_release(content->verify_queue);
+ }
+
+ content->verify_block = Block_copy(verify_block);
+ content->verify_queue = verify_queue;
+ dispatch_retain(content->verify_queue);
+ return true;
+ });
+}
+
+void
+sec_protocol_options_add_tls_extension(sec_protocol_options_t options, sec_tls_extension_t extension)
+{
+ SEC_PROTOCOL_OPTIONS_VALIDATE(options,);
+ SEC_PROTOCOL_OPTIONS_VALIDATE(extension,);
+
+ (void)sec_protocol_options_access_handle(options, ^bool(void *handle) {
+ sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle;
+ SEC_PROTOCOL_OPTIONS_VALIDATE(content, false);
+
+ if (content->custom_extensions == NULL) {
+ content->custom_extensions = sec_array_create();
+ }
+
+ sec_array_append(content->custom_extensions, (sec_object_t)extension);
+ return true;
+ });
+}
+
+const char *
+sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL);
+
+ __block const char *negotiated_protocol = NULL;
+ (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ negotiated_protocol = content->negotiated_protocol;
+ return true;
+ });
+
+ return negotiated_protocol;
+}
+
+bool
+sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata,
+ void (^handler)(sec_certificate_t certficate))
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+ SEC_PROTOCOL_METADATA_VALIDATE(handler, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ if (content->peer_certificate_chain == NULL) {
+ return false;
+ }
+ sec_array_t array = content->peer_certificate_chain;
+ sec_array_apply(array, ^bool(__unused size_t index, sec_object_t object) {
+ handler((sec_certificate_t)object);
+ return true;
+ });
+ return true;
+ });
+}
+
+dispatch_data_t
+sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL);
+
+ __block dispatch_data_t peer_public_key = NULL;
+ (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ peer_public_key = ((dispatch_data_t)content->peer_public_key);
+ if (peer_public_key) {
+ dispatch_retain(peer_public_key);
+ }
+ return true;
+ });
+
+ return peer_public_key;
+}
+
+SSLProtocol
+sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, kSSLProtocolUnknown);
+
+ __block SSLProtocol protocol_version = kSSLProtocolUnknown;
+ (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ protocol_version = content->negotiated_protocol_version;
+ return true;
+ });
+
+ return protocol_version;
+}
+
+SSLCipherSuite
+sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, SSL_NO_SUCH_CIPHERSUITE);
+
+ __block SSLCipherSuite negotiated_ciphersuite = SSL_NO_SUCH_CIPHERSUITE;
+ (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ negotiated_ciphersuite = content->negotiated_ciphersuite;
+ return true;
+ });
+
+ return negotiated_ciphersuite;
+}
+
+bool
+sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ return content->early_data_accepted;
+ });
+}
+
+bool
+sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata,
+ void (^handler)(uint16_t signature_algorithm))
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+ SEC_PROTOCOL_METADATA_VALIDATE(handler, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ if (content->supported_signature_algorithms == NULL) {
+ return false;
+ }
+ xpc_object_t array = content->supported_signature_algorithms;
+ xpc_array_apply(array, ^bool(__unused size_t index, xpc_object_t _Nonnull value) {
+ handler((uint16_t)xpc_uint64_get_value(value));
+ return true;
+ });
+ return true;
+ });
+}
+
+bool
+sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata,
+ void (^handler)(dispatch_data_t ocsp_data))
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+ SEC_PROTOCOL_METADATA_VALIDATE(handler, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ if (content->ocsp_response == NULL) {
+ return false;
+ }
+ sec_array_t array = content->ocsp_response;
+ sec_array_apply(array, ^bool(__unused size_t index, sec_object_t object) {
+ handler((dispatch_data_t)object);
+ return true;
+ });
+ return true;
+ });
+}
+
+bool
+sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata,
+ void (^handler)(dispatch_data_t distinguished_name))
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+ SEC_PROTOCOL_METADATA_VALIDATE(handler, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ if (content->distinguished_names == NULL) {
+ return false;
+ }
+ sec_array_t array = content->distinguished_names;
+ sec_array_apply(array, ^bool(__unused size_t index, sec_object_t object) {
+ handler((dispatch_data_t)object);
+ return true;
+ });
+ return true;
+ });
+}
+
+static bool
+sec_protocol_dispatch_data_are_equal(dispatch_data_t left, dispatch_data_t right)
+{
+ if (!left || !right || left == right) {
+ return left == right;
+ }
+ if (dispatch_data_get_size(left) != dispatch_data_get_size(right)) {
+ return false;
+ }
+
+ __block bool equal = true;
+ dispatch_data_apply(left, ^bool(__unused dispatch_data_t _Nonnull lregion, size_t loffset, const void * _Nonnull lbuffer, size_t lsize) {
+ dispatch_data_apply(right, ^bool(__unused dispatch_data_t _Nonnull rregion, size_t roffset, const void * _Nonnull rbuffer, size_t rsize) {
+ // There is some overlap
+ const size_t start = MAX(loffset, roffset);
+ const size_t end = MIN(loffset + lsize, roffset + rsize);
+ if (start < end) {
+ equal = memcmp(&((const uint8_t*)rbuffer)[start - roffset], &((const uint8_t*)lbuffer)[start - loffset], end - start) == 0;
+ } else {
+ if (roffset > loffset + lsize) {
+ // Iteration of right has gone past where we're at on left, bail out of inner apply
+ // left |---|
+ // right |---|
+ return false;
+ } else if (roffset + rsize < loffset) {
+ // Iteration of right has not yet reached where we're at on left, keep going
+ // left |---|
+ // right |--|
+ return true;
+ }
+ }
+ return equal;
+ });
+ return equal;
+ });
+ return equal;
+}
+
+static bool
+sec_protocol_sec_array_of_dispatch_data_are_equal(sec_array_t arrayA, sec_array_t arrayB)
+{
+ if (sec_array_get_count(arrayA) != sec_array_get_count(arrayB)) {
+ return false;
+ }
+
+ __block bool equal = true;
+ (void)sec_array_apply(arrayA, ^bool(size_t indexA, sec_object_t objectA) {
+ return sec_array_apply(arrayB, ^bool(size_t indexB, sec_object_t objectB) {
+ if (indexA == indexB) {
+ dispatch_data_t dataA = (dispatch_data_t)objectA;
+ dispatch_data_t dataB = (dispatch_data_t)objectB;
+ equal &= sec_protocol_dispatch_data_are_equal(dataA, dataB);
+ return equal;
+ }
+ return true;
+ });
+ });
+
+ return equal;
+}
+
+static bool
+sec_protocol_sec_array_of_sec_certificate_are_equal(sec_array_t arrayA, sec_array_t arrayB)
+{
+ if (sec_array_get_count(arrayA) != sec_array_get_count(arrayB)) {
+ return false;
+ }
+
+ __block bool equal = true;
+ (void)sec_array_apply(arrayA, ^bool(size_t indexA, sec_object_t objectA) {
+ return sec_array_apply(arrayB, ^bool(size_t indexB, sec_object_t objectB) {
+ if (indexA == indexB) {
+ sec_certificate_t certA = (sec_certificate_t)objectA;
+ sec_certificate_t certB = (sec_certificate_t)objectB;
+
+ SecCertificateRef certRefA = sec_certificate_copy_ref(certA);
+ SecCertificateRef certRefB = sec_certificate_copy_ref(certB);
+
+ if (certRefA == NULL && certRefB != NULL) {
+ equal = false;
+ } else if (certRefA != NULL && certRefB == NULL) {
+ equal = false;
+ } else if (certRefA == NULL && certRefB == NULL) {
+ // pass
+ } else {
+ equal &= CFEqual(certRefA, certRefB);
+ }
+
+ CFReleaseSafe(certRefA);
+ CFReleaseSafe(certRefB);
+
+ return equal;
+ }
+ return true;
+ });
+ });
+
+ return equal;
+}
+
+static bool
+sec_protocol_xpc_object_are_equal(xpc_object_t objectA, xpc_object_t objectB)
+{
+ if (objectA == NULL && objectB != NULL) {
+ return false;
+ } else if (objectA != NULL && objectB == NULL) {
+ return false;
+ } else if (objectA == NULL && objectB == NULL) {
+ return true;
+ } else {
+ return xpc_equal(objectA, objectB);
+ }
+}
+
+bool
+sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadataA, false);
+ SEC_PROTOCOL_METADATA_VALIDATE(metadataB, false);
+
+ return sec_protocol_metadata_access_handle(metadataA, ^bool(void *handleA) {
+ sec_protocol_metadata_content_t contentA = (sec_protocol_metadata_content_t)handleA;
+ SEC_PROTOCOL_METADATA_VALIDATE(contentA, false);
+
+ return sec_protocol_metadata_access_handle(metadataB, ^bool(void *handleB) {
+ sec_protocol_metadata_content_t contentB = (sec_protocol_metadata_content_t)handleB;
+ SEC_PROTOCOL_METADATA_VALIDATE(contentB, false);
+
+ // Relevant peer information includes: Certificate chain, public key, support signature algorithms, OCSP response, and distinguished names
+ if (!sec_protocol_sec_array_of_sec_certificate_are_equal(contentA->peer_certificate_chain, contentB->peer_certificate_chain)) {
+ return false;
+ }
+ if (!sec_protocol_dispatch_data_are_equal((dispatch_data_t)contentA->peer_public_key, (dispatch_data_t)contentB->peer_public_key)) {
+ return false;
+ }
+ if (!sec_protocol_xpc_object_are_equal((xpc_object_t)contentA->supported_signature_algorithms, (xpc_object_t)contentB->supported_signature_algorithms)) {
+ return false;
+ }
+ if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA->ocsp_response, contentB->ocsp_response)) {
+ return false;
+ }
+ if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA->distinguished_names, contentB->distinguished_names)) {
+ return false;
+ }
+
+ return true;
+ });
+ });
+}
+
+bool
+sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadataA, false);
+ SEC_PROTOCOL_METADATA_VALIDATE(metadataB, false);
+
+ return sec_protocol_metadata_access_handle(metadataA, ^bool(void *handleA) {
+ sec_protocol_metadata_content_t contentA = (sec_protocol_metadata_content_t)handleA;
+ SEC_PROTOCOL_METADATA_VALIDATE(contentA, false);
+
+ return sec_protocol_metadata_access_handle(metadataB, ^bool(void *handleB) {
+ sec_protocol_metadata_content_t contentB = (sec_protocol_metadata_content_t)handleB;
+ SEC_PROTOCOL_METADATA_VALIDATE(contentB, false);
+
+ if (!sec_protocol_xpc_object_are_equal((xpc_object_t)contentA->supported_signature_algorithms, (xpc_object_t)contentB->supported_signature_algorithms)) {
+ return false;
+ }
+ if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA->distinguished_names, contentB->distinguished_names)) {
+ return false;
+ }
+ if (!sec_protocol_dispatch_data_are_equal(contentA->request_certificate_types, contentB->request_certificate_types)) {
+ return false;
+ }
+
+ return true;
+ });
+ });
+}
+
+dispatch_data_t
+sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata, size_t label_len,
+ const char *label, size_t exporter_length)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(label_len, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(label, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(exporter_length, NULL);
+
+ __block dispatch_data_t secret = NULL;
+ sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+
+ if (content->exporter_function && content->exporter_context) {
+ sec_protocol_metadata_exporter exporter = (sec_protocol_metadata_exporter)content->exporter_function;
+ secret = exporter(content->exporter_context, label_len, label, 0, NULL, exporter_length);
+ }
+ return true;
+ });
+ return secret;
+}
+
+dispatch_data_t
+sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata, size_t label_len,
+ const char *label, size_t context_len,
+ const uint8_t *context, size_t exporter_length)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(label_len, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(label, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(context_len, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(context, NULL);
+ SEC_PROTOCOL_METADATA_VALIDATE(exporter_length, NULL);
+
+ __block dispatch_data_t secret = NULL;
+ sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+
+ if (content->exporter_function && content->exporter_context) {
+ sec_protocol_metadata_exporter exporter = (sec_protocol_metadata_exporter)content->exporter_function;
+ secret = exporter(content->exporter_context, label_len, label, context_len, context, exporter_length);
+ }
+ return true;
+ });
+ return secret;
+}
+
+bool
+sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ return content->false_start_used;
+ });
+}
+
+bool
+sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ return content->ticket_offered;
+ });
+}
+
+bool
+sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ return content->ticket_received;
+ });
+}
+
+bool
+sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ return content->session_resumed;
+ });
+}
+
+bool
+sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata)
+{
+ SEC_PROTOCOL_METADATA_VALIDATE(metadata, false);
+
+ return sec_protocol_metadata_access_handle(metadata, ^bool(void *handle) {
+ sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)handle;
+ SEC_PROTOCOL_METADATA_VALIDATE(content, false);
+ return content->session_renewed;
+ });
+}
+
+void *
+sec_retain(void *obj)
+{
+ if (obj != NULL) {
+ return os_retain(obj);
+ } else {
+ return NULL;
+ }
+}
+
+void
+sec_release(void *obj)
+{
+ if (obj != NULL) {
+ os_release(obj);
+ }
+}
--- /dev/null
+/*
+ * 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 SecProtocol_h
+#define SecProtocol_h
+
+#include <Security/SecProtocolObject.h>
+#include <Security/SecProtocolTypes.h>
+#include <Security/SecProtocolOptions.h>
+#include <Security/SecProtocolMetadata.h>
+
+#endif // SecProtocol_h
--- /dev/null
+/*
+ * 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 SecProtocolMetadata_h
+#define SecProtocolMetadata_h
+
+#include <Security/SecProtocolObject.h>
+#include <Security/SecProtocolTypes.h>
+#include <Security/SecBase.h>
+#include <Security/SecureTransport.h>
+
+#include <dispatch/dispatch.h>
+#include <os/object.h>
+
+/*!
+ * The following diagram shows how clients interact with sec_protocol_options
+ * and sec_protocol_metadata when configuring and using network security protocols.
+ *
+ * +--------+
+ * | Client |
+ * +-+---/ \+
+ * | |
+ * +-------------+ +-------------+
+ * | (1) set (2) get |
+ * | options metadata |
+ * +-----\ /---------------+ +------------+----------+
+ * | sec_protocol_options | | sec_protocol_metadata |
+ * +-----------------------+ +-----------------------+
+ *
+ * Clients configure security protocols with `sec_protocol_options` instances.
+ * And they inspect protocol instances using `sec_protocol_metadata` instances.
+ */
+
+#ifndef SEC_OBJECT_IMPL
+/*!
+ * A `sec_protocol_metadata` instance conatins read-only properties of a connected and configured
+ * security protocol. Clients use this object to read information about a protocol instance. Properties
+ * include, for example, the negotiated TLS version, ciphersuite, and peer certificates.
+ */
+SEC_OBJECT_DECL(sec_protocol_metadata);
+#endif // !SEC_OBJECT_IMPL
+
+__BEGIN_DECLS
+
+SEC_ASSUME_NONNULL_BEGIN
+
+/*!
+ * @function sec_protocol_metadata_get_negotiated_protocol
+ *
+ * @abstract
+ * Get the application protocol negotiated, e.g., via the TLS ALPN extension.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return A NULL-terminated string carrying the negotiated protocol.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+const char * _Nullable
+sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_copy_peer_public_key
+ *
+ * @abstract
+ * Get the protocol instance peer's public key.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return A `dispatch_data_t` containing the peer's raw public key.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED _Nullable dispatch_data_t
+sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_get_negotiated_protocol_version
+ *
+ * @abstract
+ * Get the negotiated TLS version.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return A SSLProtocol enum of the TLS version.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SSLProtocol
+sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_get_negotiated_ciphersuite
+ *
+ * @abstract
+ * Get the negotiated TLS ciphersuite.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return A SSLCipherSuite.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SSLCipherSuite
+sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_get_early_data_accepted
+ *
+ * @abstract
+ * Determine if early data was accepted by the peer.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return A bool indicating if early data was accepted.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata);
+
+#ifdef __BLOCKS__
+/*!
+ * @function sec_protocol_metadata_access_peer_certificate_chain
+ *
+ * @abstract
+ * Get the certificate chain of the protocol instance peer.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param handler
+ * A block to invoke one or more times with sec_certificate_t objects
+ *
+ * @return Returns true if the peer certificates were accessible, false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata,
+ void (^handler)(sec_certificate_t certificate));
+
+/*!
+ * @function sec_protocol_metadata_copy_ocsp_response
+ *
+ * @abstract
+ * Get the OCSP response from the protocol instance peer.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param handler
+ * A block to invoke one or more times with OCSP data
+ *
+ * @return Returns true if the OSCP response was accessible, false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata,
+ void (^handler)(dispatch_data_t ocsp_data));
+
+/*!
+ * @function sec_protocol_metadata_access_supported_signature_algorithms
+ *
+ * @abstract
+ * Get the signature algorithms supported by the peer. Clients may call this
+ * in response to a challenge block.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param handler
+ * A block to invoke one or more times with OCSP data
+ *
+ * @return Returns true if the supported signature list was accessible, false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata,
+ void (^handler)(uint16_t signature_algorithm));
+
+/*!
+ * @function sec_protocol_metadata_access_distinguished_names
+ *
+ * @abstract
+ * Get the X.509 Distinguished Names from the protocol instance peer.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param handler
+ * A block to invoke one or more times with distinguished_name data
+ *
+ * @return Returns true if the distinguished names were accessible, false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata,
+ void (^handler)(dispatch_data_t distinguished_name));
+#endif // __BLOCKS__
+
+/*!
+ * @function sec_protocol_metadata_peers_are_equal
+ *
+ * @abstract
+ * Compare peer information for two `sec_protocol_metadata` instances.
+ * This comparison does not include protocol configuration options, e.g., ciphersuites.
+ *
+ * @param metadataA
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param metadataB
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return Returns true if both metadata values refer to the same peer, and false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB);
+
+/*!
+ * @function sec_protocol_metadata_challenge_parameters_are_equal
+ *
+ * @abstract
+ * Compare challenge-relevant information for two `sec_protocol_metadata` instances.
+ *
+ * This comparison includes all information relevant to a challenge request, including:
+ * distinguished names, signature algorithms, and supported certificate types.
+ * See Section 7.4.4 of RFC5246 for more details.
+ *
+ * @param metadataA
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param metadataB
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return Returns true if both metadata values have the same challenge parameters.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA, sec_protocol_metadata_t metadataB);
+
+/*!
+ * @function sec_protocol_metadata_create_secret
+ *
+ * @abstract
+ * Export a secret, e.g., a cryptographic key, derived from the protocol metadata using a label string.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param label_len
+ * Length of the KDF label string.
+ *
+ * @param label
+ * KDF label string.
+ *
+ * @param exporter_length
+ * Length of the secret to be exported.
+ *
+ * @return Returns a dispatch_data_t object carrying the exported secret.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED _Nullable dispatch_data_t
+sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata, size_t label_len,
+ const char *label, size_t exporter_length);
+
+/*!
+ * @function sec_protocol_metadata_create_secret_with_context
+ *
+ * @abstract
+ * Export a secret, e.g., a cryptographic key, derived from the protocol metadata using a label and context string.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param label_len
+ * Length of the KDF label string.
+ *
+ * @param label
+ * KDF label string.
+ *
+ * @param context_len
+ * Length of the KDF context string.
+ *
+ * @param context
+ * Constant opaque context value
+ *
+ * @param exporter_length
+ * Length of the secret to be exported.
+ *
+ * @return Returns a dispatch_data_t object carrying the exported secret.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED _Nullable dispatch_data_t
+sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata, size_t label_len,
+ const char *label, size_t context_len,
+ const uint8_t *context, size_t exporter_length);
+
+SEC_ASSUME_NONNULL_END
+
+__END_DECLS
+
+#endif // SecProtocolMetadata_h
--- /dev/null
+/*
+ * 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 SecProtocolObject_h
+#define SecProtocolObject_h
+
+#include <sys/cdefs.h>
+#include <os/object.h>
+
+#if OS_OBJECT_USE_OBJC
+# define SEC_OBJECT_DECL(type) OS_OBJECT_DECL(type)
+#else // OS_OBJECT_USE_OBJC
+# define SEC_OBJECT_DECL(type) \
+struct type; \
+typedef struct type *type##_t
+#endif // OS_OBJECT_USE_OBJC
+
+#if __has_feature(assume_nonnull)
+# define SEC_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
+# define SEC_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
+#else // !__has_feature(assume_nonnull)
+# define SEC_ASSUME_NONNULL_BEGIN
+# define SEC_ASSUME_NONNULL_END
+#endif // !__has_feature(assume_nonnull)
+
+#if defined(__OBJC__) && __has_attribute(ns_returns_retained)
+# define SEC_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
+#else // __OBJC__ && ns_returns_retained
+# define SEC_RETURNS_RETAINED
+#endif // __OBJC__ && ns_returns_retained
+
+#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
+__BEGIN_DECLS
+__attribute__((visibility("default"))) void *sec_retain(void *obj);
+__attribute__((visibility("default"))) void sec_release(void *obj);
+__END_DECLS
+#else // !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
+#undef sec_retain
+#undef sec_release
+#define sec_retain(object) [(object) retain]
+#define sec_release(object) [(object) release]
+#endif // !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
+
+#ifndef SEC_OBJECT_IMPL
+/*!
+ * A `sec_object` is a generic, ARC-able type wrapper for common CoreFoundation Security types.
+ */
+SEC_OBJECT_DECL(sec_object);
+#endif // !SEC_OBJECT_IMPL
+
+#endif // SecProtocolObject_h
--- /dev/null
+/*
+ * 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 SecProtocolOptions_h
+#define SecProtocolOptions_h
+
+#include <Security/SecProtocolObject.h>
+#include <Security/SecBase.h>
+#include <Security/SecureTransport.h>
+#include <Security/SecTrust.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecIdentity.h>
+#include <Security/SecProtocolMetadata.h>
+
+#include <dispatch/dispatch.h>
+#include <os/object.h>
+
+/*!
+ * The following diagram shows how clients interact with sec_protocol_options
+ * and sec_protocol_metadata when configuring and using network security protocols.
+ *
+ * +--------+
+ * | Client |
+ * +-+---/ \+
+ * | |
+ * +-------------+ +-------------+
+ * | (1) set (2) get |
+ * | options metadata |
+ * +-----\ /---------------+ +------------+----------+
+ * | sec_protocol_options | | sec_protocol_metadata |
+ * +-----------------------+ +-----------------------+
+ *
+ * Clients configure security protocols with `sec_protocol_options` instances.
+ * And they inspect protocol instances using `sec_protocol_metadata` instances.
+ */
+
+#ifndef SEC_OBJECT_IMPL
+/*!
+ * A `sec_protocol_options` instance is a container of options for security protocol instances,
+ * such as TLS. Protocol options are used to configure security protocols in the network stack.
+ * For example, clients may set the maximum and minimum allowed TLS versions through protocol
+ * options.
+ */
+SEC_OBJECT_DECL(sec_protocol_options);
+#endif // !SEC_OBJECT_IMPL
+
+__BEGIN_DECLS
+
+SEC_ASSUME_NONNULL_BEGIN
+
+/*!
+ * @function sec_protocol_options_set_local_identity
+ *
+ * @abstract
+ * Set the local identity to be used for this protocol instance.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param identity
+ * A `sec_identity_t` instance carrying the private key and certificate.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_local_identity(sec_protocol_options_t options, sec_identity_t identity);
+
+/*!
+ * @function sec_protocol_options_add_tls_ciphersuite
+ *
+ * @abstract
+ * Add a TLS ciphersuite to the set of enabled ciphersuites.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param ciphersuite
+ * A SSLCipherSuite value.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCipherSuite ciphersuite);
+
+/*!
+ * @function sec_protocol_options_add_tls_ciphersuite_group
+ *
+ * @abstract
+ * Add a TLS ciphersuite group to the set of enabled ciphersuites.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param group
+ * A SSLCipherSuiteGroup value.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, SSLCiphersuiteGroup group);
+
+/*!
+ * @function sec_protocol_options_set_tls_min_version
+ *
+ * @abstract
+ * Set the minimum support TLS version.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param version
+ * A SSLProtocol enum value.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProtocol version);
+
+/*!
+ * @function sec_protocol_options_set_tls_max_version
+ *
+ * @abstract
+ * Set the maximum support TLS version.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param version
+ * A SSLProtocol enum value.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_max_version(sec_protocol_options_t options, SSLProtocol version);
+
+/*!
+ * @function sec_protocol_options_add_tls_application_protocol
+ *
+ * @abstract
+ * Add an application protocol supported by clients of this protocol instance.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param application_protocol
+ * A NULL-terminated string defining the application protocol.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options, const char *application_protocol);
+
+/*!
+ * @function sec_protocol_options_set_tls_server_name
+ *
+ * @abstract
+ * Set the server (domain) name to be used in the TLS SNI. This will override
+ * the server name obtained from the endpoint.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param server_name
+ * A NULL-terminated string carrying the server (domain) name.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_server_name(sec_protocol_options_t options, const char *server_name);
+
+/*!
+ * @function sec_protocol_options_set_tls_diffie_hellman_parameters
+ *
+ * @abstract
+ * Set the supported Diffie-Hellman parameters.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param params
+ * A dispatch_data_t containing legacy Diffie-Hellman parameters.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options, dispatch_data_t params);
+
+/*!
+ * @function sec_protocol_options_add_pre_shared_key
+ *
+ * @abstract
+ * Add a pre-shared key (PSK) and its identity to the options.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param psk
+ * A dispatch_data_t containing a PSK blob.
+ *
+ * @param psk_identity
+ * A dispatch_data_t containing a PSK identity blob.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options, dispatch_data_t psk, dispatch_data_t psk_identity);
+
+/*!
+ * @function sec_protocol_options_set_tls_tickets_enabled
+ *
+ * @abstract
+ * Enable or disable TLS session ticket support.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param tickets_enabled
+ * Flag to enable or disable TLS session ticket support.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options, bool tickets_enabled);
+
+/*!
+ * @function sec_protocol_options_set_tls_is_fallback_attempt
+ *
+ * @abstract
+ * Signal if this is a TLS fallback attempt.
+ *
+ * A fallback attempt is one following a previously failed TLS connection
+ * due to version or parameter incompatibility, e.g., when speaking to a server
+ * that does not support a client-offered ciphersuite.
+ *
+ * Clients MUST NOT enable fallback for fresh connections.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param is_fallback_attempt
+ * Set a flag indicating that this is a TLS fallback attempt.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options, bool is_fallback_attempt);
+
+/*!
+ * @function sec_protocol_options_set_tls_resumption_enabled
+ *
+ * @abstract
+ * Enable or disable TLS session resumption.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param resumption_enabled
+ * Flag to enable or disable TLS session resumption.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options, bool resumption_enabled);
+
+/*!
+ * @function sec_protocol_options_set_tls_false_start_enabled
+ *
+ * @abstract
+ * Enable or disable TLS False Start.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param false_start_enabled
+ * Flag to enable or disable TLS False Start.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options, bool false_start_enabled);
+
+/*!
+ * @function nw_protocol_options_set_tls_ocsp_enabled
+ *
+ * @abstract
+ * Enable or disable OCSP support.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param ocsp_enabled
+ * Flag to enable or disable OCSP support.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options, bool ocsp_enabled);
+
+/*!
+ * @function sec_protocol_options_set_tls_sct_enabled
+ *
+ * @abstract
+ * Enable or disable SCT (signed certificate timestamp) support.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param sct_enabled
+ * Flag to enable or disable SCT support.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options, bool sct_enabled);
+
+/*!
+ * @function sec_protocol_options_set_tls_renegotiation_enabled
+ *
+ * @abstract
+ * Enable or disable TLS (1.2 and prior) session renegotiation. This defaults to `true`.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param renegotiation_enabled
+ * Flag to enable or disable TLS (1.2 and prior) session renegotiation.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options, bool renegotiation_enabled);
+
+/*!
+ * @function sec_protocol_options_set_peer_authentication_required
+ *
+ * @abstract
+ * Enable or disable peer authentication. Clients default to true, whereas servers default to false.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param peer_authentication_required
+ * Flag to enable or disable mandatory peer authentication.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options, bool peer_authentication_required);
+
+#ifdef __BLOCKS__
+
+/*!
+ * @block sec_protocol_key_update_complete_t
+ *
+ * @abstract
+ * Block to be invoked when a key update event is handled.
+ */
+typedef void (^sec_protocol_key_update_complete_t)(void);
+
+/*!
+ * @block sec_protocol_key_update_t
+ *
+ * @abstract
+ * Block to be invoked when the protocol key MUST be updated.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param complete
+ * A `sec_protocol_key_update_complete_t` to be invoked when the key update is complete.
+ */
+typedef void (^sec_protocol_key_update_t)(sec_protocol_metadata_t metadata, sec_protocol_key_update_complete_t complete);
+
+/*!
+ * @block sec_protocol_challenge_complete_t
+ *
+ * @abstract
+ * Block to be invoked when an identity (authentication) challenge is complete.
+ *
+ * @param identity
+ * A `sec_identity_t` containing the identity to use for this challenge.
+ */
+typedef void (^sec_protocol_challenge_complete_t)(sec_identity_t identity);
+
+/*!
+ * @block sec_protocol_challenge_t
+ *
+ * @abstract
+ * Block to be invoked when the protocol instance is issued a challenge (e.g., a TLS certificate request).
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param complete
+ * A `sec_protocol_challenge_complete_t` to be invoked when the challenge is complete.
+ */
+typedef void (^sec_protocol_challenge_t)(sec_protocol_metadata_t metadata, sec_protocol_challenge_complete_t complete);
+
+/*!
+ * @block sec_protocol_verify_complete_t
+ *
+ * @abstract
+ * Block to be invoked when verification is complete.
+ *
+ * @param result
+ * A `bool` indicating if verification succeeded or failed.
+ */
+typedef void (^sec_protocol_verify_complete_t)(bool result);
+
+/*!
+ * @block sec_protocol_verify_t
+ *
+ * @abstract
+ * Block to be invoked when the protocol instance must verify the peer.
+ *
+ * NOTE: this may be called one or more times for a given connection.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @param trust_ref
+ * A `sec_trust_t` instance.
+ *
+ * @param complete
+ * A `sec_protocol_verify_finish_t` to be invoked when verification is complete.
+ */
+typedef void (^sec_protocol_verify_t)(sec_protocol_metadata_t metadata, sec_trust_t trust_ref, sec_protocol_verify_complete_t complete);
+
+/*!
+ * @function sec_protocol_options_set_key_update_block
+ *
+ * @abstract
+ * Set the key update block.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param key_update_block
+ * A `sec_protocol_key_update_t` block.
+ *
+ * @params key_update_queue
+ * A `dispatch_queue_t` on which the key update block should be called.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_key_update_block(sec_protocol_options_t options, sec_protocol_key_update_t key_update_block, dispatch_queue_t key_update_queue);
+
+/*!
+ * @function sec_protocol_options_set_challenge_block
+ *
+ * @abstract
+ * Set the challenge block.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @params challenge_block
+ * A `sec_protocol_challenge_t` block.
+ *
+ * @params challenge_queue
+ * A `dispatch_queue_t` on which the challenge block should be called.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_challenge_block(sec_protocol_options_t options, sec_protocol_challenge_t challenge_block, dispatch_queue_t challenge_queue);
+
+/*!
+ * @function sec_protocol_options_set_verify_block
+ *
+ * @abstract
+ * Set the verify block.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @params verify_block
+ * A `sec_protocol_verify_t` block.
+ *
+ * @params verify_block_queue
+ * A `dispatch_queue_t` on which the verify block should be called.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_verify_block(sec_protocol_options_t options, sec_protocol_verify_t verify_block, dispatch_queue_t verify_block_queue);
+
+#endif // __BLOCKS__
+
+SEC_ASSUME_NONNULL_END
+
+__END_DECLS
+
+#endif // SecProtocolOptions_h
--- /dev/null
+//
+// SecProtocolPriv.h
+// Security
+//
+
+#ifndef SecProtocolPriv_h
+#define SecProtocolPriv_h
+
+#include <Security/SecProtocolOptions.h>
+#include <Security/SecProtocolMetadata.h>
+
+__BEGIN_DECLS
+
+typedef struct sec_protocol_options_content {
+ SSLProtocol min_version;
+ SSLProtocol max_version;
+
+ void *ciphersuites; // xpc_object_t (array of uint64)
+
+ void *application_protocols; // xpc_object_t (array of strings)
+
+ void *identity; // sec_identity_t
+ char *server_name;
+
+ void *pre_shared_keys; // xpc_object_t (array of (data, identity))
+
+ void *key_update_block; // sec_protocol_key_update_t
+ void *key_update_queue; // dispatch_queue_t
+ void *challenge_block; // sec_protocol_challenge_t
+ void *challenge_queue; // dispatch_queue_t
+ void *verify_block; // sec_protocol_verify_t
+ void *verify_queue; // dispatch_queue_t
+
+ void *dh_params; // dispatch_data_t
+
+ void *custom_extensions; // sec_array_t of sec_tls_extension_t
+
+ unsigned disable_sni : 1;
+ unsigned enable_fallback_attempt : 1;
+ unsigned enable_false_start : 1;
+ unsigned enable_tickets : 1;
+ unsigned enable_sct : 1;
+ unsigned enable_ocsp : 1;
+ unsigned enforce_ev : 1;
+ unsigned enable_resumption : 1;
+ unsigned enable_renegotiation : 1;
+ unsigned enable_early_data : 1;
+ unsigned peer_authentication_required : 1;
+ unsigned peer_authentication_override : 1;
+} *sec_protocol_options_content_t;
+
+typedef dispatch_data_t (*sec_protocol_metadata_exporter)(void * handle, size_t label_len, const char *label,
+ size_t context_len, const uint8_t *context, size_t exporter_len);
+
+typedef struct sec_protocol_metadata_content {
+ void *peer_certificate_chain; // sec_array_t of sec_certificate_t
+ void *peer_public_key; // dispatch_data_t
+
+ const char *negotiated_protocol;
+
+ SSLProtocol negotiated_protocol_version;
+ SSLCipherSuite negotiated_ciphersuite;
+
+ void *supported_signature_algorithms; // xpc_object_t (array of uint64)
+ void *request_certificate_types; // dispatch_data
+ void *ocsp_response; // sec_array_t of dispatch_data
+ void *distinguished_names; // sec_array_t of dispatch_data
+
+ void *exporter_context; // Opaque context for the exporter function
+ sec_protocol_metadata_exporter exporter_function; // Exporter function pointer. This MUST be set by the metadata allocator.
+
+ unsigned early_data_accepted : 1;
+ unsigned false_start_used : 1;
+ unsigned ticket_offered : 1;
+ unsigned ticket_received : 1;
+ unsigned session_resumed : 1;
+ unsigned session_renewed : 1;
+
+ // Struct padding
+ unsigned __pad_bits : 2;
+} *sec_protocol_metadata_content_t;
+
+#ifndef SEC_OBJECT_IMPL
+SEC_OBJECT_DECL(sec_array);
+#endif // !SEC_OBJECT_IMPL
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED sec_array_t
+sec_array_create(void);
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_array_append(sec_array_t array, sec_object_t object);
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+size_t
+sec_array_get_count(sec_array_t array);
+
+#ifdef __BLOCKS__
+typedef bool (^sec_array_applier_t) (size_t index, sec_object_t object);
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_array_apply(sec_array_t array, sec_array_applier_t applier);
+
+#ifdef __BLOCKS__
+/*!
+ * @block sec_protocol_tls_ext_add_callback
+ *
+ * @param metadata
+ * A valid `sec_protocol_metadata_t` instance.
+ *
+ * @param extension_type
+ * The 2-byte identifier for the extension.
+ *
+ * @param data
+ * Pointer to a uint8_t buffer where the encoded extension data is located.
+ *
+ * @param data_length
+ * Pointer to a variable containing the data length. This should be set to the size of the `data` buffer.
+ *
+ * @param error
+ * Pointer to a return error code that's populated in the event of an error.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+typedef int (^sec_protocol_tls_ext_add_callback)(sec_protocol_metadata_t metadata, uint16_t extension_type,
+ const uint8_t **data, size_t *data_length, int *error);
+
+/*!
+ * @block sec_protocol_tls_ext_free_callback
+ *
+ * @param metadata
+ * A valid `sec_protocol_metadata_t` instance.
+ *
+ * @param extension_type
+ * The 2-byte identifier for the extension.
+ *
+ * @param data
+ * Pointer to a uint8_t buffer where the encoded extension data is located.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+typedef void (^sec_protocol_tls_ext_free_callback)(sec_protocol_metadata_t metadata, uint16_t extension_type,
+ const uint8_t *data);
+
+/*!
+ * @block sec_protocol_tls_ext_parse_callback
+ *
+ * @param metadata
+ * A valid `sec_protocol_metadata_t` handle.
+ *
+ * @param extension_type
+ * The 2-byte identifier for the extension.
+ *
+ * @param data
+ * A buffer where the encoded extension data is stored.
+ *
+ * @param data_length
+ * Length of the encoded extension data.
+ *
+ * @param error
+ * Pointer to a return error code that's populated in the event of an error.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+typedef int (^sec_protocol_tls_ext_parse_callback)(sec_protocol_metadata_t metadata, uint16_t extension_type,
+ const uint8_t *data, size_t data_length,
+ int *error);
+#endif // __BLOCKS__
+
+#ifndef SEC_OBJECT_IMPL
+SEC_OBJECT_DECL(sec_tls_extension);
+#endif // !SEC_OBJECT_IMPL
+
+#ifdef __BLOCKS__
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+uint16_t
+sec_tls_extension_get_type(sec_tls_extension_t extension);
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED sec_protocol_tls_ext_add_callback
+sec_tls_extension_copy_add_block(sec_tls_extension_t extension);
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED sec_protocol_tls_ext_parse_callback
+sec_tls_extension_copy_parse_block(sec_tls_extension_t extension);
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED sec_protocol_tls_ext_free_callback
+sec_tls_extension_copy_free_block(sec_tls_extension_t extension);
+
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+sec_tls_extension_t
+sec_tls_extension_create(uint16_t type, sec_protocol_tls_ext_add_callback add_block,
+ sec_protocol_tls_ext_parse_callback parse_block,
+ sec_protocol_tls_ext_free_callback free_block);
+#endif // __BLOCKS__
+
+/*!
+ * @function sec_protocol_options_add_tls_extension
+ *
+ * @abstract
+ * Add support for a custom TLS extension.
+ *
+ * Clients such as QUIC use this when custom TLS extensions are needed.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param extension
+ * A `sec_tls_extension_t` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_add_tls_extension(sec_protocol_options_t options, sec_tls_extension_t extension);
+
+#endif // __BLOCKS__
+
+/*!
+ * @function sec_protocol_options_set_tls_early_data_enabled
+ *
+ * @abstract
+ * Enable or disable early (0-RTT) data for TLS.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param early_data_enabled
+ * Flag to enable or disable early (0-RTT) data.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, bool early_data_enabled);
+
+/*!
+ * @function sec_protocol_options_set_tls_sni_disabled
+ *
+ * @abstract
+ * Enable or disable the TLS SNI extension. This defaults to `false`.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param sni_disabled
+ * Flag to enable or disable use of the TLS SNI extension.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options, bool sni_disabled);
+
+/*!
+ * @function sec_protocol_options_set_enforce_ev
+ *
+ * @abstract
+ * Enable or disable EV enforcement.
+ *
+ * @param options
+ * A `sec_protocol_options_t` instance.
+ *
+ * @param enforce_ev
+ * Flag to determine if EV is enforced.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+void
+sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce_ev);
+
+/*!
+ * @function sec_protocol_metadata_get_tls_false_start_used
+ *
+ * @abstract
+ * Determine if False Start was used.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return True if False Start was used, and false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_get_ticket_offered
+ *
+ * @abstract
+ * Determine if a ticket was offered for session resumption.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return True if a ticket was offered for resumption, and false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_get_ticket_received
+ *
+ * @abstract
+ * Determine if a ticket was received upon completing the new connection.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return True if a ticket was received from the peer (server), and false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_get_session_resumed
+ *
+ * @abstract
+ * Determine if this new connection was a session resumption.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return True if this new connection was resumed, and false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata);
+
+/*!
+ * @function sec_protocol_metadata_get_session_renewed
+ *
+ * @abstract
+ * Determine if this resumed connection was renewed with a new ticket.
+ *
+ * @param metadata
+ * A `sec_protocol_metadata_t` instance.
+ *
+ * @return True if this resumed connection was renewed with a new ticket, and false otherwise.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+bool
+sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata);
+
+__END_DECLS
+
+#endif /* SecProtocolPriv_h */
--- /dev/null
+/*
+ * 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 SecProtocolTypes_h
+#define SecProtocolTypes_h
+
+#include <Security/SecProtocolObject.h>
+#include <Security/SecTrust.h>
+#include <Security/SecCertificate.h>
+#include <Security/SecIdentity.h>
+
+#ifndef SEC_OBJECT_IMPL
+/*!
+ * These are os_object compatible and ARC-able wrappers around existing CoreFoundation
+ * Security types, including: SecTrustRef, SecIdentityRef, and SecCertificateRef. They allow
+ * clients to use these types in os_object-type APIs and data structures. The underlying
+ * CoreFoundation types may be extracted and used by clients as needed.
+ */
+SEC_OBJECT_DECL(sec_trust);
+SEC_OBJECT_DECL(sec_identity);
+SEC_OBJECT_DECL(sec_certificate);
+#endif // !SEC_OBJECT_IMPL
+
+SEC_ASSUME_NONNULL_BEGIN
+
+/*!
+ * @function sec_trust_create
+ *
+ * @abstract
+ * Create an ARC-able `sec_trust_t` instance from a `SecTrustRef`.
+ *
+ * @param trust
+ * A `SecTrustRef` instance.
+ *
+ * @return a `sec_trust_t` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED _Nullable sec_trust_t
+sec_trust_create(SecTrustRef __nonnull trust);
+
+/*!
+ * @function sec_trust_copy_ref
+ *
+ * @abstract
+ * Copy a retained reference to the underlying `SecTrustRef` instance.
+ *
+ * @param trust
+ * A `sec_trust_t` instance.
+ *
+ * @return The underlying `SecTrustRef` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SecTrustRef
+sec_trust_copy_ref(sec_trust_t __nonnull trust);
+
+/*!
+ * @function sec_identity_create
+ *
+ * @abstract
+ * Create an ARC-able `sec_identity_t` instance from a `SecIdentityRef`.
+ *
+ * @param identity
+ * A `SecIdentityRef` instance.
+ *
+ * @return a `sec_identity_t` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED _Nullable sec_identity_t
+sec_identity_create(SecIdentityRef __nonnull identity);
+
+/*!
+ * @function sec_identity_create_with_certificates
+ *
+ * @abstract
+ * Create an ARC-able `sec_identity_t` instance from a `SecIdentityRef` and
+ * array of SecCertificateRef instances.
+ *
+ * @param identity
+ * A `SecIdentityRef` instance.
+ *
+ * @param certificates
+ * An array of `SecCertificateRef` instances.
+ *
+ * @return a `sec_identity_t` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED _Nullable sec_identity_t
+sec_identity_create_with_certificates(SecIdentityRef __nonnull identity, CFArrayRef __nonnull certificates);
+
+/*!
+ * @function sec_identity_copy_ref
+ *
+ * @abstract
+ * Copy a retained reference to the underlying `SecIdentityRef` instance.
+ *
+ * @param identity
+ * A `sec_identity_t` instance.
+ *
+ * @return The underlying `SecIdentityRef` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SecIdentityRef
+sec_identity_copy_ref(sec_identity_t __nonnull identity);
+
+/*!
+ * @function sec_identity_copy_certificates_ref
+ *
+ * @abstract
+ * Copy a retained reference to the underlying `CFArrayRef` container of `SecCertificateRef` types.
+ *
+ * @param identity
+ * A `sec_identity_t` instance.
+ *
+ * @return The underlying `CFArrayRef` container with `SecCertificateRef` instances.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+CFArrayRef
+sec_identity_copy_certificates_ref(sec_identity_t __nonnull identity);
+
+/*!
+ * @function sec_certificate_create
+ *
+ * @abstract
+ * Create an ARC-able `sec_certificate_t` instance from a `SecCertificateRef`.
+ *
+ * @param certificate
+ * A `SecCertificateRef` instance.
+ *
+ * @return a `sec_certificate_t` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SEC_RETURNS_RETAINED _Nullable sec_certificate_t
+sec_certificate_create(SecCertificateRef __nonnull certificate);
+
+/*!
+ * @function sec_certificate_copy_ref
+ *
+ * @abstract
+ * Copy a retained reference to the underlying `SecCertificateRef` instance.
+ *
+ * @param certificate
+ * A `sec_certificate_t` instance.
+ *
+ * @return The underlying `SecCertificateRef` instance.
+ */
+API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0))
+SecCertificateRef
+sec_certificate_copy_ref(sec_certificate_t __nonnull certificate);
+
+SEC_ASSUME_NONNULL_END
+
+#endif // SecProtocolTypes_h
--- /dev/null
+//
+// SecProtocolTypes.m
+// Security
+//
+
+#include "utilities/SecCFRelease.h"
+
+#define OS_OBJECT_HAVE_OBJC_SUPPORT 1
+
+#define SEC_NULL_BAD_INPUT ((void *_Nonnull)NULL)
+#define SEC_NULL_OUT_OF_MEMORY SEC_NULL_BAD_INPUT
+
+#define SEC_NIL_BAD_INPUT ((void *_Nonnull)nil)
+#define SEC_NIL_OUT_OF_MEMORY SEC_NIL_BAD_INPUT
+
+#define SEC_CONCRETE_CLASS_NAME(external_type) SecConcrete_##external_type
+#define SEC_CONCRETE_PREFIX_STR "SecConcrete_"
+
+#define SEC_OBJECT_DECL_INTERNAL_OBJC(external_type) \
+ @class SEC_CONCRETE_CLASS_NAME(external_type); \
+ typedef SEC_CONCRETE_CLASS_NAME(external_type) *external_type##_t
+
+#define SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, _protocol, visibility, ...) \
+ @protocol OS_OBJECT_CLASS(external_type) <_protocol> \
+ @end \
+ visibility \
+ @interface SEC_CONCRETE_CLASS_NAME(external_type) : NSObject<OS_OBJECT_CLASS(external_type)> \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wobjc-interface-ivars\"") \
+ __VA_ARGS__ \
+ _Pragma("clang diagnostic pop") \
+ @end \
+ typedef int _useless_typedef_oio_##external_type
+
+#define SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL(external_type, _protocol, ...) \
+ SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, _protocol, ,__VA_ARGS__)
+
+#define SEC_OBJECT_IMPL_INTERNAL_OBJC(external_type, ...) \
+ SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL(external_type, NSObject, ##__VA_ARGS__)
+
+#define SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_VISIBILITY(external_type, visibility, ...) \
+ SEC_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, NSObject, visibility, ##__VA_ARGS__)
+
+#define SEC_OBJECT_IMPL 1
+
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_array);
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_identity);
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_trust);
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_certificate);
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_tls_extension);
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_object);
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_options);
+SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_metadata);
+
+#import <Security/SecProtocolPriv.h>
+
+#import <Foundation/Foundation.h>
+#import <CoreFoundation/CoreFoundation.h>
+#import <os/log.h>
+#import <xpc/private.h>
+
+#import <os/object.h>
+
+#ifndef SEC_ANALYZER_HIDE_DEADSTORE
+# ifdef __clang_analyzer__
+# define SEC_ANALYZER_HIDE_DEADSTORE(var) do { if (var) {} } while (0)
+# else // __clang_analyzer__
+# define SEC_ANALYZER_HIDE_DEADSTORE(var) do {} while (0)
+# endif // __clang_analyzer__
+#endif // SEC_ANALYZER_HIDE_DEADSTORE
+
+SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_array,
+{
+ xpc_object_t xpc_array;
+});
+
+@implementation SEC_CONCRETE_CLASS_NAME(sec_array)
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self == nil) {
+ return SEC_NIL_OUT_OF_MEMORY;
+ }
+ self->xpc_array = xpc_array_create(NULL, 0);
+ return self;
+}
+
+- (void)dealloc
+{
+ if (self->xpc_array != nil) {
+ xpc_array_apply(self->xpc_array, ^bool(size_t index, __unused xpc_object_t value) {
+ void *pointer = xpc_array_get_pointer(self->xpc_array, index);
+ sec_object_t object = (sec_object_t)CFBridgingRelease(pointer);
+ SEC_ANALYZER_HIDE_DEADSTORE(object);
+ object = nil;
+ return true;
+ });
+ self->xpc_array = nil;
+ }
+}
+
+sec_array_t
+sec_array_create(void)
+{
+ return [[SEC_CONCRETE_CLASS_NAME(sec_array) alloc] init];
+}
+
+void
+sec_array_append(sec_array_t array, sec_object_t object)
+{
+ if (array != NULL &&
+ array->xpc_array != NULL && xpc_get_type(array->xpc_array) == XPC_TYPE_ARRAY &&
+ object != NULL) {
+ void *retained_pointer = __DECONST(void *, CFBridgingRetain(object));
+ xpc_array_set_pointer(array->xpc_array, XPC_ARRAY_APPEND, retained_pointer);
+ // 'Leak' the retain, and save the pointer into the array
+ }
+}
+
+size_t
+sec_array_get_count(sec_array_t array)
+{
+ if (array != NULL &&
+ array->xpc_array != NULL && xpc_get_type(array->xpc_array) == XPC_TYPE_ARRAY) {
+ return xpc_array_get_count(array->xpc_array);
+ }
+ return 0;
+}
+
+bool
+sec_array_apply(sec_array_t array, sec_array_applier_t applier)
+{
+ if (array != NULL &&
+ array->xpc_array != NULL && xpc_get_type(array->xpc_array) == XPC_TYPE_ARRAY) {
+ return xpc_array_apply(array->xpc_array, ^bool(size_t index, __unused xpc_object_t value) {
+ void *pointer = xpc_array_get_pointer(array->xpc_array, index);
+ return applier(index, (__bridge sec_object_t)(pointer));
+ });
+ }
+ return false;
+}
+
+@end
+
+SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_identity,
+{
+ SecIdentityRef identity;
+ CFArrayRef certs;
+});
+
+@implementation SEC_CONCRETE_CLASS_NAME(sec_identity)
+
+- (instancetype)initWithIdentity:(SecIdentityRef)_identity
+{
+ if (_identity == NULL) {
+ return SEC_NIL_BAD_INPUT;
+ }
+
+ self = [super init];
+ if (self == nil) {
+ return SEC_NIL_OUT_OF_MEMORY;
+ }
+ self->identity = __DECONST(SecIdentityRef, CFRetainSafe(_identity));
+ return self;
+}
+
+- (instancetype)initWithIdentityAndCertificates:(SecIdentityRef)_identity certificates:(CFArrayRef)certificates
+{
+ if (_identity == NULL) {
+ return SEC_NIL_BAD_INPUT;
+ }
+
+ self = [super init];
+ if (self == nil) {
+ return SEC_NIL_OUT_OF_MEMORY;
+ }
+ self->identity = __DECONST(SecIdentityRef, CFRetainSafe(_identity));
+ self->certs = __DECONST(CFArrayRef, CFRetainSafe(certificates));
+
+ return self;
+}
+
+- (void)dealloc
+{
+ if (self->identity != NULL) {
+ CFRelease(self->identity);
+ self->identity = NULL;
+
+ if (self->certs) {
+ CFRelease(self->certs);
+ }
+ self->certs = NULL;
+ }
+}
+
+sec_identity_t
+sec_identity_create(SecIdentityRef identity)
+{
+ return [[SEC_CONCRETE_CLASS_NAME(sec_identity) alloc] initWithIdentity:identity];
+}
+
+sec_identity_t
+sec_identity_create_with_certificates(SecIdentityRef identity, CFArrayRef certificates)
+{
+ return [[SEC_CONCRETE_CLASS_NAME(sec_identity) alloc] initWithIdentityAndCertificates:identity certificates:certificates];
+}
+
+SecIdentityRef
+sec_identity_copy_ref(sec_identity_t object)
+{
+ if (object == NULL) {
+ return SEC_NULL_BAD_INPUT;
+ }
+ if (object->identity != NULL) {
+ return __DECONST(SecIdentityRef, CFRetain(object->identity));
+ }
+ return SEC_NULL_BAD_INPUT;
+}
+
+CFArrayRef
+sec_identity_copy_certificates_ref(sec_identity_t object)
+{
+ if (object == NULL) {
+ return SEC_NULL_BAD_INPUT;
+ }
+ if (object->certs != NULL) {
+ return __DECONST(CFArrayRef, CFRetain(object->certs));
+ }
+ return SEC_NULL_BAD_INPUT;
+}
+
+@end
+
+SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_certificate,
+{
+ SecCertificateRef certificate;
+});
+
+@implementation SEC_CONCRETE_CLASS_NAME(sec_certificate)
+
+- (instancetype)initWithCertificate:(SecCertificateRef)_certificate
+{
+ if (_certificate == NULL) {
+ return SEC_NIL_BAD_INPUT;
+ }
+
+ self = [super init];
+ if (self == nil) {
+ return SEC_NIL_OUT_OF_MEMORY;
+ }
+ self->certificate = __DECONST(SecCertificateRef, CFRetainSafe(_certificate));
+ return self;
+}
+
+- (void)dealloc
+{
+ if (self->certificate != NULL) {
+ CFRelease(self->certificate);
+ self->certificate = NULL;
+ }
+}
+
+sec_certificate_t
+sec_certificate_create(SecCertificateRef certificate)
+{
+ return [[SEC_CONCRETE_CLASS_NAME(sec_certificate) alloc] initWithCertificate:certificate];
+}
+
+SecCertificateRef
+sec_certificate_copy_ref(sec_certificate_t object)
+{
+ if (object == NULL) {
+ return SEC_NULL_BAD_INPUT;
+ }
+ if (object->certificate != NULL) {
+ return __DECONST(SecCertificateRef, CFRetain(object->certificate));
+ }
+ return SEC_NULL_BAD_INPUT;
+}
+
+@end
+
+SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_trust,
+{
+ SecTrustRef trust;
+});
+
+@implementation SEC_CONCRETE_CLASS_NAME(sec_trust)
+
+- (instancetype)initWithTrust:(SecTrustRef)_trust
+{
+ if (_trust == NULL) {
+ return SEC_NIL_BAD_INPUT;
+ }
+
+ self = [super init];
+ if (self == nil) {
+ return SEC_NIL_OUT_OF_MEMORY;
+ }
+ self->trust = __DECONST(SecTrustRef, CFRetainSafe(_trust));
+ return self;
+}
+
+- (void)dealloc
+{
+ if (self->trust != NULL) {
+ CFRelease(self->trust);
+ self->trust = NULL;
+ }
+}
+
+sec_trust_t
+sec_trust_create(SecTrustRef trust)
+{
+ return [[SEC_CONCRETE_CLASS_NAME(sec_trust) alloc] initWithTrust:trust];
+}
+
+SecTrustRef
+sec_trust_copy_ref(sec_trust_t object)
+{
+ if (object == NULL) {
+ return SEC_NULL_BAD_INPUT;
+ }
+ if (object->trust != NULL) {
+ return __DECONST(SecTrustRef, CFRetain(object->trust));
+ }
+ return SEC_NULL_BAD_INPUT;
+}
+
+@end
+
+SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_tls_extension,
+{
+ uint16_t type;
+ sec_protocol_tls_ext_add_callback adder;
+ sec_protocol_tls_ext_parse_callback parser;
+ sec_protocol_tls_ext_free_callback freer;
+});
+
+@implementation SEC_CONCRETE_CLASS_NAME(sec_tls_extension)
+
+- (instancetype)initWithCallbacks:(uint16_t)ext_type
+ adder:(sec_protocol_tls_ext_add_callback)add_block
+ parser:(sec_protocol_tls_ext_parse_callback)parse_block
+ freer:(sec_protocol_tls_ext_free_callback)free_block
+{
+ if (add_block == nil) {
+ return SEC_NIL_BAD_INPUT;
+ }
+ if (parse_block == nil) {
+ return SEC_NIL_BAD_INPUT;
+ }
+ if (free_block == nil) {
+ return SEC_NIL_BAD_INPUT;
+ }
+
+ self = [super init];
+ if (self == nil) {
+ return SEC_NIL_OUT_OF_MEMORY;
+ }
+
+ self->type = ext_type;
+ self->adder = add_block;
+ self->parser = parse_block;
+ self->freer = free_block;
+ return self;
+}
+
+uint16_t
+sec_tls_extension_get_type(sec_tls_extension_t extension)
+{
+ if (extension == NULL) {
+ return 0;
+ }
+
+ return extension->type;
+}
+
+sec_protocol_tls_ext_add_callback
+sec_tls_extension_copy_add_block(sec_tls_extension_t extension)
+{
+ if (extension == NULL) {
+ return SEC_NULL_BAD_INPUT;
+ }
+
+ return extension->adder;
+}
+
+sec_protocol_tls_ext_parse_callback
+sec_tls_extension_copy_parse_block(sec_tls_extension_t extension)
+{
+ if (extension == NULL) {
+ return SEC_NULL_BAD_INPUT;
+ }
+
+ return extension->parser;
+}
+
+sec_protocol_tls_ext_free_callback
+sec_tls_extension_copy_free_block(sec_tls_extension_t extension)
+{
+ if (extension == NULL) {
+ return SEC_NULL_BAD_INPUT;
+ }
+
+ return extension->freer;
+}
+
+sec_tls_extension_t
+sec_tls_extension_create(uint16_t type, sec_protocol_tls_ext_add_callback adder, sec_protocol_tls_ext_parse_callback parser, sec_protocol_tls_ext_free_callback freer)
+{
+ return [[SEC_CONCRETE_CLASS_NAME(sec_tls_extension) alloc] initWithCallbacks:type adder:adder parser:parser freer:freer];
+}
+
+@end
+
--- /dev/null
+/*
+ * 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 "SecCDKeychain.h"
+#import "CKKS.h"
+#import "spi.h"
+#import "SecItemServer.h"
+#import "SecdTestKeychainUtilities.h"
+#import "server_security_helpers.h"
+#import "SecDbKeychainItemV7.h"
+#import "KeychainXCTest.h"
+#import "SecCDKeychainManagedItem+CoreDataClass.h"
+#import "SecFileLocations.h"
+#import <SecurityFoundation/SFEncryptionOperation.h>
+#import <SecurityFoundation/SFKeychain.h>
+#import <XCTest/XCTest.h>
+#import <OCMock/OCMock.h>
+
+#if USE_KEYSTORE
+
+@interface SecCDKeychain (UnitTestingRedeclarations)
+
+@property (readonly, getter=_queue) dispatch_queue_t queue;
+
+- (void)_registerItemTypeForTesting:(SecCDKeychainItemType*)itemType;
+
+- (void)performOnManagedObjectQueue:(void (^)(NSManagedObjectContext* context, NSError* error))block;
+- (void)performOnManagedObjectQueueAndWait:(void (^)(NSManagedObjectContext* context, NSError* error))block;
+- (SecCDKeychainManagedItem*)fetchManagedItemForPersistentID:(NSUUID*)persistentID withManagedObjectContext:(NSManagedObjectContext*)managedObjectContext error:(NSError**)error;
+
+- (NSData*)_onQueueGetDatabaseKeyDataWithError:(NSError**)error;
+- (void)_onQueueDropClassAPersistentStore;
+
+@end
+
+@interface SecCDKeychainItem (UnitTestingRedeclarations)
+
+- (instancetype)initWithManagedItem:(SecCDKeychainManagedItem*)managedItem keychain:(SecCDKeychain*)keychain error:(NSError**)error;
+
+@end
+
+@interface TestItemType : SecCDKeychainItemType
+@end
+
+@implementation TestItemType
+
++ (instancetype)itemType
+{
+ return [[self alloc] _initWithName:@"TestItem" version:1 primaryKeys:nil syncableKeys:nil];
+}
+
+@end
+
+@interface CDKeychainTests : KeychainXCTest
+@end
+
+@implementation CDKeychainTests {
+ SecCDKeychain* _keychain;
+ SFKeychainServerFakeConnection* _connection;
+}
+
+- (void)setUp
+{
+ [super setUp];
+
+ NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain");
+ NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"];
+ NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"];
+ _keychain = [[SecCDKeychain alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:false];
+ _connection = [[SFKeychainServerFakeConnection alloc] init];
+
+ self.keychainPartialMock = OCMPartialMock(_keychain);
+ [[[[self.keychainPartialMock stub] andCall:@selector(getDatabaseKeyDataithError:) onObject:self] ignoringNonObjectArgs] _onQueueGetDatabaseKeyDataWithError:NULL];
+
+ [_keychain _registerItemTypeForTesting:[TestItemType itemType]];
+}
+
+- (void)tearDown
+{
+ [self.keychainPartialMock stopMocking];
+ self.keychainPartialMock = nil;
+
+ [super tearDown];
+}
+
+- (NSArray<SecCDKeychainLookupTuple*>*)lookupTuplesForAttributes:(NSDictionary*)attributes
+{
+ NSMutableArray* lookupTuples = [[NSMutableArray alloc] initWithCapacity:attributes.count];
+ [attributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id value, BOOL* stop) {
+ [lookupTuples addObject:[SecCDKeychainLookupTuple lookupTupleWithKey:key value:value]];
+ }];
+ return lookupTuples;
+}
+
+- (void)testInsertAndRetrieveItemWithPersistentID
+{
+ SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"];
+
+ NSUUID* persistentID = [NSUUID UUID];
+ SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:owner keyclass:key_class_ak];
+
+ XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert item"];
+ [_keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"should have been able to insert item");
+ XCTAssertNil(error, @"should not have gotten an error inserting item");
+ [insertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[insertExpectation] timeout:5.0];
+
+ XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch item"];
+ [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNotNil(fetchedItem, @"should have been able to fetch item");
+ XCTAssertNil(error, @"should not have gotten an error fetching item");
+ XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match inserted item");
+ [fetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[fetchExpectation] timeout:5.0];
+}
+
+- (SecCDKeychainItem*)fullItemForItemMetadata:(SecCDKeychainItemMetadata*)metadata
+{
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ __block SecCDKeychainItem* result = nil;
+ [metadata fetchFullItemWithKeychain:_keychain withConnection:_connection completionHandler:^(SecCDKeychainItem* item, NSError* error) {
+ result = item;
+ dispatch_semaphore_signal(semaphore);
+ }];
+ dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC));
+ return result;
+}
+
+- (void)testLookupItemByAttribute
+{
+ NSUUID* firstItemID = [NSUUID UUID];
+ NSUUID* secondItemID = [NSUUID UUID];
+ NSDictionary* firstItemAttributes = @{@"attribute1" : @"gotIt", @"sharedAttribute" : @"first"};
+ NSDictionary* secondItemAttributes = @{@"attribute2" : @"gotIt", @"sharedAttribute" : @"second"};
+ NSArray* firstItemLookupAttributes = [self lookupTuplesForAttributes:firstItemAttributes];
+ NSArray* secondItemLookupAttributes = [self lookupTuplesForAttributes:secondItemAttributes];
+
+ SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"];
+ SecCDKeychainItem* firstItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:firstItemID attributes:firstItemAttributes lookupAttributes:firstItemLookupAttributes secrets:@{@"data" : @"I'm the first"} owner:owner keyclass:key_class_ak];
+ SecCDKeychainItem* secondItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:secondItemID attributes:secondItemAttributes lookupAttributes:secondItemLookupAttributes secrets:@{@"data" : @"I'm the second"} owner:owner keyclass:key_class_ak];
+
+ XCTestExpectation* insertExpection = [self expectationWithDescription:@"insert items"];
+ [_keychain insertItems:@[firstItem, secondItem] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"failed to successfully insert items with error: %@", error);
+ XCTAssertNil(error, @"encountered error inserting items: %@", error);
+ [insertExpection fulfill];
+ }];
+ [self waitForExpectations:@[insertExpection] timeout:5.0];
+
+ XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch items"];
+ [_keychain fetchItemsWithValue:@"gotIt" forLookupKey:@"attribute1" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray<SecCDKeychainItemMetadata*>* items, NSError* error) {
+ XCTAssertEqual(items.count, (unsigned long)1, @"did not get the expected number of fetched items; expected 1, but got %d", (int)items.count);
+ SecCDKeychainItem* fetchedItem = [self fullItemForItemMetadata:items.firstObject];
+ XCTAssertNotNil(fetchedItem, @"failed to fetch item we just inserted with error: %@", error);
+ XCTAssertNil(error, @"encountered error fetching item: %@", error);
+ XCTAssertEqualObjects(fetchedItem, firstItem, @"fetched item does not match the item we expected to fetch");
+ [fetchExpectation fulfill];
+ }];
+
+ XCTestExpectation* secondFetchExpectation = [self expectationWithDescription:@"second fetch"];
+ [_keychain fetchItemsWithValue:@"first" forLookupKey:@"sharedAttribute" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray<SecCDKeychainItemMetadata*>* items, NSError* error) {
+ XCTAssertEqual(items.count, (unsigned long)1, @"did not get the expected number of fetched items; expected 1, but got %d", (int)items.count);
+ SecCDKeychainItem* fetchedItem = [self fullItemForItemMetadata:items.firstObject];
+ XCTAssertNotNil(fetchedItem, @"failed to fetch item we just inserted with error: %@", error);
+ XCTAssertNil(error, @"encountered error fetching item: %@", error);
+ XCTAssertEqualObjects(fetchedItem, firstItem, @"fetched item does not match the item we expected to fetch");
+ [secondFetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[fetchExpectation, secondFetchExpectation] timeout:5.0];
+}
+
+- (void)testLookupMultipleItems
+{
+ NSUUID* firstItemID = [NSUUID UUID];
+ NSUUID* secondItemID = [NSUUID UUID];
+ NSUUID* thirdUUID = [NSUUID UUID];
+ NSDictionary* firstItemAttributes = @{@"attribute1" : @"gotIt", @"sharedAttribute" : @"bothHaveThis"};
+ NSDictionary* secondItemAttributes = @{@"attribute2" : @"gotIt", @"sharedAttribute" : @"bothHaveThis"};
+ NSDictionary* thirdItemAttributes = @{@"attribute3" : @"gotIt", @"sharedAttribute" : @"somethingDifferent"};
+ NSArray* firstItemLookupAttributes = [self lookupTuplesForAttributes:firstItemAttributes];
+ NSArray* secondItemLookupAttributes = [self lookupTuplesForAttributes:secondItemAttributes];
+ NSArray* thirdItemLookupAttributes = [self lookupTuplesForAttributes:thirdItemAttributes];
+
+ SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"];
+ SecCDKeychainItem* firstItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:firstItemID attributes:firstItemAttributes lookupAttributes:firstItemLookupAttributes secrets:@{@"data" : @"I'm the first"} owner:owner keyclass:key_class_ak];
+ SecCDKeychainItem* secondItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:secondItemID attributes:secondItemAttributes lookupAttributes:secondItemLookupAttributes secrets:@{@"data" : @"I'm the second"} owner:owner keyclass:key_class_ak];
+ SecCDKeychainItem* thirdItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:thirdUUID attributes:thirdItemAttributes lookupAttributes:thirdItemLookupAttributes secrets:@{@"data" : @"I'm the third"} owner:owner keyclass:key_class_ak];
+
+ XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert items"];
+ [_keychain insertItems:@[firstItem, secondItem] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"failed to successfully insert items with error: %@", error);
+ XCTAssertNil(error, @"encountered error inserting items: %@", error);
+ [insertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[insertExpectation] timeout:5.0];
+
+ XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch items"];
+ [_keychain fetchItemsWithValue:@"bothHaveThis" forLookupKey:@"sharedAttribute" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray<SecCDKeychainItemMetadata*>* items, NSError* error) {
+ XCTAssertEqual(items.count, (unsigned long)2, @"did not get the expected number of fetched items; expected 2, but got %d", (int)items.count);
+ XCTAssertNil(error, @"encountered error fetching item: %@", error);
+ if (items.count >= 2) {
+ SecCDKeychainItem* firstFetchedObject = [self fullItemForItemMetadata:items[0]];
+ SecCDKeychainItem* secondFetchedObject = [self fullItemForItemMetadata:items[1]];
+ XCTAssertTrue([firstFetchedObject isEqual:firstItem] || [firstFetchedObject isEqual:secondItem], @"first fetched object does not match either of the items we expected to fetch");
+ XCTAssertTrue([secondFetchedObject isEqual:firstItem] || [secondFetchedObject isEqual:secondItem], @"second fetched object does not match either of the items we expected to fetch");
+ XCTAssertFalse([firstFetchedObject isEqual:secondFetchedObject], @"the objects we got back from our query are unexpectedly equal to each other");
+ XCTAssertFalse([items containsObject:thirdItem.metadata], @"found an unexpected item in our fetch results");
+ }
+ [fetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[fetchExpectation] timeout:5.0];
+}
+
+- (void)testDuplicates
+{
+ // TODO: test some duplicate-rejection scenarios, including the case where no primary keys are explicitly defined
+}
+
+- (void)testAccessGroups
+{
+ [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"TestAccessGroup"]];
+
+ // first we'll try inserting in an access group that should be rejected
+ SecCDKeychainAccessControlEntity* badOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"BadAccessGroup"];
+ NSUUID* persistentID = [NSUUID UUID];
+ SecCDKeychainItem* badItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:badOwner keyclass:key_class_ak];
+
+ XCTestExpectation* badAccessGroupInsertExpectation = [self expectationWithDescription:@"items insert with bad access group"];
+ [_keychain insertItems:@[badItem] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertFalse(success, @"should have rejected insert of item for a bad access group");
+ XCTAssertNotNil(error, @"should have encountered an error for inserting with bad access group");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain");
+ XCTAssertEqual(error.code, SFKeychainErrorInvalidAccessGroup, @"should have gotten the SFKeychainErrorInvalidAccessGroup error code");
+ [badAccessGroupInsertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[badAccessGroupInsertExpectation] timeout:5.0];
+
+ // ok, now try an insertion that should succeed
+ SecCDKeychainAccessControlEntity* goodOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"TestAccessGroup"];
+ SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:goodOwner keyclass:key_class_ak];
+
+ XCTestExpectation* insertExpectation = [self expectationWithDescription:@"items inserted"];
+ [_keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"should have been able to insert item");
+ XCTAssertNil(error, @"should not have gotten an error inserting item");
+ [insertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[insertExpectation] timeout:5.0];
+
+ XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch item"];
+ [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNotNil(fetchedItem, @"should have been able to fetch item");
+ XCTAssertNil(error, @"should not have gotten error fetching item");
+ XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match the inserted item");
+ [fetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[fetchExpectation] timeout:5.0];
+
+ // now change my access group and see if I get the expected error trying to fetch the item
+ [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"NotYourAccessGroup"]];
+
+ XCTestExpectation* badFetchExpectation = [self expectationWithDescription:@"fetch item with bad access group"];
+ [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNil(fetchedItem, @"should not have gotten item when fetching with a bad access group");
+ XCTAssertNotNil(error, @"should have gotten an error fetching item");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain");
+ XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code");
+ [badFetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[badFetchExpectation] timeout:5.0];
+
+ // now try to delete the thing to confirm we cannot
+
+ XCTestExpectation* badDeleteExpectation = [self expectationWithDescription:@"delete item with bad access group"];
+ [_keychain deleteItemWithPersistentID:persistentID withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertFalse(success, @"should not have succeeded at deleting item we don't have access to");
+ XCTAssertNotNil(error, @"should have gotten an error deleting item we don't have access to");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain");
+ XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code");
+ [badDeleteExpectation fulfill];
+ }];
+ [self waitForExpectations:@[badDeleteExpectation] timeout:5.0];
+
+ // switch to the good access group to make sure it's still there
+ [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"TestAccessGroup"]];
+
+ XCTestExpectation* fetchAgainExpecation = [self expectationWithDescription:@"fetch item again"];
+ [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNotNil(fetchedItem, @"should have been able to fetch item");
+ XCTAssertNil(error, @"should not have gotten error fetching item");
+ XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match the inserted item");
+ [fetchAgainExpecation fulfill];
+ }];
+ [self waitForExpectations:@[fetchAgainExpecation] timeout:5.0];
+
+ // and finally delete with proper permissions
+
+ XCTestExpectation* deleteExpectation = [self expectationWithDescription:@"delete item"];
+ [_keychain deleteItemWithPersistentID:persistentID withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"should have succeeded deleting item");
+ XCTAssertNil(error, @"should not have gotten error deleting item: %@", error);
+ [deleteExpectation fulfill];
+ }];
+ [self waitForExpectations:@[deleteExpectation] timeout:5.0];
+
+ XCTestExpectation* postDeleteFetchExpectation = [self expectationWithDescription:@"fetch item after delete"];
+ [_keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNil(fetchedItem, @"should not have gotten item when fetching with a bad access group");
+ XCTAssertNotNil(error, @"should have gotten error for fetch of deleted item");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain");
+ XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code");
+ [postDeleteFetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[postDeleteFetchExpectation] timeout:5.0];
+}
+
+- (void)testDifferentOwnersWithSimilarItems
+{
+ [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"FirstAccessGroup"]];
+ SecCDKeychainAccessControlEntity* firstOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"FirstAccessGroup"];
+
+ NSUUID* firstPersistentID = [NSUUID UUID];
+ SecCDKeychainItem* firstItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:firstPersistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MyFirstSecret"} owner:firstOwner keyclass:key_class_ak];
+
+ XCTestExpectation* firstInsertExpectation = [self expectationWithDescription:@"insert first item"];
+ [_keychain insertItems:@[firstItem] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"should have been able to insert item");
+ XCTAssertNil(error, @"should not have gotten an error inserting item");
+ [firstInsertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[firstInsertExpectation] timeout:5.0];
+
+ [_connection setFakeAccessGroups:[NSArray arrayWithObject:@"SecondAccessGroup"]];
+ SecCDKeychainAccessControlEntity* secondOwner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"SecondAccessGroup"];
+
+ NSUUID* secondPersistentID = [NSUUID UUID];
+ SecCDKeychainItem* secondItem = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:secondPersistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecondSecret"} owner:secondOwner keyclass:key_class_ak];
+
+ XCTestExpectation* secondInsertExpectation = [self expectationWithDescription:@"insert item"];
+ [_keychain insertItems:@[secondItem] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"should have been able to insert item");
+ XCTAssertNil(error, @"should not have gotten an error inserting item");
+ [secondInsertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[secondInsertExpectation] timeout:5.0];
+
+ // now try fetching the first and second items
+ // we should have access to the second but not the first
+
+ XCTestExpectation* firstFetchExpectation = [self expectationWithDescription:@"fetch first item"];
+ [_keychain fetchItemForPersistentID:firstPersistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNil(fetchedItem, @"should not have been able to fetch item from first access group");
+ XCTAssertNotNil(error, @"should have gotten an error fetching item");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain");
+ XCTAssertEqual(error.code, SFKeychainErrorItemNotFound, @"should have gotten the SFKeychainErrorItemNotFound error code");
+ [firstFetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[firstFetchExpectation] timeout:5.0];
+
+ XCTestExpectation* secondFetchExpectation = [self expectationWithDescription:@"fetch second item"];
+ [_keychain fetchItemForPersistentID:secondPersistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNotNil(fetchedItem, @"should have been able to fetch item");
+ XCTAssertNil(error, @"should not have gotten an error fetching item");
+ XCTAssertEqualObjects(fetchedItem, secondItem, @"fetched item should match inserted item");
+ [secondFetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[secondFetchExpectation] timeout:5.0];
+
+ // finally, do a search; make sure it returns exactly one result
+ XCTestExpectation* searchExpectation = [self expectationWithDescription:@"search items"];
+ [_keychain fetchItemsWithValue:@"value" forLookupKey:@"key" ofType:SecCDKeychainLookupValueTypeString withConnection:_connection completionHandler:^(NSArray<SecCDKeychainItemMetadata*>* items, NSError* error) {
+ XCTAssertEqual(items.count, (unsigned long)1, @"should have gotten 1 search result, but got %d", (int)items.count);
+ SecCDKeychainItem* fetchedItem = [self fullItemForItemMetadata:items.firstObject];
+ XCTAssertNotNil(fetchedItem, @"should have been able to fetch full item");
+ XCTAssertNil(error, @"should not have gotten error looking up item");
+ XCTAssertEqualObjects(fetchedItem, secondItem, @"item we looked up should match the one we inserted");
+ [searchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[searchExpectation] timeout:5.0];
+}
+
+- (void)testTamperedMetadata
+{
+ SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"];
+
+ NSUUID* persistentID = [NSUUID UUID];
+ SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MyFirstSecret"} owner:owner keyclass:key_class_ak];
+
+ XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert item"];
+ [_keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"should have been able to insert item");
+ XCTAssertNil(error, @"should not have gotten an error inserting item");
+ [insertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[insertExpectation] timeout:5.0];
+
+ XCTestExpectation* tamperExpectation = [self expectationWithDescription:@"tamper with item"];
+ [_keychain performOnManagedObjectQueue:^(NSManagedObjectContext* managedObjectContext, NSError* managedObjectError) {
+ XCTAssertNotNil(managedObjectContext, @"should have gotten a managed object to perform work with");
+ XCTAssertNil(managedObjectError, @"should not get error performing a block on the managed object context");
+
+ NSError* error = nil;
+ SecCDKeychainManagedItem* managedItem = [self->_keychain fetchManagedItemForPersistentID:persistentID withManagedObjectContext:managedObjectContext error:&error];
+ XCTAssertNotNil(managedItem, @"should have been able to fetch the managed item we just inserted");
+ XCTAssertNil(error, @"should not have gotten an error fetching the managed item");
+
+ // ok, now let's do something nefarious, like change the metadata
+ NSDictionary* fakeMetadata = @{@"key" : @"differentValue"};
+ managedItem.metadata = [NSPropertyListSerialization dataWithPropertyList:fakeMetadata format:NSPropertyListXMLFormat_v1_0 options:9 error:&error];
+ XCTAssertNotNil(managedItem.metadata, @"should have been able to write modified metadata");
+ XCTAssertNil(error, @"should not have gotten an error writing modified metadata");
+
+ SecCDKeychainItem* brokenItem = [[SecCDKeychainItem alloc] initWithManagedItem:managedItem keychain:self->_keychain error:&error];
+ XCTAssertNil(brokenItem, @"should not have been able to create item with tampered metadata");
+ XCTAssertNotNil(error, @"should have gotten an error attempting to create an item with tampered metadata");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"should have gotten an error in the SFKeychainErrorDomain");
+ XCTAssertEqual(error.code, SFKeychainErrorItemDecryptionFailed, @"should have gotten the SFKeychainErrorItemDecryptionFailed error");
+
+ [tamperExpectation fulfill];
+ }];
+ [self waitForExpectations:@[tamperExpectation] timeout:5.0];
+}
+
+@end
+
+// these tests do not wish to have a keychain already setup
+@interface CDKeychainSetupTests : KeychainXCTest
+@end
+
+@implementation CDKeychainSetupTests {
+ SFKeychainServerFakeConnection* _connection;
+}
+
+- (void)setUp
+{
+ [super setUp];
+
+ _connection = [[SFKeychainServerFakeConnection alloc] init];
+}
+
+- (void)testKeychainLocking
+{
+ self.lockState = LockStateLockedAndDisallowAKS;
+
+ NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain");
+ NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"];
+ NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"];
+ SecCDKeychain* keychain = [[SecCDKeychain alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:false];
+ XCTAssertNotNil(keychain, @"should have been able to create a keychain instance");
+
+ self.keychainPartialMock = OCMPartialMock(keychain);
+ [[[[self.keychainPartialMock stub] andCall:@selector(getDatabaseKeyDataithError:) onObject:self] ignoringNonObjectArgs] _onQueueGetDatabaseKeyDataWithError:NULL];
+
+ SecCDKeychainAccessControlEntity* owner = [SecCDKeychainAccessControlEntity accessControlEntityWithType:SecCDKeychainAccessControlEntityTypeAccessGroup stringRepresentation:@"com.apple.token"];
+
+ NSUUID* persistentID = [NSUUID UUID];
+ SecCDKeychainItem* item = [[SecCDKeychainItem alloc] initItemType:[TestItemType itemType] withPersistentID:persistentID attributes:@{@"key" : @"value"} lookupAttributes:nil secrets:@{@"data" : @"MySecret"} owner:owner keyclass:key_class_ak];
+
+ XCTestExpectation* insertExpectation = [self expectationWithDescription:@"insert item"];
+ [keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertFalse(success, @"should not be able to insert item while locked");
+ XCTAssertNotNil(error, @"should get error inserting item while locked");
+
+ // in the future, check for proper error
+ // // <rdar://problem/38972671> add SFKeychainErrorDeviceLocked
+
+ [insertExpectation fulfill];
+ }];
+ [self waitForExpectations:@[insertExpectation] timeout:5.0];
+
+ self.lockState = LockStateUnlocked;
+
+ [keychain _registerItemTypeForTesting:[TestItemType itemType]];
+
+ XCTestExpectation* insertAgainExpectation = [self expectationWithDescription:@"insert item again"];
+ [keychain insertItems:@[item] withConnection:_connection completionHandler:^(bool success, NSError* error) {
+ XCTAssertTrue(success, @"should be able to insert item after unlock");
+ XCTAssertNil(error, @"should not get error inserting after unlock");
+ [insertAgainExpectation fulfill];
+ }];
+ [self waitForExpectations:@[insertAgainExpectation] timeout:5.0];
+
+ XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch item"];
+ [keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNotNil(fetchedItem, @"should have been able to fetch item");
+ XCTAssertNil(error, @"should not have gotten an error fetching item");
+ XCTAssertEqualObjects(fetchedItem, item, @"fetched item should match inserted item");
+ [fetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[fetchExpectation] timeout:5.0];
+
+ self.lockState = LockStateLockedAndDisallowAKS;
+ dispatch_sync(keychain.queue, ^{
+ [keychain _onQueueDropClassAPersistentStore];
+ });
+
+ XCTestExpectation* fetchWhileLockedExpectation = [self expectationWithDescription:@"fetch item while locked"];
+ [keychain fetchItemForPersistentID:persistentID withConnection:_connection completionHandler:^(SecCDKeychainItem* fetchedItem, NSError* error) {
+ XCTAssertNil(fetchedItem, @"should not be able to fetch item while locked");
+ XCTAssertNotNil(error, @"should get an error fetching item while locked");
+
+ // in the future, check for proper error
+ // // <rdar://problem/38972671> add SFKeychainErrorDeviceLocked
+
+ [fetchWhileLockedExpectation fulfill];
+ }];
+ [self waitForExpectations:@[fetchWhileLockedExpectation] timeout:5.0];
+}
+
+@end
+
+#endif
@end
#if USE_KEYSTORE
-#include <libaks.h>
-#endif
+#import <libaks.h>
@interface KeychainCryptoTests : KeychainXCTest
@end
@implementation KeychainCryptoTests
-#if USE_KEYSTORE
-#include <libaks.h>
-
static keyclass_t parse_keyclass(CFTypeRef value) {
if (!value || CFGetTypeID(value) != CFStringGetTypeID()) {
return 0;
}
}
+- (NSDictionary* _Nullable)addTestItemExpecting:(OSStatus)code account:(NSString*)account accessible:(NSString*)accessible
+{
+ NSDictionary* addQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword,
+ (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding],
+ (id)kSecAttrAccount : account,
+ (id)kSecAttrService : [NSString stringWithFormat:@"%@-Service", account],
+ (id)kSecAttrAccessible : (id)accessible,
+ (id)kSecAttrNoLegacy : @(YES),
+ (id)kSecReturnAttributes : @(YES),
+ };
+ CFTypeRef result = NULL;
+
+ if(code == errSecSuccess) {
+ XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), code, @"Should have succeeded in adding test item to keychain");
+ XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd");
+ } else {
+ XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), code, @"Should have failed to adding test item to keychain with code %d", code);
+ XCTAssertNil((__bridge id)result, @"Should not have received a dictionary back from SecItemAdd");
+ }
+
+ return CFBridgingRelease(result);
+}
+
+- (NSDictionary* _Nullable)findTestItemExpecting:(OSStatus)code account:(NSString*)account
+{
+ NSDictionary* findQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword,
+ (id)kSecAttrAccount : account,
+ (id)kSecAttrService : [NSString stringWithFormat:@"%@-Service", account],
+ (id)kSecAttrNoLegacy : @(YES),
+ (id)kSecReturnAttributes : @(YES),
+ };
+ CFTypeRef result = NULL;
+
+ if(code == errSecSuccess) {
+ XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), code, @"Should have succeeded in finding test tiem");
+ XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemCopyMatching");
+ } else {
+ XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), code, @"Should have failed to find items in keychain with code %d", code);
+ XCTAssertNotNil((__bridge id)result, @"Should not have received a dictionary back from SecItemCopyMatching");
+ }
+
+ return CFBridgingRelease(result);
+}
+
+
- (void)testBasicEncryptDecrypt
{
CFDataRef enc = NULL;
CFErrorRef cferror = NULL;
kc_with_dbt(true, &cferror, ^bool(SecDbConnectionRef dbt) {
- CFErrorRef errref;
+ CFErrorRef errref = NULL;
SecDbExec(dbt, CFSTR("DELETE FROM metadatakeys WHERE keyclass = '6'"), &errref);
+ XCTAssertEqual(errref, NULL, "Should be no error deleting class A metadatakey");
CFReleaseNull(errref);
return true;
});
[[SecDbKeychainMetadataKeyStore sharedStore] dropClassAKeys];
}
+- (void)checkDatabaseExistenceOfMetadataKey:(keyclass_t)keyclass shouldExist:(bool)shouldExist
+{
+ CFErrorRef cferror = NULL;
+
+ kc_with_dbt(true, &cferror, ^bool(SecDbConnectionRef dbt) {
+ __block CFErrorRef errref = NULL;
+
+ NSString* sql = [NSString stringWithFormat:@"SELECT data, actualKeyclass FROM metadatakeys WHERE keyclass = %d", keyclass];
+ __block bool ok = true;
+ __block bool keyExists = false;
+ ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &errref, ^(sqlite3_stmt *stmt) {
+ ok &= SecDbStep(dbt, stmt, &errref, ^(bool *stop) {
+ NSData* wrappedKeyData = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)];
+ NSMutableData* unwrappedKeyData = [NSMutableData dataWithLength:wrappedKeyData.length];
+
+ keyExists = !!unwrappedKeyData;
+ });
+ });
+
+ XCTAssertTrue(ok, "Should have completed all operations correctly");
+ XCTAssertEqual(errref, NULL, "Should be no error deleting class A metadatakey");
+
+ if(shouldExist) {
+ XCTAssertTrue(keyExists, "Metadata class key should exist");
+ } else {
+ XCTAssertFalse(keyExists, "Metadata class key should not exist");
+ }
+ CFReleaseNull(errref);
+ return true;
+ });
+ CFReleaseNull(cferror);
+}
+
- (void)testKeychainCorruptionCopyMatching
{
NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword,
OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL);
XCTAssertEqual(result, 0, @"failed to add test item to keychain");
-
+ [self checkDatabaseExistenceOfMetadataKey:key_class_ak shouldExist:true];
NSMutableDictionary* dataQuery = item.mutableCopy;
[dataQuery removeObjectForKey:(id)kSecValueData];
CFReleaseNull(foundItem);
[self trashMetadataClassAKey];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_ak shouldExist:false];
/* 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);
+ // Just calling SecItemCopyMatching shouldn't have created a new metdata key
+ [self checkDatabaseExistenceOfMetadataKey:key_class_ak shouldExist:false];
+
/* semantics are odd, we should be able to delete it */
result = SecItemDelete((__bridge CFDictionaryRef)dataQuery);
XCTAssertEqual(result, 0, @"failed to delete item");
[mockSecDbKeychainMetadataKeyStore stopMocking];
}
+// If a metadata key is created during a database transaction which is later rolled back, it shouldn't be cached for use later.
+- (void)testMetadataKeyDoesntOutliveTxionRollback {
+ NSString* testAccount = @"TestAccount";
+ NSString* otherAccount = @"OtherAccount";
+ NSString* thirdAccount = @"ThirdAccount";
+ [self addTestItemExpecting:errSecSuccess account:testAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlock];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:false];
+
+ // This should fail, and not create a CKU metadata key
+ [self addTestItemExpecting:errSecDuplicateItem account:testAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:false];
+
+ // But successfully creating a new CKU item should create the key
+ [self addTestItemExpecting:errSecSuccess account:otherAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:true];
+
+ // Drop all metadata key caches
+ [SecDbKeychainMetadataKeyStore resetSharedStore];
+
+ [self findTestItemExpecting:errSecSuccess account:testAccount];
+ [self findTestItemExpecting:errSecSuccess account:otherAccount];
+
+ // Adding another CKU item now should be fine
+ [self addTestItemExpecting:errSecSuccess account:thirdAccount accessible:(id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_ck shouldExist:true];
+ [self checkDatabaseExistenceOfMetadataKey:key_class_cku shouldExist:true];
+
+ // Drop all metadata key caches once more, to ensure we can find all three items from the persisted keys
+ [SecDbKeychainMetadataKeyStore resetSharedStore];
+
+ [self findTestItemExpecting:errSecSuccess account:testAccount];
+ [self findTestItemExpecting:errSecSuccess account:otherAccount];
+ [self findTestItemExpecting:errSecSuccess account:thirdAccount];
+}
+
- (void)testRecoverDataFromBadKeyclassStorage
{
NSDictionary* metadataAttributesInput = @{@"TestMetadata" : @"TestValue"};
[self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAfterFirstUnlock];
XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_ck | key_class_last + 1);
-
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAlways];
XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_dk | key_class_last + 1);
+#pragma clang diagnostic pop
[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);
-
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAlwaysThisDeviceOnly];
XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_dku | key_class_last + 1);
+#pragma clang diagnostic pop
[self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly];
XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_akpu | key_class_last + 1);
[self performMetadataDecryptionOfData:encryptedData verifyingAccessibility:kSecAttrAccessibleWhenUnlocked];
}
-#endif
-
@end
+
+#endif
--- /dev/null
+/*
+ * 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 <Security/Security.h>
+#import <Security/SecItemPriv.h>
+
+#import "KeychainXCTest.h"
+
+#if USE_KEYSTORE
+@interface KeychainEntitlementsTest : KeychainXCTest
+@end
+
+@implementation KeychainEntitlementsTest
+
+- (void)testNoEntitlements {
+ NSDictionary *params = @{ (id)kSecAttrNoLegacy: @YES,
+ (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrLabel: @"label", };
+
+ // Application with no keychain-related entitlements at all, but CopyMatching must work in order to support
+ // backward compatibility with smart-card-enabled macos applications (com.apple.token AG is added automatically in this case).
+ [self setEntitlements:@{} validated:false];
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound);
+
+ // However, write access is declined for such application.
+ XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement);
+ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement);
+}
+
+#if TARGET_OS_OSX
+- (void)testInvalidEntitlementsAppID {
+ NSDictionary *params;
+ params = @{ (id)kSecAttrNoLegacy: @YES,
+ (id)kSecClass: (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel: @"label", };
+
+ // Un-validated app-identifier entitlements must disallow any access to the keychain.
+ [self setEntitlements:@{ @"com.apple.application-identifier": @"com.apple.test-app-identifier" } validated:false];
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecMissingEntitlement);
+ XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement);
+ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement);
+
+ // However, keychain-access-groups entitlements should work even if not validated, AMFI will take care
+ // about cases when keychain-access-groups is not correctly used and we have to support cases when
+ // process contains application-groups entitlement but that entitlement is not present in provisioned profile, thus
+ // failing entitlement validation test.
+ [self setEntitlements:@{ @"keychain-access-groups": @[@"com.apple.test-app-identifier"] } validated:false];
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound);
+ XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecSuccess);
+ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecSuccess);
+}
+#endif // TARGET_OS_OSX
+
+- (void)testValidEntitlementsAppID {
+ NSDictionary *params;
+ params = @{ (id)kSecAttrNoLegacy: @YES,
+ (id)kSecClass: (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel: @"label",
+ (id)kSecAttrAccessGroup: @"com.apple.test-app-identifier", };
+#if TARGET_OS_OSX
+ [self setEntitlements:@{ @"com.apple.application-identifier": @"com.apple.test-app-identifier" } validated:true];
+#else
+ [self setEntitlements:@{ @"application-identifier": @"com.apple.test-app-identifier" } validated:true];
+#endif
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound);
+ XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecSuccess);
+ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecSuccess);
+}
+
+- (void)testDisallowTokenGroupWrite {
+ NSDictionary *params;
+
+ // Explicit com.apple.token agrp is not acceptable for writing operations, but acceptable for reading.
+ params = @{ (id)kSecAttrNoLegacy: @YES,
+ (id)kSecClass: (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel: @"label",
+ (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, };
+ [self setEntitlements:@{ @"com.apple.application-identifier": (id)kSecAttrAccessGroupToken } validated:true];
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound);
+ XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement);
+ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement);
+}
+
+#if TARGET_OS_OSX
+- (void)testInvalidAppGroups {
+ NSDictionary *params;
+ params = @{ (id)kSecAttrNoLegacy: @YES,
+ (id)kSecClass: (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel: @"label", };
+ [self setEntitlements:@{ @"com.apple.security.application-groups": @[@"com.apple.test-app-groups"] } validated:false];
+
+ // Invalid access group entitlement should still allow querying com.apple.token
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound);
+
+ // But write-access is forbidden,
+ XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement);
+ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement);
+
+ // Similarly as explicitly referring to AG specified in unverified entitlements.
+ params = @{ (id)kSecAttrNoLegacy: @YES,
+ (id)kSecClass: (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel: @"label",
+ (id)kSecAttrAccessGroup: @"com.apple.test-app-groups", };
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound);
+ XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement);
+ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement);
+
+ // Explicitly referring to com.apple.token should work fine too.
+ params = @{ (id)kSecAttrNoLegacy: @YES,
+ (id)kSecClass: (id)kSecClassGenericPassword,
+ (id)kSecAttrLabel: @"label",
+ (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, };
+ XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound);
+}
+#endif // TARGET_OS_OSX
+
+@end
+
+#endif // USE_KEYSTORE
+
#import "KeychainXCTest.h"
#import "SecItemServer.h"
+#import "SFKeychainServer.h"
#import <SecurityFoundation/SFEncryptionOperation.h>
#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#if USE_KEYSTORE
-#include <libaks.h>
+#import <libaks.h>
typedef enum {
LockStateUnlocked,
@property SFAESKeySpecifier* keySpecifier;
@property SFAESKey* fakeAKSKey;
+@property id keychainPartialMock;
+
- (bool)setNewFakeAKSKey:(NSData*)newKeyData;
+- (void)setEntitlements:(NSDictionary<NSString *, id> *)entitlements validated:(BOOL)validated;
+
+- (NSData*)getDatabaseKeyDataithError:(NSError**)error;
+
+@end
+
+@interface SFKeychainServerFakeConnection : SFKeychainServerConnection
+
+- (void)setFakeAccessGroups:(NSArray*)fakeAccessGroups;
+
@end
#endif
#import "CKKS.h"
#import "SecDbKeychainItemV7.h"
#import "SecItemPriv.h"
+#import "SecTaskPriv.h"
+#import "server_security_helpers.h"
#import "SecItemServer.h"
#import "spi.h"
#import "SecDbKeychainSerializedItemV7.h"
#import "SecDbKeychainSerializedMetadata.h"
#import "SecDbKeychainSerializedSecretData.h"
#import "SecDbKeychainSerializedAKSWrappedKey.h"
+#import "SecCDKeychain.h"
#import <utilities/SecCFWrappers.h>
#import <SecurityFoundation/SFEncryptionOperation.h>
#import <SecurityFoundation/SFCryptoServicesErrors.h>
+#import <SecurityFoundation/SFKeychain.h>
#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
@end
-@implementation KeychainXCTest
+@interface FakeAKSRefKey : NSObject <SecAKSRefKey>
+@end
+
+@implementation FakeAKSRefKey {
+ SFAESKey* _key;
+}
+
+- (instancetype)initWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass
+{
+ if (self = [super init]) {
+ _key = [[SFAESKey alloc] initRandomKeyWithSpecifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:nil];
+ }
+
+ return self;
+}
+
+- (instancetype)initWithBlob:(NSData*)blob keybag:(keybag_handle_t)keybag
+{
+ if (self = [super init]) {
+ _key = [[SFAESKey alloc] initWithData:blob specifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:nil];
+ }
+
+ return self;
+}
+
+- (NSData*)wrappedDataForKey:(SFAESKey*)key
+{
+ SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]];
+ return [NSKeyedArchiver archivedDataWithRootObject:[encryptionOperation encrypt:key.keyData withKey:_key error:nil] requiringSecureCoding:YES error:nil];
+}
+
+- (SFAESKey*)keyWithWrappedData:(NSData*)wrappedKeyData
+{
+ SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256];
+ SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:keySpecifier];
+ NSData* keyData = [encryptionOperation decrypt:[NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:wrappedKeyData error:nil] withKey:_key error:nil];
+ return [[SFAESKey alloc] initWithData:keyData specifier:keySpecifier error:nil];
+}
+
+- (NSData*)refKeyBlob
+{
+ return _key.keyData;
+}
+
+@end
+
+@implementation SFKeychainServerFakeConnection {
+ NSArray* _fakeAccessGroups;
+}
+
+- (void)setFakeAccessGroups:(NSArray*)fakeAccessGroups
+{
+ _fakeAccessGroups = fakeAccessGroups.copy;
+}
+
+- (NSArray*)clientAccessGroups
+{
+ return _fakeAccessGroups ?: @[@"com.apple.token"];
+}
+
+@end
+
+@implementation KeychainXCTest {
+ id _keychainPartialMock;
+ CFArrayRef _originalAccessGroups;
+
+}
+
+@synthesize keychainPartialMock = _keychainPartialMock;
+ (void)setUp
{
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];
-
+
+ // bring back with <rdar://problem/37523001>
+// [[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(isKeychainUnlocked) onObject:self] isKeychainUnlocked];
+
+ id refKeyMock = OCMClassMock([SecAKSRefKey class]);
+ [[[refKeyMock stub] andCall:@selector(alloc) onObject:[FakeAKSRefKey class]] alloc];
+
NSArray* partsOfName = [self.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ]"]];
secd_test_setup_temp_keychain([partsOfName[1] UTF8String], NULL);
+
+ _originalAccessGroups = SecAccessGroupsGetCurrent();
}
- (void)tearDown
{
[self.mockSecDbKeychainItemV7 stopMocking];
+ SecAccessGroupsSetCurrent(_originalAccessGroups);
+
[super tearDown];
}
if (self.simulateRolledAKSKey && outKeyclass) {
*outKeyclass = keyclass | (key_class_last + 1);
+ } else if (outKeyclass) {
+ *outKeyclass = keyclass;
}
return true;
}
}
+- (NSData*)getDatabaseKeyDataithError:(NSError**)error
+{
+ if (_lockState == LockStateUnlocked) {
+ return [NSData dataWithBytes:"12345678901234567890123456789012" length:32];
+ }
+ else {
+ if (error) {
+ // <rdar://problem/38972671> add SFKeychainErrorDeviceLocked
+ *error = [NSError errorWithDomain:SFKeychainErrorDomain code:SFKeychainErrorFailedToCommunicateWithServer userInfo:nil];
+ }
+ return nil;
+ }
+}
+
+// Mock SecTask entitlement retrieval API, so that we can test access group entitlement parsing code in SecTaskCopyAccessGroups()
+static NSDictionary *currentEntitlements = nil;
+static BOOL currentEntitlementsValidated = false;
+static NSArray *currentAccessGroups = nil;
+
+CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error) {
+ id value = currentEntitlements[(__bridge id)entitlement];
+ if (value == nil && error != NULL) {
+ *error = (CFErrorRef)CFBridgingRetain([NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:nil]);
+ }
+ return CFBridgingRetain(value);
+}
+
+Boolean SecTaskEntitlementsValidated(SecTaskRef task) {
+ return currentEntitlementsValidated;
+}
+
+- (void)setEntitlements:(NSDictionary<NSString *, id> *)entitlements validated:(BOOL)validated {
+ currentEntitlements = entitlements;
+ currentEntitlementsValidated = validated;
+ id task = CFBridgingRelease(SecTaskCreateFromSelf(kCFAllocatorDefault));
+ currentAccessGroups = CFBridgingRelease(SecTaskCopyAccessGroups((__bridge SecTaskRef)task));
+ SecAccessGroupsSetCurrent((__bridge CFArrayRef)currentAccessGroups);
+}
+
@end
#endif
--- /dev/null
+/*
+ * 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 "SFKeychainServer.h"
+#import "SecCDKeychain.h"
+#import "SecFileLocations.h"
+#import <Foundation/Foundation.h>
+#import <Foundation/NSXPCConnection_Private.h>
+#import <XCTest/XCTest.h>
+#import <SecurityFoundation/SFKeychain.h>
+#import <OCMock/OCMock.h>
+
+#if USE_KEYSTORE
+
+@interface SFCredentialStore (UnitTestingForwardDeclarations)
+
+- (instancetype)_init;
+
+- (id<NSXPCProxyCreating>)_serverConnectionWithError:(NSError**)error;
+
+@end
+
+@interface SFKeychainServer (UnitTestingForwardDeclarations)
+
+@property (readonly, getter=_keychain) SecCDKeychain* keychain;
+
+@end
+
+@interface SFKeychainServerConnection (UnitTestingRedeclarations)
+
+- (instancetype)initWithKeychain:(SecCDKeychain*)keychain xpcConnection:(NSXPCConnection*)connection;
+
+@end
+
+@interface SecCDKeychain (UnitTestingRedeclarations)
+
+- (NSData*)_onQueueGetDatabaseKeyDataWithError:(NSError**)error;
+
+@end
+
+@interface KeychainNoXPCServerProxy : NSObject <NSXPCProxyCreating>
+
+@property (readonly) SFKeychainServer* server;
+
+@end
+
+@implementation KeychainNoXPCServerProxy {
+ SFKeychainServer* _server;
+ SFKeychainServerFakeConnection* _connection;
+}
+
+@synthesize server = _server;
+
+- (instancetype)init
+{
+ if (self = [super init]) {
+ NSURL* persistentStoreURL = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"CDKeychain");
+ NSBundle* resourcesBundle = [NSBundle bundleWithPath:@"/System/Library/Keychain/KeychainResources.bundle"];
+ NSURL* managedObjectModelURL = [resourcesBundle URLForResource:@"KeychainModel" withExtension:@"momd"];
+ _server = [[SFKeychainServer alloc] initWithStorageURL:persistentStoreURL modelURL:managedObjectModelURL encryptDatabase:false];
+ _connection = [[SFKeychainServerFakeConnection alloc] initWithKeychain:_server.keychain xpcConnection:nil];
+ }
+
+ return self;
+}
+
+- (id)remoteObjectProxy
+{
+ return _server;
+}
+
+- (id)remoteObjectProxyWithErrorHandler:(void (^)(NSError*))handler
+{
+ return _connection;
+}
+
+@end
+
+@interface SFCredentialStoreTests : KeychainXCTest
+@end
+
+@implementation SFCredentialStoreTests {
+ SFCredentialStore* _credentialStore;
+}
+
++ (void)setUp
+{
+ [super setUp];
+
+ id credentialStoreMock = OCMClassMock([SFCredentialStore class]);
+ [[[[credentialStoreMock stub] andCall:@selector(serverProxyWithError:) onObject:self] ignoringNonObjectArgs] _serverConnectionWithError:NULL];
+}
+
++ (id)serverProxyWithError:(NSError**)error
+{
+ return [[KeychainNoXPCServerProxy alloc] init];
+}
+
+- (void)setUp
+{
+ [super setUp];
+ self.keychainPartialMock = OCMPartialMock([(SFKeychainServer*)[[self.class serverProxyWithError:nil] server] _keychain]);
+ [[[[self.keychainPartialMock stub] andCall:@selector(getDatabaseKeyDataithError:) onObject:self] ignoringNonObjectArgs] _onQueueGetDatabaseKeyDataWithError:NULL];
+
+ _credentialStore = [[SFCredentialStore alloc] _init];
+}
+
+- (BOOL)passwordCredential:(SFPasswordCredential*)firstCredential matchesCredential:(SFPasswordCredential*)secondCredential
+{
+ return [firstCredential.primaryServiceIdentifier isEqual:secondCredential.primaryServiceIdentifier] &&
+ [[NSSet setWithArray:firstCredential.supplementaryServiceIdentifiers] isEqualToSet:[NSSet setWithArray:secondCredential.supplementaryServiceIdentifiers]] &&
+ [firstCredential.localizedLabel isEqualToString:secondCredential.localizedLabel] &&
+ [firstCredential.localizedDescription isEqualToString:secondCredential.localizedDescription] &&
+ [firstCredential.customAttributes isEqualToDictionary:secondCredential.customAttributes];
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-retain-cycles"
+// we don't care about creating retain cycles inside our testing blocks (they get broken properly anyway)
+
+- (void)testAddAndFetchCredential
+{
+ SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]];
+ __block NSString* credentialIdentifier = nil;
+
+ XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"];
+ [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ credentialIdentifier = persistentIdentifier;
+ XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential");
+ XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error);
+ [addExpectation fulfill];
+ }];
+ [self waitForExpectations:@[addExpectation] timeout:5.0];
+
+ XCTestExpectation* fetchExpecation = [self expectationWithDescription:@"fetch credential"];
+ [_credentialStore fetchPasswordCredentialForPersistentIdentifier:credentialIdentifier withResultHandler:^(SFPasswordCredential* fetchedCredential, NSString* password, NSError* error) {
+ XCTAssertNotNil(fetchedCredential, @"failed to fetch credential just added to store");
+ XCTAssertNil(error, @"received unexpected error fetching credential from store: %@", error);
+ XCTAssertTrue([self passwordCredential:credential matchesCredential:fetchedCredential], @"the credential we fetched from the store does not match the one we added");
+ XCTAssertEqualObjects(password, @"TestPass", @"the password we fetched from the store does not match the one we added");
+ [fetchExpecation fulfill];
+ }];
+ [self waitForExpectations:@[fetchExpecation] timeout:5.0];
+}
+
+- (void)testLookupCredential
+{
+ SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]];
+
+ XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"];
+ [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential");
+ XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error);
+ [addExpectation fulfill];
+ }];
+ [self waitForExpectations:@[addExpectation] timeout:5.0];
+
+ SFServiceIdentifier* serviceIdentifier = [SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"];
+ if (!serviceIdentifier) {
+ XCTAssertTrue(false, @"Failed to create a service identifier; aborting test");
+ return;
+ }
+
+ XCTestExpectation* lookupExpecation = [self expectationWithDescription:@"lookup credential"];
+ [_credentialStore lookupCredentialsForServiceIdentifiers:@[serviceIdentifier] withResultHandler:^(NSArray<SFCredential*>* results, NSError* error) {
+ XCTAssertEqual((int)results.count, 1, @"error looking up credentials with service identifiers; expected 1 result but got %d", (int)results.count);
+ XCTAssertTrue([self passwordCredential:credential matchesCredential:(SFPasswordCredential*)results.firstObject], @"the credential we looked up does not match the one we added");
+ [lookupExpecation fulfill];
+ }];
+ [self waitForExpectations:@[lookupExpecation] timeout:5.0];
+}
+
+- (void)testAddDuplicateCredential
+{
+ SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]];
+
+ XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"];
+ [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential");
+ XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error);
+ [addExpectation fulfill];
+ }];
+ [self waitForExpectations:@[addExpectation] timeout:5.0];
+
+ XCTestExpectation* conflictingAddExpectation = [self expectationWithDescription:@"add conflicting item"];
+ SFCredential* conflictingCredential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"DifferentPassword" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]];
+ [_credentialStore addCredential:conflictingCredential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ XCTAssertNil(persistentIdentifier, @"adding a credential seems to have succeeded when we expected it to fail");
+ XCTAssertNotNil(error, @"failed to get error when adding a credential that should be rejected as a duplicate entry");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain, @"duplicate error domain is not SFKeychainErrorDomain");
+ XCTAssertEqual(error.code, SFKeychainErrorDuplicateItem, @"duplicate error is not SFKeychainErrorDuplicateItem");
+ [conflictingAddExpectation fulfill];
+ }];
+ [self waitForExpectations:@[conflictingAddExpectation] timeout:5.0];
+}
+
+- (void)testRemoveCredential
+{
+ SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]];
+
+ __block NSString* newItemPersistentIdentifier = nil;
+ XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"];
+ [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential");
+ XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error);
+
+ newItemPersistentIdentifier = persistentIdentifier;
+ [addExpectation fulfill];
+ }];
+ [self waitForExpectations:@[addExpectation] timeout:5.0];
+
+ XCTestExpectation* removeExpectation = [self expectationWithDescription:@"remove credential"];
+ [_credentialStore removeCredentialWithPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(BOOL success, NSError* error) {
+ XCTAssertTrue(success, @"failed to remove credential from store");
+ XCTAssertNil(error, @"encountered error attempting to remove credential from store: %@", error);
+ [removeExpectation fulfill];
+ }];
+ [self waitForExpectations:@[removeExpectation] timeout:5.0];
+
+ XCTestExpectation* removeAgainExpectation = [self expectationWithDescription:@"remove credential gain"];
+ [_credentialStore removeCredentialWithPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(BOOL success, NSError* error) {
+ XCTAssertFalse(success, @"somehow succeeded at removing a credential that we'd already deleted");
+ XCTAssertNotNil(error, @"failed to get an error attempting to remove credential from store when there should not be a credential to delete");
+ [removeAgainExpectation fulfill];
+ }];
+
+ XCTestExpectation* fetchExpectation = [self expectationWithDescription:@"fetch credential"];
+ [_credentialStore fetchPasswordCredentialForPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(SFPasswordCredential* fetchedCredential, NSString* password, NSError* error) {
+ XCTAssertNil(fetchedCredential, @"found credential that we expected to be deleted");
+ XCTAssertNil(password, @"found password when credential was supposed to be deleted");
+ XCTAssertNotNil(error, "failed to get an error when fetching deleted credential");
+ [fetchExpectation fulfill];
+ }];
+ [self waitForExpectations:@[removeAgainExpectation, fetchExpectation] timeout:5.0];
+
+ // now try adding the thing again to make sure that works
+ XCTestExpectation* addAgainExpectation = [self expectationWithDescription:@"add credential again"];
+ [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential");
+ XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error);
+ XCTAssertNotEqual(persistentIdentifier, newItemPersistentIdentifier, @"the added credential has the same persistent identifier as the item we already deleted");
+
+ newItemPersistentIdentifier = persistentIdentifier;
+ [addAgainExpectation fulfill];
+ }];
+ [self waitForExpectations:@[addAgainExpectation] timeout:5.0];
+
+ XCTestExpectation* fetchAgainExpectation = [self expectationWithDescription:@"fetch credential again"];
+ [_credentialStore fetchPasswordCredentialForPersistentIdentifier:newItemPersistentIdentifier withResultHandler:^(SFPasswordCredential* fetchedCredential, NSString* password, NSError* error) {
+ XCTAssertNotNil(fetchedCredential, @"failed to fetch credential just added to store");
+ XCTAssertNil(error, @"received unexpected error fetching credential from store: %@", error);
+ XCTAssertTrue([self passwordCredential:credential matchesCredential:fetchedCredential], @"the credential we fetched from the store does not match the one we added");
+ XCTAssertEqualObjects(password, @"TestPass", @"the password we fetched from the store does not match the one we added");
+ [fetchAgainExpectation fulfill];
+ }];
+ [self waitForExpectations:@[fetchAgainExpectation] timeout:5.0];
+}
+
+- (void)testRemoveCredentialWithBadPersistentIdentifier
+{
+ SFPasswordCredential* credential = [[SFPasswordCredential alloc] initWithUsername:@"TestUser" password:@"TestPass" primaryServiceIdentifier:[SFServiceIdentifier serviceIdentifierForDomain:@"testdomain.com"]];
+
+ __block NSString* newItemPersistentIdentifier = nil;
+ XCTestExpectation* addExpectation = [self expectationWithDescription:@"add credential"];
+ [_credentialStore addCredential:credential withAccessPolicy:[[SFAccessPolicy alloc] initWithAccessibility:SFAccessibilityMakeWithMode(SFAccessibleWhenUnlocked) sharingPolicy:SFSharingPolicyWithTrustedDevices] resultHandler:^(NSString* persistentIdentifier, NSError* error) {
+ XCTAssertNotNil(persistentIdentifier, @"failed to get persistent identifier for added credential");
+ XCTAssertNil(error, @"received unexpected error attempting to add credential to store: %@", error);
+
+ newItemPersistentIdentifier = persistentIdentifier;
+ [addExpectation fulfill];
+ }];
+ [self waitForExpectations:@[addExpectation] timeout:5.0];
+
+ NSString* wrongPersistentIdentifier = [[NSUUID UUID] UUIDString];
+ XCTestExpectation* removeWrongIdentifierEsxpectation = [self expectationWithDescription:@"remove wrong persistent identifier"];
+ [_credentialStore removeCredentialWithPersistentIdentifier:wrongPersistentIdentifier withResultHandler:^(BOOL success, NSError* error) {
+ XCTAssertFalse(success, @"reported success deleting a credential that was never there");
+ XCTAssertNotNil(error, @"failed to get error when attempting to delete an item with an erroneous persistent identifier");
+ [removeWrongIdentifierEsxpectation fulfill];
+ }];
+
+ NSString* notEvenAUUIDString = @"badstring";
+ XCTestExpectation* removeNonUUIDIdentifierExpectation = [self expectationWithDescription:@"remove non-uuid string identifier"];
+ [_credentialStore removeCredentialWithPersistentIdentifier:notEvenAUUIDString withResultHandler:^(BOOL success, NSError* error) {
+ XCTAssertFalse(success, @"reported success deleting a credential with a malformed persistent identifier");
+ XCTAssertNotNil(error, @"failed to get error when attempting to delete an item with a malformed persistent identifier");
+ XCTAssertEqualObjects(error.domain, SFKeychainErrorDomain);
+ XCTAssertEqual(error.code, SFKeychainErrorInvalidPersistentIdentifier);
+ [removeNonUUIDIdentifierExpectation fulfill];
+ }];
+ [self waitForExpectations:@[removeWrongIdentifierEsxpectation, removeNonUUIDIdentifierExpectation] timeout:5.0];
+}
+
+#pragma clang diagnostic pop
+
+@end
+
+#endif
// TODO: Cache the result
uint32_t csflags = 0;
const uint32_t mask = CS_VALID | CS_KILL | CS_ENTITLEMENTS_VALIDATED;
+ const uint32_t debug_mask = CS_DEBUGGED | CS_ENTITLEMENTS_VALIDATED;
int rc = csops_task(task, CS_OPS_STATUS, &csflags, sizeof(csflags));
- return rc != -1 && ((csflags & mask) == mask);
+ // Allow debugged processes that were valid to continue being treated as valid
+ // We need this all the time (not just on internal) because third parties may need to debug their entitled process in xcode
+ return (rc != -1) && ((mask & csflags) == mask || (debug_mask & csflags) == debug_mask);
}
#include <CoreFoundation/CoreFoundation.h>
#include <mach/message.h>
-#if SEC_OS_IPHONE_INCLUDES
#include <sys/cdefs.h>
-#endif
#if SEC_OS_OSX
#include <Security/SecCode.h>
(id)kSecMatchLimit : (id)kSecMatchLimitAll,
(id)kSecReturnAttributes: @YES,
(id)kSecReturnData: @NO,
+ (id)kSecAttrNoLegacy : @YES,
} mutableCopy];
CFTypeRef result = NULL;
CFReleaseNull(result);
}
-static void idsproxy_print_message(CFDictionaryRef messages)
-{
- NSDictionary<NSString*, NSDictionary*> *idsMessages = (__bridge NSDictionary *)messages;
-
- printf("IDS messages in flight: %d\n", (int)[idsMessages count]);
-
- [idsMessages enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull identifier, NSDictionary* _Nonnull messageDictionary, BOOL * _Nonnull stop) {
- printf("message identifier: %s\n", [identifier cStringUsingEncoding:NSUTF8StringEncoding]);
-
- NSDictionary *messageDataAndPeerID = [messageDictionary valueForKey:(__bridge NSString*)kIDSMessageToSendKey];
- [messageDataAndPeerID enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull peerID, NSData* _Nonnull messageData, BOOL * _Nonnull stop1) {
- if(messageData)
- printf("size of message to recipient: %lu\n", (unsigned long)[messageData length]);
- }];
-
- NSString *deviceID = [messageDictionary valueForKey:(__bridge NSString*)kIDSMessageRecipientDeviceID];
- if(deviceID)
- printf("recipient device id: %s\n", [deviceID cStringUsingEncoding:NSUTF8StringEncoding]);
-
- }];
-}
-
-static void
-idsproxy_sysdiagnose(void)
-{
-
- dispatch_semaphore_t wait_for = dispatch_semaphore_create(0);
- __block CFDictionaryRef returned = NULL;
-
- dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- SOSCloudKeychainRetrievePendingMessageFromProxy(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef error) {
- secdebug("SOSCloudKeychainRetrievePendingMessageFromProxy", "returned: %@", returnedValues);
- CFRetainAssign(returned, returnedValues);
- dispatch_semaphore_signal(wait_for);
- });
-
- dispatch_semaphore_wait(wait_for, dispatch_time(DISPATCH_TIME_NOW, 2ull * NSEC_PER_SEC));
- secdebug("idsproxy sysdiagnose", "messages: %@", returned);
-
- idsproxy_print_message(returned);
-}
static void
analytics_sysdiagnose(void)
engine_sysdiagnose();
homekit_sysdiagnose();
unlock_sysdiagnose();
- idsproxy_sysdiagnose();
analytics_sysdiagnose();
// Keep this one last
{
IOReturn result;
io_service_t aksService = IO_OBJECT_NULL;
- IONotificationPortRef aksNotifyPort = IO_OBJECT_NULL;
+ IONotificationPortRef aksNotifyPort = NULL;
io_object_t notification = IO_OBJECT_NULL;
aksService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kAppleKeyStoreServiceName));
189D462D166AC95C001D8533 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 1000;
ORGANIZATIONNAME = Apple;
};
buildConfigurationList = 189D4630166AC95C001D8533 /* Build configuration list for PBXProject "securityd_service" */;
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPRESSION = lossless;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = 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;
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPRESSION = "respect-asset-catalog";
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_IMPLICIT_RETAIN_SELF = 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;
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = securityd_service/service.entitlements;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
INSTALL_PATH = /usr/libexec;
PRODUCT_NAME = "$(TARGET_NAME)";
};
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = securityd_service/service.entitlements;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
- );
INSTALL_PATH = /usr/libexec;
PRODUCT_NAME = "$(TARGET_NAME)";
};
#include <Security/SecTask.h>
#include <Security/SecTaskPriv.h>
#include <Security/SecKeychainPriv.h>
+#include <Security/SecInternalReleasePriv.h>
#include <MobileKeyBag/MobileKeyBag.h>
#include <corecrypto/ccsha2.h>
#include <corecrypto/cchmac.h>
if (S_ISDIR(st_info.st_mode)) {
created = true;
} else {
- os_log(OS_LOG_DEFAULT, "invalid directory at '%s' moving aside", kb_path);
+ os_log(OS_LOG_DEFAULT, "invalid directory at '%{public}s' moving aside", kb_path);
snprintf(new_path, sizeof(new_path), "%s-invalid", kb_path);
unlink(new_path);
if (rename(kb_path, new_path) != 0) {
- os_log(OS_LOG_DEFAULT, "failed to rename file: %s (%s)", kb_path, strerror(errno));
+ os_log(OS_LOG_DEFAULT, "failed to rename file: %{public}s %{darwin.errno}d", kb_path, errno);
goto done;
}
}
}
if (!created) {
- require_action(mkpath_np(kb_path, 0700) == 0, done, os_log(OS_LOG_DEFAULT, "could not create path: %s (%s)", kb_path, strerror(errno)));
+ require_action(mkpath_np(kb_path, 0700) == 0, done, os_log(OS_LOG_DEFAULT, "could not create path: %{public}s %{darwin.errno}d", kb_path, errno));
created = true;
}
done:
if (!created) {
- os_log(OS_LOG_DEFAULT, "_kb_verify_create_path failed %s", kb_path);
+ os_log(OS_LOG_DEFAULT, "_kb_verify_create_path failed %{public}s", kb_path);
}
return created;
}
_set_thread_credentials(service_user_record_t * ur)
{
int rc = pthread_setugid_np(ur->uid, ur->gid);
- if (rc) { os_log(OS_LOG_DEFAULT, "failed to set thread credential: %i (%s)", errno, strerror(errno)); }
+ if (rc) { os_log(OS_LOG_DEFAULT, "failed to set thread credential: %{darwin.errno}d", errno); }
rc = initgroups(ur->name, ur->gid);
if (rc) { os_log(OS_LOG_DEFAULT, "failed to initgroups: %i", rc); }
_clear_thread_credentials()
{
int rc = pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE);
- if (rc) { os_log(OS_LOG_DEFAULT, "failed to reset thread credential: %i (%s)", errno, strerror(errno)); }
+ if (rc) { os_log(OS_LOG_DEFAULT, "failed to reset thread credential: %{darwin.errno}d", errno); }
}
static bool
if (S_ISREG(st_info.st_mode)) {
exists = true;
} else {
- os_log(OS_LOG_DEFAULT, "invalid file at '%s' moving aside", bag_file);
+ os_log(OS_LOG_DEFAULT, "invalid file at '%{public}s' moving aside", bag_file);
snprintf(new_file, sizeof(new_file), "%s-invalid", bag_file);
unlink(new_file);
if (rename(bag_file, new_file) != 0) {
- os_log(OS_LOG_DEFAULT, "failed to rename file: %s (%s)", bag_file, strerror(errno));
+ os_log(OS_LOG_DEFAULT, "failed to rename file: %{public}s %{darwin.errno}d", bag_file, errno);
}
}
}
require_action(snprintf(tmp_bag, sizeof(tmp_bag), "%s.tmp", bag_file) < sizeof(tmp_bag), done, os_log(OS_LOG_DEFAULT, "path too large"));
fd = open(tmp_bag, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW, 0600);
- require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not create file: %s (%s)", tmp_bag, strerror(errno)));
- require_action(write(fd, data, length) == length, done, os_log(OS_LOG_DEFAULT, "failed to write keybag to disk %s (%s)", tmp_bag, strerror(errno)));
+ require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not create file: %{public}s %{darwin.errno}d", tmp_bag, errno));
+ require_action(write(fd, data, length) == length, done, os_log(OS_LOG_DEFAULT, "failed to write keybag to disk %s %{darwin.errno}d", tmp_bag, errno));
/* try atomic swap (will fail if destination doesn't exist); if that fails, try regular rename */
if (renamex_np(tmp_bag, bag_file, RENAME_SWAP) != 0) {
- os_log(OS_LOG_DEFAULT, "Warning: atomic swap failed, error=%i (%s)", errno, strerror(errno));
- require_noerr_action(rename(tmp_bag, bag_file), done, os_log(OS_LOG_DEFAULT, "could not save keybag file, error=%i (%s)", errno, strerror(errno)));
+ os_log(OS_LOG_DEFAULT, "Warning: atomic swap failed, error= %{darwin.errno}d", errno);
+ require_noerr_action(rename(tmp_bag, bag_file), done, os_log(OS_LOG_DEFAULT, "could not save keybag file, error= %{darwin.errno}d", errno));
} else {
(void)unlink(tmp_bag);
}
_set_thread_credentials(ur);
require(_kb_verify_create_path(ur), done);
- require_action_quiet(lstat(bag_file, &st_info) == 0, done, os_log(OS_LOG_DEFAULT, "failed to stat file: %s (%s)", bag_file, strerror(errno)));
- require_action(S_ISREG(st_info.st_mode), done, os_log(OS_LOG_DEFAULT, "failed to load, not a file: %s", bag_file));
+ require_action_quiet(lstat(bag_file, &st_info) == 0, done, os_log(OS_LOG_DEFAULT, "failed to stat file: %{public}s %{darwin.errno}d", bag_file, errno));
+ require_action(S_ISREG(st_info.st_mode), done, os_log(OS_LOG_DEFAULT, "failed to load, not a file: %{public}s", bag_file));
buf_size = (size_t)st_info.st_size;
fd = open(bag_file, O_RDONLY | O_NOFOLLOW);
- require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not open file: %s (%s)", bag_file, strerror(errno)));
+ require_action(fd != -1, done, os_log(OS_LOG_DEFAULT, "could not open file: %{public}s %{darwin.errno}d", bag_file, errno));
buf = (uint8_t *)calloc(1u, buf_size);
require(buf != NULL, done);
require(ur, out);
if (_kb_load_bag_from_disk(ur, bag_file, &buf, &buf_size, kcv)) {
- require_action(buf && buf_size <= INT_MAX, out, os_log(OS_LOG_DEFAULT, "failed to read: %s", bag_file));
- require_noerr_action(aks_invalidate_bag(buf, (int)buf_size), out, os_log(OS_LOG_DEFAULT, "failed to invalidate file: %s", bag_file));
+ require_action(buf && buf_size <= INT_MAX, out, os_log(OS_LOG_DEFAULT, "failed to read: %{public}s", bag_file));
+ require_noerr_action(aks_invalidate_bag(buf, (int)buf_size), out, os_log(OS_LOG_DEFAULT, "failed to invalidate file: %{public}s", bag_file));
} else {
- os_log(OS_LOG_DEFAULT, "failed to read file: %s", bag_file);
+ os_log(OS_LOG_DEFAULT, "failed to read file: %{public}s", bag_file);
}
out:
}
}
-static int service_kb_load(service_context_t *context, uint64_t * kcv);
+static int service_kb_load(service_context_t *context);
static int service_kb_load_uid(uid_t s_uid, uint64_t * kcv);
-#ifndef AKS_MACOS_ROOT_HANDLE
-#define AKS_MACOS_ROOT_HANDLE 4 //temporary define to avoid dependency on AKS change, filed rdar://problem/30542034
-#endif /* AKS_MACOS_ROOT_HANDLE */
-
static int
_service_kb_set_system(keybag_handle_t handle, keybag_handle_t special_handle)
{
}
static int
-_kb_get_session_handle(service_context_t * context, keybag_handle_t * handle_out, uint64_t * kcv)
+_kb_get_session_handle(service_context_t * context, keybag_handle_t * handle_out)
{
int rc = KB_BagNotLoaded;
require_noerr_quiet(_service_kb_get_system(context->s_uid, handle_out), done);
done:
if (rc == KB_BagNotLoaded) {
- if (service_kb_load(context, kcv) == KB_Success) {
+ if (service_kb_load(context) == KB_Success) {
if (_service_kb_get_system(context->s_uid, handle_out) == kIOReturnSuccess) {
rc = KB_Success;
}
static void update_keybag_handle(keybag_handle_t handle)
{
dispatch_sync(_kb_service_get_dispatch_queue(), ^{
- uid_t uid = abs(handle);
+ uid_t uid = (handle == (-AKS_MACOS_ROOT_HANDLE)) ? 0 : abs(handle);
uint8_t * buf = NULL;
size_t buf_size = 0;
service_user_record_t * ur = NULL;
}
static int
-service_kb_create(service_context_t * context, const void * secret, int secret_len, uint64_t * kcv)
+service_kb_create(service_context_t * context, const void * secret, int secret_len)
{
__block int rc = KB_GeneralError;
require_noerr(rc = aks_create_bag(secret, secret_len, kAppleKeyStoreDeviceBag, &private_handle), done);
require_noerr(rc = aks_save_bag(private_handle, (void**)&buf, (int*)&buf_size), done);
- require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError);
+ require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError);
require_noerr(rc = _service_kb_set_system(private_handle, context->s_uid), done);
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
if (secret && rc == KB_Success) {
aks_unlock_bag(session_handle, secret, secret_len);
}
// this function should never fail unless bootstrapping the user for the first time, or rare conditions from aks_load_bag
if (rc != KB_Success) {
- os_log(OS_LOG_DEFAULT, "%d: error %d loading keybag for uid (%i) at path: %s", _stage, rc, s_uid, bag_file);
+ os_log(OS_LOG_DEFAULT, "%d: error %d loading keybag for uid (%i) at path: %{public}s", _stage, rc, s_uid, bag_file);
}
if (buf) free(buf);
if (ur) free_user_record(ur);
}
static int
-service_kb_load(service_context_t * context, uint64_t * kcv)
+service_kb_load(service_context_t * context)
{
- return _service_kb_load_uid(context->s_uid, kcv);
+ return _service_kb_load_uid(context->s_uid, &context->kcv);
}
static int
}
static int
-service_kb_save(service_context_t * context, uint64_t * kcv)
+service_kb_save(service_context_t * context)
{
__block int rc = KB_GeneralError;
keybag_handle_t session_handle;
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
dispatch_sync(_kb_service_get_dispatch_queue(), ^{
uint8_t * buf = NULL;
require_noerr(rc = aks_save_bag(session_handle, (void**)&buf, (int*)&buf_size), done);
require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError);
require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_user), done, rc = KB_GeneralError);
- require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError);
+ require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError);
rc = KB_Success;
}
static int
-service_kb_unlock(service_context_t * context, const void * secret, int secret_len, uint64_t * kcv)
+service_kb_unlock(service_context_t * context, const void * secret, int secret_len)
{
int rc = KB_GeneralError;
keybag_handle_t session_handle;
require_noerr(_kb_get_options_for_uid(context->s_uid, &options), done);
/* technically, session_handle is not needed. Call this to handle lazy keybag loading */
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
require(passcode = CFDataCreateWithBytesNoCopy(NULL, secret, secret_len, kCFAllocatorNull), done);
}
static int
-service_kb_change_secret(service_context_t * context, const void * secret, int secret_len, const void * new_secret, int new_secret_len, uint64_t * kcv)
+service_kb_change_secret(service_context_t * context, const void * secret, int secret_len, const void * new_secret, int new_secret_len)
{
__block int rc = KB_GeneralError;
keybag_handle_t session_handle;
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
dispatch_sync(_kb_service_get_dispatch_queue(), ^{
uint8_t * buf = NULL;
require_noerr(rc = aks_save_bag(session_handle, (void**)&buf, (int*)&buf_size), done);
require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError);
require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_user), done, rc = KB_GeneralError);
- require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError);
+ require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError);
rc = KB_Success;
}
static int
-service_kb_reset(service_context_t * context, const void * secret, int secret_len, uint64_t * kcv)
+service_kb_reset(service_context_t * context, const void * secret, int secret_len)
{
__block int rc = KB_GeneralError;
service_user_record_t * ur = NULL;
keybag_handle_t private_handle = bad_keybag_handle, session_handle = bad_keybag_handle;
os_log(OS_LOG_DEFAULT, "resetting keybag for uid (%i) in session (%i)", context->s_uid, context->s_id);
- _kb_rename_bag_on_disk(ur, bag_file, kcv);
+ _kb_rename_bag_on_disk(ur, bag_file, &context->kcv);
require_noerr(rc = aks_create_bag(secret, secret_len, kAppleKeyStoreDeviceBag, &private_handle), done);
require_noerr(rc = aks_save_bag(private_handle, (void**)&buf, (int*)&buf_size), done);
- require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, kcv), done, rc = KB_BagError);
+ require_action(_kb_save_bag_to_disk(ur, bag_file, buf, buf_size, &context->kcv), done, rc = KB_BagError);
require_noerr(rc = _service_kb_set_system(private_handle, context->s_uid), done);
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
if (secret && rc == KB_Success) {
aks_unlock_bag(session_handle, secret, secret_len);
}
static int
-service_kb_is_locked(service_context_t * context, xpc_object_t reply, uint64_t * kcv)
+service_kb_is_locked(service_context_t * context, xpc_object_t reply)
{
int rc = KB_GeneralError;
keybag_state_t state;
keybag_handle_t session_handle;
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
require_noerr(rc = aks_get_lock_state(session_handle, &state), done);
}
static int
-service_kb_wrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv)
+service_kb_wrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply)
{
int rc = KB_GeneralError;
size_t sz;
int wrapped_key_size;
keyclass_t wrapped_key_class;
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
key = xpc_dictionary_get_data(event, SERVICE_XPC_KEY, &sz);
require_action(key != NULL, done, rc = KB_GeneralError);
}
static int
-service_kb_unwrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv)
+service_kb_unwrap_key(service_context_t *context, xpc_object_t event, xpc_object_t reply)
{
int rc = KB_GeneralError;
size_t sz;
void *key = NULL;
int key_size;
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
wrapped_key = xpc_dictionary_get_data(event, SERVICE_XPC_WRAPPED_KEY, &sz);
require_action(wrapped_key != NULL, done, rc = KB_GeneralError);
}
static int
-service_kb_stash_create(service_context_t * context, const void * key, unsigned key_size, uint64_t * kcv)
+service_kb_stash_create(service_context_t * context, const void * key, unsigned key_size)
{
int rc = KB_GeneralError;
char * bag_file = NULL;
__block bool saved = false;
require(key, done);
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError);
require_noerr(rc = aks_stash_escrow(session_handle, true, key, key_size, NULL, 0, (void**)&stashbag, &stashbag_size), done);
require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_stash), done, rc = KB_GeneralError);
// sync writing the bag to disk
dispatch_sync(_kb_service_get_dispatch_queue(), ^{
- saved = _kb_save_bag_to_disk(ur, bag_file, stashbag, stashbag_size, kcv);
+ saved = _kb_save_bag_to_disk(ur, bag_file, stashbag, stashbag_size, &context->kcv);
});
require_action(saved, done, rc = KB_BagError);
rc = KB_Success;
}
static int
-service_kb_stash_load(service_context_t * context, const void * key, unsigned key_size, bool nondestructive, uint64_t * kcv)
+service_kb_stash_load(service_context_t * context, const void * key, unsigned key_size, bool nondestructive)
{
__block int rc = KB_GeneralError;
char * bag_file = NULL;
__block size_t stashbag_size = 0;
require(key, done);
- require_noerr(rc = _kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(rc = _kb_get_session_handle(context, &session_handle), done);
require_action(ur = get_user_record(context->s_uid), done, rc = KB_GeneralError);
require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_stash), done, rc = KB_GeneralError);
// sync loading the bag from disk
dispatch_sync(_kb_service_get_dispatch_queue(), ^{
- if (!_kb_load_bag_from_disk(ur, bag_file, &stashbag, &stashbag_size, kcv)) {
+ if (!_kb_load_bag_from_disk(ur, bag_file, &stashbag, &stashbag_size, &context->kcv)) {
rc = KB_BagError;
}
});
done:
if (stashbag) { free(stashbag); }
if ((bag_file) && (!nondestructive)) {
- _kb_delete_bag_on_disk(ur, bag_file, kcv);
+ _kb_delete_bag_on_disk(ur, bag_file, &context->kcv);
free(bag_file);
}
if (ur) free_user_record(ur);
// removed from the keystore after it is returned.
// Requires the entitlement: com.apple.private.securityd.keychain
//
-OSStatus service_stash_get_key(service_context_t * context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv)
+OSStatus service_stash_get_key(service_context_t * context, xpc_object_t event, xpc_object_t reply)
{
getStashKey_InStruct_t inStruct;
getStashKey_OutStruct_t outStruct;
if (kr == KERN_SUCCESS) {
xpc_dictionary_set_data(reply, SERVICE_XPC_KEY, outStruct.outBuf.key.key, outStruct.outBuf.key.keysize);
- service_kb_stash_load(context, outStruct.outBuf.key.key, outStruct.outBuf.key.keysize, false, kcv);
+ service_kb_stash_load(context, outStruct.outBuf.key.key, outStruct.outBuf.key.keysize, false);
} else {
os_log(OS_LOG_DEFAULT, "failed to get stash key: %d", (int)kr);
}
// key and get its uuid. The second uses the uuid to flag the
// key for blob inclusion.
//
-OSStatus service_stash_set_key(service_context_t * context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv)
+OSStatus service_stash_set_key(service_context_t * context, xpc_object_t event, xpc_object_t reply)
{
kern_return_t kr = KERN_INVALID_ARGUMENT;
io_connect_t conn = IO_OBJECT_NULL;
keybag_state_t state;
keybag_handle_t session_handle;
- require_noerr(_kb_get_session_handle(context, &session_handle, kcv), done);
+ require_noerr(_kb_get_session_handle(context, &session_handle), done);
require_noerr(aks_get_lock_state(session_handle, &state), done);
require_action(!(state & keybag_lock_locked), done, kr = CSSMERR_CSP_OS_ACCESS_DENIED; LOG("stash failed keybag locked"));
NULL, NULL);
if (kr == KERN_SUCCESS) {
- service_kb_stash_create(context, keydata, (unsigned)keydata_len, kcv);
+ service_kb_stash_create(context, keydata, (unsigned)keydata_len);
}
done:
os_log(OS_LOG_DEFAULT, "set stashkey %d", (int)kr);
//
// Load the master stash key
//
-OSStatus service_stash_load_key(service_context_t * context, xpc_object_t event, xpc_object_t reply, uint64_t * kcv)
+OSStatus service_stash_load_key(service_context_t * context, xpc_object_t event, xpc_object_t reply)
{
kern_return_t kr = KERN_SUCCESS;
size_t keydata_len = 0;
const uint8_t *keydata = xpc_dictionary_get_data(event, SERVICE_XPC_KEY, &keydata_len);
require(keydata, done);
- kr = service_kb_stash_load(context, keydata, (cryptosize_t) keydata_len, true, kcv);
+ kr = service_kb_stash_load(context, keydata, (cryptosize_t) keydata_len, true);
done:
return kr;
bool free_context = false;
const void * data;
const char *entitlement;
- uint64_t kcv = 0;
xpc_object_t reply = xpc_dictionary_create_reply(event);
context->procToken = audit_token;
free_context = true;
}
+ context->kcv = 0;
require_action(context->s_id != AU_DEFAUDITSID, done, rc = KB_InvalidSession);
require_action(context->s_uid != AU_DEFAUDITID, done, rc = KB_InvalidSession); // we only want to work in actual user sessions.
case SERVICE_KB_CREATE:
// if (kb_service_has_entitlement(peer, "com.apple.keystore.device")) {
secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len);
- rc = service_kb_create(context, secret, (int)secret_len, &kcv);
+ rc = service_kb_create(context, secret, (int)secret_len);
// }
break;
case SERVICE_KB_LOAD:
- rc = service_kb_load(context, &kcv);
+ rc = service_kb_load(context);
break;
case SERVICE_KB_UNLOAD:
rc = service_kb_unload(context);
break;
case SERVICE_KB_SAVE:
- rc = service_kb_save(context, &kcv);
+ rc = service_kb_save(context);
break;
case SERVICE_KB_UNLOCK:
secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len);
- rc = service_kb_unlock(context, secret, (int)secret_len, &kcv);
+ rc = service_kb_unlock(context, secret, (int)secret_len);
break;
case SERVICE_KB_LOCK:
rc = service_kb_lock(context);
case SERVICE_KB_CHANGE_SECRET:
secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len);
new_secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET_NEW, &new_secret_len);
- rc = service_kb_change_secret(context, secret, (int)secret_len, new_secret, (int)new_secret_len, &kcv);
+ rc = service_kb_change_secret(context, secret, (int)secret_len, new_secret, (int)new_secret_len);
break;
case SERVICE_KB_RESET:
secret = xpc_dictionary_get_data(event, SERVICE_XPC_SECRET, &secret_len);
- rc = service_kb_reset(context, secret, (int)secret_len, &kcv);
+ rc = service_kb_reset(context, secret, (int)secret_len);
break;
case SERVICE_KB_IS_LOCKED:
- rc = service_kb_is_locked(context, reply, &kcv);
+ rc = service_kb_is_locked(context, reply);
break;
case SERVICE_STASH_GET_KEY:
- rc = service_stash_get_key(context, event, reply, &kcv);
+ rc = service_stash_get_key(context, event, reply);
break;
case SERVICE_STASH_SET_KEY:
- rc = service_stash_set_key(context, event, reply, &kcv);
+ rc = service_stash_set_key(context, event, reply);
break;
case SERVICE_STASH_LOAD_KEY:
- rc = service_stash_load_key(context, event, reply, &kcv);
+ rc = service_stash_load_key(context, event, reply);
break;
case SERVICE_KB_LOAD_UID:
uid = (uid_t)xpc_dictionary_get_uint64(event, SERVICE_XPC_UID);
- rc = service_kb_load_uid(uid, &kcv);
+ rc = service_kb_load_uid(uid, &context->kcv);
break;
case SERVICE_KB_WRAP_KEY:
- rc = service_kb_wrap_key(context, event, reply, &kcv);
+ rc = service_kb_wrap_key(context, event, reply);
break;
case SERVICE_KB_UNWRAP_KEY:
- rc = service_kb_unwrap_key(context, event, reply, &kcv);
+ rc = service_kb_unwrap_key(context, event, reply);
break;
#if DEBUG
case SERVICE_STASH_BLOB:
{
char log[200] = { 0 };
int count = snprintf(log, sizeof(log), "selector: %s (%llu), error: %s (%x), sid: %d, suid: %d, pid: %d", sel_to_char(request), request, err_to_char(rc), rc, context ? context->s_id : 0, context ? context->s_uid : 0, context ? get_caller_pid(&context->procToken) : 0);
- if (log_kcv(request) && (count < sizeof(log) - 1) && (count > 0) && (kcv > 0)) {
- count = snprintf(log + count, sizeof(log) - count, ", kcv: 0x%0llx", kcv);
+ if (log_kcv(request) && (count < sizeof(log) - 1) && (count > 0) && (context) && (context->kcv > 0)) {
+ count = snprintf(log + count, sizeof(log) - count, ", kcv: 0x%0llx", context->kcv);
}
if (count > 0) {
#if DEBUG
- LOG("%s", log);
+ LOG("%{public}s", log);
#else
if ((rc != 0) || log_kcv(request)) {
- os_log(OS_LOG_DEFAULT, "%s", log);
+ os_log(OS_LOG_DEFAULT, "%{public}s", log);
}
#endif
}
uint32_t flags = SecTaskGetCodeSignStatus(task);
/* check if valid and platform binary, but not platform path */
+
+
if ((flags & (CS_VALID | CS_PLATFORM_BINARY | CS_PLATFORM_PATH)) != (CS_VALID | CS_PLATFORM_BINARY)) {
- os_log(OS_LOG_DEFAULT, "client is not a platform binary: %0x08x", flags);
- CFRelease(task);
- return false;
+ if (SecIsInternalRelease()) {
+ if ((flags & (CS_DEBUGGED | CS_PLATFORM_BINARY | CS_PLATFORM_PATH)) != (CS_DEBUGGED | CS_PLATFORM_BINARY)) {
+ os_log(OS_LOG_DEFAULT, "client is not a platform binary: 0x%08x", flags);
+ CFRelease(task);
+ return false;
+ }
+ } else {
+ os_log(OS_LOG_DEFAULT, "client is not a platform binary: 0x%08x", flags);
+ CFRelease(task);
+ return false;
+ }
}
CFStringRef signingIdentity = SecTaskCopySigningIdentifier(task, NULL);
{
char * errorbuf;
if (sandbox_init(SECURITYD_SERVICE_NAME, SANDBOX_NAMED, &errorbuf) != 0) {
- os_log(OS_LOG_DEFAULT, "sandbox_init failed %s", errorbuf);
+ os_log(OS_LOG_DEFAULT, "sandbox_init failed %{public}s", errorbuf);
sandbox_free_error(errorbuf);
#ifndef DEBUG
abort();
.Os
.Sh NAME
.Nm securityd_service
-.Nd heler process to securityd to unlock keybag
+.Nd helper process to securityd to unlock keybag
.Sh DESCRIPTION
.Nm
lock and unlocks the keybag on behalf of
au_asid_t s_id;
uid_t s_uid;
audit_token_t procToken;
+ uint64_t kcv;
} service_context_t;
int service_client_kb_create(service_context_t *context, const void * secret, int secret_len);
already exists at install time.
*/
-std::string SharedMemoryCommon::SharedMemoryFilePath(const char *segmentName, uid_t uid) {
- std::string path;
- uid = SharedMemoryCommon::fixUID(uid);
- path = SharedMemoryCommon::kMDSMessagesDirectory; // i.e. /private/var/db/mds/messages/
- if (uid != 0) {
- path += std::to_string(uid) + "/"; // e.g. /private/var/db/mds/messages/501/
- }
-
- path += SharedMemoryCommon::kUserPrefix; // e.g. /var/db/mds/messages/se_
- path += segmentName; // e.g. /var/db/mds/messages/501/se_SecurityMessages
- return path;
-}
-
static bool makedir(const char *path, mode_t mode) {
// Returns true on success. Primarily to centralize logging
if (::mkdir(path, mode)==0 || errno==EEXIST) {
bool KeychainPromptAclSubject::validates(const AclValidationContext &context,
const TypedList &sample) const
{
+ // Try to grab a common lock. We'll need it in queryUser, but we can't get
+ // it in validateExplicitly since other callers have it.
+ SecurityServerEnvironment *env = context.environment<SecurityServerEnvironment>();
+ StMaybeLock<Mutex> _(env && env->database && env->database->hasCommon() ? &env->database->common() : NULL);
+
return validateExplicitly(context, ^{
if (SecurityServerEnvironment *env = context.environment<SecurityServerEnvironment>()) {
Process& process = Server::process();
//
void SecurityServerAcl::validatePartition(SecurityServerEnvironment& env, bool prompt)
{
+ // Avert your eyes!
+ StMaybeLock<Mutex> lock(env.database && env.database->hasCommon() ? &(env.database->common()) : NULL);
+
// Calling checkAppleSigned() early at boot on a clean system install
// will end up trying to create the system keychain and causes a hang.
// Avoid this by checking for the presence of the db first.
// if passphrase checking requested, save KeychainDatabase reference
// (will quietly disable check if db isn't a keychain)
- // Always require password, <rdar://problem/34677969> Always require the user's password on keychain approval dialogs
- // if (needPass)
- mPassphraseCheck = dynamic_cast<const KeychainDatabase *>(db);
+ // Always require password due to <rdar://problem/34677969>
+ mPassphraseCheck = dynamic_cast<const KeychainDatabase *>(db);
setTerminateOnSleep(true);
}
+// Callers to this function must hold the common lock
Reason QueryKeychainUse::queryUser (const char *database, const char *description, AclAuthorization action)
{
Reason reason = SecurityAgent::noReason;
hints.erase(retryHint); hints.insert(retryHint); // replace
setInput(hints, context);
- invoke();
+
+ {
+ // Must drop the common lock while showing UI.
+ StSyncLock<Mutex, Mutex> syncLock(const_cast<KeychainDatabase*>(mPassphraseCheck)->common().uiLock(), const_cast<KeychainDatabase*>(mPassphraseCheck)->common());
+ invoke();
+ }
if (retryCount > kMaximumAuthorizationTries)
{
passwordItem->getCssmData(data);
- {
- // Must hold the 'common' lock to call decode; otherwise there's a data corruption issue
- StLock<Mutex> _(const_cast<KeychainDatabase*>(mPassphraseCheck)->common());
- reason = (const_cast<KeychainDatabase*>(mPassphraseCheck)->decode(data) ? SecurityAgent::noReason : SecurityAgent::invalidPassphrase);
- }
+ reason = (const_cast<KeychainDatabase*>(mPassphraseCheck)->decode(data) ? SecurityAgent::noReason : SecurityAgent::invalidPassphrase);
}
while (reason != SecurityAgent::noReason);
Syslog::error("au_sdev_read_aia failed: %d\n", errno);
continue;
}
- secinfo("SS", "%p session notify %d %d %d", this, aia.ai_asid, event, aia.ai_auid);
+ secinfo("SecServer", "%p session notify %d %d %d", this, aia.ai_asid, event, aia.ai_auid);
if (kern_return_t rc = self_client_handleSession(mRelay, mach_task_self(), event, aia.ai_asid))
Syslog::error("self-send failed (mach error %d)", rc);
}
{
static CFStringRef const appleReq = CFSTR("anchor apple");
static CFStringRef const masReq = CFSTR("anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]");
- static CFStringRef const developmentOrDevIDReq = CFSTR("anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13]"
- " or "
- "anchor apple generic and certificate leaf[subject.CN] = \"Mac Developer:\"* and certificate 1[field.1.2.840.113635.100.6.2.1]");
+ static CFStringRef const developmentOrDevIDReq = CFSTR("anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13]" // Developer ID CA and Leaf
+ " or "
+ "anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.1] and certificate leaf[field.1.2.840.113635.100.6.1.12]" // WWDR CA and Mac Development Leaf
+ " or "
+ "anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.1] and certificate leaf[field.1.2.840.113635.100.6.1.7]"); // WWDR CA and Mac Distribution Leaf
static SecRequirementRef apple;
static SecRequirementRef mas;
static SecRequirementRef developmentOrDevID;
// bump the send-rights count on the reply port so we keep the right after replying
mClientPort.modRefs(MACH_PORT_RIGHT_SEND, +1);
- secinfo("SS", "New client connection %p: %d %d", this, rPort.port(), proc.uid());
+ secinfo("SecServer", "New client connection %p: %d %d", this, rPort.port(), proc.uid());
}
//
Connection::~Connection()
{
- secinfo("SS", "releasing client connection %p", this);
+ secinfo("SecServer", "releasing client connection %p", this);
assert(!agentWait);
}
//
void Connection::guestRef(SecGuestRef newGuest, SecCSFlags flags)
{
- secinfo("SS", "Connection %p switches to guest 0x%x", this, newGuest);
+ secinfo("SecServer", "Connection %p switches to guest 0x%x", this, newGuest);
mGuestRef = newGuest;
}
assert(state == idle);
mClientPort.modRefs(MACH_PORT_RIGHT_SEND, -1); // discard surplus send right
assert(mClientPort.getRefs(MACH_PORT_RIGHT_SEND) == 1); // one left for final reply
- secinfo("SS", "Connection %p terminated", this);
+ secinfo("SecServer", "Connection %p terminated", this);
}
mClientPort.destroy(); // dead as a doornail already
switch (state) {
case idle:
- secinfo("SS", "Connection %p aborted", this);
+ secinfo("SecServer", "Connection %p aborted", this);
break;
case busy:
state = dying; // shoot me soon, please
- secinfo("SS", "Connection %p abort deferred (busy)", this);
+ secinfo("SecServer", "Connection %p abort deferred (busy)", this);
break;
default:
assert(false); // impossible (we hope)
mOverrideReturn = CSSM_OK; // clear override
break;
case busy:
- secinfo("SS", "Attempt to re-enter connection %p(port %d)", this, mClientPort.port());
+ secinfo("SecServer", "Attempt to re-enter connection %p(port %d)", this, mClientPort.port());
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); //@@@ some state-error code instead?
default:
assert(false);
state = idle;
return;
case dying:
- secinfo("SS", "Connection %p abort resuming", this);
+ secinfo("SecServer", "Connection %p abort resuming", this);
return;
default:
assert(false);
case dynamicHosting:
mHostingPort.destroy();
mHostingPort = MACH_PORT_NULL;
- secnotice("SS", "%d host unregister", mHostingPort.port());
+ secnotice("SecServer", "%d host unregister", mHostingPort.port());
break;
case proxyHosting:
Server::active().remove(*this); // unhook service handler
mHostingState = noHosting;
mHostingPort = MACH_PORT_NULL;
mGuests.erase(mGuests.begin(), mGuests.end());
- secnotice("SS", "%d host unregister", mHostingPort.port());
+ secnotice("SecServer", "%d host unregister", mHostingPort.port());
break;
}
}
// now take the rest of the attrs
CFIndex count = CFDictionaryGetCount(attrs);
- CFTypeRef keys[count], values[count];
+
+ CFTypeRef *keys = (CFTypeRef*)malloc(count*sizeof(CFTypeRef));
+ CFTypeRef *values = (CFTypeRef*)malloc(count*sizeof(CFTypeRef));
+
+ if (keys == NULL || values == NULL) {
+ free(keys);
+ free(values);
+ MacOSError::throwMe(errSecMemoryError);
+ }
+
CFDictionaryGetKeysAndValues(attrs, keys, values);
for (;;) {
Guest *match = NULL; // previous match found
if (it->second->isGuestOf(host, strict)) {
if (it->second->matches(count, keys, values)) {
if (match) {
+ free(keys);
+ free(values);
MacOSError::throwMe(errSecCSMultipleGuests); // ambiguous
} else {
match = it->second;
}
}
}
- if (!match) // nothing found
+ if (!match) { // nothing found
+ free(keys);
+ free(values);
return host;
- else
+ }
+ else {
host = match; // and repeat
+ }
}
}
case noHosting:
mHostingPort = hostingPort;
mHostingState = dynamicHosting;
- secnotice("SS", "%d host register: %d", mHostingPort.port(), mHostingPort.port());
+ secnotice("SecServer", "%d host register: %d", mHostingPort.port(), mHostingPort.port());
break;
default:
MacOSError::throwMe(errSecCSHostProtocolContradiction);
MachServer::Handler::port(mHostingPort); // put into Handler
MachServer::active().add(*this); // start listening
mHostingState = proxyHosting; // now proxying for this host
- secnotice("SS", "%d host proxy: %d", mHostingPort.port(), mHostingPort.port());
+ secnotice("SecServer", "%d host proxy: %d", mHostingPort.port(), mHostingPort.port());
break;
case proxyHosting: // already proxying
break;
guest->setHash(cdhash, flags & kSecCSGenerateGuestHash);
guest->dedicated = (flags & kSecCSDedicatedHost);
mGuests[guest->guestRef()] = guest;
- secnotice("SS", "%d guest create %d %d status:%d %d %s", mHostingPort.port(), hostRef, guest->guestRef(), guest->status, flags, guest->path.c_str());
+ secnotice("SecServer", "%d guest create %d %d status:%d %d %s", mHostingPort.port(), hostRef, guest->guestRef(), guest->status, flags, guest->path.c_str());
return guest->guestRef();
}
if ((~status & guest->status) & (kSecCodeStatusHard | kSecCodeStatusKill))
MacOSError::throwMe(errSecCSHostProtocolStateError); // can't clear
guest->status = status;
- secnotice("SS", "%d guest change %d %d", mHostingPort.port(), guestRef, status);
+ secnotice("SecServer", "%d guest change %d %d", mHostingPort.port(), guestRef, status);
// replace attributes if requested
if (attributes)
}
for (auto &it : matchingGuests) {
- secnotice("SS", "%d guest destroy %d", mHostingPort.port(), it);
+ secnotice("SecServer", "%d guest destroy %d", mHostingPort.port(), it);
mGuests.erase(it);
}
}
return false;
}
+bool Database::hasCommon() const
+{
+ return hasParent();
+}
static const int maxUnlockTryCount = 3;
public:
+ bool hasCommon() const;
DbCommon& common() const { return parent<DbCommon>(); }
virtual const char *dbName() const = 0;
virtual void dbName(const char *name);
mBlobVersion = blob->version();
}
memcpy(mSalt, blob->salt, sizeof(mSalt));
- } else
+ } else {
Server::active().random(mSalt);
+ }
mMasterKey = deriveDbMasterKey(passphrase);
mHaveMaster = true;
}
mBlobVersion = blob->version();
}
memcpy(mSalt, blob->salt, sizeof(mSalt));
- } else
+ } else {
Server::active().random(mSalt);
+ }
mMasterKey = master;
mHaveMaster = true;
}
sample.checkProper();
switch (sample.type()) {
// interactively prompt the user - no additional data
- case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: {
- StSyncLock<Mutex, Mutex> uisync(db.common().uiLock(), db.common());
- // Once we get the ui lock, check whether another thread has already unlocked keybag
- bool locked = false;
- service_context_t context = db.common().session().get_current_service_context();
- if ((service_client_kb_is_locked(&context, &locked, NULL) == 0) && locked) {
- QueryKeybagPassphrase keybagQuery(db.common().session(), 3);
- keybagQuery.inferHints(Server::process());
- if (keybagQuery.query() == SecurityAgent::noReason) {
- return true;
+ case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT:
+ {
+ /*
+ Okay, this is messy. We need to hold the common lock to be certain we're modifying the world
+ as we intend. But UI ^ common, and QueryKeybagPassphrase::query() has tons of side effects by necessity,
+ so just confirm that the operation did what we wanted after the fact.
+ */
+ bool query_success = false;
+ bool unlock_success = false;
+ bool looped = false;
+ do {
+ {
+ StSyncLock<Mutex, Mutex> uisync(db.common().uiLock(), db.common());
+ // Once we get the ui lock, check whether another thread has already unlocked keybag
+ bool locked = false;
+ query_success = false;
+ service_context_t context = db.common().session().get_current_service_context();
+ if ((service_client_kb_is_locked(&context, &locked, NULL) == 0) && locked) {
+ QueryKeybagPassphrase keybagQuery(db.common().session(), 3);
+ keybagQuery.inferHints(Server::process());
+ if (keybagQuery.query() == SecurityAgent::noReason) {
+ query_success = true;
+ }
+ } else {
+ // another thread already unlocked the keybag
+ query_success = true; // NOT unlock_success because we have the wrong lock
+ }
+ } // StSyncLock goes out of scope, we have common lock again
+ bool locked = false;
+ service_context_t context = db.common().session().get_current_service_context();
+ if ((service_client_kb_is_locked(&context, &locked, NULL) == 0) && !locked) {
+ unlock_success = true;
}
- }
- else {
- // another thread already unlocked the keybag
- return true;
- }
- break;
+ if (looped) {
+ secnotice("KCdb", "Unlocking the keybag again (threading?)");
+ }
+ looped = true;
+ } while (query_success && !unlock_success);
}
+ break;
// try to use an explicitly given passphrase - Data:passphrase
case CSSM_SAMPLE_TYPE_PASSWORD: {
if (sample.length() != 2)
RefPointer<Key> KeychainDatabase::makeKey(Database &db, const CssmKey &newKey,
uint32 moreAttributes, const AclEntryPrototype *owner)
{
-
+ StLock<Mutex> lock(common());
if (moreAttributes & CSSM_KEYATTR_PERMANENT)
return new KeychainKey(db, newKey, moreAttributes, owner);
else
if (isLocked()) {
secnotice("KCdb", "%p(%p) unlocking for makeUnlocked()", this, &common());
assert(mBlob || (mValidData && common().hasMaster()));
- establishOldSecrets(cred);
+ bool asking_again = false;
+ do {
+ if (asking_again) {
+ secnotice("KCdb", "makeUnlocked: establishing old secrets again (threading?)");
+ }
+ establishOldSecrets(cred);
+ asking_again = true;
+ } while (!common().hasMaster());
common().setUnlocked(); // mark unlocked
if (common().isLoginKeychain()) {
CssmKey master = common().masterKey();
uint32_t KeychainDatabase::interactiveUnlockAttempts = 0;
+// This does UI so needs the UI lock. It also interacts with the common, so needs the common lock. But can't have both at once!
+// Try to hold the UI lock for the smallest amount of time possible while having the common lock where needed.
bool KeychainDatabase::interactiveUnlock()
{
secinfo("KCdb", "%p attempting interactive unlock", this);
SecurityAgent::Reason reason = SecurityAgent::noReason;
QueryUnlock query(*this);
- // take UI interlock and release DbCommon lock (to avoid deadlocks)
- StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
-
- // now that we have the UI lock, interact unless another thread unlocked us first
+
if (isLocked()) {
query.inferHints(Server::process());
+ StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
reason = query();
+ uisync.unlock();
if (mSaveSecret && reason == SecurityAgent::noReason) {
query.retrievePassword(mSecret);
}
keybagQuery.inferHints(Server::process());
CssmAutoData pass(Allocator::standard(Allocator::sensitive));
CssmAutoData oldPass(Allocator::standard(Allocator::sensitive));
+ StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
SecurityAgent::Reason queryReason = keybagQuery.query(oldPass, pass);
+ uisync.unlock();
if (queryReason == SecurityAgent::noReason) {
service_client_kb_change_secret(&context, oldPass.data(), (int)oldPass.length(), pass.data(), (int)pass.length());
} else if (queryReason == SecurityAgent::resettingPassword) {
// interactively prompt the user
case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT:
{
- secinfo("KCdb", "%p specified interactive passphrase", this);
- QueryNewPassphrase query(*this, reason);
- StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
- query.inferHints(Server::process());
- CssmAutoData passphrase(Allocator::standard(Allocator::sensitive));
- CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive));
- if (query(oldPassphrase, passphrase) == SecurityAgent::noReason) {
- common().setup(NULL, passphrase);
- change_secret_on_keybag(*this, oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length());
- return true;
- }
+ secinfo("KCdb", "%p specified interactive passphrase", this);
+ QueryNewPassphrase query(*this, reason);
+ StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
+ query.inferHints(Server::process());
+ CssmAutoData passphrase(Allocator::standard(Allocator::sensitive));
+ CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive));
+ SecurityAgent::Reason reason(query(oldPassphrase, passphrase));
+ uisync.unlock();
+ if (reason == SecurityAgent::noReason) {
+ common().setup(NULL, passphrase);
+ change_secret_on_keybag(*this, oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length());
+ return true;
+ }
}
break;
// try to use an explicitly given passphrase
query.inferHints(Server::process());
CssmAutoData passphrase(Allocator::standard(Allocator::sensitive));
CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive));
- if (query(oldPassphrase, passphrase) == SecurityAgent::noReason) {
+ SecurityAgent::Reason reason(query(oldPassphrase, passphrase));
+ uisync.unlock();
+ if (reason == SecurityAgent::noReason) {
common().setup(NULL, passphrase);
change_secret_on_keybag(*this, oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length());
return true;
// perform basic validation on the blob
assert(blob);
blob->validate(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB);
+ if (blob->startCryptoBlob > blob->totalLength) {
+ CssmError::throwMe(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB);
+ }
switch (blob->version()) {
#if defined(COMPAT_OSX_10_0)
case DbBlob::version_MacOS_10_0:
// perform basic validation on the incoming blob
assert(blob);
blob->validate(CSSMERR_APPLEDL_INVALID_KEY_BLOB);
+ if (blob->startCryptoBlob > blob->totalLength) {
+ CssmError::throwMe(CSSMERR_APPLEDL_INVALID_KEY_BLOB);
+ }
switch (blob->version()) {
#if defined(COMPAT_OSX_10_0)
case KeyBlob::version_MacOS_10_0:
db->unlockDb(false);
}
SecurityServerAcl::validate(auth, cred, relatedDatabase);
+
+ // Need the common lock some more. unlockDb and validate (in validatePartition) also take it, so must be down here.
+ StMaybeLock<Mutex> lock(relatedDatabase && relatedDatabase->hasCommon() ? &(relatedDatabase->common()) : NULL);
database().activity(); // upon successful validation
}
int main(int argc, char *argv[])
{
// clear the umask - we know what we're doing
- secnotice("SS", "starting umask was 0%o", ::umask(0));
+ secnotice("SecServer", "starting umask was 0%o", ::umask(0));
::umask(0);
// tell the keychain (client) layer to turn off the server interface
// check for the Installation-DVD environment and modify some default arguments if found
if (access("/etc/rc.cdrom", F_OK) == 0) { // /etc/rc.cdrom exists
- secnotice("SS", "starting in installmode");
+ secnotice("SecServer", "starting in installmode");
smartCardOptions = "off"; // needs writable directories that aren't
}
// okay, we're ready to roll
- secnotice("SS", "Entering service as %s", (char*)bootstrapName);
+ secnotice("SecServer", "Entering service as %s", (char*)bootstrapName);
Syslog::notice("Entering service");
// go
SharedMemoryListener::SharedMemoryListener(const char* segmentName, SegmentOffsetType segmentSize, uid_t uid, gid_t gid) :
Listener (kNotificationDomainAll, kNotificationAllEvents),
SharedMemoryServer (segmentName, segmentSize, uid, gid),
- mActive (false)
+ mActive (false), mMutex()
{
}
WriteMessage (notification->domain, notification->event, data, int_cast<size_t, UInt32>(length));
+ StLock<Mutex> lock(mMutex);
if (!mActive)
{
Server::active().setTimer (this, Time::Interval(kServerWait));
void SharedMemoryListener::action ()
{
+ StLock<Mutex> lock(mMutex);
+ notify_post (mSegmentName.c_str ());
secinfo("notify", "Posted notification to clients.");
secdebug("MDSPRIVACY","[%03d] Posted notification to clients", mUID);
- notify_post (mSegmentName.c_str ());
mActive = false;
}
bool mActive;
+ Mutex mMutex;
+
public:
SharedMemoryListener (const char* serverName, u_int32_t serverSize, uid_t uid = 0, gid_t gid = 0);
virtual ~SharedMemoryListener ();
// let's take a look at our wannabe client...
if (mTaskPort.pid() != mPid) {
- secnotice("SS", "Task/pid setup mismatch pid=%d task=%d(%d)",
+ secnotice("SecServer", "Task/pid setup mismatch pid=%d task=%d(%d)",
mPid, mTaskPort.port(), mTaskPort.pid());
CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED); // you lied!
}
|| ServerChild::find<ServerChild>(this->pid())) // securityd's child; do not mark this txn dirty
VProc::Transaction::deactivate();
- secinfo("SS", "%p client new: pid:%d session:%d %s taskPort:%d uid:%d gid:%d", this, this->pid(), this->session().sessionId(),
+ secinfo("SecServer", "%p client new: pid:%d session:%d %s taskPort:%d uid:%d gid:%d", this, this->pid(), this->session().sessionId(),
(char *)codePath(this->processCode()).c_str(), taskPort.port(), mUid, mGid);
}
{
StLock<Mutex> _(*this);
if (taskPort != mTaskPort) {
- secnotice("SS", "Process %p(%d) reset mismatch (tp %d-%d)",
+ secnotice("SecServer", "Process %p(%d) reset mismatch (tp %d-%d)",
this, pid(), taskPort.port(), mTaskPort.port());
//@@@ CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); // liar
}
ClientIdentification::setup(this->pid()); // re-constructs processCode()
if (CFEqual(oldCode, processCode())) {
- secnotice("SS", "%p Client reset amnesia", this);
+ secnotice("SecServer", "%p Client reset amnesia", this);
} else {
- secnotice("SS", "%p Client reset full", this);
+ secnotice("SecServer", "%p Client reset full", this);
CodeSigningHost::reset();
}
}
//
Process::~Process()
{
- secinfo("SS", "%p client release: %d", this, this->pid());
+ secinfo("SecServer", "%p client release: %d", this, this->pid());
// release our name for the process's task port
if (mTaskPort)
{
// re-parent
parent(Session::find(sessionId, true));
- secnotice("SS", "%p client change session to %d", this, this->session().sessionId());
+ secnotice("SecServer", "%p client change session to %d", this, this->session().sessionId());
}
// aclSequence is taken to serialize ACL validations to pick up mutual changes
Mutex aclSequence;
-
- IFDUMP(void dumpNode());
+
+ // Dumping is buggy and only hurts debugging. It's dead Jim.
+ //IFDUMP(void dumpNode());
private:
void setup(const ClientSetupInfo *info);
void Server::requestComplete(CSSM_RETURN &rcode)
{
+ Server &server = active();
+ StLock<Mutex> lock(server);
// note: there may not be an active connection if connection setup failed
- if (RefPointer<Connection> &conn = active().mCurrentConnection()) {
+ if (RefPointer<Connection> &conn = server.mCurrentConnection()) {
conn->endWork(rcode);
conn = NULL;
}
// is it a connection?
PortMap<Connection>::iterator conIt = mConnections.find(port);
if (conIt != mConnections.end()) {
- secinfo("SS", "%p dead connection %d", this, port.port());
+ secinfo("SecServer", "%p dead connection %d", this, port.port());
RefPointer<Connection> con = conIt->second;
mConnections.erase(conIt);
serverLock.unlock();
// is it a process?
PortMap<Process>::iterator procIt = mProcesses.find(port);
if (procIt != mProcesses.end()) {
- secinfo("SS", "%p dead process %d", this, port.port());
+ secinfo("SecServer", "%p dead process %d", this, port.port());
RefPointer<Process> proc = procIt->second;
mPids.erase(proc->pid());
mProcesses.erase(procIt);
//
void Server::notifyNoSenders(Port port, mach_port_mscount_t)
{
- secinfo("SS", "%p dead session %d", this, port.port());
+ secinfo("SecServer", "%p dead session %d", this, port.port());
}
mach_port_t taskPort, int sig)
{
try {
- secnotice("SS", "signal handled %d", sig);
+ secnotice("SecServer", "signal handled %d", sig);
if (taskPort != mach_task_self()) {
Syslog::error("handleSignal: received from someone other than myself");
return KERN_SUCCESS;
ServerChild::checkChildren();
break;
case SIGINT:
- secnotice("SS", "shutdown due to SIGINT");
+ secnotice("SecServer", "shutdown due to SIGINT");
Syslog::notice("securityd terminated due to SIGINT");
_exit(0);
case SIGTERM:
assert(false);
}
} catch(...) {
- secnotice("SS", "exception handling a signal (ignored)");
+ secnotice("SecServer", "exception handling a signal (ignored)");
}
mach_port_deallocate(mach_task_self(), taskPort);
return KERN_SUCCESS;
try {
if (taskPort != mach_task_self()) {
Syslog::error("handleSession: received from someone other than myself");
+ mach_port_deallocate(mach_task_self(), taskPort);
return KERN_SUCCESS;
}
if (event == AUE_SESSION_END)
Session::destroy(int_cast<uint64_t, Session::SessionId>(ident));
} catch(...) {
- secnotice("SS", "exception handling a signal (ignored)");
+ secnotice("SecServer", "exception handling a signal (ignored)");
}
mach_port_deallocate(mach_task_self(), taskPort);
return KERN_SUCCESS;
//
void Server::SleepWatcher::systemWillSleep()
{
- secnotice("SS", "%p will sleep", this);
+ secnotice("SecServer", "%p will sleep", this);
Session::processSystemSleep();
for (set<PowerWatcher *>::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++)
(*it)->systemWillSleep();
void Server::SleepWatcher::systemIsWaking()
{
- secnotice("SS", "%p is waking", this);
+ secnotice("SecServer", "%p is waking", this);
for (set<PowerWatcher *>::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++)
(*it)->systemIsWaking();
}
void Server::SleepWatcher::systemWillPowerOn()
{
- secnotice("SS", "%p will power on", this);
+ secnotice("SecServer", "%p will power on", this);
Server::active().longTermActivity();
for (set<PowerWatcher *>::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++)
(*it)->systemWillPowerOn();
{
StLock<Mutex> _(*this);
if (!mWaitForClients) {
- secnotice("SS", "%p shutting down now", this);
+ secnotice("SecServer", "%p shutting down now", this);
_exit(0);
} else {
if (!mShuttingDown) {
mShuttingDown = true;
Session::invalidateAuthHosts();
- secnotice("SS", "%p beginning shutdown", this);
+ secnotice("SecServer", "%p beginning shutdown", this);
if (verbosity() >= 2) {
reportFile = fopen("/var/log/securityd-shutdown.log", "w");
shutdownSnitch();
//
void Server::eventDone()
{
+ StLock<Mutex> lock(*this);
if (this->shuttingDown()) {
- StLock<Mutex> lazy(*this, false); // lazy lock acquisition
if (verbosity() >= 2) {
- lazy.lock();
- secnotice("SS", "shutting down with %ld processes and %ld transactions", mProcesses.size(), VProc::Transaction::debugCount());
+ secnotice("SecServer", "shutting down with %ld processes and %ld transactions", mProcesses.size(), VProc::Transaction::debugCount());
shutdownSnitch();
}
IFDUMPING("shutdown", NodeCore::dumpAll());
VProc::Transaction xact;
if (!mCssm->isActive()) {
if (!mdsIsInstalled) { // non-system securityd instance should not reinitialize MDS
- secnotice("SS", "Installing MDS");
+ secnotice("SecServer", "Installing MDS");
IFDEBUG(if (geteuid() == 0))
MDSClient::mds().install();
}
- secnotice("SS", "CSSM initializing");
+ secnotice("SecServer", "CSSM initializing");
mCssm->init();
mCSP->attach();
- secnotice("SS", "CSSM ready with CSP %s", mCSP->guid().toString().c_str());
+ secnotice("SecServer", "CSSM ready with CSP %s", mCSP->guid().toString().c_str());
}
}
}
mSessions[audit.sessionId()] = this;
// log it
- secnotice("SS", "%p Session %d created, uid:%d sessionId:%d", this, this->sessionId(), mAudit.uid(), mAudit.sessionId());
+ secnotice("SecServer", "%p Session %d created, uid:%d sessionId:%d", this, this->sessionId(), mAudit.uid(), mAudit.sessionId());
Syslog::notice("Session %d created", this->sessionId());
}
//
Session::~Session()
{
- secnotice("SS", "%p Session %d destroyed", this, this->sessionId());
+ secnotice("SecServer", "%p Session %d destroyed", this, this->sessionId());
Syslog::notice("Session %d destroyed", this->sessionId());
}
void Session::kill()
{
StLock<Mutex> _(*this); // do we need to take this so early?
- secnotice("SS", "%p killing session %d", this, this->sessionId());
+ secnotice("SecServer", "%p killing session %d", this, this->sessionId());
invalidateSessionAuthHosts();
// base kill processing
service_context_t Session::get_current_service_context()
{
- service_context_t context = { sessionId(), originatorUid(), *Server::connection().auditToken() };
+ service_context_t context = { sessionId(), originatorUid(), *Server::connection().auditToken(), 0 };
return context;
}
void NodeCore::clearReferent()
{
StLock<Mutex> _(*this);
- if (mReferent)
- assert(!mReferent->hasReference(*this));
mReferent = NULL;
}
void NodeCore::removeReference(NodeCore &p)
{
StLock<Mutex> _(*this);
- assert(hasReference(p));
mReferences.erase(&p);
}
-#if !defined(NDEBUG)
-
-bool NodeCore::hasReference(NodeCore &p)
-{
- assert(p.refCountForDebuggingOnly() > 0);
- return mReferences.find(&p) != mReferences.end();
-}
-
-#endif //NDEBUG
-
-
//
// ClearReferences clears the reference set but does not propagate
// anything; it is NOT recursive.
void NodeCore::clearReferences()
{
StLock<Mutex> _(*this);
- secinfo("ssnode", "%p clearing all %d references",
- this, int(mReferences.size()));
+ secinfo("ssnode", "%p clearing all %d references", this, int(mReferences.size()));
mReferences.erase(mReferences.begin(), mReferences.end());
}
void NodeCore::kill(NodeCore &ref)
{
StLock<Mutex> _(*this);
- assert(hasReference(ref));
ref.kill();
removeReference(ref);
}
typedef set<RefPointer<NodeCore> > ReferenceSet;
ReferenceSet mReferences;
- IFDEBUG(bool hasReference(NodeCore &p));
-
#if defined(DEBUGDUMP)
public: // dump support
NodeCore(); // dump-only constructor (registers node)
#define BEGIN_IPCN *rcode = CSSM_OK; try {
#define BEGIN_IPC(name) BEGIN_IPCN RefPointer<Connection> connRef(&Server::connection(replyPort, auditToken)); \
Connection &connection __attribute__((unused)) = *connRef; \
- secinfo("SS", "request entry " #name " (pid:%d ession:%d)", connection.process().pid(), connection.session().sessionId());
+ secinfo("SecServer", "request entry " #name " (pid:%d ession:%d)", connection.process().pid(), connection.session().sessionId());
#define END_IPC(base) END_IPCN(base) Server::requestComplete(*rcode); return KERN_SUCCESS;
-#define END_IPCN(base) secinfo("SS", "request return: %d", *(rcode)); \
+#define END_IPCN(base) secinfo("SecServer", "request return: %d", *(rcode)); \
} \
catch (const CommonError &err) { *rcode = CssmError::cssmError(err, CSSM_ ## base ## _BASE_ERROR); } \
catch (const std::bad_alloc &) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
kern_return_t ucsp_server_setup(UCSP_ARGS, mach_port_t taskPort, ClientSetupInfo info, const char *identity)
{
BEGIN_IPCN
- secinfo("SS", "request entry: setup");
+ secinfo("SecServer", "request entry: setup");
Server::active().setupConnection(Server::connectNewProcess, replyPort,
taskPort, auditToken, &info);
END_IPCN(CSSM)
kern_return_t ucsp_server_setupThread(UCSP_ARGS, mach_port_t taskPort)
{
- secinfo("SS", "request entry: setupThread");
+ secinfo("SecServer", "request entry: setupThread");
BEGIN_IPCN
Server::active().setupConnection(Server::connectNewThread, replyPort, taskPort, auditToken);
END_IPCN(CSSM)
kern_return_t ucsp_server_teardown(UCSP_ARGS)
{
BEGIN_IPCN
- secinfo("SS", "request entry: teardown");
+ secinfo("SecServer", "request entry: teardown");
Server::active().endConnection(replyPort);
END_IPCN(CSSM)
return KERN_SUCCESS;
kern_return_t ucsp_server_verifyPrivileged(UCSP_ARGS)
{
BEGIN_IPCN
- secinfo("SS", "request entry: verifyPrivileged");
+ secinfo("SecServer", "request entry: verifyPrivileged");
// doing nothing (we just want securityd's audit credentials returned)
END_IPCN(CSSM)
return KERN_SUCCESS;
{
BEGIN_IPCN
- secinfo("SS", "request entry: verifyPrivileged2");
+ secinfo("SecServer", "request entry: verifyPrivileged2");
// send the port back to the sender to check for a MitM (6986198)
*originPort = servicePort;
END_IPCN(CSSM)
extern "C" {
#endif
-#if ! SEC_OS_OSX_INCLUDES
-typedef struct OpaqueSecKeychainRef *SecKeychainRef;
-#endif
-
/* disable some Panther-only features */
#define JAGUAR_BUILD 0
SecKeychainRef keychain,
bool *foundOne);
-void sslOutputDot();
+void sslOutputDot(void);
/*
* Lists of SSLCipherSuites used in sslSetCipherRestrictions.
*/
#import <XCTest/XCTest.h>
-#import "SFAnalytics.h"
+#import <Security/SFAnalytics.h>
#import "SFAnalyticsDefines.h"
+#import "SFAnalyticsSQLiteStore.h"
+#import "SFSQLite.h"
#import <Prequelite/Prequelite.h>
#import <CoreFoundation/CFPriv.h>
#import <notify.h>
[self assertNoEventsAnywhere];
}
+- (void)testDontCrashWithEmptyDBPath
+{
+ NSString* schema = @"CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT,data BLOB);";
+ NSString* path = [NSString stringWithFormat:@"%@/empty", _path];
+
+ XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:nil schema:schema]);
+ XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:@"" schema:schema]);
+ XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:path schema:nil]);
+ XCTAssertNil([SFAnalyticsSQLiteStore storeWithPath:path schema:@""]);
+
+ XCTAssertNil([[SFSQLite alloc] initWithPath:nil schema:schema]);
+ XCTAssertNil([[SFSQLite alloc] initWithPath:@"" schema:schema]);
+ XCTAssertNil([[SFSQLite alloc] initWithPath:path schema:nil]);
+ XCTAssertNil([[SFSQLite alloc] initWithPath:path schema:@""]);
+}
+
- (void)testAddingEventsWithNilName
{
[_analytics logSuccessForEventNamed:nil];
}
- [self checkSamples:@[@(0.3f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.01f * NSEC_PER_SEC)];
+ [self checkSamples:@[@(0.3f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.05f * NSEC_PER_SEC)];
}
- (void)testTrackerMultipleBlocks
[self checkSamples:@[@(0.2f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.1f * NSEC_PER_SEC)];
}
-
-
- (void)testTrackerCancel
{
NSString* trackerName = @"UnitTestTrackerCancel";
#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>
#import "supd.h"
-#import "SFAnalytics.h"
+#import <Security/SFAnalytics.h>
#import "SFAnalyticsDefines.h"
#import <CoreFoundation/CFPriv.h>
static NSString* build = NULL;
static NSString* product = NULL;
static NSInteger _reporterWrites;
-static NSInteger _reporterCleanups;
// MARK: Stub FakeCKKSAnalytics
return nil;
}
+- (SFAnalyticsTopic *)TrustTopic {
+ for (SFAnalyticsTopic *topic in _supd.analyticsTopics) {
+ if ([topic.internalTopicName isEqualToString:SFAnaltyicsTopicTrust]) {
+ return topic;
+ }
+ }
+ return nil;
+}
+
- (void)inspectDataBlobStructure:(NSDictionary*)data
+{
+ [self inspectDataBlobStructure:data forTopic:[[self keySyncTopic] splunkTopicName]];
+}
+
+- (void)inspectDataBlobStructure:(NSDictionary*)data forTopic:(NSString*)topic
{
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");
+ XCTAssert([[self keySyncTopic] splunkTopicName], @"keysync topic has a splunk name");
+ XCTAssert([[self TrustTopic] splunkTopicName], @"trust topic has a splunk 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");
for (NSDictionary* event in data[@"events"]) {
if ([event isKindOfClass:[NSDictionary class]]) {
+ NSLog(@"build: \"%@\", eventbuild: \"%@\"", build, event[@"build"]);
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");
+ XCTAssertTrue([event[@"topic"] isEqual:topic], @"all events have a topic name");
} else {
XCTFail(@"event %@ is an NSDictionary", event);
}
return encountered;
}
-- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft forcedFail:(BOOL)forcedFail
+- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft accuracy:(int)accuracy summaries:(int)summ
{
- int hardfound = 0, softfound = 0;
- NSUInteger summfound = 0;
+ int hardfound = 0, softfound = 0, summfound = 0;
for (NSDictionary* event in data[@"events"]) {
if ([event[SFAnalyticsEventType] hasSuffix:@"HealthSummary"]) {
++summfound;
}
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);
+ XCTAssertEqual(summfound, summ);
+
+ // Add customizable fuzziness
+ XCTAssertEqualWithAccuracy(hardfound, hard, accuracy);
+ XCTAssertEqualWithAccuracy(softfound, soft, accuracy);
}
- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft
{
- [self checkTotalEventCount:data hard:hard soft:soft forcedFail:NO];
+ [self checkTotalEventCount:data hard:hard soft:soft accuracy:10 summaries:(int)[[[self keySyncTopic] topicClients] count]];
+}
+
+- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft accuracy:(int)accuracy
+{
+ [self checkTotalEventCount:data hard:hard soft:soft accuracy:accuracy summaries:(int)[[[self keySyncTopic] topicClients] count]];
}
// This is a dumb hack, but inlining stringWithFormat causes the compiler to growl for unknown reasons
}
- (NSDictionary*)getJSONDataFromSupd
+{
+ return [self getJSONDataFromSupdWithTopic:SFAnalyticsTopicKeySync];
+}
+
+- (NSDictionary*)getJSONDataFromSupdWithTopic:(NSString*)topic
{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block NSDictionary* data;
- [_supd getLoggingJSON:YES topic:SFAnalyticsTopicKeySync reply:^(NSData *json, NSError *error) {
+ [_supd getLoggingJSON:YES topic:topic reply:^(NSData *json, NSError *error) {
XCTAssertNil(error);
XCTAssertNotNil(json);
if (!error) {
OCMStub([mockTopic databasePathForPCS]).andReturn(pcsPath);
OCMStub([mockTopic databasePathForTLS]).andReturn(tlsPath);
+ // These are not used for testing, but real data can pollute tests so point to empty DBs
+ NSString *localpath = [_path stringByAppendingFormat:@"/local_empty_%ld.db", _testnum];
+ NSString *trustPath = [_path stringByAppendingFormat:@"/trust_empty_%ld.db", _testnum];
+ NSString *trustdhealthPath = [_path stringByAppendingFormat:@"/trustdhealth_empty_%ld.db", _testnum];
+ OCMStub([mockTopic databasePathForLocal]).andReturn(localpath);
+ OCMStub([mockTopic databasePathForTrust]).andReturn(trustPath);
+ OCMStub([mockTopic databasePathForTrustdHealth]).andReturn(trustdhealthPath);
+
_reporterWrites = 0;
mockReporter = OCMClassMock([SFAnalyticsReporter class]);
OCMStub([mockReporter saveReport:[OCMArg isNotNil] fileName:[OCMArg isNotNil]]).andDo(^(NSInvocation *invocation) {
_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]);
+
+ // These are only useful for debugging
+// 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;
+ runningTests = YES;
}
- (void)tearDown
XCTAssertFalse([keytopic haveEligibleClients], @"Both analytics disabled -> no keysync clients");
deviceAnalyticsEnabled = YES;
- XCTAssertFalse([keytopic haveEligibleClients], @"Only device analytics enabled -> no keysync clients");
+ XCTAssertTrue([keytopic haveEligibleClients], @"Only device analytics enabled -> we have keysync clients (localkeychain for now)");
}
- (void)testHaveEligibleClientsTrust
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];
+ [self checkTotalEventCount:data hard:2 soft:2 accuracy:0];
} else {
- [self checkTotalEventCount:data hard:0 soft:0 forcedFail:YES];
+ // localkeychain requires device analytics only so we still get it
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0 summaries:1];
}
}
[_tlsAnalytics logHardFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs];
[_tlsAnalytics logSoftFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs];
- NSDictionary* data = [self getJSONDataFromSupd];
- [self inspectDataBlobStructure:data];
+ NSDictionary* data = [self getJSONDataFromSupdWithTopic:SFAnaltyicsTopicTrust];
+ [self inspectDataBlobStructure:data forTopic:[[self TrustTopic] splunkTopicName]];
if (analyticsEnabled) {
- [self checkTotalEventCount:data hard:1 soft:1];
+ [self checkTotalEventCount:data hard:1 soft:1 accuracy:0 summaries:(int)[[[self TrustTopic] topicClients] count]];
} else {
- [self checkTotalEventCount:data hard:0 soft:0 forcedFail:YES];
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0 summaries:0];
}
}
NSDictionary* data = [self getJSONDataFromSupd];
[self inspectDataBlobStructure:data];
- [self checkTotalEventCount:data hard:testAmount + 1 soft:testAmount + 1];
+ [self checkTotalEventCount:data hard:testAmount + 1 soft:testAmount + 1 accuracy:0];
XCTAssertEqual([self failures:data eventType:@"ckkshardfail" attributes:nil class:SFAnalyticsEventClassHardFailure], testAmount);
XCTAssertEqual([self failures:data eventType:@"ckkssoftfail" attributes:nil class:SFAnalyticsEventClassSoftFailure], testAmount);
[self inspectDataBlobStructure:data];
// min, max, avg, med, dev, 1q, 3q
- [self checkTotalEventCount:data hard:0 soft:0];
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0];
[self sampleStatisticsInEvents:data[@"events"] name:sampleNameEven values:@[@5.22, @90.78, @35.60, @36.18, @21.52, @21.36, @44.11]];
}
NSDictionary* data = [self getJSONDataFromSupd];
[self inspectDataBlobStructure:data];
- [self checkTotalEventCount:data hard:0 soft:0];
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0];
[self sampleStatisticsInEvents:data[@"events"] name:sampleName4n1 values:@[@10.72, @94.24, @45.76, @43.90, @23.14, @26.33, @58.83]];
}
NSDictionary* data = [self getJSONDataFromSupd];
[self inspectDataBlobStructure:data];
- [self checkTotalEventCount:data hard:0 soft:0];
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0];
[self sampleStatisticsInEvents:data[@"events"] name:sampleName4n3 values:@[@1.67, @99.83, @44.33, @38.45, @35.28, @7.92, @81.70]];
}
NSDictionary* data = [self getJSONDataFromSupd];
[self inspectDataBlobStructure:data];
- [self checkTotalEventCount:data hard:0 soft:0];
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0];
[self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@3.14159]];
}
NSDictionary* data = [self getJSONDataFromSupd];
[self inspectDataBlobStructure:data];
- [self checkTotalEventCount:data hard:0 soft:0];
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0];
[self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@3.14, @6.28, @4.71, @4.71, @1.57]];
}
NSDictionary* data = [self getJSONDataFromSupd];
[self inspectDataBlobStructure:data];
- [self checkTotalEventCount:data hard:0 soft:0];
+ [self checkTotalEventCount:data hard:0 soft:0 accuracy:0];
[self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@313.37] amount:2];
}
@property NSURL* splunkBagURL;
@property NSString *internalTopicName;
-@property NSArray<SFAnalyticsClient *> *topicClients;
+@property NSArray<SFAnalyticsClient*>* topicClients;
// --------------------------------
// Things below are for unit testing
+ (NSString*)databasePathForCKKS;
+ (NSString*)databasePathForSOS;
+ (NSString*)databasePathForPCS;
++ (NSString*)databasePathForLocal;
++ (NSString*)databasePathForTrust;
++ (NSString*)databasePathForTrustdHealth;
+ (NSString*)databasePathForTLS;
@end
// --------------------------------
// Things below are for unit testing
+extern BOOL runningTests; // Do not use 'force' when obtaining logging json
extern BOOL deviceAnalyticsOverride;
extern BOOL deviceAnalyticsEnabled;
extern BOOL iCloudAnalyticsOverride;
#import "supd.h"
#import "SFAnalyticsDefines.h"
#import "SFAnalyticsSQLiteStore.h"
-#import "SFAnalytics.h"
+#import <Security/SFAnalytics.h>
#include <utilities/SecFileLocations.h>
#import "utilities/debugging.h"
static supd *_supdInstance = nil;
+BOOL runningTests = NO;
BOOL deviceAnalyticsOverride = NO;
BOOL deviceAnalyticsEnabled = NO;
BOOL iCloudAnalyticsOverride = NO;
@end
@implementation SFAnalyticsTopic
+
- (void)setupClientsForTopic:(NSString *)topicName
{
NSMutableArray<SFAnalyticsClient*>* clients = [NSMutableArray<SFAnalyticsClient*> new];
name:@"sos" deviceAnalytics:NO iCloudAnalytics:YES]];
[clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForPCS]
name:@"pcs" deviceAnalytics:NO iCloudAnalytics:YES]];
+ [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForSignIn]
+ name:@"signins" deviceAnalytics:NO iCloudAnalytics:YES]];
+ [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForLocal]
+ name:@"local" deviceAnalytics:YES iCloudAnalytics:NO]];
} 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
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
- (NSData*)getLoggingJSON:(bool)pretty
forUpload:(BOOL)upload
participatingClients:(NSMutableArray<SFAnalyticsClient*>**)clients
+ force:(BOOL)force // supdctl uploads ignore privacy settings and recency
error:(NSError**)error
{
NSMutableArray<SFAnalyticsClient*>* localClients = [NSMutableArray new];
ckdeviceID = os_variant_has_internal_diagnostics("com.apple.security") ? [self askSecurityForCKDeviceID] : nil;
}
for (SFAnalyticsClient* client in self->_topicClients) {
- if ([client requireDeviceAnalytics] && !_isDeviceAnalyticsEnabled()) {
+ if (!force && [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()) {
+ if (!force && [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;
if (upload) {
NSDate* uploadDate = store.uploadDate;
- if (uploadDate && [[NSDate date] timeIntervalSinceDate:uploadDate] < _secondsBetweenUploads) {
+ if (!force && uploadDate && [[NSDate date] timeIntervalSinceDate:uploadDate] < _secondsBetweenUploads) {
secnotice("json", "ignoring client '%@' for %@ because last upload too recent: %@",
client.name, _internalTopicName, uploadDate);
continue;
}
- if (!uploadDate) {
+ if (!force && !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);
+ if (force) {
+ secnotice("json", "client '%@' for topic '%@' force-included", client.name, _internalTopicName);
+ } else {
+ secnotice("json", "including client '%@' for topic '%@' for upload", client.name, _internalTopicName);
+ }
[localClients addObject:client];
}
[softFailures addObject:store.softFailures];
}
- if (clients) {
- *clients = localClients;
- }
-
if (upload && [localClients count] == 0) {
if (error) {
NSString *description = [NSString stringWithFormat:@"Upload too recent for all clients for %@", _internalTopicName];
return nil;
}
+ if (clients) {
+ *clients = localClients;
+ }
+
[self addFailures:hardFailures toUploadRecords:uploadRecords threshold:_maxEventsToReport/10];
[self addFailures:softFailures toUploadRecords:uploadRecords threshold:0];
if (error) {
*error = localError;
}
+
return json;
}
// 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
+- (NSURL*)splunkUploadURL:(BOOL)force
{
- if (![self haveEligibleClients]) {
+ if (!force && ![self haveEligibleClients]) { // force is true IFF called from supdctl. Customers don't have it and internal audiences must call it explicitly.
secnotice("getURL", "Not going to talk to server for topic %@ because no eligible clients", [self internalTopicName]);
return nil;
}
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);
+ secnotice("getURL", "Overriding server-sent post frequency because device is internal (%lu -> %lu)", (unsigned long)secondsBetweenUploads, (unsigned long)self->_secondsBetweenUploads);
} else {
strongSelf->_secondsBetweenUploads = secondsBetweenUploads;
}
return dbpath;
}
++ (NSString*)databasePathForLocal
+{
+ return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/localkeychain.db") path];
+}
+
+ (NSString*)databasePathForTrustdHealth
{
#if TARGET_OS_IPHONE
#endif
}
++ (NSString*)databasePathForSignIn
+{
+ return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(CFSTR("Analytics/signin_metrics.db")) path];
+}
+
@end
@interface supd ()
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
+ // Run our regularly scheduled scan
[self performRegularlyScheduledUpload];
}
});
- (void)performRegularlyScheduledUpload {
secnotice("upload", "Starting uploads in response to regular trigger");
NSError *error = nil;
- if ([self uploadAnalyticsWithError:&error]) {
+ if ([self uploadAnalyticsWithError:&error force:NO]) {
secnotice("upload", "Regularly scheduled upload successful");
} else {
secerror("upload: Failed to complete regularly scheduled upload: %@", error);
}
}
-- (BOOL)uploadAnalyticsWithError:(NSError**)error {
+- (BOOL)uploadAnalyticsWithError:(NSError**)error force:(BOOL)force {
[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!
+ __block NSURL* endpoint = [topic splunkUploadURL:force]; // has side effects!
if (!endpoint) {
secnotice("upload", "Skipping upload for %@ because no endpoint", [topic internalTopicName]);
}
NSMutableArray<SFAnalyticsClient*>* clients = [NSMutableArray new];
- NSData* json = [topic getLoggingJSON:false forUpload:YES participatingClients:&clients error:&localError];
+ NSData* json = [topic getLoggingJSON:false forUpload:YES participatingClients:&clients force:force error:&localError];
if (json) {
if ([topic isSampledUpload]) {
if (![self->_reporter saveReport:json fileName:[topic internalTopicName]]) {
NSData* json = nil;
for (SFAnalyticsTopic* topic in self->_analyticsTopics) {
if ([topic.internalTopicName isEqualToString:topicName]) {
- json = [topic getLoggingJSON:pretty forUpload:NO participatingClients:nil error:&error];
+ json = [topic getLoggingJSON:pretty forUpload:NO participatingClients:nil force:!runningTests error:&error];
}
}
if (!json) {
- (void)forceUploadWithReply:(void (^)(BOOL, NSError*))reply {
secnotice("upload", "Performing upload in response to rpc message");
NSError* error = nil;
- BOOL result = [self uploadAnalyticsWithError:&error];
+ BOOL result = [self uploadAnalyticsWithError:&error force:YES];
secnotice("upload", "Result of manually triggered upload: %@, error: %@", result ? @"success" : @"failure", error);
reply(result, error);
}
#include "lib/SecArgParse.h"
#import "supd/supdProtocol.h"
#import <Foundation/NSXPCConnection_Private.h>
-#import "SFAnalytics.h"
+#import <Security/SFAnalytics.h>
/* Internal Topic Names */
NSString* const SFAnalyticsTopicKeySync = @"KeySyncTopic";
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]);
+ // Success! Only print the JSON blob to make output easier to parse
+ nsprintf(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
} else {
nsprintf(@"supd gave us an error: %@", error);
}
{ .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"},
+ { .command="upload", .flag=&forceUpload, .flagval=true, .description="Force an upload of analytics data to server (ignoring privacy settings)"},
{} // Need this!
};
#ifndef mockaks_h
#define mockaks_h
+#import "SecKeybagSupport.h"
+
+#if USE_KEYSTORE
#import <libaks.h>
@interface SecMockAKS : NSObject
+ (bool)useGenerationCount;
@end
+#endif /* USE_KEYSTORE */
+
#endif /* mockaks_h */
* @APPLE_LICENSE_HEADER_END@
*/
+#import "SecKeybagSupport.h"
+
+#if USE_KEYSTORE
#import <libaks.h>
#import <libaks_ref_key.h>
#import <MobileKeyBag/MobileKeyBag.h>
+#endif
+
#import <CryptoTokenKit/CryptoTokenKit.h>
#import <ctkclient.h>
#import <coreauthd_spi.h>
#import <SecurityFoundation/SFEncryptionOperation.h>
#import "mockaks.h"
+#if USE_KEYSTORE
+
@implementation SecMockAKS
+ (bool)isLocked:(keyclass_t)key_class
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;
+ SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256];
+ SFAESKey* key = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:nil];
+ *ot = (__bridge_retained aks_ref_key_t)key;
+ return kAKSReturnSuccess;
}
int
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)
+int aks_ref_key_create_with_blob(keybag_handle_t keybag, const uint8_t *ref_key_blob, size_t ref_key_blob_len, aks_ref_key_t* handle)
{
- *handle = NULL;
+ aks_ref_key_create(keybag, 0, 0, NULL, 0, handle);
return 0;
}
return 0;
}
+CFStringRef kMKBDeviceModeMultiUser = CFSTR("kMKBDeviceModeMultiUser");
+CFStringRef kMKBDeviceModeSingleUser = CFSTR("kMKBDeviceModeSingleUser");
+CFStringRef kMKBDeviceModeKey = CFSTR("kMKBDeviceModeKey");
+
static CFStringRef staticKeybagHandle = CFSTR("keybagHandle");
int
return 0;
}
+int MKBGetDeviceLockState(CFDictionaryRef options)
+{
+ if ([SecMockAKS isLocked:key_class_ak] )
+ return kMobileKeyBagDeviceIsLocked;
+ return kMobileKeyBagDeviceIsUnlocked;
+}
+
+CF_RETURNS_RETAINED CFDictionaryRef
+MKBUserTypeDeviceMode(CFDictionaryRef options, CFErrorRef * error)
+{
+ return CFBridgingRetain(@{
+ (__bridge NSString *)kMKBDeviceModeKey : (__bridge NSString *)kMKBDeviceModeSingleUser,
+ });
+}
+
+int MKBForegroundUserSessionID( CFErrorRef * error)
+{
+ return 0;
+}
+#endif /* USE_KEYSTORE */
const CFTypeRef kAKSKeyAcl = (CFTypeRef)CFSTR("kAKSKeyAcl");
const CFTypeRef kAKSKeyAclParamRequirePasscode = (CFTypeRef)CFSTR("kAKSKeyAclParamRequirePasscode");
* @APPLE_LICENSE_HEADER_END@
*/
+#import "SecKeybagSupport.h"
#import "SecDbKeychainItem.h"
#import "SecdTestKeychainUtilities.h"
#import "CKKS.h"
#import <SecurityFoundation/SFEncryptionOperation.h>
#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
+#if USE_KEYSTORE
#import <libaks.h>
+#endif
#import <sqlite3.h>
#import "mockaks.h"
* that leads to the vnode delete kevent trap triggering for sqlite
* over and over again.
*/
+#if OCTAGON
SecCKKSTestSetDisableSOS(true);
+#endif
//securityd_init(NULL);
}
//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
{
- (void)testCreateSampleDatabase
{
+#if USE_KEYSTORE
id mock = OCMClassMock([SecMockAKS class]);
OCMStub([mock useGenerationCount]).andReturn(true);
+#endif
[self createManyItems];
[self createManyKeys];
- (void)testTestAKSGenerationCount
{
+#if USE_KEYSTORE
id mock = OCMClassMock([SecMockAKS class]);
OCMStub([mock useGenerationCount]).andReturn(true);
[self createManyItems];
[self findManyItems:50];
+#endif
}
XCTAssertEqual(SQLITE_OK, sqlite3_close(handle), "close sqlite");
}
+- (void)checkIncremental
+{
+ /*
+ * check that we made incremental vacuum mode
+ */
+
+ __block CFErrorRef localError = NULL;
+ __block bool ok = true;
+ __block int vacuumMode = -1;
+
+ kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) {
+ ok &= SecDbPrepare(dbt, CFSTR("PRAGMA auto_vacuum"), &localError, ^(sqlite3_stmt *stmt) {
+ ok = SecDbStep(dbt, stmt, NULL, ^(bool *stop) {
+ vacuumMode = sqlite3_column_int(stmt, 0);
+ });
+ });
+ return ok;
+ });
+ XCTAssertEqual(ok, true, "should work to fetch auto_vacuum value: %@", localError);
+ XCTAssertEqual(vacuumMode, 2, "vacuum mode should be incremental (2)");
+
+ CFReleaseNull(localError);
+
+}
+
- (void)testUpgradeFromVersion10_5
{
SecKeychainDbReset(^{
NSLog(@"find items from old database");
[self findManyItems:50];
+
+ [self checkIncremental];
}
- (void)testUpgradeFromVersion11_1
NSLog(@"find items from old database");
[self findManyItems:50];
+
+ [self checkIncremental];
+}
+
+#if USE_KEYSTORE
+
+- (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");
}
- (bool)isLockedSoon:(keyclass_t)key_class
return false;
}
-
/*
* Lock in the middle of migration
*/
SecKeychainDbGetVersion(dbt, &version, &error);
XCTAssertEqual(error, NULL, "error getting version");
XCTAssertEqual(version, 0x50a, "managed to upgrade when we shouldn't have");
+
+ return true;
});
/* user got the SEP out of DFU */
int version = 0;
SecKeychainDbGetVersion(dbt, &version, &error);
XCTAssertEqual(error, NULL, "error getting version");
- XCTAssertEqual(version, 0x20b, "didnt managed to upgrade");
+ XCTAssertEqual(version, 0x40b, "didnt managed to upgrade");
+
+ return true;
});
NSLog(@"find items from old database");
[self findManyItems:50];
}
+#endif /* USE_KEYSTORE */
@end
#include <Security/cssmtype.h>
#include <Security/x509defs.h>
-#endif
+#endif // SEC_OS_OSX
__BEGIN_DECLS
CFDataRef SecCertificateCopyNormalizedSubjectSequence(SecCertificateRef certificate)
__OSX_AVAILABLE_STARTING(__MAC_10_12_4, __IPHONE_10_3);
+/*!
+ @function SecCertificateCopyKey
+ @abstract Retrieves the public key for a given certificate.
+ @param certificate A reference to the certificate from which to retrieve the public key.
+ @result A reference to the public key for the specified certificate. Your code must release this reference by calling the CFRelease function. If the public key has an encoding issue or uses an unsupported algorithm, the returned reference will be null.
+ */
+__nullable CF_RETURNS_RETAINED
+SecKeyRef SecCertificateCopyKey(SecCertificateRef certificate)
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
#if TARGET_OS_IPHONE
/*!
@function SecCertificateCopyPublicKey
@abstract Retrieves the public key for a given certificate.
@param certificate A reference to the certificate from which to retrieve the public key.
@result A reference to the public key for the specified certificate. Your code must release this reference by calling the CFRelease function.
+ @discussion NOTE: Deprecated in iOS 12.0; use SecCertificateCopyKey instead for cross-platform availability.
*/
__nullable
SecKeyRef SecCertificateCopyPublicKey(SecCertificateRef certificate)
- __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_10_3);
+ API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", ios(10.3, 12.0)) API_UNAVAILABLE(macos);
#endif
#if TARGET_OS_OSX
@param certificate A reference to the certificate from which to retrieve the public key.
@param key On return, a reference to the public key for the specified certificate. Your code must release this reference by calling the CFRelease function.
@result A result code. See "Security Error Codes" (SecBase.h).
+ @discussion NOTE: Deprecated in macOS 10.14; use SecCertificateCopyKey instead for cross-platform availability.
*/
OSStatus SecCertificateCopyPublicKey(SecCertificateRef certificate, SecKeyRef * __nonnull CF_RETURNS_RETAINED key)
- __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+ API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", macos(10.3, 10.14)) API_UNAVAILABLE(ios);
#endif
/*!
*/
__nullable
CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate)
- __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, __IPHONE_10_3, __IPHONE_11_0, "SecCertificateCopySerialNumber is deprecated. Use SecCertificateCopySerialNumberData instead.");
+ API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", ios(10.3, 11.0)) API_UNAVAILABLE(macos);
#endif
#if TARGET_OS_OSX
*/
__nullable
CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorRef *error)
- __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_7, __MAC_10_13, __IPHONE_NA, __IPHONE_NA, "SecCertificateCopySerialNumber is deprecated. Use SecCertificateCopySerialNumberData instead.");
+ API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", macos(10.7, 10.13)) API_UNAVAILABLE(ios);
#endif
/*
CFArrayRef SecCertificateCopyiPhoneDeviceCAChain(void)
__OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0);
+typedef CF_ENUM(uint32_t, SeciAPSWAuthCapabilitiesType) {
+ kSeciAPSWAuthGeneralCapabilities = 0,
+ kSeciAPSWAuthAirPlayCapabilities = 1,
+ kSeciAPSWAuthHomeKitCapabilities = 2,
+} __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_11_3);
+
+/* Return the iAP SW Auth capabilities bitmask from the specificed
+ * SeciAPSWAuthCapabilitiesType type marker extensions. */
+CF_RETURNS_RETAINED
+CFDataRef SecCertificateCopyiAPSWAuthCapabilities(SecCertificateRef certificate,
+ SeciAPSWAuthCapabilitiesType type)
+ __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_11_3);
/*!
@function SecCertificateCopyExtensionValue
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)
*/
@abstract Return a newly generated CSR for subject and keypair.
@param subject RDNs in the subject
@param paramters Parameters for the CSR generation. See above.
- @param publicKey Public key (NOTE: This is unused)
+ @param publicKey Public key
@param privateKey Private key
@result On success, a newly allocated CSR, otherwise NULL
@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 publicKey Public key
@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
extern const CFStringRef kSecPolicyAppleTestOTAPKISigner
__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);
+ API_DEPRECATED_WITH_REPLACEMENT("kSecPolicyAppleIDValidationRecordSigning", ios(7.0,10.0), macos(10.9,10.12));
extern const CFStringRef kSecPolicyAppleIDValidationRecordSigning
__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
extern const CFStringRef kSecPolicyAppleSMPEncryption
__OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0);
extern const CFStringRef kSecPolicyAppleiPhoneVPNApplicationSigning
__OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0);
+extern const CFStringRef kSecPolicyAppleiAPSWAuth
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+extern const CFStringRef kSecPolicyAppleDemoDigitalCatalog
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+extern const CFStringRef kSecPolicyAppleAssetReceipt
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+extern const CFStringRef kSecPolicyAppleDeveloperIDPlusTicket
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
/*!
@enum Policy Name Constants (Private)
/*!
@function SecPolicyCreateLockdownPairing
@abstract basic x509 policy for checking lockdown pairing certificate chains.
- @disucssion This policy checks some of the Basic X.509 policy options with no
+ @discussion This policy checks some of the Basic X.509 policy options with no
validity check. It explicitly allows for empty subjects.
@result A policy object. The caller is responsible for calling CFRelease
on this when it is no longer needed.
SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef __nullable testRootHash)
__OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0);
+/*!
+ @function SecPolicyCreateiAPSWAuth
+ @abstract Returns a policy object for verifying iAP Software Auth certificates
+ @discussion The resulting policy uses the Basic X.509 policy with no validity check
+ and pinning options:
+ * There are exactly 2 certs in the chain.
+ * The leaf has a marker extension with OID 1.2.840.113635.100.6.59.1
+ The intended use of this policy is that the caller pass in the
+ SW Auth root to SecTrustSetAnchorCertificates().
+ @result A policy object. The caller is responsible for calling CFRelease on this when
+ it is no longer needed.
+ */
+__nullable CF_RETURNS_RETAINED
+SecPolicyRef SecPolicyCreateiAPSWAuth(void)
+ __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3);
+
/*!
@function SecPolicyCreateDemoDigitalCatalog
@abstract Returns a policy object for evaluating certificate chains for signing Digital
SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void)
__OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3);
+/*!
+ @function SecPolicyCreateAppleAssetReceipt
+ @abstract Returns a policy object for evaluating certificate chains for signing Asset Receipts
+ @discussion This policy uses the Basic X.509 policy with no validity check
+ and pinning options:
+ * The chain is anchored to any of the production Apple Root CAs. Internal releases allow
+ the chain to be anchored to Test Apple Root CAs if a defaults write for the policy is set.
+ * There are exactly 3 certs in the chain.
+ * The intermediate has a marker extension with OID 1.2.840.113635.100.6.2.10.
+ * The leaf has a marker extension with OID 1.2.840.113635.100.6.61.
+ * RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger.
+ @result A policy object. The caller is responsible for calling CFRelease
+ on this when it is no longer needed.
+ */
+__nullable CF_RETURNS_RETAINED
+SecPolicyRef SecPolicyCreateAppleAssetReceipt(void)
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+/*!
+ @function SecPolicyCreateAppleDeveloperIDPlustTicket
+ @abstract Returns a policy object for evaluating certificate chains for signing Developer ID+ Tickets
+ @discussion This policy uses the Basic X.509 policy with no validity check
+ and pinning options:
+ * The chain is anchored to any of the production Apple Root CAs.
+ * There are exactly 3 certs in the chain.
+ * The intermediate has a marker extension with OID 1.2.840.113635.100.6.2.17.
+ * The leaf has a marker extension with OID 1.2.840.113635.100.6.1.30.
+ * RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger.
+ @result A policy object. The caller is responsible for calling CFRelease
+ on this when it is no longer needed.
+ */
+__nullable CF_RETURNS_RETAINED
+SecPolicyRef SecPolicyCreateAppleDeveloperIDPlusTicket(void)
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+/*!
+ @function SecPolicyCreateiAPSWAuthWithExpiration
+ @abstract Returns a policy object for verifying iAP Software Auth certificates
+ @param checkExpiration Determines whether the policy checks expiration on the certificates
+ @discussion The resulting policy uses the Basic X.509 policy and pinning options:
+ * There are exactly 2 certs in the chain.
+ * The leaf has a marker extension with OID 1.2.840.113635.100.6.59.1
+ The intended use of this policy is that the caller pass in the
+ SW Auth root to SecTrustSetAnchorCertificates().
+ @result A policy object. The caller is responsible for calling CFRelease on this when
+ it is no longer needed.
+ */
+__nullable CF_RETURNS_RETAINED
+SecPolicyRef SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration)
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+/*!
+ @function SecPolicyCreateAppleFDRProvisioning
+ @abstract Returns a policy object for verifying FDR Provisioning certificates
+ @discussion The resulting policy uses the Basic X.509 policy with no validity check.
+ The intended use of this policy is that the caller pass in the FDR root to SecTrustSetAnchorCertificates().
+ @result A policy object. The caller is responsible for calling CFRelease on this when
+ it is no longer needed.
+ */
+__nullable CF_RETURNS_RETAINED
+SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void)
+ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
/*
* Legacy functions (OS X only)
*/
to SecPolicyCreateWithProperties. The return value can be NULL
if no supported policy was found for the OID argument. */
__nullable
-CFStringRef SecPolicyGetStringForOID(CSSM_OID* oid);
+CFStringRef SecPolicyGetStringForOID(CSSM_OID* oid)
+ API_DEPRECATED("No longer supported", macos(10.5,10.14));
/*!
@function SecPolicyCreateAppleTimeStampingAndRevocationPolicies
@typedef SecTrustResultType
@abstract Specifies the trust result type.
@discussion SecTrustResultType results have two dimensions. They specify
- both whether evaluation suceeded and whether this is because of a user
+ both whether evaluation succeeded and whether this is because of a user
decision. The commonly expected result is kSecTrustResultUnspecified,
which indicates a positive result that wasn't decided by the user. The
common failure is kSecTrustResultRecoverableTrustFailure, which means a
dispatch queue, or in a separate thread from your application's main
run loop. Alternatively, you can use the SecTrustEvaluateAsync function.
*/
-OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType * __nullable result)
+OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result)
__OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0);
#ifdef __BLOCKS__
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0);
#endif
+/*!
+ @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)
+ API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
+
/*!
@function SecTrustGetTrustResult
@param trust A reference to a trust object.
OSStatus SecTrustSetPinningException(SecTrustRef trust)
__OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0);
+#ifdef __BLOCKS__
/*!
- @function SecTrustEvaluateWithError
- @abstract Evaluates a trust reference synchronously.
+ @function SecTrustEvaluateFastAsync
+ @abstract Evaluates a trust reference asynchronously.
@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.
+ @param queue A dispatch queue on which the result callback will be
+ executed. Note that this function MUST be called from that queue.
+ @param result A SecTrustCallback block which will be executed when the
+ trust evaluation is complete. The block is guaranteed to be called exactly once
+ when the result code is errSecSuccess, and not called otherwise. Note that this
+ block may be called synchronously inline if no asynchronous operations are required.
+ @result A result code. See "Security Error Codes" (SecBase.h).
*/
-__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);
+OSStatus SecTrustEvaluateFastAsync(SecTrustRef trust, dispatch_queue_t queue, SecTrustCallback result)
+ __API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
+#endif
/*!
@function SecTrustReportTLSAnalytics
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
-
-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_SYMLINKS = $(PROJECT_DIR)/header_symlinks
// 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
+// We also add some 'private' headers here that aren't in the framework; this is unfortunate but better than putting very internal headers as SPI.
+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 -extra-private-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.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.
--- /dev/null
+#!/bin/sh
+
+framework="$1"
+
+found=no
+
+for a in ${TEST_FRAMEWORK_SEARCH_PATHS}; do
+ if test -d "${a}/${framework}" ; then
+ dst="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+
+ mkdir -p "{dst}" || { echo "mkdir failed with: $?" ; exit 1; }
+ ditto "${a}/${framework}" "${dst}/${framework}" || { echo "ditto failed with: $?" ; exit 1; }
+ xcrun codesign -s - -f "${dst}/${framework}" || { echo "codesign failed with: $?" ; exit 1; }
+
+ found=yes
+ break
+ fi
+done
+
+test "X${found}" != "Xyes" && exit 1
+
+exit 0