Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -147,10 +147,12 @@ 4B3379CF1979326A0088E97E /* threading.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3379CE1979326A0088E97E /* threading.m */; }; 4B39844213D3A24600E6F825 /* OFSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B39844013D3A24600E6F825 /* OFSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B39844313D3A24600E6F825 /* OFSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844113D3A24600E6F825 /* OFSet.m */; }; 4B39844713D3AFB400E6F825 /* OFMutableSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B39844513D3AFB400E6F825 /* OFMutableSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B39844813D3AFB400E6F825 /* OFMutableSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844613D3AFB400E6F825 /* OFMutableSet.m */; }; + 4B3B03EB19B3F70500F70C05 /* OFSHA256Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3B03E919B3F70500F70C05 /* OFSHA256Hash.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B3B03EC19B3F70500F70C05 /* OFSHA256Hash.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B03EA19B3F70500F70C05 /* OFSHA256Hash.m */; }; 4B3B0798166978780044E634 /* OFMapTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3B0796166978780044E634 /* OFMapTable.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3B0799166978780044E634 /* OFMapTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B0797166978780044E634 /* OFMapTable.m */; }; 4B3D238B1337FC0D00DD29B8 /* OFApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B175C1E116D130B003C99CB /* OFApplication.m */; }; 4B3D238C1337FC0D00DD29B8 /* OFArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B67995B1099E7C50041064A /* OFArray.m */; }; 4B3D238D1337FC0D00DD29B8 /* OFAutoreleasePool.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */; }; @@ -634,10 +636,12 @@ 4B3379CE1979326A0088E97E /* threading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = threading.m; path = src/threading.m; sourceTree = ""; }; 4B39844013D3A24600E6F825 /* OFSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSet.h; path = src/OFSet.h; sourceTree = ""; }; 4B39844113D3A24600E6F825 /* OFSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSet.m; path = src/OFSet.m; sourceTree = ""; }; 4B39844513D3AFB400E6F825 /* OFMutableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableSet.h; path = src/OFMutableSet.h; sourceTree = ""; }; 4B39844613D3AFB400E6F825 /* OFMutableSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableSet.m; path = src/OFMutableSet.m; sourceTree = ""; }; + 4B3B03E919B3F70500F70C05 /* OFSHA256Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSHA256Hash.h; path = src/OFSHA256Hash.h; sourceTree = ""; }; + 4B3B03EA19B3F70500F70C05 /* OFSHA256Hash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSHA256Hash.m; path = src/OFSHA256Hash.m; sourceTree = ""; }; 4B3B0796166978780044E634 /* OFMapTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMapTable.h; path = src/OFMapTable.h; sourceTree = ""; }; 4B3B0797166978780044E634 /* OFMapTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMapTable.m; path = src/OFMapTable.m; sourceTree = ""; }; 4B3D236D1337FB5800DD29B8 /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base64.h; path = src/base64.h; sourceTree = ""; }; 4B3D236E1337FB5800DD29B8 /* base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = base64.m; path = src/base64.m; sourceTree = ""; }; 4B3D23761337FBC800DD29B8 /* ObjFW.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ObjFW.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1333,10 +1337,12 @@ 4B8385151951BF9500D5358A /* OFSettings.m */, 4B8385121951BF9500D5358A /* OFSettings_INIFile.h */, 4B8385131951BF9500D5358A /* OFSettings_INIFile.m */, 4BF1BCC411C9663F0025511F /* OFSHA1Hash.h */, 4BF1BCC511C9663F0025511F /* OFSHA1Hash.m */, + 4B3B03E919B3F70500F70C05 /* OFSHA256Hash.h */, + 4B3B03EA19B3F70500F70C05 /* OFSHA256Hash.m */, 4B141BA215FCDF74000C21A8 /* OFSortedList.h */, 4B141BA315FCDF74000C21A8 /* OFSortedList.m */, 4B0256E2172B60400062B5F1 /* OFStdIOStream.h */, 4B0256E3172B60400062B5F1 /* OFStdIOStream.m */, 4B67997D1099E7C50041064A /* OFStream.h */, @@ -1599,10 +1605,11 @@ 4B3D23D31337FCB000DD29B8 /* OFSeekableStream.h in Headers */, 4B989C2F13771A3700109A30 /* OFSerialization.h in Headers */, 4B39844213D3A24600E6F825 /* OFSet.h in Headers */, 4B8385181951BF9500D5358A /* OFSettings.h in Headers */, 4B3D23D41337FCB000DD29B8 /* OFSHA1Hash.h in Headers */, + 4B3B03EB19B3F70500F70C05 /* OFSHA256Hash.h in Headers */, 4B141BA415FCDF74000C21A8 /* OFSortedList.h in Headers */, 4B0256E4172B60400062B5F1 /* OFStdIOStream.h in Headers */, 4B3D23D51337FCB000DD29B8 /* OFStream.h in Headers */, 4B3D23D71337FCB000DD29B8 /* OFStreamSocket.h in Headers */, 4B3D23D81337FCB000DD29B8 /* OFString.h in Headers */, @@ -1973,10 +1980,11 @@ 4B39844313D3A24600E6F825 /* OFSet.m in Sources */, 4BA85BCF140ECCE800E91D51 /* OFSet_hashtable.m in Sources */, 4B8385191951BF9500D5358A /* OFSettings.m in Sources */, 4B8385171951BF9500D5358A /* OFSettings_INIFile.m in Sources */, 4B3D23A21337FC0D00DD29B8 /* OFSHA1Hash.m in Sources */, + 4B3B03EC19B3F70500F70C05 /* OFSHA256Hash.m in Sources */, 4B141BA515FCDF74000C21A8 /* OFSortedList.m in Sources */, 4B0256E5172B60400062B5F1 /* OFStdIOStream.m in Sources */, 4B3D23A31337FC0D00DD29B8 /* OFStream.m in Sources */, 4B3D23A51337FC0D00DD29B8 /* OFStreamSocket.m in Sources */, 4B3D23A61337FC0D00DD29B8 /* OFString.m in Sources */, Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -42,10 +42,11 @@ ${OFPROCESS_M} \ OFRunLoop.m \ OFSeekableStream.m \ OFSet.m \ OFSHA1Hash.m \ + OFSHA256Hash.m \ OFSortedList.m \ OFStdIOStream.m \ OFStream.m \ OFString.m \ OFString+Hashing.m \ Index: src/OFDataArray+Hashing.h ================================================================== --- src/OFDataArray+Hashing.h +++ src/OFDataArray+Hashing.h @@ -38,6 +38,14 @@ * @brief Returns the SHA-1 hash of the data array as an autoreleased OFString. * * @return The SHA-1 hash of the data array as an autoreleased OFString */ - (OFString*)SHA1Hash; + +/*! + * @brief Returns the SHA-256 hash of the data array as an autoreleased + * OFString. + * + * @return The SHA-256 hash of the data array as an autoreleased OFString + */ +- (OFString*)SHA256Hash; @end Index: src/OFDataArray+Hashing.m ================================================================== --- src/OFDataArray+Hashing.m +++ src/OFDataArray+Hashing.m @@ -19,10 +19,11 @@ #import "OFDataArray.h" #import "OFString.h" #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" +#import "OFSHA256Hash.h" int _OFDataArray_Hashing_reference; @implementation OFDataArray (Hashing) - (OFString*)OF_hashAsStringWithHash: (Class )hashClass @@ -62,6 +63,11 @@ - (OFString*)SHA1Hash { return [self OF_hashAsStringWithHash: [OFSHA1Hash class]]; } + +- (OFString*)SHA256Hash +{ + return [self OF_hashAsStringWithHash: [OFSHA256Hash class]]; +} @end Index: src/OFMD5Hash.m ================================================================== --- src/OFMD5Hash.m +++ src/OFMD5Hash.m @@ -25,11 +25,11 @@ #define F(a, b, c) (((a) & (b)) | (~(a) & (c))) #define G(a, b, c) (((a) & (c)) | ((b) & ~(c))) #define H(a, b, c) ((a) ^ (b) ^ (c)) #define I(a, b, c) ((b) ^ ((a) | ~(c))) -static const uint32_t sinTable[] = { +static const uint32_t table[] = { 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, @@ -90,11 +90,11 @@ const uint_fast8_t c = (a + 2) & 3; \ const uint_fast8_t d = (a + 3) & 3; \ const uint_fast8_t r = rotateBits[(i % 4) + (i / 16) * 4]; \ \ new[a] += f(new[b], new[c], new[d]) + \ - buffer[wordOrder[i]] + sinTable[i]; \ + buffer[wordOrder[i]] + table[i]; \ new[a] = OF_ROL(new[a], r); \ new[a] += new[b]; \ } for (; i < 16; i++) Index: src/OFSHA1Hash.h ================================================================== --- src/OFSHA1Hash.h +++ src/OFSHA1Hash.h @@ -17,11 +17,11 @@ #import "OFHash.h" /*! * @class OFSHA1Hash OFSHA1Hash.h ObjFW/OFSHA1Hash.h * - * @brief A class which provides functions to create an SHA1 hash. + * @brief A class which provides functions to create an SHA-1 hash. */ @interface OFSHA1Hash: OFObject { uint32_t _state[5]; uint64_t _bits; ADDED src/OFSHA256Hash.h Index: src/OFSHA256Hash.h ================================================================== --- src/OFSHA256Hash.h +++ src/OFSHA256Hash.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFHash.h" + +/*! + * @class OFSHA256Hash OFSHA256Hash.h ObjFW/OFSHA256Hash.h + * + * @brief A class which provides functions to create an SHA-256 hash. + */ +@interface OFSHA256Hash: OFObject +{ + uint32_t _state[8]; + uint64_t _bits; + union { + uint8_t bytes[64]; + uint32_t words[64]; + } _buffer; + size_t _bufferLength; + bool _calculated; +} +@end ADDED src/OFSHA256Hash.m Index: src/OFSHA256Hash.m ================================================================== --- src/OFSHA256Hash.m +++ src/OFSHA256Hash.m @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include + +#import "OFSHA256Hash.h" + +#import "OFHashAlreadyCalculatedException.h" + +static const uint32_t table[] = { + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 +}; + +static void +byteSwapVectorIfLE(uint32_t *vector, uint_fast8_t length) +{ + uint_fast8_t i; + + for (i = 0; i < length; i++) + vector[i] = OF_BSWAP32_IF_LE(vector[i]); +} + +static void +processBlock(uint32_t *state, uint32_t *buffer) +{ + uint32_t new[8]; + uint_fast8_t i; + + new[0] = state[0]; + new[1] = state[1]; + new[2] = state[2]; + new[3] = state[3]; + new[4] = state[4]; + new[5] = state[5]; + new[6] = state[6]; + new[7] = state[7]; + + byteSwapVectorIfLE(buffer, 16); + + for (i = 16; i < 64; i++) { + uint32_t tmp; + + tmp = buffer[i - 2]; + buffer[i] = (OF_ROR(tmp, 17) ^ OF_ROR(tmp, 19) ^ (tmp >> 10)) + + buffer[i - 7]; + tmp = buffer[i - 15]; + buffer[i] += (OF_ROR(tmp, 7) ^ OF_ROR(tmp, 18) ^ (tmp >> 3)) + + buffer[i - 16]; + } + + for (i = 0; i < 64; i++) { + uint32_t tmp1 = new[7] + (OF_ROR(new[4], 6) ^ + OF_ROR(new[4], 11) ^ OF_ROR(new[4], 25)) + + ((new[4] & (new[5] ^ new[6])) ^ new[6]) + + table[i] + buffer[i]; + uint32_t tmp2 = (OF_ROR(new[0], 2) ^ OF_ROR(new[0], 13) ^ + OF_ROR(new[0], 22)) + + ((new[0] & (new[1] | new[2])) | (new[1] & new[2])); + + new[7] = new[6]; + new[6] = new[5]; + new[5] = new[4]; + new[4] = new[3] + tmp1; + new[3] = new[2]; + new[2] = new[1]; + new[1] = new[0]; + new[0] = tmp1 + tmp2; + } + + state[0] += new[0]; + state[1] += new[1]; + state[2] += new[2]; + state[3] += new[3]; + state[4] += new[4]; + state[5] += new[5]; + state[6] += new[6]; + state[7] += new[7]; +} + +@implementation OFSHA256Hash ++ (size_t)digestSize +{ + return 32; +} + ++ (size_t)blockSize +{ + return 64; +} + ++ (instancetype)hash +{ + return [[[self alloc] init] autorelease]; +} + +- init +{ + self = [super init]; + + _state[0] = 0x6A09E667; + _state[1] = 0xBB67AE85; + _state[2] = 0x3C6EF372; + _state[3] = 0xA54FF53A; + _state[4] = 0x510E527F; + _state[5] = 0x9B05688C; + _state[6] = 0x1F83D9AB; + _state[7] = 0x5BE0CD19; + + return self; +} + +- (void)updateWithBuffer: (const void*)buffer_ + length: (size_t)length +{ + const uint8_t *buffer = buffer_; + + if (_calculated) + @throw [OFHashAlreadyCalculatedException + exceptionWithHash: self]; + + _bits += (length * 8); + + while (length > 0) { + size_t min = 64 - _bufferLength; + + if (min > length) + min = length; + + memcpy(_buffer.bytes + _bufferLength, buffer, min); + _bufferLength += min; + + buffer += min; + length -= min; + + if (_bufferLength == 64) { + processBlock(_state, _buffer.words); + _bufferLength = 0; + } + } +} + +- (const uint8_t*)digest +{ + if (_calculated) + return (const uint8_t*)_state; + + _buffer.bytes[_bufferLength] = 0x80; + memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1); + + if (_bufferLength >= 56) { + processBlock(_state, _buffer.words); + memset(_buffer.bytes, 0, 64); + } + + _buffer.words[14] = OF_BSWAP32_IF_LE((uint32_t)(_bits >> 32)); + _buffer.words[15] = OF_BSWAP32_IF_LE((uint32_t)(_bits & 0xFFFFFFFF)); + + processBlock(_state, _buffer.words); + memset(&_buffer, 0, sizeof(_buffer)); + byteSwapVectorIfLE(_state, 8); + _calculated = true; + + return (const uint8_t*)_state; +} + +- (bool)isCalculated +{ + return _calculated; +} +@end Index: src/OFString+Hashing.h ================================================================== --- src/OFString+Hashing.h +++ src/OFString+Hashing.h @@ -31,11 +31,18 @@ * @return The MD5 hash of the string as an autoreleased OFString */ - (OFString*)MD5Hash; /*! - * @brief Returns the SHA1 hash of the string as an autoreleased OFString. + * @brief Returns the SHA-1 hash of the string as an autoreleased OFString. * - * @return The SHA1 hash of the string as an autoreleased OFString + * @return The SHA-1 hash of the string as an autoreleased OFString */ - (OFString*)SHA1Hash; + +/*! + * @brief Returns the SHA-256 hash of the string as an autoreleased OFString. + * + * @return The SHA-256 hash of the string as an autoreleased OFString + */ +- (OFString*)SHA256Hash; @end Index: src/OFString+Hashing.m ================================================================== --- src/OFString+Hashing.m +++ src/OFString+Hashing.m @@ -18,10 +18,11 @@ #import "OFString.h" #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" +#import "OFSHA256Hash.h" int _OFString_Hashing_reference; @implementation OFString (Hashing) - (OFString*)OF_hashAsStringWithHash: (Class )hashClass @@ -61,6 +62,11 @@ - (OFString*)SHA1Hash { return [self OF_hashAsStringWithHash: [OFSHA1Hash class]]; } + +- (OFString*)SHA256Hash +{ + return [self OF_hashAsStringWithHash: [OFSHA256Hash class]]; +} @end Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -72,10 +72,11 @@ #endif #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" +#import "OFSHA256Hash.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" #import "OFXMLAttribute.h" #import "OFXMLCharacters.h" Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -33,11 +33,12 @@ ${USE_SRCS_THREADS} \ ${OFHTTPCLIENTTESTS_M} SRCS_FILES = OFINIFileTests.m \ OFMD5HashTests.m \ OFSerializationTests.m \ - OFSHA1HashTests.m + OFSHA1HashTests.m \ + OFSHA256HashTests.m SRCS_PLUGINS = OFPluginTests.m SRCS_SOCKETS = OFTCPSocketTests.m \ OFUDPSocketTests.m SRCS_THREADS = OFThreadTests.m Index: tests/OFDataArrayTests.m ================================================================== --- tests/OFDataArrayTests.m +++ tests/OFDataArrayTests.m @@ -102,10 +102,13 @@ !memcmp([array[0] items], "abcde", 5)) TEST(@"-[MD5Hash]", [[array[0] MD5Hash] isEqual: [@"abcde" MD5Hash]]) TEST(@"-[SHA1Hash]", [[array[0] SHA1Hash] isEqual: [@"abcde" SHA1Hash]]) + + TEST(@"-[SHA256Hash]", [[array[0] SHA256Hash] + isEqual: [@"abcde" SHA256Hash]]) TEST(@"-[stringByBase64Encoding]", [[array[0] stringByBase64Encoding] isEqual: @"YWJjZGU="]) TEST(@"+[dataArrayWithBase64EncodedString:]", Index: tests/OFSHA1HashTests.m ================================================================== --- tests/OFSHA1HashTests.m +++ tests/OFSHA1HashTests.m @@ -25,11 +25,11 @@ #import "OFHashAlreadyCalculatedException.h" #import "TestsAppDelegate.h" -static OFString *module = @"OFHash"; +static OFString *module = @"OFSHA1Hash"; const uint8_t testfile_sha1[20] = "\xC9\x9A\xB8\x7E\x1E\xC8\xEC\x65\xD5\xEB\xE4\x2E\x0D\xA6\x80\x96\xF5" "\x94\xE7\x17"; ADDED tests/OFSHA256HashTests.m Index: tests/OFSHA256HashTests.m ================================================================== --- tests/OFSHA256HashTests.m +++ tests/OFSHA256HashTests.m @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include + +#import "OFSHA256Hash.h" +#import "OFString.h" +#import "OFFile.h" +#import "OFAutoreleasePool.h" + +#import "OFHashAlreadyCalculatedException.h" + +#import "TestsAppDelegate.h" + +static OFString *module = @"OFSHA256Hash"; + +const uint8_t testfile_sha256[32] = + "\x1A\x02\xD6\x46\xF5\xA6\xBA\xAA\xFF\x7F\xD5\x87\xBA\xC3\xF6\xC6\xB5" + "\x67\x93\x8F\x0F\x44\x90\xB8\xF5\x35\x89\xF0\x5A\x23\x7F\x69"; + +@implementation TestsAppDelegate (SHA256HashTests) +- (void)SHA256HashTests +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFSHA256Hash *sha256; + OFFile *f = [OFFile fileWithPath: @"testfile.bin" + mode: @"rb"]; + + TEST(@"+[hash]", (sha256 = [OFSHA256Hash hash])) + + while (![f isAtEndOfStream]) { + char buf[64]; + size_t len = [f readIntoBuffer: buf + length: 64]; + [sha256 updateWithBuffer: buf + length: len]; + } + [f close]; + + TEST(@"-[digest]", !memcmp([sha256 digest], testfile_sha256, 32)) + + EXPECT_EXCEPTION(@"Detect invalid call of " + @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, + [sha256 updateWithBuffer: "" + length: 1]) + + [pool drain]; +} +@end Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -537,10 +537,15 @@ TEST(@"-[MD5Hash]", [[@"asdfoobar" MD5Hash] isEqual: @"184dce2ec49b5422c7cfd8728864db4c"]) TEST(@"-[SHA1Hash]", [[@"asdfoobar" SHA1Hash] isEqual: @"f5f81ac0a8b5cbfdc4585ec1ad32e7b3a12b9b49"]) + + TEST(@"-[SHA256Hash]", [[@"asdfoobar" SHA256Hash] + isEqual: + @"28e65b1dcd7f6ce2ea6277b15f87b913628b5500bf7913a2bbf4cedcfa1215f6" + ]) TEST(@"-[stringByURLEncoding]", [[@"foo\"ba'_~$" stringByURLEncoding] isEqual: @"foo%22ba%27_%7E$"]) TEST(@"-[stringByURLDecoding]", Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -141,10 +141,14 @@ @end @interface TestsAppDelegate (OFSHA1HashTests) - (void)SHA1HashTests; @end + +@interface TestsAppDelegate (OFSHA256HashTests) +- (void)SHA256HashTests; +@end @interface TestsAppDelegate (OFStreamTests) - (void)streamTests; @end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -339,10 +339,11 @@ [self numberTests]; [self streamTests]; #ifdef OF_HAVE_FILES [self MD5HashTests]; [self SHA1HashTests]; + [self SHA256HashTests]; [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self TCPSocketTests]; [self UDPSocketTests];