+uint32 CommonBlob::getCurrentVersion() {
+ uint32 ret = version_MacOS_10_0;
+ // If the integrity protections are turned on, use version_partition.
+ // else, use version_MacOS_10_0.
+ CFTypeRef integrity = (CFNumberRef)CFPreferencesCopyValue(CFSTR("KeychainIntegrity"), CFSTR("com.apple.security"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+ if (integrity && CFGetTypeID(integrity) == CFBooleanGetTypeID()) {
+ bool integrityProtections = CFBooleanGetValue((CFBooleanRef)integrity);
+
+ if(integrityProtections) {
+ secnotice("integrity", "creating a partition keychain; global is on");
+ ret = version_partition;
+ } else {
+ secnotice("integrity", "creating a old-style keychain; global is off");
+ ret = version_MacOS_10_0;
+ }
+ } else {
+ secnotice("integrity", "global integrity not set, defaulting to on");
+ ret = version_partition;
+ }
+ CFReleaseSafe(integrity);
+
+ return ret;
+}
+
+uint32 CommonBlob::getCurrentVersionForDb(const char* dbName) {
+ // Currently, the scheme is as follows:
+ // in ~/Library/Keychains:
+ // version_partition
+ // Elsewhere:
+ // version_MacOS_10_0`
+
+ if(pathInHomeLibraryKeychains(dbName)) {
+ return CommonBlob::getCurrentVersion();
+ }
+
+ secnotice("integrity", "outside ~/Library/Keychains/; creating a old-style keychain");
+ return version_MacOS_10_0;
+}
+
+bool CommonBlob::pathInHomeLibraryKeychains(const string& path) {
+ // We need to check if this path is in Some User's ~/Library/Keychains directory.
+ // At this level, there's no great way of discovering what's actually a
+ // user's home directory, so instead let's look for anything under
+ // ./Library/Keychains/ that isn't /Library/Keychains or /System/Library/Keychains.
+
+ string libraryKeychains = "/Library/Keychains";
+ string systemLibraryKeychains = "/System/Library/Keychains";
+
+ bool inALibraryKeychains = (string::npos != path.find(libraryKeychains));
+ bool inRootLibraryKeychains = (0 == path.find(libraryKeychains));
+ bool inSystemLibraryKeychains = (0 == path.find(systemLibraryKeychains));
+
+ return (inALibraryKeychains && !inRootLibraryKeychains && !inSystemLibraryKeychains);
+}
+
+void CommonBlob::initialize()
+{
+ magic = magicNumber;
+
+ this->blobVersion = getCurrentVersion();
+}