aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xchecks/conventional.test2
-rwxr-xr-xchecks/defs.inc6
-rwxr-xr-xchecks/encrypt-dsa.test2
-rwxr-xr-xchecks/encrypt.test2
-rwxr-xr-xchecks/run-gpg3
-rw-r--r--cipher/Makefile.am5
-rw-r--r--cipher/cast5.c12
-rw-r--r--cipher/pubkey.c377
-rw-r--r--g10/ChangeLog10
-rw-r--r--g10/Makefile.am3
-rw-r--r--g10/build-packet.c131
-rw-r--r--g10/dsa.c69
-rw-r--r--g10/elg.c92
-rw-r--r--g10/encode.c38
-rw-r--r--g10/free-packet.c171
-rw-r--r--g10/keygen.c36
-rw-r--r--g10/keyid.c355
-rw-r--r--g10/main.h14
-rw-r--r--g10/packet.h33
-rw-r--r--g10/parse-packet.c139
-rw-r--r--g10/pubkey-enc.c44
-rw-r--r--g10/ringedit.c68
-rw-r--r--g10/rsa.c89
-rw-r--r--g10/seckey-cert.c75
-rw-r--r--g10/sig-check.c8
-rw-r--r--g10/sign.c109
-rw-r--r--include/cipher.h19
-rwxr-xr-xtools/mk-tdatabin11769 -> 35331 bytes
28 files changed, 792 insertions, 1120 deletions
diff --git a/checks/conventional.test b/checks/conventional.test
index 295db822b..0a2aabe57 100755
--- a/checks/conventional.test
+++ b/checks/conventional.test
@@ -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
diff --git a/checks/defs.inc b/checks/defs.inc
index 32711c916..14c657543 100755
--- a/checks/defs.inc
+++ b/checks/defs.inc
@@ -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=""
diff --git a/checks/encrypt-dsa.test b/checks/encrypt-dsa.test
index d506e8890..d83cdd968 100755
--- a/checks/encrypt-dsa.test
+++ b/checks/encrypt-dsa.test
@@ -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"
diff --git a/checks/encrypt.test b/checks/encrypt.test
index daf3be6ee..85a67eb37 100755
--- a/checks/encrypt.test
+++ b/checks/encrypt.test
@@ -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
diff --git a/checks/run-gpg b/checks/run-gpg
index 3420bf98e..9a3ffee8f 100755
--- a/checks/run-gpg
+++ b/checks/run-gpg
@@ -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.$$
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 10d1c8091..53ba749a8 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -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
diff --git a/cipher/cast5.c b/cipher/cast5.c
index 5e29debe6..0bd90f9df 100644
--- a/cipher/cast5.c
+++ b/cipher/cast5.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";
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 3ffc1ca33..0a4b3430d 100644
--- a/cipher/pubkey.c
+++ b/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;
+}
+
+/****************
+ * 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;
+}
/****************
- * This is the interface for the public key decryption.
+ * 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;
+}
+
diff --git a/g10/ChangeLog b/g10/ChangeLog
index a10527cf1..d6ed0cc6d 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,13 @@
+Thu Jun 11 13:26:44 1998 Werner Koch ([email protected])
+
+ * 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.
diff --git a/g10/Makefile.am b/g10/Makefile.am
index 3e20a48c2..520a945a8 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -26,9 +26,6 @@ common_source = \
mdfilter.c \
textfilter.c \
cipher.c \
- elg.c \
- dsa.c \
- rsa.c \
misc.c \
options.h \
openfile.c \
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 33709e7da..7048ad9a8 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.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,34 +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 ) {
- iobuf_put(a, 0xff );
+ 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_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.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 ) {
+ else {
iobuf_put(a, 0xff );
iobuf_put(a, skc->protect.algo );
iobuf_put(a, skc->protect.s2k.mode );
@@ -311,37 +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.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;
}
diff --git a/g10/dsa.c b/g10/dsa.c
deleted file mode 100644
index 9bcb013a5..000000000
--- a/g10/dsa.c
+++ /dev/null
@@ -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);
- }
-}
-
diff --git a/g10/elg.c b/g10/elg.c
deleted file mode 100644
index cca66d565..000000000
--- a/g10/elg.c
+++ /dev/null
@@ -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);
- }
-}
-
diff --git a/g10/encode.c b/g10/encode.c
index d3d88ca7b..3d4ad9917 100644
--- a/g10/encode.c
+++ b/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 );
+ 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 ) {
- log_error("build pubkey_enc packet failed: %s\n", g10_errstr(rc) );
+ if( rc )
return rc;
- }
}
return 0;
}
diff --git a/g10/free-packet.c b/g10/free-packet.c
index 3cf82c8ac..12382b4db 100644
--- a/g10/free-packet.c
+++ b/g10/free-packet.c
@@ -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 ) )
- 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 ) )
+ 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( 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;
}
diff --git a/g10/keygen.c b/g10/keygen.c
index 367c22de5..63c162fb2 100644
--- a/g10/keygen.c
+++ b/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 );
diff --git a/g10/keyid.c b/g10/keyid.c
index 55c0c49ae..dc24904c7 100644
--- a/g10/keyid.c
+++ b/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;
-
- 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);
+ 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 );
+
+ 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 );
- }
- 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 );
+ 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, 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);
+ if( skc->version < 4 && is_RSA(skc->pubkey_algo) ) {
+ lowbits = mpi_get_keyid( skc->skey[0], keyid ); /* take n */
}
- else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
+ else {
const byte *dp;
MD_HANDLE md;
- md = dsa_fingerprint_md_skc(skc);
- dp = md_read( md, DIGEST_ALGO_SHA1 );
+ 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);
}
- else if( is_RSA(skc->pubkey_algo) ) {
- lowbits = mpi_get_keyid( skc->d.rsa.n, keyid );
- }
- else {
- keyid[0] = keyid[1] = lowbits = 0;
- }
+
return lowbits;
}
@@ -285,38 +160,19 @@ 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);
+ if( pkc->version < 4 && is_RSA(pkc->pubkey_algo) ) {
+ lowbits = mpi_get_keyid( pkc->pkey[0], keyid ); /* from n */
}
- else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
+ else {
const byte *dp;
MD_HANDLE md;
- md = dsa_fingerprint_md(pkc);
- dp = md_read( md, DIGEST_ALGO_SHA1 );
+ 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);
}
- else if( is_RSA(pkc->pubkey_algo) ) {
- lowbits = mpi_get_keyid( pkc->d.rsa.n, keyid );
- }
- else {
- keyid[0] = keyid[1] = lowbits = 0;
- }
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,54 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
size_t len;
unsigned n;
- if( is_ELGAMAL(pkc->pubkey_algo) ) {
+ if( pkc->version < 4 && is_RSA(pkc->pubkey_algo) ) {
+ /* RSA in version 3 packets is special */
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 = md_open( DIGEST_ALGO_MD5, 0);
+ p = buf = mpi_get_buffer( pkc->pkey[0], &n, NULL );
+ md_write( md, p, n );
+ m_free(buf);
+ p = buf = mpi_get_buffer( pkc->pkey[1], &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 if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
+ else {
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 = 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);
}
- else if( is_RSA(pkc->pubkey_algo) ) {
+
+ *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( pkc->d.rsa.n, &n, NULL );
+ p = buf = mpi_get_buffer( skc->skey[1], &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( skc->skey[0], &n, NULL );
md_write( md, p, n );
m_free(buf);
md_final(md);
@@ -503,8 +321,13 @@ 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_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;
diff --git a/g10/main.h b/g10/main.h
index 017bb781b..56fd3c9d5 100644
--- a/g10/main.h
+++ b/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 --*/
diff --git a/g10/packet.h b/g10/packet.h
index cb9740cc6..4f04e1ae4 100644
--- a/g10/packet.h
+++ b/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;
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index e1f023261..0ee6e7d37 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -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) ) {
+
+ 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->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
+ k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
if( list_mode ) {
- printf("\trsa integer: ");
- mpi_print(stdout, k->d.rsa.rsa_integer, mpi_print_mode );
+ printf("\tdata: ");
+ mpi_print(stdout, k->data[i], mpi_print_mode );
putchar('\n');
}
}
- else if( list_mode )
- printf("\tunknown algorithm %d\n", k->pubkey_algo );
-
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,43 +755,21 @@ 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) ) {
+
+ 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->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
+ sig->data[i] = mpi_read(inp, &n, 0 );
+ pktlen -=n;
if( list_mode ) {
- printf("\trsa integer: ");
- mpi_print(stdout, sig->d.rsa.rsa_integer, mpi_print_mode );
+ printf("\tdata: ");
+ mpi_print(stdout, sig->data[i], mpi_print_mode );
putchar('\n');
}
}
- else if( list_mode )
- printf("\tunknown algorithm %d\n", sig->pubkey_algo );
leave:
@@ -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 )
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index 8b48255dc..ade155545 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -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];
diff --git a/g10/ringedit.c b/g10/ringedit.c
index 28faeddc1..a281d8bab 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -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
diff --git a/g10/rsa.c b/g10/rsa.c
deleted file mode 100644
index 36e0ef246..000000000
--- a/g10/rsa.c
+++ /dev/null
@@ -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*/
-}
-
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 3373bd35e..41a09b281 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -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;
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 6dc660916..a4c802c67 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -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
diff --git a/g10/sign.c b/g10/sign.c
index bd435a7c9..a85f1f952 100644
--- a/g10/sign.c
+++ b/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;
}
diff --git a/include/cipher.h b/include/cipher.h
index 186851a33..3fe56c2e3 100644
--- a/include/cipher.h
+++ b/include/cipher.h
@@ -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 );
diff --git a/tools/mk-tdata b/tools/mk-tdata
index 7fcfb389f..85e567d45 100755
--- a/tools/mk-tdata
+++ b/tools/mk-tdata
Binary files differ