aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/mainproc.c1963
-rw-r--r--g10/openfile.c241
2 files changed, 1153 insertions, 1051 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 19f1aac5e..bc186d3f9 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -1,7 +1,6 @@
/* mainproc.c - handle packets
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- * 2008, 2009 Free Software Foundation, Inc.
- * Copyright (C) 2013, 2014 Werner Koch
+ * Copyright (C) 1998-2009 Free Software Foundation, Inc.
+ * Copyright (C) 2013-2014 Werner Koch
*
* This file is part of GnuPG.
*
@@ -47,16 +46,18 @@
#define MAX_NESTING_DEPTH 32
-struct kidlist_item {
- struct kidlist_item *next;
- u32 kid[2];
- int pubkey_algo;
- int reason;
+/* An object to build a list of keyid related info. */
+struct kidlist_item
+{
+ struct kidlist_item *next;
+ u32 kid[2];
+ int pubkey_algo;
+ int reason;
};
-/****************
- * Structure to hold the context
+/*
+ * Object to hold the processing context.
*/
typedef struct mainproc_context *CTX;
struct mainproc_context
@@ -90,8 +91,8 @@ struct mainproc_context
DEK *dek;
int last_was_session_key;
- KBNODE list; /* The current list of packets. */
- IOBUF iobuf; /* Used to get the filename etc. */
+ kbnode_t list; /* The current list of packets. */
+ iobuf_t iobuf; /* Used to get the filename etc. */
int trustletter; /* Temporary usage in list_node. */
ulong symkeys;
struct kidlist_item *pkenc_list; /* List of encryption packets. */
@@ -104,135 +105,150 @@ struct mainproc_context
};
-static int do_proc_packets( CTX c, IOBUF a );
-static void list_node( CTX c, KBNODE node );
-static void proc_tree( CTX c, KBNODE node );
+/*** Local prototypes. ***/
+static int do_proc_packets (CTX c, iobuf_t a);
+static void list_node (CTX c, kbnode_t node);
+static void proc_tree (CTX c, kbnode_t node);
static int literals_seen;
+
+/*** Functions. ***/
+
+
void
reset_literals_seen(void)
{
- literals_seen=0;
+ literals_seen = 0;
}
+
static void
release_list( CTX c )
{
- if( !c->list )
- return;
- proc_tree(c, c->list );
- release_kbnode( c->list );
- while( c->pkenc_list ) {
- struct kidlist_item *tmp = c->pkenc_list->next;
- xfree( c->pkenc_list );
- c->pkenc_list = tmp;
+ if (!c->list)
+ return;
+ proc_tree (c, c->list);
+ release_kbnode (c->list);
+ while (c->pkenc_list)
+ {
+ struct kidlist_item *tmp = c->pkenc_list->next;
+ xfree (c->pkenc_list);
+ c->pkenc_list = tmp;
}
- c->pkenc_list = NULL;
- c->list = NULL;
- c->any.data = 0;
- c->any.uncompress_failed = 0;
- c->last_was_session_key = 0;
- xfree(c->dek); c->dek = NULL;
+ c->pkenc_list = NULL;
+ c->list = NULL;
+ c->any.data = 0;
+ c->any.uncompress_failed = 0;
+ c->last_was_session_key = 0;
+ xfree (c->dek);
+ c->dek = NULL;
}
static int
-add_onepass_sig( CTX c, PACKET *pkt )
+add_onepass_sig (CTX c, PACKET *pkt)
{
- KBNODE node;
+ kbnode_t node;
- if ( c->list ) /* add another packet */
- add_kbnode( c->list, new_kbnode( pkt ));
- else /* insert the first one */
- c->list = node = new_kbnode( pkt );
+ if (c->list) /* Add another packet. */
+ add_kbnode (c->list, new_kbnode (pkt));
+ else /* Insert the first one. */
+ c->list = node = new_kbnode (pkt);
return 1;
}
static int
-add_gpg_control( CTX c, PACKET *pkt )
+add_gpg_control (CTX c, PACKET *pkt)
{
- if ( pkt->pkt.gpg_control->control == CTRLPKT_CLEARSIGN_START ) {
- /* New clear text signature.
- * Process the last one and reset everything */
- release_list(c);
+ if ( pkt->pkt.gpg_control->control == CTRLPKT_CLEARSIGN_START )
+ {
+ /* New clear text signature.
+ * Process the last one and reset everything */
+ release_list(c);
}
- if( c->list ) /* add another packet */
- add_kbnode( c->list, new_kbnode( pkt ));
- else /* insert the first one */
- c->list = new_kbnode( pkt );
+ if (c->list) /* Add another packet. */
+ add_kbnode (c->list, new_kbnode (pkt));
+ else /* Insert the first one. */
+ c->list = new_kbnode (pkt);
- return 1;
+ return 1;
}
-
static int
-add_user_id( CTX c, PACKET *pkt )
+add_user_id (CTX c, PACKET *pkt)
{
- if( !c->list ) {
- log_error("orphaned user ID\n" );
- return 0;
+ if (!c->list)
+ {
+ log_error ("orphaned user ID\n");
+ return 0;
}
- add_kbnode( c->list, new_kbnode( pkt ) );
- return 1;
+ add_kbnode (c->list, new_kbnode (pkt));
+ return 1;
}
+
static int
-add_subkey( CTX c, PACKET *pkt )
+add_subkey (CTX c, PACKET *pkt)
{
- if( !c->list ) {
- log_error("subkey w/o mainkey\n" );
- return 0;
+ if (!c->list)
+ {
+ log_error ("subkey w/o mainkey\n");
+ return 0;
}
- add_kbnode( c->list, new_kbnode( pkt ) );
- return 1;
+ add_kbnode (c->list, new_kbnode (pkt));
+ return 1;
}
+
static int
-add_ring_trust( CTX c, PACKET *pkt )
+add_ring_trust (CTX c, PACKET *pkt)
{
- if( !c->list ) {
- log_error("ring trust w/o key\n" );
- return 0;
+ if (!c->list)
+ {
+ log_error ("ring trust w/o key\n");
+ return 0;
}
- add_kbnode( c->list, new_kbnode( pkt ) );
- return 1;
+ add_kbnode (c->list, new_kbnode (pkt));
+ return 1;
}
static int
-add_signature( CTX c, PACKET *pkt )
+add_signature (CTX c, PACKET *pkt)
{
- KBNODE node;
-
- c->any.sig_seen = 1;
- if( pkt->pkttype == PKT_SIGNATURE && !c->list ) {
- /* This is the first signature for the following datafile.
- * GPG does not write such packets; instead it always uses
- * onepass-sig packets. The drawback of PGP's method
- * of prepending the signature to the data is
- * that it is not possible to make a signature from data read
- * from stdin. (GPG is able to read PGP stuff anyway.) */
- node = new_kbnode( pkt );
- c->list = node;
- return 1;
+ kbnode_t node;
+
+ c->any.sig_seen = 1;
+ if (pkt->pkttype == PKT_SIGNATURE && !c->list)
+ {
+ /* This is the first signature for the following datafile.
+ * GPG does not write such packets; instead it always uses
+ * onepass-sig packets. The drawback of PGP's method
+ * of prepending the signature to the data is
+ * that it is not possible to make a signature from data read
+ * from stdin. (GPG is able to read PGP stuff anyway.) */
+ node = new_kbnode (pkt);
+ c->list = node;
+ return 1;
}
- else if( !c->list )
- return 0; /* oops (invalid packet sequence)*/
- else if( !c->list->pkt )
- BUG(); /* so nicht */
-
- /* add a new signature node id at the end */
- node = new_kbnode( pkt );
- add_kbnode( c->list, node );
- return 1;
+ else if (!c->list)
+ return 0; /* oops (invalid packet sequence)*/
+ else if (!c->list->pkt)
+ BUG(); /* so nicht */
+
+ /* Add a new signature node item at the end. */
+ node = new_kbnode (pkt);
+ add_kbnode (c->list, node);
+
+ return 1;
}
static int
-symkey_decrypt_seskey( DEK *dek, byte *seskey, size_t slen )
+symkey_decrypt_seskey (DEK *dek, byte *seskey, size_t slen)
{
gcry_cipher_hd_t hd;
@@ -267,132 +283,137 @@ symkey_decrypt_seskey( DEK *dek, byte *seskey, size_t slen )
return 0;
}
+
static void
-proc_symkey_enc( CTX c, PACKET *pkt )
+proc_symkey_enc (CTX c, PACKET *pkt)
{
- PKT_symkey_enc *enc;
+ PKT_symkey_enc *enc;
- enc = pkt->pkt.symkey_enc;
- if (!enc)
- log_error ("invalid symkey encrypted packet\n");
- else if(!c->dek)
- {
- int algo = enc->cipher_algo;
- const char *s = openpgp_cipher_algo_name (algo);
-
- if (!openpgp_cipher_test_algo (algo))
- {
- if(!opt.quiet)
- {
- if(enc->seskeylen)
- log_info(_("%s encrypted session key\n"), s );
- else
- log_info(_("%s encrypted data\n"), s );
- }
- }
- else
- log_error(_("encrypted with unknown algorithm %d\n"), algo );
-
- if(openpgp_md_test_algo (enc->s2k.hash_algo))
- {
- log_error(_("passphrase generated with unknown digest"
- " algorithm %d\n"),enc->s2k.hash_algo);
- s=NULL;
- }
-
- c->last_was_session_key = 2;
- if(!s || opt.list_only)
- goto leave;
-
- if(opt.override_session_key)
- {
- c->dek = xmalloc_clear( sizeof *c->dek );
- if(get_override_session_key(c->dek, opt.override_session_key))
- {
- xfree(c->dek);
- c->dek = NULL;
- }
- }
- else
- {
- c->dek = passphrase_to_dek (NULL, 0, algo, &enc->s2k, 3,
- NULL, NULL);
- if(c->dek)
- {
- c->dek->symmetric=1;
-
- /* FIXME: This doesn't work perfectly if a symmetric
- key comes before a public key in the message - if
- the user doesn't know the passphrase, then there is
- a chance that the "decrypted" algorithm will happen
- to be a valid one, which will make the returned dek
- appear valid, so we won't try any public keys that
- come later. */
- if(enc->seskeylen)
- {
- if(symkey_decrypt_seskey(c->dek, enc->seskey,
- enc->seskeylen))
- {
- xfree(c->dek);
- c->dek=NULL;
- }
- }
- else
- c->dek->algo_info_printed = 1;
- }
- }
- }
+ enc = pkt->pkt.symkey_enc;
+ if (!enc)
+ log_error ("invalid symkey encrypted packet\n");
+ else if(!c->dek)
+ {
+ int algo = enc->cipher_algo;
+ const char *s = openpgp_cipher_algo_name (algo);
+
+ if (!openpgp_cipher_test_algo (algo))
+ {
+ if (!opt.quiet)
+ {
+ if (enc->seskeylen)
+ log_info (_("%s encrypted session key\n"), s );
+ else
+ log_info (_("%s encrypted data\n"), s );
+ }
+ }
+ else
+ log_error (_("encrypted with unknown algorithm %d\n"), algo);
+
+ if (openpgp_md_test_algo (enc->s2k.hash_algo))
+ {
+ log_error(_("passphrase generated with unknown digest"
+ " algorithm %d\n"),enc->s2k.hash_algo);
+ s = NULL;
+ }
+
+ c->last_was_session_key = 2;
+ if (!s || opt.list_only)
+ goto leave;
+
+ if (opt.override_session_key)
+ {
+ c->dek = xmalloc_clear (sizeof *c->dek);
+ if (get_override_session_key (c->dek, opt.override_session_key))
+ {
+ xfree (c->dek);
+ c->dek = NULL;
+ }
+ }
+ else
+ {
+ c->dek = passphrase_to_dek (NULL, 0, algo, &enc->s2k, 3, NULL, NULL);
+ if (c->dek)
+ {
+ c->dek->symmetric = 1;
+
+ /* FIXME: This doesn't work perfectly if a symmetric key
+ comes before a public key in the message - if the
+ user doesn't know the passphrase, then there is a
+ chance that the "decrypted" algorithm will happen to
+ be a valid one, which will make the returned dek
+ appear valid, so we won't try any public keys that
+ come later. */
+ if (enc->seskeylen)
+ {
+ if (symkey_decrypt_seskey (c->dek,
+ enc->seskey, enc->seskeylen))
+ {
+ xfree (c->dek);
+ c->dek = NULL;
+ }
+ }
+ else
+ c->dek->algo_info_printed = 1;
+ }
+ }
+ }
leave:
- c->symkeys++;
- free_packet(pkt);
+ c->symkeys++;
+ free_packet (pkt);
}
+
static void
-proc_pubkey_enc( CTX c, PACKET *pkt )
+proc_pubkey_enc (CTX c, PACKET *pkt)
{
- PKT_pubkey_enc *enc;
- int result = 0;
-
- /* check whether the secret key is available and store in this case */
- c->last_was_session_key = 1;
- enc = pkt->pkt.pubkey_enc;
- /*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
- /* Hmmm: why do I have this algo check here - anyway there is
- * function to check it. */
- if( opt.verbose )
- log_info(_("public key is %s\n"), keystr(enc->keyid) );
-
- if( is_status_enabled() ) {
- char buf[50];
- /* FIXME: For ECC support we need to map the OpenPGP algo
- number to the Libgcrypt definef one. This is due a
- chicken-egg problem: We need to have code in libgcrypt for
- a new algorithm so to implement a proposed new algorithm
- before the IANA will finally assign an OpenPGP
- indentifier. */
- snprintf (buf, sizeof buf, "%08lX%08lX %d 0",
- (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo );
- write_status_text( STATUS_ENC_TO, buf );
+ PKT_pubkey_enc *enc;
+ int result = 0;
+
+ /* Check whether the secret key is available and store in this case. */
+ c->last_was_session_key = 1;
+ enc = pkt->pkt.pubkey_enc;
+ /*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
+ /* Hmmm: why do I have this algo check here - anyway there is
+ * function to check it. */
+ if (opt.verbose)
+ log_info (_("public key is %s\n"), keystr (enc->keyid));
+
+ if (is_status_enabled())
+ {
+ char buf[50];
+ /* FIXME: For ECC support we need to map the OpenPGP algo number
+ to the Libgcrypt defined one. This is due a chicken-egg
+ problem: We need to have code in Libgcrypt for a new
+ algorithm so to implement a proposed new algorithm before the
+ IANA will finally assign an OpenPGP indentifier. */
+ snprintf (buf, sizeof buf, "%08lX%08lX %d 0",
+ (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo);
+ write_status_text (STATUS_ENC_TO, buf);
}
- if( !opt.list_only && opt.override_session_key ) {
- /* It does not make much sense to store the session key in
- * secure memory because it has already been passed on the
- * command line and the GCHQ knows about it. */
- c->dek = xmalloc_clear( sizeof *c->dek );
- result = get_override_session_key ( c->dek, opt.override_session_key );
- if ( result ) {
- xfree(c->dek); c->dek = NULL;
+ if (!opt.list_only && opt.override_session_key)
+ {
+ /* It does not make much sense to store the session key in
+ * secure memory because it has already been passed on the
+ * command line and the GCHQ knows about it. */
+ c->dek = xmalloc_clear (sizeof *c->dek);
+ result = get_override_session_key (c->dek, opt.override_session_key);
+ if (result)
+ {
+ xfree (c->dek);
+ c->dek = NULL;
}
}
- else if( is_ELGAMAL(enc->pubkey_algo)
- || enc->pubkey_algo == PUBKEY_ALGO_DSA
- || enc->pubkey_algo == PUBKEY_ALGO_ECDSA
- || enc->pubkey_algo == PUBKEY_ALGO_EDDSA
- || enc->pubkey_algo == PUBKEY_ALGO_ECDH
- || is_RSA(enc->pubkey_algo)
- || enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL) {
+ else if (is_ELGAMAL(enc->pubkey_algo)
+ || enc->pubkey_algo == PUBKEY_ALGO_DSA
+ || enc->pubkey_algo == PUBKEY_ALGO_ECDSA
+ || enc->pubkey_algo == PUBKEY_ALGO_EDDSA
+ || enc->pubkey_algo == PUBKEY_ALGO_ECDH
+ || is_RSA (enc->pubkey_algo)
+ || enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL)
+ {
/* Note that we also allow type 20 Elgamal keys for decryption.
There are still a couple of those keys in active use as a
subkey. */
@@ -400,341 +421,352 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
/* FIXME: Store this all in a list and process it later so that
we can prioritize what key to use. This gives a better user
experience if wildcard keyids are used. */
- if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
- || opt.try_all_secrets
- || have_secret_key_with_kid (enc->keyid)) ) {
- if( opt.list_only )
- result = -1;
- else {
- c->dek = xmalloc_secure_clear( sizeof *c->dek );
- if( (result = get_session_key( enc, c->dek )) ) {
- /* error: delete the DEK */
- xfree(c->dek); c->dek = NULL;
+ if (!c->dek && ((!enc->keyid[0] && !enc->keyid[1])
+ || opt.try_all_secrets
+ || have_secret_key_with_kid (enc->keyid)))
+ {
+ if(opt.list_only)
+ result = -1;
+ else
+ {
+ c->dek = xmalloc_secure_clear (sizeof *c->dek);
+ if ((result = get_session_key (enc, c->dek)))
+ {
+ /* Error: Delete the DEK. */
+ xfree (c->dek);
+ c->dek = NULL;
}
}
}
- else
- result = G10ERR_NO_SECKEY;
+ else
+ result = G10ERR_NO_SECKEY;
}
- else
- result = G10ERR_PUBKEY_ALGO;
+ else
+ result = G10ERR_PUBKEY_ALGO;
- if( result == -1 )
- ;
- else
- {
- /* store it for later display */
- struct kidlist_item *x = xmalloc( sizeof *x );
- x->kid[0] = enc->keyid[0];
- x->kid[1] = enc->keyid[1];
- x->pubkey_algo = enc->pubkey_algo;
- x->reason = result;
- x->next = c->pkenc_list;
- c->pkenc_list = x;
-
- if( !result && opt.verbose > 1 )
- log_info( _("public key encrypted data: good DEK\n") );
- }
+ if (result == -1)
+ ;
+ else
+ {
+ /* Store it for later display. */
+ struct kidlist_item *x = xmalloc (sizeof *x);
+ x->kid[0] = enc->keyid[0];
+ x->kid[1] = enc->keyid[1];
+ x->pubkey_algo = enc->pubkey_algo;
+ x->reason = result;
+ x->next = c->pkenc_list;
+ c->pkenc_list = x;
+
+ if (!result && opt.verbose > 1)
+ log_info (_("public key encrypted data: good DEK\n"));
+ }
- free_packet(pkt);
+ free_packet(pkt);
}
-
-/****************
+/*
* Print the list of public key encrypted packets which we could
* not decrypt.
*/
static void
-print_pkenc_list( struct kidlist_item *list, int failed )
+print_pkenc_list (struct kidlist_item *list, int failed)
{
- for( ; list; list = list->next ) {
- PKT_public_key *pk;
- const char *algstr;
+ for (; list; list = list->next)
+ {
+ PKT_public_key *pk;
+ const char *algstr;
- if ( failed && !list->reason )
- continue;
- if ( !failed && list->reason )
- continue;
+ if (failed && !list->reason)
+ continue;
+ if (!failed && list->reason)
+ continue;
+
+ algstr = openpgp_pk_algo_name (list->pubkey_algo);
+ pk = xmalloc_clear (sizeof *pk);
+
+ if (!algstr)
+ algstr = "[?]";
+ pk->pubkey_algo = list->pubkey_algo;
+ if (!get_pubkey (pk, list->kid))
+ {
+ char *p;
+ log_info (_("encrypted with %u-bit %s key, ID %s, created %s\n"),
+ nbits_from_pk (pk), algstr, keystr_from_pk(pk),
+ strtimestamp (pk->timestamp));
+ p = get_user_id_native (list->kid);
+ log_printf (_(" \"%s\"\n"), p);
+ xfree (p);
+ }
+ else
+ log_info (_("encrypted with %s key, ID %s\n"),
+ algstr, keystr(list->kid));
- algstr = openpgp_pk_algo_name ( list->pubkey_algo );
- pk = xmalloc_clear( sizeof *pk );
-
- if( !algstr )
- algstr = "[?]";
- pk->pubkey_algo = list->pubkey_algo;
- if( !get_pubkey( pk, list->kid ) )
- {
- char *p;
- log_info( _("encrypted with %u-bit %s key, ID %s, created %s\n"),
- nbits_from_pk( pk ), algstr, keystr_from_pk(pk),
- strtimestamp(pk->timestamp) );
- p=get_user_id_native(list->kid);
- log_printf (_(" \"%s\"\n"),p);
- xfree(p);
- }
- else
- log_info(_("encrypted with %s key, ID %s\n"),
- algstr,keystr(list->kid));
-
- free_public_key( pk );
-
- if( list->reason == G10ERR_NO_SECKEY ) {
- if( is_status_enabled() ) {
- char buf[20];
- snprintf (buf, sizeof buf, "%08lX%08lX",
- (ulong)list->kid[0], (ulong)list->kid[1]);
- write_status_text( STATUS_NO_SECKEY, buf );
+ free_public_key (pk);
+
+ if (list->reason == G10ERR_NO_SECKEY)
+ {
+ if (is_status_enabled())
+ {
+ char buf[20];
+ snprintf (buf, sizeof buf, "%08lX%08lX",
+ (ulong)list->kid[0], (ulong)list->kid[1]);
+ write_status_text (STATUS_NO_SECKEY, buf);
}
}
- else if (list->reason)
- {
- log_info(_("public key decryption failed: %s\n"),
- g10_errstr(list->reason));
- write_status_error ("pkdecrypt_failed", list->reason);
- }
+ else if (list->reason)
+ {
+ log_info (_("public key decryption failed: %s\n"),
+ g10_errstr(list->reason));
+ write_status_error ("pkdecrypt_failed", list->reason);
+ }
}
}
static void
-proc_encrypted( CTX c, PACKET *pkt )
+proc_encrypted (CTX c, PACKET *pkt)
{
- int result = 0;
+ int result = 0;
- if (!opt.quiet)
- {
- if(c->symkeys>1)
- log_info(_("encrypted with %lu passphrases\n"),c->symkeys);
- else if(c->symkeys==1)
- log_info(_("encrypted with 1 passphrase\n"));
- print_pkenc_list ( c->pkenc_list, 1 );
- print_pkenc_list ( c->pkenc_list, 0 );
- }
+ if (!opt.quiet)
+ {
+ if (c->symkeys>1)
+ log_info (_("encrypted with %lu passphrases\n"), c->symkeys);
+ else if (c->symkeys == 1)
+ log_info (_("encrypted with 1 passphrase\n"));
+ print_pkenc_list ( c->pkenc_list, 1 );
+ print_pkenc_list ( c->pkenc_list, 0 );
+ }
- /* FIXME: Figure out the session key by looking at all pkenc packets. */
-
-
- write_status( STATUS_BEGIN_DECRYPTION );
-
- /*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
- if( opt.list_only )
- result = -1;
- else if( !c->dek && !c->last_was_session_key ) {
- int algo;
- STRING2KEY s2kbuf, *s2k = NULL;
-
- if(opt.override_session_key)
- {
- c->dek = xmalloc_clear( sizeof *c->dek );
- result=get_override_session_key(c->dek, opt.override_session_key);
- if(result)
- {
- xfree(c->dek);
- c->dek = NULL;
- }
- }
- else
- {
- /* Assume this is old style conventional encrypted data. */
- algo = opt.def_cipher_algo;
- if ( algo )
- log_info (_("assuming %s encrypted data\n"),
+ /* FIXME: Figure out the session key by looking at all pkenc packets. */
+
+ write_status (STATUS_BEGIN_DECRYPTION);
+
+ /*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
+ if (opt.list_only)
+ result = -1;
+ else if (!c->dek && !c->last_was_session_key)
+ {
+ int algo;
+ STRING2KEY s2kbuf;
+ STRING2KEY *s2k = NULL;
+
+ if (opt.override_session_key)
+ {
+ c->dek = xmalloc_clear (sizeof *c->dek);
+ result = get_override_session_key (c->dek, opt.override_session_key);
+ if (result)
+ {
+ xfree (c->dek);
+ c->dek = NULL;
+ }
+ }
+ else
+ {
+ /* Assume this is old style conventional encrypted data. */
+ algo = opt.def_cipher_algo;
+ if (algo)
+ log_info (_("assuming %s encrypted data\n"),
+ openpgp_cipher_algo_name (algo));
+ else if (openpgp_cipher_test_algo (CIPHER_ALGO_IDEA))
+ {
+ algo = opt.def_cipher_algo;
+ if (!algo)
+ algo = opt.s2k_cipher_algo;
+ log_info (_("IDEA cipher unavailable, "
+ "optimistically attempting to use %s instead\n"),
openpgp_cipher_algo_name (algo));
- else if ( openpgp_cipher_test_algo (CIPHER_ALGO_IDEA) )
- {
- algo = opt.def_cipher_algo;
- if (!algo)
- algo = opt.s2k_cipher_algo;
- log_info (_("IDEA cipher unavailable, "
- "optimistically attempting to use %s instead\n"),
- openpgp_cipher_algo_name (algo));
- }
- else
- {
- algo = CIPHER_ALGO_IDEA;
- if (!opt.s2k_digest_algo)
- {
- /* If no digest is given we assume SHA-1. */
- s2kbuf.mode = 0;
- s2kbuf.hash_algo = DIGEST_ALGO_SHA1;
- s2k = &s2kbuf;
- }
- log_info (_("assuming %s encrypted data\n"), "IDEA");
- }
-
- c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 3, NULL, NULL );
- if (c->dek)
- c->dek->algo_info_printed = 1;
- }
+ }
+ else
+ {
+ algo = CIPHER_ALGO_IDEA;
+ if (!opt.s2k_digest_algo)
+ {
+ /* If no digest is given we assume SHA-1. */
+ s2kbuf.mode = 0;
+ s2kbuf.hash_algo = DIGEST_ALGO_SHA1;
+ s2k = &s2kbuf;
+ }
+ log_info (_("assuming %s encrypted data\n"), "IDEA");
+ }
+
+ c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 3, NULL, NULL );
+ if (c->dek)
+ c->dek->algo_info_printed = 1;
+ }
}
- else if( !c->dek )
- result = G10ERR_NO_SECKEY;
-
- if (!result)
- result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
-
- if( result == -1 )
- ;
- else if( !result || (gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE
- && opt.ignore_mdc_error)) {
- write_status( STATUS_DECRYPTION_OKAY );
- if( opt.verbose > 1 )
- log_info(_("decryption okay\n"));
- if( pkt->pkt.encrypted->mdc_method && !result )
- write_status( STATUS_GOODMDC );
- else if(!opt.no_mdc_warn)
- log_info (_("WARNING: message was not integrity protected\n"));
+ else if( !c->dek )
+ result = G10ERR_NO_SECKEY;
+
+ if (!result)
+ result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
+
+ if (result == -1)
+ ;
+ else if (!result || (gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE
+ && opt.ignore_mdc_error))
+ {
+ write_status (STATUS_DECRYPTION_OKAY);
+ if (opt.verbose > 1)
+ log_info(_("decryption okay\n"));
+ if (pkt->pkt.encrypted->mdc_method && !result)
+ write_status (STATUS_GOODMDC);
+ else if (!opt.no_mdc_warn)
+ log_info (_("WARNING: message was not integrity protected\n"));
}
- else if( result == G10ERR_BAD_SIGN ) {
- glo_ctrl.lasterr = result;
- log_error(_("WARNING: encrypted message has been manipulated!\n"));
- write_status( STATUS_BADMDC );
- write_status( STATUS_DECRYPTION_FAILED );
+ else if (result == G10ERR_BAD_SIGN)
+ {
+ glo_ctrl.lasterr = result;
+ log_error (_("WARNING: encrypted message has been manipulated!\n"));
+ write_status (STATUS_BADMDC);
+ write_status (STATUS_DECRYPTION_FAILED);
}
- else {
- if (gpg_err_code (result) == GPG_ERR_BAD_KEY
- && *c->dek->s2k_cacheid != '\0')
- {
- log_debug(_("cleared passphrase cached with ID: %s\n"),
- c->dek->s2k_cacheid);
- passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0);
- }
- glo_ctrl.lasterr = result;
- write_status( STATUS_DECRYPTION_FAILED );
- log_error(_("decryption failed: %s\n"), g10_errstr(result));
- /* Hmmm: does this work when we have encrypted using multiple
- * ways to specify the session key (symmmetric and PK)*/
+ else
+ {
+ if (gpg_err_code (result) == GPG_ERR_BAD_KEY
+ && *c->dek->s2k_cacheid != '\0')
+ {
+ log_debug (_("cleared passphrase cached with ID: %s\n"),
+ c->dek->s2k_cacheid);
+ passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0);
+ }
+ glo_ctrl.lasterr = result;
+ write_status (STATUS_DECRYPTION_FAILED);
+ log_error (_("decryption failed: %s\n"), g10_errstr(result));
+ /* Hmmm: does this work when we have encrypted using multiple
+ * ways to specify the session key (symmmetric and PK). */
}
- xfree(c->dek); c->dek = NULL;
- free_packet(pkt);
- c->last_was_session_key = 0;
- write_status( STATUS_END_DECRYPTION );
+
+ xfree (c->dek);
+ c->dek = NULL;
+ free_packet (pkt);
+ c->last_was_session_key = 0;
+ write_status (STATUS_END_DECRYPTION);
}
static void
proc_plaintext( CTX c, PACKET *pkt )
{
- PKT_plaintext *pt = pkt->pkt.plaintext;
- int any, clearsig, rc;
- KBNODE n;
-
- literals_seen++;
-
- if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) )
- log_info(_("Note: sender requested \"for-your-eyes-only\"\n"));
- else if( opt.verbose )
- log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name);
- free_md_filter_context( &c->mfx );
- if (gcry_md_open (&c->mfx.md, 0, 0))
- BUG ();
- /* fixme: we may need to push the textfilter if we have sigclass 1
- * and no armoring - Not yet tested
- * Hmmm, why don't we need it at all if we have sigclass 1
- * Should we assume that plaintext in mode 't' has always sigclass 1??
- * See: Russ Allbery's mail 1999-02-09
- */
- any = clearsig = 0;
- for(n=c->list; n; n = n->next )
- {
- if( n->pkt->pkttype == PKT_ONEPASS_SIG )
- {
- /* For the onepass signature case */
- if( n->pkt->pkt.onepass_sig->digest_algo )
- {
- gcry_md_enable (c->mfx.md,
- n->pkt->pkt.onepass_sig->digest_algo);
- any = 1;
- }
- }
- else if( n->pkt->pkttype == PKT_GPG_CONTROL
- && n->pkt->pkt.gpg_control->control
- == CTRLPKT_CLEARSIGN_START )
- {
- /* For the clearsigned message case */
- size_t datalen = n->pkt->pkt.gpg_control->datalen;
- const byte *data = n->pkt->pkt.gpg_control->data;
-
- /* check that we have at least the sigclass and one hash */
- if ( datalen < 2 )
- log_fatal("invalid control packet CTRLPKT_CLEARSIGN_START\n");
- /* Note that we don't set the clearsig flag for not-dash-escaped
- * documents */
- clearsig = (*data == 0x01);
- for( data++, datalen--; datalen; datalen--, data++ )
- gcry_md_enable (c->mfx.md, *data);
- any = 1;
- break; /* Stop here as one-pass signature packets are not
- expected. */
- }
- else if(n->pkt->pkttype==PKT_SIGNATURE)
- {
- /* For the SIG+LITERAL case that PGP used to use. */
- gcry_md_enable ( c->mfx.md, n->pkt->pkt.signature->digest_algo );
- any=1;
- }
- }
+ PKT_plaintext *pt = pkt->pkt.plaintext;
+ int any, clearsig, rc;
+ kbnode_t n;
- if( !any && !opt.skip_verify )
- {
- /* This is for the old GPG LITERAL+SIG case. It's not legal
- according to 2440, so hopefully it won't come up that
- often. There is no good way to specify what algorithms to
- use in that case, so these three are the historical
- answer. */
- gcry_md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
- gcry_md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
- }
- if ( DBG_HASHING ) {
- gcry_md_debug ( c->mfx.md, "verify" );
- if ( c->mfx.md2 )
- gcry_md_debug ( c->mfx.md2, "verify2" );
+ literals_seen++;
+
+ if (pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8))
+ log_info (_("Note: sender requested \"for-your-eyes-only\"\n"));
+ else if (opt.verbose)
+ log_info (_("original file name='%.*s'\n"), pt->namelen, pt->name);
+
+ free_md_filter_context (&c->mfx);
+ if (gcry_md_open (&c->mfx.md, 0, 0))
+ BUG ();
+ /* fixme: we may need to push the textfilter if we have sigclass 1
+ * and no armoring - Not yet tested
+ * Hmmm, why don't we need it at all if we have sigclass 1
+ * Should we assume that plaintext in mode 't' has always sigclass 1??
+ * See: Russ Allbery's mail 1999-02-09
+ */
+ any = clearsig = 0;
+ for (n=c->list; n; n = n->next )
+ {
+ if (n->pkt->pkttype == PKT_ONEPASS_SIG)
+ {
+ /* The onepass signature case. */
+ if (n->pkt->pkt.onepass_sig->digest_algo)
+ {
+ gcry_md_enable (c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo);
+ any = 1;
+ }
+ }
+ else if (n->pkt->pkttype == PKT_GPG_CONTROL
+ && n->pkt->pkt.gpg_control->control == CTRLPKT_CLEARSIGN_START)
+ {
+ /* The clearsigned message case. */
+ size_t datalen = n->pkt->pkt.gpg_control->datalen;
+ const byte *data = n->pkt->pkt.gpg_control->data;
+
+ /* Check that we have at least the sigclass and one hash. */
+ if (datalen < 2)
+ log_fatal ("invalid control packet CTRLPKT_CLEARSIGN_START\n");
+ /* Note that we don't set the clearsig flag for not-dash-escaped
+ * documents. */
+ clearsig = (*data == 0x01);
+ for (data++, datalen--; datalen; datalen--, data++)
+ gcry_md_enable (c->mfx.md, *data);
+ any = 1;
+ break; /* Stop here as one-pass signature packets are not
+ expected. */
+ }
+ else if (n->pkt->pkttype == PKT_SIGNATURE)
+ {
+ /* The SIG+LITERAL case that PGP used to use. */
+ gcry_md_enable ( c->mfx.md, n->pkt->pkt.signature->digest_algo );
+ any = 1;
+ }
}
- rc=0;
+ if (!any && !opt.skip_verify)
+ {
+ /* This is for the old GPG LITERAL+SIG case. It's not legal
+ according to 2440, so hopefully it won't come up that often.
+ There is no good way to specify what algorithms to use in
+ that case, so these there are the historical answer. */
+ gcry_md_enable (c->mfx.md, DIGEST_ALGO_RMD160);
+ gcry_md_enable (c->mfx.md, DIGEST_ALGO_SHA1);
+ }
+ if (DBG_HASHING)
+ {
+ gcry_md_debug (c->mfx.md, "verify");
+ if (c->mfx.md2)
+ gcry_md_debug (c->mfx.md2, "verify2");
+ }
- if (literals_seen>1)
- {
- log_info (_("WARNING: multiple plaintexts seen\n"));
-
- if (!opt.flags.allow_multiple_messages)
- {
- write_status_text (STATUS_ERROR, "proc_pkt.plaintext 89_BAD_DATA");
- log_inc_errorcount ();
- rc = gpg_error (GPG_ERR_UNEXPECTED);
- }
- }
+ rc=0;
- if(!rc)
- {
- rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
- if ( gpg_err_code (rc) == GPG_ERR_EACCES && !c->sigs_only )
- {
- /* Can't write output but we hash it anyway to check the
- signature. */
- rc = handle_plaintext( pt, &c->mfx, 1, clearsig );
- }
- }
+ if (literals_seen > 1)
+ {
+ log_info (_("WARNING: multiple plaintexts seen\n"));
- if( rc )
- log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
- free_packet(pkt);
- c->last_was_session_key = 0;
-
- /* We add a marker control packet instead of the plaintext packet.
- * This is so that we can later detect invalid packet sequences.
- */
- n = new_kbnode (create_gpg_control (CTRLPKT_PLAINTEXT_MARK, NULL, 0));
- if (c->list)
- add_kbnode (c->list, n);
- else
- c->list = n;
+ if (!opt.flags.allow_multiple_messages)
+ {
+ write_status_text (STATUS_ERROR, "proc_pkt.plaintext 89_BAD_DATA");
+ log_inc_errorcount ();
+ rc = gpg_error (GPG_ERR_UNEXPECTED);
+ }
+ }
+
+ if (!rc)
+ {
+ rc = handle_plaintext (pt, &c->mfx, c->sigs_only, clearsig);
+ if (gpg_err_code (rc) == GPG_ERR_EACCES && !c->sigs_only)
+ {
+ /* Can't write output but we hash it anyway to check the
+ signature. */
+ rc = handle_plaintext( pt, &c->mfx, 1, clearsig );
+ }
+ }
+
+ if (rc)
+ log_error ("handle plaintext failed: %s\n", g10_errstr(rc));
+
+ free_packet(pkt);
+ c->last_was_session_key = 0;
+
+ /* We add a marker control packet instead of the plaintext packet.
+ * This is so that we can later detect invalid packet sequences. */
+ n = new_kbnode (create_gpg_control (CTRLPKT_PLAINTEXT_MARK, NULL, 0));
+ if (c->list)
+ add_kbnode (c->list, n);
+ else
+ c->list = n;
}
static int
-proc_compressed_cb( IOBUF a, void *info )
+proc_compressed_cb (iobuf_t a, void *info)
{
if ( ((CTX)info)->signed_data.used
&& ((CTX)info)->signed_data.data_fd != -1)
@@ -746,15 +778,17 @@ proc_compressed_cb( IOBUF a, void *info )
((CTX)info)->sigfilename );
}
+
static int
-proc_encrypt_cb (IOBUF a, void *info )
+proc_encrypt_cb (iobuf_t a, void *info )
{
CTX c = info;
return proc_encryption_packets (c->ctrl, info, a );
}
+
static int
-proc_compressed( CTX c, PACKET *pkt )
+proc_compressed (CTX c, PACKET *pkt)
{
PKT_compressed *zd = pkt->pkt.compressed;
int rc;
@@ -786,123 +820,135 @@ proc_compressed( CTX c, PACKET *pkt )
return rc;
}
-/****************
+
+/*
* check the signature
* Returns: 0 = valid signature or an error code
*/
static int
-do_check_sig( CTX c, KBNODE node, int *is_selfsig,
- int *is_expkey, int *is_revkey )
+do_check_sig (CTX c, kbnode_t node, int *is_selfsig,
+ int *is_expkey, int *is_revkey)
{
- PKT_signature *sig;
- gcry_md_hd_t md = NULL, md2 = NULL;
- int algo, rc;
-
- assert( node->pkt->pkttype == PKT_SIGNATURE );
- if( is_selfsig )
- *is_selfsig = 0;
- sig = node->pkt->pkt.signature;
-
- algo = sig->digest_algo;
- rc = openpgp_md_test_algo(algo);
- if (rc)
- return rc;
-
- if( sig->sig_class == 0x00 ) {
- if( c->mfx.md )
- {
- if (gcry_md_copy (&md, c->mfx.md ))
- BUG ();
- }
- else /* detached signature */
- {
- /* signature_check() will enable the md*/
- if (gcry_md_open (&md, 0, 0 ))
- BUG ();
- }
+ PKT_signature *sig;
+ gcry_md_hd_t md = NULL;
+ gcry_md_hd_t md2 = NULL;
+ int algo, rc;
+
+ assert (node->pkt->pkttype == PKT_SIGNATURE);
+ if (is_selfsig)
+ *is_selfsig = 0;
+ sig = node->pkt->pkt.signature;
+
+ algo = sig->digest_algo;
+ rc = openpgp_md_test_algo (algo);
+ if (rc)
+ return rc;
+
+ if (sig->sig_class == 0x00)
+ {
+ if (c->mfx.md)
+ {
+ if (gcry_md_copy (&md, c->mfx.md ))
+ BUG ();
+ }
+ else /* detached signature */
+ {
+ /* signature_check() will enable the md. */
+ if (gcry_md_open (&md, 0, 0 ))
+ BUG ();
+ }
}
- else if( sig->sig_class == 0x01 ) {
- /* how do we know that we have to hash the (already hashed) text
- * in canonical mode ??? (calculating both modes???) */
- if( c->mfx.md ) {
- if (gcry_md_copy (&md, c->mfx.md ))
- BUG ();
- if( c->mfx.md2 && gcry_md_copy (&md2, c->mfx.md2 ))
- BUG ();
+ else if (sig->sig_class == 0x01)
+ {
+ /* How do we know that we have to hash the (already hashed) text
+ in canonical mode ??? (calculating both modes???) */
+ if (c->mfx.md)
+ {
+ if (gcry_md_copy (&md, c->mfx.md ))
+ BUG ();
+ if (c->mfx.md2 && gcry_md_copy (&md2, c->mfx.md2))
+ BUG ();
}
- else { /* detached signature */
- log_debug("Do we really need this here?");
- /* signature_check() will enable the md*/
- if (gcry_md_open (&md, 0, 0 ))
- BUG ();
- if (gcry_md_open (&md2, 0, 0 ))
- BUG ();
+ else /* detached signature */
+ {
+ log_debug ("Do we really need this here?");
+ /* signature_check() will enable the md*/
+ if (gcry_md_open (&md, 0, 0 ))
+ BUG ();
+ if (gcry_md_open (&md2, 0, 0 ))
+ BUG ();
}
}
- else if( (sig->sig_class&~3) == 0x10
- || sig->sig_class == 0x18
- || sig->sig_class == 0x1f
- || sig->sig_class == 0x20
- || sig->sig_class == 0x28
- || sig->sig_class == 0x30 ) {
- if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
- || c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- return check_key_signature( c->list, node, is_selfsig );
+ else if ((sig->sig_class&~3) == 0x10
+ || sig->sig_class == 0x18
+ || sig->sig_class == 0x1f
+ || sig->sig_class == 0x20
+ || sig->sig_class == 0x28
+ || sig->sig_class == 0x30)
+ {
+ if (c->list->pkt->pkttype == PKT_PUBLIC_KEY
+ || c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+ {
+ return check_key_signature( c->list, node, is_selfsig );
}
- else if( sig->sig_class == 0x20 ) {
- log_error (_("standalone revocation - "
- "use \"gpg --import\" to apply\n"));
- return G10ERR_NOT_PROCESSED;
+ else if (sig->sig_class == 0x20)
+ {
+ log_error (_("standalone revocation - "
+ "use \"gpg --import\" to apply\n"));
+ return G10ERR_NOT_PROCESSED;
}
- else {
- log_error("invalid root packet for sigclass %02x\n",
- sig->sig_class);
- return G10ERR_SIG_CLASS;
+ else
+ {
+ log_error ("invalid root packet for sigclass %02x\n", sig->sig_class);
+ return G10ERR_SIG_CLASS;
}
}
- else
- return G10ERR_SIG_CLASS;
- rc = signature_check2( sig, md, NULL, is_expkey, is_revkey, NULL );
- if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2 )
- rc = signature_check2( sig, md2, NULL, is_expkey, is_revkey, NULL );
- gcry_md_close(md);
- gcry_md_close(md2);
+ else
+ return G10ERR_SIG_CLASS;
- return rc;
+ rc = signature_check2 (sig, md, NULL, is_expkey, is_revkey, NULL);
+ if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2)
+ rc = signature_check2 (sig, md2, NULL, is_expkey, is_revkey, NULL);
+
+ gcry_md_close (md);
+ gcry_md_close (md2);
+
+ return rc;
}
static void
-print_userid( PACKET *pkt )
+print_userid (PACKET *pkt)
{
- if( !pkt )
- BUG();
- if( pkt->pkttype != PKT_USER_ID ) {
- printf("ERROR: unexpected packet type %d", pkt->pkttype );
- return;
+ if (!pkt)
+ BUG();
+
+ if (pkt->pkttype != PKT_USER_ID)
+ {
+ printf ("ERROR: unexpected packet type %d", pkt->pkttype );
+ return;
}
- if( opt.with_colons )
- {
- if(pkt->pkt.user_id->attrib_data)
- printf("%u %lu",
- pkt->pkt.user_id->numattribs,
- pkt->pkt.user_id->attrib_len);
- else
- es_write_sanitized (es_stdout, pkt->pkt.user_id->name,
- pkt->pkt.user_id->len, ":", NULL);
- }
- else
- print_utf8_buffer (es_stdout, pkt->pkt.user_id->name,
- pkt->pkt.user_id->len );
+ if (opt.with_colons)
+ {
+ if (pkt->pkt.user_id->attrib_data)
+ printf("%u %lu",
+ pkt->pkt.user_id->numattribs,
+ pkt->pkt.user_id->attrib_len);
+ else
+ es_write_sanitized (es_stdout, pkt->pkt.user_id->name,
+ pkt->pkt.user_id->len, ":", NULL);
+ }
+ else
+ print_utf8_buffer (es_stdout, pkt->pkt.user_id->name,
+ pkt->pkt.user_id->len );
}
-/****************
- * List the certificate in a user friendly way
+/*
+ * List the keyblock in a user friendly way
*/
-
static void
-list_node( CTX c, KBNODE node )
+list_node (CTX c, kbnode_t node)
{
int mainkey;
char pkstrbuf[PUBKEY_STRING_SIZE];
@@ -1104,66 +1150,64 @@ list_node( CTX c, KBNODE node )
}
-
int
-proc_packets (ctrl_t ctrl, void *anchor, IOBUF a )
+proc_packets (ctrl_t ctrl, void *anchor, iobuf_t a )
{
- int rc;
- CTX c = xmalloc_clear( sizeof *c );
+ int rc;
+ CTX c = xmalloc_clear (sizeof *c);
- c->ctrl = ctrl;
- c->anchor = anchor;
- rc = do_proc_packets( c, a );
- xfree( c );
- return rc;
-}
+ c->ctrl = ctrl;
+ c->anchor = anchor;
+ rc = do_proc_packets (c, a);
+ xfree (c);
+ return rc;
+}
int
-proc_signature_packets (ctrl_t ctrl, void *anchor, IOBUF a,
+proc_signature_packets (ctrl_t ctrl, void *anchor, iobuf_t a,
strlist_t signedfiles, const char *sigfilename )
{
- CTX c = xmalloc_clear( sizeof *c );
- int rc;
-
- c->ctrl = ctrl;
- c->anchor = anchor;
- c->sigs_only = 1;
-
- c->signed_data.data_fd = -1;
- c->signed_data.data_names = signedfiles;
- c->signed_data.used = !!signedfiles;
-
- c->sigfilename = sigfilename;
- rc = do_proc_packets( c, a );
-
- /* If we have not encountered any signature we print an error
- messages, send a NODATA status back and return an error code.
- Using log_error is required because verify_files does not check
- error codes for each file but we want to terminate the process
- with an error. */
- if (!rc && !c->any.sig_seen)
- {
- write_status_text (STATUS_NODATA, "4");
- log_error (_("no signature found\n"));
- rc = G10ERR_NO_DATA;
- }
+ CTX c = xmalloc_clear (sizeof *c);
+ int rc;
+
+ c->ctrl = ctrl;
+ c->anchor = anchor;
+ c->sigs_only = 1;
- /* Propagate the signature seen flag upward. Do this only on
- success so that we won't issue the nodata status several
- times. */
- if (!rc && c->anchor && c->any.sig_seen)
- c->anchor->any.sig_seen = 1;
+ c->signed_data.data_fd = -1;
+ c->signed_data.data_names = signedfiles;
+ c->signed_data.used = !!signedfiles;
- xfree( c );
- return rc;
+ c->sigfilename = sigfilename;
+ rc = do_proc_packets ( c, a );
+
+ /* If we have not encountered any signature we print an error
+ messages, send a NODATA status back and return an error code.
+ Using log_error is required because verify_files does not check
+ error codes for each file but we want to terminate the process
+ with an error. */
+ if (!rc && !c->any.sig_seen)
+ {
+ write_status_text (STATUS_NODATA, "4");
+ log_error (_("no signature found\n"));
+ rc = G10ERR_NO_DATA;
+ }
+
+ /* Propagate the signature seen flag upward. Do this only on success
+ so that we won't issue the nodata status several times. */
+ if (!rc && c->anchor && c->any.sig_seen)
+ c->anchor->any.sig_seen = 1;
+
+ xfree (c);
+ return rc;
}
int
proc_signature_packets_by_fd (ctrl_t ctrl,
- void *anchor, IOBUF a, int signed_data_fd )
+ void *anchor, iobuf_t a, int signed_data_fd )
{
int rc;
CTX c;
@@ -1205,17 +1249,17 @@ proc_signature_packets_by_fd (ctrl_t ctrl,
int
-proc_encryption_packets (ctrl_t ctrl, void *anchor, IOBUF a )
+proc_encryption_packets (ctrl_t ctrl, void *anchor, iobuf_t a )
{
- CTX c = xmalloc_clear( sizeof *c );
- int rc;
-
- c->ctrl = ctrl;
- c->anchor = anchor;
- c->encrypt_only = 1;
- rc = do_proc_packets( c, a );
- xfree( c );
- return rc;
+ CTX c = xmalloc_clear (sizeof *c);
+ int rc;
+
+ c->ctrl = ctrl;
+ c->anchor = anchor;
+ c->encrypt_only = 1;
+ rc = do_proc_packets (c, a);
+ xfree (c);
+ return rc;
}
@@ -1233,152 +1277,168 @@ check_nesting (CTX c)
write_status_text (STATUS_UNEXPECTED, "1");
return GPG_ERR_BAD_DATA;
}
+
return 0;
}
static int
-do_proc_packets( CTX c, IOBUF a )
+do_proc_packets (CTX c, iobuf_t a)
{
- PACKET *pkt;
- int rc = 0;
- int any_data = 0;
- int newpkt;
-
- rc = check_nesting (c);
- if (rc)
- return rc;
-
- pkt = xmalloc( sizeof *pkt );
- c->iobuf = a;
- init_packet(pkt);
- while( (rc=parse_packet(a, pkt)) != -1 ) {
- any_data = 1;
- if( rc ) {
- free_packet(pkt);
- /* stop processing when an invalid packet has been encountered
- * but don't do so when we are doing a --list-packets. */
- if (gpg_err_code (rc) == GPG_ERR_INV_PACKET
- && opt.list_packets != 2 )
- break;
- continue;
+ PACKET *pkt;
+ int rc = 0;
+ int any_data = 0;
+ int newpkt;
+
+ rc = check_nesting (c);
+ if (rc)
+ return rc;
+
+ pkt = xmalloc( sizeof *pkt );
+ c->iobuf = a;
+ init_packet(pkt);
+ while ((rc=parse_packet(a, pkt)) != -1)
+ {
+ any_data = 1;
+ if (rc)
+ {
+ free_packet (pkt);
+ /* Stop processing when an invalid packet has been encountered
+ * but don't do so when we are doing a --list-packets. */
+ if (gpg_err_code (rc) == GPG_ERR_INV_PACKET
+ && opt.list_packets != 2 )
+ break;
+ continue;
}
- newpkt = -1;
- if( opt.list_packets ) {
- switch( pkt->pkttype ) {
- case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
- case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
- case PKT_COMPRESSED: rc = proc_compressed( c, pkt ); break;
- default: newpkt = 0; break;
+ newpkt = -1;
+ if (opt.list_packets)
+ {
+ switch (pkt->pkttype)
+ {
+ case PKT_PUBKEY_ENC: proc_pubkey_enc (c, pkt); break;
+ case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break;
+ case PKT_ENCRYPTED:
+ case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break;
+ case PKT_COMPRESSED: rc = proc_compressed (c, pkt); break;
+ default: newpkt = 0; break;
}
}
- else if( c->sigs_only ) {
- switch( pkt->pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- case PKT_USER_ID:
- case PKT_SYMKEY_ENC:
- case PKT_PUBKEY_ENC:
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC:
- write_status_text( STATUS_UNEXPECTED, "0" );
- rc = G10ERR_UNEXPECTED;
- goto leave;
- case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
- case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
- case PKT_COMPRESSED: rc = proc_compressed( c, pkt ); break;
- case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
- case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
- default: newpkt = 0; break;
+ else if (c->sigs_only)
+ {
+ switch (pkt->pkttype)
+ {
+ case PKT_PUBLIC_KEY:
+ case PKT_SECRET_KEY:
+ case PKT_USER_ID:
+ case PKT_SYMKEY_ENC:
+ case PKT_PUBKEY_ENC:
+ case PKT_ENCRYPTED:
+ case PKT_ENCRYPTED_MDC:
+ write_status_text( STATUS_UNEXPECTED, "0" );
+ rc = G10ERR_UNEXPECTED;
+ goto leave;
+
+ case PKT_SIGNATURE: newpkt = add_signature (c, pkt); break;
+ case PKT_PLAINTEXT: proc_plaintext (c, pkt); break;
+ case PKT_COMPRESSED: rc = proc_compressed (c, pkt); break;
+ case PKT_ONEPASS_SIG: newpkt = add_onepass_sig (c, pkt); break;
+ case PKT_GPG_CONTROL: newpkt = add_gpg_control (c, pkt); break;
+ default: newpkt = 0; break;
}
}
- else if( c->encrypt_only ) {
- switch( pkt->pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- case PKT_USER_ID:
- write_status_text( STATUS_UNEXPECTED, "0" );
- rc = G10ERR_UNEXPECTED;
- goto leave;
- case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
- case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
- case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
- case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
- case PKT_COMPRESSED: rc = proc_compressed( c, pkt ); break;
- case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
- case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
- default: newpkt = 0; break;
+ else if (c->encrypt_only)
+ {
+ switch (pkt->pkttype)
+ {
+ case PKT_PUBLIC_KEY:
+ case PKT_SECRET_KEY:
+ case PKT_USER_ID:
+ write_status_text (STATUS_UNEXPECTED, "0");
+ rc = G10ERR_UNEXPECTED;
+ goto leave;
+
+ case PKT_SIGNATURE: newpkt = add_signature (c, pkt); break;
+ case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break;
+ case PKT_PUBKEY_ENC: proc_pubkey_enc (c, pkt); break;
+ case PKT_ENCRYPTED:
+ case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break;
+ case PKT_PLAINTEXT: proc_plaintext (c, pkt); break;
+ case PKT_COMPRESSED: rc = proc_compressed (c, pkt); break;
+ case PKT_ONEPASS_SIG: newpkt = add_onepass_sig (c, pkt); break;
+ case PKT_GPG_CONTROL: newpkt = add_gpg_control (c, pkt); break;
+ default: newpkt = 0; break;
}
}
- else {
- switch( pkt->pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- release_list( c );
- c->list = new_kbnode( pkt );
- newpkt = 1;
- break;
- case PKT_PUBLIC_SUBKEY:
- case PKT_SECRET_SUBKEY:
- newpkt = add_subkey( c, pkt );
- break;
- case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break;
- case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
- case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
- case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
- case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
- case PKT_COMPRESSED: rc = proc_compressed( c, pkt ); break;
- case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
- case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
- case PKT_RING_TRUST: newpkt = add_ring_trust( c, pkt ); break;
- default: newpkt = 0; break;
+ else
+ {
+ switch (pkt->pkttype)
+ {
+ case PKT_PUBLIC_KEY:
+ case PKT_SECRET_KEY:
+ release_list (c);
+ c->list = new_kbnode (pkt);
+ newpkt = 1;
+ break;
+ case PKT_PUBLIC_SUBKEY:
+ case PKT_SECRET_SUBKEY:
+ newpkt = add_subkey (c, pkt);
+ break;
+ case PKT_USER_ID: newpkt = add_user_id (c, pkt); break;
+ case PKT_SIGNATURE: newpkt = add_signature (c, pkt); break;
+ case PKT_PUBKEY_ENC: proc_pubkey_enc (c, pkt); break;
+ case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break;
+ case PKT_ENCRYPTED:
+ case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break;
+ case PKT_PLAINTEXT: proc_plaintext (c, pkt); break;
+ case PKT_COMPRESSED: rc = proc_compressed (c, pkt); break;
+ case PKT_ONEPASS_SIG: newpkt = add_onepass_sig (c, pkt); break;
+ case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
+ case PKT_RING_TRUST: newpkt = add_ring_trust (c, pkt); break;
+ default: newpkt = 0; break;
}
}
- if (rc)
- goto leave;
-
- /* This is a very ugly construct and frankly, I don't remember why
- * I used it. Adding the MDC check here is a hack.
- * The right solution is to initiate another context for encrypted
- * packet and not to reuse the current one ... It works right
- * when there is a compression packet inbetween which adds just
- * an extra layer.
- * Hmmm: Rewrite this whole module here??
- */
- if( pkt->pkttype != PKT_SIGNATURE && pkt->pkttype != PKT_MDC )
- c->any.data = (pkt->pkttype == PKT_PLAINTEXT);
-
- if( newpkt == -1 )
- ;
- else if( newpkt ) {
- pkt = xmalloc( sizeof *pkt );
- init_packet(pkt);
+ if (rc)
+ goto leave;
+
+ /* This is a very ugly construct and frankly, I don't remember why
+ * I used it. Adding the MDC check here is a hack.
+ * The right solution is to initiate another context for encrypted
+ * packet and not to reuse the current one ... It works right
+ * when there is a compression packet inbetween which adds just
+ * an extra layer.
+ * Hmmm: Rewrite this whole module here??
+ */
+ if (pkt->pkttype != PKT_SIGNATURE && pkt->pkttype != PKT_MDC)
+ c->any.data = (pkt->pkttype == PKT_PLAINTEXT);
+
+ if (newpkt == -1)
+ ;
+ else if (newpkt)
+ {
+ pkt = xmalloc (sizeof *pkt);
+ init_packet (pkt);
}
- else
- free_packet(pkt);
+ else
+ free_packet(pkt);
}
- if( rc == G10ERR_INVALID_PACKET )
- write_status_text( STATUS_NODATA, "3" );
- if( any_data )
- rc = 0;
- else if( rc == -1 )
- write_status_text( STATUS_NODATA, "2" );
-
-
- leave:
- release_list( c );
- xfree(c->dek);
- free_packet( pkt );
- xfree( pkt );
- free_md_filter_context( &c->mfx );
- return rc;
+
+ if (rc == G10ERR_INVALID_PACKET)
+ write_status_text (STATUS_NODATA, "3");
+
+ if (any_data)
+ rc = 0;
+ else if (rc == -1)
+ write_status_text (STATUS_NODATA, "2");
+
+
+ leave:
+ release_list (c);
+ xfree(c->dek);
+ free_packet (pkt);
+ xfree (pkt);
+ free_md_filter_context (&c->mfx);
+ return rc;
}
@@ -1476,7 +1536,7 @@ print_good_bad_signature (int statno, const char *keyid_str, kbnode_t un,
static int
-check_sig_and_print (CTX c, KBNODE node)
+check_sig_and_print (CTX c, kbnode_t node)
{
PKT_signature *sig = node->pkt->pkt.signature;
const char *astr;
@@ -1520,7 +1580,7 @@ check_sig_and_print (CTX c, KBNODE node)
introduce a bug here.
*/
{
- KBNODE n;
+ kbnode_t n;
int n_onepass, n_sig;
/* log_debug ("checking signature packet composition\n"); */
@@ -1975,206 +2035,231 @@ check_sig_and_print (CTX c, KBNODE node)
}
-/****************
+/*
* Process the tree which starts at node
*/
static void
-proc_tree( CTX c, KBNODE node )
+proc_tree (CTX c, kbnode_t node)
{
- KBNODE n1;
- int rc;
-
- if( opt.list_packets || opt.list_only )
- return;
-
- /* we must skip our special plaintext marker packets here becuase
- they may be the root packet. These packets are only used in
- addionla checks and skipping them here doesn't matter */
- while ( node
- && node->pkt->pkttype == PKT_GPG_CONTROL
- && node->pkt->pkt.gpg_control->control
- == CTRLPKT_PLAINTEXT_MARK ) {
- node = node->next;
+ kbnode_t n1;
+ int rc;
+
+ if (opt.list_packets || opt.list_only)
+ return;
+
+ /* We must skip our special plaintext marker packets here because
+ they may be the root packet. These packets are only used in
+ addional checks and skipping them here doesn't matter. */
+ while (node
+ && node->pkt->pkttype == PKT_GPG_CONTROL
+ && node->pkt->pkt.gpg_control->control == CTRLPKT_PLAINTEXT_MARK)
+ {
+ node = node->next;
}
- if (!node)
- return;
+ if (!node)
+ return;
- c->trustletter = ' ';
- if( node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- merge_keys_and_selfsig( node );
- list_node( c, node );
+ c->trustletter = ' ';
+ if (node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+ {
+ merge_keys_and_selfsig (node);
+ list_node (c, node);
}
- else if( node->pkt->pkttype == PKT_SECRET_KEY ) {
- merge_keys_and_selfsig( node );
- list_node( c, node );
+ else if (node->pkt->pkttype == PKT_SECRET_KEY)
+ {
+ merge_keys_and_selfsig (node);
+ list_node (c, node);
}
- else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
- /* check all signatures */
- if( !c->any.data ) {
- int use_textmode = 0;
-
- free_md_filter_context( &c->mfx );
- /* prepare to create all requested message digests */
- if (gcry_md_open (&c->mfx.md, 0, 0))
- BUG ();
-
- /* fixme: why looking for the signature packet and not the
- one-pass packet? */
- for ( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
- {
- gcry_md_enable (c->mfx.md,
- n1->pkt->pkt.signature->digest_algo);
- }
-
- if (n1 && n1->pkt->pkt.onepass_sig->sig_class == 0x01)
- use_textmode = 1;
-
- /* Ask for file and hash it. */
- if( c->sigs_only ) {
- if (c->signed_data.used && c->signed_data.data_fd != -1)
- rc = hash_datafile_by_fd (c->mfx.md, NULL,
- c->signed_data.data_fd,
- use_textmode);
- else
- rc = hash_datafiles (c->mfx.md, NULL,
- c->signed_data.data_names,
- c->sigfilename,
- use_textmode );
+ else if (node->pkt->pkttype == PKT_ONEPASS_SIG)
+ {
+ /* Check all signatures. */
+ if (!c->any.data)
+ {
+ int use_textmode = 0;
+
+ free_md_filter_context (&c->mfx);
+ /* Prepare to create all requested message digests. */
+ if (gcry_md_open (&c->mfx.md, 0, 0))
+ BUG ();
+
+ /* Fixme: why looking for the signature packet and not the
+ one-pass packet? */
+ for (n1 = node; (n1 = find_next_kbnode (n1, PKT_SIGNATURE));)
+ gcry_md_enable (c->mfx.md, n1->pkt->pkt.signature->digest_algo);
+
+ if (n1 && n1->pkt->pkt.onepass_sig->sig_class == 0x01)
+ use_textmode = 1;
+
+ /* Ask for file and hash it. */
+ if (c->sigs_only)
+ {
+ if (c->signed_data.used && c->signed_data.data_fd != -1)
+ rc = hash_datafile_by_fd (c->mfx.md, NULL,
+ c->signed_data.data_fd,
+ use_textmode);
+ else
+ rc = hash_datafiles (c->mfx.md, NULL,
+ c->signed_data.data_names,
+ c->sigfilename,
+ use_textmode);
}
- else {
- rc = ask_for_detached_datafile (c->mfx.md, c->mfx.md2,
- iobuf_get_real_fname(c->iobuf),
- use_textmode );
+ else
+ {
+ rc = ask_for_detached_datafile (c->mfx.md, c->mfx.md2,
+ iobuf_get_real_fname (c->iobuf),
+ use_textmode);
}
- if( rc ) {
- log_error("can't hash datafile: %s\n", g10_errstr(rc));
- return;
+
+ if (rc)
+ {
+ log_error ("can't hash datafile: %s\n", g10_errstr (rc));
+ return;
}
}
- else if ( c->signed_data.used ) {
- log_error (_("not a detached signature\n") );
- return;
+ else if (c->signed_data.used)
+ {
+ log_error (_("not a detached signature\n"));
+ return;
}
- for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
- check_sig_and_print( c, n1 );
+ for (n1 = node; (n1 = find_next_kbnode (n1, PKT_SIGNATURE));)
+ check_sig_and_print (c, n1);
+
}
- else if( node->pkt->pkttype == PKT_GPG_CONTROL
- && node->pkt->pkt.gpg_control->control
- == CTRLPKT_CLEARSIGN_START ) {
- /* clear text signed message */
- if( !c->any.data ) {
- log_error("cleartext signature without data\n" );
- return;
+ else if (node->pkt->pkttype == PKT_GPG_CONTROL
+ && node->pkt->pkt.gpg_control->control == CTRLPKT_CLEARSIGN_START)
+ {
+ /* Clear text signed message. */
+ if (!c->any.data)
+ {
+ log_error ("cleartext signature without data\n");
+ return;
}
- else if ( c->signed_data.used ) {
- log_error (_("not a detached signature\n") );
- return;
+ else if (c->signed_data.used)
+ {
+ log_error (_("not a detached signature\n"));
+ return;
}
- for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
- check_sig_and_print( c, n1 );
+ for (n1 = node; (n1 = find_next_kbnode (n1, PKT_SIGNATURE));)
+ check_sig_and_print (c, n1);
+
}
- else if( node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- int multiple_ok=1;
-
- n1=find_next_kbnode(node, PKT_SIGNATURE);
- if(n1)
- {
- byte class=sig->sig_class;
- byte hash=sig->digest_algo;
-
- for(; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE)))
- {
- /* We can't currently handle multiple signatures of
- different classes or digests (we'd pretty much have
- to run a different hash context for each), but if
- they are all the same, make an exception. */
- if(n1->pkt->pkt.signature->sig_class!=class
- || n1->pkt->pkt.signature->digest_algo!=hash)
- {
- multiple_ok=0;
- log_info(_("WARNING: multiple signatures detected. "
- "Only the first will be checked.\n"));
- break;
- }
- }
- }
-
- if( sig->sig_class != 0x00 && sig->sig_class != 0x01 )
- log_info(_("standalone signature of class 0x%02x\n"),
- sig->sig_class);
- else if( !c->any.data ) {
- /* detached signature */
- free_md_filter_context( &c->mfx );
- if (gcry_md_open (&c->mfx.md, sig->digest_algo, 0))
- BUG ();
-
- if (RFC2440 || RFC4880)
- ; /* Strict RFC mode. */
- else if( sig->digest_algo == DIGEST_ALGO_SHA1
- && sig->pubkey_algo == PUBKEY_ALGO_DSA
- && sig->sig_class == 0x01 ) {
- /* Enable a workaround for a pgp5 bug when the
- * detached signature has been created in textmode. */
+ else if (node->pkt->pkttype == PKT_SIGNATURE)
+ {
+ PKT_signature *sig = node->pkt->pkt.signature;
+ int multiple_ok = 1;
+
+ n1 = find_next_kbnode (node, PKT_SIGNATURE);
+ if (n1)
+ {
+ byte class = sig->sig_class;
+ byte hash = sig->digest_algo;
+
+ for (; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE)))
+ {
+ /* We can't currently handle multiple signatures of
+ different classes or digests (we'd pretty much have
+ to run a different hash context for each), but if
+ they are all the same, make an exception. */
+ if (n1->pkt->pkt.signature->sig_class != class
+ || n1->pkt->pkt.signature->digest_algo != hash)
+ {
+ multiple_ok = 0;
+ log_info (_("WARNING: multiple signatures detected. "
+ "Only the first will be checked.\n"));
+ break;
+ }
+ }
+ }
+
+ if (sig->sig_class != 0x00 && sig->sig_class != 0x01)
+ {
+ log_info(_("standalone signature of class 0x%02x\n"), sig->sig_class);
+ }
+ else if (!c->any.data)
+ {
+ /* Detached signature */
+ free_md_filter_context (&c->mfx);
+ if (gcry_md_open (&c->mfx.md, sig->digest_algo, 0))
+ BUG ();
+
+ if (RFC2440 || RFC4880)
+ ; /* Strict RFC mode. */
+ else if (sig->digest_algo == DIGEST_ALGO_SHA1
+ && sig->pubkey_algo == PUBKEY_ALGO_DSA
+ && sig->sig_class == 0x01)
+ {
+ /* Enable a workaround for a pgp5 bug when the detached
+ * signature has been created in textmode. */
if (gcry_md_open (&c->mfx.md2, sig->digest_algo, 0 ))
BUG ();
}
- /* Here we used to have another hack to work around a pgp
- * 2 bug: It worked by not using the textmode for detached
- * signatures; this would let the first signature check
- * (on md) fail but the second one (on md2), which adds an
- * extra CR would then have produced the "correct" hash.
- * This is very, very ugly hack but it may haved help in
- * some cases (and break others).
- * c->mfx.md2? 0 :(sig->sig_class == 0x01)
- */
-
- if ( DBG_HASHING ) {
- gcry_md_debug( c->mfx.md, "verify" );
- if ( c->mfx.md2 )
- gcry_md_debug( c->mfx.md2, "verify2" );
+ /* Here we used to have another hack to work around a pgp
+ * 2 bug: It worked by not using the textmode for detached
+ * signatures; this would let the first signature check
+ * (on md) fail but the second one (on md2), which adds an
+ * extra CR would then have produced the "correct" hash.
+ * This is very, very ugly hack but it may haved help in
+ * some cases (and break others).
+ * c->mfx.md2? 0 :(sig->sig_class == 0x01)
+ */
+
+ if (DBG_HASHING)
+ {
+ gcry_md_debug (c->mfx.md, "verify");
+ if (c->mfx.md2)
+ gcry_md_debug (c->mfx.md2, "verify2");
}
- if( c->sigs_only ) {
- if (c->signed_data.used && c->signed_data.data_fd != -1)
- rc = hash_datafile_by_fd (c->mfx.md, c->mfx.md2,
- c->signed_data.data_fd,
- (sig->sig_class == 0x01));
- else
- rc = hash_datafiles (c->mfx.md, c->mfx.md2,
- c->signed_data.data_names,
- c->sigfilename,
- (sig->sig_class == 0x01));
+
+ if (c->sigs_only)
+ {
+ if (c->signed_data.used && c->signed_data.data_fd != -1)
+ rc = hash_datafile_by_fd (c->mfx.md, c->mfx.md2,
+ c->signed_data.data_fd,
+ (sig->sig_class == 0x01));
+ else
+ rc = hash_datafiles (c->mfx.md, c->mfx.md2,
+ c->signed_data.data_names,
+ c->sigfilename,
+ (sig->sig_class == 0x01));
}
- else {
- rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2,
- iobuf_get_real_fname(c->iobuf),
- (sig->sig_class == 0x01) );
+ else
+ {
+ rc = ask_for_detached_datafile (c->mfx.md, c->mfx.md2,
+ iobuf_get_real_fname(c->iobuf),
+ (sig->sig_class == 0x01));
}
- if( rc ) {
- log_error("can't hash datafile: %s\n", g10_errstr(rc));
- return;
+
+ if (rc)
+ {
+ log_error ("can't hash datafile: %s\n", g10_errstr(rc));
+ return;
}
}
- else if ( c->signed_data.used ) {
- log_error (_("not a detached signature\n") );
- return;
+ else if (c->signed_data.used)
+ {
+ log_error (_("not a detached signature\n"));
+ return;
+ }
+ else if (!opt.quiet)
+ log_info (_("old style (PGP 2.x) signature\n"));
+
+ if (multiple_ok)
+ {
+ for (n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE)))
+ check_sig_and_print (c, n1);
}
- else if (!opt.quiet)
- log_info(_("old style (PGP 2.x) signature\n"));
-
- if(multiple_ok)
- for( n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )) )
- check_sig_and_print( c, n1 );
- else
- check_sig_and_print( c, node );
+ else
+ check_sig_and_print (c, node);
+
}
- else {
- dump_kbnode (c->list);
- log_error(_("invalid root packet detected in proc_tree()\n"));
- dump_kbnode (node);
+ else
+ {
+ dump_kbnode (c->list);
+ log_error ("invalid root packet detected in proc_tree()\n");
+ dump_kbnode (node);
}
}
diff --git a/g10/openfile.c b/g10/openfile.c
index 5a436485b..ab27f44e3 100644
--- a/g10/openfile.c
+++ b/g10/openfile.c
@@ -59,7 +59,7 @@
/* FIXME: Implement opt.interactive. */
-/****************
+/*
* Check whether FNAME exists and ask if it's okay to overwrite an
* existing one.
* Returns: True: it's okay to overwrite or the file does not exist
@@ -92,35 +92,37 @@ overwrite_filep( const char *fname )
}
-/****************
+/*
* Strip known extensions from iname and return a newly allocated
* filename. Return NULL if we can't do that.
*/
char *
-make_outfile_name( const char *iname )
+make_outfile_name (const char *iname)
{
- size_t n;
-
- if ( iobuf_is_pipe_filename (iname) )
- return xstrdup("-");
-
- n = strlen(iname);
- if( n > 4 && ( !CMP_FILENAME(iname+n-4, EXTSEP_S GPGEXT_GPG)
- || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
- || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
- || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) {
- char *buf = xstrdup( iname );
- buf[n-4] = 0;
- return buf;
+ size_t n;
+
+ if (iobuf_is_pipe_filename (iname))
+ return xstrdup ("-");
+
+ n = strlen (iname);
+ if (n > 4 && (!CMP_FILENAME(iname+n-4, EXTSEP_S GPGEXT_GPG)
+ || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
+ || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
+ || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc")))
+ {
+ char *buf = xstrdup (iname);
+ buf[n-4] = 0;
+ return buf;
}
- else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) {
- char *buf = xstrdup( iname );
- buf[n-5] = 0;
- return buf;
+ else if (n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign"))
+ {
+ char *buf = xstrdup (iname);
+ buf[n-5] = 0;
+ return buf;
}
- log_info(_("%s: unknown suffix\n"), iname );
- return NULL;
+ log_info (_("%s: unknown suffix\n"), iname);
+ return NULL;
}
@@ -168,7 +170,7 @@ ask_outfile_name( const char *name, size_t namelen )
}
-/****************
+/*
* Make an output filename for the inputfile INAME.
* Returns an IOBUF and an errorcode
* Mode 0 = use ".gpg"
@@ -308,117 +310,132 @@ open_outfile (int inp_fd, const char *iname, int mode, int restrictedperm,
}
-/****************
+/*
* Try to open a file without the extension ".sig" or ".asc"
* Return NULL if such a file is not available.
*/
IOBUF
open_sigfile( const char *iname, progress_filter_context_t *pfx )
{
- IOBUF a = NULL;
- size_t len;
-
- if( !iobuf_is_pipe_filename (iname) ) {
- len = strlen(iname);
- if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig")
- || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") )
- || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) {
- char *buf;
- buf = xstrdup(iname);
- buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
- a = iobuf_open( buf );
- if (a && is_secured_file (iobuf_get_fd (a)))
- {
- iobuf_close (a);
- a = NULL;
- gpg_err_set_errno (EPERM);
- }
- if( a && opt.verbose )
- log_info(_("assuming signed data in '%s'\n"), buf );
- if (a && pfx)
- handle_progress (pfx, a, buf);
- xfree(buf);
+ IOBUF a = NULL;
+ size_t len;
+
+ if (!iobuf_is_pipe_filename (iname))
+ {
+ len = strlen(iname);
+ if( len > 4 && (!strcmp(iname + len - 4, EXTSEP_S "sig")
+ || (len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign"))
+ || !strcmp(iname + len - 4, EXTSEP_S "asc")))
+ {
+ char *buf;
+
+ buf = xstrdup(iname);
+ buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
+ a = iobuf_open( buf );
+ if (a && is_secured_file (iobuf_get_fd (a)))
+ {
+ iobuf_close (a);
+ a = NULL;
+ gpg_err_set_errno (EPERM);
+ }
+ if (a && opt.verbose)
+ log_info (_("assuming signed data in '%s'\n"), buf);
+ if (a && pfx)
+ handle_progress (pfx, a, buf);
+ xfree (buf);
}
}
- return a;
+
+ return a;
}
+
/****************
* Copy the option file skeleton to the given directory.
*/
static void
-copy_options_file( const char *destdir )
+copy_options_file (const char *destdir)
{
- const char *datadir = gnupg_datadir ();
- char *fname;
- FILE *src, *dst;
- int linefeeds=0;
- int c;
- mode_t oldmask;
- int esc = 0;
- int any_option = 0;
-
- if( opt.dry_run )
- return;
-
- fname = xmalloc( strlen(datadir) + strlen(destdir) + 15 );
- strcpy(stpcpy(fname, datadir), DIRSEP_S "gpg-conf" SKELEXT );
- src = fopen( fname, "r" );
- if (src && is_secured_file (fileno (src)))
- {
- fclose (src);
- src = NULL;
- gpg_err_set_errno (EPERM);
- }
- if( !src ) {
- log_info (_("can't open '%s': %s\n"), fname, strerror(errno) );
- xfree(fname);
- return;
+ const char *datadir = gnupg_datadir ();
+ char *fname;
+ FILE *src, *dst;
+ int linefeeds=0;
+ int c;
+ mode_t oldmask;
+ int esc = 0;
+ int any_option = 0;
+
+ if (opt.dry_run)
+ return;
+
+ fname = xmalloc (strlen(datadir) + strlen(destdir) + 15);
+ strcpy (stpcpy(fname, datadir), DIRSEP_S "gpg-conf" SKELEXT);
+ src = fopen (fname, "r");
+ if (src && is_secured_file (fileno (src)))
+ {
+ fclose (src);
+ src = NULL;
+ gpg_err_set_errno (EPERM);
+ }
+ if (!src)
+ {
+ log_info (_("can't open '%s': %s\n"), fname, strerror(errno));
+ xfree(fname);
+ return;
}
- strcpy(stpcpy(fname, destdir), DIRSEP_S GPGEXT_GPG EXTSEP_S "conf" );
- oldmask=umask(077);
- if ( is_secured_filename (fname) )
- {
- dst = NULL;
- gpg_err_set_errno (EPERM);
- }
- else
- dst = fopen( fname, "w" );
- umask(oldmask);
- if( !dst ) {
- log_info (_("can't create '%s': %s\n"), fname, strerror(errno) );
- fclose( src );
- xfree(fname);
- return;
+ strcpy (stpcpy (fname, destdir), DIRSEP_S GPGEXT_GPG EXTSEP_S "conf");
+
+ oldmask = umask (077);
+ if (is_secured_filename (fname))
+ {
+ dst = NULL;
+ gpg_err_set_errno (EPERM);
+ }
+ else
+ dst = fopen( fname, "w" );
+ umask (oldmask);
+
+ if (!dst)
+ {
+ log_info (_("can't create '%s': %s\n"), fname, strerror(errno) );
+ fclose (src);
+ xfree (fname);
+ return;
}
- while( (c=getc(src)) != EOF ) {
- if( linefeeds < 3 ) {
- if( c == '\n' )
- linefeeds++;
+ while ((c = getc (src)) != EOF)
+ {
+ if (linefeeds < 3)
+ {
+ if (c == '\n')
+ linefeeds++;
}
- else {
- putc( c, dst );
- if (c== '\n')
- esc = 1;
- else if (esc == 1) {
- if (c == ' ' || c == '\t')
- ;
- else if (c == '#')
- esc = 2;
- else
- any_option = 1;
+ else
+ {
+ putc (c, dst);
+ if (c== '\n')
+ esc = 1;
+ else if (esc == 1)
+ {
+ if (c == ' ' || c == '\t')
+ ;
+ else if (c == '#')
+ esc = 2;
+ else
+ any_option = 1;
}
}
}
- fclose( dst );
- fclose( src );
- log_info(_("new configuration file '%s' created\n"), fname );
- if (any_option)
- log_info (_("WARNING: options in '%s'"
- " are not yet active during this run\n"),
- fname);
- xfree(fname);
+
+ fclose (dst);
+ fclose (src);
+
+ log_info (_("new configuration file '%s' created\n"), fname);
+ if (any_option)
+ log_info (_("WARNING: options in '%s'"
+ " are not yet active during this run\n"),
+ fname);
+ xfree (fname);
}