Updated from latest NewPG project
[gnupg.git] / sm / encrypt.c
index aba1dc1..40e1258 100644 (file)
@@ -58,37 +58,6 @@ struct encrypt_cb_parm_s {
 };
 
 
-static KsbaCert
-get_default_recipient (void)
-{
-  const char key[] =
-    "CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=#44FC7373656C646F7266#,C=DE";
-
-  KsbaCert cert = NULL;
-  KEYDB_HANDLE kh = NULL;
-  int rc;
-
-  kh = keydb_new (0);
-  if (!kh)
-    return NULL;
-
-  rc = keydb_search_subject (kh, key);
-  if (rc)
-    {
-      log_debug ("failed to find default certificate: rc=%d\n", rc);
-    }
-  else 
-    {
-      rc = keydb_get_cert (kh, &cert);
-      if (rc)
-        {
-          log_debug ("failed to get cert: rc=%d\n", rc);
-        }
-    }
-
-  keydb_release (kh);
-  return cert;
-}
 
 
 \f
@@ -96,10 +65,11 @@ get_default_recipient (void)
 static int
 init_dek (DEK dek)
 {
-  int rc=0, i;
+  int rc=0, mode, i;
 
   dek->algo = gcry_cipher_map_name (dek->algoid);
-  if (!dek->algo)
+  mode = gcry_cipher_mode_from_oid (dek->algoid);
+  if (!dek->algo || !mode)
     {
       log_error ("unsupported algorithm `%s'\n", dek->algoid);
       return GNUPG_Unsupported_Algorithm;
@@ -119,10 +89,7 @@ init_dek (DEK dek)
       return GNUPG_Unsupported_Algorithm;
     }
   
-
-  dek->chd = gcry_cipher_open (dek->algo,
-                               GCRY_CIPHER_MODE_CBC,
-                               GCRY_CIPHER_SECURE);
+  dek->chd = gcry_cipher_open (dek->algo, mode, GCRY_CIPHER_SECURE);
   if (!dek->chd)
     {
       log_error ("failed to create cipher context: %s\n", gcry_strerror (-1));
@@ -241,7 +208,7 @@ encrypt_dek (const DEK dek, KsbaCert cert, char **encval)
 {
   GCRY_SEXP s_ciph, s_data, s_pkey;
   int rc;
-  char *buf;
+  KsbaSexp buf;
   size_t len;
 
   *encval = NULL;
@@ -253,7 +220,13 @@ encrypt_dek (const DEK dek, KsbaCert cert, char **encval)
       log_error ("no public key for recipient\n");
       return GNUPG_No_Public_Key;
     }
-  rc = gcry_sexp_sscan (&s_pkey, NULL, buf, strlen(buf));
+  len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
+  if (!len)
+    {
+      log_error ("libksba did not return a proper S-Exp\n");
+      return GNUPG_Bug;
+    }
+  rc = gcry_sexp_sscan (&s_pkey, NULL, buf, len);
   xfree (buf); buf = NULL;
   if (rc)
     {
@@ -369,9 +342,10 @@ encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
 /* Perform an encrypt operation.  
 
    Encrypt the data received on DATA-FD and write it to OUT_FP.  The
-   recipients are hardwired for now. */
+   recipients are take from the certificate given in recplist; if this
+   is NULL it will be encrypted for a default recipient */
 int
-gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
+gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
 {
   int rc = 0;
   Base64Context b64writer = NULL;
@@ -385,9 +359,18 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
   DEK dek = NULL;
   int recpno;
   FILE *data_fp = NULL;
-
+  CERTLIST cl;
 
   memset (&encparm, 0, sizeof encparm);
+
+  if (!recplist)
+    {
+      log_error(_("no valid recipients given\n"));
+      gpgsm_status (ctrl, STATUS_NO_RECP, "0");
+      rc = GNUPG_No_Public_Key;
+      goto leave;
+    }
+
   kh = keydb_new (0);
   if (!kh)
     {
@@ -416,6 +399,7 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
     }
   encparm.fp = data_fp;
 
+  ctrl->pem_name = "ENCRYPTED MESSAGE";
   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
@@ -458,7 +442,7 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
     rc = GNUPG_Out_Of_Core;
   else
   {
-    dek->algoid = "1.2.840.113549.3.7";  /*des-EDE3-CBC*/
+    dek->algoid = opt.def_cipher_algoid;
     rc = init_dek (dek);
   }
   if (rc)
@@ -478,9 +462,8 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
     }
 
   encparm.dek = dek;
-  /* fixme: we should use a larger buffer - the small one is better
-     for testing */
-  encparm.bufsize = 10 * dek->ivlen;
+  /* Use a ~8k (AES) or ~4k (3DES) buffer */
+  encparm.bufsize = 500 * dek->ivlen;
   encparm.buffer = xtrymalloc (encparm.bufsize);
   if (!encparm.buffer)
     {
@@ -490,40 +473,27 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
 
   /* gather certificates of recipients, encrypt the session key for
      each and store them in the CMS object */
-  for (recpno = 0; recpno < 1; recpno++)
+  for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
     {
-      KsbaCert cert;
       char *encval;
       
-      /* fixme: get the recipients out of the arguments passed to us */
-      cert = get_default_recipient ();
-      if (!cert)
-        {
-          log_error ("no default recipient found\n");
-          rc = seterr (General_Error);
-          goto leave;
-        }
-      
-      rc = encrypt_dek (dek, cert, &encval);
+      rc = encrypt_dek (dek, cl->cert, &encval);
       if (rc)
         {
           log_error ("encryption failed for recipient no. %d: %s\n",
                      recpno, gnupg_strerror (rc));
-          ksba_cert_release (cert);
           goto leave;
         }
       
-      err = ksba_cms_add_recipient (cms, cert);
+      err = ksba_cms_add_recipient (cms, cl->cert);
       if (err)
         {
           log_error ("ksba_cms_add_recipient failed: %s\n",
                      ksba_strerror (err));
           rc = map_ksba_err (err);
           xfree (encval);
-          ksba_cert_release (cert);
           goto leave;
         }
-      cert = NULL; /* cms does now own the certificate */
       
       err = ksba_cms_set_enc_val (cms, recpno, encval);
       xfree (encval);
@@ -547,7 +517,6 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
           rc = map_ksba_err (err);
           goto leave;
         }
-      log_debug ("ksba_cms_build - stop reason %d\n", stopreason);
     }
   while (stopreason != KSBA_SR_READY);