diff --git a/ChangeLog b/ChangeLog index c4c738a3..4ee764ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,48 +1,57 @@ +2009-08-02 Damien Stuart + * Tweaks to digest code - added SHA384 and SHA512 to supported digests. + * Updated autoconf files to account or new headers and types recently added. + * Bumped libfko version to 0.63 and perl FKO module version to 0.23. + 2009-07-26 Michael Rash - * Implemented -s command line argument on the fwknop client command line - so that the IP "0.0.0.0" can be sent within an SPA packet. The fwknopd - server can wrap access requirements around this IP. - * Initial public release of fwknop-c-0.62. + * Implemented -s command line argument on the fwknop client command line + so that the IP "0.0.0.0" can be sent within an SPA packet. The fwknopd + server can wrap access requirements around this IP. + * Initial public release of fwknop-c-0.62. 2009-07-23 Michael Rash - * Added the --show-last and --no-save command line options to show the - command line used for the previous fwknop invocation, and to have the - fwknop client not save its command line arguments. - * Bug fix to force libfko to recalculate the random data embedded in the - the SPA packet after a random port is acquired via --rand-port or - --nat-rand-port. This is a precaution so that an attacker cannot guess - some of the internal SPA data based on the destination port number. + * Added the --show-last and --no-save command line options to show the + command line used for the previous fwknop invocation, and to have the + fwknop client not save its command line arguments. + * Bug fix to force libfko to recalculate the random data embedded in the + the SPA packet after a random port is acquired via --rand-port or + --nat-rand-port. This is a precaution so that an attacker cannot guess + some of the internal SPA data based on the destination port number. 2009-07-21 Michael Rash - * Got forward and local NAT modes working with the --nat-access, - --nat-local, --nat-port, and --nat-randport options. All NAT modes - are now passing the fwknop test suite. - * Added the --server-command option to build an SPA packet with a command - for the server to execute. - * Added the --fw-timeout option for client side timeouts to be specified. - * Added the --time-offset-plus and --time-offset-minus options to allow - the user to influence the timestamp associated with an SPA packet. - * Added the --rand-port option so that the SPA packet destination port can - be randomized. + * Got forward and local NAT modes working with the --nat-access, + --nat-local, --nat-port, and --nat-randport options. All NAT modes + are now passing the fwknop test suite. + * Added the --server-command option to build an SPA packet with a command + for the server to execute. + * Added the --fw-timeout option for client side timeouts to be specified. + * Added the --time-offset-plus and --time-offset-minus options to allow + the user to influence the timestamp associated with an SPA packet. + * Added the --rand-port option so that the SPA packet destination port can + be randomized. 2009-07-16 Michael Rash - * Added the ability to send SPA packets over valid HTTP requests with - the fwknop-c client. - * Added support for transmitting SPA packets over IPv6 via TCP and UDP - sockets, and also via HTTP. - * Added GnuPG 'hQ' base64 encoded prefix handling (this prefix is - stripped out of encrypted SPA packet data). - * Added hostname resolution support to the fwknop-c client if the SPA - server is specified as a hostname instead of an IP address. + * Added the ability to send SPA packets over valid HTTP requests with + the fwknop-c client. + * Added support for transmitting SPA packets over IPv6 via TCP and UDP + sockets, and also via HTTP. + * Added GnuPG 'hQ' base64 encoded prefix handling (this prefix is + stripped out of encrypted SPA packet data). + * Added hostname resolution support to the fwknop-c client if the SPA + server is specified as a hostname instead of an IP address. + +2008-05-24 Damien Stuart + * Added win32 direcory with Visual Studio 2008 solution and project files + for buildin on the Windows platform. 2008-12-21 Damien Stuart Build 0.0.0 alpha - * autogen.sh: created. - * autoconf/automake: Initial configuration created. + * autogen.sh: created. + * autoconf/automake: Initial configuration created. - Copyright 2001, 2002, 2003, 2004, 2005 g10 Code GmbH + Copyright 2009, Damien Stuart This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/configure.ac b/configure.ac index c5b10cb7..140f208a 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ dnl Process thie file with autoconf to produce the configure script AC_PREREQ(2.61) m4_define(my_package, [fwknop-c]) -m4_define(my_version, [0.62]) +m4_define(my_version, [0.63]) m4_define(my_bug_email, [dstuart@dstuart.org]) AC_INIT(my_package, my_version, my_bug_email) @@ -21,6 +21,7 @@ AC_GNU_SOURCE AC_PROG_CC AM_PROG_CC_C_O AC_PROG_CXX +AC_PROG_AWK AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S @@ -31,14 +32,18 @@ AC_PROG_LIBTOOL # Checks for header files. # AC_HEADER_STDC -AC_CHECK_HEADERS([ctype.h endian.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/byteorder.h sys/endian.h sys/socket.h sys/stat.h sys/time.h termios.h unistd.h]) +AC_HEADER_TIME + +AC_CHECK_HEADERS([ctype.h endian.h netdb.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/byteorder.h sys/endian.h sys/socket.h sys/stat.h sys/time.h termios.h unistd.h]) # Type checks. # AC_C_CONST AC_TYPE_OFF_T AC_TYPE_SIZE_T -AC_HEADER_TIME +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + AC_CHECK_SIZEOF(unsigned int) AC_CHECK_TYPES([uint8_t, uint32_t]) @@ -49,6 +54,7 @@ AC_C_BIGENDIAN AC_FUNC_MALLOC AC_FUNC_REALLOC AC_FUNC_STAT + AC_CHECK_FUNCS([bzero gettimeofday memmove memset socket strchr strcspn strdup strncasecmp strndup strrchr strspn]) AC_SEARCH_LIBS([socket], [socket]) diff --git a/doc/libfko.texi b/doc/libfko.texi index b29fd567..cd5439f8 100644 --- a/doc/libfko.texi +++ b/doc/libfko.texi @@ -381,6 +381,8 @@ are (in order of strength): @item FKO_DIGEST_MD5 @item FKO_DIGEST_SHA1 @item FKO_DIGEST_SHA256 (libfko default) +@item FKO_DIGEST_SHA384 +@item FKO_DIGEST_SHA512 @end table @end deftypevar diff --git a/fko/Makefile.am b/fko/Makefile.am index 5b315fcd..4cf43dfb 100644 --- a/fko/Makefile.am +++ b/fko/Makefile.am @@ -6,7 +6,7 @@ libfko_source_files = \ fko_decode.c fko_encryption.c fko_error.c fko_funcs.c fko_message.c \ fko_nat_access.c fko_rand_value.c fko_server_auth.c fko.h fko_limits.h \ fko_timestamp.c fko_user.c fko_util.h md5.c md5.h \ - rijndael.c rijndael.h sha1.c sha256.c sha.h strlcat.c \ + rijndael.c rijndael.h sha1.c sha1.h sha2.c sha2.h strlcat.c \ strlcpy.c fko_state.h fko_context.h gpgme_funcs.c gpgme_funcs.h libfko_la_SOURCES = $(libfko_source_files) diff --git a/fko/digest.c b/fko/digest.c index d3f0a415..1af081f7 100644 --- a/fko/digest.c +++ b/fko/digest.c @@ -27,9 +27,10 @@ /* Convert a raw digest into its hex string representation. */ void -digest_to_hex(char *out, unsigned char *in, int size) +digest_to_hex(char *out, unsigned char *in, size_t size) { - int i; + size_t i; + for(i=0; idigest_type = FKO_DIGEST_MD5; break; - case MD_B64_SIZE(SHA1_DIGESTSIZE): + case SHA1_B64_LENGTH: ctx->digest_type = FKO_DIGEST_SHA1; break; - case MD_B64_SIZE(SHA256_DIGESTSIZE): + case SHA256_B64_LENGTH: ctx->digest_type = FKO_DIGEST_SHA256; break; + case SHA384_B64_LENGTH: + ctx->digest_type = FKO_DIGEST_SHA384; + break; + + case SHA512_B64_LENGTH: + ctx->digest_type = FKO_DIGEST_SHA512; + break; + default: /* Invalid or unsupported digest */ return(FKO_ERROR_INVALID_DIGEST_TYPE); } @@ -108,6 +116,14 @@ fko_decode_spa_data(fko_ctx_t ctx) sha256_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); break; + case FKO_DIGEST_SHA384: + sha384_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + break; + + case FKO_DIGEST_SHA512: + sha512_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + break; + } /* We give up here if the computed digest does not match the diff --git a/fko/fko_digest.c b/fko/fko_digest.c index c9f89fd0..d8a609e5 100644 --- a/fko/fko_digest.c +++ b/fko/fko_digest.c @@ -82,7 +82,7 @@ fko_set_spa_digest(fko_ctx_t ctx) switch(ctx->digest_type) { case FKO_DIGEST_MD5: - md = malloc(MD_HEX_SIZE(MD5_DIGESTSIZE)+1); + md = malloc(MD_HEX_SIZE(MD5_DIGEST_LENGTH)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); @@ -91,7 +91,7 @@ fko_set_spa_digest(fko_ctx_t ctx) break; case FKO_DIGEST_SHA1: - md = malloc(MD_HEX_SIZE(SHA1_DIGESTSIZE)+1); + md = malloc(MD_HEX_SIZE(SHA1_DIGEST_LENGTH)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); @@ -100,7 +100,7 @@ fko_set_spa_digest(fko_ctx_t ctx) break; case FKO_DIGEST_SHA256: - md = malloc(MD_HEX_SIZE(SHA256_DIGESTSIZE)+1); + md = malloc(MD_HEX_SIZE(SHA256_DIGEST_LENGTH)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); @@ -108,6 +108,24 @@ fko_set_spa_digest(fko_ctx_t ctx) (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); break; + case FKO_DIGEST_SHA384: + md = malloc(MD_HEX_SIZE(SHA384_DIGEST_LENGTH)+1); + if(md == NULL) + return(FKO_ERROR_MEMORY_ALLOCATION); + + sha384_base64(md, + (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + break; + + case FKO_DIGEST_SHA512: + md = malloc(MD_HEX_SIZE(SHA512_DIGEST_LENGTH)+1); + if(md == NULL) + return(FKO_ERROR_MEMORY_ALLOCATION); + + sha512_base64(md, + (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + break; + default: return(FKO_ERROR_INVALID_DIGEST_TYPE); } diff --git a/fko/md5.h b/fko/md5.h index 3aa873dc..2d5f789c 100644 --- a/fko/md5.h +++ b/fko/md5.h @@ -32,7 +32,7 @@ #include "fko_common.h" -#define MD5_DIGESTSIZE 16 +#define MD5_DIGEST_LENGTH 16 typedef struct _MD5Context { uint32_t buf[4]; diff --git a/fko/sha1.c b/fko/sha1.c index 0554d033..a7cfba5d 100644 --- a/fko/sha1.c +++ b/fko/sha1.c @@ -16,7 +16,7 @@ * ***************************************************************************** */ -#include "sha.h" +#include "sha1.h" /* SHA f()-functions */ #define f1(x,y,z) ((x & y) | (~x & z)) @@ -62,13 +62,13 @@ void -sha1_transform(SHA_INFO *sha_info) +sha1_transform(SHA1_INFO *sha1_info) { int i; uint8_t *dp; uint32_t T, A, B, C, D, E, W[80], *WP; - dp = sha_info->data; + dp = sha1_info->data; #undef SWAP_DONE @@ -132,11 +132,11 @@ sha1_transform(SHA_INFO *sha_info) W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; W[i] = R32(W[i], 1); } - A = sha_info->digest[0]; - B = sha_info->digest[1]; - C = sha_info->digest[2]; - D = sha_info->digest[3]; - E = sha_info->digest[4]; + A = sha1_info->digest[0]; + B = sha1_info->digest[1]; + C = sha1_info->digest[2]; + D = sha1_info->digest[3]; + E = sha1_info->digest[4]; WP = W; #ifdef UNRAVEL FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); @@ -147,11 +147,11 @@ sha1_transform(SHA_INFO *sha_info) FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); - sha_info->digest[0] = T32(sha_info->digest[0] + E); - sha_info->digest[1] = T32(sha_info->digest[1] + T); - sha_info->digest[2] = T32(sha_info->digest[2] + A); - sha_info->digest[3] = T32(sha_info->digest[3] + B); - sha_info->digest[4] = T32(sha_info->digest[4] + C); + sha1_info->digest[0] = T32(sha1_info->digest[0] + E); + sha1_info->digest[1] = T32(sha1_info->digest[1] + T); + sha1_info->digest[2] = T32(sha1_info->digest[2] + A); + sha1_info->digest[3] = T32(sha1_info->digest[3] + B); + sha1_info->digest[4] = T32(sha1_info->digest[4] + C); #else /* !UNRAVEL */ #ifdef UNROLL_LOOPS FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); @@ -168,123 +168,123 @@ sha1_transform(SHA_INFO *sha_info) for (i = 40; i < 60; ++i) { FG(3); } for (i = 60; i < 80; ++i) { FG(4); } #endif /* !UNROLL_LOOPS */ - sha_info->digest[0] = T32(sha_info->digest[0] + A); - sha_info->digest[1] = T32(sha_info->digest[1] + B); - sha_info->digest[2] = T32(sha_info->digest[2] + C); - sha_info->digest[3] = T32(sha_info->digest[3] + D); - sha_info->digest[4] = T32(sha_info->digest[4] + E); + sha1_info->digest[0] = T32(sha1_info->digest[0] + A); + sha1_info->digest[1] = T32(sha1_info->digest[1] + B); + sha1_info->digest[2] = T32(sha1_info->digest[2] + C); + sha1_info->digest[3] = T32(sha1_info->digest[3] + D); + sha1_info->digest[4] = T32(sha1_info->digest[4] + E); #endif /* !UNRAVEL */ } /* initialize the SHA digest */ void -sha1_init(SHA_INFO *sha_info) +sha1_init(SHA1_INFO *sha1_info) { - sha_info->digest[0] = 0x67452301L; - sha_info->digest[1] = 0xefcdab89L; - sha_info->digest[2] = 0x98badcfeL; - sha_info->digest[3] = 0x10325476L; - sha_info->digest[4] = 0xc3d2e1f0L; - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; + sha1_info->digest[0] = 0x67452301L; + sha1_info->digest[1] = 0xefcdab89L; + sha1_info->digest[2] = 0x98badcfeL; + sha1_info->digest[3] = 0x10325476L; + sha1_info->digest[4] = 0xc3d2e1f0L; + sha1_info->count_lo = 0L; + sha1_info->count_hi = 0L; + sha1_info->local = 0; } /* update the SHA digest */ void -sha1_update(SHA_INFO *sha_info, uint8_t *buffer, int count) +sha1_update(SHA1_INFO *sha1_info, uint8_t *buffer, int count) { int i; uint32_t clo; - clo = T32(sha_info->count_lo + ((uint32_t) count << 3)); - if (clo < sha_info->count_lo) { - ++sha_info->count_hi; + clo = T32(sha1_info->count_lo + ((uint32_t) count << 3)); + if (clo < sha1_info->count_lo) { + ++sha1_info->count_hi; } - sha_info->count_lo = clo; - sha_info->count_hi += (uint32_t) count >> 29; - if (sha_info->local) { - i = SHA_BLOCKSIZE - sha_info->local; + sha1_info->count_lo = clo; + sha1_info->count_hi += (uint32_t) count >> 29; + if (sha1_info->local) { + i = SHA1_BLOCKSIZE - sha1_info->local; if (i > count) { i = count; } - memcpy(((uint8_t *) sha_info->data) + sha_info->local, buffer, i); + memcpy(((uint8_t *) sha1_info->data) + sha1_info->local, buffer, i); count -= i; buffer += i; - sha_info->local += i; - if (sha_info->local == SHA_BLOCKSIZE) { - sha1_transform(sha_info); + sha1_info->local += i; + if (sha1_info->local == SHA1_BLOCKSIZE) { + sha1_transform(sha1_info); } else { return; } } - while (count >= SHA_BLOCKSIZE) { - memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); - buffer += SHA_BLOCKSIZE; - count -= SHA_BLOCKSIZE; - sha1_transform(sha_info); + while (count >= SHA1_BLOCKSIZE) { + memcpy(sha1_info->data, buffer, SHA1_BLOCKSIZE); + buffer += SHA1_BLOCKSIZE; + count -= SHA1_BLOCKSIZE; + sha1_transform(sha1_info); } - memcpy(sha_info->data, buffer, count); - sha_info->local = count; + memcpy(sha1_info->data, buffer, count); + sha1_info->local = count; } void -sha1_transform_and_copy(unsigned char digest[20], SHA_INFO *sha_info) +sha1_transform_and_copy(unsigned char digest[20], SHA1_INFO *sha1_info) { - sha1_transform(sha_info); - digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); - digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); - digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); - digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); - digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); - digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); - digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); - digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); - digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); - digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); - digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); - digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); - digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); - digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); - digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); - digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); - digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); - digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); - digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); - digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); + sha1_transform(sha1_info); + digest[ 0] = (unsigned char) ((sha1_info->digest[0] >> 24) & 0xff); + digest[ 1] = (unsigned char) ((sha1_info->digest[0] >> 16) & 0xff); + digest[ 2] = (unsigned char) ((sha1_info->digest[0] >> 8) & 0xff); + digest[ 3] = (unsigned char) ((sha1_info->digest[0] ) & 0xff); + digest[ 4] = (unsigned char) ((sha1_info->digest[1] >> 24) & 0xff); + digest[ 5] = (unsigned char) ((sha1_info->digest[1] >> 16) & 0xff); + digest[ 6] = (unsigned char) ((sha1_info->digest[1] >> 8) & 0xff); + digest[ 7] = (unsigned char) ((sha1_info->digest[1] ) & 0xff); + digest[ 8] = (unsigned char) ((sha1_info->digest[2] >> 24) & 0xff); + digest[ 9] = (unsigned char) ((sha1_info->digest[2] >> 16) & 0xff); + digest[10] = (unsigned char) ((sha1_info->digest[2] >> 8) & 0xff); + digest[11] = (unsigned char) ((sha1_info->digest[2] ) & 0xff); + digest[12] = (unsigned char) ((sha1_info->digest[3] >> 24) & 0xff); + digest[13] = (unsigned char) ((sha1_info->digest[3] >> 16) & 0xff); + digest[14] = (unsigned char) ((sha1_info->digest[3] >> 8) & 0xff); + digest[15] = (unsigned char) ((sha1_info->digest[3] ) & 0xff); + digest[16] = (unsigned char) ((sha1_info->digest[4] >> 24) & 0xff); + digest[17] = (unsigned char) ((sha1_info->digest[4] >> 16) & 0xff); + digest[18] = (unsigned char) ((sha1_info->digest[4] >> 8) & 0xff); + digest[19] = (unsigned char) ((sha1_info->digest[4] ) & 0xff); } /* finish computing the SHA digest */ void -sha1_final(uint8_t digest[20], SHA_INFO *sha_info) +sha1_final(uint8_t digest[20], SHA1_INFO *sha1_info) { int count; uint32_t lo_bit_count, hi_bit_count; - lo_bit_count = sha_info->count_lo; - hi_bit_count = sha_info->count_hi; + lo_bit_count = sha1_info->count_lo; + hi_bit_count = sha1_info->count_hi; count = (int) ((lo_bit_count >> 3) & 0x3f); - ((uint8_t *) sha_info->data)[count++] = 0x80; - if (count > SHA_BLOCKSIZE - 8) { - memset(((uint8_t *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count); - sha1_transform(sha_info); - memset((uint8_t *) sha_info->data, 0, SHA_BLOCKSIZE - 8); + ((uint8_t *) sha1_info->data)[count++] = 0x80; + if (count > SHA1_BLOCKSIZE - 8) { + memset(((uint8_t *) sha1_info->data) + count, 0, SHA1_BLOCKSIZE - count); + sha1_transform(sha1_info); + memset((uint8_t *) sha1_info->data, 0, SHA1_BLOCKSIZE - 8); } else { - memset(((uint8_t *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - 8 - count); + memset(((uint8_t *) sha1_info->data) + count, 0, + SHA1_BLOCKSIZE - 8 - count); } - sha_info->data[56] = (uint8_t)((hi_bit_count >> 24) & 0xff); - sha_info->data[57] = (uint8_t)((hi_bit_count >> 16) & 0xff); - sha_info->data[58] = (uint8_t)((hi_bit_count >> 8) & 0xff); - sha_info->data[59] = (uint8_t)((hi_bit_count >> 0) & 0xff); - sha_info->data[60] = (uint8_t)((lo_bit_count >> 24) & 0xff); - sha_info->data[61] = (uint8_t)((lo_bit_count >> 16) & 0xff); - sha_info->data[62] = (uint8_t)((lo_bit_count >> 8) & 0xff); - sha_info->data[63] = (uint8_t)((lo_bit_count >> 0) & 0xff); - sha1_transform_and_copy(digest, sha_info); + sha1_info->data[56] = (uint8_t)((hi_bit_count >> 24) & 0xff); + sha1_info->data[57] = (uint8_t)((hi_bit_count >> 16) & 0xff); + sha1_info->data[58] = (uint8_t)((hi_bit_count >> 8) & 0xff); + sha1_info->data[59] = (uint8_t)((hi_bit_count >> 0) & 0xff); + sha1_info->data[60] = (uint8_t)((lo_bit_count >> 24) & 0xff); + sha1_info->data[61] = (uint8_t)((lo_bit_count >> 16) & 0xff); + sha1_info->data[62] = (uint8_t)((lo_bit_count >> 8) & 0xff); + sha1_info->data[63] = (uint8_t)((lo_bit_count >> 0) & 0xff); + sha1_transform_and_copy(digest, sha1_info); } /***EOF***/ diff --git a/fko/sha.h b/fko/sha1.h similarity index 63% rename from fko/sha.h rename to fko/sha1.h index b8c3bff6..0b0015b6 100644 --- a/fko/sha.h +++ b/fko/sha1.h @@ -1,12 +1,12 @@ /* $Id$ ***************************************************************************** * - * File: sha.h + * File: sha1.h * - * Purpose: Header for sha.c + * Purpose: Header for sha1.c * - * sha - An implementation of the NIST SHA Message Digest - * algorithm. This header covers SHA1 and SHA256 + * sha - An implementation of the NIST SHA1 Message Digest + * algorithm. * * Copyright (C) 2001 Rafael R. Sevilla * This library is free software; you can redistribute it and/or @@ -25,8 +25,8 @@ * ***************************************************************************** */ -#ifndef SHA_H -#define SHA_H 1 +#ifndef SHA1_H +#define SHA1_H 1 #include "fko_common.h" @@ -40,28 +40,20 @@ #define TRUNC32(x) ((x) & 0xffffffffL) #endif -#define SHA_BLOCKSIZE 64 -#define SHA1_DIGESTSIZE 20 -#define SHA256_DIGESTSIZE 32 +#define SHA1_BLOCKSIZE 64 +#define SHA1_DIGEST_LENGTH 20 typedef struct { uint32_t digest[8]; uint32_t count_lo, count_hi; - uint8_t data[SHA_BLOCKSIZE]; + uint8_t data[SHA1_BLOCKSIZE]; int local; -} SHA_INFO; +} SHA1_INFO; /* SHA1 prototypes. */ -void sha1_init(SHA_INFO *sha_info); -void sha1_update(SHA_INFO *sha_info, uint8_t *buffer, int count); -void sha1_final(uint8_t digest[SHA1_DIGESTSIZE], SHA_INFO *sha_info); +void sha1_init(SHA1_INFO *sha1_info); +void sha1_update(SHA1_INFO *sha1_info, uint8_t *buffer, int count); +void sha1_final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_INFO *sha1_info); -/* SHA256 prototypes. -*/ -void sha256_init(SHA_INFO *sha_info); -void sha256_update(SHA_INFO *sha_info, uint8_t *buffer, int count); -void sha256_final(SHA_INFO *sha_info); -void sha256_unpackdigest(uint8_t digest[SHA256_DIGESTSIZE], SHA_INFO *sha_info); - -#endif /* SHA_H */ +#endif /* SHA1_H */ diff --git a/fko/sha256.c b/fko/sha256.c deleted file mode 100644 index b22f002e..00000000 --- a/fko/sha256.c +++ /dev/null @@ -1,295 +0,0 @@ -/* $Id$ - ***************************************************************************** - * - * File: sha256.c - * - * Purpose: Implementation of the SHA256 message-digest algorithm for - * libfwknop. - * - * - * Copyright (C) 2001 Rafael R. Sevilla - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - ***************************************************************************** -*/ -#include "sha.h" - -/* 32-bit rotate to the RIGHT -*/ -#define ROT32(x,n) TRUNC32(((x >> n) | (x << (32 - n)))) - -#define CH(x, y, z) (((x) & (y))^(~(x) & (z))) -#define MAJ(x, y, z)(((x) & (y))^((x) & (z))^((y) & (z))) - -/* Upper-case sigma functions in SHA spec -*/ -#define USIG0(x) (ROT32(x, 2)^ROT32(x, 13)^ROT32(x, 22)) -#define USIG1(x) (ROT32(x, 6)^ROT32(x, 11)^ROT32(x, 25)) - -/* Lower-case sigma functions in SHA spec -*/ -#define LSIG0(x) (ROT32(x, 7)^ROT32(x, 18)^TRUNC32(x >> 3)) -#define LSIG1(x) (ROT32(x, 17)^ROT32(x, 19)^TRUNC32(x >> 10)) - -/* SHA256 constants -*/ -static uint32_t K[64] = { - 0x428a2f98L, 0x71374491L, 0xb5c0fbcfL, 0xe9b5dba5L, - 0x3956c25bL, 0x59f111f1L, 0x923f82a4L, 0xab1c5ed5L, - 0xd807aa98L, 0x12835b01L, 0x243185beL, 0x550c7dc3L, - 0x72be5d74L, 0x80deb1feL, 0x9bdc06a7L, 0xc19bf174L, - 0xe49b69c1L, 0xefbe4786L, 0x0fc19dc6L, 0x240ca1ccL, - 0x2de92c6fL, 0x4a7484aaL, 0x5cb0a9dcL, 0x76f988daL, - 0x983e5152L, 0xa831c66dL, 0xb00327c8L, 0xbf597fc7L, - 0xc6e00bf3L, 0xd5a79147L, 0x06ca6351L, 0x14292967L, - 0x27b70a85L, 0x2e1b2138L, 0x4d2c6dfcL, 0x53380d13L, - 0x650a7354L, 0x766a0abbL, 0x81c2c92eL, 0x92722c85L, - 0xa2bfe8a1L, 0xa81a664bL, 0xc24b8b70L, 0xc76c51a3L, - 0xd192e819L, 0xd6990624L, 0xf40e3585L, 0x106aa070L, - 0x19a4c116L, 0x1e376c08L, 0x2748774cL, 0x34b0bcb5L, - 0x391c0cb3L, 0x4ed8aa4aL, 0x5b9cca4fL, 0x682e6ff3L, - 0x748f82eeL, 0x78a5636fL, 0x84c87814L, 0x8cc70208L, - 0x90befffaL, 0xa4506cebL, 0xbef9a3f7L, 0xc67178f2L -}; - -static void -sha256_transform(SHA_INFO *sha_info) -{ - int i, j; - uint8_t *dp; - uint32_t T, T1, T2, A, B, C, D, E, F, G, H, W[64]; - - dp = sha_info->data; - -#undef SWAP_DONE - -#if BYTEORDER == 1234 -#define SWAP_DONE - for (i = 0; i < 16; ++i) { - T = *((uint32_t *) dp); - dp += 4; - W[i] = - ((T << 24) & 0xff000000) | - ((T << 8) & 0x00ff0000) | - ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); - } -#endif - -#if BYTEORDER == 4321 -#define SWAP_DONE - for (i = 0; i < 16; ++i) { - T = *((uint32_t *) dp); - dp += 4; - W[i] = TRUNC32(T); - } -#endif - -#if BYTEORDER == 12345678 -#define SWAP_DONE - for (i = 0; i < 16; i += 2) { - T = *((uint32_t *) dp); - dp += 8; - W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | - ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); - T >>= 32; - W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | - ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); - } -#endif - -#if BYTEORDER == 87654321 -#define SWAP_DONE - for (i = 0; i < 16; i += 2) { - T = *((uint32_t *) dp); - dp += 8; - W[i] = TRUNC32(T >> 32); - W[i+1] = TRUNC32(T); - } -#endif - -#ifndef SWAP_DONE -#define SWAP_DONE - for (i = 0; i < 16; ++i) { - T = *((uint32_t *) dp); - dp += 4; - W[i] = TRUNC32(T); - } - #ifndef WIN32 - #warning Undetermined or unsupported Byte Order... We will try LITTLE_ENDIAN - #endif -#endif /* SWAP_DONE */ - - A = sha_info->digest[0]; - B = sha_info->digest[1]; - C = sha_info->digest[2]; - D = sha_info->digest[3]; - E = sha_info->digest[4]; - F = sha_info->digest[5]; - G = sha_info->digest[6]; - H = sha_info->digest[7]; - - for (i=16; i<64; i++) - W[i] = TRUNC32(LSIG1(W[i-2]) + W[i-7] + LSIG0(W[i-15]) + W[i-16]); - - for (j=0; j<64; j++) { - T1 = TRUNC32(H + USIG1(E) + CH(E, F, G) + K[j] + W[j]); - T2 = TRUNC32(USIG0(A) + MAJ(A, B, C)); - H = G; - G = F; - F = E; - E = TRUNC32(D + T1); - D = C; - C = B; - B = A; - A = TRUNC32(T1 + T2); - } - - sha_info->digest[0] = TRUNC32(sha_info->digest[0] + A); - sha_info->digest[1] = TRUNC32(sha_info->digest[1] + B); - sha_info->digest[2] = TRUNC32(sha_info->digest[2] + C); - sha_info->digest[3] = TRUNC32(sha_info->digest[3] + D); - sha_info->digest[4] = TRUNC32(sha_info->digest[4] + E); - sha_info->digest[5] = TRUNC32(sha_info->digest[5] + F); - sha_info->digest[6] = TRUNC32(sha_info->digest[6] + G); - sha_info->digest[7] = TRUNC32(sha_info->digest[7] + H); -} - -void -sha256_init(SHA_INFO *sha_info) -{ - sha_info->digest[0] = 0x6a09e667L; - sha_info->digest[1] = 0xbb67ae85L; - sha_info->digest[2] = 0x3c6ef372L; - sha_info->digest[3] = 0xa54ff53aL; - sha_info->digest[4] = 0x510e527fL; - sha_info->digest[5] = 0x9b05688cL; - sha_info->digest[6] = 0x1f83d9abL; - sha_info->digest[7] = 0x5be0cd19L; - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - memset((uint8_t *)sha_info->data, 0, SHA_BLOCKSIZE); -} - -/* Update the SHA digest -*/ -void -sha256_update(SHA_INFO *sha_info, uint8_t *buffer, int count) -{ - int i; - uint32_t clo; - - clo = TRUNC32(sha_info->count_lo + ((uint8_t) count << 3)); - if (clo < sha_info->count_lo) { - sha_info->count_hi++; - } - sha_info->count_lo = clo; - sha_info->count_hi += (uint32_t) count >> 29; - if (sha_info->local) { - i = SHA_BLOCKSIZE - sha_info->local; - if (i > count) { - i = count; - } - memcpy(((uint8_t *) sha_info->data) + sha_info->local, buffer, i); - count -= i; - buffer += i; - sha_info->local += i; - if (sha_info->local == SHA_BLOCKSIZE) { - sha256_transform(sha_info); - } else { - return; - } - } - while (count >= SHA_BLOCKSIZE) { - memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); - buffer += SHA_BLOCKSIZE; - count -= SHA_BLOCKSIZE; - sha256_transform(sha_info); - } - memcpy(sha_info->data, buffer, count); - sha_info->local = count; -} - -/* Finish computing the SHA digest -*/ -void -sha256_final(SHA_INFO *sha_info) -{ - int count; - uint32_t lo_bit_count, hi_bit_count; - - lo_bit_count = sha_info->count_lo; - hi_bit_count = sha_info->count_hi; - count = (int) ((lo_bit_count >> 3) & 0x3f); - ((uint8_t *) sha_info->data)[count++] = 0x80; - if (count > SHA_BLOCKSIZE - 8) { - memset(((uint8_t *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count); - sha256_transform(sha_info); - memset((uint8_t *) sha_info->data, 0, SHA_BLOCKSIZE - 8); - } else { - memset(((uint8_t *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - 8 - count); - } - sha_info->data[56] = (hi_bit_count >> 24) & 0xff; - sha_info->data[57] = (hi_bit_count >> 16) & 0xff; - sha_info->data[58] = (hi_bit_count >> 8) & 0xff; - sha_info->data[59] = (hi_bit_count >> 0) & 0xff; - sha_info->data[60] = (lo_bit_count >> 24) & 0xff; - sha_info->data[61] = (lo_bit_count >> 16) & 0xff; - sha_info->data[62] = (lo_bit_count >> 8) & 0xff; - sha_info->data[63] = (lo_bit_count >> 0) & 0xff; - sha256_transform(sha_info); -} - -void -sha256_unpackdigest(uint8_t digest[32], SHA_INFO *sha_info) -{ - digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); - digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); - digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); - digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); - digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); - digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); - digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); - digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); - digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); - digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); - digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); - digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); - digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); - digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); - digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); - digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); - digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); - digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); - digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); - digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); - digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); - digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); - digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); - digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff); - digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); - digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); - digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); - digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff); - digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); - digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); - digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); - digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff); -} - - -/***EOF***/ diff --git a/perl/FKO/lib/FKO.pm b/perl/FKO/lib/FKO.pm index 4209f6c8..ecd8e953 100644 --- a/perl/FKO/lib/FKO.pm +++ b/perl/FKO/lib/FKO.pm @@ -16,7 +16,7 @@ use warnings; use Carp; require Exporter; -our $VERSION = '0.22'; +our $VERSION = '0.23'; our @ISA = qw(Exporter); @@ -706,6 +706,14 @@ The SHA1 message digest algorithm. The SHA256 message digest algorithm. This is the I default. +=item * B + +The SHA384 message digest algorithm. This is the I default. + +=item * B + +The SHA512 message digest algorithm. This is the I default. + =back diff --git a/perl/FKO/lib/FKO_Constants.pl b/perl/FKO/lib/FKO_Constants.pl index ef53e7c3..67e6bc11 100644 --- a/perl/FKO/lib/FKO_Constants.pl +++ b/perl/FKO/lib/FKO_Constants.pl @@ -27,6 +27,8 @@ our @DIGEST_TYPES = qw( FKO_DIGEST_MD5 FKO_DIGEST_SHA1 FKO_DIGEST_SHA256 + FKO_DIGEST_SHA384 + FKO_DIGEST_SHA512 ); # Encryption types tag list. @@ -101,6 +103,8 @@ use constant { FKO_DIGEST_MD5 => 1, FKO_DIGEST_SHA1 => 2, FKO_DIGEST_SHA256 => 3, + FKO_DIGEST_SHA384 => 4, + FKO_DIGEST_SHA512 => 5, # Encryption types FKO_ENCRYPTION_RIJNDAEL => 1, diff --git a/src/config_init.c b/src/config_init.c index 8ce3cc67..41d9ae04 100644 --- a/src/config_init.c +++ b/src/config_init.c @@ -77,11 +77,15 @@ get_char_val(const char *var_name, char *dest, char *lptr) static int parse_time_offset(char *offset_str) { - int offset = 0, i, j, offset_type = TIME_OFFSET_SECONDS; + int i, j; + int offset = 0; + int offset_type = TIME_OFFSET_SECONDS; + int os_len = strlen(offset_str); + char offset_digits[MAX_TIME_STR_LEN]; j=0; - for (i=0; i < strlen(offset_str); i++) { + for (i=0; i < os_len; i++) { if (isdigit(offset_str[i])) { offset_digits[j] = offset_str[i]; j++; @@ -247,7 +251,7 @@ validate_options(fko_cli_options_t *options) void config_init(fko_cli_options_t *options, int argc, char **argv) { - int cmd_arg, index, i; + int cmd_arg, index; struct opts_track ot; /* Zero out options and opts_track. @@ -309,6 +313,10 @@ config_init(fko_cli_options_t *options, int argc, char **argv) options->digest_type = FKO_DIGEST_SHA1; else if(strncasecmp(optarg, "sha256", 6) == 0) options->digest_type = FKO_DIGEST_SHA256; + else if(strncasecmp(optarg, "sha384", 6) == 0) + options->digest_type = FKO_DIGEST_SHA384; + else if(strncasecmp(optarg, "sha512", 6) == 0) + options->digest_type = FKO_DIGEST_SHA512; else { fprintf(stderr, "* Invalid digest type: %s\n", optarg); diff --git a/src/fwknop.c b/src/fwknop.c index 571c5688..73b19f74 100644 --- a/src/fwknop.c +++ b/src/fwknop.c @@ -431,8 +431,9 @@ static int ipv4_str_has_port(char *str) { int rv = 0, i; + int st_len = strlen(str); - for (i=0; i < strlen(str); i++) { + for (i=0; i < st_len; i++) { if (str[i] == ',' || str[i] == ':') { str[i] = ','; /* force "," format */ rv = 1; @@ -453,7 +454,6 @@ static void resolve_ip_http(fko_cli_options_t *options) struct addrinfo *result, *rp, hints; char http_buf[HTTP_MAX_REQUEST_LEN]; char http_response[HTTP_MAX_RESPONSE_LEN]; - char ip_str[MAX_IP_STR_LEN]; /* Build our HTTP request to resolve the external IP (this is similar to * to contacting whatismyip.org, but using a different URL). @@ -520,7 +520,7 @@ static void resolve_ip_http(fko_cli_options_t *options) ); } - res = read(sock, http_response, HTTP_MAX_RESPONSE_LEN); + res = recv(sock, http_response, HTTP_MAX_RESPONSE_LEN, 0); http_response[HTTP_MAX_RESPONSE_LEN-1] = '\0'; #ifdef WIN32