summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>1998-01-02 21:40:10 +0100
committerWerner Koch <wk@gnupg.org>1998-01-02 21:40:10 +0100
commitb7bdef0834f9d04f96f69a5323e0ac3e5e1b7bc2 (patch)
treecb6bae66627f4ea4d0a6b29631223ed2fe78ee8e /g10
parentSylvester Version (diff)
downloadgnupg2-b7bdef0834f9d04f96f69a5323e0ac3e5e1b7bc2.tar.xz
gnupg2-b7bdef0834f9d04f96f69a5323e0ac3e5e1b7bc2.zip
added more stuff
Diffstat (limited to 'g10')
-rw-r--r--g10/Makefile.am1
-rw-r--r--g10/Makefile.in8
-rw-r--r--g10/encode.c88
-rw-r--r--g10/filter.h4
-rw-r--r--g10/g10.c69
-rw-r--r--g10/kbnode.c55
-rw-r--r--g10/keydb.h5
-rw-r--r--g10/keyid.c6
-rw-r--r--g10/main.h12
-rw-r--r--g10/mainproc.c93
-rw-r--r--g10/options.h2
-rw-r--r--g10/packet.h1
-rw-r--r--g10/passphrase.c59
-rw-r--r--g10/seckey-cert.c6
-rw-r--r--g10/sign.c173
-rw-r--r--g10/trustdb.c35
16 files changed, 466 insertions, 151 deletions
diff --git a/g10/Makefile.am b/g10/Makefile.am
index 02639904a..901370ffb 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -30,6 +30,7 @@ g10_SOURCES = g10.c \
options.h \
openfile.c \
keyid.c \
+ trustdb.c \
packet.h \
parse-packet.c \
passphrase.c \
diff --git a/g10/Makefile.in b/g10/Makefile.in
index 40cf3aeed..531b1b8e9 100644
--- a/g10/Makefile.in
+++ b/g10/Makefile.in
@@ -68,6 +68,7 @@ g10_SOURCES = g10.c \
options.h \
openfile.c \
keyid.c \
+ trustdb.c \
packet.h \
parse-packet.c \
passphrase.c \
@@ -100,8 +101,8 @@ LINK = $(CC) $(LDFLAGS) -o $@
g10_OBJECTS = g10.o build-packet.o compress.o encode.o encr-data.o \
free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o keygen.o \
mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o rsa.o \
-openfile.o keyid.o parse-packet.o passphrase.o plaintext.o pubkey-enc.o \
-seckey-cert.o seskey.o sign.o comment.o sig-check.o
+openfile.o keyid.o trustdb.o parse-packet.o passphrase.o plaintext.o \
+pubkey-enc.o seckey-cert.o seskey.o sign.o comment.o sig-check.o
EXTRA_g10_SOURCES =
g10_LDADD = $(LDADD)
DIST_COMMON = Makefile.am Makefile.in
@@ -130,7 +131,8 @@ $(srcdir)/.deps/plaintext.P $(srcdir)/.deps/pubkey-enc.P \
$(srcdir)/.deps/ringedit.P $(srcdir)/.deps/rsa.P \
$(srcdir)/.deps/seckey-cert.P $(srcdir)/.deps/seskey.P \
$(srcdir)/.deps/sig-check.P $(srcdir)/.deps/sign.P \
-$(srcdir)/.deps/skclist.P $(srcdir)/.deps/textfilter.P
+$(srcdir)/.deps/skclist.P $(srcdir)/.deps/textfilter.P \
+$(srcdir)/.deps/trustdb.P
SOURCES = $(g10_SOURCES)
OBJECTS = $(g10_OBJECTS)
diff --git a/g10/encode.c b/g10/encode.c
index b73ee28d7..b0b148dd1 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -37,6 +37,7 @@
static int encode_simple( const char *filename, int mode );
+static int write_pubkey_enc_from_list( PKC_LIST pkc_list, DEK *dek, IOBUF out );
@@ -164,7 +165,7 @@ encode_crypt( const char *filename, STRLIST remusr )
cipher_filter_context_t cfx;
armor_filter_context_t afx;
compress_filter_context_t zfx;
- PKC_LIST pkc_list, pkc_rover;
+ PKC_LIST pkc_list;
memset( &cfx, 0, sizeof cfx);
memset( &afx, 0, sizeof afx);
@@ -203,31 +204,9 @@ encode_crypt( const char *filename, STRLIST remusr )
if( DBG_CIPHER )
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
- /* loop over all public key certificates */
- for( pkc_rover=pkc_list; pkc_rover; pkc_rover = pkc_rover->next ) {
- PKT_public_cert *pkc;
- PKT_pubkey_enc *enc;
-
- pkc = pkc_rover->pkc;
- enc = m_alloc_clear( sizeof *enc );
- enc->pubkey_algo = pkc->pubkey_algo;
- if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
- g10_elg_encrypt( pkc, enc, cfx.dek );
- else if( enc->pubkey_algo == PUBKEY_ALGO_RSA )
- g10_rsa_encrypt( pkc, enc, cfx.dek );
- else
- log_bug(NULL);
- /* and write it */
- init_packet(&pkt);
- pkt.pkttype = PKT_PUBKEY_ENC;
- pkt.pkt.pubkey_enc = enc;
- rc = build_packet( out, &pkt );
- free_pubkey_enc(enc);
- if( rc ) {
- log_error("build pubkey_enc packet failed: %s\n", g10_errstr(rc) );
- goto leave;
- }
- }
+ rc = write_pubkey_enc_from_list( pkc_list, cfx.dek, out );
+ if( rc )
+ goto leave;
/* setup the inner packet */
if( filename ) {
@@ -276,7 +255,6 @@ encode_crypt( const char *filename, STRLIST remusr )
/****************
* Filter to do a complete public key encryption.
*/
- #if 0
int
encrypt_filter( void *opaque, int control,
IOBUF a, byte *buf, size_t *ret_len)
@@ -289,6 +267,24 @@ encrypt_filter( void *opaque, int control,
log_bug(NULL); /* not used */
}
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
+ if( !efx->header_okay ) {
+ efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek );
+ efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
+ make_session_key( efx->cfx.dek );
+ if( DBG_CIPHER )
+ log_hexdump("DEK is: ",
+ efx->cfx.dek->key, efx->cfx.dek->keylen );
+
+ rc = write_pubkey_enc_from_list( efx->pkc_list, efx->cfx.dek, a );
+ if( rc )
+ return rc;
+
+ iobuf_push_filter( a, cipher_filter, &efx->cfx );
+
+ efx->header_okay = 1;
+ }
+ rc = iobuf_write( a, buf, size );
+
}
else if( control == IOBUFCTRL_FREE ) {
}
@@ -297,5 +293,41 @@ encrypt_filter( void *opaque, int control,
}
return rc;
}
- #endif
+
+
+/****************
+ * Write pubkey-enc packets from the list of PKCs to OUT.
+ */
+static int
+write_pubkey_enc_from_list( PKC_LIST pkc_list, DEK *dek, IOBUF out )
+{
+ PACKET pkt;
+ PKT_public_cert *pkc;
+ PKT_pubkey_enc *enc;
+ int rc;
+
+ for( ; pkc_list; pkc_list = pkc_list->next ) {
+
+ pkc = pkc_list->pkc;
+ enc = m_alloc_clear( sizeof *enc );
+ enc->pubkey_algo = pkc->pubkey_algo;
+ if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
+ g10_elg_encrypt( pkc, enc, dek );
+ else if( enc->pubkey_algo == PUBKEY_ALGO_RSA )
+ g10_rsa_encrypt( pkc, enc, dek );
+ else
+ log_bug(NULL);
+ /* and write it */
+ init_packet(&pkt);
+ pkt.pkttype = PKT_PUBKEY_ENC;
+ pkt.pkt.pubkey_enc = enc;
+ rc = build_packet( out, &pkt );
+ free_pubkey_enc(enc);
+ if( rc ) {
+ log_error("build pubkey_enc packet failed: %s\n", g10_errstr(rc) );
+ return rc;
+ }
+ }
+ return 0;
+}
diff --git a/g10/filter.h b/g10/filter.h
index 11c05e4a4..83ed3d153 100644
--- a/g10/filter.h
+++ b/g10/filter.h
@@ -65,6 +65,7 @@ typedef struct {
} cipher_filter_context_t;
+
typedef struct {
size_t linesize;
byte *line;
@@ -73,6 +74,9 @@ typedef struct {
int eof;
} text_filter_context_t;
+
+/* encrypt_filter_context_t defined in main.h */
+
/*-- mdfilter.c --*/
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
void free_md_filter_context( md_filter_context_t *mfx );
diff --git a/g10/g10.c b/g10/g10.c
index 1df800803..45fc6b66a 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -121,7 +121,7 @@ main( int argc, char **argv )
{ 'e', "encrypt", 0, "encrypt data" },
{ 'd', "decrypt", 0, "decrypt data (default)" },
/*{ 'c', "check", 0, "check a signature (default)" }, */
- { 'l', "local-user",2, "use this user-id to sign or decrypt" },
+ { 'u', "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" },
{ 511, "debug-all" ,0, "enable full debugging"},
@@ -135,13 +135,17 @@ main( int argc, char **argv )
{ 518, "options" , 2, "read options from file" },
{ 519, "no-armor", 0, "\r"},
{ 520, "no-default-keyring", 0, "\r" },
+ { 521, "list-packets",0,"list only the sequence of packets"},
+ { 522, "no-greeting", 0, "\r" },
+ { 523, "passphrase-fd",1, "\r" },
+ { 524, "edit-sig" ,0, "edit a key signature" },
{0} };
ARGPARSE_ARGS pargs;
IOBUF a;
int rc;
enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
- aTest, aPrintMDs, aSignKey, aClearsig
+ aTest, aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig,
} action = aNull;
int orig_argc;
char **orig_argv;
@@ -158,9 +162,10 @@ main( int argc, char **argv )
int default_config =1;
int errors=0;
int default_keyring = 1;
+ int greeting = 1;
- opt.compress = 0; /* defaults to no compression level */
+ opt.compress = -1; /* defaults to standard compress level */
/* check wether we have a config file on the commandline */
orig_argc = argc;
@@ -221,7 +226,7 @@ main( int argc, char **argv )
/* fall trough */
case 's': action = action == aEncr? aSignEncr : aSign; break;
case 't': action = aClearsig; break;
- case 'l': /* store the local users */
+ case 'u': /* store the local users */
sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
strcpy(sl->d, pargs.r.ret_str);
sl->next = locusr;
@@ -233,7 +238,7 @@ main( int argc, char **argv )
sl->next = remusr;
remusr = sl;
break;
- case 500: opt.batch = 1; break;
+ case 500: opt.batch = 1; greeting = 0; break;
case 501: opt.answer_yes = 1; break;
case 502: opt.answer_no = 1; break;
case 503: action = aKeygen; break;
@@ -259,6 +264,10 @@ main( int argc, char **argv )
break;
case 519: opt.no_armor=1; opt.armor=0; break;
case 520: default_keyring = 0; break;
+ case 521: action = aListPackets; break;
+ case 522: greeting = 0; break;
+ case 523: set_passphrase_fd( pargs.r.ret_int ); break;
+ case 524: action = aEditSig; break;
default : errors++; pargs.err = configfp? 1:2; break;
}
}
@@ -275,11 +284,11 @@ main( int argc, char **argv )
set_debug();
if( opt.verbose > 1 )
set_packet_list_mode(1);
- if( opt.verbose && isatty(fileno(stdin)) ) {
+ if( greeting ) {
if( *(s=strusage(10)) )
- fputs(s, stderr);
+ tty_printf("%s", s);
if( *(s=strusage(30)) )
- fputs(s, stderr);
+ tty_printf("%s", s);
}
if( !sec_nrings || default_keyring ) { /* add default secret rings */
@@ -347,6 +356,14 @@ main( int argc, char **argv )
log_error("sign_key('%s'): %s\n", fname_print, g10_errstr(rc) );
break;
+ case aEditSig: /* Edit a key signature */
+ if( argc != 1 )
+ usage(1);
+ /* note: fname is the user id! */
+ if( (rc = edit_keysigs(fname)) )
+ log_error("edit_keysig('%s'): %s\n", fname_print, g10_errstr(rc) );
+ break;
+
case aPrimegen:
if( argc == 1 ) {
@@ -388,6 +405,8 @@ main( int argc, char **argv )
case aTest: do_test( argc? atoi(*argv): 0 ); break;
+ case aListPackets:
+ opt.list_packets=1;
default:
if( argc > 1 )
usage(1);
@@ -398,6 +417,10 @@ main( int argc, char **argv )
memset( &afx, 0, sizeof afx);
iobuf_push_filter( a, armor_filter, &afx );
}
+ if( action == aListPackets ) {
+ set_packet_list_mode(1);
+ opt.list_packets=1;
+ }
proc_packets( a );
iobuf_close(a);
break;
@@ -406,7 +429,7 @@ main( int argc, char **argv )
/* cleanup */
FREE_STRLIST(remusr);
FREE_STRLIST(locusr);
- return 0;
+ return log_get_errorcount(0)? 2:0;
}
@@ -509,33 +532,5 @@ do_test(int times)
m_check(NULL);
#endif
- #if 0
- char *array;
- int i, j;
- int n = 6;
- int m = times;
-
- if( m > n )
- abort();
- array = m_alloc_clear( n );
- memset( array, 1, m );
-
- for(i=0;; i++) {
- printf("i=%3d: ", i );
- for(j=0; j < n ; j++ )
- if( array[j] )
- putchar( 'X' );
- else
- putchar( '-' );
- putchar('\n');
- m_out_of_n( array, m, n );
- for(j=0; j < n; j++ )
- if( !array[j] )
- break;
- if( j == m )
- break;
- }
- #endif
}
-
diff --git a/g10/kbnode.c b/g10/kbnode.c
index 844bafe6c..19e0870df 100644
--- a/g10/kbnode.c
+++ b/g10/kbnode.c
@@ -38,6 +38,7 @@ new_kbnode( PACKET *pkt )
n->pkt = pkt;
n->child = NULL;
n->flag = 0;
+ n->private_flag=0; /* kludge to delete a node */
return n;
}
@@ -58,6 +59,16 @@ release_kbnode( KBNODE n )
/****************
+ * Delete NODE from ROOT, ROOT must exist!
+ * Note does only work with walk_kbtree!!
+ */
+void
+delete_kbnode( KBNODE root, KBNODE node )
+{
+ node->private_flag |= 1;
+}
+
+/****************
* Append NODE to ROOT, ROOT must exist!
*/
void
@@ -116,26 +127,35 @@ find_kbparent( KBNODE root, KBNODE node )
KBNODE
walk_kbtree( KBNODE root, KBNODE *context )
{
+ return walk_kbtree2( root, context, 0 );
+}
+
+KBNODE
+walk_kbtree2( KBNODE root, KBNODE *context, int all )
+{
KBNODE n;
- if( !*context ) {
- *context = root;
- return root;
- }
+ do {
+ if( !*context ) {
+ *context = root;
+ return root;
+ }
+
+ n = *context;
+ if( n->child ) {
+ n = n->child;
+ *context = n;
+ }
+ else if( n->next ) {
+ n = n->next;
+ *context = n;
+ }
+ else if( (n = find_kbparent( root, n )) ) {
+ n = n->next;
+ *context = n;
+ }
+ } while( !all && n && (n->private_flag & 1) );
- n = *context;
- if( n->child ) {
- n = n->child;
- *context = n;
- }
- else if( n->next ) {
- n = n->next;
- *context = n;
- }
- else if( (n = find_kbparent( root, n )) ) {
- n = n->next;
- *context = n;
- }
return n;
}
@@ -147,3 +167,4 @@ clear_kbnode_flags( KBNODE n )
n->flag = 0;
}
}
+
diff --git a/g10/keydb.h b/g10/keydb.h
index f0d8b517b..cbca04cb9 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -41,6 +41,7 @@ struct kbnode_struct {
KBNODE next; /* used to form a link list */
KBNODE child;
int flag;
+ int private_flag;
};
/****************
@@ -81,6 +82,8 @@ void release_skc_list( SKC_LIST skc_list );
int build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock );
/*-- passphrase.h --*/
+void set_passphrase_fd( int fd );
+int get_passphrase_fd(void);
DEK *get_passphrase_hash( u32 *keyid, char *text );
int make_dek_from_passphrase( DEK *dek, int mode );
@@ -112,10 +115,12 @@ byte *fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len );
/*-- kbnode.c --*/
KBNODE new_kbnode( PACKET *pkt );
void release_kbnode( KBNODE n );
+void delete_kbnode( KBNODE root, KBNODE node );
void add_kbnode( KBNODE root, KBNODE node );
void add_kbnode_as_child( KBNODE root, KBNODE node );
KBNODE find_kbparent( KBNODE root, KBNODE node );
KBNODE walk_kbtree( KBNODE root, KBNODE *context );
+KBNODE walk_kbtree2( KBNODE root, KBNODE *context, int all );
void clear_kbnode_flags( KBNODE n );
/*-- ringedit.c --*/
diff --git a/g10/keyid.c b/g10/keyid.c
index 307e28c61..5848459c8 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -155,7 +155,7 @@ datestr_from_pkc( PKT_public_cert *pkc )
time_t atime = pkc->timestamp;
tp = gmtime( &atime );
- sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
+ sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
return buffer;
}
@@ -167,7 +167,7 @@ datestr_from_skc( PKT_secret_cert *skc )
time_t atime = skc->timestamp;
tp = gmtime( &atime );
- sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
+ sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
return buffer;
}
@@ -179,7 +179,7 @@ datestr_from_sig( PKT_signature *sig )
time_t atime = sig->timestamp;
tp = gmtime( &atime );
- sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
+ sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
return buffer;
}
diff --git a/g10/main.h b/g10/main.h
index 0d00dd19a..15caaab9a 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -28,15 +28,27 @@
#define DEFAULT_PUBKEY_ALGO PUBKEY_ALGO_ELGAMAL
#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_RMD160
+
+typedef struct {
+ int header_okay;
+ PKC_LIST pkc_list;
+ cipher_filter_context_t cfx;
+} encrypt_filter_context_t;
+
+
/*-- encode.c --*/
int encode_symmetric( const char *filename );
int encode_store( const char *filename );
int encode_crypt( const char *filename, STRLIST remusr );
+int encrypt_filter( void *opaque, int control,
+ IOBUF a, byte *buf, size_t *ret_len);
+
/*-- sign.c --*/
int sign_file( const char *filename, int detached, STRLIST locusr,
int encrypt, STRLIST remusr );
int sign_key( const char *username, STRLIST locusr );
+int edit_keysigs( const char *username );
/*-- sig-check.c --*/
int check_key_signature( KBNODE root, KBNODE node );
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 338ce3d2d..b46cb1344 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -46,7 +46,6 @@ typedef struct {
md_filter_context_t mfx;
DEK *dek;
int last_was_pubkey_enc;
- int opt_list;
KBNODE cert; /* the current certificate */
int have_data;
IOBUF iobuf; /* used to get the filename etc. */
@@ -198,7 +197,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
c->last_was_pubkey_enc = 1;
enc = pkt->pkt.pubkey_enc;
- printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );
+ /*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 */
@@ -213,11 +212,12 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
if( result == -1 )
;
- else if( !result )
- fputs( " DEK is good", stdout );
+ else if( !result ) {
+ if( opt.verbose > 1 )
+ log_info( "pubkey_enc packet: Good DEK\n" );
+ }
else
- printf( " %s", g10_errstr(result));
- putchar('\n');
+ log_error( "pubkey_enc packet: %s\n", g10_errstr(result));
free_packet(pkt);
}
@@ -228,7 +228,7 @@ proc_encrypted( CTX c, PACKET *pkt )
{
int result = 0;
- printf("dat: %sencrypted data\n", c->dek?"":"conventional ");
+ /*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 );
@@ -242,11 +242,13 @@ proc_encrypted( CTX c, PACKET *pkt )
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');
+ else if( !result ) {
+ if( opt.verbose > 1 )
+ log_info("encryption okay\n");
+ }
+ else {
+ log_error("encryption failed: %s\n", g10_errstr(result));
+ }
free_packet(pkt);
c->last_was_pubkey_enc = 0;
}
@@ -256,9 +258,10 @@ static void
proc_plaintext( CTX c, PACKET *pkt )
{
PKT_plaintext *pt = pkt->pkt.plaintext;
- int result;
+ int rc;
- printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
+ if( opt.verbose )
+ log_info("original file name='%.*s'\n", pt->namelen, pt->name);
free_md_filter_context( &c->mfx );
/* fixme: take the digest algo(s) to use from the
* onepass_sig packet (if we have these)
@@ -266,12 +269,9 @@ proc_plaintext( CTX c, PACKET *pkt )
* textmode filter (sigclass 0x01)
*/
c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
- result = handle_plaintext( pt, &c->mfx );
- if( !result )
- fputs( " okay", stdout);
- else
- printf( " %s", g10_errstr(result));
- putchar('\n');
+ rc = handle_plaintext( pt, &c->mfx );
+ if( rc )
+ log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
free_packet(pkt);
c->last_was_pubkey_enc = 0;
}
@@ -281,15 +281,12 @@ static void
proc_compressed( CTX c, PACKET *pkt )
{
PKT_compressed *zd = pkt->pkt.compressed;
- int result;
+ int rc;
- printf("zip: compressed data packet\n");
- result = handle_compressed( zd );
- if( !result )
- fputs( " okay", stdout);
- else
- printf( " %s", g10_errstr(result));
- putchar('\n');
+ /*printf("zip: compressed data packet\n");*/
+ rc = handle_compressed( zd );
+ if( rc )
+ log_error("uncompressing failed: %s\n", g10_errstr(rc));
free_packet(pkt);
c->last_was_pubkey_enc = 0;
}
@@ -505,7 +502,6 @@ proc_packets( IOBUF a )
u32 keyid[2];
int newpkt;
- c->opt_list = 1;
c->iobuf = a;
init_packet(pkt);
while( (rc=parse_packet(a, pkt)) != -1 ) {
@@ -522,17 +518,27 @@ proc_packets( IOBUF a )
continue;
}
newpkt = -1;
- switch( pkt->pkttype ) {
- case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break;
- case PKT_SECRET_CERT: newpkt = add_secret_cert( 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_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( opt.list_packets ) {
+ switch( pkt->pkttype ) {
+ case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
+ case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
+ case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
+ default: newpkt = 0; break;
+ }
+ }
+ else {
+ switch( pkt->pkttype ) {
+ case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break;
+ case PKT_SECRET_CERT: newpkt = add_secret_cert( 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_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( pkt->pkttype != PKT_SIGNATURE )
c->have_data = pkt->pkttype == PKT_PLAINTEXT;
@@ -575,13 +581,16 @@ proc_tree( CTX c, KBNODE node )
KBNODE n1;
int rc;
+ if( opt.list_packets )
+ return;
+
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");
+ log_error("proc_tree: onepass_sig without data\n");
else if( node->child->pkt->pkttype != PKT_SIGNATURE )
log_error("proc_tree: onepass_sig not followed by signature\n");
else { /* check all signatures */
@@ -611,6 +620,8 @@ proc_tree( CTX c, KBNODE node )
log_error("BAD signature from ");
print_keyid( stderr, sig->keyid );
putc('\n', stderr);
+ if( opt.batch )
+ exit(1);
}
else
log_error("Can't check signature made by %08lX: %s\n",
diff --git a/g10/options.h b/g10/options.h
index c1aea3f95..31aa95522 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -35,7 +35,7 @@ struct {
int fingerprint; /* list fingerprints */
int list_sigs; /* list signatures */
int no_armor;
- int reserved5;
+ int list_packets; /* list-packets mode */
int reserved6;
int reserved7;
int reserved8;
diff --git a/g10/packet.h b/g10/packet.h
index f7dbf9734..4a5a5a3cc 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -210,6 +210,7 @@ struct packet_struct {
/*-- mainproc.c --*/
int proc_packets( IOBUF a );
+int list_packets( IOBUF a );
/*-- parse-packet.c --*/
int set_packet_list_mode( int mode );
diff --git a/g10/passphrase.c b/g10/passphrase.c
index a974ca9f5..df8ac7176 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -25,13 +25,27 @@
#include <assert.h>
#include "util.h"
#include "memory.h"
+#include "options.h"
#include "ttyio.h"
#include "cipher.h"
#include "keydb.h"
+static int pwfd = -1;
static int hash_passphrase( DEK *dek, char *pw );
+void
+set_passphrase_fd( int fd )
+{
+ pwfd = fd;
+}
+
+int
+get_passphrase_fd()
+{
+ return pwfd;
+}
+
/****************
* Get a passphrase for the secret key with KEYID, display TEXT
@@ -41,35 +55,51 @@ static int hash_passphrase( DEK *dek, char *pw );
DEK *
get_passphrase_hash( u32 *keyid, char *text )
{
- char *p=NULL, *pw;
+ char *pw;
DEK *dek;
- if( keyid ) {
+ if( keyid && !opt.batch ) {
char *ustr;
- tty_printf("\nNeed a pass phrase to unlock the secret key!\n");
- tty_printf("KeyID: " );
+ tty_printf("Need a pass phrase to unlock the secret key for:\n");
+ tty_printf(" \"" );
ustr = get_user_id_string( keyid );
tty_print_string( ustr, strlen(ustr) );
m_free(ustr);
- tty_printf("\n\n");
+ tty_printf("\"\n\n");
}
- if( keyid && (p=getenv("G10PASSPHRASE")) ) {
- pw = m_alloc_secure(strlen(p)+1);
- strcpy(pw,p);
- tty_printf("Taking it from $G10PASSPHRASE !\n", keyid[1] );
+ if( pwfd != -1 ) { /* read the passphrase from the given descriptor */
+ int i, len;
+
+ if( !opt.batch )
+ tty_printf("Reading from file descriptor %d ...", pwfd );
+ for( pw = NULL, i = len = 100; ; i++ ) {
+ if( i >= len-1 ) {
+ char *pw2 = pw;
+ len += 100;
+ pw = m_alloc_secure( len );
+ if( pw2 )
+ memcpy(pw, pw2, i );
+ i=0;
+ }
+ if( read( pwfd, pw+i, 1) != 1 || pw[i] == '\n' )
+ break;
+ }
+ pw[i] = 0;
+ if( !opt.batch )
+ tty_printf("\b\b\b \n" );
}
- else
+ else if( opt.batch )
+ log_fatal("Can't query password in batchmode\n");
+ else {
pw = tty_get_hidden("Enter pass phrase: " );
+ tty_kill_prompt();
+ }
dek = m_alloc_secure( sizeof *dek );
dek->algo = CIPHER_ALGO_BLOWFISH;
if( hash_passphrase( dek, pw ) )
log_bug("get_passphrase_hash\n");
m_free(pw); /* is allocated in secure memory, so it will be burned */
- if( !p ) {
- tty_kill_prompt();
- tty_printf("\n");
- }
return dek;
}
@@ -89,6 +119,7 @@ make_dek_from_passphrase( DEK *dek, int mode )
tty_kill_prompt();
if( mode == 2 ) {
pw2 = tty_get_hidden("Repeat pass phrase: " );
+ tty_kill_prompt();
if( strcmp(pw, pw2) ) {
m_free(pw2);
m_free(pw);
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 85d93b4f9..c1ea596ac 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -65,6 +65,7 @@ check_elg( PKT_secret_cert *cert )
unsigned nbytes;
u32 keyid[2];
ELG_secret_key skey;
+ char save_iv[8];
if( cert->d.elg.is_protected ) { /* remove the protection */
DEK *dek = NULL;
@@ -80,6 +81,7 @@ check_elg( PKT_secret_cert *cert )
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
m_free(dek); /* pw is in secure memory, so m_free() burns it */
blowfish_setiv( blowfish_ctx, NULL );
+ memcpy(save_iv, cert->d.elg.protect.blowfish.iv, 8 );
blowfish_decode_cfb( blowfish_ctx,
cert->d.elg.protect.blowfish.iv,
cert->d.elg.protect.blowfish.iv, 8 );
@@ -94,6 +96,7 @@ check_elg( PKT_secret_cert *cert )
/* now let's see wether we have used the right passphrase */
if( csum != cert->d.elg.csum ) {
mpi_free(test_x);
+ memcpy( cert->d.elg.protect.blowfish.iv, save_iv, 8 );
return G10ERR_BAD_PASS;
}
@@ -105,6 +108,7 @@ check_elg( PKT_secret_cert *cert )
memset( &skey, 0, sizeof skey );
if( !res ) {
mpi_free(test_x);
+ memcpy( cert->d.elg.protect.blowfish.iv, save_iv, 8 );
return G10ERR_BAD_PASS;
}
mpi_set(cert->d.elg.x, test_x);
@@ -274,6 +278,8 @@ check_secret_key( PKT_secret_cert *cert )
#endif
else
rc = G10ERR_PUBKEY_ALGO;
+ if( get_passphrase_fd() != -1 )
+ break;
}
return rc;
}
diff --git a/g10/sign.c b/g10/sign.c
index 67e229f29..a8541391d 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -79,6 +79,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
compress_filter_context_t zfx;
md_filter_context_t mfx;
text_filter_context_t tfx;
+ encrypt_filter_context_t efx;
IOBUF inp = NULL, out = NULL;
PACKET pkt;
PKT_plaintext *pt = NULL;
@@ -92,6 +93,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
memset( &zfx, 0, sizeof zfx);
memset( &mfx, 0, sizeof mfx);
memset( &tfx, 0, sizeof tfx);
+ memset( &efx, 0, sizeof efx);
init_packet( &pkt );
if( (rc=build_skc_list( locusr, &skc_list, 1 )) )
@@ -127,8 +129,9 @@ sign_file( const char *filename, int detached, STRLIST locusr,
iobuf_push_filter( out, compress_filter, &zfx );
if( encrypt ) {
- /* prepare for encryption */
- /* FIXME!!!!!!! */
+ efx.pkc_list = pkc_list;
+ /* fixme: set efx.cfx.datalen if known */
+ iobuf_push_filter( out, encrypt_filter, &efx );
}
/* loop over the secret certificates and build headers */
@@ -348,7 +351,15 @@ sign_it_p( PKT_public_cert *pkc, PKT_user_id *uid )
}
-static void
+/****************
+ * Check the keysigs and set the flags to indicate errors.
+ * Usage of nodes flag bits:
+ * Bit 0 = bad signature
+ * 1 = no public key
+ * 2 = other error
+ * Returns true if error found.
+ */
+static int
check_all_keysigs( KBNODE keyblock )
{
KBNODE kbctx;
@@ -384,6 +395,7 @@ check_all_keysigs( KBNODE keyblock )
m_free(p);
}
tty_printf("\n");
+ /* FIXME: update the trustdb */
}
}
if( inv_sigs )
@@ -392,6 +404,76 @@ check_all_keysigs( KBNODE keyblock )
tty_printf("No public key for %d signatures\n", no_key );
if( oth_err )
tty_printf("%d signatures not checked due to errors\n", oth_err );
+ return inv_sigs || no_key || oth_err;
+}
+
+
+/****************
+ * Ask and remove invalid signatures are to be removed.
+ */
+static int
+remove_keysigs( KBNODE keyblock, int all )
+{
+ KBNODE kbctx;
+ KBNODE node;
+ char *answer;
+ int yes;
+ int count;
+
+ count = 0;
+ for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
+ if( ((node->flag & 7) || all )
+ && node->pkt->pkttype == PKT_SIGNATURE
+ && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
+ PKT_signature *sig = node->pkt->pkt.signature;
+ int sigrc;
+
+ if( all ) {
+ /* fixme: skip self-sig */
+ }
+
+ tty_printf("\n \"%08lX %s ",
+ sig->keyid[1], datestr_from_sig(sig));
+ if( node->flag & 6 )
+ tty_printf("[User name not available] ");
+ else {
+ size_t n;
+ char *p = get_user_id( sig->keyid, &n );
+ tty_print_string( p, n );
+ m_free(p);
+ }
+ tty_printf("\"\n");
+ if( node->flag & 1 )
+ tty_printf("This is a BAD signature!\n");
+ else if( node->flag & 2 )
+ tty_printf("Public key not available.\n");
+ else if( node->flag & 4 )
+ tty_printf("The signature could not be checked!\n");
+ answer = tty_get("\nRemove this signature? ");
+ tty_kill_prompt();
+ if( answer_is_yes(answer) ) {
+ node->flag |= 128; /* use bit 7 to mark this node */
+ count++;
+ }
+ m_free(answer);
+ }
+ }
+
+ if( !count )
+ return 0; /* nothing to remove */
+ answer = tty_get("Do you really want to remove the selected signatures? ");
+ tty_kill_prompt();
+ yes = answer_is_yes(answer);
+ m_free(answer);
+ if( !yes )
+ return 0;
+
+ for( kbctx=NULL; (node=walk_kbtree2( keyblock, &kbctx, 1)) ; ) {
+ if( node->flag & 128)
+ delete_kbnode( keyblock, node );
+ }
+
+ return 1;
}
@@ -414,6 +496,7 @@ sign_key( const char *username, STRLIST locusr )
PKT_public_cert *pkc;
int any;
u32 pkc_keyid[2];
+ char *answer;
memset( &mfx, 0, sizeof mfx);
@@ -464,9 +547,16 @@ sign_key( const char *username, STRLIST locusr )
}
clear_kbnode_flags( keyblock );
- check_all_keysigs( keyblock );
- /* look wether we should ask to remove invalid keys */
- /*+ FIXME: */
+ if( check_all_keysigs( keyblock ) ) {
+ if( !opt.batch ) {
+ /* ask wether we really should do anything */
+ answer = tty_get("To you want to remove some of the invalid sigs? ");
+ tty_kill_prompt();
+ if( answer_is_yes(answer) )
+ remove_keysigs( keyblock, 0 );
+ m_free(answer);
+ }
+ }
/* check wether we have already signed it */
for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
@@ -524,7 +614,7 @@ sign_key( const char *username, STRLIST locusr )
rc = update_keyblock( &kbpos, keyblock );
if( rc ) {
- log_error("insert_keyblock failed: %s\n", g10_errstr(rc) );
+ log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
goto leave;
}
@@ -537,6 +627,75 @@ sign_key( const char *username, STRLIST locusr )
+int
+edit_keysigs( const char *username )
+{
+ int rc = 0;
+ KBNODE keyblock = NULL;
+ KBNODE kbctx, node;
+ KBPOS kbpos;
+ PKT_public_cert *pkc;
+ int any;
+ u32 pkc_keyid[2];
+ char *answer;
+
+ /* search the userid */
+ rc = search_keyblock_byname( &kbpos, username );
+ if( rc ) {
+ log_error("user '%s' not found\n", username );
+ goto leave;
+ }
+
+ /* read the keyblock */
+ rc = read_keyblock( &kbpos, &keyblock );
+ if( rc ) {
+ log_error("error reading the certificate: %s\n", g10_errstr(rc) );
+ goto leave;
+ }
+
+ /* get the keyid from the keyblock */
+ for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
+ if( node->pkt->pkttype == PKT_PUBLIC_CERT )
+ break;
+ }
+ if( !node ) {
+ log_error("Oops; public key not found anymore!\n");
+ rc = G10ERR_GENERAL;
+ goto leave;
+ }
+
+ pkc = node->pkt->pkt.public_cert;
+ keyid_from_pkc( pkc, pkc_keyid );
+ log_info("Checking signatures of this public key certificate:\n");
+ tty_printf("pub %4u%c/%08lX %s ",
+ nbits_from_pkc( pkc ),
+ pubkey_letter( pkc->pubkey_algo ),
+ pkc_keyid[1], datestr_from_pkc(pkc) );
+ {
+ size_t n;
+ char *p = get_user_id( pkc_keyid, &n );
+ tty_print_string( p, n > 40? 40 : n );
+ m_free(p);
+ tty_printf("\n");
+ }
+
+ clear_kbnode_flags( keyblock );
+ check_all_keysigs( keyblock );
+ if( remove_keysigs( keyblock, 1 ) ) {
+ rc = update_keyblock( &kbpos, keyblock );
+ if( rc ) {
+ log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
+ goto leave;
+ }
+ }
+
+ leave:
+ release_kbnode( keyblock );
+ return rc;
+}
+
+
+
/****************
* Create a signature packet for the given public key certificate
* and the user id and return it in ret_sig. User signature class SIGCLASS
diff --git a/g10/trustdb.c b/g10/trustdb.c
new file mode 100644
index 000000000..00774f572
--- /dev/null
+++ b/g10/trustdb.c
@@ -0,0 +1,35 @@
+/* trustdb.c
+ * Copyright (c) 1997 by Werner Koch (dd9jn)
+ *
+ * This file is part of G10.
+ *
+ * G10 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * G10 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "errors.h"
+#include "iobuf.h"
+#include "keydb.h"
+#include "memory.h"
+#include "util.h"
+
+
+