1// 2// secd-02-corruption.c 3// sec 4// 5// Created by Fabrice Gautier on 5/31/13. 6// 7// 8 9#include "secd_regressions.h" 10 11#include <securityd/SecDbItem.h> 12#include <utilities/array_size.h> 13#include <utilities/SecCFWrappers.h> 14#include <utilities/SecFileLocations.h> 15#include <utilities/fileIo.h> 16 17#include <securityd/SOSCloudCircleServer.h> 18#include <securityd/SecItemServer.h> 19 20#include <Security/SecBasePriv.h> 21 22#include <TargetConditionals.h> 23#include <AssertMacros.h> 24 25#include <stdio.h> 26#include <unistd.h> 27#include <sys/stat.h> 28#include <pthread.h> 29 30#if TARGET_OS_IPHONE && USE_KEYSTORE 31#include <libaks.h> 32 33#include "SecdTestKeychainUtilities.h" 34 35#include "brighton_keychain_2_db.h" 36 37static OSStatus query_one(void) 38{ 39 OSStatus ok; 40 41 /* querying a password */ 42 const void *keys[] = { 43 kSecClass, 44 kSecAttrServer, 45 }; 46 const void *values[] = { 47 kSecClassInternetPassword, 48 CFSTR("members.spamcop.net"), 49 }; 50 CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 51 array_size(keys), NULL, NULL); 52 CFTypeRef results = NULL; 53 54 ok = SecItemCopyMatching(query, &results); 55 56 CFReleaseSafe(results); 57 CFReleaseSafe(query); 58 59 return ok; 60} 61 62 63 64static void *do_query(void *arg) 65{ 66 /* querying a password */ 67 const void *keys[] = { 68 kSecClass, 69 kSecAttrServer, 70 }; 71 const void *values[] = { 72 kSecClassInternetPassword, 73 CFSTR("members.spamcop.net"), 74 }; 75 CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 76 array_size(keys), NULL, NULL); 77 CFTypeRef results = NULL; 78 79 for(int i=0;i<20;i++) 80 verify_action(SecItemCopyMatching(query, &results)==errSecUpgradePending, return (void *)-1); 81 82 CFReleaseSafe(query); 83 84 return NULL; 85} 86 87static void *do_sos(void *arg) 88{ 89 90 for(int i=0;i<20;i++) 91 verify_action(SOSCCThisDeviceIsInCircle_Server(NULL)==-1, return (void *)-1); 92 93 return NULL; 94} 95 96 97#define N_THREADS 10 98 99int secd_02_upgrade_while_locked(int argc, char *const *argv) 100{ 101 plan_tests(11 + N_THREADS + kSecdTestSetupTestCount); 102 103 __block keybag_handle_t keybag; 104 __block keybag_state_t state; 105 char *passcode="password"; 106 int passcode_len=(int)strlen(passcode); 107 108 /* custom keychain dir */ 109 secd_test_setup_temp_keychain("secd_02_upgrade_while_locked", ^{ 110 CFStringRef keychain_path_cf = __SecKeychainCopyPath(); 111 112 CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) { 113 writeFile(keychain_path, brighton_keychain_2_db, brighton_keychain_2_db_len); 114 115 /* custom notification */ 116 SecItemServerSetKeychainChangedNotification("com.apple.secdtests.keychainchanged"); 117 118 /* Create and lock custom keybag */ 119 ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); 120 ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); 121 ok(!(state&keybag_state_locked), "keybag unlocked"); 122 SecItemServerSetKeychainKeybag(keybag); 123 124 /* lock */ 125 ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag"); 126 ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); 127 ok(state&keybag_state_locked, "keybag locked"); 128 }); 129 130 CFReleaseSafe(keychain_path_cf); 131 }); 132 133 pthread_t query_thread[N_THREADS]; 134 pthread_t sos_thread; 135 void *query_err[N_THREADS] = {NULL,}; 136 void *sos_err = NULL; 137 138 for(int i=0; i<N_THREADS; i++) 139 pthread_create(&query_thread[i], NULL, do_query, NULL); 140 pthread_create(&sos_thread, NULL, do_sos, NULL); 141 142 for(int i=0; i<N_THREADS; i++) 143 pthread_join(query_thread[i],&query_err[i]); 144 pthread_join(sos_thread, &sos_err); 145 146 for(int i=0; i<N_THREADS; i++) 147 ok(query_err[i]==NULL, "query thread ok"); 148 ok(sos_err==NULL, "sos thread ok"); 149 150 ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "lock keybag"); 151 ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); 152 ok(!(state&keybag_state_locked), "keybag unlocked"); 153 154 is_status(query_one(), errSecItemNotFound, "Query after unlock"); 155 156 /* Reset keybag */ 157 SecItemServerResetKeychainKeybag(); 158 159 return 0; 160} 161 162#else 163 164int secd_02_upgrade_while_locked(int argc, char *const *argv) 165{ 166 plan_tests(1); 167 168 todo("Not yet working in simulator"); 169 170TODO: { 171 ok(false); 172} 173 /* not implemented in simulator (no keybag) */ 174 /* Not implemented in OSX (no upgrade scenario) */ 175 return 0; 176} 177#endif 178