aboutsummaryrefslogtreecommitdiffstats
path: root/g10/sign.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2000-10-04 11:16:19 +0000
committerWerner Koch <[email protected]>2000-10-04 11:16:19 +0000
commit9c20f65cbe9d3d806b02f0f90a2051a20f3857db (patch)
tree6c784f870b191b2a1b3f16f86cff3a5af59ff2f6 /g10/sign.c
parentSee ChangeLog: Mon Sep 18 16:35:45 CEST 2000 Werner Koch (diff)
downloadgnupg-9c20f65cbe9d3d806b02f0f90a2051a20f3857db.tar.gz
gnupg-9c20f65cbe9d3d806b02f0f90a2051a20f3857db.zip
See ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch
Diffstat (limited to 'g10/sign.c')
-rw-r--r--g10/sign.c300
1 files changed, 123 insertions, 177 deletions
diff --git a/g10/sign.c b/g10/sign.c
index b53444b7c..bdc5b8afe 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -40,6 +40,8 @@
#include "i18n.h"
+#define ENABLE_BETTER_PGP2_COMPAT 1
+
#ifdef HAVE_DOSISH_SYSTEM
#define LF "\r\n"
#else
@@ -217,13 +219,13 @@ complete_sig( PKT_signature *sig, PKT_secret_key *sk, GCRY_MD_HD md )
}
static int
-hash_for(int pubkey_algo )
+hash_for(int pubkey_algo, int packet_version )
{
if( opt.def_digest_algo )
return opt.def_digest_algo;
if( pubkey_algo == GCRY_PK_DSA )
return GCRY_MD_SHA1;
- if( pubkey_algo == GCRY_PK_RSA )
+ if( pubkey_algo == GCRY_PK_RSA && packet_version < 4 )
return GCRY_MD_MD5;
return DEFAULT_DIGEST_ALGO;
}
@@ -265,6 +267,94 @@ print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
write_status_text( STATUS_SIG_CREATED, buf );
}
+static int
+write_one_signature( IOBUF out, PKT_secret_key *sk, int old_style,
+ const char *outfile,
+ GCRY_MD_HD datamd,
+ int sig_class,
+ int status_char )
+{
+ PKT_signature *sig;
+ GCRY_MD_HD md;
+ int rc;
+
+ /* build the signature packet */
+ /* fixme: this code is partly duplicated in make_keysig_packet */
+ sig = gcry_xcalloc( 1, sizeof *sig );
+ sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
+ keyid_from_sk( sk, sig->keyid );
+ sig->digest_algo = hash_for(sk->pubkey_algo, sk->version);
+ sig->pubkey_algo = sk->pubkey_algo;
+ sig->timestamp = make_timestamp();
+ sig->sig_class = sig_class;
+
+ md = gcry_md_copy( datamd );
+ if( !md )
+ BUG();
+ if( sig->version >= 4 ) {
+ build_sig_subpkt_from_sig( sig );
+ gcry_md_putc( md, sig->version );
+ }
+
+ mk_notation_and_policy( sig );
+
+ gcry_md_putc( md, sig->sig_class );
+ if( sig->version < 4 ) {
+ u32 a = sig->timestamp;
+ gcry_md_putc( md, (a >> 24) & 0xff );
+ gcry_md_putc( md, (a >> 16) & 0xff );
+ gcry_md_putc( md, (a >> 8) & 0xff );
+ gcry_md_putc( md, a & 0xff );
+ }
+ else {
+ byte buf[6];
+ size_t n;
+
+ gcry_md_putc( md, sig->pubkey_algo );
+ gcry_md_putc( md, sig->digest_algo );
+ if( sig->hashed_data ) {
+ n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
+ gcry_md_write( md, sig->hashed_data, n+2 );
+ n += 6;
+ }
+ else {
+ gcry_md_putc( md, 0 );/* always hash the length of the subpacket*/
+ gcry_md_putc( md, 0 );
+ n = 6;
+ }
+ /* add some magic */
+ buf[0] = sig->version;
+ buf[1] = 0xff;
+ buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
+ buf[3] = n >> 16;
+ buf[4] = n >> 8;
+ buf[5] = n;
+ gcry_md_write( md, buf, 6 );
+ }
+ gcry_md_final( md );
+
+ rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo, sk->version) );
+ gcry_md_close( md );
+ /* Hmmm: Do we release sig in case of rc != 0? */
+
+ if( !rc ) { /* and write it */
+ PACKET pkt;
+
+ init_packet(&pkt);
+ pkt.pkttype = PKT_SIGNATURE;
+ pkt.pkt.signature = sig;
+ rc = build_packet( out, &pkt );
+ if( !rc && is_status_enabled() ) {
+ print_status_sig_created ( sk, sig, status_char );
+ }
+ free_packet( &pkt );
+ if( rc )
+ log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
+ }
+
+ return rc;
+}
+
/****************
* Sign the files whose names are in FILENAME.
@@ -360,7 +450,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
- gcry_md_enable(mfx.md, hash_for(sk->pubkey_algo));
+ gcry_md_enable(mfx.md, hash_for(sk->pubkey_algo, sk->version ));
}
if( !multifile )
@@ -385,6 +475,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
iobuf_push_filter( out, encrypt_filter, &efx );
}
+ /* Select a compress algorithm */
if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) {
if( !compr_algo )
; /* don't use compression */
@@ -397,6 +488,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
}
+ /* Build one-pass signature packets when needed */
if( !detached && !old_style ) {
int skcount=0;
/* loop over the secret certificates and build headers
@@ -417,7 +509,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
sk = sk_rover->sk;
ops = gcry_xcalloc( 1, sizeof *ops );
ops->sig_class = opt.textmode && !outfile ? 0x01 : 0x00;
- ops->digest_algo = hash_for(sk->pubkey_algo);
+ ops->digest_algo = hash_for(sk->pubkey_algo, sk->version);
ops->pubkey_algo = sk->pubkey_algo;
keyid_from_sk( sk, ops->keyid );
ops->last = skcount == 1;
@@ -437,6 +529,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
/* setup the inner packet */
if( detached ) {
+ /* this is pretty much the same for old and new PGP. So no
+ * need to cope with different packet ordering */
if( multifile ) {
STRLIST sl;
@@ -468,9 +562,11 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
}
else {
+ /* get the filename to be stored into the literal datapacket */
if (!opt.no_literal) {
if( fname || opt.set_filename ) {
- char *s = make_basename( opt.set_filename ? opt.set_filename : fname );
+ char *s = make_basename( opt.set_filename ?
+ opt.set_filename : fname );
pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
pt->namelen = strlen(s);
memcpy(pt->name, s, pt->namelen );
@@ -490,7 +586,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
- /* because the text_filter modifies the length of the
+ /* Because the text_filter modifies the length of the
* data, it is not possible to know the used length
* without a double read of the file - to avoid that
* we simple use partial length packets.
@@ -511,7 +607,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
pkt.pkt.plaintext = pt;
/*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/
if( (rc = build_packet( out, &pkt )) )
- log_error("build_packet(PLAINTEXT) failed: %s\n", gpg_errstr(rc) );
+ log_error("build_packet(PLAINTEXT) failed: %s\n",
+ gpg_errstr(rc) );
pt->buf = NULL;
}
else {
@@ -520,100 +617,24 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
rc = GPGERR_WRITE_FILE;
- log_error("copying input to output failed: %s\n", gpg_errstr(rc));
+ log_error("copying input to output failed: %s\n",
+ gpg_errstr(rc));
break;
}
memset(copy_buffer, 0, 4096); /* burn buffer */
}
}
- /* catch errors from above blocks */
+ /* catch errors from above */
if (rc)
goto leave;
- /* loop over the secret certificates */
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- PKT_secret_key *sk;
- PKT_signature *sig;
- GCRY_MD_HD md;
-
- sk = sk_rover->sk;
-
- /* build the signature packet */
- /* fixme: this code is partly duplicated in make_keysig_packet */
- sig = gcry_xcalloc( 1, sizeof *sig );
- sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
- keyid_from_sk( sk, sig->keyid );
- sig->digest_algo = hash_for(sk->pubkey_algo);
- sig->pubkey_algo = sk->pubkey_algo;
- sig->timestamp = make_timestamp();
- sig->sig_class = opt.textmode && !outfile? 0x01 : 0x00;
-
- md = gcry_md_copy( mfx.md );
- if( !md )
- BUG();
-
- if( sig->version >= 4 ) {
- build_sig_subpkt_from_sig( sig );
- gcry_md_putc( md, sig->version );
- }
-
- mk_notation_and_policy( sig );
-
- gcry_md_putc( md, sig->sig_class );
- if( sig->version < 4 ) {
- u32 a = sig->timestamp;
- gcry_md_putc( md, (a >> 24) & 0xff );
- gcry_md_putc( md, (a >> 16) & 0xff );
- gcry_md_putc( md, (a >> 8) & 0xff );
- gcry_md_putc( md, a & 0xff );
- }
- else {
- byte buf[6];
- size_t n;
-
- gcry_md_putc( md, sig->pubkey_algo );
- gcry_md_putc( md, sig->digest_algo );
- if( sig->hashed_data ) {
- n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
- gcry_md_write( md, sig->hashed_data, n+2 );
- n += 6;
- }
- else {
- gcry_md_putc( md, 0 ); /* always hash the length of the subpacket*/
- gcry_md_putc( md, 0 );
- n = 6;
- }
- /* add some magic */
- buf[0] = sig->version;
- buf[1] = 0xff;
- buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
- buf[3] = n >> 16;
- buf[4] = n >> 8;
- buf[5] = n;
- gcry_md_write( md, buf, 6 );
-
- }
- gcry_md_final( md );
-
- rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo) );
- gcry_md_close( md );
-
- if( !rc ) { /* and write it */
- init_packet(&pkt);
- pkt.pkttype = PKT_SIGNATURE;
- pkt.pkt.signature = sig;
- rc = build_packet( out, &pkt );
- if( !rc && is_status_enabled() ) {
- print_status_sig_created ( sk, sig, detached ? 'D':'S');
- }
- free_packet( &pkt );
- if( rc )
- log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
- }
- if( rc )
- goto leave;
-
+ /* write all the signature packets */
+ for( sk_rover = sk_list; sk_rover && !rc ; sk_rover = sk_rover->next ) {
+ rc = write_one_signature( out, sk_rover->sk,
+ old_style, outfile, mfx.md,
+ opt.textmode && !outfile? 0x01 : 0x00,
+ detached ? 'D':'S' );
}
@@ -626,6 +647,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
gcry_md_close( mfx.md );
release_sk_list( sk_list );
release_pk_list( pk_list );
+ /* FIXME: Did we release the efx.cfx.dek ? */
return rc;
}
@@ -679,7 +701,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
- if( hash_for(sk->pubkey_algo) == GCRY_MD_MD5 )
+ if( hash_for(sk->pubkey_algo, sk->version) == GCRY_MD_MD5 )
only_md5 = 1;
else {
only_md5 = 0;
@@ -697,7 +719,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
iobuf_writestr(out, "Hash: " );
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
- int i = hash_for(sk->pubkey_algo);
+ int i = hash_for(sk->pubkey_algo, sk->version);
if( !hashs_seen[ i & 0xff ] ) {
if( !openpgp_md_test_algo( i ) ) {
@@ -723,7 +745,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
BUG();
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
- gcry_md_enable(textmd, hash_for(sk->pubkey_algo));
+ gcry_md_enable(textmd, hash_for(sk->pubkey_algo, sk->version));
}
if ( DBG_HASHING )
gcry_md_start_debug( textmd, "clearsign" );
@@ -735,90 +757,14 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
afx.what = 2;
iobuf_push_filter( out, armor_filter, &afx );
- /* loop over the secret certificates */
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- PKT_secret_key *sk;
- PKT_signature *sig;
- GCRY_MD_HD md;
-
- sk = sk_rover->sk;
-
- /* build the signature packet */
- /* fixme: this code is duplicated above */
- sig = gcry_xcalloc( 1, sizeof *sig );
- sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
- keyid_from_sk( sk, sig->keyid );
- sig->digest_algo = hash_for(sk->pubkey_algo);
- sig->pubkey_algo = sk->pubkey_algo;
- sig->timestamp = make_timestamp();
- sig->sig_class = 0x01;
-
- md = gcry_md_copy( textmd );
- if( !md )
- BUG();
- if( sig->version >= 4 ) {
- build_sig_subpkt_from_sig( sig );
- gcry_md_putc( md, sig->version );
- }
-
- mk_notation_and_policy( sig );
-
- gcry_md_putc( md, sig->sig_class );
- if( sig->version < 4 ) {
- u32 a = sig->timestamp;
- gcry_md_putc( md, (a >> 24) & 0xff );
- gcry_md_putc( md, (a >> 16) & 0xff );
- gcry_md_putc( md, (a >> 8) & 0xff );
- gcry_md_putc( md, a & 0xff );
- }
- else {
- byte buf[6];
- size_t n;
-
- gcry_md_putc( md, sig->pubkey_algo );
- gcry_md_putc( md, sig->digest_algo );
- if( sig->hashed_data ) {
- n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
- gcry_md_write( md, sig->hashed_data, n+2 );
- n += 6;
- }
- else {
- gcry_md_putc( md, 0 ); /* always hash the length of the subpacket*/
- gcry_md_putc( md, 0 );
- n = 6;
- }
- /* add some magic */
- buf[0] = sig->version;
- buf[1] = 0xff;
- buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
- buf[3] = n >> 16;
- buf[4] = n >> 8;
- buf[5] = n;
- gcry_md_write( md, buf, 6 );
-
- }
- gcry_md_final( md );
-
- rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo) );
- gcry_md_close( md );
-
- if( !rc ) { /* and write it */
- init_packet(&pkt);
- pkt.pkttype = PKT_SIGNATURE;
- pkt.pkt.signature = sig;
- rc = build_packet( out, &pkt );
- if( !rc && is_status_enabled() ) {
- print_status_sig_created ( sk, sig, 'C');
- }
- free_packet( &pkt );
- if( rc )
- log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
- }
- if( rc )
- goto leave;
+ /* write all the signature packets */
+ for( sk_rover = sk_list; sk_rover && !rc ; sk_rover = sk_rover->next ) {
+ rc = write_one_signature( out, sk_rover->sk,
+ old_style, outfile, textmd,
+ 0x01,
+ 'C' );
}
-
leave:
if( rc )
iobuf_cancel(out);