diff -r 000000000000 -r 0a6527af039b MYDigest.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MYDigest.m Sat Apr 04 20:42:03 2009 -0700 @@ -0,0 +1,278 @@ +// +// MYDigest.m +// MYCrypto +// +// Created by Jens Alfke on 1/4/08. +// Copyright 2008 Jens Alfke. All rights reserved. +// + +#import "MYDigest.h" +#import +#import "MYCrypto_Private.h" + + +#if USE_IPHONE_API +enum { + CSSM_ALGID_SHA1 = 8, + CSSM_ALGID_SHA256 = 0x80000000 + 14 +}; +#endif + + +@implementation MYDigest + ++ (uint32_t) algorithm { + AssertAbstractMethod(); +} + ++ (size_t) length { + AssertAbstractMethod(); +} + ++ (void) computeDigest: (void*)dstDigest ofBytes: (const void*)bytes length: (size_t)length { + AssertAbstractMethod(); +} + + +- (id) initWithRawDigest: (const void*)rawDigest length: (size_t)length { + Assert([self class] != [MYDigest class], @"MYDigest is an abstract class"); + Assert(rawDigest!=NULL); + AssertEq(length,[[self class] length]); + self = [super init]; + if (self) { + _rawDigest = malloc(length); + Assert(_rawDigest); + memcpy(_rawDigest,rawDigest,length); + } + return self; +} + +- (void) dealloc +{ + if(_rawDigest) free(_rawDigest); + [super dealloc]; +} + + +- (id) copyWithZone: (NSZone*)zone +{ + return [self retain]; +} + +- (id)initWithCoder:(NSCoder *)decoder +{ + NSUInteger length; + const void *bytes = [decoder decodeBytesForKey: @"digest" returnedLength: &length]; + return [self initWithRawDigest: bytes length: length]; +} + + +- (void)encodeWithCoder:(NSCoder *)coder +{ + [coder encodeBytes: self.bytes length: self.length forKey: @"digest"]; +} + + ++ (MYDigest*) digestFromDigestData: (NSData*)digestData { + return [[[self alloc] initWithRawDigest: digestData.bytes length: digestData.length] autorelease]; +} + ++ (MYDigest*) digestFromHexString: (NSString*)hexString +{ + const char *cStr = [hexString UTF8String]; + const size_t length = [self length]; + if( !cStr || strlen(cStr)!=2*length ) + return nil; + uint8_t digest[length]; + for( int i=0; i0); + CC_SHA1(bytes,length, dstDigest); +} + ++ (uint32_t) algorithm {return CSSM_ALGID_SHA1;} ++ (size_t) length {return sizeof(RawSHA1Digest);} + +- (MYSHA1Digest*) initWithRawSHA1Digest: (const RawSHA1Digest*)rawDigest { + return [super initWithRawDigest: rawDigest length: sizeof(*rawDigest)]; +} + ++ (MYSHA1Digest*) digestFromRawSHA1Digest: (const RawSHA1Digest*)rawDigest { + return [[[self alloc] initWithRawSHA1Digest: rawDigest] autorelease]; +} + +- (const RawSHA1Digest*) rawSHA1Digest { + return self.bytes; +} + + +@end + + + +@implementation MYSHA256Digest + ++ (void) computeDigest: (void*)dstDigest ofBytes: (const void*)bytes length: (size_t)length { + NSParameterAssert(bytes!=NULL); + NSParameterAssert(length>0); + CC_SHA256(bytes,length, dstDigest); +} + ++ (uint32_t) algorithm {return CSSM_ALGID_SHA256;} ++ (size_t) length {return sizeof(RawSHA256Digest);} + +- (MYSHA256Digest*) initWithRawSHA256Digest: (const RawSHA256Digest*)rawDigest { + return [super initWithRawDigest: rawDigest length: sizeof(*rawDigest)]; +} + ++ (MYSHA256Digest*) digestFromRawSHA256Digest: (const RawSHA256Digest*)rawDigest { + return [[[self alloc] initWithRawSHA256Digest: rawDigest] autorelease]; +} + +- (const RawSHA256Digest*) rawSHA256Digest { + return self.bytes; +} + + +@end + + + +@implementation NSData (MYDigest) + +- (MYSHA1Digest*) my_SHA1Digest +{ + return (MYSHA1Digest*) [MYSHA1Digest digestOfData: self]; +} + +- (MYSHA256Digest*) my_SHA256Digest +{ + return (MYSHA256Digest*) [MYSHA256Digest digestOfData: self]; +} + +@end + + + +#import "Test.h" + + +static void testDigestOf( NSData *src, NSString *expectedSHA1Hex, NSString *expectedSHA256Hex ) +{ + MYSHA1Digest *d1 = [src my_SHA1Digest]; + NSString *hex = d1.hexString; + Log(@"Digesting %u bytes to %@",src.length,hex); + if( expectedSHA1Hex ) + CAssertEqual(hex,expectedSHA1Hex); + MYSHA1Digest *d2 = (MYSHA1Digest*) [MYSHA1Digest digestFromHexString: hex]; + CAssertEqual(d1,d2); + CAssertEqual(d2.hexString,hex); + + MYSHA256Digest *d256 = [src my_SHA256Digest]; + hex = d256.hexString; + Log(@"Digesting %u bytes to %@",src.length,hex); + if( expectedSHA256Hex ) + CAssertEqual(hex,expectedSHA256Hex); + MYSHA256Digest *d256_2 = (MYSHA256Digest*) [MYSHA256Digest digestFromHexString: hex]; + CAssertEqual(d256,d256_2); + CAssertEqual(d256_2.hexString,hex); +} + + +TestCase(MYDigest) { + testDigestOf([@"Pack my box with five dozen liquor jugs, you ugly potatoe pie!" + dataUsingEncoding: NSUTF8StringEncoding], + @"4F254781ED6C0103BE056DD8418EFBAC0C2EBE3C", + @"08AA4BCDDF7654D7AB5CDD25395A4DD8F3BEB5C79FE567D10C1A21B9134F48FD"); + testDigestOf([NSData dataWithContentsOfFile: @"/Library/Desktop Pictures/Nature/Zen Garden.jpg"], + @"62A17839B3B86D3543EB2E34D2718A0FE044FA31", + @"FBD25FA6CEE794049973DE3BDF752345617FCA81018C8FC65350BCDD901142DB"); +}