summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2000-10-04 13:16:19 +0200
committerWerner Koch <wk@gnupg.org>2000-10-04 13:16:19 +0200
commit9c20f65cbe9d3d806b02f0f90a2051a20f3857db (patch)
tree6c784f870b191b2a1b3f16f86cff3a5af59ff2f6 /g10
parentSee ChangeLog: Mon Sep 18 16:35:45 CEST 2000 Werner Koch (diff)
downloadgnupg2-9c20f65cbe9d3d806b02f0f90a2051a20f3857db.tar.xz
gnupg2-9c20f65cbe9d3d806b02f0f90a2051a20f3857db.zip
See ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog15
-rw-r--r--g10/encode.c135
-rw-r--r--g10/export.c2
-rw-r--r--g10/getkey.c58
-rw-r--r--g10/gpg.c4
-rw-r--r--g10/keydb.h1
-rw-r--r--g10/keygen.c3
-rw-r--r--g10/keyid.c2
-rw-r--r--g10/misc.c1
-rw-r--r--g10/pkclist.c12
-rw-r--r--g10/seckey-cert.c7
-rw-r--r--g10/sign.c300
-rw-r--r--g10/skclist.c13
-rw-r--r--g10/status.c3
14 files changed, 263 insertions, 293 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 7cb0f17b7..fb25e7fdc 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,18 @@
+Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
+
+ * getkey.c (merge_selfsigs_main): Fixed for v3 keys.
+
+ * sign.c (hash_for): New arg to take packet version in account. Changed
+ all callers.
+ (write_one_sig): New. Moved the shared code from sign_file and
+ clearsign_file to here.
+ * skclist.c (build_sk_list): Fixed usage check.
+ * pkclist.c (build_pk_list): Ditto.
+
+ * encode.c (encode_crypt): Removed duplicated stuff by using
+ encrypt_filter as sign.c already did. Removed already disabled
+ comment-packet code.
+
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* parse-packet.c (dump_sig_subpkt): Dump key flags.
diff --git a/g10/encode.c b/g10/encode.c
index a817f9094..f033c76ae 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -293,18 +293,17 @@ encode_crypt( const char *filename, STRLIST remusr )
PKT_plaintext *pt = NULL;
int rc = 0;
u32 filesize;
- cipher_filter_context_t cfx;
armor_filter_context_t afx;
compress_filter_context_t zfx;
text_filter_context_t tfx;
+ encrypt_filter_context_t efx;
PK_LIST pk_list;
int do_compress = opt.compress && !opt.rfc1991;
-
- memset( &cfx, 0, sizeof cfx);
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
memset( &tfx, 0, sizeof tfx);
+ memset( &efx, 0, sizeof efx);
init_packet(&pkt);
if( (rc=build_pk_list( remusr, &pk_list, GCRY_PK_USAGE_ENCR)) )
@@ -320,83 +319,67 @@ encode_crypt( const char *filename, STRLIST remusr )
else if( opt.verbose )
log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
+ /* If the user selected textmode, push the text filter onto the input */
if( opt.textmode )
iobuf_push_filter( inp, text_filter, &tfx );
+ /* Now we can create the outputfile */
if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
goto leave;
-
+ /* The first thing we have to push on the output stream
+ * is the armor filter */
if( opt.armor )
iobuf_push_filter( out, armor_filter, &afx );
- #ifdef ENABLE_COMMENT_PACKETS
- else {
- write_comment( out, "#created by GNUPG v" VERSION " ("
- PRINTABLE_OS_NAME ")");
- if( opt.comment_string )
- write_comment( out, opt.comment_string );
- }
- #endif
- /* create a session key */
- cfx.dek = gcry_xmalloc_secure( sizeof *cfx.dek );
- if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
- cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM );
- if( cfx.dek->algo == -1 )
- cfx.dek->algo = DEFAULT_CIPHER_ALGO;
- }
- else
- cfx.dek->algo = opt.def_cipher_algo;
- make_session_key( cfx.dek );
- if( DBG_CIPHER )
- log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
-
- rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
- if( rc )
- goto leave;
-
- if (!opt.no_literal) {
- /* setup the inner packet */
- if( filename || opt.set_filename ) {
- char *s = make_basename( opt.set_filename ? opt.set_filename : filename );
- pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
- pt->namelen = strlen(s);
- memcpy(pt->name, s, pt->namelen );
- gcry_free(s);
- }
- else { /* no filename */
- pt = gcry_xmalloc( sizeof *pt - 1 );
- pt->namelen = 0;
- }
- }
-
- if( filename && !opt.textmode ) {
- if( !(filesize = iobuf_get_filelength(inp)) )
- log_info(_("%s: WARNING: empty file\n"), filename );
- /* we can't yet encode the length of very large files,
- * so we switch to partial lengthn encoding in this case */
- if ( filesize >= IOBUF_FILELENGTH_LIMIT )
- filesize = 0;
- }
- else
- filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
-
- if (!opt.no_literal) {
- pt->timestamp = make_timestamp();
- pt->mode = opt.textmode ? 't' : 'b';
- pt->len = filesize;
- pt->new_ctb = !pt->len && !opt.rfc1991;
- pt->buf = inp;
- pkt.pkttype = PKT_PLAINTEXT;
- pkt.pkt.plaintext = pt;
- cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
- }
- else
- cfx.datalen = filesize && !do_compress ? filesize : 0;
-
- /* register the cipher filter */
- iobuf_push_filter( out, cipher_filter, &cfx );
- /* register the compress filter */
+ /* Prepare the plaintext packet */
+ {
+ if (!opt.no_literal) {
+ if( filename || opt.set_filename ) {
+ char *s = make_basename( opt.set_filename ?
+ opt.set_filename : filename );
+ pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
+ pt->namelen = strlen(s);
+ memcpy(pt->name, s, pt->namelen );
+ gcry_free(s);
+ }
+ else { /* no filename */
+ pt = gcry_xmalloc( sizeof *pt - 1 );
+ pt->namelen = 0;
+ }
+ }
+
+ if( filename && !opt.textmode ) {
+ if( !(filesize = iobuf_get_filelength(inp)) )
+ log_info(_("%s: WARNING: empty file\n"), filename );
+ /* we can't yet encode the length of very large files,
+ * so we switch to partial lengthn encoding in this case */
+ if ( filesize >= IOBUF_FILELENGTH_LIMIT )
+ filesize = 0;
+ }
+ else
+ filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
+
+ if (!opt.no_literal) {
+ pt->timestamp = make_timestamp();
+ pt->mode = opt.textmode ? 't' : 'b';
+ pt->len = filesize;
+ pt->new_ctb = !pt->len && !opt.rfc1991;
+ pt->buf = inp;
+ pkt.pkttype = PKT_PLAINTEXT;
+ pkt.pkt.plaintext = pt;
+ efx.cfx.datalen = filesize && !do_compress?
+ calc_packet_length( &pkt ) : 0;
+ }
+ else
+ efx.cfx.datalen = filesize && !do_compress ? filesize : 0;
+ } /* end preparation of plaintext packet */
+
+ /* push in the actual encryption filter */
+ efx.pk_list = pk_list;
+ iobuf_push_filter( out, encrypt_filter, &efx );
+
+ /* register the compress filter (so that it is done before encryption) */
if( do_compress ) {
int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
if( !compr_algo )
@@ -414,7 +397,8 @@ encode_crypt( const char *filename, STRLIST remusr )
log_error("build_packet failed: %s\n", gpg_errstr(rc) );
}
else {
- /* user requested not to create a literal packet, so we copy the plain data */
+ /* user requested not to create a literal packet,
+ * so we copy the plain data */
byte copy_buffer[4096];
int bytes_copied;
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
@@ -423,7 +407,7 @@ encode_crypt( const char *filename, STRLIST remusr )
log_error("copying input to output failed: %s\n", gpg_errstr(rc) );
break;
}
- memset(copy_buffer, 0, 4096); /* burn buffer */
+ memset(copy_buffer, 0, DIM(copy_buffer)); /* burn buffer */
}
/* finish the stuff */
@@ -436,7 +420,8 @@ encode_crypt( const char *filename, STRLIST remusr )
if( pt )
pt->buf = NULL;
free_packet(&pkt);
- gcry_free(cfx.dek);
+ gcry_free(efx.cfx.dek); /* Hmmm, why does the encrypt filter does not
+ * take care about this? */
release_pk_list( pk_list );
return rc;
}
@@ -445,7 +430,7 @@ encode_crypt( const char *filename, STRLIST remusr )
/****************
- * Filter to do a complete public key encryption.
+ * Filter to handle the entire public key encryption.
*/
int
encrypt_filter( void *opaque, int control,
diff --git a/g10/export.c b/g10/export.c
index 2de9f91bf..ddcc971d9 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -162,7 +162,7 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
log_error(_("certificate read problem: %s\n"), gpg_errstr(rc));
goto leave;
}
-
+
/* do not export keys which are incompatible with rfc2440 */
if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
diff --git a/g10/getkey.c b/g10/getkey.c
index 17dc6fafb..aa32dff74 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -795,12 +795,19 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
ctx->nitems = n;
for(n=0, r=namelist; r; r = r->next, n++ ) {
- ctx->items[n].mode = classify_user_id( r->d,
- ctx->items[n].keyid,
- ctx->items[n].fprint,
- &ctx->items[n].name,
- NULL );
- if( !ctx->items[n].mode ) {
+ int mode = classify_user_id( r->d,
+ ctx->items[n].keyid,
+ ctx->items[n].fprint,
+ &ctx->items[n].name,
+ NULL );
+
+ /* if we don't use one of the exact key specifications, we assume that
+ * the primary key is requested */
+ if ( mode != 10 && mode != 11 && mode != 16 && mode == 20 )
+ ctx->primary = 1;
+
+ ctx->items[n].mode = mode;
+ if( !ctx->items[n].mode ) {
gcry_free( ctx );
return GPGERR_INV_USER_ID;
}
@@ -810,8 +817,7 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
}
}
- /* and call the lookup function */
- ctx->primary = 1; /* we want to look for the primary key only */
+
if ( !ret_kb )
ret_kb = &help_kb;
@@ -1337,8 +1343,13 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
pk->main_keyid[0] = kid[0];
pk->main_keyid[1] = kid[1];
- if ( pk->version < 4 )
- return; /* nothing to do for old keys FIXME: This is wrong!!!!*/
+ if ( pk->version < 4 ) {
+ /* before v4 the key packet itself contains the expiration date
+ * and there was noway to change it. So we also use only the
+ * one from the key packet */
+ key_expire = pk->expiredate;
+ key_expire_seen = 1;
+ }
/* first pass: find the latest direct key self-signature.
* We assume that the newest one overrides all others
@@ -1394,12 +1405,14 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
key_usage |= GCRY_PK_USAGE_ENCR;
}
- p = parse_sig_subpkt ( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL);
- if ( p ) {
- key_expire = sig->timestamp + buffer_to_u32(p);
- key_expire_seen = 1;
+ if ( pk->version > 3 ) {
+ p = parse_sig_subpkt ( sig->hashed_data,
+ SIGSUBPKT_KEY_EXPIRE, NULL);
+ if ( p ) {
+ key_expire = sig->timestamp + buffer_to_u32(p);
+ key_expire_seen = 1;
+ }
}
-
/* and set the created field */
pk->created = sigdate;
/* and mark that key as valid: one direct key signature should
@@ -1518,8 +1531,8 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
}
}
}
- if ( key_expire >= curtime )
- pk->has_expired = key_expire;
+
+ pk->has_expired = key_expire >= curtime? 0 : key_expire;
/* FIXME: we should see how to get rid of the expiretime fields */
@@ -1651,7 +1664,7 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
key_expire = sig->timestamp + buffer_to_u32(p);
else
key_expire = 0;
- subpk->has_expired = key_expire >= curtime? key_expire : 0;
+ subpk->has_expired = key_expire >= curtime? 0 : key_expire;
}
@@ -1711,7 +1724,7 @@ merge_selfsigs( KBNODE keyblock )
* keys at all and have a way to store just the real secret parts
* from the key.
*/
-static void
+void
merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
{
KBNODE pub;
@@ -1942,8 +1955,8 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
}
if (DBG_CACHE)
- log_debug( "\tconsidering key created %lu\n",
- (ulong)pk->created);
+ log_debug( "\tconsidering key %08lX\n",
+ (ulong)keyid_from_pk( pk, NULL));
if ( pk->created > latest_date ) {
latest_date = pk->created;
latest_key = k;
@@ -1989,7 +2002,8 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
}
if (DBG_CACHE)
- log_debug( "\tusing key created %lu\n", (ulong)latest_date );
+ log_debug( "\tusing key %08lX\n",
+ (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) );
ctx->found_key = latest_key;
diff --git a/g10/gpg.c b/g10/gpg.c
index be4ec98a7..6faeb0721 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -509,6 +509,10 @@ static void
register_extension( const char *mainpgm, const char *fname )
{
#warning fixme add register cipher extension
+ /* Before we do so, we should design a beter API for this.
+ * I am currently thinking about using S-Exp to pass everything we
+ * need from the module to gcrypt. I hope we are not going to
+ * implement my-own-lisp-library-no-17000 */
#if 0
if( *fname != '/' ) { /* do tilde expansion etc */
char *tmp;
diff --git a/g10/keydb.h b/g10/keydb.h
index 830a7db3c..43c36e719 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -166,6 +166,7 @@ int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
void get_seckey_end( GETKEY_CTX ctx );
int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys );
void merge_keys_and_selfsig( KBNODE keyblock );
+void merge_public_with_secret ( KBNODE pubblock, KBNODE secblock );
char*get_user_id_string( u32 *keyid );
char*get_user_id_string_native( u32 *keyid );
char*get_long_user_id_string( u32 *keyid );
diff --git a/g10/keygen.c b/g10/keygen.c
index fc3b2cf8c..ef0064fc7 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -294,7 +294,6 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
{
int rc;
- int i;
PACKET *pkt;
PKT_secret_key *sk;
PKT_public_key *pk;
@@ -407,7 +406,6 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
{
int rc;
- int i;
PACKET *pkt;
PKT_secret_key *sk;
PKT_public_key *pk;
@@ -948,7 +946,6 @@ ask_user_id( int mode )
/* append a warning if we do not have dev/random
* or it is switched into quick testmode */
- #warning quick_random_gen() not available
#if 0
if( quick_random_gen(-1) )
strcpy(p, " (INSECURE!)" );
diff --git a/g10/keyid.c b/g10/keyid.c
index fb652e7b2..a4acb16d5 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -454,7 +454,7 @@ fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
int rc;
size_t nbytes;
- #warning Why is the hash sequence for secret keys different
+ /* FIXME: Why is the hash sequence for secret keys different */
rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, sk->skey[1] );
assert( !rc );
/* fixme: allocate it on the stack */
diff --git a/g10/misc.c b/g10/misc.c
index a62a04766..2348e46f0 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -330,6 +330,7 @@ print_cipher_algo_note( int algo )
else if( algo == GCRY_CIPHER_3DES
|| algo == GCRY_CIPHER_CAST5
|| algo == GCRY_CIPHER_BLOWFISH
+ || algo == GCRY_CIPHER_RIJNDAEL
|| algo == GCRY_CIPHER_TWOFISH
)
;
diff --git a/g10/pkclist.c b/g10/pkclist.c
index d827ce653..d585880ea 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -819,7 +819,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
free_public_key( pk ); pk = NULL;
log_error(_("%s: skipped: %s\n"), rov->d, gpg_errstr(rc) );
}
- else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
+ else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+ pk->pubkey_usage)) ) {
/* Skip the actual key if the key is already present
* in the list */
if (key_present_in_pk_list(pk_list, pk) == 0) {
@@ -874,7 +875,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
rc = get_pubkey_byname( NULL, pk, answer, NULL );
if( rc )
tty_printf(_("No such user ID.\n"));
- else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) {
+ else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+ pk->pubkey_usage)) ) {
if( have_def_rec ) {
if (key_present_in_pk_list(pk_list, pk) == 0) {
free_public_key(pk); pk = NULL;
@@ -940,7 +942,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
rc = get_pubkey_byname( NULL, pk, def_rec, NULL );
if( rc )
log_error(_("unknown default recipient `%s'\n"), def_rec );
- else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) {
+ else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+ pk->pubkey_usage)) ) {
PK_LIST r = gcry_xmalloc( sizeof *r );
r->pk = pk; pk = NULL;
r->next = pk_list;
@@ -966,7 +969,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
free_public_key( pk ); pk = NULL;
log_error(_("%s: skipped: %s\n"), remusr->d, gpg_errstr(rc) );
}
- else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
+ else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+ pk->pubkey_usage)) ) {
int trustlevel;
rc = check_trust( pk, &trustlevel, pk->namehash, NULL, NULL );
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 0be514eb3..2adb9ef4c 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -75,7 +75,6 @@ pk_check_secret_key( int algo, MPI *skey )
static int
do_check( PKT_secret_key *sk )
{
- byte *buffer;
u16 csum=0;
int i, res;
unsigned nbytes;
@@ -324,7 +323,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
GCRY_STRONG_RANDOM);
gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
- #warning FIXME: replace set/get buffer
+ /* FIXME: replace set/get buffer */
if( sk->version >= 4 ) {
byte *bufarr[GNUPG_MAX_NSKEY];
unsigned narr[GNUPG_MAX_NSKEY];
@@ -336,7 +335,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) {
assert( !gcry_mpi_get_flag( sk->skey[i], GCRYMPI_FLAG_OPAQUE ) );
- if( gcry_mpi_aprint( GCRYMPI_FMT_USG, (char*)bufarr+j,
+ if( gcry_mpi_aprint( GCRYMPI_FMT_USG, (void**)bufarr+j,
narr+j, sk->skey[i]))
BUG();
@@ -374,7 +373,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
else {
/* NOTE: we always recalculate the checksum because there
* are some test releases which calculated it wrong */
- #warning FIXME: Replace this code
+ /* FIXME: Replace this code -- Hmmm: why */
csum = 0;
for(i=pubkey_get_npkey(sk->pubkey_algo);
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
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);
diff --git a/g10/skclist.c b/g10/skclist.c
index 5c6d6fbd7..dceba71f8 100644
--- a/g10/skclist.c
+++ b/g10/skclist.c
@@ -50,7 +50,7 @@ release_sk_list( SK_LIST sk_list )
int
build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
- unsigned use )
+ unsigned int use )
{
SK_LIST sk_list = NULL;
int rc;
@@ -64,9 +64,11 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
free_secret_key( sk ); sk = NULL;
log_error("no default secret key: %s\n", gpg_errstr(rc) );
}
- else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) {
+ else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo,
+ sk->pubkey_usage)) ) {
SK_LIST r;
- if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN )
+
+ if( sk->version == 4 && (sk->pubkey_usage & GCRY_PK_USAGE_SIGN )
&& sk->pubkey_algo == GCRY_PK_ELG_E ) {
log_info("this is a PGP generated "
"ElGamal key which is NOT secure for signatures!\n");
@@ -95,9 +97,10 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
free_secret_key( sk ); sk = NULL;
log_error(_("skipped `%s': %s\n"), locusr->d, gpg_errstr(rc) );
}
- else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) {
+ else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo,
+ sk->pubkey_usage)) ) {
SK_LIST r;
- if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN)
+ if( sk->version == 4 && (sk->pubkey_usage & GCRY_PK_USAGE_SIGN)
&& sk->pubkey_algo == GCRY_PK_ELG_E ) {
log_info(_("skipped `%s': this is a PGP generated "
"ElGamal key which is not secure for signatures!\n"),
diff --git a/g10/status.c b/g10/status.c
index 2eb6724f3..d336ae3b0 100644
--- a/g10/status.c
+++ b/g10/status.c
@@ -74,8 +74,9 @@ set_status_fd ( int newfd )
{
fd = newfd;
if ( fd != -1 ) {
- #if 0
#warning fixme - progress functions
+ /* Has to be fixed in libgcrypt */
+ #if 0
register_primegen_progress ( progress_cb, "primegen" );
register_pk_dsa_progress ( progress_cb, "pk_dsa" );
register_pk_elg_progress ( progress_cb, "pk_elg" );