diff options
author | Werner Koch <[email protected]> | 1998-06-13 06:59:14 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 1998-06-13 06:59:14 +0000 |
commit | 37d2adfe61d9671086fa701b779c3b47895afe4c (patch) | |
tree | 3af3791cb54dbd56687ee09e6a2666fabdecdc15 | |
parent | . (diff) | |
download | gnupg-37d2adfe61d9671086fa701b779c3b47895afe4c.tar.gz gnupg-37d2adfe61d9671086fa701b779c3b47895afe4c.zip |
a whole bunch of internal cleanups
Diffstat (limited to '')
-rwxr-xr-x | checks/conventional.test | 2 | ||||
-rwxr-xr-x | checks/defs.inc | 6 | ||||
-rwxr-xr-x | checks/encrypt-dsa.test | 2 | ||||
-rwxr-xr-x | checks/encrypt.test | 2 | ||||
-rwxr-xr-x | checks/run-gpg | 3 | ||||
-rw-r--r-- | cipher/Makefile.am | 5 | ||||
-rw-r--r-- | cipher/cast5.c | 12 | ||||
-rw-r--r-- | cipher/pubkey.c | 377 | ||||
-rw-r--r-- | g10/ChangeLog | 10 | ||||
-rw-r--r-- | g10/Makefile.am | 3 | ||||
-rw-r--r-- | g10/build-packet.c | 131 | ||||
-rw-r--r-- | g10/dsa.c | 69 | ||||
-rw-r--r-- | g10/elg.c | 92 | ||||
-rw-r--r-- | g10/encode.c | 38 | ||||
-rw-r--r-- | g10/free-packet.c | 171 | ||||
-rw-r--r-- | g10/keygen.c | 36 | ||||
-rw-r--r-- | g10/keyid.c | 355 | ||||
-rw-r--r-- | g10/main.h | 14 | ||||
-rw-r--r-- | g10/packet.h | 33 | ||||
-rw-r--r-- | g10/parse-packet.c | 139 | ||||
-rw-r--r-- | g10/pubkey-enc.c | 44 | ||||
-rw-r--r-- | g10/ringedit.c | 68 | ||||
-rw-r--r-- | g10/rsa.c | 89 | ||||
-rw-r--r-- | g10/seckey-cert.c | 75 | ||||
-rw-r--r-- | g10/sig-check.c | 8 | ||||
-rw-r--r-- | g10/sign.c | 109 | ||||
-rw-r--r-- | include/cipher.h | 19 | ||||
-rwxr-xr-x | tools/mk-tdata | bin | 11769 -> 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 Binary files differindex 7fcfb389f..85e567d45 100755 --- a/tools/mk-tdata +++ b/tools/mk-tdata |