gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
[gnupg.git] / g10 / call-agent.c
index ed141da..4ce6a06 100644 (file)
@@ -336,7 +336,7 @@ default_inq_cb (void *opaque, const char *line)
   gpg_error_t err = 0;
   struct default_inq_parm_s *parm = opaque;
 
-  if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
+  if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
     {
       err = gpg_proxy_pinentry_notify (parm->ctrl, line);
       if (err)
@@ -344,7 +344,8 @@ default_inq_cb (void *opaque, const char *line)
                    "PINENTRY_LAUNCHED");
       /* We do not pass errors to avoid breaking other code.  */
     }
-  else if (!strncmp (line, "PASSPHRASE", 10) && (line[10]==' '||!line[10])
+  else if ((has_leading_keyword (line, "PASSPHRASE")
+            || has_leading_keyword (line, "NEW_PASSPHRASE"))
            && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
     {
       if (have_static_passphrase ())
@@ -599,6 +600,34 @@ agent_learn (struct agent_card_info_s *info)
   return rc;
 }
 
+
+int
+agent_keytocard (const char *hexgrip, int keyno, int force,
+                 const char *serialno, const char *timestamp)
+{
+  int rc;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+  parm.ctx = agent_ctx;
+
+  snprintf (line, DIM(line)-1, "KEYTOCARD %s%s %s OPENPGP.%d %s",
+            force?"--force ": "", hexgrip, serialno, keyno, timestamp);
+  line[DIM(line)-1] = 0;
+
+  rc = start_agent (NULL, 1);
+  if (rc)
+    return rc;
+
+  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
+                        NULL, NULL);
+  if (rc)
+    return rc;
+
+  return rc;
+}
+\f
 /* Call the agent to retrieve a data object.  This function returns
    the data in the same structure as used by the learn command.  It is
    allowed to update such a structure using this commmand. */
@@ -696,7 +725,7 @@ inq_writecert_parms (void *opaque, const char *line)
   int rc;
   struct writecert_parm_s *parm = opaque;
 
-  if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
+  if (has_leading_keyword (line, "CERTDATA"))
     {
       rc = assuan_send_data (parm->dflt->ctx,
                              parm->certdata, parm->certdatalen);
@@ -749,7 +778,7 @@ inq_writekey_parms (void *opaque, const char *line)
   int rc;
   struct writekey_parm_s *parm = opaque;
 
-  if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
+  if (has_leading_keyword (line, "KEYDATA"))
     {
       rc = assuan_send_data (parm->dflt->ctx, parm->keydata, parm->keydatalen);
     }
@@ -1442,9 +1471,9 @@ keyinfo_status_cb (void *opaque, const char *line)
   char **serialno = opaque;
   const char *s, *s2;
 
-  if (!strncmp (line, "KEYINFO ", 8) && !*serialno)
+  if ((s = has_leading_keyword (line, "KEYINFO ")) && !*serialno)
     {
-      s = strchr (line+8, ' ');
+      s = strchr (s, ' ');
       if (s && s[1] == 'T' && s[2] == ' ' && s[3])
         {
           s += 3;
@@ -1546,7 +1575,7 @@ inq_genkey_parms (void *opaque, const char *line)
   struct genkey_parm_s *parm = opaque;
   gpg_error_t err;
 
-  if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
+  if (has_leading_keyword (line, "KEYPARAM"))
     {
       err = assuan_send_data (parm->dflt->ctx,
                               parm->keyparms, strlen (parm->keyparms));
@@ -1773,7 +1802,7 @@ inq_ciphertext_cb (void *opaque, const char *line)
   struct cipher_parm_s *parm = opaque;
   int rc;
 
-  if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
+  if (has_leading_keyword (line, "CIPHERTEXT"))
     {
       assuan_begin_confidential (parm->ctx);
       rc = assuan_send_data (parm->dflt->ctx,
@@ -1787,17 +1816,34 @@ inq_ciphertext_cb (void *opaque, const char *line)
 }
 
 
+/* Check whether there is any padding info from the agent.  */
+static gpg_error_t
+padding_info_cb (void *opaque, const char *line)
+{
+  int *r_padding = opaque;
+  const char *s;
+
+  if ((s=has_leading_keyword (line, "PADDING")))
+    {
+      *r_padding = atoi (s);
+    }
+
+  return 0;
+}
+
+
 /* Call the agent to do a decrypt operation using the key identified
    by the hex string KEYGRIP and the input data S_CIPHERTEXT.  On the
    success the decoded value is stored verbatim at R_BUF and its
    length at R_BUF; the callers needs to release it.  KEYID, MAINKEYID
    and PUBKEY_ALGO are used to construct additional promots or status
-   messages. */
+   messages.   The padding information is stored at R_PADDING with -1
+   for not known.  */
 gpg_error_t
 agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
                  u32 *keyid, u32 *mainkeyid, int pubkey_algo,
                  gcry_sexp_t s_ciphertext,
-                 unsigned char **r_buf, size_t *r_buflen)
+                 unsigned char **r_buf, size_t *r_buflen, int *r_padding)
 {
   gpg_error_t err;
   char line[ASSUAN_LINELENGTH];
@@ -1812,9 +1858,12 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
   dfltparm.keyinfo.mainkeyid   = mainkeyid;
   dfltparm.keyinfo.pubkey_algo = pubkey_algo;
 
-  if (!keygrip || strlen(keygrip) != 40 || !s_ciphertext || !r_buf || !r_buflen)
+  if (!keygrip || strlen(keygrip) != 40
+      || !s_ciphertext || !r_buf || !r_buflen || !r_padding)
     return gpg_error (GPG_ERR_INV_VALUE);
+
   *r_buf = NULL;
+  *r_padding = -1;
 
   err = start_agent (ctrl, 0);
   if (err)
@@ -1852,7 +1901,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
       return err;
     err = assuan_transact (agent_ctx, "PKDECRYPT",
                            membuf_data_cb, &data,
-                           inq_ciphertext_cb, &parm, NULL, NULL);
+                           inq_ciphertext_cb, &parm,
+                           padding_info_cb, r_padding);
     xfree (parm.ciphertext);
   }
   if (err)
@@ -1955,7 +2005,7 @@ inq_import_key_parms (void *opaque, const char *line)
   struct import_key_parm_s *parm = opaque;
   gpg_error_t err;
 
-  if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
+  if (has_leading_keyword (line, "KEYDATA"))
     {
       err = assuan_send_data (parm->dflt->ctx, parm->key, parm->keylen);
     }
@@ -1969,7 +2019,7 @@ inq_import_key_parms (void *opaque, const char *line)
 /* Call the agent to import a key into the agent.  */
 gpg_error_t
 agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
-                  const void *key, size_t keylen)
+                  const void *key, size_t keylen, int unattended)
 {
   gpg_error_t err;
   struct import_key_parm_s parm;
@@ -1999,7 +2049,8 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
   parm.key    = key;
   parm.keylen = keylen;
 
-  snprintf (line, sizeof line, "IMPORT_KEY%s%s",
+  snprintf (line, sizeof line, "IMPORT_KEY%s%s%s",
+            unattended? " --unattended":"",
             cache_nonce_addr && *cache_nonce_addr? " ":"",
             cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
   cn_parm.cache_nonce_addr = cache_nonce_addr;