From 2b1671fa2b47dc427293e35029f0c21900e0bd45 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 13 May 2004 21:46:53 +0000 Subject: [PATCH] Security-176.tar.gz --- AppleCSP/AppleCSP/.cvsignore | 1 - AppleDL/.cvsignore | 1 - AppleX509CL/.cvsignore | 2 - Keychain/CCallbackMgr.cp | 60 ++++--- Keychain/CCallbackMgr.h | 4 +- Keychain/SecCFTypes.cpp | 86 ++++++++-- Keychain/SecCFTypes.h | 10 +- Keychain/SecRuntime.cpp | 2 +- Keychain/iToolsTrustedApps.plist | 10 +- SecureTransport/sslTransport.cpp | 11 +- Security.pbproj/.cvsignore | 2 - Security.pbproj/project.pbxproj | 106 +++++++++---- .../Authorization/AuthorizationEngine.cpp | 1 - .../Authorization/AuthorizationEngine.h | 1 - .../Authorization/AuthorizationRule.cpp | 51 +++++- .../Authorization/AuthorizationRule.h | 1 - .../Authorization/authorization.plist | 17 ++ .../SecuritySettings.pbproj/.cvsignore | 1 - SecurityServer/authority.cpp | 16 +- SecurityServer/authority.h | 9 +- SecurityServer/server.cpp | 30 +++- SecurityServer/server.h | 12 +- SecurityServer/session.cpp | 4 +- SecurityServer/session.h | 2 +- SecurityServer/transition.cpp | 10 +- SecurityServer/ucsp.defs | 2 +- cdsa/cdsa_pluginlib/.cvsignore | 1 - cdsa/cdsa_utilities/.cvsignore | 1 - cdsa/cdsa_utilities/ccaudit.cpp | 105 +++++++++++++ cdsa/cdsa_utilities/ccaudit.h | 148 ++++++++++++++++++ cdsa/cdsa_utilities/utilities.h | 1 - cdsa/cssm/.cvsignore | 1 - cdsa/mds/.cvsignore | 2 - checkpw/checkpw.c | 10 +- keychains/Makefile | 28 ++-- keychains/X509Anchors | Bin 178112 -> 0 bytes keychains/X509Certificates | Bin 79704 -> 0 bytes keychains/certscript | 24 --- keychains/makecerts | 24 --- keychains/makeroots | 20 --- keychains/postinstall.sh | 21 +++ keychains/roots/.cvsignore | 1 - keychains/roots/AOLTimeWarner1.der | Bin 0 -> 1002 bytes keychains/roots/AmericaOnline1.der | Bin 0 -> 936 bytes keychains/roots/TCTrustCenterClass1CA.der | Bin 0 -> 864 bytes keychains/roots/TCTrustCenterClass2CA.der | Bin 0 -> 864 bytes keychains/roots/TCTrustCenterClass3CA.der | Bin 0 -> 864 bytes keychains/roots/TCTrustCenterClass4CA.der | Bin 0 -> 864 bytes .../roots/TCTrustCenterTimeStampingCA.der | Bin 0 -> 839 bytes .../ValiCertAddTrustPublicChainingCA.cer | Bin 0 -> 927 bytes keychains/roots/ValiCertAddTrustSystemCA.cer | Bin 0 -> 918 bytes keychains/roots/ValiCertClass1PVA.cer | Bin 0 -> 747 bytes keychains/roots/ValiCertClass2PVA.cer | Bin 0 -> 747 bytes keychains/roots/ValiCertClass3PVA.cer | Bin 0 -> 747 bytes keychains/roots/beTRUSTedRootCertificate.der | Bin 0 -> 1328 bytes 55 files changed, 638 insertions(+), 201 deletions(-) delete mode 100644 AppleCSP/AppleCSP/.cvsignore delete mode 100644 AppleDL/.cvsignore delete mode 100644 AppleX509CL/.cvsignore delete mode 100644 Security.pbproj/.cvsignore delete mode 100644 SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore delete mode 100644 cdsa/cdsa_pluginlib/.cvsignore delete mode 100644 cdsa/cdsa_utilities/.cvsignore create mode 100644 cdsa/cdsa_utilities/ccaudit.cpp create mode 100644 cdsa/cdsa_utilities/ccaudit.h delete mode 100644 cdsa/cssm/.cvsignore delete mode 100644 cdsa/mds/.cvsignore delete mode 100644 keychains/X509Anchors delete mode 100644 keychains/X509Certificates delete mode 100755 keychains/certscript delete mode 100755 keychains/makecerts delete mode 100755 keychains/makeroots create mode 100755 keychains/postinstall.sh delete mode 100644 keychains/roots/.cvsignore create mode 100644 keychains/roots/AOLTimeWarner1.der create mode 100644 keychains/roots/AmericaOnline1.der create mode 100644 keychains/roots/TCTrustCenterClass1CA.der create mode 100644 keychains/roots/TCTrustCenterClass2CA.der create mode 100644 keychains/roots/TCTrustCenterClass3CA.der create mode 100644 keychains/roots/TCTrustCenterClass4CA.der create mode 100644 keychains/roots/TCTrustCenterTimeStampingCA.der create mode 100644 keychains/roots/ValiCertAddTrustPublicChainingCA.cer create mode 100644 keychains/roots/ValiCertAddTrustSystemCA.cer create mode 100644 keychains/roots/ValiCertClass1PVA.cer create mode 100644 keychains/roots/ValiCertClass2PVA.cer create mode 100644 keychains/roots/ValiCertClass3PVA.cer create mode 100644 keychains/roots/beTRUSTedRootCertificate.der diff --git a/AppleCSP/AppleCSP/.cvsignore b/AppleCSP/AppleCSP/.cvsignore deleted file mode 100644 index abaf517e..00000000 --- a/AppleCSP/AppleCSP/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -rotty?Data diff --git a/AppleDL/.cvsignore b/AppleDL/.cvsignore deleted file mode 100644 index 7b6b8240..00000000 --- a/AppleDL/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -AppleCSPDL?Data diff --git a/AppleX509CL/.cvsignore b/AppleX509CL/.cvsignore deleted file mode 100644 index 8be42d6a..00000000 --- a/AppleX509CL/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -PBUserInfo -AppleX509CL?Data diff --git a/Keychain/CCallbackMgr.cp b/Keychain/CCallbackMgr.cp index 5fc770bd..6e549b35 100644 --- a/Keychain/CCallbackMgr.cp +++ b/Keychain/CCallbackMgr.cp @@ -130,7 +130,8 @@ void CCallbackMgr::RemoveCallback(SecKeychainCallback inCallbackFunction) MacOSError::throwMe(errSecInvalidCallback); } -void CCallbackMgr::AlertClients(SecKeychainEvent inEvent, +void CCallbackMgr::AlertClients(const list &eventCallbacks, + SecKeychainEvent inEvent, pid_t inPid, const Keychain &inKeychain, const Item &inItem) @@ -138,15 +139,10 @@ void CCallbackMgr::AlertClients(SecKeychainEvent inEvent, secdebug("kcnotify", "dispatch event %ld pid %d keychain %p item %p", inEvent, inPid, &inKeychain, !!inItem ? &*inItem : NULL); - // Deal with events that we care about ourselves first. - if (inEvent == kSecDeleteEvent && inKeychain.get() && inItem.get()) - inKeychain->didDeleteItem(inItem.get()); - // Iterate through callbacks, looking for those registered for inEvent const SecKeychainEventMask theMask = 1U << inEvent; - for ( CallbackInfoListIterator ix = CCallbackMgr::Instance().mEventCallbacks.begin(); - ix != CCallbackMgr::Instance().mEventCallbacks.end(); ++ix ) + for (ConstCallbackInfoListIterator ix = eventCallbacks.begin(); ix != eventCallbacks.end(); ++ix) { if (!(ix->mEventMask & theMask)) continue; @@ -175,40 +171,54 @@ void CCallbackMgr::AlertClients(SecKeychainEvent inEvent, * If it wasn't 'us', we should remove our cached reference to the item that was deleted. * ***********************************************************************************/ -void CCallbackMgr::Event (Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary) +void CCallbackMgr::Event(Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary) { // Decode from userInfo the event type, 'keychain' CFDict, and 'item' CFDict SecKeychainEvent thisEvent = whichEvent; pid_t thisPid; - const NameValuePair* pidRef = dictionary.FindByName (PID_KEY); + const NameValuePair* pidRef = dictionary.FindByName(PID_KEY); if (pidRef == 0) { thisPid = 0; } else { - thisPid = *reinterpret_cast(pidRef->Value ().data ()); + thisPid = *reinterpret_cast(pidRef->Value().data()); } Keychain thisKeychain = 0; - - // make sure we have a database identifier - if (dictionary.FindByName (SSUID_KEY) != 0) - { - DLDbIdentifier dbid = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary (dictionary); - thisKeychain = globals().storageManager.keychain (dbid); - } - - const NameValuePair* item = dictionary.FindByName (ITEM_KEY); Item thisItem; + list eventCallbacks; - if (item && thisKeychain) - { - PrimaryKey pk(item->Value ()); - thisItem = thisKeychain->item(pk); - } + { + // Lock the global API lock before doing stuff with StorageManager. + StLock _(globals().apiLock); + + // make sure we have a database identifier + if (dictionary.FindByName (SSUID_KEY) != 0) + { + DLDbIdentifier dbid = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary (dictionary); + thisKeychain = globals().storageManager.keychain(dbid); + } + + const NameValuePair* item = dictionary.FindByName(ITEM_KEY); + + if (item && thisKeychain) + { + PrimaryKey pk(item->Value()); + thisItem = thisKeychain->item(pk); + } + + // Deal with events that we care about ourselves first. + if (thisEvent == kSecDeleteEvent && thisKeychain.get() && thisItem.get()) + thisKeychain->didDeleteItem(thisItem.get()); + + 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. + } // Notify our process of this event. - CCallbackMgr::AlertClients(thisEvent, thisPid, thisKeychain, thisItem); + CCallbackMgr::AlertClients(eventCallbacks, thisEvent, thisPid, thisKeychain, thisItem); } diff --git a/Keychain/CCallbackMgr.h b/Keychain/CCallbackMgr.h index be58f280..972fd955 100644 --- a/Keychain/CCallbackMgr.h +++ b/Keychain/CCallbackMgr.h @@ -81,8 +81,8 @@ private: void Event (Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary); - static void AlertClients( SecKeychainEvent inEvent, pid_t inPid, - const Keychain& inKeychain, const Item &inItem); + static void AlertClients(const list &eventCallbacks, SecKeychainEvent inEvent, pid_t inPid, + const Keychain& inKeychain, const Item &inItem); list mEventCallbacks; static CCallbackMgr* mCCallbackMgr; diff --git a/Keychain/SecCFTypes.cpp b/Keychain/SecCFTypes.cpp index a6a0e378..1d1a342d 100644 --- a/Keychain/SecCFTypes.cpp +++ b/Keychain/SecCFTypes.cpp @@ -58,13 +58,27 @@ SecCFTypes::SecCFTypes() : Policy("SecPolicy"), PolicyCursor("SecPolicySearch"), Trust("SecTrust"), - TrustedApplication("SecTrustedApplication") + TrustedApplication("SecTrustedApplication"), + allocator(CFAllocatorCreate(NULL, &CFClass::allocatorContext)) { } // // CFClass // +CFAllocatorContext CFClass::allocatorContext = +{ + 0, + NULL, + NULL, /* retain */ + NULL, /* release */ + NULL, /* copyDescription */ + allocatorAllocate, /* allocate */ + allocatorReallocate, /* reallocate */ + allocatorDeallocate, /* deallocate */ + allocatorPreferredSize /* preferredSize */ +}; + CFClass::CFClass(const char *name) { // initialize the CFRuntimeClass structure @@ -72,7 +86,7 @@ CFClass::CFClass(const char *name) className = name; init = NULL; copy = NULL; - finalize = finalizeType; + finalize = NULL; equal = equalType; hash = hashType; copyFormattingDesc = copyFormattingDescType; @@ -83,21 +97,6 @@ CFClass::CFClass(const char *name) assert(typeID != _kCFRuntimeNotATypeID); } -void -CFClass::finalizeType(CFTypeRef cf) -{ - /* - * Called on a CFRelease of any Sec object: single thread through - * same lock held by public API calls. This is a recursive lock - * so it's safe to do this for CF objects allocated and released - * within the Sec layer. - */ - StLock _(globals().apiLock); - SecCFObject *obj = SecCFObject::optional(cf); - if (!obj->isNew()) - obj->~SecCFObject(); -} - Boolean CFClass::equalType(CFTypeRef cf1, CFTypeRef cf2) { @@ -122,3 +121,56 @@ CFClass::copyDebugDescType(CFTypeRef cf) { return SecCFObject::optional(cf)->copyDebugDesc(); } + +// +// CFAllocatorContext callbacks. +// +void * +CFClass::allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info) +{ + return malloc(allocSize); +} + +void * +CFClass::allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) +{ + return realloc(ptr, newsize); +} + +void +CFClass::allocatorDeallocate(void *ptr, void *info) +{ + /* + * Called on a CFRelease of any Sec object: single thread through + * same lock held by public API calls. This is a recursive lock + * so it's safe to do this for CF objects allocated and released + * within the Sec layer. + */ + StLock _(globals().apiLock); + CFTypeRef cf = reinterpret_cast(reinterpret_cast(ptr) + sizeof(CFAllocatorRef)); + CFIndex rc = CFGetRetainCount(cf); + if (rc == 1) + { + SecCFObject *obj = SecCFObject::optional(cf); + if (!obj->isNew()) + obj->~SecCFObject(); + free(ptr); + } + else if (rc > 1) + { + // Since CFRelease did nothing other than call CFAllocatorDeallocate() followed + // by a CFRelease() of the allocator we need to counter that here. + CFRetain(CFGetAllocator(cf)); + CFRelease(cf); + } + else + { + // Something bad happened we're screwed + } +} + +CFIndex +CFClass::allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info) +{ + return size; +} diff --git a/Keychain/SecCFTypes.h b/Keychain/SecCFTypes.h index a9f62e9d..63873e83 100644 --- a/Keychain/SecCFTypes.h +++ b/Keychain/SecCFTypes.h @@ -36,14 +36,20 @@ public: CFClass(const char *name); private: - static void finalizeType(CFTypeRef cf); static Boolean equalType(CFTypeRef cf1, CFTypeRef cf2); static CFHashCode hashType(CFTypeRef cf); static CFStringRef copyFormattingDescType(CFTypeRef cf, CFDictionaryRef dict); static CFStringRef copyDebugDescType(CFTypeRef cf); + // CFAllocatorContext callbacks. + static void *allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info); + static void *allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info); + static void allocatorDeallocate(void *ptr, void *info); + static CFIndex allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info); + public: CFTypeID typeID; + static CFAllocatorContext allocatorContext; }; /* Singleton that registers all the CFClass instances with the CFRuntime. @@ -102,6 +108,8 @@ public: CFClass PolicyCursor; CFClass Trust; CFClass TrustedApplication; + + CFAllocatorRef allocator; }; extern SecCFTypes &gTypes(); diff --git a/Keychain/SecRuntime.cpp b/Keychain/SecRuntime.cpp index a8c01a92..8033967d 100644 --- a/Keychain/SecRuntime.cpp +++ b/Keychain/SecRuntime.cpp @@ -52,7 +52,7 @@ SecCFObject::required(CFTypeRef cfTypeRef, OSStatus error) void * SecCFObject::allocate(size_t size, CFTypeID typeID) throw(std::bad_alloc) { - void *p = const_cast(_CFRuntimeCreateInstance(NULL, typeID, + void *p = const_cast(_CFRuntimeCreateInstance(gTypes().allocator, typeID, size + kAlignedRuntimeSize - sizeof(CFRuntimeBase), NULL)); if (p == NULL) throw std::bad_alloc(); diff --git a/Keychain/iToolsTrustedApps.plist b/Keychain/iToolsTrustedApps.plist index d3c5c8e3..57d04d6f 100644 --- a/Keychain/iToolsTrustedApps.plist +++ b/Keychain/iToolsTrustedApps.plist @@ -3,10 +3,16 @@ /Applications/Mail.app + /Applications/System Preferences.app + /Applications/iCal.app /Applications/iChat.app + /Applications/iMovie.app + /Applications/iPhoto.app /Applications/iSync.app - /Applications/System Preferences.app - /System/Library/PrivateFrameworks/InstantMessage.framework/iChatAgent.app + /Applications/iTunes.app + /System/Library/CoreServices/Finder.app + /System/Library/CoreServices/MirrorAgent.app /System/Library/CoreServices/SyncServer.app + /System/Library/PrivateFrameworks/InstantMessage.framework/iChatAgent.app diff --git a/SecureTransport/sslTransport.cpp b/SecureTransport/sslTransport.cpp index 91cf61d5..1b352e43 100644 --- a/SecureTransport/sslTransport.cpp +++ b/SecureTransport/sslTransport.cpp @@ -49,7 +49,7 @@ static void inline sslIoTrace( UInt32 moved, OSStatus stat) { - sslLogRecordIo("===%s: req %4lu moved %4lu status %ld\n", + sslLogRecordIo("===%s: req %4lu moved %4lu status %ld", op, req, moved, stat); } #else @@ -72,6 +72,7 @@ SSLWrite( SSLRecord rec; UInt32 dataLen, processed; + sslLogRecordIo("SSLWrite top"); if((ctx == NULL) || (bytesWritten == NULL)) { return paramErr; } @@ -159,12 +160,14 @@ SSLRead ( UInt32 bufSize, remaining, count; SSLRecord rec; + sslLogRecordIo("SSLRead top"); if((ctx == NULL) || (processed == NULL)) { return paramErr; } bufSize = dataLength; *processed = 0; /* Initialize in case we return with errSSLWouldBlock */ +readRetry: /* first handle cases in which we know we're finished */ switch(ctx->state) { case SSL_HdskStateGracefulClose: @@ -276,6 +279,11 @@ SSLRead ( err = noErr; exit: + /* test for renegotiate: loop until something happens */ + if((err == noErr) && (*processed == 0)) { + sslLogNegotiateDebug("SSLRead recursion"); + goto readRetry; + } /* shut down on serious errors */ switch(err) { case noErr: @@ -496,6 +504,7 @@ SSLClose(SSLContext *ctx) { OSStatus err = noErr; + sslHdskStateDebug("SSLClose"); if(ctx == NULL) { return paramErr; } diff --git a/Security.pbproj/.cvsignore b/Security.pbproj/.cvsignore deleted file mode 100644 index ae0520be..00000000 --- a/Security.pbproj/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -michael.pbxuser -perry.pbxuser diff --git a/Security.pbproj/project.pbxproj b/Security.pbproj/project.pbxproj index 3f4a0055..fb48422d 100644 --- a/Security.pbproj/project.pbxproj +++ b/Security.pbproj/project.pbxproj @@ -123,7 +123,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/BSafe.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/BSafe.framework/Headers\" \"$(SRCROOT)/AppleCSP\" \"$(SRCROOT)/AppleCSP/open_ssl\""; LIBRARY_STYLE = STATIC; @@ -419,7 +419,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = "-DVDADER_RULES"; @@ -497,7 +497,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -557,7 +557,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -650,7 +650,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -2698,6 +2698,7 @@ }; 01FA8039FFF2B54C11CD283A = { children = ( + B6F3F06205E5C8DD003E48D8, 014259A8001645E911CD296C, 01FA804DFFF2B54C11CD283A, 01FA804EFFF2B54C11CD283A, @@ -6428,13 +6429,13 @@ 01FA8900FFF2BC5611CD283A, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/derived_src\""; INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)"; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = "-DDatabase=XDatabase"; - OTHER_LDFLAGS = "-twolevel_namespace -lSecurityAgentClient"; + OTHER_LDFLAGS = "-twolevel_namespace -lSecurityAgentClient -lbsm"; OTHER_REZFLAGS = ""; PRODUCT_NAME = SecurityServer; REZ_EXECUTABLE = YES; @@ -6481,6 +6482,7 @@ 40ACEF4D0462F6EC0035B857, 40ACEF510462F6FF0035B857, C2C11915047187E800CA2E77, + B6F3F06605E5C926003E48D8, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -6513,6 +6515,7 @@ 40ACEF4C0462F6EC0035B857, 40ACEF500462F6FF0035B857, C2C11914047187E800CA2E77, + B6F3F06505E5C926003E48D8, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -6554,7 +6557,7 @@ 01FA890AFFF2BCA811CD283A, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)"; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -6927,7 +6930,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -8856,9 +8859,9 @@ F5DDE3AE00B3358F01CD283A, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; FRAMEWORK_VERSION = A; HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(BUILT_PRODUCTS_DIR)/derived_src\""; @@ -8906,11 +8909,11 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -9983,7 +9986,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/include\""; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; @@ -11842,7 +11845,7 @@ 325EAA2800D6B08805CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -11882,11 +11885,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12420,7 +12423,7 @@ 3290382100D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -12461,11 +12464,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12529,7 +12532,7 @@ 3290382700D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -12570,11 +12573,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12626,7 +12629,7 @@ 3290382D00D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -12667,11 +12670,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12723,7 +12726,7 @@ 3290383300D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_LDFLAGS = "-bundle -undefined error"; @@ -12762,11 +12765,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -14967,7 +14970,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; OTHER_CFLAGS = ""; @@ -16199,6 +16202,49 @@ //9D2 //9D3 //9D4 +//B60 +//B61 +//B62 +//B63 +//B64 + B6F3F06205E5C8DD003E48D8 = { + children = ( + B6F3F06305E5C926003E48D8, + B6F3F06405E5C926003E48D8, + ); + isa = PBXGroup; + name = "Common Criteria"; + refType = 4; + }; + B6F3F06305E5C926003E48D8 = { + fileEncoding = 30; + isa = PBXFileReference; + path = ccaudit.cpp; + refType = 4; + }; + B6F3F06405E5C926003E48D8 = { + fileEncoding = 30; + isa = PBXFileReference; + path = ccaudit.h; + refType = 4; + }; + B6F3F06505E5C926003E48D8 = { + fileRef = B6F3F06305E5C926003E48D8; + isa = PBXBuildFile; + settings = { + }; + }; + B6F3F06605E5C926003E48D8 = { + fileRef = B6F3F06405E5C926003E48D8; + isa = PBXBuildFile; + settings = { + }; + }; +//B60 +//B61 +//B62 +//B63 +//B64 //BD0 //BD1 //BD2 diff --git a/SecurityServer/Authorization/AuthorizationEngine.cpp b/SecurityServer/Authorization/AuthorizationEngine.cpp index 1412ac8b..210a4423 100644 --- a/SecurityServer/Authorization/AuthorizationEngine.cpp +++ b/SecurityServer/Authorization/AuthorizationEngine.cpp @@ -49,7 +49,6 @@ namespace Authorization { - // // Errors to be thrown // diff --git a/SecurityServer/Authorization/AuthorizationEngine.h b/SecurityServer/Authorization/AuthorizationEngine.h index dc81591c..f4ce6a06 100644 --- a/SecurityServer/Authorization/AuthorizationEngine.h +++ b/SecurityServer/Authorization/AuthorizationEngine.h @@ -40,7 +40,6 @@ #include #include - class AuthorizationToken; using Authorization::AuthorizationDBPlist; diff --git a/SecurityServer/Authorization/AuthorizationRule.cpp b/SecurityServer/Authorization/AuthorizationRule.cpp index 6592038a..a8d4b8f8 100644 --- a/SecurityServer/Authorization/AuthorizationRule.cpp +++ b/SecurityServer/Authorization/AuthorizationRule.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include +#include "ccaudit.h" // // Rule class @@ -42,6 +45,7 @@ CFStringRef RuleImpl::kRuleUserID = CFSTR(kAuthorizationRuleClassUser); CFStringRef RuleImpl::kRuleDelegateID = CFSTR(kAuthorizationRightRule); CFStringRef RuleImpl::kRuleMechanismsID = CFSTR(kAuthorizationRuleClassMechanisms); + string RuleImpl::Attribute::getString(CFDictionaryRef config, CFStringRef key, bool required = false, char *defaultValue = NULL) { @@ -434,6 +438,8 @@ RuleImpl::evaluateMechanism(const AuthItemRef &inRight, const AuthItemSet &envir AuthItemSet context = auth.infoSet(); AuthItemSet hints = environment; + CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken()); + AuthorizationResult result = kAuthorizationResultAllow; vector::const_iterator currentMechanism = mEvalDef.begin(); @@ -489,11 +495,18 @@ RuleImpl::evaluateMechanism(const AuthItemRef &inRight, const AuthItemSet &envir Credential newCredential(username, password, true); // create a new shared credential if (newCredential->isValid()) + { Syslog::info("authinternal authenticated user %s (uid %lu) for right %s.", newCredential->username().c_str(), newCredential->uid(), inRight->name()); + auditrec.submit(AUE_ssauthint, CommonCriteria::errNone, inRight->name()); + } else + { // we can't be sure that the user actually exists so inhibit logging of uid Syslog::error("authinternal failed to authenticate user %s for right %s.", newCredential->username().c_str(), inRight->name()); - + + auditrec.submit(AUE_ssauthint, CommonCriteria::errInvalidCredential, inRight->name()); + } + if (newCredential->isValid()) { outCredentials.clear(); // only keep last one @@ -614,17 +627,26 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, // fetch context and construct a credential to be tested AuthItemSet inContext = auth.infoSet(); CredentialSet newCredentials = makeCredentials(inContext); + // clear context after extracting credentials + auth.clearInfoSet(); for (CredentialSet::const_iterator it = newCredentials.begin(); it != newCredentials.end(); ++it) { const Credential& newCredential = *it; + CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken()); // @@@ we log the uid a process was running under when it created the authref, which is misleading in the case of loginwindow if (newCredential->isValid()) + { Syslog::info("uid %lu succeeded authenticating as user %s (uid %lu) for right %s.", auth.creatorUid(), newCredential->username().c_str(), newCredential->uid(), inRight->name()); + auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, inRight->name()); + } else + { // we can't be sure that the user actually exists so inhibit logging of uid Syslog::error("uid %lu failed to authenticate as user %s for right %s.", auth.creatorUid(), newCredential->username().c_str(), inRight->name()); + auditrec.submit(AUE_ssauthorize, CommonCriteria::errInvalidCredential, inRight->name()); + } if (!newCredential->isValid()) { @@ -639,12 +661,18 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, { // whack an equivalent credential, so it gets updated to a later achieved credential which must have been more stringent credentials.erase(newCredential); credentials.insert(newCredential); + // use valid credential to set context info + auth.setCredentialInfo(newCredential); secdebug("SSevalMech", "added valid credential for user %s", newCredential->username().c_str()); status = errAuthorizationSuccess; break; } else + { reason = SecurityAgent::userNotInGroup; //unacceptableUser; // userNotInGroup + // don't audit: we denied on the basis of something + // other than a bad user or password + } } if (status == errAuthorizationSuccess) @@ -653,7 +681,10 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, else if ((status == errAuthorizationCanceled) || (status == errAuthorizationInternal)) - break; + { + auth.clearInfoSet(); + break; + } } // If we fell out of the loop because of too many tries, notify user @@ -665,6 +696,7 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries)); environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace evaluateMechanism(inRight, environmentToClient, auth, credentials); + auth.clearInfoSet(); } Process &cltProc = Server::active().connection().process; @@ -1089,6 +1121,9 @@ RuleImpl::evaluateAuthorizationOld(const AuthItemRef &inRight, const Rule &inRul Credential newCredential; // @@@ Keep the default reason the same, so the agent only gets userNotInGroup or invalidPassphrase SecurityAgent::Reason reason = SecurityAgent::userNotInGroup; + + CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken()); + // @@@ Hardcoded 3 tries to avoid infinite loops. for (uint32_t tryCount = 0; tryCount < mTries; ++tryCount) { @@ -1099,7 +1134,10 @@ RuleImpl::evaluateAuthorizationOld(const AuthItemRef &inRight, const Rule &inRul // Now we have successfully obtained a credential we need to make sure it authorizes the requested right if (!newCredential->isValid()) + { reason = SecurityAgent::invalidPassphrase; + auditrec.submit(AUE_ssauthorize, CommonCriteria::errInvalidCredential, inRight->name()); + } else { status = evaluateCredentialForRight(inRight, inRule, environmentToClient, now, newCredential, true); if (status == errAuthorizationSuccess) @@ -1112,14 +1150,23 @@ RuleImpl::evaluateAuthorizationOld(const AuthItemRef &inRight, const Rule &inRul // add credential to authinfo auth.setCredentialInfo(newCredential); + auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, inRight->name()); return errAuthorizationSuccess; } else if (status != errAuthorizationDenied) + { + if (status == errAuthorizationCanceled) + auditrec.submit(AUE_ssauthorize, CommonCriteria::errUserCanceled, inRight->name()); + // else don't audit--error not due to bad + // username or password return status; + } } reason = SecurityAgent::userNotInGroup; } query.cancel(SecurityAgent::tooManyTries); + + auditrec.submit(AUE_ssauthorize, CommonCriteria::errTooManyTries, inRight->name()); return errAuthorizationDenied; } diff --git a/SecurityServer/Authorization/AuthorizationRule.h b/SecurityServer/Authorization/AuthorizationRule.h index 91aefcf1..a567f099 100644 --- a/SecurityServer/Authorization/AuthorizationRule.h +++ b/SecurityServer/Authorization/AuthorizationRule.h @@ -74,7 +74,6 @@ private: map localizedPrompts() const { return mLocalizedPrompts; } - // parsed attributes private: enum Type diff --git a/SecurityServer/Authorization/authorization.plist b/SecurityServer/Authorization/authorization.plist index c7f9188c..5e22b0ba 100644 --- a/SecurityServer/Authorization/authorization.plist +++ b/SecurityServer/Authorization/authorization.plist @@ -366,6 +366,23 @@ If the proccess that created the AuthorizationRef has uid = 0 this right will au rule appserver-admin + com.apple.desktopservices + + class + user + comment + authorize privileged file operations from the finder + group + admin + mechanisms + + builtin:authenticate + + shared + + timeout + 0 + com.apple.appserver.privilege.user class diff --git a/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore b/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore deleted file mode 100644 index 0857ac37..00000000 --- a/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pbxuser diff --git a/SecurityServer/authority.cpp b/SecurityServer/authority.cpp index 60cefe45..533dff60 100644 --- a/SecurityServer/authority.cpp +++ b/SecurityServer/authority.cpp @@ -55,11 +55,13 @@ Authority::~Authority() // // Create an authorization token. // -AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, const security_token_t &securityToken) +AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken) : session(ssn), mBaseCreds(base), mTransferCount(INT_MAX), - mCreatorUid(securityToken.val[0]), + mCreatorUid(auditToken.val[1]), + mCreatorGid(auditToken.val[2]), mCreatorCode(Server::connection().process.clientCode()), - mCreatorPid(Server::connection().process.pid()) + mCreatorPid(Server::connection().process.pid()), + mCreatorAuditToken(auditToken) { // generate our (random) handle Server::active().random(mHandle); @@ -257,3 +259,11 @@ AuthorizationToken::setCredentialInfo(const Credential &inCred) setInfoSet(dstInfoSet); } +void +AuthorizationToken::clearInfoSet() +{ + AuthItemSet dstInfoSet; + secdebug("SSauth", "Authorization %p clearing context", this); + setInfoSet(dstInfoSet); +} + diff --git a/SecurityServer/authority.h b/SecurityServer/authority.h index 6882a47d..80a940e0 100644 --- a/SecurityServer/authority.h +++ b/SecurityServer/authority.h @@ -35,7 +35,7 @@ class Session; class AuthorizationToken { public: - AuthorizationToken(Session &ssn, const CredentialSet &base, const security_token_t &securityToken); + AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken); ~AuthorizationToken(); Session &session; @@ -60,12 +60,16 @@ public: bool mayInternalize(Process &proc, bool countIt = true); uid_t creatorUid() const { return mCreatorUid; } + uid_t creatorGid() const { return mCreatorGid; } CodeSigning::OSXCode *creatorCode() const { return mCreatorCode; } pid_t creatorPid() const { return mCreatorPid; } + audit_token_t creatorAuditToken() const {return mCreatorAuditToken; } + AuthItemSet infoSet(AuthorizationString tag = NULL); void setInfoSet(AuthItemSet &newInfoSet); void setCredentialInfo(const Credential &inCred); + void clearInfoSet(); public: static AuthorizationToken &find(const AuthorizationBlob &blob); @@ -93,9 +97,12 @@ private: ProcessSet mUsingProcesses; // set of process objects using this token uid_t mCreatorUid; // Uid of proccess that created this authorization + gid_t mCreatorGid; // Gid of proccess that created this authorization RefPointer mCreatorCode; // code id of creator pid_t mCreatorPid; // Pid of processs that created this authorization + audit_token_t mCreatorAuditToken; // Audit token of the process that created this authorization + AuthItemSet mInfoSet; // Side band info gathered from evaluations in this session private: diff --git a/SecurityServer/server.cpp b/SecurityServer/server.cpp index 35914b5f..a26998bb 100644 --- a/SecurityServer/server.cpp +++ b/SecurityServer/server.cpp @@ -25,10 +25,15 @@ #include "notifications.h" #include "ucsp.h" #include +#include +#include +#include +#include +#include +#include "ccaudit.h" using namespace MachPlusPlus; - // // Construct the server object // @@ -40,6 +45,9 @@ Server::Server(Authority &authority, CodeSignatures &signatures, const char *boo mAuthority(authority), mCodeSignatures(signatures) { + + initAudit(); + // engage the subsidiary port handler for sleep notifications add(sleepWatcher); } @@ -112,7 +120,7 @@ void Server::run() { MachServer::run(0x10000, MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) | - MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER)); + MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT)); } @@ -157,8 +165,11 @@ boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out) // Everything at and below that level is constructed. This is straight-forward except // in the case of session re-initialization (see below). // +// audit_token_t.val[1] is the EUID, audit_token_t.val[2] is the EGID. +// void Server::setupConnection(ConnectLevel type, Port servicePort, Port replyPort, Port taskPort, - const security_token_t &securityToken, const ClientSetupInfo *info, const char *identity) + const audit_token_t &auditToken, + const ClientSetupInfo *info, const char *identity) { // first, make or find the process based on task port StLock _(lock); @@ -180,7 +191,7 @@ void Server::setupConnection(ConnectLevel type, Port servicePort, Port replyPort CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); assert(info && identity); proc = new Process(servicePort, taskPort, info, identity, - securityToken.val[0], securityToken.val[1]); + auditToken.val[1], auditToken.val[2]); notifyIfDead(taskPort); } @@ -265,6 +276,17 @@ void Server::SleepWatcher::systemWillSleep() Session::lockAllDatabases(true); } +void Server::initAudit(void) +{ + secdebug("SS", "initializing Common Criteria auditing"); + mAudit.auditId(geteuid()); + // Set the class mask so only the audit records we submit are written. + mAudit.eventMask().set(AUE_NULL, AUE_NULL); + mAudit.terminalId().set(); + // XXX If we use SS session IDs instead, get the RootSession ID + mAudit.sessionId(getpid()); + mAudit.registerSession(); +} // // Return the primary Cryptographic Service Provider. diff --git a/SecurityServer/server.h b/SecurityServer/server.h index 3da8b93c..38ff0628 100644 --- a/SecurityServer/server.h +++ b/SecurityServer/server.h @@ -36,6 +36,7 @@ #include "xdatabase.h" #include "authority.h" #include +#include "ccaudit.h" #define EQUIVALENCEDBPATH "/var/db/CodeEquivalenceDatabase" @@ -81,8 +82,8 @@ public: connectNewThread }; void setupConnection(ConnectLevel type, Port servicePort, Port replyPort, Port taskPort, - const security_token_t &securityToken, - const ClientSetupInfo *info = NULL, const char *executablePath = NULL); + const audit_token_t &auditToken, + const ClientSetupInfo *info = NULL, const char *executablePath = NULL); void endConnection(Port replyPort); @@ -103,7 +104,9 @@ private: void systemWillSleep(); }; SleepWatcher sleepWatcher; - + + void initAudit(void); + private: Mutex lock; // master lock @@ -131,6 +134,9 @@ private: Authority &mAuthority; CodeSignatures &mCodeSignatures; + + // Per-process audit initialization. + CommonCriteria::AuditSession mAudit; }; #endif //_H_SERVER diff --git a/SecurityServer/session.cpp b/SecurityServer/session.cpp index 090275ed..5c16649c 100644 --- a/SecurityServer/session.cpp +++ b/SecurityServer/session.cpp @@ -238,13 +238,13 @@ OSStatus Session::authCreate(const AuthItemSet &rights, const AuthItemSet &environment, AuthorizationFlags flags, AuthorizationBlob &newHandle, - const security_token_t &securityToken) + const audit_token_t &auditToken) { // invoke the authorization computation engine CredentialSet resultCreds; // this will acquire mLock, so we delay acquiring it - auto_ptr auth(new AuthorizationToken(*this, resultCreds, securityToken)); + auto_ptr auth(new AuthorizationToken(*this, resultCreds, auditToken)); // Make a copy of the mSessionCreds CredentialSet sessionCreds; diff --git a/SecurityServer/session.h b/SecurityServer/session.h index 3ceb2abb..35c89fca 100644 --- a/SecurityServer/session.h +++ b/SecurityServer/session.h @@ -87,7 +87,7 @@ public: const CredentialSet &authCredentials() const { return mSessionCreds; } OSStatus authCreate(const AuthItemSet &rights, const AuthItemSet &environment, - AuthorizationFlags flags, AuthorizationBlob &newHandle, const security_token_t &securityToken); + AuthorizationFlags flags, AuthorizationBlob &newHandle, const audit_token_t &auditToken); void authFree(const AuthorizationBlob &auth, AuthorizationFlags flags); OSStatus authGetRights(const AuthorizationBlob &auth, const AuthItemSet &requestedRights, const AuthItemSet &environment, diff --git a/SecurityServer/transition.cpp b/SecurityServer/transition.cpp index 86da930d..7f7073cd 100644 --- a/SecurityServer/transition.cpp +++ b/SecurityServer/transition.cpp @@ -32,7 +32,7 @@ // // Bracket Macros // -#define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, security_token_t securityToken, \ +#define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, audit_token_t auditToken, \ CSSM_RETURN *rcode #define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrSize @@ -87,7 +87,7 @@ kern_return_t ucsp_server_setup(UCSP_ARGS, mach_port_t taskPort, ClientSetupInfo { BEGIN_IPCN Server::active().setupConnection(Server::connectNewProcess, servicePort, replyPort, - taskPort, securityToken, &info, identity); + taskPort, auditToken, &info, identity); END_IPCN(CSSM) return KERN_SUCCESS; } @@ -100,7 +100,7 @@ kern_return_t ucsp_server_setupNew(UCSP_ARGS, mach_port_t taskPort, try { Session *session = new DynamicSession(TaskPort(taskPort).bootstrap()); Server::active().setupConnection(Server::connectNewSession, session->servicePort(), replyPort, - taskPort, securityToken, &info, identity); + taskPort, auditToken, &info, identity); *newServicePort = session->servicePort(); } catch (const MachPlusPlus::Error &err) { switch (err.error) { @@ -118,7 +118,7 @@ kern_return_t ucsp_server_setupThread(UCSP_ARGS, mach_port_t taskPort) { BEGIN_IPCN Server::active().setupConnection(Server::connectNewThread, servicePort, replyPort, - taskPort, securityToken); + taskPort, auditToken); END_IPCN(CSSM) return KERN_SUCCESS; } @@ -644,7 +644,7 @@ kern_return_t ucsp_server_authorizationCreate(UCSP_ARGS, Authorization::AuthItemSet rights(inRights), environment(inEnvironment); *rcode = connection.process.session.authCreate(rights, environment, - flags, *authorization, securityToken); + flags, *authorization, auditToken); END_IPC(CSSM) } diff --git a/SecurityServer/ucsp.defs b/SecurityServer/ucsp.defs index 9c8370ac..52c92806 100644 --- a/SecurityServer/ucsp.defs +++ b/SecurityServer/ucsp.defs @@ -108,7 +108,7 @@ type ExecutablePath = c_string[*:2048]; // #define UCSP_PORTS requestport sport: mach_port_t; \ replyport rport: mach_port_make_send_t; \ - serversectoken sourceSecurity: security_token_t; \ + serveraudittoken sourceAudit: audit_token_t; \ out rcode: CSSM_RETURN #define IN_CONTEXT in context: Context; in contextBase: BasePointer; in attrs: ContextAttributes #define IN_BLOB(name,type) in name: type##Blob; in name##Base: type##Ptr diff --git a/cdsa/cdsa_pluginlib/.cvsignore b/cdsa/cdsa_pluginlib/.cvsignore deleted file mode 100644 index d2615714..00000000 --- a/cdsa/cdsa_pluginlib/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -cdsa_pluginlib?Data diff --git a/cdsa/cdsa_utilities/.cvsignore b/cdsa/cdsa_utilities/.cvsignore deleted file mode 100644 index 2a8f2f8b..00000000 --- a/cdsa/cdsa_utilities/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -cdsa_utilities?Data diff --git a/cdsa/cdsa_utilities/ccaudit.cpp b/cdsa/cdsa_utilities/ccaudit.cpp new file mode 100644 index 00000000..24caac9a --- /dev/null +++ b/cdsa/cdsa_utilities/ccaudit.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + + +#include // bcopy() +#include // gethostname() +#include // gethostbyname() +#include // inet_addr() +#include // inet_addr() +#include // inet_addr() +#include // inet_addr() +#include +#include "utilities.h" +#include +#include +#include "ccaudit.h" + +namespace Security +{ +namespace CommonCriteria +{ + +void TerminalId::set(void) +{ + if (audit_set_terminal_id(&mTid) != kAUNoErr) + { + // If we start seeing the syslog too often, change to secdebug() + Syslog::warning("setting terminal ID info failed; using defaults"); + mTid.port = 0; + mTid.machine = 0; + } +} + +void AuditSession::registerSession(void) +{ + auditinfo_t auinfo; + + auinfo.ai_auid = mAuditId; + auinfo.ai_asid = mSessionId; + bcopy(&mTerminalId.get(), &(auinfo.ai_termid), sizeof(auinfo.ai_termid)); + bcopy(&mEventMask.get(), &(auinfo.ai_mask), sizeof(auinfo.ai_mask)); + + if (setaudit(&auinfo) != 0) + { + if (errno == ENOTSUP) + { + Syslog::notice("Attempted to initialize auditing, but this kernel that does not support auditing"); + return; + } + Syslog::notice("Could not initialize auditing; continuing"); + } +} + +void AuditRecord::submit(const short event_code, const int returnCode, + const char *msg) +{ + // If we're not auditing, do nothing + if (au_get_state() == AUC_NOAUDIT) + return; + + // XXX make this a secdebug, then enable it + // Syslog::notice("Submitting authorization audit record"); + + int ret = kAUNoErr; + + // XXX/gh 3574731: Fix BSM SPI so the const_cast<>s aren't necessary + if (returnCode == 0) + { + token_t *tok = NULL; + + if (msg) + tok = au_to_text(const_cast(msg)); + ret = audit_write_success(event_code, const_cast(tok), + mAuditId, mEUid, mEGid, mRUid, mRGid, + mPid, mSessionId, + const_cast(&(mTerminalId.get()))); + } + else + { + ret = audit_write_failure(event_code, const_cast(msg), + returnCode, mAuditId, mEUid, mEGid, + mRUid, mRGid, mPid, mSessionId, + const_cast(&(mTerminalId.get()))); + } + if (ret != kAUNoErr) + MacOSError::throwMe(ret); +} + + +} // end namespace CommonCriteria +} // end namespace Security diff --git a/cdsa/cdsa_utilities/ccaudit.h b/cdsa/cdsa_utilities/ccaudit.h new file mode 100644 index 00000000..0fc9b2d9 --- /dev/null +++ b/cdsa/cdsa_utilities/ccaudit.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + + +#ifndef _H_CCAUDIT +#define _H_CCAUDIT + +#include +#include + +namespace Security +{ + +namespace CommonCriteria +{ + +// for Tiger, this should be incorporated into Security's OSStatus range +enum ExternalErrors +{ + errNone = 0, + errInvalidCredential = 1111, // try to make easier to find in log + errUserCanceled, + errTooManyTries, + errEndOfExternalErrors // sentry/placeholder +}; + +class AuditMask +{ + public: + AuditMask() { } + AuditMask(const AuditMask &am) { set(am.get()); } + AuditMask(const au_mask_t &am) { set(am); } + ~AuditMask() { } + + void set(const au_mask_t &am) { set(am.am_success, am.am_failure); } + void set(unsigned int s, unsigned int f) { mMask.am_success = s; mMask.am_failure = f; } + const au_mask_t &get(void) const { return mMask; } + + private: + au_mask_t mMask; +}; + +// For the most part, we won't have a machine ID to initialize the +// au_tid_t's machine field. There's no machine ID in the audit token, +// for example, since MIG is localhost-only. +class TerminalId +{ + public: + TerminalId() { } + TerminalId(const TerminalId &t) { set(t.get()); } + TerminalId(const au_tid_t &tid) { set(tid); } + TerminalId(dev_t p, u_int32_t m) { port(p); machine(m); } + ~TerminalId() { } + + void set(void); // set using localhost + void set(const au_tid_t &tid) { port(tid.port); machine(tid.machine); } + void port(dev_t p) { mTid.port = p; } + void machine(u_int32_t m) { mTid.machine = m; } + const au_tid_t &get(void) const { return mTid; } + + private: + au_tid_t mTid; +}; + +// audit session state for the current process; only used by Server +class AuditSession +{ + public: + AuditSession() { } + AuditSession(au_id_t auid, AuditMask &mask, au_asid_t sid, + TerminalId &tid) + : mAuditId(auid), mEventMask(mask), mTerminalId(tid), + mSessionId(sid) { } + ~AuditSession() { } + + // set audit info for this process in kernel + void registerSession(void); + + void auditId(au_id_t auid) { mAuditId = auid; } + void eventMask(AuditMask &mask) { mEventMask = mask; } + void terminalId(TerminalId &tid) { mTerminalId = tid; } + void sessionId(au_asid_t sid) { mSessionId = sid; } + + au_id_t auditId(void) { return mAuditId; } + AuditMask &eventMask(void) { return mEventMask; } + TerminalId &terminalId(void) { return mTerminalId; } + au_asid_t sessionId(void) { return mSessionId; } + + private: + au_id_t mAuditId; + AuditMask mEventMask; + TerminalId mTerminalId; + au_asid_t mSessionId; +}; + +// +// For submitting audit records. Not general-purpose: no ability to +// submit arbitrary BSM tokens, for example. However, the SecurityServer +// has only limited auditing requirements under Common Criteria. +// +class AuditRecord +{ + public: + AuditRecord(const audit_token_t &auditToken) + : mAuditId(auditToken.val[0]), + mRUid(auditToken.val[3]), + mRGid(auditToken.val[4]), + mEUid(auditToken.val[1]), + mEGid(auditToken.val[2]), + mPid(auditToken.val[5]), + mSessionId(auditToken.val[6]), + mTerminalId(auditToken.val[7], 0) { } + ~AuditRecord() { } + + // returnCode == 0 --> success; nonzero returnCode --> failure + void submit(const short event_code, const int returnCode, + const char *msg = NULL); + + private: + au_id_t mAuditId; + uid_t mRUid; + gid_t mRGid; + uid_t mEUid; + gid_t mEGid; + pid_t mPid; + au_asid_t mSessionId; + TerminalId mTerminalId; +}; + +} // end namespace CommonCriteria + +} // end namespace Security + +#endif // _H_CCAUDIT diff --git a/cdsa/cdsa_utilities/utilities.h b/cdsa/cdsa_utilities/utilities.h index 0d148163..bb451cc4 100644 --- a/cdsa/cdsa_utilities/utilities.h +++ b/cdsa/cdsa_utilities/utilities.h @@ -751,7 +751,6 @@ private: const _Tp *_M_finish; }; - } // end namespace Security diff --git a/cdsa/cssm/.cvsignore b/cdsa/cssm/.cvsignore deleted file mode 100644 index 02a2add0..00000000 --- a/cdsa/cssm/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -cdsa?Data diff --git a/cdsa/mds/.cvsignore b/cdsa/mds/.cvsignore deleted file mode 100644 index 9c0531bf..00000000 --- a/cdsa/mds/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -PBUserInfo -mds?Data diff --git a/checkpw/checkpw.c b/checkpw/checkpw.c index 23c21352..f300addf 100644 --- a/checkpw/checkpw.c +++ b/checkpw/checkpw.c @@ -65,6 +65,7 @@ typedef struct sComData unsigned long fPID; unsigned long fPort; unsigned long fIPAddress; + mach_msg_audit_trailer_t fTail; sObject obj[ 10 ]; char data[ 1 ]; } sComData; @@ -86,7 +87,8 @@ typedef struct sIPCMsg unsigned long fPort; sObject obj[ 10 ]; char fData[ kIPCMsgLen ]; - mach_msg_security_trailer_t fTail; + mach_msg_audit_trailer_t fTail; // this is the largest trailer struct + // we have the bucket large enough to receive it } sIPCMsg; typedef enum { @@ -216,7 +218,7 @@ int checkpw_internal( const struct passwd* pw, const char* password ) msg->obj[0].length = curr; msg->fHeader.msgh_bits = MACH_MSGH_BITS( MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND ); - msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_security_trailer_t ); + msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_audit_trailer_t ); msg->fHeader.msgh_id = kCheckUserNameAndPassword; msg->fHeader.msgh_remote_port = serverPort; msg->fHeader.msgh_local_port = replyPort; @@ -238,7 +240,9 @@ int checkpw_internal( const struct passwd* pw, const char* password ) // get reply memset( msg, 0, kIPCMsgLen ); - result = mach_msg( (mach_msg_header_t *)msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, + result = mach_msg( (mach_msg_header_t *)msg, + MACH_RCV_MSG | MACH_RCV_TIMEOUT | + MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0), 0, kIPCMsgSize, replyPort, 300 * 1000, MACH_PORT_NULL ); if ( result != MACH_MSG_SUCCESS ) { diff --git a/keychains/Makefile b/keychains/Makefile index 87d49399..cf7cda47 100644 --- a/keychains/Makefile +++ b/keychains/Makefile @@ -5,7 +5,8 @@ KEYCHAINS_SRC=$(SRCROOT)/keychains SYSTEM_LIBRARY_DIR=$(DSTROOT)/System/Library KEYCHAINS_DIR=$(SYSTEM_LIBRARY_DIR)/Keychains -X509KEYCHAINS=X509Anchors X509Certificates +ANCHORS_DIR=$(KEYCHAINS_DIR)/Anchors +CERTIFICATES_DIR=$(KEYCHAINS_DIR)/Certificates # # world-writable directory we need to create for CRL cache @@ -38,18 +39,21 @@ clean: # Install # install: - if [ ! -d $(KEYCHAINS_DIR) ]; then \ - mkdir -p $(KEYCHAINS_DIR); \ - chown root.admin $(KEYCHAINS_DIR); \ - chmod 755 $(KEYCHAINS_DIR); \ - fi - cd $(KEYCHAINS_SRC); cp $(X509KEYCHAINS) $(KEYCHAINS_DIR) - cd $(KEYCHAINS_DIR); \ - chown root.admin $(X509KEYCHAINS); \ - chmod 664 $(X509KEYCHAINS); \ - ls -l $(X509KEYCHAINS) + for d in "$(KEYCHAINS_DIR)" "$(ANCHORS_DIR)" "$(CERTIFICATES_DIR)"; do \ + if [ ! -d "$${d}" ]; then \ + mkdir -p "$${d}"; \ + chown root:admin "$${d}"; \ + chmod 755 "$${d}"; \ + fi; \ + done; \ + find "$(KEYCHAINS_SRC)/roots" -maxdepth 1 -a -type f -exec cp {} "$(ANCHORS_DIR)" \; ; \ + find "$(KEYCHAINS_SRC)/certs" -maxdepth 1 -a -type f -exec cp {} "$(CERTIFICATES_DIR)" \; ; \ + chown root:admin "$(ANCHORS_DIR)/"*; \ + chmod 664 "$(ANCHORS_DIR)/"*; \ + chown root:admin "$(CERTIFICATES_DIR)/"*; \ + chmod 664 "$(CERTIFICATES_DIR)/"*; \ if [ ! -d $(CRL_CACHE_DIR) ]; then \ mkdir -p $(CRL_CACHE_DIR); \ - chown root.wheel $(CRL_CACHE_DIR); \ + chown root:wheel $(CRL_CACHE_DIR); \ chmod 777 $(CRL_CACHE_DIR); \ fi diff --git a/keychains/X509Anchors b/keychains/X509Anchors deleted file mode 100644 index 167c13187611a50e92a8e13c6a002fcc8e280c64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178112 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 diff --git a/keychains/X509Certificates b/keychains/X509Certificates deleted file mode 100644 index 1f2c700f0ff5a80b76d0c930dddcef547c4cbe1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79704 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 D=j8Dm diff --git a/keychains/certscript b/keychains/certscript deleted file mode 100755 index 3a9d6cc8..00000000 --- a/keychains/certscript +++ /dev/null @@ -1,24 +0,0 @@ -#! /bin/csh -f -# -# Build a keychain out of roots or certs. -# -set prog=$0 -if ( $#argv != 2 ) then - echo usage: ${prog:t} dbfile certsdir - echo dbfile must NOT exist. - exit(1) -endif -# -# Our job is to cook up a list of files in certsdir, not including -# the CVS directory. -# -set cwd=`pwd` -set dbfile=$cwd/$argv[1] -set certsdir=$argv[2] -if ( -e $dbfile ) then - echo I insist that you delete $argv[1] manually. - exit(1) -endif -# -set cmd="./makecerts $dbfile $certsdir/[a-zABD-Z0-9]* $certsdir/C[a-zA-UW-Z0-9]*" -$cmd || exit(1) diff --git a/keychains/makecerts b/keychains/makecerts deleted file mode 100755 index 157320d6..00000000 --- a/keychains/makecerts +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/perl -# -# Use to gather certificates into specified keychain. -# -$numFiles = $#ARGV; -if($numFiles < 1) { - print "usage: makecerts keychainfile cert...\n"; - die; -} -$dbname = $ARGV[0]; - -my $count = 0; -my $created; -foreach $argnum (1 .. $numFiles) { - $thisCert = $ARGV[$argnum]; - my @cmd = ("certtool", "i", $thisCert, "k=$dbname", "d"); - do { push @cmd, "c"; $created = 1; } unless $created; - print "$thisCert "; - die if system @cmd; - $count++; -} - -print "$count certificates placed into $dbname\n"; -exit 0; diff --git a/keychains/makeroots b/keychains/makeroots deleted file mode 100755 index 7c134b04..00000000 --- a/keychains/makeroots +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/perl -# -# -# -use strict; - -my $dbname = "X509Anchors"; - -my $count = 0; -my $created; -for my $file (@ARGV) { - my @cmd = ("certtool", "i", $file, "k=$dbname", "d"); - do { push @cmd, "c"; $created = 1; } unless $created; - print "$file "; - die if system @cmd; - $count++; -} - -print "$count certificates placed into $dbname\n"; -exit 0; diff --git a/keychains/postinstall.sh b/keychains/postinstall.sh new file mode 100755 index 00000000..9042a2de --- /dev/null +++ b/keychains/postinstall.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Create keychains if not there already +if [ ! -f "$targetdisk/System/Library/Keychains/X509Anchors" ]; then + "$targetdisk/usr/bin/security" create-keychain -p X509Anchors "$targetdisk/System/Library/Keychains/X509Anchors" +fi +if [ ! -f "$targetdisk/System/Library/Keychains/X509Certificates" ]; then + "$targetdisk/usr/bin/security" create-keychain -p X509Certificates "$targetdisk/System/Library/Keychains/X509Certificates" +fi + +# Add all anchors +cd "$targetdisk/System/Library/Keychains/Anchors/" +"$targetdisk/usr/bin/security" add-certificate -k "$targetdisk/System/Library/Keychains/X509Anchors" * + +# Add all intermediates +cd "$targetdisk/System/Library/Keychains/Certificates/" +"$targetdisk/usr/bin/security" add-certificate -k "$targetdisk/System/Library/Keychains/X509Certificates" * + +# we might want to delete the raw certificate files, in the interest of cruft cleanup +#rm -rf "$targetdisk/System/Library/Keychains/Anchors" +#rm -rf "$targetdisk/System/Library/Keychains/Certificates" diff --git a/keychains/roots/.cvsignore b/keychains/roots/.cvsignore deleted file mode 100644 index e43b0f98..00000000 --- a/keychains/roots/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.DS_Store diff --git a/keychains/roots/AOLTimeWarner1.der b/keychains/roots/AOLTimeWarner1.der new file mode 100644 index 0000000000000000000000000000000000000000..49df4b3fda67b87533dfd8f51a543e173324b727 GIT binary patch literal 1002 zcmXqLVt!`O#B^=}GZP~d6CAW;Q!O?20?yJs-8C%{KU8Ww&TIWWAbL}xu0=}x^6h!oPd&ML zeN{wY`-czR9)6Dw9f`~|NZMwwsE1o{W}<0s-TR{(CD{~&`kWr#=bt7JwBr1n_^Bc{ z)?1fy8!E`V=r2lg+`L;t@%E`go1Qn@cJj`DANbz4TIdru&%-qi{pIx=PE{20#EKOb zEV_Qks`V`2tRoK?He6MGbw~Tj6kUrsosQut8mW>p+g!GsFwE{_tS*aGtrwMP;ixH2 zRp464q9~a%Vk{yH%?!j&w@qMhZ3y1jf8vI1&Axac z19_0NGK++PSOazid>{q%%hlx~e}HpYMcjiLe!uJ;LwguiHB>J-oa#VDmn~*{>|j`_(J+|3_A@$ZI`+*?XnuhWHJZ8X0`WcU5QI69NDfylgrE literal 0 HcmV?d00001 diff --git a/keychains/roots/AmericaOnline1.der b/keychains/roots/AmericaOnline1.der new file mode 100644 index 0000000000000000000000000000000000000000..900dc146b483a95f7a64e2a2c82fc9af4107ac4e GIT binary patch literal 936 zcmXqLVqRj<#MHBZnTe5!iILHOmyJ`a&7D}zC@A-4f18*?ZNn=n&ou%V2B z6o|tmEbN$@T9lcbsNkQMlbM&Q;F*`KXJ}?%0+MAG){YLH83(THL@@;GXR1pab9C{LqkJLBLfp-AeTOlXkt`C_BBO}8K{TE9z*_hoAzto!XUvg2wtYZP2>XzQm@RhFN-!?s?R(DzV z^p`1ZCl|k8(6&Dzb&hvP$03iSUY7es9!G{gmE2NtVhgKfjM&mgQ&}Gft&8klWSkKp zv+RoK_8arB-zi*OH*5dwK4X5Rzw&y|+0EW3SsuN6dY7t*@;#nowl?RQIG&~1-3qi8 zvs%nrzu->$)j5BPRxYTmc(UCvR4#S*mBbB-32z0AijGcFmHRQlOQOR4ew~52U4Zm$ znakO;+Jf0PykEms@uOwtKgC|3hHX4e-_i;yr7rs~KL7E&+XiobySp7pJ9<`fYFJkt zpZ-wp>6iHj4y;pIaAM(2{%h50O_@fv%bA!N85kEQ8zdU=10z{hn33^63#$P$kTQ@3 z3GlIqv4}9Ny}9^X<+r?&mG#E9jpEmR&Kut|kOxUCvq%_-HDFi32U5TfGLQwB4BL>S z0hk7X(ZI-1({)i^!o2Chjtz_7hD|+@lsJcV(b+>uYKdnB#IB#&l4^26uxss#m8@y+ zOFrku&z-scTleqRL7P}-EXvn98nRb)Z~VFwZLi#P4sPCi@TF&ggxGWr;U0wt(t1|z zr{$h77)*`+;=1^N)CNYs)q4*p=Ox=WcpYVbd*@O9@q0vD?6_&$ z=AYBz-EQ-^{{0+qIRDsTkF{>g9;&-@$@0zKcBs5Q`O|}1seOMQ+`oQ&dCrEP>vq}v YE!iUYB7(PJ&*c>jRx{t0o^h)N0Fn7|x&QzG literal 0 HcmV?d00001 diff --git a/keychains/roots/TCTrustCenterClass1CA.der b/keychains/roots/TCTrustCenterClass1CA.der new file mode 100644 index 0000000000000000000000000000000000000000..a45bfe25dbf86093f05d6b82bea9ef16a6bcb936 GIT binary patch literal 864 zcmXqLVvaFrVmi8jnTe5!iHZ580WTY;R+~rLcV0$D7FGs>#yy7I2Apinp)72|OfIg5 z0tS2_4u>$iM`CVLX;C^%gdHJbWnckP!zFAO;;ax-R9al(oSIjXTBMMcU!)M6np|3x zSyHKxnWx~ASdysVms(PuUzA;};GUc0VW?!F0Mg4XEQzMqIVZ8WSiw-i+0jtbKppN# zPDU}Qd%pMa#yOrW;n53M->esw{<|x2 z^^NC+_jMVj#0GlQD!(sHYMEfeB_AnRqTkoB^sfPvt!B{KA}LSBIeShA^?58zo_0c@ z)gUvx#PvW_+p(**4>H1Q4YO2wU8ma_)@7s_<*DSpF)};pc*y>7|(|sX3W>sl^6@2u+M2a~Rl>!vdIgnSp`eKQprRL`qoG(R|w* zZk+lyfd`itL^MtkdiCXs7{j!%7;}wJ;c~BI_iw!H z%3mbIe2L+>PUx+F@ttMekFJz|_2m>_e`MEc18x5uvafFbkNgl&;=#yy7I2Apinp)72|OfIg5 z0tS2_4u>$iM`CVLX;C^%gdHJbWnckP!zFAO;;ax-R9al(oSIjXTBMMcU!)M6np|3x zSyHKxnWx~ASdysVms(PuUzA;};GUc0VW?!F0Mg4XEQzMqIVZ8WSiwla+0jtbKppN# zPDU}QzPjj;*y^va(D6YIjUVe891! zuW5TvO;mcbN;dGi?dHHu&3>_`JvV&t34NNad%Ts~KxUF()0I<9Z@=g7yYt|&$PU)v zPqV&+bw|x>oqTaiQ`kD+-7CDq#rFLB5i#$FX77gTvlS=(*L0`ze4O+9Px$Qc7=KMnl@(@W{LjK_zzn3oNl2C-B)|epcWnm7Y@7*g9*k{2oESM+)WlRW zN=gc>^!3Zj%k@y>Q$M{lGbJ@AGcUE+KoFsc5o8VnJ91b6(=IbG5L$wMYux`YU&^?L zaUV#yy7I2Apinp)72|OfIg5 z0tS2_4u>$iM`CVLX;C^%gdHJbWnckP!zFAO;;ax-R9al(oSIjXTBMMcU!)M6np|3x zSyHKxnWx~ASdysVms(PuUzA;};GUc0VW?!F0Mg4XEQzMqIVZ8WSixAq+0jtbKppN# zPDU}QRv$TD0`Z1LW9_0SiTX~9M+s6%j*MBb&w_U$Fvuc|9{`JNSXK6*QI5)W*`MlLbCiI0Ty7oYcnur<4kDtU~K#0#K^&-CZ>{6 zQc_^0uU}qXu7?_*`st;aDXBS`d8x$)f(T8FAafYlk;4L*cA0^JAZB~)?7`iwg{^M$ z?G*Y0HD#yy7I2Apinp)72|OfIg5 z0tS2_4u>$iM`CVLX;C^%gdHJbWnckP!zFAO;;ax-R9al(oSIjXTBMMcU!)M6np|3x zSyHKxnWx~ASdysVms(PuUzA;};GUc0VW?!F0Mg4XEQzMqIVZ8WSiwZW+0jtbKppN# zPDU}Q(QV>ZO0jwp()T^==i{-#%Z?#+b@#`UHOdloQIt z%*epFINKo8fFBs6vcimv|5;cKn1K{H3CZ$<1XzISuFb%hjWeOmgR$+06C($UnwUyP zNlAf~zJ7UmxgKhK>Zg}xrljU%=A{-J2qH8wg3MuHM-B^M+GPd?LXqIpsgABjyJUVe zi2P35{(9Z4bEVCJ2iA4%7Qd+Ryi8vBn6_KtGSPCDna|@kO;pKe<|%%zJg@B3KAxke zk4%vGlWUdtAgn?9@ckY$VfUY@2b+Vg#>DKs>6G@+R53$HU`fIRJNw2LhkF)o5M_xv Y_gW_;%=;%xrS9BUJ(2orEBAT;08&sKsQ>@~ literal 0 HcmV?d00001 diff --git a/keychains/roots/TCTrustCenterTimeStampingCA.der b/keychains/roots/TCTrustCenterTimeStampingCA.der new file mode 100644 index 0000000000000000000000000000000000000000..dc6d1f03b788c3eab99b805008e4e92496f8df5c GIT binary patch literal 839 zcmXqLVs#)F332Apinp)72|OfIg5 z0tS2_4u>$iM`CVLX;C^%gdHJbWnckP!zFAO;;ax-R9al(oSIjXTBMMcU!)M6np|3x zSyHKxnWx~ASdysVms(PuUzA;};GUc0VW?rC2GYwdERUu)Br`WvA-E(lw;(ewUBTHA zrjnVUN&`7@UP}uDV*^V=LsLsr%P4VPLqh`~gmQ<49~h0Cq@nyH8GWpl9B=|ef{$Ca=j8z!bt`v9KDoO{q)kzl+>KeywqZ3 zj{=h@Gth^6Yx=iIE?CkN$GDp_^O_#(?=tO7)9WYl*;Yt@x*E@Y#{2WZ;4f46&*{tA z9AC|S?Ae^<7j&5Iu3A2vllR*3$H^4u9kz?S9?JQ*PP#7bo@Xz9YyBHByFRH-UB}LA qnflJFV)Z_~xDfJ=SM2Dmf*V35F6+d+OWyWyuQuiK$as^#v={XN literal 0 HcmV?d00001 diff --git a/keychains/roots/ValiCertAddTrustPublicChainingCA.cer b/keychains/roots/ValiCertAddTrustPublicChainingCA.cer new file mode 100644 index 0000000000000000000000000000000000000000..66d812dc954911a2c52aae991de0fb422743e8ab GIT binary patch literal 927 zcmXqLVxDc##LTjQnTe5!i80N9myJ`a&7D}zDfZbKCVB{t?z7ItCju*959 z=hUJS1rQ@8u_QA;Pr)y>q&&YU+fdv<6r_qvm=C5(N5L~MS# zx%!3*26Ax6ax#huX6B{kJ0L4DkQ3)MFf=eTG&M2?l9o|Gt|=1NAls1JfD>d5n=n(b ztD%U25X2AMjwvZ2MWw|h3XV>OvIf!+4~W1;LqY=J9#=O|g*a3WE*(&s1azl@b4Frj zUS?jpg0rK7fssKIqY`rHGO{u-H!<=v0L8hOniv@wK5XtTm;b^eXZeA@XuDj%-kLUr z*(c4VUdX zTR&yk2Va?*-u~}`t6oyq?nP}U*T-ddN1fTMr?K#=(We8icWhoG{_=dVTB-ccNwW`~ zd~SDzW4hMt8=vBT$?k0O$ckDjwn>er{IcGn1?SFoztdmn!gPi6ozJ0D|MnaVwO#+q zt?o)%@YTvqb`dAbiWIi^%DC8CH*bHZs1+Y=>s=bP_1^I;wJO`!vmI>8*2qJnG!O({icp$wgb4m>C%u7grfn z7;pmvRFPA%*gnkg~NaiNCDHSK`2Op0*jx4kAW8(XF{6?W81GZMn(f$ z18X)8Z8l)aWoKd((+8!TV)Uewms+AIm`A2V9yW*o@hj083+VUE@=u}2>x+LF$n-4xL&>$7u_ laoGFs1?ii=thRN!Sv*ZW@pp(PuL_@4uC4{A(d+eVya5+(Mq&T} literal 0 HcmV?d00001 diff --git a/keychains/roots/ValiCertAddTrustSystemCA.cer b/keychains/roots/ValiCertAddTrustSystemCA.cer new file mode 100644 index 0000000000000000000000000000000000000000..e98462a082c766e8248da264140249b5261a1a8d GIT binary patch literal 918 zcmXqLVxDBs#PoXsGZP~d6JxpoFB_*;n@8JsUPeY%RtAH{-G(X#N^H!bEbPM4VTn1J z&Z$Ku3Lr*GVo7Fxo`PR$NqK%zwxPIzC`c8TFds~nj)G@ivYw%-fiXyeTUZAsq2Qd8 zSX``Ns1T5!lbKwJY?@~9{aSf6TxeYi$*02dP z1-lxG7zjc9!0nil5>ixJT%zFUWGHJO4e@{oTr?yk0Pb-)0~v@zMd8xHmBl5gxeCsX z3I;|7O^iy&fy&6rz}&>h&j1wXVrpV!WZ34R^L56QKhD!ceyQyE8Z7+ci|<{FmaxgJ zlUL5E2zcNZYW98dw_V!4aYvi=)b)S2fBCaY-KhPY8DsK?$}~ zck;}i-`9NIx@vd($?12tUhuKdH?UTz{dZpd!r3^z={s2ZYigwqNID&0jdc8JANi#9 z!)yL{r3aNA-8vGLnOOqY*50V!5nV1!> zg$0-t*}yR&E6m9FpM}GK4M;IDG8%+}6ezIx8Tc4@v2iA}c`&y9N&|}98d$S&XtMzm zEISjUm_8`M6r-n@ywno?qSS)?;>?o#qDp<|fMETyf?{1mJwxQ!0Va9o#zuy|=p>K( z_p4kNeR%0)c8y=-U;NXf<-6+Dk4pGNKJ*pXe)_8zzsahwO?U52b3b|}QA4G9m%I6g zfTbR(%o+U;rKdAa60g1**YpIMk%&a1F8-d<@Swlb))TbW7IZu0H=6M`zT e2P7DNO$%Kwa7$FcbE)t#nS`C%W}g6? literal 0 HcmV?d00001 diff --git a/keychains/roots/ValiCertClass1PVA.cer b/keychains/roots/ValiCertClass1PVA.cer new file mode 100644 index 0000000000000000000000000000000000000000..02b4f23e89d20c071a4652c41f5c3ab44b45bcac GIT binary patch literal 747 zcmXqLVtQ`S#1z29$Y{XJ#;Mij(e|B}k&%^^!Ju)sp^AYL8*?ZNyRdXvVos)WYEg*- zh>?<5l9`{U;Fnrbo?n!0C~hDMQpF|A2UDe^;F*`KXJ~3*43gj$)`3YVIOil57b_Sl z1mx#rCRZYx=2%*ikzbTqQfa7YAP>^UEG&^xQc_^0uU}qXu2%-MHyP*vz2y8{eM1EU zIk;mv8N~!M^V0Gikd+w7iSt@o8kiZG8W|ZGn^;7N^BN*^hq&(==Of1!BP#=QV=pkq zI++?98E!;2Rdw!|wriPwMt+3e@(>xeyf3eMJ@yz*5&!VnZ_lP3rjyDxTv)o4@j3&u zkdh?FkN<+ov(K@A-JdC?_RsI-#rnBA4ziIMdCPu8Y?v$6f7$-y9Z9yv6?_k@?w$yC z|gY;YAJqVzqECE(7!nww>^q37k7A7bWQoR zMx)VThDwPyk>Z^vk7dafp8UJLWT~oa=24H;k`G4zzwf_6E-oV2j=9X+< dX}4hM|81Vk!nc&pye(|fo_XGC`&Zqf69DKC2I>F+ literal 0 HcmV?d00001 diff --git a/keychains/roots/ValiCertClass2PVA.cer b/keychains/roots/ValiCertClass2PVA.cer new file mode 100644 index 0000000000000000000000000000000000000000..90f10c1d52955eaa27c3b193bb6dc6f05ac87109 GIT binary patch literal 747 zcmXqLVtQ`S#1z29$Y{XJ#;Mij(e|B}k&%^^!Ju)sp^AYL8*?ZNyRdXvVos)WYEg*- zh>?<5l9`{U;Fnrbo?n!0C~hDMQpF|A2UDe^;F*`KXJ~3*43gj$)`3YVIOil57b_Sk z1mx#rCRZYx=2%*ikzbTqQfa7YAP>^UEG&^xQc_^0uU}qXu2%-MHyP*vz2y8{eM1EU zIk;mv8N~!M^V0Gikd+w7iSt@o8kiZG85kH^nwmt3^BN*^hq&(==Of1!BP#=QV=pkq zI++?98O~W1o_f0aMC7E<>#J{+@cn#u^INEUWU4zKYv`TVGt6vaf@3cmoVR$h*Rk`h zsuQP5Hdox{n!7=|KF_XPtBs0WnR>-jSXaeYCLn+7!PXG#e}zvj$2k3Lcra0lE85a5 z{j+^&jkNui_>^Lk$6JK*&py{*(L!a;76%q9dD;c)#e%ZU;@g~2?JH?<5l9`{U;Fnrbo?n!0C~hDMQpF|A2UDe^;F*`KXJ~3*43gj$)`3YVIOil57b_Sm z1mx#rCRZYx=2%*ikzbTqQfa7YAP>^UEG&^xQc_^0uU}qXu2%-MHyP*vz2y8{eM1EU zIk;mv8N~!M^V0Gikd+w7iSt@o8kiZG85kHD85>85^BN*^hq&(==Of1!BP#=QV=pkq zI++?986M9FoF?<)>PEK4tnkA{rIS~mpSSGKXR)Aby1w>~_F^__BL;S!jMOH-El; zb?kk!LXnyMcMeVZ_&j0K^fxy=?(9Fvq;O1SiH46sR9WuEn9q0b%@ZhG*l|31wqx$8 z4LkZo->o&)KJU&FQ(DM1LuH2Ma?i-6cYkbmPD=cI`O$??dnRT^2K2S^0%u!jlW(_pZjGCm%!$eM|B=e$||f-|5VWIblL9w%8)M~Z%h*FxyW+bd-cir zuIp^NR&FRXjy-WS{QmkCrkm?K+h4v=owTFAwQAk9J#yv|TInYzp4V!$dwb0C{sBA5 eIg)3DeVZJ&_S}15o4}#K?^>6=sD5#e=sN%}p$eD) literal 0 HcmV?d00001 diff --git a/keychains/roots/beTRUSTedRootCertificate.der b/keychains/roots/beTRUSTedRootCertificate.der new file mode 100644 index 0000000000000000000000000000000000000000..eec29beeb469ef0234a6fb093aadfa679adf785b GIT binary patch literal 1328 zcmXqLV%0HdVi8%u%*4pV#A4}R+it+i#;Mij(e|B}k&%^^!63?z+klgeIh2J>m?=Em zP{=?4#NiU=OiB$23JnfPO)-=dwHyhG6(0Y$T=*5|*qi9m{^IS)h+lsu&${pb%FeX* zhjG=jkJr!UdwSdY>*nz_TS-)uFFybLi*NCbS=Lgr`=$n;SD1e2yq!u=4o_cdRQu35*yX7-}o=d*DT$0 zr@}Se#P-X2ncgS4*>4p#r_b7wcv?Ka)AavyzXL`>&)>bd|9`qc$=hD{zSmn0yF6R& zQy=F1V#l6s`+hY~f42Mgk!_RrNlMuDH0~_!5c@LCc}{w<_=FprdC6m4sHbxf4 zjdqL-pm4MRVn#L&pcpGFI}?*Z;}@yMk3p$9nTdJHsS5dd3MCnt#R|!(MJ1VOnaPPI zsR~Jz3W<4@3I&NpB|uhjacOR9u|i^Ua%w>dL{Az}PbvuKDI^vY?9^73*$ zxC*`G{9OIA#L}D+eXw&34BKnnOlam)fN4*ntM z4q!n5%pHsjm5H|($K{D_d{q|s^R(#f)0z98HD=G(kWaO{E7&^e$_vN+b;f&@pMO-? zzhuiYNycM6y{0v(OZ+*PT)Uwx$|}6vxpMvO#eB1?E2KWNv_&2J)}!EV;Tga-wJ{qhTm zJ3C&kcP?fWDp~w6CSEjF<@3)cU$&*E3q4O!>iV|Sahc4vgk;w)fi1h-1lBo*r{>rz U3)m|PL~eiLa952-`P-^>0H!|Cb^rhX literal 0 HcmV?d00001 -- 2.50.0