mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-30 16:17:02 +01:00
a whole bunch of internal cleanups
This commit is contained in:
parent
d42ad47688
commit
37d2adfe61
@ -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
|
||||
|
@ -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=""
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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.$$
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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";
|
||||
|
377
cipher/pubkey.c
377
cipher/pubkey.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -26,9 +26,6 @@ common_source = \
|
||||
mdfilter.c \
|
||||
textfilter.c \
|
||||
cipher.c \
|
||||
elg.c \
|
||||
dsa.c \
|
||||
rsa.c \
|
||||
misc.c \
|
||||
options.h \
|
||||
openfile.c \
|
||||
|
@ -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;
|
||||
}
|
||||
|
69
g10/dsa.c
69
g10/dsa.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
92
g10/elg.c
92
g10/elg.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
40
g10/encode.c
40
g10/encode.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
36
g10/keygen.c
36
g10/keygen.c
@ -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 );
|
||||
|
||||
|
385
g10/keyid.c
385
g10/keyid.c
@ -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;
|
||||
|
14
g10/main.h
14
g10/main.h
@ -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 --*/
|
||||
|
33
g10/packet.h
33
g10/packet.h
@ -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;
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
89
g10/rsa.c
89
g10/rsa.c
@ -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*/
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
109
g10/sign.c
109
g10/sign.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
|
BIN
tools/mk-tdata
BIN
tools/mk-tdata
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user