See ChangeLog: Fri Feb 26 17:55:41 CET 1999 Werner Koch

This commit is contained in:
Werner Koch 1999-02-26 16:59:48 +00:00
parent 946916a53d
commit 694099b9af
23 changed files with 362 additions and 251 deletions

18
BUGS
View File

@ -42,29 +42,27 @@ an "info standards" to find out why a disclaimer is needed for GNU.)
Buserror on IRIX 6.4: Crash while doing a keygen. I think while creating
the prime. Other buserrors are reported when doing a "gpg README"
on sparc-solaris2.6.
--> I hope I've fixed this: Please, can someone it. I can't reproduce it
on the alpha I have access to.
--> I hope I've fixed this: Please, can check someone it.
I can't reproduce it on the alpha I have access to.
[ **] #7 1999-02-22 <dwpalmer@dwpalm.jf.intel.com> 0.9.3
[ *] #7 1999-02-22 <dwpalmer@dwpalm.jf.intel.com> 0.9.3
Conventional encrytion incompatibilty:
$ gpg -c --cipher-algo cast5 --compress-algo 1 --no-comment secrets.txt
Creates a file that gpg can decrypt, but PGP 5.5 has problems with it.
PGP decrypts 6416k out of 6424k, then complains with "PGP Warning",
"The keyring contains a bad (corrupted) PGP packet". The resulting
file is missing information from the front.
[26.02.99: temporary fix in encrypt_simple()
[ *] #8 1999-02-25 <kazu@iijlab.net>
[ ] #8 1999-02-25 <kazu@iijlab.net> 0.9.3
%gpg --encrypt -r kazu@iijlab.net --batch foo
gpg: Warning: using insecure memory!
gpg: 11C23F61: no info to calculate a trust probability
This creates a symmetrically encrypted message WITHOUT a session key
encrypted with public cryptographic(i.e. foo.gpg). This is probably
because GNUPG encrypted a message with a random session key first then
tries to find public keys specified with the -r option. I don't like
this.
[26.02.99 fixed]
[ **] #9 1999-02-25
[ ] #9 1999-02-25
Misalignment in md5.c#md5_write.
[26.02.99 fixed]

View File

@ -1,3 +1,7 @@
Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* encode.c (encode_simple): temporary fix.
Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* configure.in: New option --enable-static-rnd.

1
THANKS
View File

@ -67,6 +67,7 @@ QingLong qinglong@bolizm.ihep.su
Ralph Gillen gillen@theochem.uni-duesseldorf.de
Rat ratinox@peorth.gweep.net
Reinhard Wobst R.Wobst@ifw-dresden.de
Rémi Guyomarch rguyomarch@ifn.fr
Reuben Sumner rasumner@wisdom.weizmann.ac.il
Roddy Strachan roddy@satlink.com.au
Roland Rosenfeld roland@spinnaker.rhein.de

12
TODO
View File

@ -18,17 +18,7 @@
What about 2.2 or should we use the system calls directly?
* when decryptiong multiple key: print a warning only if no usable pubkey
encrypte package was found. Extension: display a list of all recipients.
* in pkclist.c : display info about the key before saying that
we have (no) trust info.
* for new key: the last keyring specified is used. Order is: default
keyrings, keyrings from options, keyrings from the command line.
* display a kind of message-id from a signature (the timestamp may not
be suffiecient but DSA signatures are always different). This can
be used to prevent replay attacks. (something is mentioned in rfc2440).
encrypt package was found. Extension: display a list of all recipients.
Nice to have

View File

@ -64,5 +64,7 @@ data-32000:
data-80000:
../tools/mk-tdata 80000 >data-80000
plain-large:
cat ../doc/HACKING ../doc/DETAILS ../doc/FAQ >plain-large
cat $(srcdir)/../doc/HACKING \
$(srcdir)/../doc/DETAILS \
$(srcdir)/../doc/FAQ >plain-large

View File

@ -74,12 +74,11 @@ pgmname=`basename $0`
[ -z "$srcdir" ] && fatal "not called from make"
# Note don't use lock-once here because we call gpg in a pipe
cat <<EOF >./options
no-greeting
no-secmem-warning
load-extension ../cipher/tiger
load-extension ../cipher/rndlinux
batch
lock-once
EOF

View File

@ -1,3 +1,7 @@
Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* md.c: Nearly a total rewrote.
Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* cipher.c (context): Fixed alignment

View File

@ -1,5 +1,5 @@
/* md5.c - MD5 Message-Digest Algorithm
* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
* Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
*
* according to the definition of MD5 in RFC 1321 from April 1992.
* NOTE: This is *not* the same file as the one from glibc.
@ -19,7 +19,7 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
/* modified for GnuPG by <werner.koch@guug.de> */
/* heavily modified for GnuPG by <werner.koch@guug.de> */
/* Test values:
* "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
@ -40,24 +40,12 @@
typedef struct {
u32 A,B,C,D; /* chaining variables */
u32 total[2];
u32 buflen;
char buffer[128];
u32 nblocks;
byte buf[64];
int count;
} MD5_CONTEXT;
#ifdef BIG_ENDIAN_HOST
#define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else
#define SWAP(n) (n)
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
static void
md5_init( MD5_CONTEXT *ctx )
{
@ -66,8 +54,8 @@ md5_init( MD5_CONTEXT *ctx )
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
ctx->nblocks = 0;
ctx->count = 0;
}
@ -87,157 +75,137 @@ md5_init( MD5_CONTEXT *ctx )
* transform n*64 bytes
*/
static void
transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )
/*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/
transform( MD5_CONTEXT *ctx, byte *data )
{
u32 correct_words[16];
const u32 *words = buffer;
size_t nwords = len / sizeof(u32);
const u32 *endp = words + nwords;
u32 A = ctx->A;
u32 B = ctx->B;
u32 C = ctx->C;
u32 D = ctx->D;
u32 *cwp = correct_words;
/* First increment the byte count. RFC 1321 specifies the possible
length of the file up to 2^64 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] += len;
if( ctx->total[0] < len )
++ctx->total[1];
#ifdef BIG_ENDIAN_HOST
{ int i;
byte *p2, *p1;
for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) {
p2[3] = *p1++;
p2[2] = *p1++;
p2[1] = *p1++;
p2[0] = *p1++;
}
}
#else
memcpy( correct_words, data, 64 );
#endif
/* Process all bytes in the buffer with 64 bytes in each round of
the loop. */
while(words < endp) {
u32 *cwp = correct_words;
u32 A_save = A;
u32 B_save = B;
u32 C_save = C;
u32 D_save = D;
#define OP(a, b, c, d, s, T) \
do \
{ \
a += FF (b, c, d) + (*cwp++) + T; \
CYCLIC (a, s); \
a += b; \
} \
while (0)
/* First round: using the given function, the context and a constant
the next context is computed. Because the algorithm's processing
unit is a 32-bit word, and it is determined to work on words in
little endian byte order, we perhaps have to change the byte order
before the computation. To reduce the work for the next steps
we store the swapped words in the array CORRECT_WORDS. */
#define OP(a, b, c, d, s, T) \
do \
{ \
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
++words; \
CYCLIC (a, s); \
a += b; \
} \
while (0)
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
/* Before we start, one word about the strange constants.
They are defined in RFC 1321 as
/* Before we start, one word about the strange constants.
They are defined in RFC 1321 as
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/
/* Round 1. */
OP (A, B, C, D, 7, 0xd76aa478);
OP (D, A, B, C, 12, 0xe8c7b756);
OP (C, D, A, B, 17, 0x242070db);
OP (B, C, D, A, 22, 0xc1bdceee);
OP (A, B, C, D, 7, 0xf57c0faf);
OP (D, A, B, C, 12, 0x4787c62a);
OP (C, D, A, B, 17, 0xa8304613);
OP (B, C, D, A, 22, 0xfd469501);
OP (A, B, C, D, 7, 0x698098d8);
OP (D, A, B, C, 12, 0x8b44f7af);
OP (C, D, A, B, 17, 0xffff5bb1);
OP (B, C, D, A, 22, 0x895cd7be);
OP (A, B, C, D, 7, 0x6b901122);
OP (D, A, B, C, 12, 0xfd987193);
OP (C, D, A, B, 17, 0xa679438e);
OP (B, C, D, A, 22, 0x49b40821);
/* Round 1. */
OP (A, B, C, D, 7, 0xd76aa478);
OP (D, A, B, C, 12, 0xe8c7b756);
OP (C, D, A, B, 17, 0x242070db);
OP (B, C, D, A, 22, 0xc1bdceee);
OP (A, B, C, D, 7, 0xf57c0faf);
OP (D, A, B, C, 12, 0x4787c62a);
OP (C, D, A, B, 17, 0xa8304613);
OP (B, C, D, A, 22, 0xfd469501);
OP (A, B, C, D, 7, 0x698098d8);
OP (D, A, B, C, 12, 0x8b44f7af);
OP (C, D, A, B, 17, 0xffff5bb1);
OP (B, C, D, A, 22, 0x895cd7be);
OP (A, B, C, D, 7, 0x6b901122);
OP (D, A, B, C, 12, 0xfd987193);
OP (C, D, A, B, 17, 0xa679438e);
OP (B, C, D, A, 22, 0x49b40821);
/* For the second to fourth round we have the possibly swapped words
in CORRECT_WORDS. Redefine the macro to take an additional first
argument specifying the function to use. */
#undef OP
#define OP(f, a, b, c, d, k, s, T) \
do \
{ \
a += f (b, c, d) + correct_words[k] + T; \
CYCLIC (a, s); \
a += b; \
} \
while (0)
do \
{ \
a += f (b, c, d) + correct_words[k] + T; \
CYCLIC (a, s); \
a += b; \
} \
while (0)
/* Round 2. */
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
OP (FG, D, A, B, C, 10, 9, 0x02441453);
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
/* Round 2. */
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
OP (FG, D, A, B, C, 10, 9, 0x02441453);
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
/* Round 3. */
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
/* Round 3. */
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
/* Round 4. */
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
/* Add the starting values of the context. */
A += A_save;
B += B_save;
C += C_save;
D += D_save;
}
/* Round 4. */
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
/* Put checksum in context given as argument. */
ctx->A = A;
ctx->B = B;
ctx->C = C;
ctx->D = D;
ctx->A += A;
ctx->B += B;
ctx->C += C;
ctx->D += D;
}
@ -247,46 +215,33 @@ transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )
* in the message whose digest is being computed.
*/
static void
md5_write( MD5_CONTEXT *ctx, const void *buffer, size_t len)
md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
if( hd->count == 64 ) { /* flush the buffer */
transform( hd, hd->buf );
hd->count = 0;
hd->nblocks++;
}
if( !inbuf )
return;
if( hd->count ) {
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
md5_write( hd, NULL, 0 );
if( !inlen )
return;
}
memcpy (&ctx->buffer[left_over], buffer, add);
ctx->buflen += add;
while( inlen >= 64 ) {
transform( hd, inbuf );
hd->count = 0;
hd->nblocks++;
inlen -= 64;
inbuf += 64;
}
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
if (left_over + add > 64)
{
transform(ctx, ctx->buffer, (left_over + add) & ~63);
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
(left_over + add) & 63);
ctx->buflen = (left_over + add) & 63;
}
buffer = (const char *) buffer + add;
len -= add;
/* FIXME: misalignment occurs ... tsssss */
}
/* Process available complete blocks. */
if (len > 64)
{
transform( ctx, buffer, len & ~63);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
/* Move remaining bytes in internal buffer. */
if (len > 0)
{
memcpy (ctx->buffer, buffer, len);
ctx->buflen = len;
}
}
@ -298,39 +253,68 @@ md5_write( MD5_CONTEXT *ctx, const void *buffer, size_t len)
*/
static void
md5_final( MD5_CONTEXT *ctx )
md5_final( MD5_CONTEXT *hd )
{
/* Take yet unprocessed bytes into account. */
u32 bytes = ctx->buflen;
size_t pad;
u32 t, msb, lsb;
byte *p;
/* Now count remaining bytes. */
ctx->total[0] += bytes;
if( ctx->total[0] < bytes )
++ctx->total[1];
md5_write(hd, NULL, 0); /* flush */;
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
memcpy (&ctx->buffer[bytes], fillbuf, pad);
msb = 0;
t = hd->nblocks;
if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
msb++;
msb += t >> 26;
t = lsb;
if( (lsb = t + hd->count) < t ) /* add the count */
msb++;
t = lsb;
if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
msb++;
msb += t >> 29;
/* Put the 64-bit file length in *bits* at the end of the buffer. */
*(u32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
*(u32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
(ctx->total[0] >> 29));
if( hd->count < 56 ) { /* enough room */
hd->buf[hd->count++] = 0x80; /* pad */
while( hd->count < 56 )
hd->buf[hd->count++] = 0; /* pad */
}
else { /* need one extra block */
hd->buf[hd->count++] = 0x80; /* pad character */
while( hd->count < 64 )
hd->buf[hd->count++] = 0;
md5_write(hd, NULL, 0); /* flush */;
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
hd->buf[56] = lsb ;
hd->buf[57] = lsb >> 8;
hd->buf[58] = lsb >> 16;
hd->buf[59] = lsb >> 24;
hd->buf[60] = msb ;
hd->buf[61] = msb >> 8;
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform( hd, hd->buf );
/* Process last bytes. */
transform( ctx, ctx->buffer, bytes + pad + 8);
p = hd->buf;
#ifdef BIG_ENDIAN_HOST
#define X(a) do { *p++ = hd->##a ; *p++ = hd->##a >> 8; \
*p++ = hd->##a >> 16; *p++ = hd->##a >> 24; } while(0)
#else /* little endian */
#define X(a) do { *(u32*)p = hd->##a ; p += 4; } while(0)
#endif
X(A);
X(B);
X(C);
X(D);
#undef X
/* Store the result in buffer */
((u32 *)ctx->buffer)[0] = SWAP (ctx->A);
((u32 *)ctx->buffer)[1] = SWAP (ctx->B);
((u32 *)ctx->buffer)[2] = SWAP (ctx->C);
((u32 *)ctx->buffer)[3] = SWAP (ctx->D);
}
static byte *
md5_read( MD5_CONTEXT *hd )
{
return hd->buffer;
return hd->buf;
}
/****************

View File

@ -173,8 +173,6 @@ rol(int n, u32 x)
static void
transform( RMD160_CONTEXT *hd, byte *data )
{
u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
#ifdef BIG_ENDIAN_HOST
u32 x[16];

View File

@ -125,7 +125,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
"\n"
"Not enough random bytes available. Please do some other work to give\n"
"the OS a chance to collect more entropy! (Need %d more bytes)\n"), length );
warn = 0; /* <--- set to 1 to display the message only once */
warn = 1;
continue;
}
else if( rc == -1 ) {
@ -140,17 +140,23 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
/* process reply */
if( n == -1 )
g10_log_error("read error on EGD: %s\n", strerror(errno));
else if( n < 2 )
else if( cmd == 2 && n != nbytes ) {
g10_log_error("bad EGD reply: too short %d/%d\n", nbytes, n );
}
else if( cmd == 2 ) {
(*add)( buffer, n, requester );
length -= n;
}
else if( !n )
g10_log_error("bad EGD reply: too short\n");
else if( buffer[0] != cmd )
g10_log_error("bad EGD reply: cmd mismatch %d/%d\n",
cmd, *buffer );
else if( buffer[1] != nbytes )
else if( buffer[0] != n-1 )
g10_log_error("bad EGD reply: count mismatch %d/%d\n",
nbytes, buffer[1] );
n-1, buffer[0] );
else if( n==1 )
g10_log_info("no data from EGD\n");
else {
n -= 2;
(*add)( buffer+2, n, requester );
n -= 1;
(*add)( buffer+1, n, requester );
length -= n;
}
}

View File

@ -64,6 +64,12 @@ more arguments in future versions.
as GOODSIG but has the fingerprint as the argument. Both
status lines ere emitted for a good signature.
SIG_ID <radix64_string>
This is emitted only for DSA or ElGamal signatures which
have been verified okay. The strings is a signature id
and maybe used in applications to detect replay attacks
of signed messages.
TRUST_UNDEFINED
TRUST_NEVER
TRUST_MARGINAL

View File

@ -1,3 +1,18 @@
Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* pkclist.c (build_pk_list): Return error if there are no recipients.
* sig-check.c (signature_check): New signature id feature.
* armor.c (make_radic64_string): New.
* mainproc.c (proc_pubkey_enc): early check for seckey availability.
* pkclist.c (do_we_trust_pre): print user id before asking.
* ringedit.c (add_keyblock_resource,get_keyblock_handle): Cleaner
handling of default resource.
Thu Feb 25 18:47:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* pkclist.c (algo_available): New.

View File

@ -1007,4 +1007,31 @@ armor_filter( void *opaque, int control,
}
/****************
* create a radix64 encoded string.
*/
char *
make_radix64_string( const byte *data, size_t len )
{
char *buffer, *p;
buffer = p = m_alloc( (len+2)/3*4 + 1 );
for( ; len >= 3 ; len -= 3, data += 3 ) {
*p++ = bintoasc[(data[0] >> 2) & 077];
*p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
*p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
*p++ = bintoasc[data[2]&077];
}
if( len == 2 ) {
*p++ = bintoasc[(data[0] >> 2) & 077];
*p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
*p++ = bintoasc[((data[1]<<2)&074)];
}
else if( len == 1 ) {
*p++ = bintoasc[(data[0] >> 2) & 077];
*p++ = bintoasc[(data[0] <<4)&060];
}
*p = 0;
return buffer;
}

View File

@ -150,7 +150,13 @@ encode_simple( const char *filename, int mode )
pt = m_alloc( sizeof *pt - 1 );
pt->namelen = 0;
}
if( filename ) {
/* pgp5 has problems to decrypt symmetrically encrypted data from
* GnuPOG if the filelength is in the inner packet. It works
* when only partial length headers are use. Until we have
* tracked this problem down. We use this temporary fix
* (fixme: remove the && !mode )
*/
if( filename && !mode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
}

View File

@ -49,6 +49,9 @@ void print_pubkey_algo_note( int algo );
void print_cipher_algo_note( int algo );
void print_digest_algo_note( int algo );
/*-- armor.c --*/
char *make_radix64_string( const byte *data, size_t len );
/*-- misc.c --*/
void trap_unaligned(void);
void disable_core_dumps(void);

View File

@ -178,10 +178,13 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
c->last_was_session_key = 1;
enc = pkt->pkt.pubkey_enc;
/*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
/* Hmmm: why do I have this algo check here - anyway there is
* function to check it. */
if( is_ELGAMAL(enc->pubkey_algo)
|| enc->pubkey_algo == PUBKEY_ALGO_DSA
|| is_RSA(enc->pubkey_algo) ) {
if ( !c->dek ) {
if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
|| !seckey_available( enc->keyid )) ) {
c->dek = m_alloc_secure( sizeof *c->dek );
if( (result = get_session_key( enc, c->dek )) ) {
/* error: delete the DEK */

View File

@ -230,6 +230,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
}
lid = pk->local_id;
#if 0 /* FIXME: enable this when trustdb stuff works again */
while( enum_cert_paths( &context, &lid, &otrust, &validity ) != -1 ) {
if( lid == pk->local_id )
continue;
@ -256,6 +257,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
}
}
enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
#endif
if( !any )
tty_printf(_("No path leading to one of our keys found.\n\n") );
@ -374,6 +376,19 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
return 0;
else if( !opt.batch && !rc ) {
char *p;
u32 keyid[2];
size_t n;
keyid_from_pk( pk, keyid);
tty_printf( "%4u%c/%08lX %s \"",
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], datestr_from_pk( pk ) );
p = get_user_id( keyid, &n );
tty_print_string( p, n ),
m_free(p);
tty_printf("\"\n\n");
tty_printf(_(
"It is NOT certain that the key belongs to its owner.\n"
"If you *really* know what you are doing, you may answer\n"
@ -382,6 +397,10 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
if( cpr_get_answer_is_yes("untrusted_key.override",
_("Use this key anyway? ")) )
rc = 1;
/* Hmmm: Should we set a flag to tell the user the user about
* his decision the next time he encrypts for this recipient?
*/
}
else if( opt.always_trust && !rc ) {
log_info(_("WARNING: Using untrusted key!\n"));
@ -598,6 +617,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
}
}
else {
any_recipients = 0;
for(; remusr; remusr = remusr->next ) {
if( (remusr->flags & 1) )
continue; /* encrypt-to keys are already handled */

View File

@ -79,6 +79,8 @@ typedef struct resource_table_struct RESTBL;
#define MAX_RESOURCES 10
static RESTBL resource_table[MAX_RESOURCES];
static int default_public_resource;
static int default_secret_resource;
static int search( PACKET *pkt, KBPOS *kbpos, int secret );
@ -348,11 +350,17 @@ add_keyblock_resource( const char *url, int force, int secret )
goto leave;
}
/* fixme: avoid duplicate resources */
resource_table[i].used = 1;
resource_table[i].secret = !!secret;
resource_table[i].fname = m_strdup(filename);
resource_table[i].iobuf = iobuf;
resource_table[i].rt = rt;
if( secret )
default_secret_resource = i;
else
default_public_resource = i;
leave:
if( rc )
log_error("keyblock resource `%s': %s\n", filename, g10_errstr(rc) );
@ -386,9 +394,12 @@ keyblock_resource_name( KBPOS *kbpos )
int
get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
{
int i;
int i = 0;
for(i=0; i < MAX_RESOURCES; i++ )
if( !filename )
i = secret? default_secret_resource : default_public_resource;
for(; i < MAX_RESOURCES; i++ ) {
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
/* fixme: dos needs case insensitive file compare */
if( !filename || !strcmp( resource_table[i].fname, filename ) ) {
@ -398,6 +409,7 @@ get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
return 0;
}
}
}
return -1; /* not found */
}

View File

@ -64,6 +64,34 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
rc = do_check( pk, sig, digest );
free_public_key( pk );
if( !rc && is_status_enabled()
&& ( sig->pubkey_algo == PUBKEY_ALGO_DSA
|| sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) ) {
/* If we are using these public key algorithms we can
* calculate an unique signature id, which may be useful
* in an application to prevent replac attacks */
MD_HANDLE md;
int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
byte *p;
md = md_open( DIGEST_ALGO_RMD160, 0);
for(i=0; i < nsig; i++ ) {
unsigned n = mpi_get_nbits( sig->data[i]);
md_putc( md, n>>8);
md_putc( md, n );
p = mpi_get_buffer( sig->data[i], &n, NULL );
md_write( md, p, n );
m_free(p);
}
md_final( md );
p = make_radix64_string( md_read( md, 0 ), 20 );
write_status_text( STATUS_SIG_ID, p );
m_free(p);
md_close(md);
}
return rc;
}

View File

@ -98,6 +98,7 @@ write_status_text ( int no, const char *text)
case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN\n"; break;
case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE\n"; break;
case STATUS_VALIDSIG : s = "VALIDSIG\n"; break;
case STATUS_SIG_ID : s = "SIG_ID\n"; break;
default: s = "?\n"; break;
}

View File

@ -49,6 +49,7 @@
#define STATUS_NEED_PASSPHRASE 20
#define STATUS_VALIDSIG 21
#define STATUS_SIG_ID 22
/*-- status.c --*/
void set_status_fd ( int fd );

View File

@ -1,3 +1,7 @@
Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* secmem.c (memblock_struct): Force align (Rémi Guyomarch)
Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* iobuf.c (block_filter): Fixed the oscillating partial packet chunks.

View File

@ -47,8 +47,7 @@ struct memblock_struct {
unsigned size;
union {
MEMBLOCK *next;
long align_dummy;
char d[1];
PROPERLY_ALIGNED_TYPE aligned;
} u;
};
@ -291,7 +290,7 @@ secmem_malloc( size_t size )
max_alloced = cur_alloced;
if( cur_blocks > max_blocks )
max_blocks = cur_blocks;
return &mb->u.d;
return &mb->u.aligned.c;
}
@ -302,7 +301,7 @@ secmem_realloc( void *p, size_t newsize )
size_t size;
void *a;
mb = (MEMBLOCK*)((char*)p - ((size_t) &((MEMBLOCK*)0)->u.d));
mb = (MEMBLOCK*)((char*)p - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
size = mb->size;
if( newsize < size )
return p; /* it is easier not to shrink the memory */
@ -323,7 +322,7 @@ secmem_free( void *a )
if( !a )
return;
mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.d));
mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
size = mb->size;
memset(mb, 0xff, size );
memset(mb, 0xaa, size );