aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog14
-rw-r--r--g10/encode.c110
-rw-r--r--g10/g10.c35
-rw-r--r--g10/main.h15
-rw-r--r--g10/sign.c4
5 files changed, 128 insertions, 50 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 3918b528c..b1c3488b0 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,17 @@
+2003-11-12 David Shaw <[email protected]>
+
+ * g10.c (main): Add --symmetric --sign --encrypt.
+
+ * main.h, encode.c (setup_symkey): New. Prompt for a passphrase
+ and create a DEK for symmetric encryption.
+ (write_symkey_enc): New. Write out symmetrically encrypted
+ session keys.
+ (encode_crypt, encrypt_filter): Use them here here when creating a
+ message that can be decrypted with a passphrase or a pk.
+
+ * sign.c (sign_file): Call setup_symkey if we are doing a
+ --symmetric --sign --encrypt.
+
2003-11-09 David Shaw <[email protected]>
* mainproc.c (proc_symkey_enc): Don't show algorithm information
diff --git a/g10/encode.c b/g10/encode.c
index dfde96234..b291ecefd 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -371,6 +371,53 @@ encode_simple( const char *filename, int mode, int use_seskey )
return rc;
}
+int
+setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek)
+{
+ *symkey_s2k=m_alloc_clear(sizeof(STRING2KEY));
+ (*symkey_s2k)->mode = opt.s2k_mode;
+ (*symkey_s2k)->hash_algo = opt.s2k_digest_algo;
+
+ *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo,
+ *symkey_s2k,2,NULL,NULL);
+ if(!*symkey_dek || !(*symkey_dek)->keylen)
+ {
+ m_free(*symkey_dek);
+ m_free(*symkey_s2k);
+ return G10ERR_PASSPHRASE;
+ }
+
+ return 0;
+}
+
+static int
+write_symkey_enc(STRING2KEY *symkey_s2k,DEK *symkey_dek,DEK *dek,IOBUF out)
+{
+ int rc,seskeylen=cipher_get_keylen(dek->algo)/8;
+
+ PKT_symkey_enc *enc;
+ byte enckey[33];
+ PACKET pkt;
+
+ enc=m_alloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
+ encode_seskey(symkey_dek,&dek,enckey);
+
+ enc->version = 4;
+ enc->cipher_algo = opt.s2k_cipher_algo;
+ enc->s2k = *symkey_s2k;
+ enc->seskeylen = seskeylen + 1; /* algo id */
+ memcpy( enc->seskey, enckey, seskeylen + 1 );
+
+ pkt.pkttype = PKT_SYMKEY_ENC;
+ pkt.pkt.symkey_enc = enc;
+
+ if((rc=build_packet(out,&pkt)))
+ log_error("build symkey_enc packet failed: %s\n",g10_errstr(rc));
+
+ m_free(enc);
+ return rc;
+}
+
/****************
* Encrypt the file with the given userids (or ask if none
* is supplied).
@@ -399,25 +446,13 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
memset( &tfx, 0, sizeof tfx);
init_packet(&pkt);
+ if(use_symkey
+ && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
+ return rc;
+
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
return rc;
- if(use_symkey)
- {
- symkey_s2k=m_alloc_clear(sizeof(STRING2KEY));
- symkey_s2k->mode = opt.s2k_mode;
- symkey_s2k->hash_algo = opt.s2k_digest_algo;
-
- symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo,
- symkey_s2k,2,NULL,NULL);
- if(!symkey_dek || !symkey_dek->keylen)
- {
- m_free(symkey_dek);
- m_free(symkey_s2k);
- return G10ERR_PASSPHRASE;
- }
- }
-
if(PGP2) {
for(work_list=pk_list; work_list; work_list=work_list->next)
if(!(is_RSA(work_list->pk->pubkey_algo) &&
@@ -524,32 +559,8 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
seems to be the most useful on the recipient side - there is no
point in prompting a user for a passphrase if they have the
secret key needed to decrypt. */
- if(use_symkey)
- {
- int seskeylen=cipher_get_keylen(cfx.dek->algo)/8;
- PKT_symkey_enc *enc;
- byte enckey[33];
-
- enc=m_alloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
- encode_seskey(symkey_dek,&cfx.dek,enckey);
-
- enc->version = 4;
- enc->cipher_algo = opt.s2k_cipher_algo;
- enc->s2k = *symkey_s2k;
- enc->seskeylen = seskeylen + 1; /* algo id */
- memcpy( enc->seskey, enckey, seskeylen + 1 );
-
- pkt.pkttype = PKT_SYMKEY_ENC;
- pkt.pkt.symkey_enc = enc;
- if( (rc = build_packet( out, &pkt )) )
- {
- log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
- m_free(enc);
- goto leave;
- }
-
- m_free(enc);
- }
+ if(use_symkey && (rc=write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
+ goto leave;
if (!opt.no_literal) {
/* setup the inner packet */
@@ -723,6 +734,14 @@ encrypt_filter( void *opaque, int control,
if( rc )
return rc;
+ if(efx->symkey_s2k && efx->symkey_dek)
+ {
+ rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek,
+ efx->cfx.dek,a);
+ if(rc)
+ return rc;
+ }
+
iobuf_push_filter( a, cipher_filter, &efx->cfx );
efx->header_okay = 1;
@@ -730,8 +749,11 @@ encrypt_filter( void *opaque, int control,
rc = iobuf_write( a, buf, size );
}
- else if( control == IOBUFCTRL_FREE ) {
- }
+ else if( control == IOBUFCTRL_FREE )
+ {
+ m_free(efx->symkey_dek);
+ m_free(efx->symkey_s2k);
+ }
else if( control == IOBUFCTRL_DESC ) {
*(char**)buf = "encrypt_filter";
}
diff --git a/g10/g10.c b/g10/g10.c
index eeb9101b9..b38a728e4 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -87,6 +87,7 @@ enum cmd_and_opt_values
aStore,
aKeygen,
aSignEncr,
+ aSignEncrSym,
aSignSym,
aSignKey,
aLSignKey,
@@ -879,6 +880,12 @@ set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
cmd = aEncrSym;
else if( cmd == aKMode && new_cmd == aSym )
cmd = aKModeC;
+ else if (cmd == aSignEncr && new_cmd == aSym)
+ cmd = aSignEncrSym;
+ else if (cmd == aSignSym && new_cmd == aEncr)
+ cmd = aSignEncrSym;
+ else if (cmd == aEncrSym && new_cmd == aSign)
+ cmd = aSignEncrSym;
else if( ( cmd == aSign && new_cmd == aClearsign )
|| ( cmd == aClearsign && new_cmd == aSign ) )
cmd = aClearsign;
@@ -2543,10 +2550,36 @@ main( int argc, char **argv )
else
sl = NULL;
if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
- log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
+ log_error("%s: sign+encrypt failed: %s\n",
+ print_fname_stdin(fname), g10_errstr(rc) );
free_strlist(sl);
break;
+ case aSignEncrSym: /* sign and encrypt the given file */
+ if( argc > 1 )
+ wrong_args(_("--symmetric --sign --encrypt [filename]"));
+ else if(opt.s2k_mode==0)
+ log_error(_("you cannot use --symmetric --sign --encrypt"
+ " with --s2k-mode 0\n"));
+ else if(PGP2 || PGP6 || PGP7 || RFC1991)
+ log_error(_("you cannot use --symmetric --sign --encrypt"
+ " while in %s mode\n"),compliance_option_string());
+ else
+ {
+ if( argc )
+ {
+ sl = m_alloc_clear( sizeof *sl + strlen(fname));
+ strcpy(sl->d, fname);
+ }
+ else
+ sl = NULL;
+ if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
+ log_error("%s: symmetric+sign+encrypt failed: %s\n",
+ print_fname_stdin(fname), g10_errstr(rc) );
+ free_strlist(sl);
+ }
+ break;
+
case aSignSym: /* sign and conventionally encrypt the given file */
if (argc > 1)
wrong_args(_("--sign --symmetric [filename]"));
diff --git a/g10/main.h b/g10/main.h
index 1288790db..8afde1104 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -1,5 +1,6 @@
/* main.h
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -32,10 +33,13 @@
#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_SHA1
#define DEFAULT_COMPRESS_ALGO COMPRESS_ALGO_ZIP
-typedef struct {
- int header_okay;
- PK_LIST pk_list;
- cipher_filter_context_t cfx;
+typedef struct
+{
+ int header_okay;
+ PK_LIST pk_list;
+ DEK *symkey_dek;
+ STRING2KEY *symkey_s2k;
+ cipher_filter_context_t cfx;
} encrypt_filter_context_t;
struct groupitem
@@ -110,6 +114,7 @@ int parse_options(char *str,unsigned int *options,struct parse_options *opts);
void display_online_help( const char *keyword );
/*-- encode.c --*/
+int setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek);
int encode_symmetric( const char *filename );
int encode_store( const char *filename );
int encode_crypt( const char *filename, STRLIST remusr, int use_symkey );
diff --git a/g10/sign.c b/g10/sign.c
index b24e68f89..e595ce9b1 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -723,6 +723,10 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
if( fname && filenames->next && (!detached || encryptflag) )
log_bug("multiple files can only be detached signed");
+ if(encryptflag==2
+ && (rc=setup_symkey(&efx.symkey_s2k,&efx.symkey_dek)))
+ goto leave;
+
if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991)
duration=ask_expire_interval(1);