Add internal md5 and sha1 message digests

pull/128/merge
Nils Maier 2013-09-20 22:39:33 +02:00
parent a1deb0e9f1
commit 38bdea4e06
9 changed files with 679 additions and 1 deletions

View File

@ -453,6 +453,9 @@ else
if test "x$have_openssl" = "xyes"; then
AC_DEFINE([USE_OPENSSL_MD], [1], [What message digest implementation to use])
use_md="openssl"
else
AC_DEFINE([USE_INTERNAL_MD], [1], [What message digest implementation to use])
use_md="internal"
fi
fi
fi
@ -481,6 +484,7 @@ AM_CONDITIONAL([HAVE_LIBGCRYPT], [ test "x$have_libgcrypt" = "xyes" ])
AM_CONDITIONAL([USE_LIBGCRYPT_MD], [ test "x$use_md" = "xlibgcrypt"])
AM_CONDITIONAL([HAVE_OPENSSL], [ test "x$have_openssl" = "xyes" ])
AM_CONDITIONAL([USE_OPENSSL_MD], [ test "x$use_md" = "xopenssl"])
AM_CONDITIONAL([USE_INTERNAL_MD], [ test "x$use_md" = "xinternal"])
if test "x$use_md" != "x"; then
AC_DEFINE([ENABLE_MESSAGE_DIGEST], [1],
@ -969,7 +973,7 @@ echo "Epoll: $have_epoll"
echo "Bittorrent: $enable_bittorrent"
echo "Metalink: $enable_metalink"
echo "XML-RPC: $enable_xml_rpc"
echo "Message Digest: $enable_message_digest"
echo "Message Digest: $use_md"
echo "WebSocket: $enable_websocket"
echo "Libaria2: $enable_libaria2"
if test "x$enable_libaria2" = "xyes"; then

View File

@ -0,0 +1,110 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2013 Nils Maier
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "MessageDigestImpl.h"
#include "md5.h"
#include "sha1.h"
namespace aria2 {
namespace {
template<size_t dlen,
typename ctx_t,
int (*init_fn)(ctx_t**),
void (*update_fn)(ctx_t*, const void*, size_t),
void (*final_fn)(ctx_t*, uint8_t*),
void (*free_fn)(ctx_t**)>
class MessageDigestBase : public MessageDigestImpl {
public:
MessageDigestBase() { reset(); }
virtual ~MessageDigestBase() {
free_fn(&ctx_);
}
static size_t length() {
return dlen;
}
virtual size_t getDigestLength() const CXX11_OVERRIDE {
return dlen;
}
virtual void reset() CXX11_OVERRIDE {
printf("hash-%d\n", dlen);
init_fn(&ctx_);
}
virtual void update(const void* data, size_t length) CXX11_OVERRIDE {
auto bytes = reinterpret_cast<const char*>(data);
while (length) {
size_t l = std::min(length, (size_t)std::numeric_limits<uint32_t>::max());
update_fn(ctx_, bytes, l);
length -= l;
bytes += l;
}
}
virtual void digest(unsigned char* md) CXX11_OVERRIDE {
final_fn(ctx_, md);
}
private:
ctx_t* ctx_;
};
typedef MessageDigestBase<MD5_LENGTH,
struct MD5_CTX,
MD5_Init,
MD5_Update,
MD5_Final,
MD5_Free>
MessageDigestMD5;
typedef MessageDigestBase<SHA1_LENGTH,
SHA1_CTX,
SHA1_Init,
SHA1_Update,
SHA1_Final,
SHA1_Free>
MessageDigestSHA1;
} // namespace
std::unique_ptr<MessageDigestImpl> MessageDigestImpl::sha1()
{
return std::unique_ptr<MessageDigestImpl>(new MessageDigestSHA1());
}
MessageDigestImpl::hashes_t MessageDigestImpl::hashes = {
{ "sha-1", make_hi<MessageDigestSHA1>() },
{ "md5", make_hi<MessageDigestMD5>() },
};
} // namespace aria2

View File

@ -333,6 +333,10 @@ if USE_WINDOWS_MD
SRCS += WinMessageDigestImpl.cc
endif # USE_WINDOWS_MD
if USE_INTERNAL_MD
SRCS += InternalMessageDigestImpl.cc sha1.c md5.c
endif # USE_WINDOWS_MD
if HAVE_LIBGNUTLS
SRCS += LibgnutlsTLSContext.cc LibgnutlsTLSContext.h \
LibgnutlsTLSSession.cc LibgnutlsTLSSession.h

311
src/md5.c Normal file
View File

@ -0,0 +1,311 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* (This is a heavily cut-down "BSD license".)
*
* This differs from Colin Plumb's older public domain implementation in that
* no exactly 32-bit integer data type is required (any 32-bit or wider
* unsigned integer data type will do), there's no compile-time endianness
* configuration, and the function prototypes match OpenSSL's. No code from
* Colin Plumb's implementation has been reused; this comment merely compares
* the properties of the two independent implementations.
*
* The primary goals of this implementation are portability and ease of use.
* It is meant to be fast, but not as fast as possible. Some known
* optimizations are not included to reduce source code size and avoid
* compile-time configuration.
*/
#include "md5.h"
#include <stdlib.h>
#include <string.h>
struct MD5_CTX {
size_t lo, hi;
size_t a, b, c, d;
uint8_t buffer[64];
size_t block[16];
};
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
/*
* The MD5 transformation for all four rounds.
*/
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them
* in a properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned
* memory accesses is just an optimization. Nothing will break if it
* doesn't work.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) \
(*(size_t *)&ptr[(n) * 4])
#define GET(n) \
SET(n)
#else
#define SET(n) \
(ctx->block[(n)] = \
(size_t)ptr[(n) * 4] | \
((size_t)ptr[(n) * 4 + 1] << 8) | \
((size_t)ptr[(n) * 4 + 2] << 16) | \
((size_t)ptr[(n) * 4 + 3] << 24))
#define GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update
* the bit counters. There are no alignment requirements.
*/
static const void *body(struct MD5_CTX *ctx, const void *data, size_t size)
{
const uint8_t *ptr;
size_t a, b, c, d;
size_t saved_a, saved_b, saved_c, saved_d;
ptr = data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do {
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
int MD5_Init(struct MD5_CTX **ctx)
{
*ctx = malloc(sizeof(struct MD5_CTX));
if (!*ctx) {
return 0;
}
(*ctx)->a = 0x67452301;
(*ctx)->b = 0xefcdab89;
(*ctx)->c = 0x98badcfe;
(*ctx)->d = 0x10325476;
(*ctx)->lo = 0;
(*ctx)->hi = 0;
return 1;
}
void MD5_Update(struct MD5_CTX *ctx, const void *data, size_t size)
{
size_t saved_lo;
size_t used, free;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used) {
free = 64 - used;
if (size < free) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, free);
data = (unsigned char *)data + free;
size -= free;
body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = body(ctx, data, size & ~(size_t)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
void MD5_Final(struct MD5_CTX *ctx, unsigned char* result)
{
size_t used, free;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
free = 64 - used;
if (free < 8) {
memset(&ctx->buffer[used], 0, free);
body(ctx, ctx->buffer, 64);
used = 0;
free = 64;
}
memset(&ctx->buffer[used], 0, free - 8);
ctx->lo <<= 3;
ctx->buffer[56] = ctx->lo;
ctx->buffer[57] = ctx->lo >> 8;
ctx->buffer[58] = ctx->lo >> 16;
ctx->buffer[59] = ctx->lo >> 24;
ctx->buffer[60] = ctx->hi;
ctx->buffer[61] = ctx->hi >> 8;
ctx->buffer[62] = ctx->hi >> 16;
ctx->buffer[63] = ctx->hi >> 24;
body(ctx, ctx->buffer, 64);
result[0] = ctx->a;
result[1] = ctx->a >> 8;
result[2] = ctx->a >> 16;
result[3] = ctx->a >> 24;
result[4] = ctx->b;
result[5] = ctx->b >> 8;
result[6] = ctx->b >> 16;
result[7] = ctx->b >> 24;
result[8] = ctx->c;
result[9] = ctx->c >> 8;
result[10] = ctx->c >> 16;
result[11] = ctx->c >> 24;
result[12] = ctx->d;
result[13] = ctx->d >> 8;
result[14] = ctx->d >> 16;
result[15] = ctx->d >> 24;
}
void MD5_Free(struct MD5_CTX** ctx) {
if (!ctx || !*ctx) {
return;
}
free(*ctx);
*ctx = NULL;
}

47
src/md5.h Normal file
View File

@ -0,0 +1,47 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* See md5.c for more information.
*/
#ifndef INTERNAL_MD5_H
#define INTERNAL_MD5_H
#include <sys/types.h>
#include <stdint.h>
struct MD5_CTX;
#define MD5_LENGTH 16
#ifdef __cplusplus
extern "C" {
#endif
int MD5_Init(struct MD5_CTX **ctx);
void MD5_Update(struct MD5_CTX *ctx, const void *data, size_t size);
void MD5_Final(struct MD5_CTX *ctx, uint8_t *result);
void MD5_Free(struct MD5_CTX **ctx);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INTERNAL_MD5_H */

160
src/sha1.c Normal file
View File

@ -0,0 +1,160 @@
/* This code is public-domain - it is based on libcrypt
* placed in the public domain by Wei Dai and other contributors.
*/
#include "sha1.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define BLOCK_LENGTH 64
union _buffer {
uint8_t b[BLOCK_LENGTH];
uint32_t w[BLOCK_LENGTH/4];
};
union _state {
uint8_t b[SHA1_LENGTH];
uint32_t w[SHA1_LENGTH/4];
};
struct SHA1_CTX {
union _buffer buffer;
uint8_t bufferOffset;
union _state state;
uint32_t byteCount;
uint8_t keyBuffer[BLOCK_LENGTH];
uint8_t innerHash[SHA1_LENGTH];
};
#define SHA1_K0 0x5a827999
#define SHA1_K20 0x6ed9eba1
#define SHA1_K40 0x8f1bbcdc
#define SHA1_K60 0xca62c1d6
const uint8_t sha1InitState[] = {
0x01,0x23,0x45,0x67, // H0
0x89,0xab,0xcd,0xef, // H1
0xfe,0xdc,0xba,0x98, // H2
0x76,0x54,0x32,0x10, // H3
0xf0,0xe1,0xd2,0xc3 // H4
};
static uint32_t sha1_rol32(uint32_t number, uint8_t bits) {
return ((number << bits) | (number >> (32-bits)));
}
static void sha1_hashBlock(struct SHA1_CTX *s) {
uint8_t i;
uint32_t a,b,c,d,e,t;
a=s->state.w[0];
b=s->state.w[1];
c=s->state.w[2];
d=s->state.w[3];
e=s->state.w[4];
for (i=0; i<80; i++) {
if (i>=16) {
t = s->buffer.w[(i+13)&15] ^ s->buffer.w[(i+8)&15] ^ s->buffer.w[(i+2)&15] ^ s->buffer.w[i&15];
s->buffer.w[i&15] = sha1_rol32(t,1);
}
if (i<20) {
t = (d ^ (b & (c ^ d))) + SHA1_K0;
} else if (i<40) {
t = (b ^ c ^ d) + SHA1_K20;
} else if (i<60) {
t = ((b & c) | (d & (b | c))) + SHA1_K40;
} else {
t = (b ^ c ^ d) + SHA1_K60;
}
t+=sha1_rol32(a,5) + e + s->buffer.w[i&15];
e=d;
d=c;
c=sha1_rol32(b,30);
b=a;
a=t;
}
s->state.w[0] += a;
s->state.w[1] += b;
s->state.w[2] += c;
s->state.w[3] += d;
s->state.w[4] += e;
}
static void sha1_addUncounted(struct SHA1_CTX *s, uint8_t data) {
s->buffer.b[s->bufferOffset ^ 3] = data;
s->bufferOffset++;
if (s->bufferOffset == BLOCK_LENGTH) {
sha1_hashBlock(s);
s->bufferOffset = 0;
}
}
static void sha1_writebyte(struct SHA1_CTX *s, uint8_t data) {
++s->byteCount;
sha1_addUncounted(s, data);
}
static void sha1_pad(struct SHA1_CTX *s) {
// Implement SHA-1 padding (fips180-2 §5.1.1)
// Pad with 0x80 followed by 0x00 until the end of the block
sha1_addUncounted(s, 0x80);
while (s->bufferOffset != 56) sha1_addUncounted(s, 0x00);
// Append length in the last 8 bytes
sha1_addUncounted(s, 0); // We're only using 32 bit lengths
sha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths
sha1_addUncounted(s, 0); // So zero pad the top bits
sha1_addUncounted(s, s->byteCount >> 29); // Shifting to multiply by 8
sha1_addUncounted(s, s->byteCount >> 21); // as SHA-1 supports bitstreams as well as
sha1_addUncounted(s, s->byteCount >> 13); // byte.
sha1_addUncounted(s, s->byteCount >> 5);
sha1_addUncounted(s, s->byteCount << 3);
}
int SHA1_Init(struct SHA1_CTX **s) {
*s = malloc(sizeof(struct SHA1_CTX));
if (!*s) {
return 0;
}
memcpy((*s)->state.b, sha1InitState, SHA1_LENGTH);
(*s)->byteCount = 0;
(*s)->bufferOffset = 0;
return 1;
}
void SHA1_Update(struct SHA1_CTX *s, const void *data, size_t len) {
const uint8_t *bytes = data;
for (;len--;) sha1_writebyte(s, *bytes++);
}
void SHA1_Final(struct SHA1_CTX *s, unsigned char* result) {
int i;
// Pad to complete the last block
sha1_pad(s);
// Swap byte order back
for (i=0; i<5; i++) {
uint32_t a,b;
a=s->state.w[i];
b=a<<24;
b|=(a<<8) & 0x00ff0000;
b|=(a>>8) & 0x0000ff00;
b|=a>>24;
s->state.w[i]=b;
}
// Return pointer to hash (20 characters)
memcpy(result, s->state.b, sizeof(s->state.b));
}
void SHA1_Free(struct SHA1_CTX** s) {
if (!s || !*s) {
return;
}
free(*s);
*s = NULL;
}

28
src/sha1.h Normal file
View File

@ -0,0 +1,28 @@
/* This code is public-domain - it is based on libcrypt
* placed in the public domain by Wei Dai and other contributors.
*/
#ifndef INTERNAL_SHA1_H
#define INTERNAL_SHA1_H
#include <sys/types.h>
#include <stdint.h>
#define SHA1_LENGTH 20
struct SHA1_CTX;
#ifdef __cplusplus
extern "C" {
#endif
int SHA1_Init(struct SHA1_CTX **s);
void SHA1_Update(struct SHA1_CTX *s, const void *data, size_t len);
void SHA1_Final(struct SHA1_CTX *s, uint8_t *result);
void SHA1_Free(struct SHA1_CTX **s);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INTERNAL_SHA1_H */

View File

@ -654,14 +654,20 @@ void HttpResponseTest::testGetDigest()
"MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
std::vector<Checksum> result;
httpResponse.getDigest(result);
#ifdef USE_INTERNAL_MD
CPPUNIT_ASSERT_EQUAL((size_t)2, result.size());
#else
CPPUNIT_ASSERT_EQUAL((size_t)3, result.size());
#endif
Checksum c = result[0];
#ifndef USE_INTERNAL_MD
CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), c.getHashType());
CPPUNIT_ASSERT_EQUAL(std::string("f83f271ae773dc6fe4a6454a41e0eb237c43e7bbf451e426cc60993a4d379ec5"),
util::toHex(c.getDigest()));
c = result[1];
#endif
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c.getHashType());
CPPUNIT_ASSERT_EQUAL(std::string("f36003f22b462ffa184390533c500d8989e9f681"),
util::toHex(c.getDigest()));

View File

@ -18,9 +18,11 @@ class MessageDigestTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END();
std::unique_ptr<MessageDigest> sha1_;
std::unique_ptr<MessageDigest> md5_;
public:
void setUp()
{
md5_ = MessageDigest::create("md5");
sha1_ = MessageDigest::sha1();
}
@ -37,6 +39,10 @@ CPPUNIT_TEST_SUITE_REGISTRATION( MessageDigestTest );
void MessageDigestTest::testDigest()
{
md5_->update("aria2", 5);
CPPUNIT_ASSERT_EQUAL(std::string("2c90cadbef42945f0dcff2b959977ff8"),
util::toHex(md5_->digest()));
sha1_->update("aria2", 5);
CPPUNIT_ASSERT_EQUAL(std::string("f36003f22b462ffa184390533c500d8989e9f681"),
util::toHex(sha1_->digest()));
@ -44,6 +50,7 @@ void MessageDigestTest::testDigest()
void MessageDigestTest::testSupports()
{
CPPUNIT_ASSERT(MessageDigest::supports("md5"));
CPPUNIT_ASSERT(MessageDigest::supports("sha-1"));
// Fails because sha1 is not valid name.
CPPUNIT_ASSERT(!MessageDigest::supports("sha1"));
@ -51,6 +58,7 @@ void MessageDigestTest::testSupports()
void MessageDigestTest::testGetDigestLength()
{
CPPUNIT_ASSERT_EQUAL((size_t)16, MessageDigest::getDigestLength("md5"));
CPPUNIT_ASSERT_EQUAL((size_t)20, MessageDigest::getDigestLength("sha-1"));
CPPUNIT_ASSERT_EQUAL((size_t)20, sha1_->getDigestLength());
}