* g10.c (main): Add --symmetric --sign --encrypt.
authorDavid Shaw <dshaw@jabberwocky.com>
Thu, 13 Nov 2003 02:54:12 +0000 (02:54 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Thu, 13 Nov 2003 02:54:12 +0000 (02:54 +0000)
* 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.

g10/ChangeLog
g10/encode.c
g10/g10.c
g10/main.h
g10/sign.c

index 3918b52..b1c3488 100644 (file)
@@ -1,3 +1,17 @@
+2003-11-12  David Shaw  <dshaw@jabberwocky.com>
+
+       * 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  <dshaw@jabberwocky.com>
 
        * mainproc.c (proc_symkey_enc): Don't show algorithm information
index dfde962..b291ece 100644 (file)
@@ -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";
     }
index eeb9101..b38a728 100644 (file)
--- 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]"));
index 1288790..8afde11 100644 (file)
@@ -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.
  *
 #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 );
index b24e68f..e595ce9 100644 (file)
@@ -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);