a whole bunch of internal cleanups

This commit is contained in:
Werner Koch 1998-06-13 06:59:14 +00:00
parent d42ad47688
commit 37d2adfe61
28 changed files with 819 additions and 1147 deletions

View File

@ -10,7 +10,7 @@ for i in plain-2 data-32000 ; do
done
for i in plain-1 data-80000 ; do
echo "Hier spricht HAL" | ./run-gpg --passphrase-fd 0 \
--cipher-algo cast -c -o x --yes $i
--cipher-algo cast5 -c -o x --yes $i
echo "Hier spricht HAL" | ./run-gpg --passphrase-fd 0 -o y --yes x
cmp $i y || error "$i: mismatch"
done

View File

@ -21,8 +21,10 @@ dsa_usrname2="0xCB879DE9"
dsa_keyrings="--keyring ./pubring.pkr --secret-keyring ./secring.skr"
plain_files="plain-1 plain-2 plain-3"
data_files="data-500 data-9000 data-32000 data-80000"
#plain_files="plain-1 plain-2 plain-3"
#data_files="data-500 data-9000 data-32000 data-80000"
plain_files="plain-1 plain-2"
data_files="data-500 data-9000"
exp_files=""

View File

@ -11,7 +11,7 @@ done
# and with cast
for i in $plain_files $data_files ; do
./run-gpg $dsa_keyrings --cipher-algo cast -e \
./run-gpg $dsa_keyrings --cipher-algo cast5 -e \
-o x --yes -r "$dsa_usrname2" $i
./run-gpg $dsa_keyrings -o y --yes x
cmp $i y || error "$i: mismatch"

View File

@ -9,7 +9,7 @@ for i in $plain_files $data_files ; do
cmp $i y || error "$i: mismatch"
done
for i in $plain_files $data_files ; do
./run-gpg -e -o x --yes -r "$usrname2" --cipher-algo cast $i
./run-gpg -e -o x --yes -r "$usrname2" --cipher-algo cast5 $i
./run-gpg -o y --yes x
cmp $i y || error "$i: mismatch"
done

View File

@ -6,6 +6,7 @@ if ! ../g10/gpg --homedir . $* 2>err.tmp.$$ ; then
rm err.tmp.$$
exit 1
fi
grep -v 'gpg: Good signature from' err.tmp.$$ || true
grep -v 'gpg: Good signature from' err.tmp.$$ \
| grep -v 'gpg: Signature made ' || true
rm err.tmp.$$

View File

@ -6,6 +6,9 @@ noinst_LIBRARIES = libcipher.a
libcipher_a_SOURCES = cipher.c \
pubkey.c \
md.c \
md.h \
dynload.c \
dynload.h \
blowfish.c \
@ -32,8 +35,6 @@ libcipher_a_SOURCES = cipher.c \
sha1.c \
dsa.h \
dsa.c \
md.c \
md.h \
misc.c \
smallprime.c

View File

@ -594,17 +594,17 @@ setkey( CAST5_context *c, byte *key, unsigned keylen )
const char *
cast5_get_info( int algo, size_t *keylen,
size_t *blocksize, size_t *contextsize,
void (**setkey)( void *c, byte *key, unsigned keylen ),
void (**encrypt)( void *c, byte *outbuf, byte *inbuf ),
void (**decrypt)( void *c, byte *outbuf, byte *inbuf )
void (**r_setkey)( void *c, byte *key, unsigned keylen ),
void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
)
{
*keylen = 128;
*blocksize = CAST5_BLOCKSIZE;
*contextsize = sizeof(CAST5_context);
*setkey = FNCCAST_SETKEY(setkey);
*encrypt= FNCCAST_CRYPT(encrypt_block);
*decrypt= FNCCAST_CRYPT(decrypt_block);
*r_setkey = FNCCAST_SETKEY(setkey);
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
if( algo == CIPHER_ALGO_CAST5 )
return "CAST5";

View File

@ -30,32 +30,199 @@
#include "cipher.h"
#include "dynload.h"
/****************
* Return the number of public key material numbers
*/
int
pubkey_get_npkey( int algo )
{
if( is_ELGAMAL(algo) )
return 3;
if( is_RSA(algo) )
return 2;
if( algo == PUBKEY_ALGO_DSA )
return 4;
return 0;
}
/****************
* This is the interface for the public key decryption.
* Return the number of secret key material numbers
*/
int
pubkey_get_nskey( int algo )
{
if( is_ELGAMAL(algo) )
return 4;
if( is_RSA(algo) )
return 6;
if( algo == PUBKEY_ALGO_DSA )
return 5;
return 0;
}
/****************
* Return the number of signature material numbers
*/
int
pubkey_get_nsig( int algo )
{
if( is_ELGAMAL(algo) )
return 2;
if( is_RSA(algo) )
return 1;
if( algo == PUBKEY_ALGO_DSA )
return 2;
return 0;
}
/****************
* Return the number of encryption material numbers
*/
int
pubkey_get_nenc( int algo )
{
if( is_ELGAMAL(algo) )
return 2;
if( is_RSA(algo) )
return 1;
return 0;
}
/****************
* Get the number of nbits from the public key
*/
unsigned
pubkey_nbits( int algo, MPI *pkey )
{
if( is_ELGAMAL( algo ) )
return mpi_get_nbits( pkey[0] );
if( algo == PUBKEY_ALGO_DSA )
return mpi_get_nbits( pkey[0] );
if( is_RSA( algo) )
return mpi_get_nbits( pkey[0] );
return 0;
}
int
pubkey_check_secret_key( int algo, MPI *skey )
{
int rc = 0;
if( is_ELGAMAL(algo) ) {
ELG_secret_key sk;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
if( !elg_check_secret_key( &sk ) )
rc = G10ERR_BAD_SECKEY;
}
else if( algo == PUBKEY_ALGO_DSA ) {
DSA_secret_key sk;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
if( !dsa_check_secret_key( &sk ) )
rc = G10ERR_BAD_SECKEY;
}
#ifdef HAVE_RSA_CIPHER
else if( is_RSA(k->pubkey_algo) ) {
/* FIXME */
RSA_secret_key sk;
assert( ndata == 1 && nskey == 6 );
sk.n = skey[0];
sk.e = skey[1];
sk.d = skey[2];
sk.p = skey[3];
sk.q = skey[4];
sk.u = skey[5];
plain = mpi_alloc_secure( mpi_get_nlimbs(sk.n) );
rsa_secret( plain, data[0], &sk );
}
#endif
else
rc = G10ERR_PUBKEY_ALGO;
return rc;
}
/****************
* This is the interface to the public key encryption.
* Encrypt DATA with PKEY and put it into RESARR which
* should be an array of MPIs of size PUBKEY_MAX_NENC (or less if the
* algorithm allows this - check with pubkey_get_nenc() )
*/
int
pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{
if( DBG_CIPHER ) {
int i;
log_debug("pubkey_encrypt: algo=%d\n", algo );
for(i=0; i < pubkey_get_npkey(algo); i++ )
log_mpidump(" pkey:", pkey[i] );
log_mpidump(" data:", data );
}
/* FIXME: check that data fits into the key */
if( is_ELGAMAL(algo) ) {
ELG_public_key pk;
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
elg_encrypt( resarr[0], resarr[1], data, &pk );
}
#ifdef HAVE_RSA_CIPHER
else if( algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E ) {
RSA_public_key pk;
pk.n = pkey[0];
pk.e = pkey[1];
resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
rsa_public( resarr[0], data, &pk );
}
#endif
else
return G10ERR_PUBKEY_ALGO;
if( DBG_CIPHER ) {
int i;
for(i=0; i < pubkey_get_nenc(algo); i++ )
log_mpidump(" encr:", resarr[i] );
}
return 0;
}
/****************
* This is the interface to the public key decryption.
* ALGO gives the algorithm to use and this implicitly determines
* the size of the arrays.
* result is a pointer to a mpi variable which will receive a
* newly allocated mpi or NULL in case of an error.
*/
int
pubkey_decrypt( int algo, MPI *result, int ndata, MPI *data,
int nskey, MPI *skey )
pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
{
MPI plain = NULL;
*result = NULL; /* so the caller can do always do an mpi_free */
*result = NULL; /* so the caller can always do an mpi_free */
if( DBG_CIPHER ) {
int i;
log_debug("pubkey_decrypt: algo=%d\n", algo );
for(i=0; i < nskey; i++ )
for(i=0; i < pubkey_get_nskey(algo); i++ )
log_mpidump(" skey:", skey[i] );
for(i=0; i < ndata; i++ )
for(i=0; i < pubkey_get_nenc(algo); i++ )
log_mpidump(" data:", data[i] );
}
if( is_ELGAMAL(algo) ) {
ELG_secret_key sk;
assert( ndata == 2 && nskey == 4 );
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
@ -63,22 +230,204 @@ pubkey_decrypt( int algo, MPI *result, int ndata, MPI *data,
plain = mpi_alloc_secure( mpi_get_nlimbs( sk.p ) );
elg_decrypt( plain, data[0], data[1], &sk );
}
else if( is_RSA(k->pubkey_algo) ) {
#ifdef HAVE_RSA_CIPHER
else if( algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E ) {
RSA_secret_key sk;
assert( ndata == 1 && nskey == 6 );
sk.e = skey[0];
sk.n = skey[1];
sk.p = skey[2];
sk.q = skey[3];
sk.d = skey[4];
sk.n = skey[0];
sk.e = skey[1];
sk.d = skey[2];
sk.p = skey[3];
sk.q = skey[4];
sk.u = skey[5];
plain = mpi_alloc_secure( mpi_get_nlimbs(sk.n) );
rsa_secret( plain, data[0], &sk );
}
#endif
else
return G10ERR_PUBKEY_ALGO;
*result = plain;
return 0;
}
/****************
* This is the interface to the public key signing.
* Sign hash with skey and put the result into resarr which
* should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
* algorithm allows this - check with pubkey_get_nsig() )
*/
int
pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
{
if( DBG_CIPHER ) {
int i;
log_debug("pubkey_sign: algo=%d\n", algo );
for(i=0; i < pubkey_get_nskey(algo); i++ )
log_mpidump(" skey:", skey[i] );
log_mpidump(" data:", data );
}
if( is_ELGAMAL(algo) ) {
ELG_secret_key sk;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
elg_sign( resarr[0], resarr[1], data, &sk );
}
else if( algo == PUBKEY_ALGO_DSA ) {
DSA_secret_key sk;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
dsa_sign( resarr[0], resarr[1], data, &sk );
}
#ifdef HAVE_RSA_CIPHER
else if( algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_S ) {
RSA_secret_key sk;
sk.n = skey[0];
sk.e = skey[1];
sk.d = skey[2];
sk.p = skey[3];
sk.q = skey[4];
sk.u = skey[5];
plain = mpi_alloc_secure( mpi_get_nlimbs(sk.n) );
rsa_sign( plain, data[0], &sk );
}
#endif
else
return G10ERR_PUBKEY_ALGO;
if( DBG_CIPHER ) {
int i;
for(i=0; i < pubkey_get_nsig(algo); i++ )
log_mpidump(" sig:", resarr[i] );
}
return 0;
}
/****************
* Verify a public key signature.
* Return 0 if the signature is good
*/
int
pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey )
{
int rc = 0;
if( is_ELGAMAL( algo ) ) {
ELG_public_key pk;
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
if( !elg_verify( data[0], data[1], hash, &pk ) )
rc = G10ERR_BAD_SIGN;
}
else if( algo == PUBKEY_ALGO_DSA ) {
DSA_public_key pk;
pk.p = pkey[0];
pk.q = pkey[1];
pk.g = pkey[2];
pk.y = pkey[3];
if( !dsa_verify( data[0], data[1], hash, &pk ) )
rc = G10ERR_BAD_SIGN;
}
#ifdef HAVE_RSA_CIPHER
else if( algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_S ) {
RSA_public_key pk;
int i, j, c, old_enc;
byte *dp;
const byte *asn;
size_t mdlen, asnlen;
pk.e = pkey[0];
pk.n = pkey[1];
result = mpi_alloc(40);
rsa_public( result, data[0], &pk );
old_enc = 0;
for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
if( !j ) {
if( !i && c != 1 )
break;
else if( i && c == 0xff )
; /* skip the padding */
else if( i && !c )
j++;
else
break;
}
else if( ++j == 18 && c != 1 )
break;
else if( j == 19 && c == 0 ) {
old_enc++;
break;
}
}
if( old_enc ) {
log_error("old encoding scheme is not supported\n");
rc = G10ERR_GENERAL;
goto leave;
}
if( (rc=check_digest_algo(sig->digest_algo)) )
goto leave; /* unsupported algo */
md_enable( digest, sig->digest_algo );
asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
i++, j-- )
if( asn[j] != c )
break;
if( j != -1 || mpi_getbyte(result, i) ) { /* ASN is wrong */
rc = G10ERR_BAD_PUBKEY;
goto leave;
}
for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
if( c != 0xff )
break;
i++;
if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
/* Padding or leading bytes in signature is wrong */
rc = G10ERR_BAD_PUBKEY;
goto leave;
}
if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
|| mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
/* Wrong key used to check the signature */
rc = G10ERR_BAD_PUBKEY;
goto leave;
}
/* complete the digest */
md_putc( digest, sig->sig_class );
{ u32 a = sig->timestamp;
md_putc( digest, (a >> 24) & 0xff );
md_putc( digest, (a >> 16) & 0xff );
md_putc( digest, (a >> 8) & 0xff );
md_putc( digest, a & 0xff );
}
md_final( digest );
dp = md_read( digest, sig->digest_algo );
for(i=mdlen-1; i >= 0; i--, dp++ ) {
if( mpi_getbyte( result, i ) != *dp ) {
rc = G10ERR_BAD_SIGN;
break;
}
}
}
#endif
else
rc = G10ERR_PUBKEY_ALGO;
return rc;
}

View File

@ -1,3 +1,13 @@
Thu Jun 11 13:26:44 1998 Werner Koch (wk@isil.d.shuttle.de)
* packet.h: Mjor chnages to the structure of public key material
which is now stored in an array and not anaymore in a union of
algorithm specific structures. These is needed to make the system
more extendable and makes a lot of stuff much simpler. Changed
all over the system.
* dsa.c, rsa.c, elg.c: Removed.
Wed Jun 10 07:22:02 1998 Werner Koch,mobil,,, (wk@tobold)
* g10.c ("load-extension"): New option.

View File

@ -26,9 +26,6 @@ common_source = \
mdfilter.c \
textfilter.c \
cipher.c \
elg.c \
dsa.c \
rsa.c \
misc.c \
options.h \
openfile.c \

View File

@ -177,6 +177,7 @@ static int
do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
{
int rc = 0;
int n, i;
IOBUF a = iobuf_temp();
if( !pkc->version )
@ -187,31 +188,14 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
if( pkc->version < 4 )
write_16(a, pkc->valid_days );
iobuf_put(a, pkc->pubkey_algo );
if( is_ELGAMAL(pkc->pubkey_algo) ) {
mpi_write(a, pkc->d.elg.p );
mpi_write(a, pkc->d.elg.g );
mpi_write(a, pkc->d.elg.y );
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
mpi_write(a, pkc->d.dsa.p );
mpi_write(a, pkc->d.dsa.q );
mpi_write(a, pkc->d.dsa.g );
mpi_write(a, pkc->d.dsa.y );
}
else if( is_RSA(pkc->pubkey_algo) ) {
mpi_write(a, pkc->d.rsa.n );
mpi_write(a, pkc->d.rsa.e );
}
else {
rc = G10ERR_PUBKEY_ALGO;
goto leave;
}
n = pubkey_get_npkey( pkc->pubkey_algo );
for(i=0; i < n; i++ )
mpi_write(a, pkc->pkey[i] );
write_header2(out, ctb, iobuf_get_temp_length(a), pkc->hdrbytes, 1 );
if( iobuf_write_temp( out, a ) )
rc = G10ERR_WRITE_FILE;
leave:
iobuf_close(a);
return rc;
}
@ -227,7 +211,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
int rc = 0;
int c;
IOBUF a = iobuf_temp();
#if 1
#if 0
FILE *fp = fopen("dump.pkc", "a");
int i=0;
@ -241,7 +225,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
if( (rc = build_packet( a, &pkt )) )
log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc));
while( (c=iobuf_get(a)) != -1 ) {
#if 1
#if 0
fprintf( fp," %02x", c );
if( (++i == 24) ) {
putc('\n', fp);
@ -250,7 +234,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
#endif
md_putc( md, c );
}
#if 1
#if 0
putc('\n', fp);
fclose(fp);
#endif
@ -262,6 +246,7 @@ static int
do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
{
int rc = 0;
int i, nskey, npkey;
IOBUF a = iobuf_temp();
if( !skc->version )
@ -272,11 +257,18 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
if( skc->version < 4 )
write_16(a, skc->valid_days );
iobuf_put(a, skc->pubkey_algo );
if( is_ELGAMAL(skc->pubkey_algo) ) {
mpi_write(a, skc->d.elg.p );
mpi_write(a, skc->d.elg.g );
mpi_write(a, skc->d.elg.y );
if( skc->is_protected ) {
nskey = pubkey_get_nskey( skc->pubkey_algo );
npkey = pubkey_get_npkey( skc->pubkey_algo );
assert( npkey < nskey );
for(i=0; i < npkey; i++ )
mpi_write(a, skc->skey[i] );
if( skc->is_protected ) {
if( is_RSA(skc->pubkey_algo) && skc->version < 4 ) {
iobuf_put(a, skc->protect.algo );
iobuf_write(a, skc->protect.iv, 8 );
}
else {
iobuf_put(a, 0xff );
iobuf_put(a, skc->protect.algo );
iobuf_put(a, skc->protect.s2k.mode );
@ -288,60 +280,17 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
write_32(a, skc->protect.s2k.count );
iobuf_write(a, skc->protect.iv, 8 );
}
else
iobuf_put(a, 0 );
mpi_write(a, skc->d.elg.x );
write_16(a, skc->csum );
}
else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
mpi_write(a, skc->d.dsa.p );
mpi_write(a, skc->d.dsa.q );
mpi_write(a, skc->d.dsa.g );
mpi_write(a, skc->d.dsa.y );
if( skc->is_protected ) {
iobuf_put(a, 0xff );
iobuf_put(a, skc->protect.algo );
iobuf_put(a, skc->protect.s2k.mode );
iobuf_put(a, skc->protect.s2k.hash_algo );
if( skc->protect.s2k.mode == 1
|| skc->protect.s2k.mode == 4 )
iobuf_write(a, skc->protect.s2k.salt, 8 );
if( skc->protect.s2k.mode == 4 )
write_32(a, skc->protect.s2k.count );
iobuf_write(a, skc->protect.iv, 8 );
}
else
iobuf_put(a, 0 );
mpi_write(a, skc->d.dsa.x );
write_16(a, skc->csum );
}
else if( is_RSA(skc->pubkey_algo) ) {
mpi_write(a, skc->d.rsa.n );
mpi_write(a, skc->d.rsa.e );
if( skc->is_protected ) {
iobuf_put(a, skc->protect.algo );
iobuf_write(a, skc->protect.iv, 8 );
}
else
iobuf_put(a, 0 );
mpi_write(a, skc->d.rsa.d );
mpi_write(a, skc->d.rsa.p );
mpi_write(a, skc->d.rsa.q );
mpi_write(a, skc->d.rsa.u );
write_16(a, skc->csum );
}
else {
rc = G10ERR_PUBKEY_ALGO;
goto leave;
}
else
iobuf_put(a, 0 );
for( ; i < nskey; i++ )
mpi_write(a, skc->skey[i] );
write_16(a, skc->csum );
write_header2(out, ctb, iobuf_get_temp_length(a), skc->hdrbytes, 1 );
if( iobuf_write_temp( out, a ) )
rc = G10ERR_WRITE_FILE;
leave:
iobuf_close(a);
return rc;
}
@ -381,29 +330,21 @@ static int
do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
{
int rc = 0;
int n, i;
IOBUF a = iobuf_temp();
write_version( a, ctb );
write_32(a, enc->keyid[0] );
write_32(a, enc->keyid[1] );
iobuf_put(a,enc->pubkey_algo );
if( is_ELGAMAL(enc->pubkey_algo) ) {
mpi_write(a, enc->d.elg.a );
mpi_write(a, enc->d.elg.b );
}
else if( is_RSA(enc->pubkey_algo) ) {
mpi_write(a, enc->d.rsa.rsa_integer );
}
else {
rc = G10ERR_PUBKEY_ALGO;
goto leave;
}
n = pubkey_get_nenc( enc->pubkey_algo );
for(i=0; i < n; i++ )
mpi_write(a, enc->data[i] );
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;
}
@ -650,6 +591,7 @@ static int
do_signature( IOBUF out, int ctb, PKT_signature *sig )
{
int rc = 0;
int n, i;
IOBUF a = iobuf_temp();
if( !sig->version )
@ -684,27 +626,14 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
}
iobuf_put(a, sig->digest_start[0] );
iobuf_put(a, sig->digest_start[1] );
if( is_ELGAMAL(sig->pubkey_algo) ) {
mpi_write(a, sig->d.elg.a );
mpi_write(a, sig->d.elg.b );
}
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
mpi_write(a, sig->d.dsa.r );
mpi_write(a, sig->d.dsa.s );
}
else if( is_RSA(sig->pubkey_algo) ) {
mpi_write(a, sig->d.rsa.rsa_integer );
}
else {
rc = G10ERR_PUBKEY_ALGO;
goto leave;
}
n = pubkey_get_nsig( sig->pubkey_algo );
for(i=0; i < n; i++ )
mpi_write(a, sig->data[i] );
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;
}

View File

@ -1,69 +0,0 @@
/* dsa.c
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* This file is part of GNUPG.
*
* GNUPG 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.
*
* GNUPG 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 <errno.h>
#include <assert.h>
#include "options.h"
#include "packet.h"
#include "errors.h"
#include "iobuf.h"
#include "keydb.h"
#include "memory.h"
#include "util.h"
#include "main.h"
void
g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{
MPI frame;
byte *dp;
assert( sig->pubkey_algo == PUBKEY_ALGO_DSA );
if( !digest_algo )
digest_algo = md_get_algo(md);
dp = md_read( md, digest_algo );
sig->digest_algo = digest_algo;
sig->digest_start[0] = dp[0];
sig->digest_start[1] = dp[1];
sig->d.dsa.r = mpi_alloc( mpi_get_nlimbs(skc->d.dsa.p) );
sig->d.dsa.s = mpi_alloc( mpi_get_nlimbs(skc->d.dsa.p) );
frame = mpi_alloc( (md_digest_length(digest_algo)+BYTES_PER_MPI_LIMB-1)
/ BYTES_PER_MPI_LIMB );
mpi_set_buffer( frame, md_read(md, digest_algo),
md_digest_length(digest_algo), 0 );
if( DBG_CIPHER )
log_mpidump("used sig frame: ", frame);
dsa_sign( sig->d.dsa.r, sig->d.dsa.s, frame, &skc->d.dsa );
mpi_free(frame);
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("DSA signature from: %s\n", ustr );
m_free(ustr);
}
}

View File

@ -1,92 +0,0 @@
/* elg.c
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* This file is part of GNUPG.
*
* GNUPG 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.
*
* GNUPG 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 <errno.h>
#include <assert.h>
#include "options.h"
#include "packet.h"
#include "errors.h"
#include "iobuf.h"
#include "keydb.h"
#include "memory.h"
#include "util.h"
#include "main.h"
void
g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
{
MPI frame;
assert( is_ELGAMAL(enc->pubkey_algo) );
enc->d.elg.a = mpi_alloc( mpi_get_nlimbs(pkc->d.elg.p) );
enc->d.elg.b = mpi_alloc( mpi_get_nlimbs(pkc->d.elg.p) );
keyid_from_pkc( pkc, enc->keyid );
frame = encode_session_key( dek, mpi_get_nbits(pkc->d.elg.p) );
if( DBG_CIPHER )
log_mpidump("Plain DEK frame: ", frame);
elg_encrypt( enc->d.elg.a, enc->d.elg.b, frame, &pkc->d.elg );
mpi_free( frame );
if( DBG_CIPHER ) {
log_mpidump("Encry DEK a: ", enc->d.elg.a );
log_mpidump(" DEK b: ", enc->d.elg.b );
}
if( opt.verbose ) {
char *ustr = get_user_id_string( enc->keyid );
log_info("ElGamal encrypted for: %s\n", ustr );
m_free(ustr);
}
}
void
g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{
MPI frame;
byte *dp;
assert( is_ELGAMAL(sig->pubkey_algo) );
if( !digest_algo )
digest_algo = md_get_algo(md);
dp = md_read( md, digest_algo );
sig->digest_algo = digest_algo;
sig->digest_start[0] = dp[0];
sig->digest_start[1] = dp[1];
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
sig->d.elg.b = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
frame = encode_md_value( md, digest_algo, mpi_get_nbits(skc->d.elg.p));
if( DBG_CIPHER )
log_mpidump("calc sig frame (elg): ", frame);
elg_sign( sig->d.elg.a, sig->d.elg.b, frame, &skc->d.elg );
mpi_free(frame);
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("ElGamal signature from: %s\n", ustr );
m_free(ustr);
}
}

View File

@ -329,26 +329,36 @@ write_pubkey_enc_from_list( PKC_LIST pkc_list, DEK *dek, IOBUF out )
int rc;
for( ; pkc_list; pkc_list = pkc_list->next ) {
MPI frame;
pkc = pkc_list->pkc;
enc = m_alloc_clear( sizeof *enc );
enc->pubkey_algo = pkc->pubkey_algo;
if( is_ELGAMAL(enc->pubkey_algo) )
g10_elg_encrypt( pkc, enc, dek );
else if( is_RSA(enc->pubkey_algo) )
g10_rsa_encrypt( pkc, enc, dek );
else
BUG();
/* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_PUBKEY_ENC;
pkt.pkt.pubkey_enc = enc;
rc = build_packet( out, &pkt );
free_pubkey_enc(enc);
if( rc ) {
log_error("build pubkey_enc packet failed: %s\n", g10_errstr(rc) );
return rc;
keyid_from_pkc( pkc, enc->keyid );
frame = encode_session_key( dek, pubkey_nbits( pkc->pubkey_algo,
pkc->pkey ) );
rc = pubkey_encrypt( pkc->pubkey_algo, enc->data, frame, pkc->pkey );
mpi_free( frame );
if( rc )
log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );
else {
if( opt.verbose ) {
char *ustr = get_user_id_string( enc->keyid );
log_info("%s encrypted for: %s\n",
pubkey_algo_to_string(enc->pubkey_algo), ustr );
m_free(ustr);
}
/* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_PUBKEY_ENC;
pkt.pkt.pubkey_enc = enc;
rc = build_packet( out, &pkt );
if( rc )
log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
}
free_pubkey_enc(enc);
if( rc )
return rc;
}
return 0;
}

View File

@ -40,28 +40,20 @@ free_symkey_enc( PKT_symkey_enc *enc )
void
free_pubkey_enc( PKT_pubkey_enc *enc )
{
if( is_ELGAMAL(enc->pubkey_algo) ) {
mpi_free( enc->d.elg.a );
mpi_free( enc->d.elg.b );
}
else if( is_RSA(enc->pubkey_algo) )
mpi_free( enc->d.rsa.rsa_integer );
int n, i;
n = pubkey_get_nenc( enc->pubkey_algo );
for(i=0; i < n; i++ )
mpi_free( enc->data[i] );
m_free(enc);
}
void
free_seckey_enc( PKT_signature *sig )
{
if( is_ELGAMAL(sig->pubkey_algo) ) {
mpi_free( sig->d.elg.a );
mpi_free( sig->d.elg.b );
}
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
mpi_free( sig->d.dsa.r );
mpi_free( sig->d.dsa.s );
}
else if( is_RSA(sig->pubkey_algo) )
mpi_free( sig->d.rsa.rsa_integer );
int n, i;
n = pubkey_get_nenc( sig->pubkey_algo );
for(i=0; i < n; i++ )
mpi_free( sig->data[i] );
m_free(sig->hashed_data);
m_free(sig->unhashed_data);
m_free(sig);
@ -72,23 +64,15 @@ free_seckey_enc( PKT_signature *sig )
void
release_public_cert_parts( PKT_public_cert *cert )
{
if( is_ELGAMAL(cert->pubkey_algo) ) {
mpi_free( cert->d.elg.p ); cert->d.elg.p = NULL;
mpi_free( cert->d.elg.g ); cert->d.elg.g = NULL;
mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
}
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA ) {
mpi_free( cert->d.dsa.p ); cert->d.dsa.p = NULL;
mpi_free( cert->d.dsa.q ); cert->d.dsa.q = NULL;
mpi_free( cert->d.dsa.g ); cert->d.dsa.g = NULL;
mpi_free( cert->d.dsa.y ); cert->d.dsa.y = NULL;
}
else if( is_RSA(cert->pubkey_algo) ) {
mpi_free( cert->d.rsa.n ); cert->d.rsa.n = NULL;
mpi_free( cert->d.rsa.e ); cert->d.rsa.e = NULL;
int n, i;
n = pubkey_get_npkey( cert->pubkey_algo );
for(i=0; i < n; i++ ) {
mpi_free( cert->pkey[i] );
cert->pkey[i] = NULL;
}
}
void
free_public_cert( PKT_public_cert *cert )
{
@ -99,50 +83,26 @@ free_public_cert( PKT_public_cert *cert )
PKT_public_cert *
copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
{
int n, i;
if( !d )
d = m_alloc(sizeof *d);
memcpy( d, s, sizeof *d );
if( is_ELGAMAL(s->pubkey_algo) ) {
d->d.elg.p = mpi_copy( s->d.elg.p );
d->d.elg.g = mpi_copy( s->d.elg.g );
d->d.elg.y = mpi_copy( s->d.elg.y );
}
else if( s->pubkey_algo == PUBKEY_ALGO_DSA ) {
d->d.dsa.p = mpi_copy( s->d.dsa.p );
d->d.dsa.q = mpi_copy( s->d.dsa.q );
d->d.dsa.g = mpi_copy( s->d.dsa.g );
d->d.dsa.y = mpi_copy( s->d.dsa.y );
}
else if( is_RSA(s->pubkey_algo) ) {
d->d.rsa.n = mpi_copy( s->d.rsa.n );
d->d.rsa.e = mpi_copy( s->d.rsa.e );
}
n = pubkey_get_npkey( s->pubkey_algo );
for(i=0; i < n; i++ )
d->pkey[i] = mpi_copy( s->pkey[i] );
return d;
}
void
release_secret_cert_parts( PKT_secret_cert *cert )
{
if( is_ELGAMAL(cert->pubkey_algo) ) {
mpi_free( cert->d.elg.p ); cert->d.elg.p = NULL;
mpi_free( cert->d.elg.g ); cert->d.elg.g = NULL;
mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
mpi_free( cert->d.elg.x ); cert->d.elg.x = NULL;
}
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA ) {
mpi_free( cert->d.dsa.p ); cert->d.dsa.p = NULL;
mpi_free( cert->d.dsa.q ); cert->d.dsa.q = NULL;
mpi_free( cert->d.dsa.g ); cert->d.dsa.g = NULL;
mpi_free( cert->d.dsa.y ); cert->d.dsa.y = NULL;
mpi_free( cert->d.dsa.x ); cert->d.dsa.x = NULL;
}
else if( is_RSA(cert->pubkey_algo) ) {
mpi_free( cert->d.rsa.n ); cert->d.rsa.n = NULL;
mpi_free( cert->d.rsa.e ); cert->d.rsa.e = NULL;
mpi_free( cert->d.rsa.d ); cert->d.rsa.d = NULL;
mpi_free( cert->d.rsa.p ); cert->d.rsa.p = NULL;
mpi_free( cert->d.rsa.q ); cert->d.rsa.q = NULL;
mpi_free( cert->d.rsa.u ); cert->d.rsa.u = NULL;
int n, i;
n = pubkey_get_nskey( cert->pubkey_algo );
for(i=0; i < n; i++ ) {
mpi_free( cert->skey[i] );
cert->skey[i] = NULL;
}
}
@ -156,30 +116,14 @@ free_secret_cert( PKT_secret_cert *cert )
PKT_secret_cert *
copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s )
{
int n, i;
if( !d )
d = m_alloc(sizeof *d);
memcpy( d, s, sizeof *d );
if( is_ELGAMAL(s->pubkey_algo) ) {
d->d.elg.p = mpi_copy( s->d.elg.p );
d->d.elg.g = mpi_copy( s->d.elg.g );
d->d.elg.y = mpi_copy( s->d.elg.y );
d->d.elg.x = mpi_copy( s->d.elg.x );
}
else if( s->pubkey_algo == PUBKEY_ALGO_DSA ) {
d->d.dsa.p = mpi_copy( s->d.dsa.p );
d->d.dsa.q = mpi_copy( s->d.dsa.q );
d->d.dsa.g = mpi_copy( s->d.dsa.g );
d->d.dsa.y = mpi_copy( s->d.dsa.y );
d->d.dsa.x = mpi_copy( s->d.dsa.x );
}
else if( is_RSA(s->pubkey_algo) ) {
d->d.rsa.n = mpi_copy( s->d.rsa.n );
d->d.rsa.e = mpi_copy( s->d.rsa.e );
d->d.rsa.d = mpi_copy( s->d.rsa.d );
d->d.rsa.p = mpi_copy( s->d.rsa.p );
d->d.rsa.q = mpi_copy( s->d.rsa.q );
d->d.rsa.u = mpi_copy( s->d.rsa.u );
}
n = pubkey_get_nskey( s->pubkey_algo );
for(i=0; i < n; i++ )
d->skey[i] = mpi_copy( s->skey[i] );
return d;
}
@ -298,6 +242,8 @@ free_packet( PACKET *pkt )
int
cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b )
{
int n, i;
if( a->timestamp != b->timestamp )
return -1;
if( a->valid_days != b->valid_days )
@ -305,28 +251,9 @@ cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b )
if( a->pubkey_algo != b->pubkey_algo )
return -1;
if( is_ELGAMAL(a->pubkey_algo) ) {
if( mpi_cmp( a->d.elg.p , b->d.elg.p ) )
return -1;
if( mpi_cmp( a->d.elg.g , b->d.elg.g ) )
return -1;
if( mpi_cmp( a->d.elg.y , b->d.elg.y ) )
return -1;
}
else if( a->pubkey_algo == PUBKEY_ALGO_DSA ) {
if( mpi_cmp( a->d.dsa.p , b->d.dsa.p ) )
return -1;
if( mpi_cmp( a->d.dsa.q , b->d.dsa.q ) )
return -1;
if( mpi_cmp( a->d.dsa.g , b->d.dsa.g ) )
return -1;
if( mpi_cmp( a->d.dsa.y , b->d.dsa.y ) )
return -1;
}
else if( is_RSA(a->pubkey_algo) ) {
if( mpi_cmp( a->d.rsa.n , b->d.rsa.n ) )
return -1;
if( mpi_cmp( a->d.rsa.e , b->d.rsa.e ) )
n = pubkey_get_npkey( b->pubkey_algo );
for(i=0; i < n; i++ ) {
if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
return -1;
}
@ -339,6 +266,8 @@ cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b )
int
cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc )
{
int n, i;
if( pkc->timestamp != skc->timestamp )
return -1;
if( pkc->valid_days != skc->valid_days )
@ -346,31 +275,11 @@ cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc )
if( pkc->pubkey_algo != skc->pubkey_algo )
return -1;
if( is_ELGAMAL(pkc->pubkey_algo) ) {
if( mpi_cmp( pkc->d.elg.p , skc->d.elg.p ) )
return -1;
if( mpi_cmp( pkc->d.elg.g , skc->d.elg.g ) )
return -1;
if( mpi_cmp( pkc->d.elg.y , skc->d.elg.y ) )
n = pubkey_get_npkey( pkc->pubkey_algo );
for(i=0; i < n; i++ ) {
if( mpi_cmp( pkc->pkey[i] , skc->skey[i] ) )
return -1;
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
if( mpi_cmp( pkc->d.dsa.p , skc->d.dsa.p ) )
return -1;
if( mpi_cmp( pkc->d.dsa.q , skc->d.dsa.q ) )
return -1;
if( mpi_cmp( pkc->d.dsa.g , skc->d.dsa.g ) )
return -1;
if( mpi_cmp( pkc->d.dsa.y , skc->d.dsa.y ) )
return -1;
}
else if( is_RSA(pkc->pubkey_algo) ) {
if( mpi_cmp( pkc->d.rsa.n , skc->d.rsa.n ) )
return -1;
if( mpi_cmp( pkc->d.rsa.e , skc->d.rsa.e ) )
return -1;
}
return 0;
}

View File

@ -155,17 +155,17 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
skc->version = pkc->version = version;
skc->valid_days = pkc->valid_days = valid_days;
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
pkc->d.elg.p = pk.p;
pkc->d.elg.g = pk.g;
pkc->d.elg.y = pk.y;
skc->d.elg.p = sk.p;
skc->d.elg.g = sk.g;
skc->d.elg.y = sk.y;
skc->d.elg.x = sk.x;
pkc->pkey[0] = pk.p;
pkc->pkey[1] = pk.g;
pkc->pkey[2] = pk.y;
skc->skey[0] = sk.p;
skc->skey[1] = sk.g;
skc->skey[2] = sk.y;
skc->skey[3] = sk.x;
skc->is_protected = 0;
skc->protect.algo = 0;
skc->csum = checksum_mpi( skc->d.elg.x );
skc->csum = checksum_mpi( skc->skey[3] );
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
*ret_skc = copy_secret_cert( NULL, skc );
@ -296,19 +296,19 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
*/
skc->valid_days = pkc->valid_days = valid_days;
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_DSA;
pkc->d.dsa.p = pk.p;
pkc->d.dsa.q = pk.q;
pkc->d.dsa.g = pk.g;
pkc->d.dsa.y = pk.y;
skc->d.dsa.p = sk.p;
skc->d.dsa.q = sk.q;
skc->d.dsa.g = sk.g;
skc->d.dsa.y = sk.y;
skc->d.dsa.x = sk.x;
pkc->pkey[0] = pk.p;
pkc->pkey[1] = pk.q;
pkc->pkey[2] = pk.g;
pkc->pkey[3] = pk.y;
skc->skey[0] = sk.p;
skc->skey[1] = sk.q;
skc->skey[2] = sk.g;
skc->skey[3] = sk.y;
skc->skey[4] = sk.x;
skc->is_protected = 0;
skc->protect.algo = 0;
skc->csum = checksum_mpi( skc->d.dsa.x );
skc->csum = checksum_mpi( skc->skey[4] );
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
*ret_skc = copy_secret_cert( NULL, skc );

View File

@ -47,182 +47,72 @@ pubkey_letter( int algo )
}
}
/* this is special code for V3 which uses ElGamal and
* calculates a fingerprint like V4, but with rmd160
* and a version byte of 3. Returns an md handle, caller must
* do md_close()
*/
static MD_HANDLE
v3_elg_fingerprint_md( PKT_public_cert *pkc )
do_fingerprint_md( PKT_public_cert *pkc )
{
MD_HANDLE md;
byte *buf1, *buf2, *buf3;
byte *p1, *p2, *p3;
unsigned n1, n2, n3;
unsigned nb1, nb2, nb3;
unsigned n;
unsigned nb[PUBKEY_MAX_NPKEY];
unsigned nn[PUBKEY_MAX_NPKEY];
byte *pp[PUBKEY_MAX_NPKEY];
int i;
int npkey = pubkey_get_npkey( pkc->pubkey_algo );
nb1 = mpi_get_nbits(pkc->d.elg.p);
p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
nb2 = mpi_get_nbits(pkc->d.elg.g);
p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
nb3 = mpi_get_nbits(pkc->d.elg.y);
p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
/* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
n = 14 + n1 + n2 + n3;
md = md_open( DIGEST_ALGO_RMD160, 0);
md = md_open( pkc->version < 4 ? DIGEST_ALGO_RMD160 : DIGEST_ALGO_SHA1, 0);
n = pkc->version < 4 ? 8 : 6;
for(i=0; i < npkey; i++ ) {
nb[i] = mpi_get_nbits(pkc->pkey[i]);
pp[i] = mpi_get_buffer( pkc->pkey[i], nn+i, NULL );
n += 2 + nn[i];
}
md_putc( md, 0x99 ); /* ctb */
md_putc( md, n >> 8 ); /* 2 byte length header */
md_putc( md, n );
md_putc( md, 3 ); /* version */
if( pkc->version < 4 )
md_putc( md, 3 );
else
md_putc( md, 4 );
{ u32 a = pkc->timestamp;
md_putc( md, a >> 24 );
md_putc( md, a >> 16 );
md_putc( md, a >> 8 );
md_putc( md, a );
}
{ u16 a = pkc->valid_days;
if( pkc->version < 4 ) {
u16 a = pkc->valid_days;
md_putc( md, a >> 8 );
md_putc( md, a );
}
md_putc( md, pkc->pubkey_algo );
md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 );
md_putc( md, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 );
md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 );
m_free(buf1);
m_free(buf2);
m_free(buf3);
md_final( md );
return md;
}
static MD_HANDLE
elg_fingerprint_md( PKT_public_cert *pkc )
{
MD_HANDLE md;
byte *buf1, *buf3, *buf4 ;
byte *p1, *p3, *p4;
unsigned n1, n3, n4;
unsigned nb1, nb3, nb4;
unsigned n;
nb1 = mpi_get_nbits(pkc->d.elg.p);
p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
nb3 = mpi_get_nbits(pkc->d.elg.g);
p3 = buf3 = mpi_get_buffer( pkc->d.elg.g, &n3, NULL );
nb4 = mpi_get_nbits(pkc->d.elg.y);
p4 = buf4 = mpi_get_buffer( pkc->d.elg.y, &n4, NULL );
/* calculate length of packet */
n = 12 + n1 + n3 +n4 ;
md = md_open( DIGEST_ALGO_SHA1, 0);
md_putc( md, 0x99 ); /* ctb */
md_putc( md, n >> 8 ); /* 2 byte length header */
md_putc( md, n );
md_putc( md, 4 ); /* version */
{ u32 a = pkc->timestamp;
md_putc( md, a >> 24 );
md_putc( md, a >> 16 );
md_putc( md, a >> 8 );
md_putc( md, a );
for(i=0; i < npkey; i++ ) {
md_putc( md, nb[i]>>8);
md_putc( md, nb[i] );
md_write( md, pp[i], nn[i] );
m_free(pp[i]);
}
md_putc( md, pkc->pubkey_algo );
md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 );
md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 );
md_putc( md, nb4>>8); md_putc( md, nb4 ); md_write( md, p4, n4 );
m_free(buf1);
m_free(buf3);
m_free(buf4);
md_final( md );
return md;
}
static MD_HANDLE
dsa_fingerprint_md( PKT_public_cert *pkc )
{
MD_HANDLE md;
byte *buf1, *buf2, *buf3, *buf4 ;
byte *p1, *p2, *p3, *p4;
unsigned n1, n2, n3, n4;
unsigned nb1, nb2, nb3, nb4;
unsigned n;
nb1 = mpi_get_nbits(pkc->d.dsa.p);
p1 = buf1 = mpi_get_buffer( pkc->d.dsa.p, &n1, NULL );
nb2 = mpi_get_nbits(pkc->d.dsa.q);
p2 = buf2 = mpi_get_buffer( pkc->d.dsa.q, &n2, NULL );
nb3 = mpi_get_nbits(pkc->d.dsa.g);
p3 = buf3 = mpi_get_buffer( pkc->d.dsa.g, &n3, NULL );
nb4 = mpi_get_nbits(pkc->d.dsa.y);
p4 = buf4 = mpi_get_buffer( pkc->d.dsa.y, &n4, NULL );
/* calculate length of packet */
n = 14 + n1 + n2 + n3 +n4 ;
md = md_open( DIGEST_ALGO_SHA1, 0);
md_putc( md, 0x99 ); /* ctb */
md_putc( md, n >> 8 ); /* 2 byte length header */
md_putc( md, n );
md_putc( md, 4 ); /* version */
{ u32 a = pkc->timestamp;
md_putc( md, a >> 24 );
md_putc( md, a >> 16 );
md_putc( md, a >> 8 );
md_putc( md, a );
}
md_putc( md, pkc->pubkey_algo );
md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 );
md_putc( md, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 );
md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 );
md_putc( md, nb4>>8); md_putc( md, nb4 ); md_write( md, p4, n4 );
m_free(buf1);
m_free(buf2);
m_free(buf3);
m_free(buf4);
md_final( md );
return md;
}
static MD_HANDLE
elg_fingerprint_md_skc( PKT_secret_cert *skc )
do_fingerprint_md_skc( PKT_secret_cert *skc )
{
PKT_public_cert pkc;
int npkey = pubkey_get_npkey( skc->pubkey_algo ); /* npkey is correct! */
int i;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.version = skc->version;
pkc.timestamp = skc->timestamp;
pkc.valid_days = skc->valid_days;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.d.elg.p = skc->d.elg.p;
pkc.d.elg.g = skc->d.elg.g;
pkc.d.elg.y = skc->d.elg.y;
if( pkc.version < 4 )
return v3_elg_fingerprint_md( &pkc );
else
return elg_fingerprint_md( &pkc );
}
static MD_HANDLE
dsa_fingerprint_md_skc( PKT_secret_cert *skc )
{
PKT_public_cert pkc;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.timestamp = skc->timestamp;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.d.dsa.p = skc->d.dsa.p;
pkc.d.dsa.q = skc->d.dsa.q;
pkc.d.dsa.g = skc->d.dsa.g;
pkc.d.dsa.y = skc->d.dsa.y;
return dsa_fingerprint_md( &pkc );
for( i=0; i < npkey; i++ )
pkc.pkey[i] = skc->skey[i];
return do_fingerprint_md( &pkc );
}
@ -239,35 +129,20 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
if( !keyid )
keyid = dummy_keyid;
if( is_ELGAMAL(skc->pubkey_algo) ) {
const byte *dp;
MD_HANDLE md;
md = elg_fingerprint_md_skc(skc);
if( skc->version < 4 )
dp = md_read( md, DIGEST_ALGO_RMD160 );
else
dp = md_read( md, DIGEST_ALGO_SHA1 );
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
md_close(md);
}
else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
const byte *dp;
MD_HANDLE md;
md = dsa_fingerprint_md_skc(skc);
dp = md_read( md, DIGEST_ALGO_SHA1 );
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
md_close(md);
}
else if( is_RSA(skc->pubkey_algo) ) {
lowbits = mpi_get_keyid( skc->d.rsa.n, keyid );
if( skc->version < 4 && is_RSA(skc->pubkey_algo) ) {
lowbits = mpi_get_keyid( skc->skey[0], keyid ); /* take n */
}
else {
keyid[0] = keyid[1] = lowbits = 0;
const byte *dp;
MD_HANDLE md;
md = do_fingerprint_md_skc(skc);
dp = md_read( md, 0 );
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
md_close(md);
}
return lowbits;
}
@ -285,37 +160,18 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
if( !keyid )
keyid = dummy_keyid;
if( is_ELGAMAL(pkc->pubkey_algo) ) {
const byte *dp;
MD_HANDLE md;
if( pkc->version < 4 ) {
md = v3_elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_RMD160 );
}
else {
md = elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_SHA1 );
}
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
md_close(md);
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
const byte *dp;
MD_HANDLE md;
md = dsa_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_SHA1 );
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
md_close(md);
}
else if( is_RSA(pkc->pubkey_algo) ) {
lowbits = mpi_get_keyid( pkc->d.rsa.n, keyid );
if( pkc->version < 4 && is_RSA(pkc->pubkey_algo) ) {
lowbits = mpi_get_keyid( pkc->pkey[0], keyid ); /* from n */
}
else {
keyid[0] = keyid[1] = lowbits = 0;
const byte *dp;
MD_HANDLE md;
md = do_fingerprint_md(pkc);
dp = md_read( md, 0 );
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
md_close(md);
}
return lowbits;
@ -338,17 +194,7 @@ keyid_from_sig( PKT_signature *sig, u32 *keyid )
unsigned
nbits_from_pkc( PKT_public_cert *pkc )
{
if( is_ELGAMAL(pkc->pubkey_algo) ) {
return mpi_get_nbits( pkc->d.elg.p );
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
return mpi_get_nbits( pkc->d.dsa.p );
}
else if( is_RSA(pkc->pubkey_algo) ) {
return mpi_get_nbits( pkc->d.rsa.n );
}
else
return 0;
return pubkey_nbits( pkc->pubkey_algo, pkc->pkey );
}
/****************
@ -357,17 +203,7 @@ nbits_from_pkc( PKT_public_cert *pkc )
unsigned
nbits_from_skc( PKT_secret_cert *skc )
{
if( is_ELGAMAL(skc->pubkey_algo) ) {
return mpi_get_nbits( skc->d.elg.p );
}
else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
return mpi_get_nbits( skc->d.dsa.p );
}
else if( is_RSA(skc->pubkey_algo) ) {
return mpi_get_nbits( skc->d.rsa.n );
}
else
return 0;
return pubkey_nbits( skc->pubkey_algo, skc->skey );
}
/****************
@ -417,40 +253,6 @@ datestr_from_sig( PKT_signature *sig )
* The length of the array is returned in ret_len. Caller must free
* the array.
*/
byte *
fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
{
PKT_public_cert pkc;
byte *p;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.version = skc->version;
if( is_ELGAMAL(pkc.pubkey_algo) ) {
pkc.timestamp = skc->timestamp;
pkc.valid_days = skc->valid_days;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.d.elg.p = skc->d.elg.p;
pkc.d.elg.g = skc->d.elg.g;
pkc.d.elg.y = skc->d.elg.y;
}
else if( pkc.pubkey_algo == PUBKEY_ALGO_DSA ) {
pkc.timestamp = skc->timestamp;
pkc.valid_days = skc->valid_days;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.d.dsa.p = skc->d.dsa.p;
pkc.d.dsa.q = skc->d.dsa.q;
pkc.d.dsa.g = skc->d.dsa.g;
pkc.d.dsa.y = skc->d.dsa.y;
}
else if( is_RSA(pkc.pubkey_algo) ) {
pkc.d.rsa.n = skc->d.rsa.n;
pkc.d.rsa.e = skc->d.rsa.e;
}
p = fingerprint_from_pkc( &pkc, ret_len );
memset(&pkc, 0, sizeof pkc); /* not really needed */
return p;
}
@ -462,38 +264,15 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
size_t len;
unsigned n;
if( is_ELGAMAL(pkc->pubkey_algo) ) {
MD_HANDLE md;
if( pkc->version < 4 ) {
md = v3_elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_RMD160 );
}
else {
md = elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_SHA1 );
}
array = m_alloc( 20 );
len = 20;
memcpy(array, dp, 20 );
md_close(md);
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
MD_HANDLE md;
md = dsa_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_SHA1 );
array = m_alloc( 20 );
len = 20;
memcpy(array, dp, 20 );
md_close(md);
}
else if( is_RSA(pkc->pubkey_algo) ) {
if( pkc->version < 4 && is_RSA(pkc->pubkey_algo) ) {
/* RSA in version 3 packets is special */
MD_HANDLE md;
md = md_open( DIGEST_ALGO_MD5, 0);
p = buf = mpi_get_buffer( pkc->d.rsa.n, &n, NULL );
p = buf = mpi_get_buffer( pkc->pkey[0], &n, NULL );
md_write( md, p, n );
m_free(buf);
p = buf = mpi_get_buffer( pkc->d.rsa.e, &n, NULL );
p = buf = mpi_get_buffer( pkc->pkey[1], &n, NULL );
md_write( md, p, n );
m_free(buf);
md_final(md);
@ -503,8 +282,52 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
md_close(md);
}
else {
array = m_alloc(1);
len = 0; /* ooops */
MD_HANDLE md;
md = do_fingerprint_md(pkc);
dp = md_read( md, 0 );
len = md_digest_length( md_get_algo( md ) );
array = m_alloc( len );
memcpy(array, dp, len );
md_close(md);
}
*ret_len = len;
return array;
}
byte *
fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
{
byte *p, *buf, *array;
const char *dp;
size_t len;
unsigned n;
if( skc->version < 4 && is_RSA(skc->pubkey_algo) ) {
/* RSA in version 3 packets is special */
MD_HANDLE md;
md = md_open( DIGEST_ALGO_MD5, 0);
p = buf = mpi_get_buffer( skc->skey[1], &n, NULL );
md_write( md, p, n );
m_free(buf);
p = buf = mpi_get_buffer( skc->skey[0], &n, NULL );
md_write( md, p, n );
m_free(buf);
md_final(md);
array = m_alloc( 16 );
len = 16;
memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
md_close(md);
}
else {
MD_HANDLE md;
md = do_fingerprint_md_skc(skc);
dp = md_read( md, 0 );
len = md_digest_length( md_get_algo( md ) );
array = m_alloc( len );
memcpy(array, dp, len );
md_close(md);
}
*ret_len = len;

View File

@ -91,20 +91,6 @@ MPI encode_md_value( MD_HANDLE md, int hash_algo, unsigned nbits );
KBNODE make_comment_node( const char *s );
KBNODE make_mpi_comment_node( const char *s, MPI a );
/*-- elg.c --*/
void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo );
/*-- dsa.c --*/
void g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo );
/*-- rsa.c --*/
void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo );
/*-- import.c --*/
int import_pubkeys( const char *filename );
/*-- export.c --*/

View File

@ -68,8 +68,7 @@ typedef struct {
u32 keyid[2]; /* 64 bit keyid */
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
int mpi_count; /* 1 for rsa, 2 for ELG */
MPI material[2]; /* (ELG needs 2)
MPI data[PUBKEY_MAX_NENC];
} PKT_pubkey_enc;
@ -94,20 +93,16 @@ typedef struct {
byte *hashed_data; /* all subpackets with hashed data (v4 only) */
byte *unhashed_data; /* ditto for unhashed data */
byte digest_start[2]; /* first 2 bytes of the digest */
union {
struct {
MPI a, b; /* integers with the digest */
} elg;
struct {
MPI r, s; /* integers with the digest */
} dsa;
struct {
MPI rsa_integer; /* the encrypted digest */
} rsa;
} d;
MPI data[PUBKEY_MAX_NSIG];
} PKT_signature;
/****************
* Note about the pkey/skey elements: We assume that the secret keys
* has the same elemts as the public key at the begin of the array, so
* that npkey < nskey and it is possible to compare the secret and
* public keys by comparing the first npkey elements of pkey againts skey.
*/
typedef struct {
u32 timestamp; /* certificate made */
u16 valid_days; /* valid for this number of days */
@ -115,11 +110,7 @@ typedef struct {
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
ulong local_id; /* internal use, valid if > 0 */
union {
ELG_public_key elg;
DSA_public_key dsa;
RSA_public_key rsa;
} d;
MPI pkey[PUBKEY_MAX_NPKEY];
} PKT_public_cert;
typedef struct {
@ -137,11 +128,7 @@ typedef struct {
STRING2KEY s2k;
byte iv[8]; /* initialization vector for CFB mode */
} protect;
union {
ELG_secret_key elg;
DSA_secret_key dsa;
RSA_secret_key rsa;
} d;
MPI skey[PUBKEY_MAX_NSKEY];
u16 csum; /* checksum */
} PKT_secret_cert;

View File

@ -318,6 +318,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
break;
case PKT_RING_TRUST:
parse_trust(inp, pkttype, pktlen);
rc = 0;
break;
case PKT_PLAINTEXT:
rc = parse_plaintext(inp, pkttype, pktlen, pkt );
@ -502,6 +503,7 @@ static int
parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
unsigned n;
int i, ndata;
PKT_pubkey_enc *k;
k = packet->pkt.pubkey_enc = m_alloc(sizeof *packet->pkt.pubkey_enc );
@ -520,31 +522,20 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
if( list_mode )
printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
if( is_ELGAMAL(k->pubkey_algo) ) {
n = pktlen;
k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n;
n = pktlen;
k->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\telg a: ");
mpi_print(stdout, k->d.elg.a, mpi_print_mode );
printf("\n\telg b: ");
mpi_print(stdout, k->d.elg.b, mpi_print_mode );
putchar('\n');
}
}
else if( is_RSA(k->pubkey_algo) ) {
n = pktlen;
k->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\trsa integer: ");
mpi_print(stdout, k->d.rsa.rsa_integer, mpi_print_mode );
putchar('\n');
}
}
else if( list_mode )
printf("\tunknown algorithm %d\n", k->pubkey_algo );
ndata = pubkey_get_nenc(k->pubkey_algo);
if( !ndata && list_mode )
printf("\tunsupported algorithm %d\n", k->pubkey_algo );
for( i=0; i < ndata; i++ ) {
n = pktlen;
k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
if( list_mode ) {
printf("\tdata: ");
mpi_print(stdout, k->data[i], mpi_print_mode );
putchar('\n');
}
}
leave:
skip_rest(inp, pktlen);
@ -663,6 +654,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
unsigned n;
int is_v4=0;
int rc=0;
int i, ndata;
if( pktlen < 16 ) {
log_error("packet(%d) too short\n", pkttype);
@ -763,44 +755,22 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
parse_sig_subpkt( sig->unhashed_data,SIGSUBPKT_LIST_UNHASHED, NULL);
}
}
if( is_ELGAMAL(sig->pubkey_algo) ) {
n = pktlen;
sig->d.elg.a = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen;
sig->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\telg a: ");
mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
printf("\n\telg b: ");
mpi_print(stdout, sig->d.elg.b, mpi_print_mode );
putchar('\n');
}
}
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
n = pktlen;
sig->d.dsa.r = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen;
sig->d.dsa.s = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\tdsa r: ");
mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
printf("\n\tdsa s: ");
mpi_print(stdout, sig->d.elg.b, mpi_print_mode );
putchar('\n');
}
}
else if( is_RSA(sig->pubkey_algo) ) {
n = pktlen;
sig->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\trsa integer: ");
mpi_print(stdout, sig->d.rsa.rsa_integer, mpi_print_mode );
putchar('\n');
}
}
else if( list_mode )
ndata = pubkey_get_nsig(sig->pubkey_algo);
if( !ndata && list_mode )
printf("\tunknown algorithm %d\n", sig->pubkey_algo );
for( i=0; i < ndata; i++ ) {
n = pktlen;
sig->data[i] = mpi_read(inp, &n, 0 );
pktlen -=n;
if( list_mode ) {
printf("\tdata: ");
mpi_print(stdout, sig->data[i], mpi_print_mode );
putchar('\n');
}
}
leave:
skip_rest(inp, pktlen);
@ -932,17 +902,17 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
putchar('\n');
}
if( pkttype == PKT_PUBLIC_CERT || pkttype == PKT_PUBKEY_SUBCERT ) {
pkt->pkt.public_cert->d.elg.p = elg_p;
pkt->pkt.public_cert->d.elg.g = elg_g;
pkt->pkt.public_cert->d.elg.y = elg_y;
pkt->pkt.public_cert->pkey[0] = elg_p;
pkt->pkt.public_cert->pkey[1] = elg_g;
pkt->pkt.public_cert->pkey[2] = elg_y;
}
else {
PKT_secret_cert *cert = pkt->pkt.secret_cert;
byte temp[8];
pkt->pkt.secret_cert->d.elg.p = elg_p;
pkt->pkt.secret_cert->d.elg.g = elg_g;
pkt->pkt.secret_cert->d.elg.y = elg_y;
pkt->pkt.secret_cert->skey[0] = elg_p;
pkt->pkt.secret_cert->skey[1] = elg_g;
pkt->pkt.secret_cert->skey[2] = elg_y;
cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
if( cert->protect.algo ) {
cert->is_protected = 1;
@ -1032,20 +1002,16 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
* If the user is so careless, not to protect his secret key,
* we can assume, that he operates an open system :=(.
* So we put the key into secure memory when we unprotect it. */
n = pktlen; cert->d.elg.x = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->skey[3] = mpi_read(inp, &n, 0 ); pktlen -=n;
cert->csum = read_16(inp); pktlen -= 2;
if( list_mode ) {
printf("\telg x: ");
mpi_print(stdout, cert->d.elg.x, mpi_print_mode );
mpi_print(stdout, cert->skey[3], mpi_print_mode );
putchar('\n');
printf("\t[secret value x is not shown]\n"
"\tchecksum: %04hx\n", cert->csum);
}
/*log_mpidump("elg p=", cert->d.elg.p );
log_mpidump("elg g=", cert->d.elg.g );
log_mpidump("elg y=", cert->d.elg.y );
log_mpidump("elg x=", cert->d.elg.x ); */
}
}
else if( algorithm == PUBKEY_ALGO_DSA ) {
@ -1066,19 +1032,19 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
putchar('\n');
}
if( pkttype == PKT_PUBLIC_CERT || pkttype == PKT_PUBKEY_SUBCERT ) {
pkt->pkt.public_cert->d.dsa.p = dsa_p;
pkt->pkt.public_cert->d.dsa.q = dsa_q;
pkt->pkt.public_cert->d.dsa.g = dsa_g;
pkt->pkt.public_cert->d.dsa.y = dsa_y;
pkt->pkt.public_cert->pkey[0] = dsa_p;
pkt->pkt.public_cert->pkey[1] = dsa_q;
pkt->pkt.public_cert->pkey[2] = dsa_g;
pkt->pkt.public_cert->pkey[3] = dsa_y;
}
else {
PKT_secret_cert *cert = pkt->pkt.secret_cert;
byte temp[8];
pkt->pkt.secret_cert->d.dsa.p = dsa_p;
pkt->pkt.secret_cert->d.dsa.q = dsa_q;
pkt->pkt.secret_cert->d.dsa.g = dsa_g;
pkt->pkt.secret_cert->d.dsa.y = dsa_y;
pkt->pkt.secret_cert->skey[0] = dsa_p;
pkt->pkt.secret_cert->skey[1] = dsa_q;
pkt->pkt.secret_cert->skey[2] = dsa_g;
pkt->pkt.secret_cert->skey[3] = dsa_y;
cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
if( cert->protect.algo ) {
cert->is_protected = 1;
@ -1164,18 +1130,13 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
* If the user is so careless, not to protect his secret key,
* we can assume, that he operates an open system :=(.
* So we put the key into secure memory when we unprotect it. */
n = pktlen; cert->d.dsa.x = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->skey[4] = mpi_read(inp, &n, 0 ); pktlen -=n;
cert->csum = read_16(inp); pktlen -= 2;
if( list_mode ) {
printf("\t[secret value x is not shown]\n"
"\tchecksum: %04hx\n", cert->csum);
}
/*log_mpidump("dsa p=", cert->d.dsa.p );
log_mpidump("dsa q=", cert->d.dsa.q );
log_mpidump("dsa g=", cert->d.dsa.g );
log_mpidump("dsa y=", cert->d.dsa.y );
log_mpidump("dsa x=", cert->d.dsa.x ); */
}
}
else if( is_RSA(algorithm) ) {
@ -1191,15 +1152,15 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
putchar('\n');
}
if( pkttype == PKT_PUBLIC_CERT || pkttype == PKT_PUBKEY_SUBCERT ) {
pkt->pkt.public_cert->d.rsa.n = rsa_pub_mod;
pkt->pkt.public_cert->d.rsa.e = rsa_pub_exp;
pkt->pkt.public_cert->pkey[0] = rsa_pub_mod;
pkt->pkt.public_cert->pkey[1] = rsa_pub_exp;
}
else {
PKT_secret_cert *cert = pkt->pkt.secret_cert;
byte temp[8];
pkt->pkt.secret_cert->d.rsa.n = rsa_pub_mod;
pkt->pkt.secret_cert->d.rsa.e = rsa_pub_exp;
pkt->pkt.secret_cert->skey[0] = rsa_pub_mod;
pkt->pkt.secret_cert->skey[1] = rsa_pub_exp;
cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
if( list_mode )
printf( "\tprotect algo: %d\n", cert->protect.algo);
@ -1219,22 +1180,16 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
else
cert->is_protected = 0;
/* (See comments at the code for elg keys) */
n = pktlen; cert->d.rsa.d = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->d.rsa.p = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->d.rsa.q = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->d.rsa.u = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->skey[2] = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->skey[3] = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->skey[4] = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; cert->skey[5] = mpi_read(inp, &n, 0 ); pktlen -=n;
cert->csum = read_16(inp); pktlen -= 2;
if( list_mode ) {
printf("\t[secret values d,p,q,u are not shown]\n"
"\tchecksum: %04hx\n", cert->csum);
}
/* log_mpidump("rsa n=", cert->d.rsa.n );
log_mpidump("rsa e=", cert->d.rsa.e );
log_mpidump("rsa d=", cert->d.rsa.d );
log_mpidump("rsa p=", cert->d.rsa.p );
log_mpidump("rsa q=", cert->d.rsa.q );
log_mpidump("rsa u=", cert->d.rsa.u ); */
}
}
else if( list_mode )

View File

@ -56,26 +56,9 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
if( (rc = get_seckey( skc, k->keyid )) )
goto leave;
if( is_ELGAMAL(k->pubkey_algo) ) {
if( DBG_CIPHER ) {
log_mpidump("Encr DEK a:", k->d.elg.a );
log_mpidump(" DEK b:", k->d.elg.b );
}
plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skc->d.elg.p) );
elg_decrypt( plain_dek, k->d.elg.a, k->d.elg.b, &skc->d.elg );
}
else if( is_RSA(k->pubkey_algo) ) {
if( DBG_CIPHER )
log_mpidump("Encr DEK frame:", k->d.rsa.rsa_integer );
plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skc->d.rsa.n) );
rsa_secret( plain_dek, k->d.rsa.rsa_integer, &skc->d.rsa );
}
else {
log_info("need some glue code for pubkey algo %d\n", k->pubkey_algo);
rc = G10ERR_PUBKEY_ALGO; /* unsupported algorithm */
rc = pubkey_decrypt(k->pubkey_algo, &plain_dek, k->data, skc->skey );
if( rc )
goto leave;
}
free_secret_cert( skc ); skc = NULL;
frame = mpi_get_buffer( plain_dek, &nframe, NULL );
mpi_free( plain_dek ); plain_dek = NULL;
@ -117,25 +100,18 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
dek->keylen = nframe - (n+1) - 2;
dek->algo = frame[n++];
switch( dek->algo ) {
case CIPHER_ALGO_IDEA:
if( dek->algo == CIPHER_ALGO_IDEA )
write_status(STATUS_RSA_OR_IDEA);
rc = G10ERR_NI_CIPHER;
goto leave;
case CIPHER_ALGO_BLOWFISH160:
if( dek->keylen != 20 )
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
break;
case CIPHER_ALGO_BLOWFISH:
case CIPHER_ALGO_CAST5:
if( dek->keylen != 16 )
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
break;
default:
rc = check_cipher_algo( dek->algo );
if( rc ) {
dek->algo = 0;
rc = G10ERR_CIPHER_ALGO;
goto leave;
}
if( (dek->keylen*8) != cipher_get_keylen( dek->algo ) ) {
rc = G10ERR_WRONG_SECKEY;
goto leave;
}
/* copy the key to DEK and compare the checksum */
csum = frame[nframe-2] << 8;
csum |= frame[nframe-1];

View File

@ -448,6 +448,35 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
********** Functions which operates on regular keyrings ********
****************************************************************/
static int
cmp_seckey( PKT_secret_cert *req_skc, PKT_secret_cert *skc )
{
int n,i;
assert( req_skc->pubkey_algo == skc->pubkey_algo );
n = pubkey_get_nskey( req_skc->pubkey_algo );
for(i=0; i < n; i++ ) {
if( mpi_cmp( req_skc->skey[i], skc->skey[i] ) )
return -1;
}
return 0;
}
static int
cmp_pubkey( PKT_public_cert *req_pkc, PKT_public_cert *pkc )
{
int n, i;
assert( req_pkc->pubkey_algo == pkc->pubkey_algo );
n = pubkey_get_npkey( req_pkc->pubkey_algo );
for(i=0; i < n; i++ ) {
if( mpi_cmp( req_pkc->pkey[i], pkc->pkey[i] ) )
return -1;
}
return 0;
}
/****************
* search one keyring, return 0 if found, -1 if not found or an errorcode.
@ -489,26 +518,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
if( req_skc->timestamp == skc->timestamp
&& req_skc->valid_days == skc->valid_days
&& req_skc->pubkey_algo == skc->pubkey_algo
&& ( ( is_ELGAMAL(skc->pubkey_algo)
&& !mpi_cmp( req_skc->d.elg.p, skc->d.elg.p )
&& !mpi_cmp( req_skc->d.elg.g, skc->d.elg.g )
&& !mpi_cmp( req_skc->d.elg.y, skc->d.elg.y )
&& !mpi_cmp( req_skc->d.elg.x, skc->d.elg.x )
)
|| ( skc->pubkey_algo == PUBKEY_ALGO_DSA
&& !mpi_cmp( req_skc->d.dsa.p, skc->d.dsa.p )
&& !mpi_cmp( req_skc->d.dsa.q, skc->d.dsa.q )
&& !mpi_cmp( req_skc->d.dsa.g, skc->d.dsa.g )
&& !mpi_cmp( req_skc->d.dsa.y, skc->d.dsa.y )
&& !mpi_cmp( req_skc->d.dsa.x, skc->d.dsa.x )
)
|| ( is_RSA(skc->pubkey_algo)
&& !mpi_cmp( req_skc->d.rsa.n, skc->d.rsa.n )
&& !mpi_cmp( req_skc->d.rsa.e, skc->d.rsa.e )
&& !mpi_cmp( req_skc->d.rsa.d, skc->d.rsa.d )
)
)
)
&& !cmp_seckey( req_skc, skc) )
break; /* found */
}
else if( pkt.pkttype == PKT_PUBLIC_CERT ) {
@ -517,23 +527,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
if( req_pkc->timestamp == pkc->timestamp
&& req_pkc->valid_days == pkc->valid_days
&& req_pkc->pubkey_algo == pkc->pubkey_algo
&& ( ( is_ELGAMAL(pkc->pubkey_algo)
&& !mpi_cmp( req_pkc->d.elg.p, pkc->d.elg.p )
&& !mpi_cmp( req_pkc->d.elg.g, pkc->d.elg.g )
&& !mpi_cmp( req_pkc->d.elg.y, pkc->d.elg.y )
)
|| ( pkc->pubkey_algo == PUBKEY_ALGO_DSA
&& !mpi_cmp( req_pkc->d.dsa.p, pkc->d.dsa.p )
&& !mpi_cmp( req_pkc->d.dsa.q, pkc->d.dsa.q )
&& !mpi_cmp( req_pkc->d.dsa.g, pkc->d.dsa.g )
&& !mpi_cmp( req_pkc->d.dsa.y, pkc->d.dsa.y )
)
|| ( is_RSA(pkc->pubkey_algo)
&& !mpi_cmp( req_pkc->d.rsa.n, pkc->d.rsa.n )
&& !mpi_cmp( req_pkc->d.rsa.e, pkc->d.rsa.e )
)
)
)
&& !cmp_pubkey( req_pkc, pkc ) )
break; /* found */
}
else

View File

@ -1,89 +0,0 @@
/* rsa.c - glue code for RSA cipher
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* This file is part of GNUPG.
*
* GNUPG 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.
*
* GNUPG 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 <errno.h>
#include <assert.h>
#include "options.h"
#include "packet.h"
#include "errors.h"
#include "iobuf.h"
#include "keydb.h"
#include "memory.h"
#include "util.h"
#include "main.h"
void
g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
{
#ifdef HAVE_RSA_CIPHER
assert( is_RSA(enc->pubkey_algo) );
keyid_from_pkc( pkc, enc->keyid );
enc->d.rsa.rsa_integer = encode_session_key( dek,
mpi_get_nbits(pkc->d.rsa.rsa_n) );
if( DBG_CIPHER )
log_mpidump("Plain DEK frame: ", enc->d.rsa.rsa_integer);
rsa_public( enc->d.rsa.rsa_integer, enc->d.rsa.rsa_integer, &pkc->d.rsa);
if( DBG_CIPHER )
log_mpidump("Encry DEK frame: ", enc->d.rsa.rsa_integer);
if( opt.verbose ) {
char *ustr = get_user_id_string( enc->keyid );
log_info("RSA encrypted for: %s\n", ustr );
m_free(ustr);
}
#else
BUG();
#endif/* ! HAVE_RSA_CIPHER*/
}
void
g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{
#ifdef HAVE_RSA_CIPHER
byte *dp;
assert( is_RSA(sig->pubkey_algo) );
if( !digest_algo )
digest_algo = md_get_algo(md);
dp = md_read( md, digest_algo );
sig->digest_algo = digest_algo;
sig->digest_start[0] = dp[0];
sig->digest_start[1] = dp[1];
sig->d.rsa.rsa_integer =
encode_md_value( md, digest_algo, mpi_get_nbits(skc->d.rsa.rsa_n));
rsa_secret( sig->d.rsa.rsa_integer, sig->d.rsa.rsa_integer, &skc->d.rsa );
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("RSA signature from: %s\n", ustr );
m_free(ustr);
}
#else
BUG();
#endif/* ! HAVE_RSA_CIPHER*/
}

View File

@ -67,17 +67,18 @@ do_check( PKT_secret_cert *cert )
switch( cert->pubkey_algo ) {
case PUBKEY_ALGO_ELGAMAL:
case PUBKEY_ALGO_ELGAMAL_E:
buffer = mpi_get_secure_buffer( cert->d.elg.x, &nbytes, NULL );
/* FIXME: removed ELG knowledge from this function */
buffer = mpi_get_secure_buffer( cert->skey[3], &nbytes, NULL );
cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.elg.x, buffer, nbytes, 0 );
csum = checksum_mpi( cert->d.elg.x );
mpi_set_buffer( cert->skey[3], buffer, nbytes, 0 );
csum = checksum_mpi( cert->skey[3] );
m_free( buffer );
break;
case PUBKEY_ALGO_DSA:
buffer = mpi_get_secure_buffer( cert->d.dsa.x, &nbytes, NULL );
buffer = mpi_get_secure_buffer( cert->skey[4], &nbytes, NULL );
cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 );
csum = checksum_mpi( cert->d.dsa.x );
mpi_set_buffer( cert->skey[4], buffer, nbytes, 0 );
csum = checksum_mpi( cert->skey[4] );
m_free( buffer );
break;
#ifdef HAVE_RSA_CIPHER
@ -107,15 +108,6 @@ do_check( PKT_secret_cert *cert )
cipher_close( cipher_hd );
/* now let's see whether we have used the right passphrase */
if( csum != cert->csum ) {
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
/* very bad kludge to work around an early bug */
csum -= checksum_u16( mpi_get_nbits(cert->d.elg.x) );
nbytes = mpi_get_nlimbs(cert->d.elg.x) * 4;
csum += checksum_u16( nbytes*8 );
if( !opt.batch && csum == cert->csum )
log_info("Probably you have an old key - use "
"\"--change-passphrase\" to convert.\n");
}
if( csum != cert->csum ) {
copy_secret_cert( cert, save_cert );
free_secret_cert( save_cert );
@ -124,24 +116,8 @@ do_check( PKT_secret_cert *cert )
}
}
switch( cert->pubkey_algo ) {
case PUBKEY_ALGO_ELGAMAL_E:
case PUBKEY_ALGO_ELGAMAL:
res = elg_check_secret_key( &cert->d.elg );
break;
case PUBKEY_ALGO_DSA:
res = dsa_check_secret_key( &cert->d.dsa );
break;
#ifdef HAVE_RSA_CIPHER
case PUBKEY_ALGO_RSA:
case PUBKEY_ALGO_RSA_E:
case PUBKEY_ALGO_RSA_S:
res = rsa_check_secret_key( &cert->d.rsa );
break;
#endif
default: BUG();
}
if( !res ) {
res = pubkey_check_secret_key( cert->pubkey_algo, cert->skey );
if( res ) {
copy_secret_cert( cert, save_cert );
free_secret_cert( save_cert );
memcpy( cert->protect.iv, save_iv, 8 );
@ -154,10 +130,10 @@ do_check( PKT_secret_cert *cert )
switch( cert->pubkey_algo ) {
case PUBKEY_ALGO_ELGAMAL_E:
case PUBKEY_ALGO_ELGAMAL:
csum = checksum_mpi( cert->d.elg.x );
csum = checksum_mpi( cert->skey[3] );
break;
case PUBKEY_ALGO_DSA:
csum = checksum_mpi( cert->d.dsa.x );
csum = checksum_mpi( cert->skey[4] );
break;
#ifdef HAVE_RSA_CIPHER
case PUBKEY_ALGO_RSA_E:
@ -184,19 +160,8 @@ do_check( PKT_secret_cert *cert )
#endif
default: BUG();
}
if( csum != cert->csum ) {
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
/* very bad kludge to work around an early bug */
csum -= checksum_u16( mpi_get_nbits(cert->d.elg.x) );
nbytes = mpi_get_nlimbs(cert->d.elg.x) * 4;
csum += checksum_u16( nbytes*8 );
if( !opt.batch && csum == cert->csum )
log_info("Probably you have an old key - use "
"\"--change-passphrase\" to convert.\n");
}
if( csum != cert->csum )
return G10ERR_CHECKSUM;
}
if( csum != cert->csum )
return G10ERR_CHECKSUM;
}
return 0;
@ -274,23 +239,17 @@ do_protect( void (*fnc)(CIPHER_HANDLE, byte *, byte *, unsigned),
switch( cert->pubkey_algo ) {
case PUBKEY_ALGO_ELGAMAL_E:
/* recalculate the checksum, so that --change-passphrase
* can be used to convert from the faulty to the correct one
* wk 06.04.98:
* fixme: remove this some time in the future.
*/
cert->csum = checksum_mpi( cert->d.elg.x );
case PUBKEY_ALGO_ELGAMAL:
buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL );
buffer = mpi_get_buffer( cert->skey[3], &nbytes, NULL );
(*fnc)( fnc_hd, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.elg.x, buffer, nbytes, 0 );
mpi_set_buffer( cert->skey[3], buffer, nbytes, 0 );
m_free( buffer );
break;
case PUBKEY_ALGO_DSA:
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
buffer = mpi_get_buffer( cert->skey[4], &nbytes, NULL );
(*fnc)( fnc_hd, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 );
mpi_set_buffer( cert->skey[4], buffer, nbytes, 0 );
m_free( buffer );
break;

View File

@ -95,11 +95,10 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
}
md_final( digest );
result = encode_md_value( digest, sig->digest_algo,
mpi_get_nbits(pkc->d.elg.p));
mpi_get_nbits(pkc->pkey[0]));
if( DBG_CIPHER )
log_mpidump("calc sig frame (elg): ", result);
if( !elg_verify( sig->d.elg.a, sig->d.elg.b, result, &pkc->d.elg ) )
rc = G10ERR_BAD_SIGN;
rc = pubkey_verify( pkc->pubkey_algo, result, sig->data, pkc->pkey );
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
if( (rc=check_digest_algo(sig->digest_algo)) )
@ -148,8 +147,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
md_digest_length(sig->digest_algo), 0 );
if( DBG_CIPHER )
log_mpidump("calc sig frame: ", result);
if( !dsa_verify( sig->d.dsa.r, sig->d.dsa.s, result, &pkc->d.dsa ) )
rc = G10ERR_BAD_SIGN;
rc = pubkey_verify( pkc->pubkey_algo, result, sig->data, pkc->pkey );
}
#ifdef HAVE_RSA_CIPHER
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA

View File

@ -38,22 +38,53 @@
#include "i18n.h"
static int
do_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{
MPI frame;
byte *dp;
int rc;
if( !digest_algo )
digest_algo = md_get_algo(md);
dp = md_read( md, digest_algo );
sig->digest_algo = digest_algo;
sig->digest_start[0] = dp[0];
sig->digest_start[1] = dp[1];
if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
frame = mpi_alloc( (md_digest_length(digest_algo)+BYTES_PER_MPI_LIMB-1)
/ BYTES_PER_MPI_LIMB );
mpi_set_buffer( frame, md_read(md, digest_algo),
md_digest_length(digest_algo), 0 );
}
else
frame = encode_md_value( md, digest_algo, mpi_get_nbits(skc->skey[0]));
rc = pubkey_sign( skc->pubkey_algo, sig->data, frame, skc->skey );
mpi_free(frame);
if( rc )
log_error("pubkey_sign failed: %s\n", g10_errstr(rc) );
else {
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("%s signature from: %s\n",
pubkey_algo_to_string(skc->pubkey_algo), ustr );
m_free(ustr);
}
}
return rc;
}
int
complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md )
{
int rc=0;
if( (rc=check_secret_key( skc )) )
;
else if( is_ELGAMAL(sig->pubkey_algo) )
g10_elg_sign( skc, sig, md, 0 );
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA )
g10_dsa_sign( skc, sig, md, 0 );
else if( is_RSA(sig->pubkey_algo) )
g10_rsa_sign( skc, sig, md, 0 );
else
BUG();
if( !(rc=check_secret_key( skc )) )
rc = do_sign( skc, sig, md, 0 );
/* fixme: should we check whether the signature is okay?
* maybe by using an option */
@ -334,27 +365,20 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
md_final( md );
if( is_ELGAMAL(sig->pubkey_algo) )
g10_elg_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA )
g10_dsa_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
else if( is_RSA(sig->pubkey_algo) )
g10_rsa_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
else
BUG();
rc = do_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
md_close( md );
/* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
free_packet( &pkt );
if( rc ) {
log_error("build signature packet failed: %s\n", g10_errstr(rc) );
goto leave;
if( !rc ) { /* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
free_packet( &pkt );
if( rc )
log_error("build signature packet failed: %s\n", g10_errstr(rc) );
}
if( rc )
goto leave;
}
@ -538,27 +562,20 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
}
md_final( md );
if( is_ELGAMAL(sig->pubkey_algo) )
g10_elg_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA )
g10_dsa_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
else if( is_RSA(sig->pubkey_algo) )
g10_rsa_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
else
BUG();
rc = do_sign( skc, sig, md, hash_for(sig->pubkey_algo) );
md_close( md );
/* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
free_packet( &pkt );
if( rc ) {
log_error("build signature packet failed: %s\n", g10_errstr(rc) );
goto leave;
if( !rc ) { /* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
free_packet( &pkt );
if( rc )
log_error("build signature packet failed: %s\n", g10_errstr(rc) );
}
if( rc )
goto leave;
}

View File

@ -84,6 +84,8 @@ struct cipher_handle_s { char does_not_matter[1]; };
#define CIPHER_MODE_DUMMY 5 /* used with algo DUMMY for no encryption */
int cipher_debug_mode;
/*-- dynload.c --*/
@ -102,6 +104,23 @@ void cipher_encrypt( CIPHER_HANDLE c, byte *out, byte *in, unsigned nbytes );
void cipher_decrypt( CIPHER_HANDLE c, byte *out, byte *in, unsigned nbytes );
void cipher_sync( CIPHER_HANDLE c );
/*-- pubkey.c --*/
#define PUBKEY_MAX_NPKEY 4
#define PUBKEY_MAX_NSKEY 6
#define PUBKEY_MAX_NSIG 2
#define PUBKEY_MAX_NENC 2
int pubkey_get_npkey( int algo );
int pubkey_get_nskey( int algo );
int pubkey_get_nsig( int algo );
int pubkey_get_nenc( int algo );
unsigned pubkey_nbits( int algo, MPI *pkey );
int pubkey_check_secret_key( int algo, MPI *skey );
int pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey );
/*-- misc.c --*/
int string_to_pubkey_algo( const char *string );

Binary file not shown.