// Diagnostic only: private SecKeychainCreate/Delete/CFRelease, with no certificate, PFX, SDK or CLR. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define REPETITIONS 200 static char root[PATH_MAX]; static struct timespec started; static unsigned created_refs, released_refs, query_releases; static double elapsed(void) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); return (double)(now.tv_sec-started.tv_sec)+(double)(now.tv_nsec-started.tv_nsec)/1e9; } static void die(const char *message) { fprintf(stdout,"{\"kind\":\"failed\",\"message\":\"%s\",\"createdRefs\":%u,\"releasedRefs\":%u,\"elapsedSeconds\":%.6f}\n",message,created_refs,released_refs,elapsed()); fflush(stdout); exit(1); } static void hex(const unsigned char *bytes, size_t length, char *out) { const char *alphabet="0123456789abcdef"; for(size_t i=0;i>4];out[i*2+1]=alphabet[bytes[i]&15];} out[length*2]=0; } static void wipe(void *memory, size_t length) { volatile unsigned char *bytes=(volatile unsigned char *)memory; while(length--)*bytes++=0; } static OSStatus keychain_path(SecKeychainRef keychain, char *path) { UInt32 length=PATH_MAX-1; OSStatus status=SecKeychainGetPath(keychain,&length,path); if(status==errSecSuccess && length=sizeof(next))die("Checkpoint path overflow"); while(access(next,F_OK)!=0){if(elapsed()>180)die("Checkpoint deadline exceeded");struct timespec pause={0,25000000};nanosleep(&pause,NULL);} } static int absent(const char *path){struct stat state;if(lstat(path,&state)==0)return 0;return errno==ENOENT;} static void operation(unsigned iteration) { unsigned char random[48];if(SecRandomCopyBytes(kSecRandomDefault,sizeof(random),random)!=errSecSuccess)die("Secure random failed"); char suffix[33],password[65];hex(random,16,suffix);hex(random+16,32,password);wipe(random,sizeof(random)); char path[PATH_MAX],backing[PATH_MAX];int n=snprintf(path,sizeof(path),"%s/tmp/native-retention-%s.keychain",root,suffix); if(n<0 || (size_t)n>=sizeof(path))die("Fixture path overflow"); n=snprintf(backing,sizeof(backing),"%s-db",path);if(n<0 || (size_t)n>=sizeof(backing))die("Fixture backing path overflow"); if(!absent(path)||!absent(backing))die("Generated private fixture path already exists"); SecKeychainRef keychain=NULL; OSStatus create_status=SecKeychainCreate(path,(UInt32)strlen(password),password,false,NULL,&keychain); wipe(password,sizeof(password)); OSStatus path_status=errSecInvalidKeychain,delete_status=INT32_MIN; int verified=0,released=0; if(keychain){ created_refs++; char actual[PATH_MAX];memset(actual,0,sizeof(actual));path_status=keychain_path(keychain,actual); // Only a returned reference whose path is exactly this generated private fixture can be deleted. verified=path_status==errSecSuccess && (!strcmp(actual,path)||!strcmp(actual,backing)); if(verified)delete_status=SecKeychainDelete(keychain); // Exactly one CFRelease for this returned owned reference, irrespective of delete status. CFRelease(keychain);keychain=NULL;released_refs++;released=1; } fprintf(stdout,"{\"kind\":\"operation\",\"iteration\":%u,\"createStatus\":%d,\"pathStatus\":%d,\"deleteStatus\":%d,\"returnedRef\":%s,\"privatePathVerified\":%s,\"releasedExactlyOnce\":%s}\n",iteration,(int)create_status,(int)path_status,(int)delete_status,released?"true":"false",verified?"true":"false",released?"true":"false");fflush(stdout); if(create_status || path_status || delete_status || !verified || !released)die("Private keychain lifecycle operation failed"); } int main(int argc,char **argv) { clock_gettime(CLOCK_MONOTONIC,&started); if(argc!=2 || !realpath(argv[1],root))die("Expected existing private fixture root"); struct stat state;if(stat(root,&state) || !S_ISDIR(state.st_mode) || (state.st_mode&077))die("Fixture root must be mode0700"); struct fingerprint before=fingerprint("before");checkpoint("before",0); for(unsigned i=1;i<=REPETITIONS;i++){operation(i);if(i==1)checkpoint("first",i);} checkpoint("repeated",REPETITIONS); struct timespec idle={5,0};while(nanosleep(&idle,&idle)!=0){if(errno!=EINTR)die("Idle delay failed");} struct fingerprint after=fingerprint("after"); checkpoint("idle",REPETITIONS); int unchanged=!strcmp(before.default_sha,after.default_sha)&&!strcmp(before.search_sha,after.search_sha)&&before.search_count==after.search_count; if(!unchanged || created_refs!=REPETITIONS || released_refs!=REPETITIONS)die("Fingerprint or native ownership guard failed"); fprintf(stdout,"{\"kind\":\"complete\",\"operations\":200,\"createdRefs\":%u,\"releasedRefs\":%u,\"readOnlyDefaultAndSearchListUnchanged\":true,\"elapsedSeconds\":%.6f,\"fullSoakGate\":false}\n",created_refs,released_refs,elapsed());fflush(stdout);return 0; }