a whole bunch of internal cleanups
authorWerner Koch <wk@gnupg.org>
Sat, 13 Jun 1998 06:59:14 +0000 (06:59 +0000)
committerWerner Koch <wk@gnupg.org>
Sat, 13 Jun 1998 06:59:14 +0000 (06:59 +0000)
28 files changed:
checks/conventional.test
checks/defs.inc
checks/encrypt-dsa.test
checks/encrypt.test
checks/run-gpg
cipher/Makefile.am
cipher/cast5.c
cipher/pubkey.c
g10/ChangeLog
g10/Makefile.am
g10/build-packet.c
g10/dsa.c [deleted file]
g10/elg.c [deleted file]
g10/encode.c
g10/free-packet.c
g10/keygen.c
g10/keyid.c
g10/main.h
g10/packet.h
g10/parse-packet.c
g10/pubkey-enc.c
g10/ringedit.c
g10/rsa.c [deleted file]
g10/seckey-cert.c
g10/sig-check.c
g10/sign.c
include/cipher.h
tools/mk-tdata

index 295db82..0a2aabe 100755 (executable)
@@ -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
index 32711c9..14c6575 100755 (executable)
@@ -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=""
 
 
index d506e88..d83cdd9 100755 (executable)
@@ -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"
index daf3be6..85a67eb 100755 (executable)
@@ -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
index 3420bf9..9a3ffee 100755 (executable)
@@ -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.$$
 
index 10d1c80..53ba749 100644 (file)
@@ -6,6 +6,9 @@ noinst_LIBRARIES = libcipher.a
 
 
 libcipher_a_SOURCES = cipher.c \
+                pubkey.c       \
+                md.c           \
+                md.h           \
                 dynload.c      \
                 dynload.h      \
                 blowfish.c     \
@@ -32,8 +35,6 @@ libcipher_a_SOURCES = cipher.c        \
                 sha1.c         \
                 dsa.h          \
                 dsa.c          \
-                md.c           \
-                md.h           \
                 misc.c         \
                 smallprime.c
 
index 5e29deb..0bd90f9 100644 (file)
@@ -594,17 +594,17 @@ setkey( CAST5_context *c, byte *key, unsigned keylen )
 const char *
 cast5_get_info( int algo, size_t *keylen,
                   size_t *blocksize, size_t *contextsize,
-                  void (**setkey)( void *c, byte *key, unsigned keylen ),
-                  void (**encrypt)( void *c, byte *outbuf, byte *inbuf ),
-                  void (**decrypt)( void *c, byte *outbuf, byte *inbuf )
+                  void (**r_setkey)( void *c, byte *key, unsigned keylen ),
+                  void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
+                  void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
                 )
 {
     *keylen = 128;
     *blocksize = CAST5_BLOCKSIZE;
     *contextsize = sizeof(CAST5_context);
-    *setkey = FNCCAST_SETKEY(setkey);
-    *encrypt= FNCCAST_CRYPT(encrypt_block);
-    *decrypt= FNCCAST_CRYPT(decrypt_block);
+    *r_setkey = FNCCAST_SETKEY(setkey);
+    *r_encrypt= FNCCAST_CRYPT(encrypt_block);
+    *r_decrypt= FNCCAST_CRYPT(decrypt_block);
 
     if( algo == CIPHER_ALGO_CAST5 )
        return "CAST5";
index 3ffc1ca..0a4b343 100644 (file)
 #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;
+}
+
index a10527c..d6ed0cc 100644 (file)
@@ -1,3 +1,13 @@
+Thu Jun 11 13:26:44 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * packet.h: Mjor chnages to the structure of public key material
+       which is now stored in an array and not anaymore in a union of
+       algorithm specific structures.  These is needed to make the system
+       more extendable and makes a lot of stuff much simpler. Changed
+       all over the system.
+
+       * dsa.c, rsa.c, elg.c: Removed.
+
 Wed Jun 10 07:22:02 1998  Werner Koch,mobil,,, (wk@tobold)
 
        * g10.c ("load-extension"): New option.
index 3e20a48..520a945 100644 (file)
@@ -26,9 +26,6 @@ common_source =  \
              mdfilter.c        \
              textfilter.c      \
              cipher.c          \
-             elg.c             \
-             dsa.c             \
-             rsa.c             \
              misc.c            \
              options.h         \
              openfile.c        \
index 33709e7..7048ad9 100644 (file)
@@ -177,6 +177,7 @@ static int
 do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
 {
     int rc = 0;
+    int n, i;
     IOBUF a = iobuf_temp();
 
     if( !pkc->version )
@@ -187,31 +188,14 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
     if( pkc->version < 4 )
        write_16(a, pkc->valid_days );
     iobuf_put(a, pkc->pubkey_algo );
-    if( is_ELGAMAL(pkc->pubkey_algo) ) {
-       mpi_write(a, pkc->d.elg.p );
-       mpi_write(a, pkc->d.elg.g );
-       mpi_write(a, pkc->d.elg.y );
-    }
-    else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       mpi_write(a, pkc->d.dsa.p );
-       mpi_write(a, pkc->d.dsa.q );
-       mpi_write(a, pkc->d.dsa.g );
-       mpi_write(a, pkc->d.dsa.y );
-    }
-    else if( is_RSA(pkc->pubkey_algo) ) {
-       mpi_write(a, pkc->d.rsa.n );
-       mpi_write(a, pkc->d.rsa.e );
-    }
-    else {
-       rc = G10ERR_PUBKEY_ALGO;
-       goto leave;
-    }
+    n = pubkey_get_npkey( pkc->pubkey_algo );
+    for(i=0; i < n; i++ )
+       mpi_write(a, pkc->pkey[i] );
 
     write_header2(out, ctb, iobuf_get_temp_length(a), pkc->hdrbytes, 1 );
     if( iobuf_write_temp( out, a ) )
        rc = G10ERR_WRITE_FILE;
 
-  leave:
     iobuf_close(a);
     return rc;
 }
@@ -227,7 +211,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
     int rc = 0;
     int c;
     IOBUF a = iobuf_temp();
-  #if 1
+  #if 0
     FILE *fp = fopen("dump.pkc", "a");
     int i=0;
 
@@ -241,7 +225,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
     if( (rc = build_packet( a, &pkt )) )
        log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc));
     while( (c=iobuf_get(a)) != -1 ) {
-      #if 1
+      #if 0
        fprintf( fp," %02x", c );
        if( (++i == 24) ) {
            putc('\n', fp);
@@ -250,7 +234,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
       #endif
        md_putc( md, c );
     }
-  #if 1
+  #if 0
     putc('\n', fp);
     fclose(fp);
   #endif
@@ -262,6 +246,7 @@ static int
 do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
 {
     int rc = 0;
+    int i, nskey, npkey;
     IOBUF a = iobuf_temp();
 
     if( !skc->version )
@@ -272,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 (file)
index 9bcb013..0000000
--- 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 (file)
index cca66d5..0000000
--- 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);
-    }
-}
-
index d3d88ca..3d4ad99 100644 (file)
@@ -329,26 +329,36 @@ write_pubkey_enc_from_list( PKC_LIST pkc_list, DEK *dek, IOBUF out )
     int rc;
 
     for( ; pkc_list; pkc_list = pkc_list->next ) {
+       MPI frame;
 
        pkc = pkc_list->pkc;
        enc = m_alloc_clear( sizeof *enc );
        enc->pubkey_algo = pkc->pubkey_algo;
-       if( is_ELGAMAL(enc->pubkey_algo) )
-           g10_elg_encrypt( pkc, enc, dek );
-       else if( is_RSA(enc->pubkey_algo) )
-           g10_rsa_encrypt( pkc, enc, dek );
-       else
-           BUG();
-       /* and write it */
-       init_packet(&pkt);
-       pkt.pkttype = PKT_PUBKEY_ENC;
-       pkt.pkt.pubkey_enc = enc;
-       rc = build_packet( out, &pkt );
+       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;
 }
index 3cf82c8..12382b4 100644 (file)
@@ -40,28 +40,20 @@ free_symkey_enc( PKT_symkey_enc *enc )
 void
 free_pubkey_enc( PKT_pubkey_enc *enc )
 {
-    if( is_ELGAMAL(enc->pubkey_algo) ) {
-       mpi_free( enc->d.elg.a );
-       mpi_free( enc->d.elg.b );
-    }
-    else if( is_RSA(enc->pubkey_algo) )
-       mpi_free( enc->d.rsa.rsa_integer );
+    int n, i;
+    n = pubkey_get_nenc( enc->pubkey_algo );
+    for(i=0; i < n; i++ )
+       mpi_free( enc->data[i] );
     m_free(enc);
 }
 
 void
 free_seckey_enc( PKT_signature *sig )
 {
-    if( is_ELGAMAL(sig->pubkey_algo) ) {
-       mpi_free( sig->d.elg.a );
-       mpi_free( sig->d.elg.b );
-    }
-    else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       mpi_free( sig->d.dsa.r );
-       mpi_free( sig->d.dsa.s );
-    }
-    else if( is_RSA(sig->pubkey_algo) )
-       mpi_free( sig->d.rsa.rsa_integer );
+    int n, i;
+    n = pubkey_get_nenc( sig->pubkey_algo );
+    for(i=0; i < n; i++ )
+       mpi_free( sig->data[i] );
     m_free(sig->hashed_data);
     m_free(sig->unhashed_data);
     m_free(sig);
@@ -72,23 +64,15 @@ free_seckey_enc( PKT_signature *sig )
 void
 release_public_cert_parts( PKT_public_cert *cert )
 {
-    if( is_ELGAMAL(cert->pubkey_algo) ) {
-       mpi_free( cert->d.elg.p ); cert->d.elg.p = NULL;
-       mpi_free( cert->d.elg.g ); cert->d.elg.g = NULL;
-       mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
-    }
-    else if( cert->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       mpi_free( cert->d.dsa.p ); cert->d.dsa.p = NULL;
-       mpi_free( cert->d.dsa.q ); cert->d.dsa.q = NULL;
-       mpi_free( cert->d.dsa.g ); cert->d.dsa.g = NULL;
-       mpi_free( cert->d.dsa.y ); cert->d.dsa.y = NULL;
-    }
-    else if( is_RSA(cert->pubkey_algo) ) {
-       mpi_free( cert->d.rsa.n ); cert->d.rsa.n = NULL;
-       mpi_free( cert->d.rsa.e ); cert->d.rsa.e = NULL;
+    int n, i;
+    n = pubkey_get_npkey( cert->pubkey_algo );
+    for(i=0; i < n; i++ ) {
+       mpi_free( cert->pkey[i] );
+       cert->pkey[i] = NULL;
     }
 }
 
+
 void
 free_public_cert( PKT_public_cert *cert )
 {
@@ -99,50 +83,26 @@ free_public_cert( PKT_public_cert *cert )
 PKT_public_cert *
 copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
 {
+    int n, i;
+
     if( !d )
        d = m_alloc(sizeof *d);
     memcpy( d, s, sizeof *d );
-    if( is_ELGAMAL(s->pubkey_algo) ) {
-       d->d.elg.p = mpi_copy( s->d.elg.p );
-       d->d.elg.g = mpi_copy( s->d.elg.g );
-       d->d.elg.y = mpi_copy( s->d.elg.y );
-    }
-    else if( s->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       d->d.dsa.p = mpi_copy( s->d.dsa.p );
-       d->d.dsa.q = mpi_copy( s->d.dsa.q );
-       d->d.dsa.g = mpi_copy( s->d.dsa.g );
-       d->d.dsa.y = mpi_copy( s->d.dsa.y );
-    }
-    else if( is_RSA(s->pubkey_algo) ) {
-       d->d.rsa.n = mpi_copy( s->d.rsa.n );
-       d->d.rsa.e = mpi_copy( s->d.rsa.e );
-    }
+    n = pubkey_get_npkey( s->pubkey_algo );
+    for(i=0; i < n; i++ )
+       d->pkey[i] = mpi_copy( s->pkey[i] );
     return d;
 }
 
 void
 release_secret_cert_parts( PKT_secret_cert *cert )
 {
-    if( is_ELGAMAL(cert->pubkey_algo) ) {
-       mpi_free( cert->d.elg.p ); cert->d.elg.p = NULL;
-       mpi_free( cert->d.elg.g ); cert->d.elg.g = NULL;
-       mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
-       mpi_free( cert->d.elg.x ); cert->d.elg.x = NULL;
-    }
-    else if( cert->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       mpi_free( cert->d.dsa.p ); cert->d.dsa.p = NULL;
-       mpi_free( cert->d.dsa.q ); cert->d.dsa.q = NULL;
-       mpi_free( cert->d.dsa.g ); cert->d.dsa.g = NULL;
-       mpi_free( cert->d.dsa.y ); cert->d.dsa.y = NULL;
-       mpi_free( cert->d.dsa.x ); cert->d.dsa.x = NULL;
-    }
-    else if( is_RSA(cert->pubkey_algo) ) {
-       mpi_free( cert->d.rsa.n ); cert->d.rsa.n = NULL;
-       mpi_free( cert->d.rsa.e ); cert->d.rsa.e = NULL;
-       mpi_free( cert->d.rsa.d ); cert->d.rsa.d = NULL;
-       mpi_free( cert->d.rsa.p ); cert->d.rsa.p = NULL;
-       mpi_free( cert->d.rsa.q ); cert->d.rsa.q = NULL;
-       mpi_free( cert->d.rsa.u ); cert->d.rsa.u = NULL;
+    int n, i;
+
+    n = pubkey_get_nskey( cert->pubkey_algo );
+    for(i=0; i < n; i++ ) {
+       mpi_free( cert->skey[i] );
+       cert->skey[i] = NULL;
     }
 }
 
@@ -156,30 +116,14 @@ free_secret_cert( PKT_secret_cert *cert )
 PKT_secret_cert *
 copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s )
 {
+    int n, i;
+
     if( !d )
        d = m_alloc(sizeof *d);
     memcpy( d, s, sizeof *d );
-    if( is_ELGAMAL(s->pubkey_algo) ) {
-       d->d.elg.p = mpi_copy( s->d.elg.p );
-       d->d.elg.g = mpi_copy( s->d.elg.g );
-       d->d.elg.y = mpi_copy( s->d.elg.y );
-       d->d.elg.x = mpi_copy( s->d.elg.x );
-    }
-    else if( s->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       d->d.dsa.p = mpi_copy( s->d.dsa.p );
-       d->d.dsa.q = mpi_copy( s->d.dsa.q );
-       d->d.dsa.g = mpi_copy( s->d.dsa.g );
-       d->d.dsa.y = mpi_copy( s->d.dsa.y );
-       d->d.dsa.x = mpi_copy( s->d.dsa.x );
-    }
-    else if( is_RSA(s->pubkey_algo) ) {
-       d->d.rsa.n = mpi_copy( s->d.rsa.n );
-       d->d.rsa.e = mpi_copy( s->d.rsa.e );
-       d->d.rsa.d = mpi_copy( s->d.rsa.d );
-       d->d.rsa.p = mpi_copy( s->d.rsa.p );
-       d->d.rsa.q = mpi_copy( s->d.rsa.q );
-       d->d.rsa.u = mpi_copy( s->d.rsa.u );
-    }
+    n = pubkey_get_nskey( s->pubkey_algo );
+    for(i=0; i < n; i++ )
+       d->skey[i] = mpi_copy( s->skey[i] );
     return d;
 }
 
@@ -298,6 +242,8 @@ free_packet( PACKET *pkt )
 int
 cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b )
 {
+    int n, i;
+
     if( a->timestamp != b->timestamp )
        return -1;
     if( a->valid_days != b->valid_days )
@@ -305,28 +251,9 @@ cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b )
     if( a->pubkey_algo != b->pubkey_algo )
        return -1;
 
-    if( is_ELGAMAL(a->pubkey_algo) ) {
-       if( mpi_cmp( a->d.elg.p , b->d.elg.p ) )
-           return -1;
-       if( mpi_cmp( a->d.elg.g , b->d.elg.g ) )
-           return -1;
-       if( mpi_cmp( a->d.elg.y , b->d.elg.y ) )
-           return -1;
-    }
-    else if( a->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       if( mpi_cmp( a->d.dsa.p , b->d.dsa.p ) )
-           return -1;
-       if( mpi_cmp( a->d.dsa.q , b->d.dsa.q ) )
-           return -1;
-       if( mpi_cmp( a->d.dsa.g , b->d.dsa.g ) )
-           return -1;
-       if( mpi_cmp( a->d.dsa.y , b->d.dsa.y ) )
-           return -1;
-    }
-    else if( is_RSA(a->pubkey_algo) ) {
-       if( mpi_cmp( a->d.rsa.n , b->d.rsa.n ) )
-           return -1;
-       if( mpi_cmp( a->d.rsa.e , b->d.rsa.e ) )
+    n = pubkey_get_npkey( b->pubkey_algo );
+    for(i=0; i < n; i++ ) {
+       if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
            return -1;
     }
 
@@ -339,6 +266,8 @@ cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b )
 int
 cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc )
 {
+    int n, i;
+
     if( pkc->timestamp != skc->timestamp )
        return -1;
     if( pkc->valid_days != skc->valid_days )
@@ -346,31 +275,11 @@ cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc )
     if( pkc->pubkey_algo != skc->pubkey_algo )
        return -1;
 
-    if( is_ELGAMAL(pkc->pubkey_algo) ) {
-       if( mpi_cmp( pkc->d.elg.p , skc->d.elg.p ) )
-           return -1;
-       if( mpi_cmp( pkc->d.elg.g , skc->d.elg.g ) )
-           return -1;
-       if( mpi_cmp( pkc->d.elg.y , skc->d.elg.y ) )
-           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;
 }
 
index 367c22d..63c162f 100644 (file)
@@ -155,17 +155,17 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
     skc->version = pkc->version = version;
     skc->valid_days = pkc->valid_days = valid_days;
     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
-                      pkc->d.elg.p = pk.p;
-                      pkc->d.elg.g = pk.g;
-                      pkc->d.elg.y = pk.y;
-    skc->d.elg.p = sk.p;
-    skc->d.elg.g = sk.g;
-    skc->d.elg.y = sk.y;
-    skc->d.elg.x = sk.x;
+                      pkc->pkey[0] = pk.p;
+                      pkc->pkey[1] = pk.g;
+                      pkc->pkey[2] = pk.y;
+    skc->skey[0] = sk.p;
+    skc->skey[1] = sk.g;
+    skc->skey[2] = sk.y;
+    skc->skey[3] = sk.x;
     skc->is_protected = 0;
     skc->protect.algo = 0;
 
-    skc->csum = checksum_mpi( skc->d.elg.x );
+    skc->csum = checksum_mpi( skc->skey[3] );
     if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
        *ret_skc = copy_secret_cert( NULL, skc );
 
@@ -296,19 +296,19 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
      */
     skc->valid_days = pkc->valid_days = valid_days;
     skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_DSA;
-                      pkc->d.dsa.p = pk.p;
-                      pkc->d.dsa.q = pk.q;
-                      pkc->d.dsa.g = pk.g;
-                      pkc->d.dsa.y = pk.y;
-    skc->d.dsa.p = sk.p;
-    skc->d.dsa.q = sk.q;
-    skc->d.dsa.g = sk.g;
-    skc->d.dsa.y = sk.y;
-    skc->d.dsa.x = sk.x;
+                      pkc->pkey[0] = pk.p;
+                      pkc->pkey[1] = pk.q;
+                      pkc->pkey[2] = pk.g;
+                      pkc->pkey[3] = pk.y;
+    skc->skey[0] = sk.p;
+    skc->skey[1] = sk.q;
+    skc->skey[2] = sk.g;
+    skc->skey[3] = sk.y;
+    skc->skey[4] = sk.x;
     skc->is_protected = 0;
     skc->protect.algo = 0;
 
-    skc->csum = checksum_mpi( skc->d.dsa.x );
+    skc->csum = checksum_mpi( skc->skey[4] );
     if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
         *ret_skc = copy_secret_cert( NULL, skc );
 
index 55c0c49..dc24904 100644 (file)
@@ -47,182 +47,72 @@ pubkey_letter( int algo )
     }
 }
 
-/* this is special code for V3 which uses ElGamal and
- * calculates a fingerprint like V4, but with rmd160
- * and a version byte of 3. Returns an md handle, caller must
- * do md_close()
- */
 
 static MD_HANDLE
-v3_elg_fingerprint_md( PKT_public_cert *pkc )
+do_fingerprint_md( PKT_public_cert *pkc )
 {
     MD_HANDLE md;
-    byte *buf1, *buf2, *buf3;
-    byte *p1, *p2, *p3;
-    unsigned n1, n2, n3;
-    unsigned nb1, nb2, nb3;
     unsigned n;
-
-    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;
index 017bb78..56fd3c9 100644 (file)
@@ -91,20 +91,6 @@ MPI encode_md_value( MD_HANDLE md, int hash_algo, unsigned nbits );
 KBNODE make_comment_node( const char *s );
 KBNODE make_mpi_comment_node( const char *s, MPI a );
 
-/*-- elg.c --*/
-void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
-void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
-                                        MD_HANDLE md, int digest_algo );
-
-/*-- dsa.c --*/
-void g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
-                                        MD_HANDLE md, int digest_algo );
-
-/*-- rsa.c --*/
-void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
-void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
-                                        MD_HANDLE md, int digest_algo );
-
 /*-- import.c --*/
 int import_pubkeys( const char *filename );
 /*-- export.c --*/
index cb9740c..4f04e1a 100644 (file)
@@ -68,8 +68,7 @@ typedef struct {
     u32     keyid[2];      /* 64 bit keyid */
     byte    version;
     byte    pubkey_algo;    /* algorithm used for public key scheme */
-    int     mpi_count;     /* 1 for rsa, 2 for ELG */
-    MPI     material[2];    /* (ELG needs 2)
+    MPI     data[PUBKEY_MAX_NENC];
 } PKT_pubkey_enc;
 
 
@@ -94,20 +93,16 @@ typedef struct {
     byte *hashed_data;     /* all subpackets with hashed  data (v4 only) */
     byte *unhashed_data;    /* ditto for unhashed data */
     byte digest_start[2];   /* first 2 bytes of the digest */
-    union {
-      struct {
-       MPI  a, b;            /* integers with the digest */
-      } elg;
-      struct {
-       MPI  r, s;            /* integers with the digest */
-      } dsa;
-      struct {
-       MPI  rsa_integer;     /* the encrypted digest */
-      } rsa;
-    } d;
+    MPI  data[PUBKEY_MAX_NSIG];
 } PKT_signature;
 
 
+/****************
+ * Note about the pkey/skey elements:  We assume that the secret keys
+ * has the same elemts as the public key at the begin of the array, so
+ * that npkey < nskey and it is possible to compare the secret and
+ * public keys by comparing the first npkey elements of pkey againts skey.
+ */
 typedef struct {
     u32     timestamp;     /* certificate made */
     u16     valid_days;     /* valid for this number of days */
@@ -115,11 +110,7 @@ typedef struct {
     byte    version;
     byte    pubkey_algo;    /* algorithm used for public key scheme */
     ulong   local_id;      /* internal use, valid if > 0 */
-    union {
-       ELG_public_key elg;
-       DSA_public_key dsa;
-       RSA_public_key rsa;
-    } d;
+    MPI     pkey[PUBKEY_MAX_NPKEY];
 } PKT_public_cert;
 
 typedef struct {
@@ -137,11 +128,7 @@ typedef struct {
        STRING2KEY s2k;
        byte iv[8]; /* initialization vector for CFB mode */
     } protect;
-    union {
-       ELG_secret_key elg;
-       DSA_secret_key dsa;
-       RSA_secret_key rsa;
-    } d;
+    MPI skey[PUBKEY_MAX_NSKEY];
     u16 csum;          /* checksum */
 } PKT_secret_cert;
 
index e1f0232..0ee6e7d 100644 (file)
@@ -318,6 +318,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
        break;
       case PKT_RING_TRUST:
        parse_trust(inp, pkttype, pktlen);
+       rc = 0;
        break;
       case PKT_PLAINTEXT:
        rc = parse_plaintext(inp, pkttype, pktlen, pkt );
@@ -502,6 +503,7 @@ static int
 parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
 {
     unsigned n;
+    int i, ndata;
     PKT_pubkey_enc *k;
 
     k = packet->pkt.pubkey_enc = m_alloc(sizeof *packet->pkt.pubkey_enc );
@@ -520,31 +522,20 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
     if( list_mode )
        printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
          k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
-    if( is_ELGAMAL(k->pubkey_algo) ) {
-       n = pktlen;
-       k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n;
-       n = pktlen;
-       k->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
-       if( list_mode ) {
-           printf("\telg a: ");
-           mpi_print(stdout, k->d.elg.a, mpi_print_mode );
-           printf("\n\telg b: ");
-           mpi_print(stdout, k->d.elg.b, mpi_print_mode );
-           putchar('\n');
-       }
-    }
-    else if( is_RSA(k->pubkey_algo) ) {
+
+    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 )
index 8b48255..ade1555 100644 (file)
@@ -56,26 +56,9 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
     if( (rc = get_seckey( skc, k->keyid )) )
        goto leave;
 
-    if( is_ELGAMAL(k->pubkey_algo) ) {
-       if( DBG_CIPHER ) {
-           log_mpidump("Encr DEK a:", k->d.elg.a );
-           log_mpidump("     DEK b:", k->d.elg.b );
-       }
-       plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skc->d.elg.p) );
-       elg_decrypt( plain_dek, k->d.elg.a, k->d.elg.b, &skc->d.elg );
-    }
-    else if( is_RSA(k->pubkey_algo) ) {
-       if( DBG_CIPHER )
-           log_mpidump("Encr DEK frame:", k->d.rsa.rsa_integer );
-
-       plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skc->d.rsa.n) );
-       rsa_secret( plain_dek, k->d.rsa.rsa_integer, &skc->d.rsa );
-    }
-    else {
-       log_info("need some glue code for pubkey algo %d\n", k->pubkey_algo);
-       rc = G10ERR_PUBKEY_ALGO; /* unsupported algorithm */
+    rc = pubkey_decrypt(k->pubkey_algo, &plain_dek, k->data, skc->skey );
+    if( rc )
        goto leave;
-    }
     free_secret_cert( skc ); skc = NULL;
     frame = mpi_get_buffer( plain_dek, &nframe, NULL );
     mpi_free( plain_dek ); plain_dek = NULL;
@@ -117,25 +100,18 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
 
     dek->keylen = nframe - (n+1) - 2;
     dek->algo = frame[n++];
-    switch( dek->algo ) {
-      case CIPHER_ALGO_IDEA:
+    if( dek->algo ==  CIPHER_ALGO_IDEA )
        write_status(STATUS_RSA_OR_IDEA);
-       rc = G10ERR_NI_CIPHER;
-       goto leave;
-      case CIPHER_ALGO_BLOWFISH160:
-       if( dek->keylen != 20 )
-           { rc = G10ERR_WRONG_SECKEY; goto leave; }
-       break;
-      case CIPHER_ALGO_BLOWFISH:
-      case CIPHER_ALGO_CAST5:
-       if( dek->keylen != 16 )
-           { rc = G10ERR_WRONG_SECKEY; goto leave; }
-       break;
-      default:
+    rc = check_cipher_algo( dek->algo );
+    if( rc ) {
        dek->algo = 0;
-       rc = G10ERR_CIPHER_ALGO;
        goto leave;
     }
+    if( (dek->keylen*8) != cipher_get_keylen( dek->algo ) ) {
+       rc = G10ERR_WRONG_SECKEY;
+       goto leave;
+    }
+
     /* copy the key to DEK and compare the checksum */
     csum  = frame[nframe-2] << 8;
     csum |= frame[nframe-1];
index 28faedd..a281d8b 100644 (file)
@@ -448,6 +448,35 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
  ********** Functions which operates on regular keyrings ********
  ****************************************************************/
 
+static int
+cmp_seckey( PKT_secret_cert *req_skc, PKT_secret_cert *skc )
+{
+    int n,i;
+
+    assert( req_skc->pubkey_algo == skc->pubkey_algo );
+
+    n = pubkey_get_nskey( req_skc->pubkey_algo );
+    for(i=0; i < n; i++ ) {
+       if( mpi_cmp( req_skc->skey[i], skc->skey[i] ) )
+           return -1;
+    }
+    return 0;
+}
+
+static int
+cmp_pubkey( PKT_public_cert *req_pkc, PKT_public_cert *pkc )
+{
+    int n, i;
+
+    assert( req_pkc->pubkey_algo == pkc->pubkey_algo );
+
+    n = pubkey_get_npkey( req_pkc->pubkey_algo );
+    for(i=0; i < n; i++ ) {
+       if( mpi_cmp( req_pkc->pkey[i], pkc->pkey[i] )  )
+           return -1;
+    }
+    return 0;
+}
 
 /****************
  * search one keyring, return 0 if found, -1 if not found or an errorcode.
@@ -489,26 +518,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
            if(   req_skc->timestamp == skc->timestamp
               && req_skc->valid_days == skc->valid_days
               && req_skc->pubkey_algo == skc->pubkey_algo
-              && (   ( is_ELGAMAL(skc->pubkey_algo)
-                       && !mpi_cmp( req_skc->d.elg.p, skc->d.elg.p )
-                       && !mpi_cmp( req_skc->d.elg.g, skc->d.elg.g )
-                       && !mpi_cmp( req_skc->d.elg.y, skc->d.elg.y )
-                       && !mpi_cmp( req_skc->d.elg.x, skc->d.elg.x )
-                     )
-                  || ( skc->pubkey_algo == PUBKEY_ALGO_DSA
-                       && !mpi_cmp( req_skc->d.dsa.p, skc->d.dsa.p )
-                       && !mpi_cmp( req_skc->d.dsa.q, skc->d.dsa.q )
-                       && !mpi_cmp( req_skc->d.dsa.g, skc->d.dsa.g )
-                       && !mpi_cmp( req_skc->d.dsa.y, skc->d.dsa.y )
-                       && !mpi_cmp( req_skc->d.dsa.x, skc->d.dsa.x )
-                     )
-                  || ( is_RSA(skc->pubkey_algo)
-                       && !mpi_cmp( req_skc->d.rsa.n, skc->d.rsa.n )
-                       && !mpi_cmp( req_skc->d.rsa.e, skc->d.rsa.e )
-                       && !mpi_cmp( req_skc->d.rsa.d, skc->d.rsa.d )
-                     )
-                 )
-             )
+              && !cmp_seckey( req_skc, skc) )
                break; /* found */
        }
        else if( pkt.pkttype == PKT_PUBLIC_CERT ) {
@@ -517,23 +527,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
            if(   req_pkc->timestamp == pkc->timestamp
               && req_pkc->valid_days == pkc->valid_days
               && req_pkc->pubkey_algo == pkc->pubkey_algo
-              && (   ( is_ELGAMAL(pkc->pubkey_algo)
-                       && !mpi_cmp( req_pkc->d.elg.p, pkc->d.elg.p )
-                       && !mpi_cmp( req_pkc->d.elg.g, pkc->d.elg.g )
-                       && !mpi_cmp( req_pkc->d.elg.y, pkc->d.elg.y )
-                     )
-                  || ( pkc->pubkey_algo == PUBKEY_ALGO_DSA
-                       && !mpi_cmp( req_pkc->d.dsa.p, pkc->d.dsa.p )
-                       && !mpi_cmp( req_pkc->d.dsa.q, pkc->d.dsa.q )
-                       && !mpi_cmp( req_pkc->d.dsa.g, pkc->d.dsa.g )
-                       && !mpi_cmp( req_pkc->d.dsa.y, pkc->d.dsa.y )
-                     )
-                  || ( is_RSA(pkc->pubkey_algo)
-                       && !mpi_cmp( req_pkc->d.rsa.n, pkc->d.rsa.n )
-                       && !mpi_cmp( req_pkc->d.rsa.e, pkc->d.rsa.e )
-                     )
-                 )
-             )
+              && !cmp_pubkey( req_pkc, pkc ) )
                break; /* found */
        }
        else
diff --git a/g10/rsa.c b/g10/rsa.c
deleted file mode 100644 (file)
index 36e0ef2..0000000
--- 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*/
-}
-
index 3373bd3..41a09b2 100644 (file)
@@ -67,17 +67,18 @@ do_check( PKT_secret_cert *cert )
        switch( cert->pubkey_algo ) {
          case PUBKEY_ALGO_ELGAMAL:
          case PUBKEY_ALGO_ELGAMAL_E:
-           buffer = mpi_get_secure_buffer( cert->d.elg.x, &nbytes, NULL );
+           /* FIXME: removed ELG knowledge from this function */
+           buffer = mpi_get_secure_buffer( cert->skey[3], &nbytes, NULL );
            cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
-           mpi_set_buffer( cert->d.elg.x, buffer, nbytes, 0 );
-           csum = checksum_mpi( cert->d.elg.x );
+           mpi_set_buffer( cert->skey[3], buffer, nbytes, 0 );
+           csum = checksum_mpi( cert->skey[3] );
            m_free( buffer );
            break;
          case PUBKEY_ALGO_DSA:
-           buffer = mpi_get_secure_buffer( cert->d.dsa.x, &nbytes, NULL );
+           buffer = mpi_get_secure_buffer( cert->skey[4], &nbytes, NULL );
            cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
-           mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 );
-           csum = checksum_mpi( cert->d.dsa.x );
+           mpi_set_buffer( cert->skey[4], buffer, nbytes, 0 );
+           csum = checksum_mpi( cert->skey[4] );
            m_free( buffer );
            break;
        #ifdef HAVE_RSA_CIPHER
@@ -107,15 +108,6 @@ do_check( PKT_secret_cert *cert )
        cipher_close( cipher_hd );
        /* now let's see whether we have used the right passphrase */
        if( csum != cert->csum ) {
-           if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
-               /* very bad kludge to work around an early bug */
-               csum -= checksum_u16( mpi_get_nbits(cert->d.elg.x) );
-               nbytes = mpi_get_nlimbs(cert->d.elg.x) * 4;
-               csum += checksum_u16( nbytes*8 );
-               if( !opt.batch && csum == cert->csum )
-                   log_info("Probably you have an old key - use "
-                        "\"--change-passphrase\" to convert.\n");
-           }
            if( csum != cert->csum ) {
                copy_secret_cert( cert, save_cert );
                free_secret_cert( save_cert );
@@ -124,24 +116,8 @@ do_check( PKT_secret_cert *cert )
            }
        }
 
-       switch( cert->pubkey_algo ) {
-         case PUBKEY_ALGO_ELGAMAL_E:
-         case PUBKEY_ALGO_ELGAMAL:
-           res = elg_check_secret_key( &cert->d.elg );
-           break;
-         case PUBKEY_ALGO_DSA:
-           res = dsa_check_secret_key( &cert->d.dsa );
-           break;
-       #ifdef HAVE_RSA_CIPHER
-         case PUBKEY_ALGO_RSA:
-         case PUBKEY_ALGO_RSA_E:
-         case PUBKEY_ALGO_RSA_S:
-           res = rsa_check_secret_key( &cert->d.rsa );
-           break;
-       #endif
-         default: BUG();
-       }
-       if( !res ) {
+       res = pubkey_check_secret_key( cert->pubkey_algo, cert->skey );
+       if( res ) {
            copy_secret_cert( cert, save_cert );
            free_secret_cert( save_cert );
            memcpy( cert->protect.iv, save_iv, 8 );
@@ -154,10 +130,10 @@ do_check( PKT_secret_cert *cert )
        switch( cert->pubkey_algo ) {
          case PUBKEY_ALGO_ELGAMAL_E:
          case PUBKEY_ALGO_ELGAMAL:
-           csum = checksum_mpi( cert->d.elg.x );
+           csum = checksum_mpi( cert->skey[3] );
            break;
          case PUBKEY_ALGO_DSA:
-           csum = checksum_mpi( cert->d.dsa.x );
+           csum = checksum_mpi( cert->skey[4] );
            break;
        #ifdef HAVE_RSA_CIPHER
          case PUBKEY_ALGO_RSA_E:
@@ -184,19 +160,8 @@ do_check( PKT_secret_cert *cert )
        #endif
          default: BUG();
        }
-       if( csum != cert->csum ) {
-           if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
-               /* very bad kludge to work around an early bug */
-               csum -= checksum_u16( mpi_get_nbits(cert->d.elg.x) );
-               nbytes = mpi_get_nlimbs(cert->d.elg.x) * 4;
-               csum += checksum_u16( nbytes*8 );
-               if( !opt.batch && csum == cert->csum )
-                   log_info("Probably you have an old key - use "
-                        "\"--change-passphrase\" to convert.\n");
-           }
-           if( csum != cert->csum )
-               return G10ERR_CHECKSUM;
-       }
+       if( csum != cert->csum )
+           return G10ERR_CHECKSUM;
     }
 
     return 0;
@@ -274,23 +239,17 @@ do_protect( void (*fnc)(CIPHER_HANDLE, byte *, byte *, unsigned),
 
     switch( cert->pubkey_algo ) {
       case PUBKEY_ALGO_ELGAMAL_E:
-       /* recalculate the checksum, so that --change-passphrase
-        * can be used to convert from the faulty to the correct one
-        * wk 06.04.98:
-        * fixme: remove this some time in the future.
-        */
-       cert->csum = checksum_mpi( cert->d.elg.x );
       case PUBKEY_ALGO_ELGAMAL:
-       buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL );
+       buffer = mpi_get_buffer( cert->skey[3], &nbytes, NULL );
        (*fnc)( fnc_hd, buffer, buffer, nbytes );
-       mpi_set_buffer( cert->d.elg.x, buffer, nbytes, 0 );
+       mpi_set_buffer( cert->skey[3], buffer, nbytes, 0 );
        m_free( buffer );
        break;
 
       case PUBKEY_ALGO_DSA:
-       buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
+       buffer = mpi_get_buffer( cert->skey[4], &nbytes, NULL );
        (*fnc)( fnc_hd, buffer, buffer, nbytes );
-       mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 );
+       mpi_set_buffer( cert->skey[4], buffer, nbytes, 0 );
        m_free( buffer );
        break;
 
index 6dc6609..a4c802c 100644 (file)
@@ -95,11 +95,10 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
        }
        md_final( digest );
        result = encode_md_value( digest, sig->digest_algo,
-                                         mpi_get_nbits(pkc->d.elg.p));
+                                         mpi_get_nbits(pkc->pkey[0]));
        if( DBG_CIPHER )
            log_mpidump("calc sig frame (elg): ", result);
-       if( !elg_verify( sig->d.elg.a, sig->d.elg.b, result, &pkc->d.elg ) )
-           rc = G10ERR_BAD_SIGN;
+       rc = pubkey_verify( pkc->pubkey_algo, result, sig->data, pkc->pkey );
     }
     else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
        if( (rc=check_digest_algo(sig->digest_algo)) )
@@ -148,8 +147,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
                                md_digest_length(sig->digest_algo), 0 );
        if( DBG_CIPHER )
            log_mpidump("calc sig frame: ", result);
-       if( !dsa_verify( sig->d.dsa.r, sig->d.dsa.s, result, &pkc->d.dsa ) )
-           rc = G10ERR_BAD_SIGN;
+       rc = pubkey_verify( pkc->pubkey_algo, result, sig->data, pkc->pkey );
     }
  #ifdef HAVE_RSA_CIPHER
     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA
index bd435a7..a85f1f9 100644 (file)
 #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;
     }
 
 
index 186851a..3fe56c2 100644 (file)
@@ -84,6 +84,8 @@ struct cipher_handle_s { char does_not_matter[1]; };
 #define CIPHER_MODE_DUMMY     5  /* used with algo DUMMY for no encryption */
 
 
+
+
 int cipher_debug_mode;
 
 /*-- dynload.c --*/
@@ -102,6 +104,23 @@ void cipher_encrypt( CIPHER_HANDLE c, byte *out, byte *in, unsigned nbytes );
 void cipher_decrypt( CIPHER_HANDLE c, byte *out, byte *in, unsigned nbytes );
 void cipher_sync( CIPHER_HANDLE c );
 
+/*-- pubkey.c --*/
+#define PUBKEY_MAX_NPKEY  4
+#define PUBKEY_MAX_NSKEY  6
+#define PUBKEY_MAX_NSIG   2
+#define PUBKEY_MAX_NENC   2
+
+int pubkey_get_npkey( int algo );
+int pubkey_get_nskey( int algo );
+int pubkey_get_nsig( int algo );
+int pubkey_get_nenc( int algo );
+unsigned pubkey_nbits( int algo, MPI *pkey );
+int pubkey_check_secret_key( int algo, MPI *skey );
+int pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
+int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
+int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
+int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey );
+
 
 /*-- misc.c --*/
 int string_to_pubkey_algo( const char *string );
index 7fcfb38..85e567d 100755 (executable)
Binary files a/tools/mk-tdata and b/tools/mk-tdata differ