Matthias Urlichs wrote: > Hello, > > I need to sign files remotely. They're moderately large, so > transmitting them back to my firewalled-off laptop (I'm usually > behind a slow line), where the secret key lives, isn't a good idea. > > Ideas?
I'currenty working on a patch for gnupg that enables remote signatures. see attachment for an ALPHA version (working but unsafe code) Thomas
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 NotDashEscaped: You need GnuPG to verify this message Remote Signatures for GnuPG WARNING: DON'T USE THE PATCH ON PRODUCTION SYSTEMS (lot's of ugly, unsafe code and missing guardians) Apply the patch to the gnupg-1.4.2 sources and follow the usual instructions to build gnupg --print-seed algo file ====================== algo: MD5 SHA1 RIPEMD160 (SHA256 SHA384 SHA512) file: the file file that should be signed sample: gpg --print-seed SHA1 ./NEWS > algo=SHA1&sig_type=0&block=1119&state=%DE%7C%02Qtt%E1Y%98%C5%BA%12e > %3F%9Erl%BB%ED%F6&length=432&buffer=%20MERCHANTABILITY%20or%20FITNE > SS%20FOR%20A%20PARTICULAR%20PURPOSE%2E%0A --sign-seed seed ================ seed: a seed generated by --print-seed sample: gpg --sign-seed algo=SHA1&sig_[...]2E%0A > -----BEGIN PGP SIGNATURE----- > > iQIVAwUAQ/jWkjOg8GEoPYU1AQI6kBAAsPYDJfIbSjMyovbWqNNiF2ueD6y9K66o > By0BDlwt4A5VpmZU5wWcqnIAcKcc6OcAwrt+BDyjdnDHF/0MB8li64x3/LIrV4Vd > V0VsAFV8SBnBmG0KVFNHyHhr/KI4mSTF7RyH5K+Xhw5B0jauKcH1JZEONPziWzOn > yIVHCEuEKR7SImE3b+pIwdK1V89NAqEtnMvsN9fGosXTDraCZVAf702XbkANown+ > nw8uGxd8FpQYB0tmA6KOBYlj0XnaL1p5iFP6JnHS2wNJxGtZJEWl3kywsJ0dj4wg > nmN5okMHvkJ/NjYXyk2w5RAtbM2kSL+bfyLk4oV4s4q/jfRjTL4y/qrmBu5R9+Sf > CAWdhph1WM1Z1Vnujgo9tsBKR80yL/1r0C+kDylsGbUYBQ23DLdYTQILIKovSjab > xePA1Q11PHPPQvwtwxMdDU+1LNHu/lcjzxkKoR3Xcq6+jdTZxrvXMAm2vmXFXtcO > ECr2o9ckBFAqHjeQggdsAXTG5d2ZPzcpP42UECRMD3Eg0JCLbxq5yxTCTe5MRRaj > xyuq7xnlXo3LErmZGrPdm9w4xMcHvVFXuHNRt7/FWyGUxrrpy0kFnyHerIKKw/bn > 4oZQI2EVO8MqFb9QMCON5QsjAiQsYyC3e39g1IpE3/d3vXijaidRSy+vPRMhSiVQ > WiUe2+IQqpY= > =1MFy > -----END PGP SIGNATURE----- License: GPL Copyright: 2006 Thomas Kuehne <[EMAIL PROTECTED]> Thomas diff -urBbN gnupg-1.4.2/cipher/algorithms.h gnupg-1.4.2-md-seed-1/cipher/algorithms.h --- gnupg-1.4.2/cipher/algorithms.h 2005-05-31 08:29:54.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/cipher/algorithms.h 2006-02-18 18:56:37.000000000 +0100 @@ -21,6 +21,10 @@ #ifndef GNUPG_ALGORITHMS_H #define GNUPG_ALGORITHMS_H 1 +#ifdef ENABLE_MD_SEED +#include "md_seed.h" +#endif + const char *dynload_enum_module_names (int seq); const char * @@ -30,6 +34,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ); @@ -40,6 +48,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ); const char * @@ -49,6 +61,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ); const char * @@ -58,6 +74,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ); const char * @@ -67,6 +87,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ); const char * @@ -76,6 +100,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ); const char * diff -urBbN gnupg-1.4.2/cipher/md.c gnupg-1.4.2-md-seed-1/cipher/md.c --- gnupg-1.4.2/cipher/md.c 2005-05-31 08:29:54.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/cipher/md.c 2006-02-19 17:57:54.000000000 +0100 @@ -31,6 +31,10 @@ #include "algorithms.h" #include "i18n.h" +#ifdef ENABLE_MD_SEED +#include "md_seed.h" +#endif + /**************** * This structure is used for the list of available algorithms * and for the list of algorithms in MD_HANDLE. @@ -46,6 +50,10 @@ void (*write)( void *c, byte *buf, size_t nbytes ); void (*final)( void *c ); byte *(*read)( void *c ); +#ifdef ENABLE_MD_SEED + void (*read_seed)( void *c , MD_SEED seed); + void (*write_seed)( void *c , MD_SEED seed); +#endif size_t contextsize; /* allocate this amount of context */ PROPERLY_ALIGNED_TYPE context; }; @@ -58,7 +66,12 @@ const char *(*get_info)( int, size_t*,byte**, int*, int*, void (**)(void*), void (**)(void*,byte*,size_t), - void (**)(void*),byte *(**)(void*))) + void (**)(void*),byte *(**)(void*) +#ifdef ENABLE_MD_SEED + ,void (**)(void*, MD_SEED), + void (**)(void*, MD_SEED) +#endif + )) { struct md_digest_list_s *r; @@ -66,7 +79,13 @@ r->algo = algo; r->name = (*get_info)( algo, &r->contextsize, &r->asnoid, &r->asnlen, &r->mdlen, - &r->init, &r->write, &r->final, &r->read ); + &r->init, &r->write, &r->final, &r->read +#ifdef ENABLE_MD_SEED + ,&r->read_seed, &r->write_seed +#endif + ); + + if (!r->name ) { m_free(r); @@ -526,3 +547,39 @@ } #endif } + +#ifdef ENABLE_MD_SEED +void +md_write_seed( MD_HANDLE a, MD_SEED seed) +{ + struct md_digest_list_s *r; + + r=a->list; + if(! r) + BUG(); + + + (*r->write_seed)( &r->context.c, seed); + + +} + +MD_HANDLE +md_read_seed( MD_SEED seed, int secure ) +{ + MD_HANDLE md = md_open( seed->algo, secure ); + if( ! md_get_algo( md ) ) + BUG(); + + struct md_digest_list_s *r; + r=md->list; + + (*r->read_seed)( &r->context.c, seed); + + return md; +} + +void debug_md (MD_HANDLE a){ + sha1_debug(a->list->context.c); +} +#endif /* ENABLE_MD_SEED */ diff -urBbN gnupg-1.4.2/cipher/md5.c gnupg-1.4.2-md-seed-1/cipher/md5.c --- gnupg-1.4.2/cipher/md5.c 2005-05-31 08:29:54.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/cipher/md5.c 2006-02-19 18:19:52.000000000 +0100 @@ -331,6 +331,77 @@ return hd->buf; } +#if ENABLE_MD_SEED +#include "md_seed.h" +#include "i18n.h" + +void +md5_write_seed( MD5_CONTEXT *hd, MD_SEED seed ) +{ + u32 t; + + md5_write(hd, NULL, 0); /* flush */; + + seed->algo = DIGEST_ALGO_MD5; + + seed->buffer = m_alloc(hd->count); + memcpy(seed->buffer, hd->buf, hd->count); + seed->buffer_length = hd->count * 8; + + seed->block_count = hd->nblocks; + + seed->state_length = 4 * sizeof(u32); + seed->state = m_alloc(seed->state_length); + + /* slow but struct alignment save */ + t = hton_32(hd->A); + memcpy(seed->state + 0 * sizeof(u32), &t, sizeof(u32)); + t = hton_32(hd->B); + memcpy(seed->state + 1 * sizeof(u32), &t, sizeof(u32)); + t = hton_32(hd->C); + memcpy(seed->state + 2 * sizeof(u32), &t, sizeof(u32)); + t = hton_32(hd->D); + memcpy(seed->state + 3 * sizeof(u32), &t, sizeof(u32)); +} + +void +md5_read_seed( MD5_CONTEXT *hd, MD_SEED seed ) +{ + u32 len = seed->buffer_length; + + if( seed->algo != DIGEST_ALGO_MD5) + BUG(); + + if(len % 8) + g10_log_error("%s\n", _("this MD5 implementation doesn't support non-byte aligned buffers")); + else + len = len / 8; + + if(sizeof(hd->buf) < len) + g10_log_error("%s\n", _("excessive length of seed's buffer")); + + if(4 * sizeof(u32) != seed->state_length) + g10_log_error("%s\n", _("unexpected length of state data")); + + if( (u64)((u32) seed->block_count) != seed->block_count ) + g10_log_error("%s\n", _("excessive block count")); + + if( log_get_errorcount(0) ) + return; + + memcpy(hd->buf, seed->buffer, len); + hd->count = len; + + hd->nblocks = seed->block_count; + + /* slow but struct alignment save */ + hd->A = hton_32(*((u32*) (seed->state + 0 * sizeof(u32)))); + hd->B = hton_32(*((u32*) (seed->state + 1 * sizeof(u32)))); + hd->C = hton_32(*((u32*) (seed->state + 2 * sizeof(u32)))); + hd->D = hton_32(*((u32*) (seed->state + 3 * sizeof(u32)))); +} +#endif /* ENABLE_MD_SEED */ + /**************** * Return some information about the algorithm. We need algo here to * distinguish different flavors of the algorithm. @@ -344,6 +415,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ) { static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */ @@ -362,5 +437,10 @@ *(void (**)(MD5_CONTEXT *))r_final = md5_final; *(byte *(**)(MD5_CONTEXT *))r_read = md5_read; +#ifdef ENABLE_MD_SEED + *(void (**)(MD5_CONTEXT *, MD_SEED))r_read_seed = md5_read_seed; + *(void (**)(MD5_CONTEXT *, MD_SEED))r_write_seed = md5_write_seed; +#endif return "MD5"; } + diff -urBbN gnupg-1.4.2/cipher/rmd160.c gnupg-1.4.2-md-seed-1/cipher/rmd160.c --- gnupg-1.4.2/cipher/rmd160.c 2005-05-31 08:29:54.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/cipher/rmd160.c 2006-02-19 18:13:14.000000000 +0100 @@ -552,6 +552,79 @@ memcpy( outbuf, hd.buf, 20 ); } +#if ENABLE_MD_SEED +#include "md_seed.h" +#include "i18n.h" + +static void +rmd160_write_seed( RMD160_CONTEXT *hd, MD_SEED seed ) +{ + u32 t; + + rmd160_write(hd, NULL, 0); /* flush */; + + seed->algo = DIGEST_ALGO_RMD160; + + seed->buffer = m_alloc(hd->count); + memcpy(seed->buffer, hd->buf, hd->count); + seed->buffer_length = hd->count * 8; + + seed->block_count = hd->nblocks; + + seed->state_length = 5 * sizeof(u32); + seed->state = m_alloc(seed->state_length); + + /* slow but struct alignment save */ + t = hton_32(hd->h0); + memcpy(seed->state, &t, 4); + t = hton_32(hd->h1); + memcpy(seed->state+4, &t, 4); + t = hton_32(hd->h2); + memcpy(seed->state+8, &t, 4); + t = hton_32(hd->h3); + memcpy(seed->state+12, &t, 4); + t = hton_32(hd->h4); + memcpy(seed->state+16, &t, 4); +} + +static void +rmd160_read_seed( RMD160_CONTEXT *hd, const MD_SEED seed ) +{ + u32 len = seed->buffer_length; + + if( seed->algo != DIGEST_ALGO_RMD160) + BUG(); + + if(len % 8) + g10_log_error("%s\n", _("this RIPEMD160 implementation doesn't support non-byte aligned buffers")); + else + len = len / 8; + + if(sizeof(hd->buf) < len) + g10_log_error("%s\n", _("excessive length of seed's buffer")); + + if(5 * sizeof(u32) != seed->state_length) + g10_log_error("%s\n", _("unexpected length of state data")); + + if( (u64)((u32) seed->block_count) != seed->block_count ) + g10_log_error("%s\n", _("excessive block count")); + + if( log_get_errorcount(0) ) + return; + + memcpy(hd->buf, seed->buffer, len); + hd->count = len; + + hd->nblocks = seed->block_count; + + /* slow but struct alignment save */ + hd->h0 = hton_32(*((u32*) (seed->state + 0 * sizeof(u32)))); + hd->h1 = hton_32(*((u32*) (seed->state + 1 * sizeof(u32)))); + hd->h2 = hton_32(*((u32*) (seed->state + 2 * sizeof(u32)))); + hd->h3 = hton_32(*((u32*) (seed->state + 3 * sizeof(u32)))); + hd->h4 = hton_32(*((u32*) (seed->state + 4 * sizeof(u32)))); +} +#endif /**************** * Return some information about the algorithm. We need algo here to @@ -566,6 +639,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ) { static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */ @@ -584,5 +661,11 @@ *(void (**)(RMD160_CONTEXT *))r_final = rmd160_final; *(byte *(**)(RMD160_CONTEXT *))r_read = rmd160_read; +#ifdef ENABLE_MD_SEED + *(void (**)(RMD160_CONTEXT *, MD_SEED ))r_read_seed = rmd160_read_seed; + *(void (**)(RMD160_CONTEXT *, MD_SEED ))r_write_seed = rmd160_write_seed; +#endif + return "RIPEMD160"; } + diff -urBbN gnupg-1.4.2/cipher/sha1.c gnupg-1.4.2-md-seed-1/cipher/sha1.c --- gnupg-1.4.2/cipher/sha1.c 2005-05-31 08:29:54.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/cipher/sha1.c 2006-02-19 18:17:30.000000000 +0100 @@ -62,6 +61,15 @@ } +void sha1_debug(SHA1_CONTEXT* hd){ + fprintf(stderr, "h0: %i\nh1: %i\nh2: %i\nh3: %i\nh4: %i\nnblocks: %i\ncount: %i\n", + hd->h0, hd->h1, hd->h2, hd->h3, hd->h4, hd->nblocks, hd->count); + int i; + for(i = 0; i < sizeof(hd->buf); i++){ + fprintf(stderr, "[%i] %2X %c\n", i, hd->buf[i], hd->buf[i]); + } +} + void sha1_init( SHA1_CONTEXT *hd ) { @@ -325,6 +333,79 @@ return hd->buf; } +#if ENABLE_MD_SEED +#include "md_seed.h" +#include "i18n.h" + +static void +sha1_write_seed( SHA1_CONTEXT *hd, MD_SEED seed ) +{ + u32 t; + + seed->algo = DIGEST_ALGO_SHA1; + + seed->buffer = m_alloc(hd->count); + memcpy(seed->buffer, hd->buf, hd->count); + seed->buffer_length = hd->count * 8; + + seed->block_count = hd->nblocks; + + seed->state_length = 5 * sizeof(u32); + seed->state = m_alloc(seed->state_length); + + + /* slow but struct alignment save */ + t = hton_32(hd->h0); + memcpy(seed->state + 0 * sizeof(u32), &t, sizeof(u32)); + t = hton_32(hd->h1); + memcpy(seed->state + 1 * sizeof(u32), &t, sizeof(u32)); + t = hton_32(hd->h2); + memcpy(seed->state + 2 * sizeof(u32), &t, sizeof(u32)); + t = hton_32(hd->h3); + memcpy(seed->state + 3 * sizeof(u32), &t, sizeof(u32)); + t = hton_32(hd->h4); + memcpy(seed->state + 4 * sizeof(u32), &t, sizeof(u32)); +} + +static void +sha1_read_seed( SHA1_CONTEXT *hd, MD_SEED seed ) +{ + u32 len = seed->buffer_length; + + if( seed->algo != DIGEST_ALGO_SHA1) + BUG(); + + if(len % 8) + g10_log_error("%s\n", _("this SHA1 implementation doesn't support non-byte aligned buffers")); + else + len = len / 8; + + if(sizeof(hd->buf) < len) + g10_log_error("%s\n", _("excessive length of seed's buffer")); + + if(5 * sizeof(u32) != seed->state_length) + g10_log_error("%s\n", _("unexpected length of state data")); + + if( (u64)((u32) seed->block_count) != seed->block_count ) + g10_log_error("%s\n", _("excessive block count")); + + if( log_get_errorcount(0) ) + return; + + memcpy(hd->buf, seed->buffer, len); + hd->count = len; + + hd->nblocks = seed->block_count; + + /* slow but struct alignment save */ + hd->h0 = hton_32(*((u32*) (seed->state + 0 * sizeof(u32)))); + hd->h1 = hton_32(*((u32*) (seed->state + 1 * sizeof(u32)))); + hd->h2 = hton_32(*((u32*) (seed->state + 2 * sizeof(u32)))); + hd->h3 = hton_32(*((u32*) (seed->state + 3 * sizeof(u32)))); + hd->h4 = hton_32(*((u32*) (seed->state + 4 * sizeof(u32)))); +} +#endif + /**************** * Return some information about the algorithm. We need algo here to * distinguish different flavors of the algorithm. @@ -338,6 +419,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ) { static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */ @@ -355,5 +440,10 @@ *(void (**)(SHA1_CONTEXT *))r_final = sha1_final; *(byte *(**)(SHA1_CONTEXT *))r_read = sha1_read; +#ifdef ENABLE_MD_SEED + *(void (**)(SHA1_CONTEXT *, MD_SEED))r_write_seed = sha1_write_seed; + *(void (**)(SHA1_CONTEXT *, MD_SEED))r_read_seed = sha1_read_seed; +#endif return "SHA1"; } + diff -urBbN gnupg-1.4.2/cipher/sha256.c gnupg-1.4.2-md-seed-1/cipher/sha256.c --- gnupg-1.4.2/cipher/sha256.c 2005-05-31 08:29:54.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/cipher/sha256.c 2006-02-19 18:21:54.000000000 +0100 @@ -280,6 +280,83 @@ return hd->buf; } +#if ENABLE_MD_SEED +#include "md_seed.h" +#include "i18n.h" + +static void +sha256_write_seed( SHA256_CONTEXT *hd, MD_SEED seed ) +{ + u32 t; + + seed->algo = DIGEST_ALGO_SHA256; + + seed->buffer = m_alloc(hd->count); + memcpy(seed->buffer, hd->buf, hd->count); + seed->buffer_length = hd->count * 8; + + seed->block_count = hd->nblocks; + + seed->state_length = 8 * sizeof(u32); + seed->state = m_alloc(seed->state_length); + + /* slow but struct alignment save */ + t = hton_32(hd->h0); + memcpy(seed->state + (0 * sizeof(u32)), &t, sizeof(u32)); + t = hton_32(hd->h1); + memcpy(seed->state + (1 * sizeof(u32)), &t, sizeof(u32)); + t = hton_32(hd->h2); + memcpy(seed->state + (2 * sizeof(u32)), &t, sizeof(u32)); + t = hton_32(hd->h3); + memcpy(seed->state + (3 * sizeof(u32)), &t, sizeof(u32)); + t = hton_32(hd->h4); + memcpy(seed->state + (4 * sizeof(u32)), &t, sizeof(u32)); + t = hton_32(hd->h5); + memcpy(seed->state + (5 * sizeof(u32)), &t, sizeof(u32)); + t = hton_32(hd->h6); + memcpy(seed->state + (6 * sizeof(u32)), &t, sizeof(u32)); + t = hton_32(hd->h7); + memcpy(seed->state + (7 * sizeof(u32)), &t, sizeof(u32)); +} + +static void +sha256_read_seed( SHA256_CONTEXT *hd, MD_SEED seed ) +{ + u32 len = seed->buffer_length; + + if( seed->algo != DIGEST_ALGO_SHA256 ) + BUG(); + + if( len % 8 ) + g10_log_error("%s\n", _("this SHA256 implementation doesn't support non-byte aligned buffers")); + else + len = len / 8; + + if( sizeof(hd->buf) < len ) + g10_log_error("%s\n", _("excessive length of seed's buffer")); + + if( 8 * sizeof(u32) != seed->state_length ) + g10_log_error("%s\n", _("unexpected length of seed's state data")); + + if( log_get_errorcount(0) ) + return; + + memcpy( hd->buf, seed->buffer, len ); + hd->count = len; + + hd->nblocks = seed->block_count; + + hd->h0 = hton_32(*((u32*) (seed->state + 0 * sizeof(u32)))); + hd->h1 = hton_32(*((u32*) (seed->state + 1 * sizeof(u32)))); + hd->h2 = hton_32(*((u32*) (seed->state + 2 * sizeof(u32)))); + hd->h3 = hton_32(*((u32*) (seed->state + 3 * sizeof(u32)))); + hd->h4 = hton_32(*((u32*) (seed->state + 4 * sizeof(u32)))); + hd->h5 = hton_32(*((u32*) (seed->state + 5 * sizeof(u32)))); + hd->h6 = hton_32(*((u32*) (seed->state + 6 * sizeof(u32)))); + hd->h7 = hton_32(*((u32*) (seed->state + 7 * sizeof(u32)))); +} +#endif + /**************** * Return some information about the algorithm. We need algo here to * distinguish different flavors of the algorithm. @@ -293,6 +370,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ) { static byte asn[] = /* Object ID is 2.16.840.1.101.3.4.2.1 */ @@ -314,5 +395,11 @@ *(void (**)(SHA256_CONTEXT *))r_final = sha256_final; *(byte *(**)(SHA256_CONTEXT *))r_read = sha256_read; +#ifdef ENABLE_MD_SEED + *(void (**)(SHA256_CONTEXT *, MD_SEED ))r_read_seed = sha256_read_seed; + *(void (**)(SHA256_CONTEXT *, MD_SEED ))r_write_seed = sha256_write_seed; +#endif + return "SHA256"; } + diff -urBbN gnupg-1.4.2/cipher/sha512.c gnupg-1.4.2-md-seed-1/cipher/sha512.c --- gnupg-1.4.2/cipher/sha512.c 2005-05-31 08:29:54.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/cipher/sha512.c 2006-02-19 19:17:57.000000000 +0100 @@ -359,6 +359,110 @@ return hd->buf; } +#ifdef ENABLE_MD_SEED +#include "md_seed.h" +#include "i18n.h" + +static void +sha512_write_seed( SHA512_CONTEXT *hd, MD_SEED seed ) +{ + u64 t; + + sha512_write(hd, NULL, 0); /* flush */; + + seed->algo = DIGEST_ALGO_SHA512; + + seed->buffer = m_alloc(hd->count); + memcpy(seed->buffer, hd->buf, hd->count); + seed->buffer_length = hd->count * 8; + + seed->block_count = hd->nblocks; + + seed->state_length = 8 * sizeof(u64); + seed->state = m_alloc(seed->state_length); + + t = hton_64(hd->h0); + memcpy(seed->state + (0 * sizeof(u64)), &t, sizeof(u64)); + t = hton_64(hd->h1); + memcpy(seed->state + (1 * sizeof(u64)), &t, sizeof(u64)); + t = hton_64(hd->h2); + memcpy(seed->state + (2 * sizeof(u64)), &t, sizeof(u64)); + t = hton_64(hd->h3); + memcpy(seed->state + (3 * sizeof(u64)), &t, sizeof(u64)); + t = hton_64(hd->h4); + memcpy(seed->state + (4 * sizeof(u64)), &t, sizeof(u64)); + t = hton_64(hd->h5); + memcpy(seed->state + (5 * sizeof(u64)), &t, sizeof(u64)); + t = hton_64(hd->h6); + memcpy(seed->state + (6 * sizeof(u64)), &t, sizeof(u64)); + t = hton_64(hd->h7); + memcpy(seed->state + (7 * sizeof(u64)), &t, sizeof(u64)); +} + +static void +sha512_read_Xseed( SHA512_CONTEXT *hd, MD_SEED seed ) +{ + u32 len = seed->buffer_length; + + if( (seed->algo != DIGEST_ALGO_SHA512) && (seed->algo != DIGEST_ALGO_SHA384) ) + BUG(); + + if( len % 8 ) + g10_log_error("%s\n", _("this SHA512/SHA384 implementation doesn't support non-byte aligned buffers")); + else + len = len / 8; + + if( sizeof(hd->buf) < len ) + g10_log_error("%s\n", _("excessive length of seed's buffer")); + + if( 8 * sizeof(u64) != seed->state_length ) + g10_log_error("%s\n", _("unexpected length of seed's state data")); + + if( log_get_errorcount(0) ) + return; + + memcpy( hd->buf, seed->buffer, len ); + hd->count = len; + + hd->nblocks = seed->block_count; + + hd->h0 = hton_64(*((u64*) (seed->state + 0 * sizeof(u64)))); + hd->h1 = hton_64(*((u64*) (seed->state + 1 * sizeof(u64)))); + hd->h2 = hton_64(*((u64*) (seed->state + 2 * sizeof(u64)))); + hd->h3 = hton_64(*((u64*) (seed->state + 3 * sizeof(u64)))); + hd->h4 = hton_64(*((u64*) (seed->state + 4 * sizeof(u64)))); + hd->h5 = hton_64(*((u64*) (seed->state + 5 * sizeof(u64)))); + hd->h6 = hton_64(*((u64*) (seed->state + 6 * sizeof(u64)))); + hd->h7 = hton_64(*((u64*) (seed->state + 7 * sizeof(u64)))); +} + +static void +sha512_read_seed( SHA512_CONTEXT *hd, MD_SEED seed ) +{ + if( seed->algo != DIGEST_ALGO_SHA512 ) + BUG(); + + sha512_read_Xseed(hd, seed); +} + +static void +sha384_write_seed( SHA512_CONTEXT *hd, MD_SEED seed ) +{ + sha512_write_seed(hd, seed); + seed->algo = DIGEST_ALGO_SHA384; +} + +static void +sha384_read_seed( SHA512_CONTEXT *hd, MD_SEED seed ) +{ + if( seed->algo != DIGEST_ALGO_SHA384 ) + BUG(); + + sha512_read_Xseed(hd, seed); +} + +#endif + /**************** * Return some information about the algorithm. We need algo here to * distinguish different flavors of the algorithm. @@ -372,6 +476,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ) { static byte asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */ @@ -393,6 +501,11 @@ *(void (**)(SHA512_CONTEXT *))r_final = sha512_final; *(byte *(**)(SHA512_CONTEXT *))r_read = sha512_read; +#ifdef ENABLE_MD_SEED + *(void (**)(SHA512_CONTEXT *, MD_SEED ))r_read_seed = sha512_read_seed; + *(void (**)(SHA512_CONTEXT *, MD_SEED ))r_write_seed = sha512_write_seed; +#endif + return "SHA512"; } @@ -405,6 +518,10 @@ void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) +#ifdef ENABLE_MD_SEED + , void (**r_read_seed)( void *c, MD_SEED seed), + void (**r_write_seed)( void *c, MD_SEED seed) +#endif ) { static byte asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */ @@ -426,5 +543,12 @@ *(void (**)(SHA512_CONTEXT *))r_final = sha512_final; *(byte *(**)(SHA512_CONTEXT *))r_read = sha512_read; +#ifdef ENABLE_MD_SEED + *(void (**)(SHA512_CONTEXT *, MD_SEED ))r_read_seed = sha384_read_seed; + *(void (**)(SHA512_CONTEXT *, MD_SEED ))r_write_seed = sha384_write_seed; +#endif + return "SHA384"; } + + diff -urBbN gnupg-1.4.2/config.h.in gnupg-1.4.2-md-seed-1/config.h.in --- gnupg-1.4.2/config.h.in 2005-07-26 18:08:19.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/config.h.in 2006-02-18 23:57:49.000000000 +0100 @@ -41,6 +41,9 @@ /* Define to include OpenPGP card support */ #undef ENABLE_CARD_SUPPORT +/* Define to enable remote signatures */ +#undef ENABLE_MD_SEED + /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS diff -urBbN gnupg-1.4.2/configure gnupg-1.4.2-md-seed-1/configure --- gnupg-1.4.2/configure 2005-07-26 17:54:43.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/configure 2006-02-18 23:55:32.000000000 +0100 @@ -865,6 +865,7 @@ --enable-minimal build the smallest gpg binary possible --disable-card-support disable OpenPGP card support --disable-agent-support disable gpg-agent support + --disable-md-seed disable remote signatures --disable-rsa disable the RSA public key algorithm --disable-idea disable the IDEA cipher --disable-cast5 disable the CAST5 cipher @@ -1021,7 +1022,7 @@ else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi - cd "$ac_popdir" + cd $ac_popdir done fi @@ -2048,6 +2049,7 @@ card_support=yes agent_support=yes disable_keyserver_path=no +use_mdseed=yes # Check whether --enable-minimal or --disable-minimal was given. if test "${enable_minimal+set}" = set; then @@ -2064,6 +2066,7 @@ use_exec=no card_support=no agent_support=no + use_mdseed=no fi; @@ -2089,6 +2093,22 @@ echo "$as_me:$LINENO: result: $agent_support" >&5 echo "${ECHO_T}$agent_support" >&6 +echo "$as_me:$LINENO: checking whether to enable remote signatures" >&5 +echo $ECHO_N "checking whether to enable remote signatures... $ECHO_C" >&6 +# Check whether --enable-md-seed or --disable-md-seed was given. +if test "${enable_md_seed+set}" = set; then + enableval="$enable_md_seed" + use_mdseed=$enableval +fi; +echo "$as_me:$LINENO: result: $use_mdseed" >&5 +echo "${ECHO_T}$use_mdseed" >&6 +if test x"$use_mdseed" = xyes ; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_MD_SEED 1 +_ACEOF + +fi echo "$as_me:$LINENO: checking whether to enable the RSA public key algorithm" >&5 echo $ECHO_N "checking whether to enable the RSA public key algorithm... $ECHO_C" >&6 diff -urBbN gnupg-1.4.2/configure.ac gnupg-1.4.2-md-seed-1/configure.ac --- gnupg-1.4.2/configure.ac 2005-07-26 17:17:46.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/configure.ac 2006-02-18 23:55:08.000000000 +0100 @@ -154,6 +154,7 @@ card_support=yes agent_support=yes disable_keyserver_path=no +use_mdseed=yes AC_ARG_ENABLE(minimal, AC_HELP_STRING([--enable-minimal],[build the smallest gpg binary possible]), @@ -168,7 +169,9 @@ use_bzip2=no use_exec=no card_support=no - agent_support=no) + agent_support=no + use_mdseed=no) + AC_MSG_CHECKING([whether OpenPGP card support is requested]) @@ -187,6 +190,14 @@ agent_support=$enableval) AC_MSG_RESULT($agent_support) +AC_MSG_CHECKING([whether to enable remote signatures]) +AC_ARG_ENABLE(md-seed, + AC_HELP_STRING([--disable-md-seed],[disable remote signatures]), + use_mdseed=$enableval) +AC_MSG_RESULT($use_mdseed) +if test x"$use_mdseed" = xyes ; then + AC_DEFINE(ENABLE_MD_SEED,1,[Define to enable remote signatures]) +fi AC_MSG_CHECKING([whether to enable the RSA public key algorithm]) AC_ARG_ENABLE(rsa, diff -urBbN gnupg-1.4.2/g10/g10.c gnupg-1.4.2-md-seed-1/g10/g10.c --- gnupg-1.4.2/g10/g10.c 2005-07-22 17:58:08.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/g10/g10.c 2006-02-19 16:17:18.000000000 +0100 @@ -58,6 +58,9 @@ #ifdef ENABLE_CARD_SUPPORT #include "ccid-driver.h" #endif +#ifdef ENABLE_MD_SEED +#include "md_seed.h" +#endif #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) #define MY_O_BINARY O_BINARY @@ -354,6 +357,10 @@ opcscDriver, oDisableCCID, +#ifdef ENABLE_MD_SEED + aPrintSeed, + aSignSeed, +#endif oNoop }; @@ -688,6 +695,11 @@ { oDebugCCIDDriver, "debug-ccid-driver", 0, "@"}, #endif +#ifdef ENABLE_MD_SEED + { aPrintSeed, "print-seed", 256, N_("|algo file| generate md seed")}, + { aSignSeed, "sign-seed", 256, N_("|seed| sign seed")}, +#endif + {0,NULL,0,NULL} }; @@ -1683,6 +1695,7 @@ opt.def_sig_expire="0"; opt.def_cert_expire="0"; set_homedir ( default_homedir () ); + opt.outfile = NULL; #ifdef ENABLE_CARD_SUPPORT # ifdef _WIN32 @@ -2553,7 +2566,10 @@ case oLimitCardInsertTries: opt.limit_card_insert_tries = pargs.r.ret_int; break; - +#ifdef ENABLE_MD_SEED + case aPrintSeed: set_cmd( &cmd, aPrintSeed); break; + case aSignSeed: set_cmd( &cmd, aSignSeed); break; +#endif case oNoop: break; @@ -3008,6 +3024,9 @@ case aDeArmor: case aEnArmor: case aFixTrustDB: +#ifdef ENABLE_MD_SEED + case aPrintSeed: +#endif break; case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break; case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break; @@ -3024,6 +3043,7 @@ case aSign: case aSignSym: case aClearsign: + case aSignSeed: if (!opt.quiet && any_explicit_recipient) log_info (_("WARNING: recipients (-r) given " "without using public key encryption\n")); @@ -3598,7 +3618,26 @@ m_free(str); } break; +#ifdef ENABLE_MD_SEED + case aPrintSeed: + if( (argc < 1) || (2 < argc)) + wrong_args("--print-seed algo [file]"); + { + int algo = string_to_digest_algo(argv[0]); + if( !algo ) + log_error(_("invalid hash algorithm `%s'\n"), argv[0] ); + else + print_seed(argc>1 ? argv[1] : NULL, algo, opt.outfile); + } + break; + case aSignSeed: + if( argc != 1) + wrong_args("--sign-seed seed"); + else + sign_seed(argv[0], opt.outfile ? opt.outfile : "-", locusr); + break; +#endif case aListPackets: opt.list_packets=2; default: diff -urBbN gnupg-1.4.2/g10/sign.c gnupg-1.4.2-md-seed-1/g10/sign.c --- gnupg-1.4.2/g10/sign.c 2005-05-31 08:29:59.000000000 +0200 +++ gnupg-1.4.2-md-seed-1/g10/sign.c 2006-02-19 21:08:57.000000000 +0100 @@ -43,6 +43,10 @@ #include "i18n.h" #include "cardglue.h" +#ifdef ENABLE_MD_SEED +#include "md_seed.h" +#include "http.h" +#endif #ifdef HAVE_DOSISH_SYSTEM #define LF "\r\n" @@ -1506,3 +1510,494 @@ *ret_sig = sig; return rc; } + +#ifdef ENABLE_MD_SEED +/**************** + * Remove all %xx escapes; this is done inplace. + * Returns: new length of the string. + */ +int +remove_escapes( byte *string ) +{ + int n = 0; + byte *p, *s; + + for(p=s=string; *s ; s++ ) { + if( *s == '%' ) { + if( s[1] && s[2] && isxdigit(s[1]) && isxdigit(s[2]) ) { + s++; + *p = *s >= '0' && *s <= '9' ? *s - '0' : + *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10 ; + *p <<= 4; + s++; + *p |= *s >= '0' && *s <= '9' ? *s - '0' : + *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10 ; + p++; + n++; + } + else { + *p++ = *s++; + if( *s ) + *p++ = *s++; + if( *s ) + *p++ = *s++; + if( *s ) + *p = 0; + return -1; /* bad URI */ + } + } + else + { + *p++ = *s; + n++; + } + } + *p = 0; /* always keep a string terminator */ + return n; +} + +URI_TUPLE +read_tuple(char* source) +{ + URI_TUPLE tuple = m_alloc(sizeof(struct uri_tuple)); + tuple->next = NULL; + tuple->name = NULL; + tuple->value = NULL; + tuple->valuelen = 0; + + char* start = source; + char* end = start; + + if( end == NULL) + BUG(); + + // name + while(1){ + if(*end == 0){ + tuple->name = start; + remove_escapes(tuple->name); + return tuple; + }else if(*end == '='){ + *end++ = 0; + tuple->name = start; + break; + }else if(*end == '&'){ + *end++ = 0; + tuple->name = start; + remove_escapes(tuple->name); + tuple->next = read_tuple(end); + return tuple; + } + end++; + } + + start = end; + + while(1){ + if(*end == 0){ + tuple->value = start; + tuple->valuelen = remove_escapes(tuple->value); + return tuple; + }else if(*end == '='){ + BUG(); + }else if(*end == '&'){ + *end++ = 0; + tuple->value = start; + tuple->valuelen = remove_escapes(tuple->value); + tuple->next = read_tuple(end); + return tuple; + } + end++; + } +} + +void +write_tuple(URI_TUPLE tuple, FILE* output) +{ + + const byte * s = tuple->name; + byte c = *s; + while(c){ + if((('A' <= c) && (c <= 'Z')) + || (('a' <= c) && (c <= 'z')) + || (('0' <= c) && (c <= '9')) + || (c == '_') || (c == '-')) + { + if(EOF == fputc(c, output)){ + fprintf(stderr, "! -%c-\n", c); + BUG(); + } + } else { + fprintf(output, "%%%02X", c); + } + c = *(++s); + } + + size_t len = tuple->valuelen; + + if(len > 0) + { + if(EOF == fputc('=', output)) + BUG(); + + s = tuple->value; + + while(len-- > 0) + { + byte c = *(s++); + + if((('A' <= c) && (c <= 'Z')) + || (('a' <= c) && (c <= 'z')) + || (('0' <= c) && (c <= '9'))) + { + if(EOF == fputc(c, output)) + BUG(); + } else { + fprintf(output, "%%%02X", c); + } + } + if(tuple->next != NULL){ + if(EOF == fputc('&', output)) + BUG(); + write_tuple(tuple->next, output); + } + }else if(tuple->next != NULL){ + if(EOF == fputc('=', output)) + BUG(); + write_tuple(tuple->next, output); + } +} + +MD_SEED +tuple2seed(URI_TUPLE tuple) +{ + URI_TUPLE current = tuple; + MD_SEED seed = m_alloc(sizeof(struct md_seed)); + seed->algo = 0; + seed->state = 0; + seed->state_length = 0; + seed->buffer = 0; + seed->buffer_length = 0; + seed->sig_type = 0; + + char* buffer = NULL; + size_t buffer_enc_len = 0; + int had_block = 0; + int had_state = 0; + int had_length = 0; + int had_type = 0; + int had_algo = 0; + + while(current){ + if(0 == strcmp("algo", current->name)){ + seed->algo = string_to_digest_algo( current->value ); + had_algo = 1; + }else if(0 == strcmp("sig_type", current->name)){ + char* tmp; + long int x = strtol(current->value, &tmp, 10); + if(current->value + current->valuelen != tmp) + BUG(); + + if(x < 0) + BUG(); + + seed->sig_type = x; + had_type = 1; + }else if(0 == strcmp("block", current->name)){ + char* tmp; + long int x = strtol(current->value, &tmp, 10); + if(current->value + current->valuelen != tmp) + BUG(); + + if(x < 0) + BUG(); + + seed->block_count = x; + had_block = 1; + }else if(0 == strcmp("state", current->name)){ + seed->state = current->value; + seed->state_length = current->valuelen; + had_state = 1; + }else if(0 == strcmp("length", current->name)){ + char* tmp; + long int x = strtol(current->value, &tmp, 10); + if(current->value + current->valuelen != tmp) + BUG(); + + if(x < 0) + BUG(); + + seed->buffer_length = x; + had_length = 1; + }else if(0 == strcmp("buffer", current->name)){ + buffer = current->value; + buffer_enc_len = current->valuelen; + }else{ + // ignore unknown keys + } + current = current->next; + } + + seed->buffer = buffer; + + if( ! had_algo ) + log_error(_("missing algorithm data\n")); + + if( ! had_type ) + log_error(_("missing signature type data\n")); + + if( ! had_block ) + log_error(_("missing block count data\n")); + + if( ! had_state ) + log_error(_("missing state data\n")); + + if( ! had_length ) + log_error(_("missing buffer length data\n")); + + if( log_get_errorcount(0) ) + return NULL; + else + return seed; +} + +URI_TUPLE +seed2tuple(MD_SEED seed) +{ + char* tmp; + + URI_TUPLE root = m_alloc(sizeof(struct uri_tuple)); + URI_TUPLE current = root; + + if( seed->algo == 0 ) + BUG(); + + current->name = "algo"; + current->value = digest_algo_to_string(seed->algo); + current->valuelen = strlen(current->value); + + current->next = m_alloc(sizeof(struct uri_tuple)); + current = current->next; + + current->name = "sig_type"; + tmp = m_alloc(64); + snprintf(tmp, 64, "%hhu", seed->sig_type); + current->value = tmp; + + current->valuelen = strlen(current->value); + current->next = m_alloc(sizeof(struct uri_tuple)); + current = current->next; + + current->name = "block"; + tmp = m_alloc(64); + snprintf(tmp, 64, "%zu", seed->block_count); + current->value = tmp; + + current->valuelen = strlen(current->value); + current->next = m_alloc(sizeof(struct uri_tuple)); + current = current->next; + + current->name = "state"; + current->value = seed->state; + current->valuelen = seed->state_length; + + current->next = m_alloc(sizeof(struct uri_tuple)); + current = current->next; + + current->name = "length"; + tmp = m_alloc(64); + snprintf(tmp, 64, "%zu", seed->buffer_length); + current->value = tmp; + current->valuelen = strlen(current->value); + + if(seed->buffer_length > 0){ + current->next = m_alloc(sizeof(struct uri_tuple)); + current = current->next; + + current->name = "buffer"; + current->value = seed->buffer; + current->valuelen = seed->buffer_length / 8; + + if( seed->buffer_length % 8 ) + current->valuelen += 1; + } + + current->next = NULL; + + return root; +} + +void +sign_seed( const char *seed_source , const char *outfile, STRLIST locusr) +{ + URI_TUPLE tuple; + tuple = read_tuple(seed_source); + + if( !tuple ) + BUG(); + + MD_SEED seed = tuple2seed(tuple); + + if( !seed ) + BUG(); + + MD_HANDLE md = md_read_seed(seed, 0); + if( !md ) + BUG(); + + PK_LIST pk_list = NULL; + SK_LIST sk_list = NULL; + int rc = 0; + u32 duration=0; + IOBUF out = NULL; + + armor_filter_context_t afx; + memset( &afx, 0, sizeof afx); + + PACKET pkt; + init_packet( &pkt ); + + if(!opt.force_v3_sigs && !RFC1991) + { + if(opt.ask_sig_expire && !opt.batch) + duration=ask_expire_interval(1,opt.def_sig_expire); + else + duration=parse_expire_string(opt.def_sig_expire); + } + + if( (rc = open_outfile( outfile, opt.armor ? 1 : 2, &out ))) + BUG(); + + if( !RFC1991 ) + afx.what = 2; + + if( opt.armor ) + iobuf_push_filter( out, armor_filter, &afx ); + + + if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) + BUG(); + + opt.def_digest_algo = md_get_algo(md); + + if(!opt.expert && + select_algo_from_prefs(pk_list,PREFTYPE_HASH, + opt.def_digest_algo, + NULL)!=opt.def_digest_algo) + log_info(_("WARNING: forcing digest algorithm %s (%d)" + " violates recipient preferences\n"), + digest_algo_to_string(opt.def_digest_algo), + opt.def_digest_algo); + + recipient_digest_algo = opt.def_digest_algo; + + /* write the signatures */ + rc = write_signature_packets (sk_list, out, md, + seed->sig_type, + 0, duration, 'D'); + + + if( rc ) + iobuf_cancel(out); + else { + iobuf_close(out); + } + md_close( md ); + release_sk_list( sk_list ); + release_pk_list( pk_list ); + recipient_digest_algo=0; +} + +void +print_seed( const char *fname, int algo , const char *outfile ) +{ + FILE *fp; + FILE *output; + + char buf[1024]; + size_t n; + MD_HANDLE md; + + if( opt.textmode ) + { + log_error(_("textmode isn't yet implemented for md seeds\n")); + return; + } + + + if( !outfile ) + output = stdout; + else { + output = fopen( outfile, "w" ); + if (fp && is_secured_file (fileno (fp))) + { + fclose (fp); + fp = NULL; + errno = EPERM; + } + } + + if( !output ) { + log_error("%s: %s\n", outfile , strerror(errno) ); + return; + } + + if( !fname ) { + fp = stdin; +#ifdef HAVE_DOSISH_SYSTEM + setmode ( fileno(fp) , O_BINARY ); +#endif + } + else { + fp = fopen( fname, "rb" ); + if (fp && is_secured_file (fileno (fp))) + { + fclose (fp); + fp = NULL; + errno = EPERM; + } + } + if( !fp ) { + log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) ); + return; + } + + if( algo ) + md = md_open( algo, 0 ); + else + BUG(); + + if( ! md ){ + printf("algo: %i\n", algo); + BUG(); + } + + while( (n=fread( buf, 1, DIM(buf), fp )) ) + md_write( md, buf, n ); + + + if( ferror(fp) ) + log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) ); + else { + MD_SEED seed; + seed = m_alloc( sizeof(struct md_seed) ); + md_write_seed( md, seed ); + + seed->sig_type = 0; // @todo@ handle text mode + + URI_TUPLE tuple = seed2tuple( seed ); + write_tuple(tuple, output); + fputc('\n', output); + } + + md_close(md); + + if( fp != stdin ) + fclose(fp); + + if( output != stdout ) { + fflush( output ); + fclose( output ); + } +} +#endif /* ENABLE_MD_SEED */ diff -urBbN gnupg-1.4.2/include/md_seed.h gnupg-1.4.2-md-seed-1/include/md_seed.h --- gnupg-1.4.2/include/md_seed.h 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.2-md-seed-1/include/md_seed.h 2006-02-19 15:44:13.000000000 +0100 @@ -0,0 +1,44 @@ +#ifndef MD_SEED_H +#define MD_SEED_H + +#ifdef ENABLE_MD_SEED +#include <byteswap.h> +#include "types.h" +#include "cipher.h" + +struct md_seed { + size_t buffer_length; // number of _bits_ yet to be hashed + byte * buffer; + + size_t state_length; // number of _bytes_ in the state buffer + byte * state; + + size_t block_count; + + byte algo; + byte sig_type; +}; + +typedef struct md_seed* MD_SEED; + +MD_HANDLE md_read_seed(MD_SEED seed, int secure); +void md_write_seed(MD_HANDLE md, MD_SEED seed); + +void print_seed( const char *fname, int algo, const char *outfile); +void sign_seed( const char *seed_source , const char *outfile, STRLIST locusr); + +#ifdef BIG_ENDIAN_HOST +#define hton_32(x) (x) +#define ntoh_32(x) (x) +#define hton_64(x) (x) +#define ntoh_64(x) (x) +#else +#define hton_32(x) (bswap_32(x)) +#define ntoh_32(x) (bswap_32(x)) +#define hton_64(x) (bswap_64(x)) +#define ntoh_64(x) (bswap_64(x)) +#endif /* BIG_ENDIAN_HOST */ + +#endif /* ENABLE_MD_SEED */ + +#endif /* MD_SEED_H */ -----BEGIN PGP SIGNATURE----- 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 jCshk85xvtQ= =mlWI -----END PGP SIGNATURE-----
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Gnupg-users mailing list Gnupg-users@gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-users