X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/79b9da22a1f4b26279940d285c1bc28ce4e99252..7e6b461318c8a779d91381531435a68ee4e8b6ed:/OSX/libsecurity_keychain/lib/TokenLogin.cpp?ds=inline diff --git a/OSX/libsecurity_keychain/lib/TokenLogin.cpp b/OSX/libsecurity_keychain/lib/TokenLogin.cpp index 77bf44da..347d007b 100644 --- a/OSX/libsecurity_keychain/lib/TokenLogin.cpp +++ b/OSX/libsecurity_keychain/lib/TokenLogin.cpp @@ -35,7 +35,7 @@ #include extern "C" { -#include +#include #include } @@ -119,7 +119,7 @@ static CFDataRef getPubKeyHashWrap(CFDictionaryRef context) return pubKeyHashWrap; } -static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey, CFTypeRef *laCtx) +static OSStatus privKeyForPubKeyHashWrap(CFDictionaryRef context, SecKeyRef *privKey, CFTypeRef *laCtx) { if (!context) { os_log_error(TL_LOG, "private key for pubkeyhash wrong params"); @@ -133,14 +133,14 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey if (pin) { CFRef LAContext = LACreateNewContextWithACMContext(NULL, error.take()); if (!LAContext) { - os_log_error(TL_LOG, "Failed to LA Context: %@", error.get()); + os_log_error(TL_LOG, "Failed to LA Context: %{public}@", error.get()); return errSecParam; } if (laCtx) *laCtx = (CFTypeRef)CFRetain(LAContext); CFRef externalizedContext = LACopyACMContext(LAContext, error.take()); if (!externalizedContext) { - os_log_error(TL_LOG, "Failed to get externalized context: %@", error.get()); + os_log_error(TL_LOG, "Failed to get externalized context: %{public}@", error.get()); return errSecParam; } CFDictionarySetValue(tokenAttributes, kSecUseCredentialReference, externalizedContext.get()); @@ -149,17 +149,22 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey CFRef token = TKTokenCreate(tokenAttributes, error.take()); if (!token) { - os_log_error(TL_LOG, "Failed to create token: %@", error.get()); + os_log_error(TL_LOG, "Failed to create token: %{public}@", error.get()); return errSecParam; } CFRef identities = TKTokenCopyIdentities(token, TKTokenKeyUsageAny, error.take()); if (!identities || !CFArrayGetCount(identities)) { - os_log_error(TL_LOG, "No identities found for token: %@", error.get()); + os_log_error(TL_LOG, "No identities found for token: %{public}@", error.get()); + return errSecParam; + } + + CFDataRef desiredHash = getPubKeyHashWrap(context); + if (!desiredHash) { + os_log_error(TL_LOG, "No wrap key in context"); return errSecParam; } - CFDataRef desiredHash = getPubKeyHashWrap(context); CFIndex idx, count = CFArrayGetCount(identities); for (idx = 0; idx < count; ++idx) { SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(identities, idx); @@ -213,12 +218,12 @@ OSStatus TokenLoginGetContext(const void *base64TokenLoginData, UInt32 base64Tok NULL, error.take()); if (!*context || CFGetTypeID(*context) != CFDictionaryGetTypeID()) { - os_log_error(TL_LOG, "Invalid token login data property list, %@", error.get()); + os_log_error(TL_LOG, "Invalid token login data property list, %{public}@", error.get()); return errSecParam; } if (!getPin(*context) || !getTokenId(*context) || !getPubKeyHash(*context) || !getPubKeyHashWrap(*context)) { - os_log_error(TL_LOG, "Invalid token login data context, %@", error.get()); + os_log_error(TL_LOG, "Invalid token login data context, %{public}@", error.get()); return errSecParam; } @@ -231,8 +236,8 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) os_log_error(TL_LOG, "Get unlock key - wrong params"); return errSecParam; } - - CFRef loginData; + + CFRef loginData; OSStatus result = TokenLoginGetLoginData(context, loginData.take()); if (result != errSecSuccess) { os_log_error(TL_LOG, "Failed to get login data: %d", (int)result); @@ -249,12 +254,23 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) os_log_error(TL_LOG, "Algorithm not found in unlock key data"); return errSecParam; } + CFDataRef pubKeyHashWrapFromPlist = (CFDataRef)CFDictionaryGetValue(loginData, kSecAttrPublicKeyHash); + if (pubKeyHashWrapFromPlist == NULL) { + os_log_error(TL_LOG, "Failed to get wrapkey for unlock key data"); + return errSecInternal; + } + CFRef ctx = makeCFDictionary(3, + kSecAttrTokenID, getTokenId(context), + kSecAttrService, getPin(context), + kSecAttrAccount, pubKeyHashWrapFromPlist + ); + CFRef privKey; CFRef LAContext; - result = privKeyForPubKeyHash(context, privKey.take(), LAContext.take()); + result = privKeyForPubKeyHashWrap(ctx, privKey.take(), LAContext.take()); if (result != errSecSuccess) { - os_log_error(TL_LOG, "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 %{public}@: %d", pubKeyHashWrapFromPlist, (int)result); return result; } @@ -269,14 +285,14 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) wrappedUnlockKey, error.take()); if (!*unlockKey) { - os_log_error(TL_LOG, "Failed to unwrap unlock key: %@", error.get()); + os_log_error(TL_LOG, "Failed to unwrap unlock key: %{public}@", error.get()); return errSecDecode; } // we need to re-wrap already unwrapped data to avoid capturing and reusing communication with the smartcard CFRef reWrappedUnlockKey = SecKeyCreateEncryptedData(pubKey, algorithm, *unlockKey, error.take()); if (!reWrappedUnlockKey) { - os_log_error(TL_LOG, "Failed to rewrap unlock key: %@", error.get()); + os_log_error(TL_LOG, "Failed to rewrap unlock key: %{public}@", error.get()); TokenLoginDeleteUnlockData(getPubKeyHash(context)); return errSecParam; } @@ -292,30 +308,18 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) OSStatus TokenLoginGetLoginData(CFDictionaryRef context, CFDictionaryRef *loginData) { - 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 pubKeyHashHex = cfDataToHex(getPubKeyHash(context)); - os_log(TL_LOG, "pubkeyhash %@", pubKeyHashHex.get()); CFPreferencesSynchronize(kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); CFRef storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); - os_log(TL_LOG, "stored data %@", storedData.get()); - if (!storedData) { + // this is not an error, might be a normal situation if the value does not exist os_log_debug(TL_LOG, "Failed to read token login plist"); - os_log(TL_LOG, "Failed to read token login plist"); return errSecIO; } @@ -326,7 +330,7 @@ OSStatus TokenLoginGetLoginData(CFDictionaryRef context, CFDictionaryRef *loginD NULL, error.take()); if (!*loginData || CFGetTypeID(*loginData) != CFDictionaryGetTypeID()) { - os_log_error(TL_LOG, "Failed to deserialize unlock key data: %@", error.get()); + os_log_error(TL_LOG, "Failed to deserialize unlock key data: %{public}@", error.get()); return errSecParam; } @@ -373,9 +377,9 @@ OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CF kSecAttrAccount, pubKeyHashWrap ); CFRef privKey; - OSStatus result = privKeyForPubKeyHash(ctx, privKey.take(), NULL); + OSStatus result = privKeyForPubKeyHashWrap(ctx, privKey.take(), NULL); if (result != errSecSuccess) { - os_log_error(TL_LOG, "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 %{public}@: %d", pubKeyHashWrap, (int)result); return result; } @@ -414,7 +418,7 @@ OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CF CFRef error; CFRef wrappedUnlockKey = SecKeyCreateEncryptedData(pubKey, algorithm, unlockKey, error.take()); if (!wrappedUnlockKey) { - os_log_error(TL_LOG, "Failed to wrap unlock key: %@", error.get()); + os_log_error(TL_LOG, "Failed to wrap unlock key: %{public}@", error.get()); return errSecParam; } @@ -429,7 +433,7 @@ OSStatus TokenLoginCreateLoginData(CFStringRef tokenId, CFDataRef pubKeyHash, CF OSStatus TokenLoginStoreUnlockData(CFDictionaryRef context, CFDictionaryRef loginData) { - os_log(TL_LOG, "Storing unlock data"); + os_log_debug(TL_LOG, "Storing unlock data"); CFRef error; CFRef data = CFPropertyListCreateData(kCFAllocatorDefault, @@ -438,24 +442,24 @@ OSStatus TokenLoginStoreUnlockData(CFDictionaryRef context, CFDictionaryRef logi 0, error.take()); if (!data) { - os_log_error(TL_LOG, "Failed to create unlock data: %@", error.get()); + os_log_error(TL_LOG, "Failed to create unlock data: %{public}@", error.get()); return errSecInternal; } CFRef pubKeyHashHex = cfDataToHex(getPubKeyHash(context)); - os_log(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get()); + os_log_debug(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get()); CFPreferencesSetValue(pubKeyHashHex, data, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); - os_log(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get()); + os_log_debug(TL_LOG, "Pubkeyhash %@", pubKeyHashHex.get()); CFPreferencesSynchronize(kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); CFRef storedData = (CFDataRef)CFPreferencesCopyValue(pubKeyHashHex, kSecTokenLoginDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); - os_log(TL_LOG, "Stored data %@", storedData.get()); + os_log_debug(TL_LOG, "Stored data %@", storedData.get()); if (!storedData || !CFEqual(storedData, data)) { os_log_error(TL_LOG, "Failed to write token login plist"); return errSecIO; } - os_log(TL_LOG, "Original data %@. Everything is OK", data.get()); + os_log_debug(TL_LOG, "Original data %@. Everything is OK", data.get()); return errSecSuccess; } @@ -488,9 +492,9 @@ OSStatus TokenLoginGetScBlob(CFDataRef pubKeyHashWrap, CFStringRef tokenId, CFSt ); CFRef privKey; - OSStatus retval = privKeyForPubKeyHash(ctx, privKey.take(), NULL); + OSStatus retval = privKeyForPubKeyHashWrap(ctx, privKey.take(), NULL); if (retval != errSecSuccess) { - os_log_error(TL_LOG, "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 %{public}@: %d", pubKeyHashWrap, (int)retval); return retval; } @@ -550,6 +554,7 @@ OSStatus TokenLoginGetScBlob(CFDataRef pubKeyHashWrap, CFStringRef tokenId, CFSt return aks_retval; } +// context = data wrapped in password variable, loginData = dictionary from stored plist OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginData) { if (!loginData || !context) { @@ -562,12 +567,24 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa return errSecInternal; } + CFDataRef pubKeyHashWrapFromPlist = (CFDataRef)CFDictionaryGetValue(loginData, kSecAttrPublicKeyHash); + if (pubKeyHashWrapFromPlist == NULL) { + os_log_error(TL_LOG, "Failed to get wrapkey"); + return errSecInternal; + } + + CFRef ctx = makeCFDictionary(3, + kSecAttrTokenID, getTokenId(context), + kSecAttrService, getPin(context), + kSecAttrAccount, pubKeyHashWrapFromPlist + ); + CFRef error; CFRef privKey; CFRef LAContext; - OSStatus retval = privKeyForPubKeyHash(context, privKey.take(), LAContext.take()); + OSStatus retval = privKeyForPubKeyHashWrap(ctx, privKey.take(), LAContext.take()); if (retval != errSecSuccess) { - os_log_error(TL_LOG, "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 %{public}@: %d", pubKeyHashWrapFromPlist, (int)retval); return retval; } @@ -639,7 +656,7 @@ OSStatus TokenLoginUnlockKeybag(CFDictionaryRef context, CFDictionaryRef loginDa (CFDataRef)wrappedUsk.get(), error.take()); if (!unwrappedUsk) { - os_log_error(TL_LOG, "TokenLoginUnlockKeybag failed to unwrap blob: %@", error.get()); + os_log_error(TL_LOG, "TokenLoginUnlockKeybag failed to unwrap blob: %{public}@", error.get()); return errSecInternal; }