diff options
author | Max <post@wickenrode.com> | 2015-09-13 05:09:25 +0200 |
---|---|---|
committer | Max <post@wickenrode.com> | 2015-09-13 05:09:25 +0200 |
commit | fa2cd0b4841324776b10d968e1250676b0c65e32 (patch) | |
tree | 6c887957cfe7096c43090a13b0ffc08dd755f2b9 /Source | |
parent | b958ab043a666b2f545b46c2486e0f8fd3d301b1 (diff) | |
download | sequelpro-fa2cd0b4841324776b10d968e1250676b0c65e32.tar.gz sequelpro-fa2cd0b4841324776b10d968e1250676b0c65e32.tar.bz2 sequelpro-fa2cd0b4841324776b10d968e1250676b0c65e32.zip |
Replace OpenSSL for SHA1 calculation with Apple's CommonCrypto
(The easier half of #2223)
Also added some unit tests.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/SPDataAdditions.h | 2 | ||||
-rw-r--r-- | Source/SPDataAdditions.m | 52 |
2 files changed, 47 insertions, 7 deletions
diff --git a/Source/SPDataAdditions.h b/Source/SPDataAdditions.h index 0ceca0d3..118f47e2 100644 --- a/Source/SPDataAdditions.h +++ b/Source/SPDataAdditions.h @@ -30,6 +30,8 @@ @interface NSData (SPDataAdditions) +- (NSData *)sha1Hash; + - (NSData *)dataEncryptedWithPassword:(NSString *)password; - (NSData *)dataDecryptedWithPassword:(NSString *)password; - (NSData *)compress; diff --git a/Source/SPDataAdditions.m b/Source/SPDataAdditions.m index e9eaa927..23280c8b 100644 --- a/Source/SPDataAdditions.m +++ b/Source/SPDataAdditions.m @@ -36,11 +36,41 @@ #include <zlib.h> #include <openssl/aes.h> -#include <openssl/sha.h> +#include <CommonCrypto/CommonCrypto.h> #include <stdlib.h> +uint32_t LimitUInt32(NSUInteger i); + +#pragma mark - + @implementation NSData (SPDataAdditions) +- (NSData *)sha1Hash +{ + unsigned char digest[CC_SHA1_DIGEST_LENGTH]; + + //let's do it as a one step operation, if it fits + if([self length] <= UINT32_MAX) { + CC_SHA1([self bytes], (uint32_t)[self length], digest); + } + // or multi-step if length > 32 bit + else { + CC_SHA1_CTX ctx; + CC_SHA1_Init(&ctx); + + NSUInteger offset = 0; + uint32_t len; + while((len = LimitUInt32([self length]-offset)) > 0) { + CC_SHA1_Update(&ctx, ([self bytes]+offset), len); + offset += len; + } + + CC_SHA1_Final(digest, &ctx); + } + + return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; +} + - (NSData *)dataEncryptedWithPassword:(NSString *)password { // Create a random 128-bit initialization vector @@ -68,10 +98,9 @@ memcpy(paddedBytes + (paddedLength - 4), &bigIntDataLength, 4); // Create the key from first 128-bits of the 160-bit password hash - unsigned char passwordDigest[20]; - SHA1((const unsigned char *)[password UTF8String], strlen([password UTF8String]), passwordDigest); + NSData *passwordDigest = [[password dataUsingEncoding:NSUTF8StringEncoding] sha1Hash]; AES_KEY aesKey; - AES_set_encrypt_key(passwordDigest, 128, &aesKey); + AES_set_encrypt_key([passwordDigest bytes], 128, &aesKey); // AES-128-cbc encrypt the data, filling in the buffer after the IV AES_cbc_encrypt(paddedBytes, encryptedBytes + 16, paddedLength, &aesKey, iv, AES_ENCRYPT); @@ -83,12 +112,11 @@ - (NSData *)dataDecryptedWithPassword:(NSString *)password { // Create the key from the password hash - unsigned char passwordDigest[20]; - SHA1((const unsigned char *)[password UTF8String], strlen([password UTF8String]), passwordDigest); + NSData *passwordDigest = [[password dataUsingEncoding:NSUTF8StringEncoding] sha1Hash]; // AES-128-cbc decrypt the data AES_KEY aesKey; - AES_set_decrypt_key(passwordDigest, 128, &aesKey); + AES_set_decrypt_key([passwordDigest bytes], 128, &aesKey); // Total length = encrypted length + IV NSInteger totalLength = [self length]; @@ -312,3 +340,13 @@ } @end + +#pragma mark - + +uint32_t LimitUInt32(NSUInteger i) { +#if NSUIntegerMax > UINT32_MAX + return (i > UINT32_MAX)? UINT32_MAX : (uint32_t)i; +#else + return i; +#endif +} |