X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/914fc88e61be54aed6b18205ff2775b48793a3b6..07691282a056c4efea71e1e505527601e8cc166b:/OSX/libsecurity_keychain/lib/SecRecoveryPassword.c diff --git a/OSX/libsecurity_keychain/lib/SecRecoveryPassword.c b/OSX/libsecurity_keychain/lib/SecRecoveryPassword.c index d665dd3a..a409f0fd 100644 --- a/OSX/libsecurity_keychain/lib/SecRecoveryPassword.c +++ b/OSX/libsecurity_keychain/lib/SecRecoveryPassword.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -89,19 +90,17 @@ sec_debug_imp(int level, const char *funcname, char *format, ...) { // Read /dev/random for random bytes static CFDataRef -getRandomBytes(size_t len) +createRandomBytes(size_t len) { - uint8_t *buffer; - CFDataRef randData = NULL; - int fdrand; - - if((buffer = malloc(len)) == NULL) return NULL; - if((fdrand = open("/dev/random", O_RDONLY)) == -1) return NULL; - if(read(fdrand, buffer, len) == len) randData = CFDataCreate(kCFAllocatorDefault, (const UInt8 *) buffer, len); - close(fdrand); - - free(buffer); - return randData; + CFMutableDataRef data = CFDataCreateMutable(NULL, len); + if (data == NULL) + return NULL; + CFDataSetLength(data, len); + if (SecRandomCopyBytes(kSecRandomDefault, len, CFDataGetMutableBytePtr(data)) != noErr) { + CFRelease(data); + return NULL; + } + return data; } // This is the normalization routine - subject to change. We need to make sure that whitespace is removed and @@ -132,7 +131,8 @@ static void secNormalize(CFMutableStringRef theString, CFLocaleRef theLocale) #define MAXANSWERBUFF 4096 #define PBKDF_ROUNDS 100000 -static SecKeyRef secDeriveKeyFromAnswers(CFArrayRef answers, CFLocaleRef theLocale) +static SecKeyRef CF_RETURNS_RETAINED +secDeriveKeyFromAnswers(CFArrayRef answers, CFLocaleRef theLocale) { static const uint8_t salt[16] = { 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F }; static const int saltLen = sizeof(salt); @@ -210,7 +210,7 @@ static SecKeyRef secDeriveKeyFromAnswers(CFArrayRef answers, CFLocaleRef theLoca // Single shot CFString processing routines for digests/encoding/encrypt/decrypt static CFDataRef -digestString(CFStringRef str) +createDigestString(CFStringRef str) { CFDataRef retval = NULL; CFErrorRef error = NULL; @@ -223,12 +223,14 @@ digestString(CFStringRef str) if(error == NULL) { retval = SecTransformExecute(digestTrans, &error); if(retval == NULL) { - secDebug(ASL_LEVEL_ERR, "Couldn't create digest %s\n", CFStringGetCStringPtr(CFErrorCopyFailureReason(error), kCFStringEncodingUTF8)); + CFStringRef errorReason = CFErrorCopyFailureReason(error); + secDebug(ASL_LEVEL_ERR, "Couldn't create digest %s\n", CFStringGetCStringPtr(errorReason, kCFStringEncodingUTF8)); + CFReleaseNull(errorReason); } } - CFRelease(digestTrans); } - CFRelease(inputString); + CFReleaseNull(digestTrans); + CFReleaseNull(inputString); return retval; } @@ -256,7 +258,7 @@ b64decode(CFDataRef input) return retval; } -static CFDataRef +static CFDataRef CF_RETURNS_RETAINED encryptString(SecKeyRef wrapKey, CFDataRef iv, CFStringRef str) { CFDataRef retval = NULL; @@ -354,7 +356,7 @@ createIVFromPassword(CFStringRef password) { CFDataRef hashedPassword, retval; CFMutableDataRef iv; - if((hashedPassword = digestString(password)) == NULL) return NULL; + if((hashedPassword = createDigestString(password)) == NULL) return NULL; iv = CFDataCreateMutableCopy(kCFAllocatorDefault, CFDataGetLength(hashedPassword)+1, hashedPassword); CFDataDeleteBytes(iv, CFRangeMake(IVBYTECOUNT, CFDataGetLength(iv)-IVBYTECOUNT)); retval = CFDataCreateCopy(kCFAllocatorDefault, iv); @@ -375,54 +377,66 @@ createIVFromPassword(CFStringRef password) * recovery dictionary. */ -CFDictionaryRef +CFDictionaryRef CF_RETURNS_RETAINED SecWrapRecoveryPasswordWithAnswers(CFStringRef password, CFArrayRef questions, CFArrayRef answers) { uint32_t vers = 1; - CFDataRef iv; - CFDataRef wrappedPassword; + CFDataRef iv = NULL; + CFDataRef wrappedPassword = NULL; CFMutableDictionaryRef retval = NULL; CFLocaleRef theLocale = CFLocaleCopyCurrent(); CFStringRef theLocaleString = CFLocaleGetIdentifier(theLocale); + SecKeyRef wrapKey = NULL; CFIndex ix, limit; - if (!password || !questions || !answers) - return NULL; + if (!password || !questions || !answers) { + goto error; + } limit = CFArrayGetCount(answers); - if (limit != CFArrayGetCount(questions)) - return NULL; // Error + if (limit != CFArrayGetCount(questions)) { + goto error; + } CFTypeRef chkval; for (ix=0; ix