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 [email protected] http://lists.gnupg.org/mailman/listinfo/gnupg-users
