mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
IDEA removed, signing works
This commit is contained in:
parent
db19a27518
commit
a51cca90b6
7
TODO
7
TODO
@ -5,14 +5,12 @@
|
|||||||
* add a way to difference between errors and eof in the underflow/flush
|
* add a way to difference between errors and eof in the underflow/flush
|
||||||
function of iobuf.
|
function of iobuf.
|
||||||
* filter all output read from the input when displaying it to the user.
|
* filter all output read from the input when displaying it to the user.
|
||||||
* remove idea.
|
|
||||||
* keyring editing
|
* keyring editing
|
||||||
* improve the prime number generator
|
* improve the prime number generator
|
||||||
* remove some debugging stuff (e.g. the listing mode in mainproc)
|
* remove some debugging stuff (e.g. the listing mode in mainproc)
|
||||||
* add trust stuff
|
* add trust stuff
|
||||||
* make ttyio.c work (hide passwords etc..)
|
* make ttyio.c work (hide passwords etc..)
|
||||||
* add signal handling
|
* add detached signatures
|
||||||
* add writing of signatures and checking of detached signatures.
|
|
||||||
* add option file handling.
|
* add option file handling.
|
||||||
* use correct ASN values for DEK encoding
|
* use correct ASN values for DEK encoding
|
||||||
* add checking of armor trailers
|
* add checking of armor trailers
|
||||||
@ -20,11 +18,12 @@
|
|||||||
* add real secure memory
|
* add real secure memory
|
||||||
* look for a way to reuse RSA signatures
|
* look for a way to reuse RSA signatures
|
||||||
* add ElGamal and make it the default one.
|
* add ElGamal and make it the default one.
|
||||||
* find a way to remove the arnor filter after it
|
* find a way to remove the armor filter after it
|
||||||
has detected, that the data is not armored.
|
has detected, that the data is not armored.
|
||||||
* Use the Chines Remainder Theorem to speed up RSA calculations.
|
* Use the Chines Remainder Theorem to speed up RSA calculations.
|
||||||
* remove all "Fixmes"
|
* remove all "Fixmes"
|
||||||
* add credits for the MPI lib.
|
* add credits for the MPI lib.
|
||||||
* speed up the RIPE-MD-160
|
* speed up the RIPE-MD-160
|
||||||
|
* add signal handling
|
||||||
* enable a SIGSEGV handler while using zlib functions
|
* enable a SIGSEGV handler while using zlib functions
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@ cipher_SOURCES = blowfish.c \
|
|||||||
elgamal.h \
|
elgamal.h \
|
||||||
gost.c \
|
gost.c \
|
||||||
gost.h \
|
gost.h \
|
||||||
idea.c \
|
|
||||||
idea.h \
|
|
||||||
md5.c \
|
md5.c \
|
||||||
md5.h \
|
md5.h \
|
||||||
primegen.c \
|
primegen.c \
|
||||||
|
@ -48,8 +48,6 @@ cipher_SOURCES = blowfish.c \
|
|||||||
elgamal.h \
|
elgamal.h \
|
||||||
gost.c \
|
gost.c \
|
||||||
gost.h \
|
gost.h \
|
||||||
idea.c \
|
|
||||||
idea.h \
|
|
||||||
md5.c \
|
md5.c \
|
||||||
md5.h \
|
md5.h \
|
||||||
primegen.c \
|
primegen.c \
|
||||||
@ -79,8 +77,8 @@ LIBS = @LIBS@
|
|||||||
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||||
LINK = $(CC) $(LDFLAGS) -o $@
|
LINK = $(CC) $(LDFLAGS) -o $@
|
||||||
cipher_LIBADD =
|
cipher_LIBADD =
|
||||||
cipher_OBJECTS = blowfish.o elgamal.o gost.o idea.o md5.o primegen.o \
|
cipher_OBJECTS = blowfish.o elgamal.o gost.o md5.o primegen.o random.o \
|
||||||
random.o rmd160.o rsa.o smallprime.o
|
rmd160.o rsa.o smallprime.o
|
||||||
EXTRA_cipher_SOURCES =
|
EXTRA_cipher_SOURCES =
|
||||||
LIBFILES = libcipher.a
|
LIBFILES = libcipher.a
|
||||||
AR = ar
|
AR = ar
|
||||||
@ -98,9 +96,8 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
|
|||||||
|
|
||||||
TAR = tar
|
TAR = tar
|
||||||
DEP_FILES = $(srcdir)/.deps/blowfish.P $(srcdir)/.deps/elgamal.P \
|
DEP_FILES = $(srcdir)/.deps/blowfish.P $(srcdir)/.deps/elgamal.P \
|
||||||
$(srcdir)/.deps/gost.P $(srcdir)/.deps/idea.P $(srcdir)/.deps/md5.P \
|
$(srcdir)/.deps/gost.P $(srcdir)/.deps/md5.P $(srcdir)/.deps/primegen.P \
|
||||||
$(srcdir)/.deps/primegen.P $(srcdir)/.deps/random.P \
|
$(srcdir)/.deps/random.P $(srcdir)/.deps/rmd160.P $(srcdir)/.deps/rsa.P \
|
||||||
$(srcdir)/.deps/rmd160.P $(srcdir)/.deps/rsa.P \
|
|
||||||
$(srcdir)/.deps/smallprime.P
|
$(srcdir)/.deps/smallprime.P
|
||||||
SOURCES = $(cipher_SOURCES)
|
SOURCES = $(cipher_SOURCES)
|
||||||
OBJECTS = $(cipher_OBJECTS)
|
OBJECTS = $(cipher_OBJECTS)
|
||||||
|
352
cipher/idea.c
352
cipher/idea.c
@ -1,352 +0,0 @@
|
|||||||
/* idea.c - IDEA function
|
|
||||||
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
|
||||||
*
|
|
||||||
* ATTENTION: This code patented and needs a license for any commercial use.
|
|
||||||
*
|
|
||||||
* The code herin is take from:
|
|
||||||
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
|
|
||||||
* ISBN 0-471-11709-9. .
|
|
||||||
*
|
|
||||||
* This file is part of G10.
|
|
||||||
*
|
|
||||||
* G10 is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* G10 is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "util.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "idea.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static u16
|
|
||||||
mul_inv( u16 x )
|
|
||||||
{
|
|
||||||
u16 t0, t1;
|
|
||||||
u16 q, y;
|
|
||||||
|
|
||||||
if( x < 2 )
|
|
||||||
return x;
|
|
||||||
t1 = 0x10001L / x;
|
|
||||||
y = 0x10001L % x;
|
|
||||||
if( y == 1 )
|
|
||||||
return (1-t1) & 0xffff;
|
|
||||||
|
|
||||||
t0 = 1;
|
|
||||||
do {
|
|
||||||
q = x / y;
|
|
||||||
x = x % y;
|
|
||||||
t0 += q * t1;
|
|
||||||
if( x == 1 )
|
|
||||||
return t0;
|
|
||||||
q = y / x;
|
|
||||||
y = y % x;
|
|
||||||
t1 += q * t0;
|
|
||||||
} while( y != 1 );
|
|
||||||
return (1-t1) & 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
expand_key( byte *userkey, u16 *ek )
|
|
||||||
{
|
|
||||||
int i,j;
|
|
||||||
|
|
||||||
for(j=0; j < 8; j++ ) {
|
|
||||||
ek[j] = (*userkey << 8) + userkey[1];
|
|
||||||
userkey += 2;
|
|
||||||
}
|
|
||||||
for(i=0; j < IDEA_KEYLEN; j++ ) {
|
|
||||||
i++;
|
|
||||||
ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
|
|
||||||
ek += i & 8;
|
|
||||||
i &= 7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
u16 t1, t2, t3;
|
|
||||||
u16 temp[IDEA_KEYLEN];
|
|
||||||
u16 *p = temp + IDEA_KEYLEN;
|
|
||||||
|
|
||||||
t1 = mul_inv( *ek++ );
|
|
||||||
t2 = -*ek++;
|
|
||||||
t3 = -*ek++;
|
|
||||||
*--p = mul_inv( *ek++ );
|
|
||||||
*--p = t3;
|
|
||||||
*--p = t2;
|
|
||||||
*--p = t1;
|
|
||||||
|
|
||||||
for(i=0; i < IDEA_ROUNDS-1; i++ ) {
|
|
||||||
t1 = *ek++;
|
|
||||||
*--p = *ek++;
|
|
||||||
*--p = t1;
|
|
||||||
|
|
||||||
t1 = mul_inv( *ek++ );
|
|
||||||
t2 = -*ek++;
|
|
||||||
t3 = -*ek++;
|
|
||||||
*--p = mul_inv( *ek++ );
|
|
||||||
*--p = t3;
|
|
||||||
*--p = t2;
|
|
||||||
*--p = t1;
|
|
||||||
}
|
|
||||||
t1 = *ek++;
|
|
||||||
*--p = *ek++;
|
|
||||||
*--p = t1;
|
|
||||||
|
|
||||||
t1 = mul_inv( *ek++ );
|
|
||||||
t2 = -*ek++;
|
|
||||||
t3 = -*ek++;
|
|
||||||
*--p = mul_inv( *ek++ );
|
|
||||||
*--p = t3;
|
|
||||||
*--p = t2;
|
|
||||||
*--p = t1;
|
|
||||||
memcpy(dk, temp, sizeof(temp) );
|
|
||||||
memset(temp, 0, sizeof(temp) ); /* burn temp */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
cipher( byte *outbuf, byte *inbuf, u16 *key )
|
|
||||||
{
|
|
||||||
u16 x1, x2, x3,x4, s2, s3;
|
|
||||||
u16 *in, *out;
|
|
||||||
int r = IDEA_ROUNDS;
|
|
||||||
#define MUL(x,y) \
|
|
||||||
do {u16 _t16; u32 _t32; \
|
|
||||||
if( (_t16 = (y)) ) { \
|
|
||||||
if( (x = (x)&0xffff) ) { \
|
|
||||||
_t32 = (u32)x * _t16; \
|
|
||||||
x = _t32 & 0xffff; \
|
|
||||||
_t16 = _t32 >> 16; \
|
|
||||||
x = ((x)-_t16) + (x<_t16?1:0); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
x = 1 - _t16; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
x = 1 - x; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
in = (u16*)inbuf;
|
|
||||||
x1 = *in++;
|
|
||||||
x2 = *in++;
|
|
||||||
x3 = *in++;
|
|
||||||
x4 = *in;
|
|
||||||
#ifdef HAVE_LITTLE_ENDIAN
|
|
||||||
x1 = (x1>>8) | (x1<<8);
|
|
||||||
x2 = (x2>>8) | (x2<<8);
|
|
||||||
x3 = (x3>>8) | (x3<<8);
|
|
||||||
x4 = (x4>>8) | (x4<<8);
|
|
||||||
#endif
|
|
||||||
do {
|
|
||||||
MUL(x1, *key++);
|
|
||||||
x2 += *key++;
|
|
||||||
x3 += *key++;
|
|
||||||
MUL(x4, *key++ );
|
|
||||||
|
|
||||||
s3 = x3;
|
|
||||||
x3 ^= x1;
|
|
||||||
MUL(x3, *key++);
|
|
||||||
s2 = x2;
|
|
||||||
x2 ^=x4;
|
|
||||||
x2 += x3;
|
|
||||||
MUL(x2, *key++);
|
|
||||||
x3 += x2;
|
|
||||||
|
|
||||||
x1 ^= x2;
|
|
||||||
x4 ^= x3;
|
|
||||||
|
|
||||||
x2 ^= s3;
|
|
||||||
x3 ^= s2;
|
|
||||||
} while( --r );
|
|
||||||
MUL(x1, *key++);
|
|
||||||
x3 += *key++;
|
|
||||||
x2 += *key++;
|
|
||||||
MUL(x4, *key);
|
|
||||||
|
|
||||||
out = (u16*)outbuf;
|
|
||||||
#ifdef HAVE_LITTLE_ENDIAN
|
|
||||||
*out++ = (x1>>8) | (x1<<8);
|
|
||||||
*out++ = (x3>>8) | (x3<<8);
|
|
||||||
*out++ = (x2>>8) | (x2<<8);
|
|
||||||
*out = (x4>>8) | (x4<<8);
|
|
||||||
#else
|
|
||||||
*out++ = x1;
|
|
||||||
*out++ = x3;
|
|
||||||
*out++ = x2;
|
|
||||||
*out = x4;
|
|
||||||
#endif
|
|
||||||
#undef MUL
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
idea_setkey( IDEA_context *c, byte *key )
|
|
||||||
{
|
|
||||||
expand_key( key, c->ek );
|
|
||||||
invert_key( c->ek, c->dk );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
idea_setiv( IDEA_context *c, byte *iv )
|
|
||||||
{
|
|
||||||
if( iv )
|
|
||||||
memcpy( c->iv, iv, IDEA_BLOCKSIZE );
|
|
||||||
else
|
|
||||||
memset( c->iv, 0, IDEA_BLOCKSIZE );
|
|
||||||
c->nleft = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
idea_encode( IDEA_context *c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
|
||||||
{
|
|
||||||
unsigned n;
|
|
||||||
|
|
||||||
for(n=0; n < nblocks; n++ ) {
|
|
||||||
cipher( outbuf, inbuf, c->ek );
|
|
||||||
inbuf += 8;
|
|
||||||
outbuf += 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
idea_decode( IDEA_context *c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
|
||||||
{
|
|
||||||
unsigned n;
|
|
||||||
|
|
||||||
for(n=0; n < nblocks; n++ ) {
|
|
||||||
cipher( outbuf, inbuf, c->dk );
|
|
||||||
inbuf += 8;
|
|
||||||
outbuf += 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
cfbshift( byte *iv, byte *buf, unsigned count)
|
|
||||||
{
|
|
||||||
unsigned n;
|
|
||||||
|
|
||||||
if( count ) {
|
|
||||||
for( n = IDEA_BLOCKSIZE - count; n; n-- )
|
|
||||||
*iv++ = iv[count];
|
|
||||||
for( ; count; count-- )
|
|
||||||
*iv++ = *buf++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* FIXME: Make use of bigger chunks
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
xorblock( byte *out, byte *a, byte *b, unsigned count )
|
|
||||||
{
|
|
||||||
for( ; count ; count--, a++, b++ )
|
|
||||||
*out++ = *a ^ *b ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
idea_encode_cfb( IDEA_context *c, byte *outbuf, byte *inbuf, unsigned nbytes)
|
|
||||||
{
|
|
||||||
byte temp[IDEA_BLOCKSIZE];
|
|
||||||
|
|
||||||
while( nbytes >= IDEA_BLOCKSIZE ) {
|
|
||||||
cipher( temp, c->iv, c->ek );
|
|
||||||
xorblock( outbuf, inbuf, temp, IDEA_BLOCKSIZE);
|
|
||||||
cfbshift( c->iv, outbuf, IDEA_BLOCKSIZE );
|
|
||||||
nbytes -= IDEA_BLOCKSIZE;
|
|
||||||
inbuf += IDEA_BLOCKSIZE;
|
|
||||||
outbuf += IDEA_BLOCKSIZE;
|
|
||||||
}
|
|
||||||
if( nbytes ) {
|
|
||||||
cipher( temp, c->iv, c->ek );
|
|
||||||
xorblock( outbuf, inbuf, temp, nbytes );
|
|
||||||
cfbshift( c->iv, outbuf, nbytes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
idea_decode_cfb( IDEA_context *c, byte *outbuf, byte *inbuf, unsigned nbytes)
|
|
||||||
{
|
|
||||||
byte t, *ivptr;
|
|
||||||
|
|
||||||
ivptr = c->iv + IDEA_BLOCKSIZE - c->nleft;
|
|
||||||
if( nbytes <= c->nleft ) {
|
|
||||||
c->nleft -= nbytes;
|
|
||||||
for( ; nbytes ; nbytes--, ivptr++, inbuf++ ) {
|
|
||||||
t = *ivptr;
|
|
||||||
*outbuf++ = t ^ (*ivptr = *inbuf) ;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nbytes -= c->nleft;
|
|
||||||
for( ; c->nleft ; c->nleft--, ivptr++, inbuf++ ) {
|
|
||||||
t = *ivptr;
|
|
||||||
*outbuf++ = t ^ (*ivptr = *inbuf) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
while( nbytes >= IDEA_BLOCKSIZE ) {
|
|
||||||
memcpy(c->lastcipher, c->iv, IDEA_BLOCKSIZE);
|
|
||||||
cipher( c->iv, c->iv, c->ek );
|
|
||||||
c->nleft = IDEA_BLOCKSIZE;
|
|
||||||
nbytes -= IDEA_BLOCKSIZE;
|
|
||||||
ivptr = c->iv;
|
|
||||||
for( ; c->nleft; c->nleft--, ivptr++, inbuf++ ) {
|
|
||||||
t = *ivptr;
|
|
||||||
*outbuf++ = t ^ (*ivptr = *inbuf) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memcpy(c->lastcipher, c->iv, IDEA_BLOCKSIZE);
|
|
||||||
cipher( c->iv, c->iv, c->ek );
|
|
||||||
c->nleft = IDEA_BLOCKSIZE - nbytes;
|
|
||||||
ivptr = c->iv;
|
|
||||||
for( ; nbytes; nbytes--, ivptr++, inbuf++ ) {
|
|
||||||
t = *ivptr;
|
|
||||||
*outbuf++ = t ^ (*ivptr = *inbuf) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* This is used for the special way IDEA CFB is used in PGP
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
idea_sync_cfb( IDEA_context *c )
|
|
||||||
{
|
|
||||||
if( c->nleft ) {
|
|
||||||
memmove(c->iv + c->nleft, c->iv, IDEA_BLOCKSIZE - c->nleft );
|
|
||||||
memcpy(c->iv, c->lastcipher + IDEA_BLOCKSIZE - c->nleft, c->nleft);
|
|
||||||
c->nleft = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
/* idea.h
|
|
||||||
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
|
||||||
*
|
|
||||||
* ATTENTION: This code patented and needs a license for any commercial use.
|
|
||||||
*
|
|
||||||
* This file is part of G10.
|
|
||||||
*
|
|
||||||
* G10 is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* G10 is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
||||||
*/
|
|
||||||
#ifndef G10_IDEA_H
|
|
||||||
#define G10_IDEA_H
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#define IDEA_KEYSIZE 16
|
|
||||||
#define IDEA_BLOCKSIZE 8
|
|
||||||
#define IDEA_ROUNDS 8
|
|
||||||
#define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u16 ek[IDEA_KEYLEN];
|
|
||||||
u16 dk[IDEA_KEYLEN];
|
|
||||||
byte iv[IDEA_BLOCKSIZE];
|
|
||||||
byte lastcipher[IDEA_BLOCKSIZE];
|
|
||||||
int nleft;
|
|
||||||
} IDEA_context;
|
|
||||||
|
|
||||||
void idea_setkey( IDEA_context *c, byte *key );
|
|
||||||
void idea_setiv( IDEA_context *c, byte *iv );
|
|
||||||
void idea_encode( IDEA_context *c, byte *out, byte *in, unsigned nblocks );
|
|
||||||
void idea_decode( IDEA_context *c, byte *out, byte *in, unsigned nblocks );
|
|
||||||
void idea_encode_cfb( IDEA_context *c, byte *outbuf,
|
|
||||||
byte *inbuf, unsigned nbytes);
|
|
||||||
void idea_decode_cfb( IDEA_context *c, byte *outbuf,
|
|
||||||
byte *inbuf, unsigned nbytes);
|
|
||||||
void idea_sync_cfb( IDEA_context *c );
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*G10_IDEA_H*/
|
|
@ -20,7 +20,7 @@ g10_SOURCES = g10.c \
|
|||||||
mdfilter.c \
|
mdfilter.c \
|
||||||
cipher.c \
|
cipher.c \
|
||||||
options.h \
|
options.h \
|
||||||
overwrite.c \
|
openfile.c \
|
||||||
packet.h \
|
packet.h \
|
||||||
parse-packet.c \
|
parse-packet.c \
|
||||||
passphrase.c \
|
passphrase.c \
|
||||||
@ -28,6 +28,8 @@ g10_SOURCES = g10.c \
|
|||||||
pubkey-enc.c \
|
pubkey-enc.c \
|
||||||
seckey-cert.c \
|
seckey-cert.c \
|
||||||
seskey.c \
|
seskey.c \
|
||||||
|
sign.c \
|
||||||
|
comment.c \
|
||||||
sig-check.c
|
sig-check.c
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ g10_SOURCES = g10.c \
|
|||||||
mdfilter.c \
|
mdfilter.c \
|
||||||
cipher.c \
|
cipher.c \
|
||||||
options.h \
|
options.h \
|
||||||
overwrite.c \
|
openfile.c \
|
||||||
packet.h \
|
packet.h \
|
||||||
parse-packet.c \
|
parse-packet.c \
|
||||||
passphrase.c \
|
passphrase.c \
|
||||||
@ -66,6 +66,8 @@ g10_SOURCES = g10.c \
|
|||||||
pubkey-enc.c \
|
pubkey-enc.c \
|
||||||
seckey-cert.c \
|
seckey-cert.c \
|
||||||
seskey.c \
|
seskey.c \
|
||||||
|
sign.c \
|
||||||
|
comment.c \
|
||||||
sig-check.c
|
sig-check.c
|
||||||
|
|
||||||
LDADD = -L ../cipher -L ../mpi -L ../util -lcipher -lmpi -lutil -lz
|
LDADD = -L ../cipher -L ../mpi -L ../util -lcipher -lmpi -lutil -lz
|
||||||
@ -88,8 +90,8 @@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
|||||||
LINK = $(CC) $(LDFLAGS) -o $@
|
LINK = $(CC) $(LDFLAGS) -o $@
|
||||||
g10_OBJECTS = g10.o build-packet.o compress.o encode.o encr-data.o \
|
g10_OBJECTS = g10.o build-packet.o compress.o encode.o encr-data.o \
|
||||||
free-packet.o getkey.o keygen.o mainproc.o armor.o mdfilter.o cipher.o \
|
free-packet.o getkey.o keygen.o mainproc.o armor.o mdfilter.o cipher.o \
|
||||||
overwrite.o parse-packet.o passphrase.o plaintext.o pubkey-enc.o \
|
openfile.o parse-packet.o passphrase.o plaintext.o pubkey-enc.o \
|
||||||
seckey-cert.o seskey.o sig-check.o
|
seckey-cert.o seskey.o sign.o comment.o sig-check.o
|
||||||
EXTRA_g10_SOURCES =
|
EXTRA_g10_SOURCES =
|
||||||
g10_LDADD = $(LDADD)
|
g10_LDADD = $(LDADD)
|
||||||
DIST_COMMON = Makefile.am Makefile.in
|
DIST_COMMON = Makefile.am Makefile.in
|
||||||
@ -105,15 +107,16 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
|
|||||||
|
|
||||||
TAR = tar
|
TAR = tar
|
||||||
DEP_FILES = $(srcdir)/.deps/armor.P $(srcdir)/.deps/build-packet.P \
|
DEP_FILES = $(srcdir)/.deps/armor.P $(srcdir)/.deps/build-packet.P \
|
||||||
$(srcdir)/.deps/cipher.P $(srcdir)/.deps/compress.P \
|
$(srcdir)/.deps/cipher.P $(srcdir)/.deps/comment.P \
|
||||||
$(srcdir)/.deps/encode.P $(srcdir)/.deps/encr-data.P \
|
$(srcdir)/.deps/compress.P $(srcdir)/.deps/encode.P \
|
||||||
$(srcdir)/.deps/free-packet.P $(srcdir)/.deps/g10.P \
|
$(srcdir)/.deps/encr-data.P $(srcdir)/.deps/free-packet.P \
|
||||||
$(srcdir)/.deps/getkey.P $(srcdir)/.deps/keygen.P \
|
$(srcdir)/.deps/g10.P $(srcdir)/.deps/getkey.P $(srcdir)/.deps/keygen.P \
|
||||||
$(srcdir)/.deps/mainproc.P $(srcdir)/.deps/mdfilter.P \
|
$(srcdir)/.deps/mainproc.P $(srcdir)/.deps/mdfilter.P \
|
||||||
$(srcdir)/.deps/overwrite.P $(srcdir)/.deps/parse-packet.P \
|
$(srcdir)/.deps/openfile.P $(srcdir)/.deps/parse-packet.P \
|
||||||
$(srcdir)/.deps/passphrase.P $(srcdir)/.deps/plaintext.P \
|
$(srcdir)/.deps/passphrase.P $(srcdir)/.deps/plaintext.P \
|
||||||
$(srcdir)/.deps/pubkey-enc.P $(srcdir)/.deps/seckey-cert.P \
|
$(srcdir)/.deps/pubkey-enc.P $(srcdir)/.deps/seckey-cert.P \
|
||||||
$(srcdir)/.deps/seskey.P $(srcdir)/.deps/sig-check.P
|
$(srcdir)/.deps/seskey.P $(srcdir)/.deps/sig-check.P \
|
||||||
|
$(srcdir)/.deps/sign.P
|
||||||
SOURCES = $(g10_SOURCES)
|
SOURCES = $(g10_SOURCES)
|
||||||
OBJECTS = $(g10_OBJECTS)
|
OBJECTS = $(g10_OBJECTS)
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ static u32 calc_plaintext( PKT_plaintext *pt );
|
|||||||
static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
|
static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
|
||||||
static int do_encr_data( IOBUF out, int ctb, PKT_encr_data *ed );
|
static int do_encr_data( IOBUF out, int ctb, PKT_encr_data *ed );
|
||||||
static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
|
static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
|
||||||
|
static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
|
||||||
|
|
||||||
static int calc_header_length( u32 len );
|
static int calc_header_length( u32 len );
|
||||||
static int write_16(IOBUF inp, u16 a);
|
static int write_16(IOBUF inp, u16 a);
|
||||||
@ -92,6 +93,8 @@ build_packet( IOBUF out, PACKET *pkt )
|
|||||||
rc = do_compressed( out, ctb, pkt->pkt.compressed );
|
rc = do_compressed( out, ctb, pkt->pkt.compressed );
|
||||||
break;
|
break;
|
||||||
case PKT_SIGNATURE:
|
case PKT_SIGNATURE:
|
||||||
|
rc = do_signature( out, ctb, pkt->pkt.signature );
|
||||||
|
break;
|
||||||
case PKT_RING_TRUST:
|
case PKT_RING_TRUST:
|
||||||
default:
|
default:
|
||||||
log_bug("invalid packet type in build_packet()");
|
log_bug("invalid packet type in build_packet()");
|
||||||
@ -255,6 +258,9 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
calc_plaintext( PKT_plaintext *pt )
|
calc_plaintext( PKT_plaintext *pt )
|
||||||
{
|
{
|
||||||
@ -323,6 +329,38 @@ do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_signature( IOBUF out, int ctb, PKT_signature *sig )
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
IOBUF a = iobuf_temp();
|
||||||
|
|
||||||
|
write_version( a, ctb );
|
||||||
|
iobuf_put(a, 5 ); /* constant */
|
||||||
|
iobuf_put(a, sig->sig_class );
|
||||||
|
write_32(a, sig->timestamp );
|
||||||
|
write_32(a, sig->keyid[0] );
|
||||||
|
write_32(a, sig->keyid[1] );
|
||||||
|
iobuf_put(a, sig->pubkey_algo );
|
||||||
|
if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||||
|
iobuf_put(a, sig->d.rsa.digest_algo );
|
||||||
|
iobuf_put(a, sig->d.rsa.digest_start[0] );
|
||||||
|
iobuf_put(a, sig->d.rsa.digest_start[1] );
|
||||||
|
mpi_encode(a, sig->d.rsa.rsa_integer );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = G10ERR_PUBKEY_ALGO;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_header(out, ctb, iobuf_get_temp_length(a) );
|
||||||
|
if( iobuf_write_temp( out, a ) )
|
||||||
|
rc = G10ERR_WRITE_FILE;
|
||||||
|
|
||||||
|
leave:
|
||||||
|
iobuf_close(a);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -124,6 +124,7 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
|||||||
IOBUF a, size_t *ret_len )
|
IOBUF a, size_t *ret_len )
|
||||||
{
|
{
|
||||||
int zrc;
|
int zrc;
|
||||||
|
int rc=0;
|
||||||
size_t n;
|
size_t n;
|
||||||
byte *p;
|
byte *p;
|
||||||
int c;
|
int c;
|
||||||
@ -147,7 +148,9 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
|||||||
if( DBG_FILTER )
|
if( DBG_FILTER )
|
||||||
log_debug("inflate returned: avail_in=%u, avail_out=%u, zrc=%d\n",
|
log_debug("inflate returned: avail_in=%u, avail_out=%u, zrc=%d\n",
|
||||||
(unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc);
|
(unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc);
|
||||||
if( zrc != Z_OK && zrc != Z_STREAM_END ) {
|
if( zrc == Z_STREAM_END )
|
||||||
|
rc = -1; /* eof */
|
||||||
|
else if( zrc != Z_OK ) {
|
||||||
if( zs->msg )
|
if( zs->msg )
|
||||||
log_fatal("zlib inflate problem: %s\n", zs->msg );
|
log_fatal("zlib inflate problem: %s\n", zs->msg );
|
||||||
else
|
else
|
||||||
@ -157,7 +160,7 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
|||||||
*ret_len = zfx->outbufsize - zs->avail_out;
|
*ret_len = zfx->outbufsize - zs->avail_out;
|
||||||
if( DBG_FILTER )
|
if( DBG_FILTER )
|
||||||
log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len );
|
log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len );
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
59
g10/encode.c
59
g10/encode.c
@ -1,4 +1,4 @@
|
|||||||
/* encode.c - encode/sign data
|
/* encode.c - encode data
|
||||||
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
||||||
*
|
*
|
||||||
* This file is part of G10.
|
* This file is part of G10.
|
||||||
@ -39,7 +39,6 @@
|
|||||||
|
|
||||||
|
|
||||||
static int encode_simple( const char *filename, int mode );
|
static int encode_simple( const char *filename, int mode );
|
||||||
static IOBUF open_outfile( const char *iname );
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
@ -62,22 +61,6 @@ encode_store( const char *filename )
|
|||||||
return encode_simple( filename, 0 );
|
return encode_simple( filename, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
write_comment( IOBUF out, const char *s )
|
|
||||||
{
|
|
||||||
PACKET pkt;
|
|
||||||
size_t n = strlen(s);
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
pkt.pkttype = PKT_COMMENT;
|
|
||||||
pkt.pkt.comment = m_alloc( sizeof *pkt.pkt.comment + n - 1 );
|
|
||||||
pkt.pkt.comment->len = n;
|
|
||||||
strcpy(pkt.pkt.comment->data, s);
|
|
||||||
if( (rc = build_packet( out, &pkt )) )
|
|
||||||
log_error("build_packet(comment) failed: %s\n", g10_errstr(rc) );
|
|
||||||
free_packet( &pkt );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
encode_simple( const char *filename, int mode )
|
encode_simple( const char *filename, int mode )
|
||||||
@ -335,44 +318,4 @@ encode_crypt( const char *filename, STRLIST remusr )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* Make an output filename for the inputfile INAME.
|
|
||||||
* Returns an
|
|
||||||
*/
|
|
||||||
static IOBUF
|
|
||||||
open_outfile( const char *iname )
|
|
||||||
{
|
|
||||||
IOBUF a = NULL;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if( (!iname && !opt.outfile) || opt.outfile_is_stdout ) {
|
|
||||||
if( !(a = iobuf_create(NULL)) )
|
|
||||||
log_error("can't open [stdout]: %s\n", strerror(errno) );
|
|
||||||
else if( opt.verbose )
|
|
||||||
log_info("writing to stdout\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
char *buf=NULL;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
if( opt.outfile )
|
|
||||||
name = opt.outfile;
|
|
||||||
else {
|
|
||||||
buf = m_alloc(strlen(iname)+4+1);
|
|
||||||
strcpy(stpcpy(buf,iname), ".g10");
|
|
||||||
name = buf;
|
|
||||||
}
|
|
||||||
if( !(rc=overwrite_filep( name )) ) {
|
|
||||||
if( !(a = iobuf_create( name )) )
|
|
||||||
log_error("can't create %s: %s\n", name, strerror(errno) );
|
|
||||||
else if( opt.verbose )
|
|
||||||
log_info("writing to '%s'\n", name );
|
|
||||||
}
|
|
||||||
else if( rc != -1 )
|
|
||||||
log_error("oops: overwrite_filep(%s): %s\n", name, g10_errstr(rc) );
|
|
||||||
m_free(buf);
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ typedef struct {
|
|||||||
|
|
||||||
/*-- mdfilter.c --*/
|
/*-- mdfilter.c --*/
|
||||||
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
|
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
|
||||||
|
void free_md_filter_context( md_filter_context_t *mfx );
|
||||||
|
|
||||||
/*-- armor.c --*/
|
/*-- armor.c --*/
|
||||||
int armor_filter( void *opaque, int control,
|
int armor_filter( void *opaque, int control,
|
||||||
|
@ -89,6 +89,21 @@ free_seckey_cert( PKT_seckey_cert *cert )
|
|||||||
m_free(cert);
|
m_free(cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PKT_seckey_cert *
|
||||||
|
copy_seckey_cert( PKT_seckey_cert *d, PKT_seckey_cert *s )
|
||||||
|
{
|
||||||
|
if( !d )
|
||||||
|
d = m_alloc(sizeof *d);
|
||||||
|
memcpy( d, s, sizeof *d );
|
||||||
|
d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
|
||||||
|
d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
|
||||||
|
d->d.rsa.rsa_d = mpi_copy( s->d.rsa.rsa_d );
|
||||||
|
d->d.rsa.rsa_p = mpi_copy( s->d.rsa.rsa_p );
|
||||||
|
d->d.rsa.rsa_q = mpi_copy( s->d.rsa.rsa_q );
|
||||||
|
d->d.rsa.rsa_u = mpi_copy( s->d.rsa.rsa_u );
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
free_comment( PKT_comment *rem )
|
free_comment( PKT_comment *rem )
|
||||||
{
|
{
|
||||||
|
47
g10/g10.c
47
g10/g10.c
@ -77,6 +77,8 @@ set_debug(void)
|
|||||||
mpi_debug_mode = 1;
|
mpi_debug_mode = 1;
|
||||||
if( opt.debug & DBG_CIPHER_VALUE )
|
if( opt.debug & DBG_CIPHER_VALUE )
|
||||||
cipher_debug_mode = 1;
|
cipher_debug_mode = 1;
|
||||||
|
if( opt.debug & DBG_IOBUF_VALUE )
|
||||||
|
iobuf_debug_mode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -116,10 +118,10 @@ main( int argc, char **argv )
|
|||||||
ARGPARSE_ARGS pargs = { &argc, &argv, 0 };
|
ARGPARSE_ARGS pargs = { &argc, &argv, 0 };
|
||||||
IOBUF a;
|
IOBUF a;
|
||||||
int rc;
|
int rc;
|
||||||
enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen,
|
enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
||||||
} action = aNull;
|
} action = aNull;
|
||||||
const char *fname, *fname_print;
|
const char *fname, *fname_print;
|
||||||
STRLIST sl, remusr= NULL;
|
STRLIST sl, remusr= NULL, locusr=NULL;
|
||||||
int nrings=0;
|
int nrings=0;
|
||||||
armor_filter_context_t afx;
|
armor_filter_context_t afx;
|
||||||
|
|
||||||
@ -131,13 +133,26 @@ main( int argc, char **argv )
|
|||||||
opt.compress = pargs.r.ret_int;
|
opt.compress = pargs.r.ret_int;
|
||||||
break;
|
break;
|
||||||
case 'a': opt.armor = 1; break;
|
case 'a': opt.armor = 1; break;
|
||||||
|
case 'b': opt.batch = 1; break;
|
||||||
case 'c': action = aSym; break;
|
case 'c': action = aSym; break;
|
||||||
case 'e': action = aEncr; break;
|
|
||||||
case 'o': opt.outfile = pargs.r.ret_str;
|
case 'o': opt.outfile = pargs.r.ret_str;
|
||||||
if( opt.outfile[0] == '-' && !opt.outfile[1] )
|
if( opt.outfile[0] == '-' && !opt.outfile[1] )
|
||||||
opt.outfile_is_stdout = 1;
|
opt.outfile_is_stdout = 1;
|
||||||
break;
|
break;
|
||||||
case 'b': opt.batch = 1; break;
|
case 'e': action = action == aSign? aSignEncr : aEncr; break;
|
||||||
|
case 's': action = action == aEncr? aSignEncr : aSign; break;
|
||||||
|
case 'l': /* store the local users */
|
||||||
|
sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
|
||||||
|
strcpy(sl->d, pargs.r.ret_str);
|
||||||
|
sl->next = locusr;
|
||||||
|
locusr = sl;
|
||||||
|
break;
|
||||||
|
case 'r': /* store the remote users */
|
||||||
|
sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
|
||||||
|
strcpy(sl->d, pargs.r.ret_str);
|
||||||
|
sl->next = remusr;
|
||||||
|
remusr = sl;
|
||||||
|
break;
|
||||||
case 501: opt.answer_yes = 1; break;
|
case 501: opt.answer_yes = 1; break;
|
||||||
case 502: opt.answer_no = 1; break;
|
case 502: opt.answer_no = 1; break;
|
||||||
case 507: action = aStore; break;
|
case 507: action = aStore; break;
|
||||||
@ -146,12 +161,6 @@ main( int argc, char **argv )
|
|||||||
case 510: opt.debug |= pargs.r.ret_ulong; break;
|
case 510: opt.debug |= pargs.r.ret_ulong; break;
|
||||||
case 511: opt.debug = ~0; break;
|
case 511: opt.debug = ~0; break;
|
||||||
case 512: opt.cache_all = 1; break;
|
case 512: opt.cache_all = 1; break;
|
||||||
case 'r': /* store the remote users */
|
|
||||||
sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
|
|
||||||
strcpy(sl->d, pargs.r.ret_str);
|
|
||||||
sl->next = remusr;
|
|
||||||
remusr = sl;
|
|
||||||
break;
|
|
||||||
case 513: action = aPrimegen; break;
|
case 513: action = aPrimegen; break;
|
||||||
case 514: action = aKeygen; break;
|
case 514: action = aKeygen; break;
|
||||||
default : pargs.err = 2; break;
|
default : pargs.err = 2; break;
|
||||||
@ -187,16 +196,25 @@ main( int argc, char **argv )
|
|||||||
if( argc > 1 )
|
if( argc > 1 )
|
||||||
usage(1);
|
usage(1);
|
||||||
if( (rc = encode_symmetric(fname)) )
|
if( (rc = encode_symmetric(fname)) )
|
||||||
log_error("encode_symmetric('%s'): %s\n",
|
log_error("encode_symmetric('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||||
fname_print, g10_errstr(rc) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aEncr: /* encrypt the given file */
|
case aEncr: /* encrypt the given file */
|
||||||
if( argc > 1 )
|
if( argc > 1 )
|
||||||
usage(1);
|
usage(1);
|
||||||
if( (rc = encode_crypt(fname,remusr)) )
|
if( (rc = encode_crypt(fname,remusr)) )
|
||||||
log_error("encode_crypt('%s'): %s\n",
|
log_error("encode_crypt('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||||
fname_print, g10_errstr(rc) );
|
break;
|
||||||
|
|
||||||
|
case aSign: /* sign the given file */
|
||||||
|
if( argc > 1 )
|
||||||
|
usage(1);
|
||||||
|
if( (rc = sign_file(fname, 0, locusr)) )
|
||||||
|
log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case aSignEncr: /* sign and encrypt the given file */
|
||||||
|
usage(1); /* FIXME */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aPrimegen:
|
case aPrimegen:
|
||||||
@ -227,6 +245,7 @@ main( int argc, char **argv )
|
|||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
FREE_STRLIST(remusr);
|
FREE_STRLIST(remusr);
|
||||||
|
FREE_STRLIST(locusr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
150
g10/getkey.c
150
g10/getkey.c
@ -61,7 +61,8 @@ static int pkc_cache_entries; /* number of entries in pkc cache */
|
|||||||
|
|
||||||
static int scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid,
|
static int scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid,
|
||||||
const char *name, const char *filename );
|
const char *name, const char *filename );
|
||||||
static int scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename);
|
static int scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid,
|
||||||
|
const char *name, const char *filename);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -254,10 +255,10 @@ int
|
|||||||
get_seckey( RSA_secret_key *skey, u32 *keyid )
|
get_seckey( RSA_secret_key *skey, u32 *keyid )
|
||||||
{
|
{
|
||||||
int rc=0;
|
int rc=0;
|
||||||
PACKET pkt;
|
PKT_seckey_cert skc;
|
||||||
|
|
||||||
init_packet( &pkt );
|
memset( &skc, 0, sizeof skc );
|
||||||
if( !(rc=scan_secret_keyring( &pkt, keyid, "../keys/secring.g10" ) ) )
|
if( !(rc=scan_secret_keyring( &skc, keyid, NULL, "../keys/secring.g10" ) ) )
|
||||||
goto found;
|
goto found;
|
||||||
/* fixme: look at other places */
|
/* fixme: look at other places */
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -266,30 +267,46 @@ get_seckey( RSA_secret_key *skey, u32 *keyid )
|
|||||||
/* get the secret key (this may prompt for a passprase to
|
/* get the secret key (this may prompt for a passprase to
|
||||||
* unlock the secret key
|
* unlock the secret key
|
||||||
*/
|
*/
|
||||||
if( (rc = check_secret_key( pkt.pkt.seckey_cert )) )
|
if( (rc = check_secret_key( &skc )) )
|
||||||
goto leave;
|
goto leave;
|
||||||
if( pkt.pkt.seckey_cert->pubkey_algo != PUBKEY_ALGO_RSA ) {
|
if( skc.pubkey_algo != PUBKEY_ALGO_RSA ) {
|
||||||
rc = G10ERR_PUBKEY_ALGO; /* unsupport algorithm */
|
rc = G10ERR_PUBKEY_ALGO; /* unsupport algorithm */
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
/* copy the stuff to SKEY. skey is then the owner */
|
/* copy the stuff to SKEY. skey is then the owner */
|
||||||
skey->e = pkt.pkt.seckey_cert->d.rsa.rsa_e;
|
skey->e = skc.d.rsa.rsa_e;
|
||||||
skey->n = pkt.pkt.seckey_cert->d.rsa.rsa_n;
|
skey->n = skc.d.rsa.rsa_n;
|
||||||
skey->p = pkt.pkt.seckey_cert->d.rsa.rsa_p;
|
skey->p = skc.d.rsa.rsa_p;
|
||||||
skey->q = pkt.pkt.seckey_cert->d.rsa.rsa_q;
|
skey->q = skc.d.rsa.rsa_q;
|
||||||
skey->d = pkt.pkt.seckey_cert->d.rsa.rsa_d;
|
skey->d = skc.d.rsa.rsa_d;
|
||||||
skey->u = pkt.pkt.seckey_cert->d.rsa.rsa_u;
|
skey->u = skc.d.rsa.rsa_u;
|
||||||
/* set all these to NULL, so that free_packet will not destroy
|
|
||||||
* these integers. */
|
leave:
|
||||||
pkt.pkt.seckey_cert->d.rsa.rsa_e = NULL;
|
memset( &skc, 0, sizeof skc );
|
||||||
pkt.pkt.seckey_cert->d.rsa.rsa_n = NULL;
|
return rc;
|
||||||
pkt.pkt.seckey_cert->d.rsa.rsa_p = NULL;
|
}
|
||||||
pkt.pkt.seckey_cert->d.rsa.rsa_q = NULL;
|
|
||||||
pkt.pkt.seckey_cert->d.rsa.rsa_d = NULL;
|
/****************
|
||||||
pkt.pkt.seckey_cert->d.rsa.rsa_u = NULL;
|
* Get a secret key by name and store it into skc
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_seckey_by_name( PKT_seckey_cert *skc, const char *name )
|
||||||
|
{
|
||||||
|
int rc=0;
|
||||||
|
|
||||||
|
if( !(rc=scan_secret_keyring( skc, NULL, name, "../keys/secring.g10" ) ) )
|
||||||
|
goto found;
|
||||||
|
/* fixme: look at other places */
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
found:
|
||||||
|
/* get the secret key (this may prompt for a passprase to
|
||||||
|
* unlock the secret key
|
||||||
|
*/
|
||||||
|
if( (rc = check_secret_key( skc )) )
|
||||||
|
goto leave;
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
free_packet(&pkt);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,11 +433,18 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid,
|
|||||||
* PKT returns the secret key certificate.
|
* PKT returns the secret key certificate.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename )
|
scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid,
|
||||||
|
const char *name, const char *filename )
|
||||||
{
|
{
|
||||||
|
int rc=0;
|
||||||
|
int found = 0;
|
||||||
IOBUF a;
|
IOBUF a;
|
||||||
int save_mode, rc;
|
PACKET pkt;
|
||||||
|
int save_mode;
|
||||||
u32 akeyid[2];
|
u32 akeyid[2];
|
||||||
|
PKT_seckey_cert *last_pk = NULL;
|
||||||
|
|
||||||
|
assert( !keyid || !name );
|
||||||
|
|
||||||
if( !(a = iobuf_open( filename ) ) ) {
|
if( !(a = iobuf_open( filename ) ) ) {
|
||||||
log_debug("scan_secret_keyring: can't open '%s'\n", filename );
|
log_debug("scan_secret_keyring: can't open '%s'\n", filename );
|
||||||
@ -428,28 +452,84 @@ scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename )
|
|||||||
}
|
}
|
||||||
|
|
||||||
save_mode = set_packet_list_mode(0);
|
save_mode = set_packet_list_mode(0);
|
||||||
init_packet(pkt);
|
init_packet(&pkt);
|
||||||
while( (rc=parse_packet(a, pkt)) != -1 ) {
|
while( (rc=parse_packet(a, &pkt)) != -1 ) {
|
||||||
if( rc )
|
if( rc )
|
||||||
;
|
; /* e.g. unknown packet */
|
||||||
else if( pkt->pkttype == PKT_SECKEY_CERT ) {
|
else if( keyid && found && pkt.pkttype == PKT_SECKEY_CERT ) {
|
||||||
mpi_get_keyid( pkt->pkt.seckey_cert->d.rsa.rsa_n , akeyid );
|
log_error("Hmmm, seckey without an user id in '%s'\n", filename);
|
||||||
if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
|
goto leave;
|
||||||
iobuf_close(a);
|
}
|
||||||
set_packet_list_mode(save_mode);
|
else if( keyid && pkt.pkttype == PKT_SECKEY_CERT ) {
|
||||||
return 0; /* got it */
|
switch( pkt.pkt.seckey_cert->pubkey_algo ) {
|
||||||
|
case PUBKEY_ALGO_RSA:
|
||||||
|
mpi_get_keyid( pkt.pkt.seckey_cert->d.rsa.rsa_n , akeyid );
|
||||||
|
if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
|
||||||
|
copy_seckey_cert( skc, pkt.pkt.seckey_cert );
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log_error("cannot handle pubkey algo %d\n",
|
||||||
|
pkt.pkt.seckey_cert->pubkey_algo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free_packet(pkt);
|
else if( keyid && found && pkt.pkttype == PKT_USER_ID ) {
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
else if( name && pkt.pkttype == PKT_SECKEY_CERT ) {
|
||||||
|
if( last_pk )
|
||||||
|
free_seckey_cert(last_pk);
|
||||||
|
last_pk = pkt.pkt.seckey_cert;
|
||||||
|
pkt.pkt.seckey_cert = NULL;
|
||||||
|
}
|
||||||
|
else if( name && pkt.pkttype == PKT_USER_ID ) {
|
||||||
|
if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) {
|
||||||
|
if( !last_pk )
|
||||||
|
log_error("Ooops: no seckey for userid '%.*s'\n",
|
||||||
|
pkt.pkt.user_id->len, pkt.pkt.user_id->name);
|
||||||
|
else if( skc->pubkey_algo &&
|
||||||
|
skc->pubkey_algo != last_pk->pubkey_algo )
|
||||||
|
log_info("skipping id '%.*s': want algo %d, found %d\n",
|
||||||
|
pkt.pkt.user_id->len, pkt.pkt.user_id->name,
|
||||||
|
skc->pubkey_algo, last_pk->pubkey_algo );
|
||||||
|
else {
|
||||||
|
copy_seckey_cert( skc, last_pk );
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( !keyid && !name && pkt.pkttype == PKT_SECKEY_CERT ) {
|
||||||
|
if( last_pk )
|
||||||
|
free_seckey_cert(last_pk);
|
||||||
|
last_pk = pkt.pkt.seckey_cert;
|
||||||
|
pkt.pkt.seckey_cert = NULL;
|
||||||
|
}
|
||||||
|
else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) {
|
||||||
|
if( !last_pk )
|
||||||
|
log_error("Ooops: no seckey for userid '%.*s'\n",
|
||||||
|
pkt.pkt.user_id->len, pkt.pkt.user_id->name);
|
||||||
|
else {
|
||||||
|
if( last_pk->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||||
|
mpi_get_keyid( last_pk->d.rsa.rsa_n , akeyid );
|
||||||
|
cache_user_id( pkt.pkt.user_id, akeyid );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free_packet(&pkt);
|
||||||
}
|
}
|
||||||
|
rc = G10ERR_NO_SECKEY;
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if( last_pk )
|
||||||
|
free_seckey_cert(last_pk);
|
||||||
|
free_packet(&pkt);
|
||||||
iobuf_close(a);
|
iobuf_close(a);
|
||||||
set_packet_list_mode(save_mode);
|
set_packet_list_mode(save_mode);
|
||||||
return G10ERR_NO_SECKEY;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Return a string with a printable representation of the user_id.
|
* Return a string with a printable representation of the user_id.
|
||||||
* this string must be freed by m_free.
|
* this string must be freed by m_free.
|
||||||
|
@ -36,6 +36,7 @@ void cache_user_id( PKT_user_id *uid, u32 *keyid );
|
|||||||
int get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid );
|
int get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid );
|
||||||
int get_pubkey_by_name( PKT_pubkey_cert *pkc, const char *name );
|
int get_pubkey_by_name( PKT_pubkey_cert *pkc, const char *name );
|
||||||
int get_seckey( RSA_secret_key *skey, u32 *keyid );
|
int get_seckey( RSA_secret_key *skey, u32 *keyid );
|
||||||
|
int get_seckey_by_name( PKT_seckey_cert *skc, const char *name );
|
||||||
char*get_user_id_string( u32 *keyid );
|
char*get_user_id_string( u32 *keyid );
|
||||||
|
|
||||||
|
|
||||||
|
15
g10/keygen.c
15
g10/keygen.c
@ -44,21 +44,6 @@ answer_is_yes( const char *s )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
write_comment( IOBUF out, const char *s )
|
|
||||||
{
|
|
||||||
PACKET pkt;
|
|
||||||
size_t n = strlen(s);
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
pkt.pkttype = PKT_COMMENT;
|
|
||||||
pkt.pkt.comment = m_alloc( sizeof *pkt.pkt.comment + n - 1 );
|
|
||||||
pkt.pkt.comment->len = n;
|
|
||||||
strcpy(pkt.pkt.comment->data, s);
|
|
||||||
if( (rc = build_packet( out, &pkt )) )
|
|
||||||
log_error("build_packet(comment) failed: %s\n", g10_errstr(rc) );
|
|
||||||
free_packet( &pkt );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_uid( IOBUF out, const char *s )
|
write_uid( IOBUF out, const char *s )
|
||||||
|
@ -20,16 +20,21 @@
|
|||||||
#ifndef G10_MAIN_H
|
#ifndef G10_MAIN_H
|
||||||
#define G10_MAIN_H
|
#define G10_MAIN_H
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "iobuf.h"
|
||||||
|
|
||||||
/*-- encode.c --*/
|
/*-- encode.c --*/
|
||||||
int encode_symmetric( const char *filename );
|
int encode_symmetric( const char *filename );
|
||||||
int encode_store( const char *filename );
|
int encode_store( const char *filename );
|
||||||
int encode_crypt( const char *filename, STRLIST remusr );
|
int encode_crypt( const char *filename, STRLIST remusr );
|
||||||
|
|
||||||
|
/*-- sign.c --*/
|
||||||
|
int sign_file( const char *filename, int detached, STRLIST locusr );
|
||||||
|
|
||||||
/*-- keygen.c --*/
|
/*-- keygen.c --*/
|
||||||
void generate_keypair(void);
|
void generate_keypair(void);
|
||||||
|
|
||||||
/*-- overwrite.c --*/
|
/*-- openfile.c --*/
|
||||||
int overwrite_filep( const char *fname );
|
int overwrite_filep( const char *fname );
|
||||||
|
IOBUF open_outfile( const char *fname );
|
||||||
|
|
||||||
#endif /*G10_MAIN_H*/
|
#endif /*G10_MAIN_H*/
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
static int opt_list=1; /* and list the data packets to stdout */
|
static int opt_list=1; /* and list the data packets to stdout */
|
||||||
|
|
||||||
@ -48,7 +48,9 @@ proc_packets( IOBUF a )
|
|||||||
int lvl0, lvl1;
|
int lvl0, lvl1;
|
||||||
int last_was_pubkey_enc = 0;
|
int last_was_pubkey_enc = 0;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
|
md_filter_context_t mfx;
|
||||||
|
|
||||||
|
memset( &mfx, 0, sizeof mfx );
|
||||||
lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */
|
lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */
|
||||||
lvl1 = opt.check_sigs? 1:3; /* stdout or error */
|
lvl1 = opt.check_sigs? 1:3; /* stdout or error */
|
||||||
pkt = m_alloc( sizeof *pkt );
|
pkt = m_alloc( sizeof *pkt );
|
||||||
@ -135,7 +137,14 @@ proc_packets( IOBUF a )
|
|||||||
sig = pkt->pkt.signature;
|
sig = pkt->pkt.signature;
|
||||||
ustr = get_user_id_string(sig->keyid);
|
ustr = get_user_id_string(sig->keyid);
|
||||||
result = -1;
|
result = -1;
|
||||||
if( sig->sig_class != 0x10 )
|
if( sig->sig_class == 0x00 ) {
|
||||||
|
if( mfx.rmd160 )
|
||||||
|
result = 0;
|
||||||
|
else
|
||||||
|
printstr(lvl1,"sig?: %s: no plaintext for signature\n",
|
||||||
|
ustr);
|
||||||
|
}
|
||||||
|
else if( sig->sig_class != 0x10 )
|
||||||
printstr(lvl1,"sig?: %s: unknown signature class %02x\n",
|
printstr(lvl1,"sig?: %s: unknown signature class %02x\n",
|
||||||
ustr, sig->sig_class);
|
ustr, sig->sig_class);
|
||||||
else if( !pkt->pkc_parent || !pkt->user_parent )
|
else if( !pkt->pkc_parent || !pkt->user_parent )
|
||||||
@ -145,20 +154,25 @@ proc_packets( IOBUF a )
|
|||||||
|
|
||||||
if( result )
|
if( result )
|
||||||
;
|
;
|
||||||
else if( !opt.check_sigs ) {
|
else if( !opt.check_sigs && sig->sig_class != 0x00 ) {
|
||||||
result = -1;
|
result = -1;
|
||||||
printstr(lvl0, "sig: from %s\n", ustr );
|
printstr(lvl0, "sig: from %s\n", ustr );
|
||||||
}
|
}
|
||||||
else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||||
md_handle.algo = sig->d.rsa.digest_algo;
|
md_handle.algo = sig->d.rsa.digest_algo;
|
||||||
if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) {
|
if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) {
|
||||||
md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
|
if( sig->sig_class == 0x00 )
|
||||||
rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
|
md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
|
||||||
pkt->user_parent->len);
|
else {
|
||||||
|
md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
|
||||||
|
rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
|
||||||
|
pkt->user_parent->len);
|
||||||
|
}
|
||||||
result = signature_check( sig, md_handle );
|
result = signature_check( sig, md_handle );
|
||||||
rmd160_close(md_handle.u.rmd);
|
rmd160_close(md_handle.u.rmd);
|
||||||
}
|
}
|
||||||
else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5 ) {
|
else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5
|
||||||
|
&& sig->sig_class != 0x00 ) {
|
||||||
md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
|
md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
|
||||||
md5_write(md_handle.u.md5, pkt->user_parent->name,
|
md5_write(md_handle.u.md5, pkt->user_parent->name,
|
||||||
pkt->user_parent->len);
|
pkt->user_parent->len);
|
||||||
@ -173,6 +187,8 @@ proc_packets( IOBUF a )
|
|||||||
|
|
||||||
if( result == -1 )
|
if( result == -1 )
|
||||||
;
|
;
|
||||||
|
else if( !result && sig->sig_class == 0x00 )
|
||||||
|
printstr(1, "sig: good signature from %s\n", ustr );
|
||||||
else if( !result )
|
else if( !result )
|
||||||
printstr(lvl0, "sig: good signature from %s\n", ustr );
|
printstr(lvl0, "sig: good signature from %s\n", ustr );
|
||||||
else
|
else
|
||||||
@ -235,7 +251,9 @@ proc_packets( IOBUF a )
|
|||||||
else if( pkt->pkttype == PKT_PLAINTEXT ) {
|
else if( pkt->pkttype == PKT_PLAINTEXT ) {
|
||||||
PKT_plaintext *pt = pkt->pkt.plaintext;
|
PKT_plaintext *pt = pkt->pkt.plaintext;
|
||||||
printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
|
printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
|
||||||
result = handle_plaintext( pt );
|
free_md_filter_context( &mfx );
|
||||||
|
mfx.rmd160 = rmd160_open(0);
|
||||||
|
result = handle_plaintext( pt, &mfx );
|
||||||
if( !result )
|
if( !result )
|
||||||
fputs( " okay",stdout);
|
fputs( " okay",stdout);
|
||||||
else
|
else
|
||||||
@ -269,6 +287,7 @@ proc_packets( IOBUF a )
|
|||||||
m_free(dek);
|
m_free(dek);
|
||||||
free_packet( pkt );
|
free_packet( pkt );
|
||||||
m_free( pkt );
|
m_free( pkt );
|
||||||
|
free_md_filter_context( &mfx );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ md_filter( void *opaque, int control,
|
|||||||
int i, c, rc=0;
|
int i, c, rc=0;
|
||||||
|
|
||||||
if( control == IOBUFCTRL_UNDERFLOW ) {
|
if( control == IOBUFCTRL_UNDERFLOW ) {
|
||||||
if( size > mfx->maxbuf_size )
|
if( mfx->maxbuf_size && size > mfx->maxbuf_size )
|
||||||
size = mfx->maxbuf_size;
|
size = mfx->maxbuf_size;
|
||||||
for(i=0; i < size; i++ ) {
|
for(i=0; i < size; i++ ) {
|
||||||
if( (c = iobuf_get(a)) == -1 )
|
if( (c = iobuf_get(a)) == -1 )
|
||||||
@ -68,3 +68,16 @@ md_filter( void *opaque, int control,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
free_md_filter_context( md_filter_context_t *mfx )
|
||||||
|
{
|
||||||
|
if( mfx->md5 )
|
||||||
|
md5_close(mfx->md5);
|
||||||
|
mfx->md5 = NULL;
|
||||||
|
if( mfx->rmd160 )
|
||||||
|
rmd160_close(mfx->rmd160);
|
||||||
|
mfx->rmd160 = NULL;
|
||||||
|
mfx->maxbuf_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* overwrite.c
|
/* openfile.c
|
||||||
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
||||||
*
|
*
|
||||||
* This file is part of G10.
|
* This file is part of G10.
|
||||||
@ -77,3 +77,43 @@ overwrite_filep( const char *fname )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Make an output filename for the inputfile INAME.
|
||||||
|
* Returns an IOBUF
|
||||||
|
*/
|
||||||
|
IOBUF
|
||||||
|
open_outfile( const char *iname )
|
||||||
|
{
|
||||||
|
IOBUF a = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( (!iname && !opt.outfile) || opt.outfile_is_stdout ) {
|
||||||
|
if( !(a = iobuf_create(NULL)) )
|
||||||
|
log_error("can't open [stdout]: %s\n", strerror(errno) );
|
||||||
|
else if( opt.verbose )
|
||||||
|
log_info("writing to stdout\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char *buf=NULL;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
if( opt.outfile )
|
||||||
|
name = opt.outfile;
|
||||||
|
else {
|
||||||
|
buf = m_alloc(strlen(iname)+4+1);
|
||||||
|
strcpy(stpcpy(buf,iname), ".g10");
|
||||||
|
name = buf;
|
||||||
|
}
|
||||||
|
if( !(rc=overwrite_filep( name )) ) {
|
||||||
|
if( !(a = iobuf_create( name )) )
|
||||||
|
log_error("can't create %s: %s\n", name, strerror(errno) );
|
||||||
|
else if( opt.verbose )
|
||||||
|
log_info("writing to '%s'\n", name );
|
||||||
|
}
|
||||||
|
else if( rc != -1 )
|
||||||
|
log_error("oops: overwrite_filep(%s): %s\n", name, g10_errstr(rc) );
|
||||||
|
m_free(buf);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
10
g10/packet.h
10
g10/packet.h
@ -103,9 +103,6 @@ typedef struct {
|
|||||||
byte iv[8]; /* initialization vector for CFB mode */
|
byte iv[8]; /* initialization vector for CFB mode */
|
||||||
/* when protected, the MPIs above are pointers
|
/* when protected, the MPIs above are pointers
|
||||||
* to plain storage */
|
* to plain storage */
|
||||||
} idea;
|
|
||||||
struct {
|
|
||||||
byte iv[8];
|
|
||||||
} blowfish;
|
} blowfish;
|
||||||
} protect;
|
} protect;
|
||||||
} rsa;
|
} rsa;
|
||||||
@ -190,6 +187,7 @@ void free_user_id( PKT_user_id *uid );
|
|||||||
void free_comment( PKT_comment *rem );
|
void free_comment( PKT_comment *rem );
|
||||||
void free_packet( PACKET *pkt );
|
void free_packet( PACKET *pkt );
|
||||||
PKT_pubkey_cert *copy_pubkey_cert( PKT_pubkey_cert *d, PKT_pubkey_cert *s );
|
PKT_pubkey_cert *copy_pubkey_cert( PKT_pubkey_cert *d, PKT_pubkey_cert *s );
|
||||||
|
PKT_seckey_cert *copy_seckey_cert( PKT_seckey_cert *d, PKT_seckey_cert *s );
|
||||||
|
|
||||||
|
|
||||||
/*-- sig-check.c --*/
|
/*-- sig-check.c --*/
|
||||||
@ -209,6 +207,10 @@ int decrypt_data( PKT_encr_data *ed, DEK *dek );
|
|||||||
int encrypt_data( PKT_encr_data *ed, DEK *dek );
|
int encrypt_data( PKT_encr_data *ed, DEK *dek );
|
||||||
|
|
||||||
/*-- plaintext.c --*/
|
/*-- plaintext.c --*/
|
||||||
int handle_plaintext( PKT_plaintext *pt );
|
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx );
|
||||||
|
|
||||||
|
/*-- comment.c --*/
|
||||||
|
int write_comment( IOBUF out, const char *s );
|
||||||
|
|
||||||
|
|
||||||
#endif /*G10_PACKET_H*/
|
#endif /*G10_PACKET_H*/
|
||||||
|
@ -157,7 +157,6 @@ parse_packet( IOBUF inp, PACKET *pkt )
|
|||||||
case PKT_SIGNATURE:
|
case PKT_SIGNATURE:
|
||||||
pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
|
pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
|
||||||
rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
|
rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
|
||||||
m_check(pkt->pkt.signature);
|
|
||||||
break;
|
break;
|
||||||
case PKT_USER_ID:
|
case PKT_USER_ID:
|
||||||
rc = parse_user_id(inp, pkttype, pktlen, pkt );
|
rc = parse_user_id(inp, pkttype, pktlen, pkt );
|
||||||
@ -266,14 +265,12 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
log_error("packet(%d) with unknown version %d\n", pkttype, version);
|
log_error("packet(%d) with unknown version %d\n", pkttype, version);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
m_check(sig);
|
|
||||||
md5_len = iobuf_get_noeof(inp); pktlen--;
|
md5_len = iobuf_get_noeof(inp); pktlen--;
|
||||||
sig->sig_class = iobuf_get_noeof(inp); pktlen--;
|
sig->sig_class = iobuf_get_noeof(inp); pktlen--;
|
||||||
sig->timestamp = read_32(inp); pktlen -= 4;
|
sig->timestamp = read_32(inp); pktlen -= 4;
|
||||||
sig->keyid[0] = read_32(inp); pktlen -= 4;
|
sig->keyid[0] = read_32(inp); pktlen -= 4;
|
||||||
sig->keyid[1] = read_32(inp); pktlen -= 4;
|
sig->keyid[1] = read_32(inp); pktlen -= 4;
|
||||||
sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
|
sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
|
||||||
m_check(sig);
|
|
||||||
if( list_mode )
|
if( list_mode )
|
||||||
printf(":signature packet: keyid %08lX%08lX\n"
|
printf(":signature packet: keyid %08lX%08lX\n"
|
||||||
"\tversion %d, created %lu, md5len %d, sigclass %02x\n",
|
"\tversion %d, created %lu, md5len %d, sigclass %02x\n",
|
||||||
@ -284,11 +281,9 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
log_error("packet(%d) too short\n", pkttype);
|
log_error("packet(%d) too short\n", pkttype);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
m_check(sig);
|
|
||||||
sig->d.rsa.digest_algo = iobuf_get_noeof(inp); pktlen--;
|
sig->d.rsa.digest_algo = iobuf_get_noeof(inp); pktlen--;
|
||||||
sig->d.rsa.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
|
sig->d.rsa.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
|
||||||
sig->d.rsa.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
|
sig->d.rsa.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
|
||||||
m_check(sig);
|
|
||||||
n = pktlen;
|
n = pktlen;
|
||||||
sig->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
|
sig->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
|
||||||
if( list_mode ) {
|
if( list_mode ) {
|
||||||
@ -302,7 +297,6 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
}
|
}
|
||||||
else if( list_mode )
|
else if( list_mode )
|
||||||
printf("\tunknown algorithm %d\n", sig->pubkey_algo );
|
printf("\tunknown algorithm %d\n", sig->pubkey_algo );
|
||||||
m_check(sig);
|
|
||||||
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
@ -395,9 +389,7 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
printf(" %02x", temp[i] );
|
printf(" %02x", temp[i] );
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
if( cert->d.rsa.protect_algo == CIPHER_ALGO_IDEA )
|
if( cert->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH )
|
||||||
memcpy(cert->d.rsa.protect.idea.iv, temp, 8 );
|
|
||||||
else if( cert->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH )
|
|
||||||
memcpy(cert->d.rsa.protect.blowfish.iv, temp, 8 );
|
memcpy(cert->d.rsa.protect.blowfish.iv, temp, 8 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -100,17 +100,7 @@ hash_passphrase( DEK *dek, char *pw )
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
dek->keylen = 0;
|
dek->keylen = 0;
|
||||||
if( dek->algo == CIPHER_ALGO_IDEA ) {
|
if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
|
||||||
MD5HANDLE md5;
|
|
||||||
|
|
||||||
md5 = md5_open(1);
|
|
||||||
md5_write( md5, pw, strlen(pw) );
|
|
||||||
md5_final( md5 );
|
|
||||||
dek->keylen = 16;
|
|
||||||
memcpy( dek->key, md5_read(md5), dek->keylen );
|
|
||||||
md5_close(md5);
|
|
||||||
}
|
|
||||||
else if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
|
|
||||||
RMDHANDLE rmd;
|
RMDHANDLE rmd;
|
||||||
|
|
||||||
rmd = rmd160_open(1);
|
rmd = rmd160_open(1);
|
||||||
|
@ -28,13 +28,17 @@
|
|||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "ttyio.h"
|
#include "ttyio.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Handle a plaintext packet
|
* Handle a plaintext packet. If MFX is not NULL, update the MDs
|
||||||
|
* Note: we should use the filter stuff here, but we have to add some
|
||||||
|
* easy mimic to set a read limit, so we calculate only the
|
||||||
|
* bytes from the plaintext.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
handle_plaintext( PKT_plaintext *pt )
|
handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
||||||
{
|
{
|
||||||
char *fname;
|
char *fname;
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
@ -78,6 +82,10 @@ handle_plaintext( PKT_plaintext *pt )
|
|||||||
rc = G10ERR_READ_FILE;
|
rc = G10ERR_READ_FILE;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
if( mfx->rmd160 )
|
||||||
|
rmd160_putchar(mfx->rmd160, c );
|
||||||
|
if( mfx->md5 )
|
||||||
|
md5_putchar(mfx->md5, c );
|
||||||
if( putc( c, fp ) == EOF ) {
|
if( putc( c, fp ) == EOF ) {
|
||||||
log_error("Error writing to '%s': %s\n", fname, strerror(errno) );
|
log_error("Error writing to '%s': %s\n", fname, strerror(errno) );
|
||||||
rc = G10ERR_WRITE_FILE;
|
rc = G10ERR_WRITE_FILE;
|
||||||
@ -87,6 +95,10 @@ handle_plaintext( PKT_plaintext *pt )
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while( (c = iobuf_get(pt->buf)) != -1 ) {
|
while( (c = iobuf_get(pt->buf)) != -1 ) {
|
||||||
|
if( mfx->rmd160 )
|
||||||
|
rmd160_putchar(mfx->rmd160, c );
|
||||||
|
if( mfx->md5 )
|
||||||
|
md5_putchar(mfx->md5, c );
|
||||||
if( putc( c, fp ) == EOF ) {
|
if( putc( c, fp ) == EOF ) {
|
||||||
log_error("Error writing to '%s': %s\n",
|
log_error("Error writing to '%s': %s\n",
|
||||||
fname, strerror(errno) );
|
fname, strerror(errno) );
|
||||||
|
@ -68,9 +68,8 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
|
|||||||
* 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
|
* 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
|
||||||
*
|
*
|
||||||
* RND are non-zero randow bytes.
|
* RND are non-zero randow bytes.
|
||||||
* A is the cipher algorithm ( 1 for IDEA, 42 for blowfish )
|
* A is the cipher algorithm
|
||||||
* DEK is the encryption key (session key) with length k
|
* DEK is the encryption key (session key) with length k
|
||||||
* (16 for idea, 42 for blowfish)
|
|
||||||
* CSUM
|
* CSUM
|
||||||
*/
|
*/
|
||||||
if( DBG_CIPHER )
|
if( DBG_CIPHER )
|
||||||
|
@ -50,7 +50,6 @@ checksum( byte *p )
|
|||||||
int
|
int
|
||||||
check_secret_key( PKT_seckey_cert *cert )
|
check_secret_key( PKT_seckey_cert *cert )
|
||||||
{
|
{
|
||||||
IDEA_context idea_ctx; /* FIXME: allocate this in secure space ! */
|
|
||||||
byte iv[8];
|
byte iv[8];
|
||||||
byte *mpibuf;
|
byte *mpibuf;
|
||||||
u16 n;
|
u16 n;
|
||||||
@ -58,7 +57,7 @@ check_secret_key( PKT_seckey_cert *cert )
|
|||||||
int res;
|
int res;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
|
|
||||||
#if IDEA_BLOCKSIZE != 8 || BLOWFISH_BLOCKSIZE != 8
|
#if BLOWFISH_BLOCKSIZE != 8
|
||||||
#error unsupportted blocksize
|
#error unsupportted blocksize
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -73,37 +72,23 @@ check_secret_key( PKT_seckey_cert *cert )
|
|||||||
case CIPHER_ALGO_NONE:
|
case CIPHER_ALGO_NONE:
|
||||||
log_bug("unprotect seckey_cert is flagged protected\n");
|
log_bug("unprotect seckey_cert is flagged protected\n");
|
||||||
break;
|
break;
|
||||||
case CIPHER_ALGO_IDEA:
|
|
||||||
case CIPHER_ALGO_BLOWFISH:
|
case CIPHER_ALGO_BLOWFISH:
|
||||||
mpi_get_keyid( cert->d.rsa.rsa_n , keyid );
|
mpi_get_keyid( cert->d.rsa.rsa_n , keyid );
|
||||||
dek = get_passphrase_hash( keyid, NULL );
|
dek = get_passphrase_hash( keyid, NULL );
|
||||||
|
|
||||||
/* idea_setkey( &idea_ctx, dpw );*/
|
|
||||||
m_free(dek); /* pw is in secure memory, so m_free() burns it */
|
m_free(dek); /* pw is in secure memory, so m_free() burns it */
|
||||||
memset( iv, 0, BLOWFISH_BLOCKSIZE );
|
memset( iv, 0, BLOWFISH_BLOCKSIZE );
|
||||||
if( cert->d.rsa.protect_algo == CIPHER_ALGO_IDEA ) {
|
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
|
||||||
idea_setiv( &idea_ctx, iv );
|
blowfish_setiv( blowfish_ctx, iv );
|
||||||
/* fixme: is it save to leave the IV unencrypted in the
|
blowfish_decode_cfb( blowfish_ctx,
|
||||||
* certificate or should we move it to secure storage? */
|
cert->d.rsa.protect.blowfish.iv,
|
||||||
idea_decode_cfb( &idea_ctx, cert->d.rsa.protect.idea.iv,
|
cert->d.rsa.protect.blowfish.iv, 8 );
|
||||||
cert->d.rsa.protect.idea.iv, 8 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
|
|
||||||
blowfish_setiv( blowfish_ctx, iv );
|
|
||||||
blowfish_decode_cfb( blowfish_ctx,
|
|
||||||
cert->d.rsa.protect.blowfish.iv,
|
|
||||||
cert->d.rsa.protect.blowfish.iv, 8 );
|
|
||||||
}
|
|
||||||
cert->d.rsa.calc_csum = 0;
|
cert->d.rsa.calc_csum = 0;
|
||||||
#define X(a) do { \
|
#define X(a) do { \
|
||||||
mpibuf = (byte*)cert->d.rsa.rsa_##a; \
|
mpibuf = (byte*)cert->d.rsa.rsa_##a; \
|
||||||
n = ((mpibuf[0] << 8) | mpibuf[1])-2; \
|
n = ((mpibuf[0] << 8) | mpibuf[1])-2; \
|
||||||
if( blowfish_ctx ) \
|
blowfish_decode_cfb( blowfish_ctx, \
|
||||||
blowfish_decode_cfb( blowfish_ctx, \
|
mpibuf+4, mpibuf+4, n ); \
|
||||||
mpibuf+4, mpibuf+4, n ); \
|
|
||||||
else \
|
|
||||||
idea_decode_cfb( &idea_ctx, mpibuf+4, mpibuf+4, n );\
|
|
||||||
cert->d.rsa.calc_csum += checksum( mpibuf ); \
|
cert->d.rsa.calc_csum += checksum( mpibuf ); \
|
||||||
cert->d.rsa.rsa_##a = mpi_decode_buffer( mpibuf ); \
|
cert->d.rsa.rsa_##a = mpi_decode_buffer( mpibuf ); \
|
||||||
m_free( mpibuf ); \
|
m_free( mpibuf ); \
|
||||||
@ -120,12 +105,7 @@ check_secret_key( PKT_seckey_cert *cert )
|
|||||||
mpi_print(stdout, cert->d.rsa.rsa_##a, 1 ); \
|
mpi_print(stdout, cert->d.rsa.rsa_##a, 1 ); \
|
||||||
putchar('\n'); \
|
putchar('\n'); \
|
||||||
} while(0)
|
} while(0)
|
||||||
X(n);
|
X(n); X(e); X(d); X(p); X(q); X(u);
|
||||||
X(e);
|
|
||||||
X(d);
|
|
||||||
X(p);
|
|
||||||
X(q);
|
|
||||||
X(u);
|
|
||||||
#undef X
|
#undef X
|
||||||
#endif
|
#endif
|
||||||
/* now let's see wether we have used the right passphrase */
|
/* now let's see wether we have used the right passphrase */
|
||||||
|
41
g10/seskey.c
41
g10/seskey.c
@ -1,4 +1,4 @@
|
|||||||
/* seskey.c - make sesssion keys
|
/* seskey.c - make sesssion keys etc.
|
||||||
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
||||||
*
|
*
|
||||||
* This file is part of G10.
|
* This file is part of G10.
|
||||||
@ -99,3 +99,42 @@ encode_session_key( DEK *dek, unsigned nbits )
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Encode a ripemd160 message digest of LEN bytes into NBITS.
|
||||||
|
* returns: A mpi with the session key (caller must free)
|
||||||
|
*/
|
||||||
|
MPI
|
||||||
|
encode_rmd160_value( byte *md, unsigned len, unsigned nbits )
|
||||||
|
{
|
||||||
|
static byte asn[18] = /* stored reverse FIXME: need other values*/
|
||||||
|
{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
|
||||||
|
0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
|
||||||
|
int nframe = (nbits+7) / 8;
|
||||||
|
byte *p;
|
||||||
|
MPI frame;
|
||||||
|
int i,n,c;
|
||||||
|
|
||||||
|
if( (nbits % BITS_PER_MPI_LIMB) || nframe < 42 || len != 20 )
|
||||||
|
log_bug("can't encode a %d bit MD into a %d bits frame\n",len*8, nbits);
|
||||||
|
|
||||||
|
/* We encode the MD in this way:
|
||||||
|
*
|
||||||
|
* 0 42 PAD(n bytes) 0 ASN(18 bytes) MD(20 bytes)
|
||||||
|
*
|
||||||
|
* PAD consists of FF bytes.
|
||||||
|
*/
|
||||||
|
frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB );
|
||||||
|
n = 0;
|
||||||
|
for(i=20-1; i >= 0; i--, n++ )
|
||||||
|
mpi_putbyte(frame, n, md[i] );
|
||||||
|
for( i=18-1; i >= 0; i--, n++ )
|
||||||
|
mpi_putbyte(frame, n, asn[i] );
|
||||||
|
mpi_putbyte(frame, n++, 0 );
|
||||||
|
while( n < nframe-2 )
|
||||||
|
mpi_putbyte(frame, n++, 0xff );
|
||||||
|
mpi_putbyte(frame, n++, DIGEST_ALGO_RMD160 );
|
||||||
|
mpi_putbyte(frame, n++, 0 );
|
||||||
|
assert( n == nframe );
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -115,28 +115,27 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
|
|||||||
{ 0x10, 0x04, 0x00, 0x05, 0x05, 0x02, 0x0d, 0xf7, 0x86,
|
{ 0x10, 0x04, 0x00, 0x05, 0x05, 0x02, 0x0d, 0xf7, 0x86,
|
||||||
0x48, 0x86, 0x2a, 0x08, 0x06, 0x0c, 0x30, 0x20, 0x30 };
|
0x48, 0x86, 0x2a, 0x08, 0x06, 0x0c, 0x30, 0x20, 0x30 };
|
||||||
|
|
||||||
for(i=20,j=0; j < 18 && (c=mpi_getbyte(result, i)) != -1; i++, j++ )
|
for(i=20,j=0; (c=mpi_getbyte(result, i)) != -1 && j < 18; i++, j++ )
|
||||||
if( asn[j] != c )
|
if( asn[j] != c )
|
||||||
break;
|
break;
|
||||||
if( j != 18 ) { /* ASN is wrong */
|
if( j != 18 || c ) { /* ASN is wrong */
|
||||||
rc = G10ERR_BAD_PUBKEY;
|
rc = G10ERR_BAD_PUBKEY;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if( !c ) {
|
for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
|
||||||
for(; (c=mpi_getbyte(result, i)) != -1; i++ )
|
if( c != 0xff )
|
||||||
if( c != 0xff )
|
break;
|
||||||
break;
|
i++;
|
||||||
if( c != 42 || mpi_getbyte(result, i) ) {
|
if( c != DIGEST_ALGO_RMD160 || mpi_getbyte(result, i) ) {
|
||||||
/* Padding or leading bytes in signature is wrong */
|
/* Padding or leading bytes in signature is wrong */
|
||||||
rc = G10ERR_BAD_PUBKEY;
|
rc = G10ERR_BAD_PUBKEY;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if( mpi_getbyte(result, 19) != sig->d.rsa.digest_start[0]
|
if( mpi_getbyte(result, 19) != sig->d.rsa.digest_start[0]
|
||||||
|| mpi_getbyte(result, 18) != sig->d.rsa.digest_start[1] ) {
|
|| mpi_getbyte(result, 18) != sig->d.rsa.digest_start[1] ) {
|
||||||
/* Wrong key used to check the signature */
|
/* Wrong key used to check the signature */
|
||||||
rc = G10ERR_BAD_PUBKEY;
|
rc = G10ERR_BAD_PUBKEY;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* complete the digest */
|
/* complete the digest */
|
||||||
@ -162,25 +161,24 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
|
|||||||
for(i=16,j=0; j < 18 && (c=mpi_getbyte(result, i)) != -1; i++, j++ )
|
for(i=16,j=0; j < 18 && (c=mpi_getbyte(result, i)) != -1; i++, j++ )
|
||||||
if( asn[j] != c )
|
if( asn[j] != c )
|
||||||
break;
|
break;
|
||||||
if( j != 18 ) { /* ASN is wrong */
|
if( j != 18 || c ) { /* ASN is wrong */
|
||||||
rc = G10ERR_BAD_PUBKEY;
|
rc = G10ERR_BAD_PUBKEY;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if( !c ) {
|
for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
|
||||||
for(; (c=mpi_getbyte(result, i)) != -1; i++ )
|
if( c != 0xff )
|
||||||
if( c != 0xff )
|
break;
|
||||||
break;
|
i++;
|
||||||
if( c != 1 || mpi_getbyte(result, i) ) {
|
if( c != DIGEST_ALGO_MD5 || mpi_getbyte(result, i) ) {
|
||||||
/* Padding or leading bytes in signature is wrong */
|
/* Padding or leading bytes in signature is wrong */
|
||||||
rc = G10ERR_BAD_PUBKEY;
|
rc = G10ERR_BAD_PUBKEY;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if( mpi_getbyte(result, 15) != sig->d.rsa.digest_start[0]
|
if( mpi_getbyte(result, 15) != sig->d.rsa.digest_start[0]
|
||||||
|| mpi_getbyte(result, 14) != sig->d.rsa.digest_start[1] ) {
|
|| mpi_getbyte(result, 14) != sig->d.rsa.digest_start[1] ) {
|
||||||
/* Wrong key used to check the signature */
|
/* Wrong key used to check the signature */
|
||||||
rc = G10ERR_BAD_PUBKEY;
|
rc = G10ERR_BAD_PUBKEY;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* complete the digest */
|
/* complete the digest */
|
||||||
|
@ -33,14 +33,13 @@
|
|||||||
#ifdef HAVE_RSA_CIPHER
|
#ifdef HAVE_RSA_CIPHER
|
||||||
#include "../cipher/rsa.h"
|
#include "../cipher/rsa.h"
|
||||||
#endif
|
#endif
|
||||||
#include "../cipher/idea.h"
|
|
||||||
#include "../cipher/blowfish.h"
|
#include "../cipher/blowfish.h"
|
||||||
#include "../cipher/gost.h"
|
#include "../cipher/gost.h"
|
||||||
#include "../cipher/elgamal.h"
|
#include "../cipher/elgamal.h"
|
||||||
|
|
||||||
|
|
||||||
#define CIPHER_ALGO_NONE 0
|
#define CIPHER_ALGO_NONE 0
|
||||||
#define CIPHER_ALGO_IDEA 1
|
#define CIPHER_ALGO_IDEA 1 /* used only for documentation */
|
||||||
#define CIPHER_ALGO_BLOWFISH 42
|
#define CIPHER_ALGO_BLOWFISH 42
|
||||||
#define CIPHER_ALGO_GOST 43
|
#define CIPHER_ALGO_GOST 43
|
||||||
|
|
||||||
@ -84,6 +83,7 @@ MPI generate_random_prime( unsigned nbits );
|
|||||||
/*-- seskey.c --*/
|
/*-- seskey.c --*/
|
||||||
void make_session_key( DEK *dek );
|
void make_session_key( DEK *dek );
|
||||||
MPI encode_session_key( DEK *dek, unsigned nbits );
|
MPI encode_session_key( DEK *dek, unsigned nbits );
|
||||||
|
MPI encode_rmd160_value( byte *md, unsigned len, unsigned nbits );
|
||||||
|
|
||||||
|
|
||||||
#endif /*G10_CIPHER_H*/
|
#endif /*G10_CIPHER_H*/
|
||||||
|
@ -248,6 +248,10 @@ mpi_free( MPI a )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Note: This copy function shpould not interpret the MPI
|
||||||
|
* but copy it transparently.
|
||||||
|
*/
|
||||||
MPI
|
MPI
|
||||||
#ifdef M_DEBUG
|
#ifdef M_DEBUG
|
||||||
mpi_debug_copy( MPI a, const char *info )
|
mpi_debug_copy( MPI a, const char *info )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user