aboutsummaryrefslogtreecommitdiffstats
path: root/g10/mainproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/mainproc.c')
-rw-r--r--g10/mainproc.c97
1 files changed, 95 insertions, 2 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c
index fd814cc80..8004c3803 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -75,6 +75,7 @@ typedef struct {
static void list_node( CTX c, NODE node );
+static void proc_tree( CTX c, NODE node );
static int
pubkey_letter( int algo )
@@ -142,12 +143,31 @@ release_cert( CTX c )
{
if( !c->cert )
return;
- list_node(c, c->cert );
+ proc_tree(c, c->cert );
release_node( c->cert );
c->cert = NULL;
}
+static int
+add_onepass_sig( CTX c, PACKET *pkt )
+{
+ if( c->cert ) { /* add another packet */
+ NODE node;
+
+ if( c->cert->pkt->pkttype != PKT_ONEPASS_SIG ) {
+ log_error("add_onepass_sig: another packet is in the way\n");
+ release_cert( c );
+ }
+ node = new_node( pkt );
+ node->next = c->cert;
+ c->cert = node;
+ }
+ else /* insert the first one */
+ c->cert = new_node( pkt );
+ return 1;
+}
+
static int
add_public_cert( CTX c, PACKET *pkt )
@@ -205,10 +225,24 @@ add_signature( CTX c, PACKET *pkt )
NODE node, n1, n2;
if( !c->cert ) {
- log_error("orphaned signature (no certificate)\n" );
+ /* orphaned signature (no certificate)
+ * this is the first signature for a following datafile
+ */
return 0;
}
assert( c->cert->pkt );
+ if( c->cert->pkt->pkttype == PKT_ONEPASS_SIG ) {
+ /* The root is a onepass signature, so we are signing data
+ * The childs direct under the root are the signatures
+ * (there is no need to keep the correct sequence of packets)
+ */
+ node = new_node( pkt );
+ node->next = c->cert->child;
+ c->cert->child = node;
+ return 1;
+ }
+
+
if( !c->cert->child ) {
log_error("orphaned signature (no userid)\n" );
return 0;
@@ -531,6 +565,7 @@ proc_packets( IOBUF a )
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
+ case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
default: newpkt = 0; break;
}
if( newpkt == -1 )
@@ -553,3 +588,61 @@ proc_packets( IOBUF a )
}
+static void
+print_keyid( FILE *fp, u32 *keyid )
+{
+ size_t n;
+ char *p = get_user_id( keyid, &n );
+ print_string( fp, p, n );
+ m_free(p);
+}
+
+/****************
+ * Preocess the tree which starts at node
+ */
+static void
+proc_tree( CTX c, NODE node )
+{
+ NODE n1;
+ int rc;
+
+ if( node->pkt->pkttype == PKT_PUBLIC_CERT )
+ list_node( c, node );
+ else if( node->pkt->pkttype == PKT_SECRET_CERT )
+ list_node( c, node );
+ else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
+ if( !node->child )
+ log_error("proc_tree: onepass_sig without followin data\n");
+ else if( node->child->pkt->pkttype != PKT_SIGNATURE )
+ log_error("proc_tree: onepass_sig not followed by signature\n");
+ else { /* check all signature */
+ for(n1=node->child; n1; n1 = n1->next ) {
+ PKT_signature *sig = n1->pkt->pkt.signature;
+
+ rc = do_check_sig(c, n1 );
+ if( !rc ) {
+ log_info("Good signature from ");
+ print_keyid( stderr, sig->keyid );
+ putc('\n', stderr);
+ }
+ else if( rc == G10ERR_BAD_SIGN ) {
+ log_error("BAD signature from ");
+ print_keyid( stderr, sig->keyid );
+ putc('\n', stderr);
+ }
+ else
+ log_error("Can't check signature made by %08lX: %s\n",
+ sig->keyid[1], g10_errstr(rc) );
+ }
+ }
+ }
+ else if( node->pkt->pkttype == PKT_SIGNATURE ) {
+ log_info("proc_tree: old style signature\n");
+ }
+ else
+ log_error("proc_tree: invalid root packet\n");
+
+}
+
+
+