diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/g10.c | 31 | ||||
-rw-r--r-- | g10/mainproc.c | 481 |
2 files changed, 271 insertions, 241 deletions
@@ -33,7 +33,7 @@ #include "cipher.h" #include "filter.h" -static void do_test(void); +static void do_test(int); const char * strusage( int level ) @@ -114,7 +114,7 @@ main( int argc, char **argv ) { 's', "sign", 0, "make a signature"}, { 'e', "encrypt", 0, "encrypt data" }, { 'd', "decrypt", 0, "decrypt data (default)" }, - { 'c', "check", 0, "check a signature (default)" }, + /*{ 'c', "check", 0, "check a signature (default)" }, */ { 'l', "local-user",2, "use this user-id to sign or decrypt" }, { 'r', "remote-user", 2, "use this user-id for encryption" }, { 510, "debug" ,4|16, "set debugging flags" }, @@ -246,7 +246,7 @@ main( int argc, char **argv ) generate_keypair(); break; - case aTest: do_test(); break; + case aTest: do_test( atoi(*argv) ); break; default: if( argc > 1 ) @@ -270,7 +270,7 @@ main( int argc, char **argv ) static void -do_test() +do_test(int times) { MPI t = mpi_alloc( 50 ); MPI m = mpi_alloc( 50 ); @@ -278,22 +278,17 @@ do_test() MPI b = mpi_alloc( 50 ); MPI p = mpi_alloc( 50 ); MPI x = mpi_alloc( 50 ); - mpi_fromstr(a, "0xef45678343589854354a4545545454554545455" - "aaaaaaaaaaaaa44444fffdecb33434343443331" ); - mpi_fromstr(b, "0x8765765589854354a4545545454554545455" - "aaaaaaa466577778decb36666343443331" ); - mpi_fromstr(p, "0xcccddd456700000012222222222222254545455" - "aaaaaaaaaaaaa44444fffdecb33434343443337" ); - mpi_fromstr(x, "0x100004545543656456656545545454554545455" - "aaa33aaaa465456544fffdecb33434bbbac3331" ); /* output = b/(a^x) mod p */ - log_debug("powm ..\n"); - mpi_powm( t, a, x, p ); - log_debug("invm ..\n"); - mpi_invm( t, t, p ); - log_debug("mulm ..\n"); - mpi_mulm( m, b, t, p ); + log_debug("invm %d times ", times); + for( ; times > 0; times -- ) { + mpi_fromstr(a, "0xef45678343589854354a4545545454554545455" + "aaaaaaaaaaaaa44444fffdecb33434343443331" ); + mpi_fromstr(b, "0x8765765589854354a4545545454554545455" + "aaaaaaa466577778decb36666343443331" ); + mpi_invm( t, a, b ); + fputc('.', stderr); fflush(stderr); + } m_check(NULL); diff --git a/g10/mainproc.c b/g10/mainproc.c index c056ac0af..9e34fbd0e 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -32,8 +32,21 @@ #include "filter.h" #include "main.h" + +typedef struct { + PKT_pubkey_cert *last_pubkey; + PKT_seckey_cert *last_seckey; + PKT_user_id *last_user_id; + md_filter_context_t mfx; + DEK *dek; + int last_was_pubkey_enc; +} *CTX; + + + + static int opt_list=1; /* and list the data packets to stdout */ -#if 0 +#if 1 static void do_free_last_user_id( CTX c ) { @@ -62,10 +75,15 @@ do_free_last_seckey( CTX c ) static void proc_pubkey_cert( CTX c, PACKET *pkt ) { + u32 keyid[2]; + char *ustr; + int lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */ + do_free_last_user_id( c ); do_free_last_seckey( c ); if( opt.check_sigs ) { - char *ustr = get_user_id_string(sig->keyid); /* sig ???? */ + keyid_from_pkc( pkt->pkt.pubkey_cert, keyid ); + ustr = get_user_id_string(keyid); printstr(lvl0, "pub: %s\n", ustr ); m_free(ustr); } @@ -104,36 +122,246 @@ proc_seckey_cert( CTX c, PACKET *pkt ) } +static void +proc_user_id( CTX c, PACKET *pkt ) +{ + u32 keyid[2]; + + do_free_last_user_id( c ); + 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 ); + } + } + + c->last_user_id = pkt->pkt.user_id; /* save */ + pkt->pkt.user_id = NULL; + free_packet(pkt); + pkt->user_parent = c->last_user_id; /* and set this as user */ +} + + +static void +proc_signature( CTX c, PACKET *pkt ) +{ + PKT_signature *sig; + MD_HANDLE md_handle; /* union to pass handles down */ + char *ustr; + int result = -1; + int lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */ + int lvl1 = opt.check_sigs? 1:3; /* stdout or error */ + + sig = pkt->pkt.signature; + ustr = get_user_id_string(sig->keyid); + if( sig->sig_class == 0x00 ) { + if( c->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( c->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( c->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); +} + + +static void +proc_pubkey_enc( CTX c, PACKET *pkt ) +{ + PKT_pubkey_enc *enc; + int result = 0; + + c->last_was_pubkey_enc = 1; + 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(c->dek ); /* paranoid: delete a pending DEK */ + c->dek = m_alloc_secure( sizeof *c->dek ); + if( (result = get_session_key( enc, c->dek )) ) { + /* error: delete the DEK */ + m_free(c->dek); c->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); +} + + + +static void +proc_encr_data( CTX c, PACKET *pkt ) +{ + int result = 0; + + printf("dat: %sencrypted data\n", c->dek?"":"conventional "); + if( !c->dek && !c->last_was_pubkey_enc ) { + /* assume this is conventional encrypted data */ + c->dek = m_alloc_secure( sizeof *c->dek ); + c->dek->algo = DEFAULT_CIPHER_ALGO; + result = make_dek_from_passphrase( c->dek, 0 ); + } + else if( !c->dek ) + result = G10ERR_NO_SECKEY; + if( !result ) + result = decrypt_data( pkt->pkt.encr_data, c->dek ); + m_free(c->dek); c->dek = NULL; + if( result == -1 ) + ; + else if( !result ) + fputs( " encryption okay",stdout); + else + printf( " %s", g10_errstr(result)); + putchar('\n'); + free_packet(pkt); + c->last_was_pubkey_enc = 0; +} + + +static void +proc_plaintext( CTX c, PACKET *pkt ) +{ + PKT_plaintext *pt = pkt->pkt.plaintext; + int result; + + printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name); + free_md_filter_context( &c->mfx ); + c->mfx.rmd160 = rmd160_open(0); + result = handle_plaintext( pt, &c->mfx ); + if( !result ) + fputs( " okay", stdout); + else + printf( " %s", g10_errstr(result)); + putchar('\n'); + free_packet(pkt); + c->last_was_pubkey_enc = 0; +} + + +static void +proc_compr_data( CTX c, PACKET *pkt ) +{ + PKT_compressed *zd = pkt->pkt.compressed; + int result; + + 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); + c->last_was_pubkey_enc = 0; +} 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" */ + CTX c = m_alloc_clear( sizeof *c ); + PACKET *pkt = m_alloc( sizeof *pkt ); 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 ) { + if( c->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 */ + m_free(c->dek); c->dek = NULL; /* burn it */ } if( rc ) { @@ -143,217 +371,24 @@ proc_packets( IOBUF a ) 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); + case PKT_USER_ID: proc_user_id( c, pkt ); break; + case PKT_SIGNATURE: proc_signature( c, pkt ); break; + case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; + case PKT_ENCR_DATA: proc_encr_data( c, pkt ); break; + case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; + case PKT_COMPR_DATA: proc_compr_data( c, pkt ); 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); + do_free_last_user_id( c ); + do_free_last_seckey( c ); + do_free_last_pubkey( c ); + m_free(c->dek); free_packet( pkt ); m_free( pkt ); - free_md_filter_context( &mfx ); + free_md_filter_context( &c->mfx ); + m_free( c ); return 0; } |