aboutsummaryrefslogtreecommitdiffstats
path: root/g10/mainproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/mainproc.c')
-rw-r--r--g10/mainproc.c326
1 files changed, 325 insertions, 1 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 6c7e32f3c..c056ac0af 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -33,7 +33,331 @@
#include "main.h"
static int opt_list=1; /* and list the data packets to stdout */
+#if 0
+static void
+do_free_last_user_id( CTX c )
+{
+ if( c->last_user_id ) {
+ free_user_id( c->last_user_id );
+ c->last_user_id = NULL;
+ }
+}
+static void
+do_free_last_pubkey( CTX c )
+{
+ if( c->last_pubkey ) {
+ free_pubkey_cert( c->last_pubkey );
+ c->last_pubkey = NULL;
+ }
+}
+static void
+do_free_last_seckey( CTX c )
+{
+ if( c->last_seckey ) {
+ free_seckey_cert( c->last_seckey );
+ c->last_seckey = NULL;
+ }
+}
+
+static void
+proc_pubkey_cert( CTX c, PACKET *pkt )
+{
+ do_free_last_user_id( c );
+ do_free_last_seckey( c );
+ if( opt.check_sigs ) {
+ char *ustr = get_user_id_string(sig->keyid); /* sig ???? */
+ printstr(lvl0, "pub: %s\n", ustr );
+ m_free(ustr);
+ }
+ else
+ fputs( "pub: [Public Key Cerificate]\n", stdout );
+ c->last_pubkey = pkt->pkt.pubkey_cert;
+ pkt->pkt.pubkey_cert = NULL;
+ free_packet(pkt);
+ pkt->pkc_parent = c->last_pubkey; /* set this as parent */
+}
+
+
+static void
+proc_seckey_cert( CTX c, PACKET *pkt )
+{
+ int rc;
+
+ do_free_last_user_id( c );
+ do_free_last_pubkey( c );
+ if( opt_list )
+ fputs( "sec: (secret key certificate)\n", stdout );
+ rc = check_secret_key( pkt->pkt.seckey_cert );
+ if( opt_list ) {
+ if( !rc )
+ fputs( " Secret key is good", stdout );
+ else
+ fputs( g10_errstr(rc), stdout);
+ putchar('\n');
+ }
+ else if( rc )
+ log_error("secret key certificate error: %s\n", g10_errstr(rc));
+ c->last_seckey = pkt->pkt.seckey_cert;
+ pkt->pkt.seckey_cert = NULL;
+ free_packet(pkt);
+ pkt->skc_parent = c->last_seckey; /* set this as parent */
+}
+
+
+
+
+
+int
+proc_packets( IOBUF a )
+{
+ PACKET *pkt;
+ PKT_pubkey_cert *last_pubkey = NULL;
+ PKT_seckey_cert *last_seckey = NULL;
+ PKT_user_id *last_user_id = NULL;
+ DEK *dek = NULL;
+ PKT_signature *sig; /* CHECK: "might be used uninitialied" */
+ int rc, result;
+ MD_HANDLE md_handle; /* union to pass handles */
+ char *ustr;
+ int lvl0, lvl1;
+ int last_was_pubkey_enc = 0;
+ u32 keyid[2];
+ md_filter_context_t mfx;
+
+ memset( &mfx, 0, sizeof mfx );
+ lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */
+ lvl1 = opt.check_sigs? 1:3; /* stdout or error */
+ pkt = m_alloc( sizeof *pkt );
+ init_packet(pkt);
+ while( (rc=parse_packet(a, pkt)) != -1 ) {
+ /* cleanup if we have an illegal data structure */
+ if( dek && pkt->pkttype != PKT_ENCR_DATA ) {
+ log_error("oops: valid pubkey enc packet not followed by data\n");
+ m_free(dek); dek = NULL; /* burn it */
+ }
+
+ if( rc ) {
+ free_packet(pkt);
+ continue;
+ }
+ switch( pkt->pkttype ) {
+ case PKT_PUBKEY_CERT: proc_pubkey_cert( c, pkt ); break;
+ case PKT_SECKEY_CERT: proc_seckey_cert( c, pkt ); break;
+ case PKT_USER_ID:
+ if( last_user_id ) {
+ free_user_id( last_user_id );
+ last_user_id = NULL;
+ }
+ if( opt_list ) {
+ printf("uid: '%.*s'\n", pkt->pkt.user_id->len,
+ pkt->pkt.user_id->name );
+ if( !pkt->pkc_parent && !pkt->skc_parent )
+ puts(" (orphaned)");
+ }
+ if( pkt->pkc_parent ) {
+ if( pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_ELGAMAL
+ || pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_RSA ) {
+ keyid_from_pkc( pkt->pkc_parent, keyid );
+ cache_user_id( pkt->pkt.user_id, keyid );
+ }
+ }
+
+ last_user_id = pkt->pkt.user_id; /* save */
+ pkt->pkt.user_id = NULL;
+ free_packet(pkt); /* fixme: free_packet is not a good name */
+ pkt->user_parent = last_user_id; /* and set this as user */
+ break;
+
+ case PKT_SIGNATURE:
+ sig = pkt->pkt.signature;
+ ustr = get_user_id_string(sig->keyid);
+ result = -1;
+ if( sig->sig_class == 0x00 ) {
+ if( mfx.rmd160 )
+ result = 0;
+ else
+ printstr(lvl1,"sig?: %s: no plaintext for signature\n",
+ ustr);
+ }
+ else if( sig->sig_class != 0x10 )
+ printstr(lvl1,"sig?: %s: unknown signature class %02x\n",
+ ustr, sig->sig_class);
+ else if( !pkt->pkc_parent || !pkt->user_parent )
+ printstr(lvl1,"sig?: %s: orphaned encoded packet\n", ustr);
+ else
+ result = 0;
+
+ if( result )
+ ;
+ else if( !opt.check_sigs && sig->sig_class != 0x00 ) {
+ result = -1;
+ printstr(lvl0, "sig: from %s\n", ustr );
+ }
+ else if(sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
+ md_handle.algo = sig->d.elg.digest_algo;
+ if( sig->d.elg.digest_algo == DIGEST_ALGO_RMD160 ) {
+ if( sig->sig_class == 0x00 )
+ md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
+ else {
+ md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
+ rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
+ pkt->user_parent->len);
+ }
+ result = signature_check( sig, md_handle );
+ rmd160_close(md_handle.u.rmd);
+ }
+ else if( sig->d.elg.digest_algo == DIGEST_ALGO_MD5
+ && sig->sig_class != 0x00 ) {
+ md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
+ md5_write(md_handle.u.md5, pkt->user_parent->name,
+ pkt->user_parent->len);
+ result = signature_check( sig, md_handle );
+ md5_close(md_handle.u.md5);
+ }
+ else
+ result = G10ERR_DIGEST_ALGO;
+ }
+ else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
+ md_handle.algo = sig->d.rsa.digest_algo;
+ if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) {
+ if( sig->sig_class == 0x00 )
+ md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
+ else {
+ md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
+ rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
+ pkt->user_parent->len);
+ }
+ result = signature_check( sig, md_handle );
+ rmd160_close(md_handle.u.rmd);
+ }
+ else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5
+ && sig->sig_class != 0x00 ) {
+ md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
+ md5_write(md_handle.u.md5, pkt->user_parent->name,
+ pkt->user_parent->len);
+ result = signature_check( sig, md_handle );
+ md5_close(md_handle.u.md5);
+ }
+ else
+ result = G10ERR_DIGEST_ALGO;
+ }
+ else
+ result = G10ERR_PUBKEY_ALGO;
+
+ if( result == -1 )
+ ;
+ else if( !result && sig->sig_class == 0x00 )
+ printstr(1, "sig: good signature from %s\n", ustr );
+ else if( !result )
+ printstr(lvl0, "sig: good signature from %s\n", ustr );
+ else
+ printstr(lvl1, "sig? %s: %s\n", ustr, g10_errstr(result));
+ free_packet(pkt);
+ m_free(ustr);
+ break;
+
+ case PKT_PUBKEY_ENC:
+ PKT_pubkey_enc *enc;
+
+ last_was_pubkey_enc = 1;
+ result = 0;
+ enc = pkt->pkt.pubkey_enc;
+ printf("enc: encrypted by a pubkey with keyid %08lX\n",
+ enc->keyid[1] );
+ if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
+ || enc->pubkey_algo == PUBKEY_ALGO_RSA ) {
+ m_free(dek ); /* paranoid: delete a pending DEK */
+ dek = m_alloc_secure( sizeof *dek );
+ if( (result = get_session_key( enc, dek )) ) {
+ /* error: delete the DEK */
+ m_free(dek); dek = NULL;
+ }
+ }
+ else
+ result = G10ERR_PUBKEY_ALGO;
+
+ if( result == -1 )
+ ;
+ else if( !result )
+ fputs( " DEK is good", stdout );
+ else
+ printf( " %s", g10_errstr(result));
+ putchar('\n');
+ free_packet(pkt);
+ break;
+
+ case PKT_ENCR_DATA:
+ result = 0;
+ printf("dat: %sencrypted data\n", dek?"":"conventional ");
+ if( !dek && !last_was_pubkey_enc ) {
+ /* assume this is conventional encrypted data */
+ dek = m_alloc_secure( sizeof *dek );
+ dek->algo = DEFAULT_CIPHER_ALGO;
+ result = make_dek_from_passphrase( dek, 0 );
+ }
+ else if( !dek )
+ result = G10ERR_NO_SECKEY;
+ if( !result )
+ result = decrypt_data( pkt->pkt.encr_data, dek );
+ m_free(dek); dek = NULL;
+ if( result == -1 )
+ ;
+ else if( !result )
+ fputs( " encryption okay",stdout);
+ else
+ printf( " %s", g10_errstr(result));
+ putchar('\n');
+ free_packet(pkt);
+ last_was_pubkey_enc = 0;
+ break;
+
+ case PKT_PLAINTEXT:
+ PKT_plaintext *pt = pkt->pkt.plaintext;
+ printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
+ free_md_filter_context( &mfx );
+ mfx.rmd160 = rmd160_open(0);
+ result = handle_plaintext( pt, &mfx );
+ if( !result )
+ fputs( " okay",stdout);
+ else
+ printf( " %s", g10_errstr(result));
+ putchar('\n');
+ free_packet(pkt);
+ last_was_pubkey_enc = 0;
+ break;
+
+ case PKT_COMPR_DATA:
+ PKT_compressed *zd = pkt->pkt.compressed;
+ printf("zip: compressed data packet\n");
+ result = handle_compressed( zd );
+ if( !result )
+ fputs( " okay",stdout);
+ else
+ printf( " %s", g10_errstr(result));
+ putchar('\n');
+ free_packet(pkt);
+ last_was_pubkey_enc = 0;
+ break;
+
+ default:
+ free_packet(pkt);
+ }
+ }
+
+ if( last_user_id )
+ free_user_id( last_user_id );
+ if( last_seckey )
+ free_seckey_cert( last_seckey );
+ if( last_pubkey )
+ free_pubkey_cert( last_pubkey );
+ m_free(dek);
+ free_packet( pkt );
+ m_free( pkt );
+ free_md_filter_context( &mfx );
+ return 0;
+}
+#else /* old */
int
proc_packets( IOBUF a )
{
@@ -317,5 +641,5 @@ proc_packets( IOBUF a )
free_md_filter_context( &mfx );
return 0;
}
-
+#endif