common: When classifying keyids and fingerprints, reject trailing junk.
[gnupg.git] / agent / cvt-openpgp.c
index cadc871..0b9ecf0 100644 (file)
@@ -83,14 +83,19 @@ get_keygrip (int pubkey_algo, const char *curve, gcry_mpi_t *pkey,
     case GCRY_PK_ECC:
       if (!curve)
         err = gpg_error (GPG_ERR_BAD_SECKEY);
-      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
-        err = gcry_sexp_build (&s_pkey, NULL,
-                               "(public-key(ecc(curve %s)(flags eddsa)(q%m)))",
-                               "Ed25519", pkey[0]);
       else
-        err = gcry_sexp_build (&s_pkey, NULL,
-                               "(public-key(ecc(curve %s)(q%m)))",
-                               curve, pkey[0]);
+        {
+          const char *format;
+
+          if (!strcmp (curve, "Ed25519"))
+            format = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))";
+          else if (!strcmp (curve, "Curve25519"))
+            format = "(public-key(ecc(curve %s)(flags djb-tweak)(q%m)))";
+          else
+            format = "(public-key(ecc(curve %s)(q%m)))";
+
+          err = gcry_sexp_build (&s_pkey, NULL, format, curve, pkey[0]);
+        }
       break;
 
     default:
@@ -146,19 +151,21 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
     case GCRY_PK_ECC:
       if (!curve)
         err = gpg_error (GPG_ERR_BAD_SECKEY);
-      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
+      else
         {
-          /* Do not store the OID as name but the real name and the
-             EdDSA flag.  */
-          err = gcry_sexp_build (&s_skey, NULL,
-                                 "(private-key(ecc(curve%s)(flags eddsa)"
-                                 "(q%m)(d%m)))",
-                                 "Ed25519", skey[0], skey[1]);
+          const char *format;
+
+          if (!strcmp (curve, "Ed25519"))
+            /* Do not store the OID as name but the real name and the
+               EdDSA flag.  */
+            format = "(private-key(ecc(curve %s)(flags eddsa)(q%m)(d%m)))";
+          else if (!strcmp (curve, "Curve25519"))
+            format = "(private-key(ecc(curve %s)(flags djb-tweak)(q%m)(d%m)))";
+          else
+            format = "(private-key(ecc(curve %s)(q%m)(d%m)))";
+
+          err = gcry_sexp_build (&s_skey, NULL, format, curve, skey[0], skey[1]);
         }
-      else
-        err = gcry_sexp_build (&s_skey, NULL,
-                               "(private-key(ecc(curve%s)(q%m)(d%m)))",
-                               curve, skey[0], skey[1]);
       break;
 
     default:
@@ -216,22 +223,24 @@ convert_transfer_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
     case GCRY_PK_ECC:
       if (!curve)
         err = gpg_error (GPG_ERR_BAD_SECKEY);
-      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
+      else
         {
-          /* Do not store the OID as name but the real name and the
-             EdDSA flag.  */
-          err = gcry_sexp_build
-            (&s_skey, NULL,
-             "(protected-private-key(ecc(curve%s)(flags eddsa)(q%m)"
-             "(protected openpgp-native%S)))",
-             "Ed25519", skey[0], transfer_key);
+          const char *format;
+
+          if (!strcmp (curve, "Ed25519"))
+            /* Do not store the OID as name but the real name and the
+               EdDSA flag.  */
+            format = "(protected-private-key(ecc(curve %s)(flags eddsa)(q%m)"
+              "(protected openpgp-native%S)))";
+          else if (!strcmp (curve, "Curve25519"))
+            format = "(protected-private-key(ecc(curve %s)(flags djb-tweak)(q%m)"
+              "(protected openpgp-native%S)))";
+          else
+            format = "(protected-private-key(ecc(curve %s)(q%m)"
+              "(protected openpgp-native%S)))";
+
+          err = gcry_sexp_build (&s_skey, NULL, format, curve, skey[0], transfer_key);
         }
-      else
-        err = gcry_sexp_build
-          (&s_skey, NULL,
-           "(protected-private-key(ecc(curve%s)(q%m)"
-           "(protected openpgp-native%S)))",
-           curve, skey[0], transfer_key);
       break;
 
     default:
@@ -648,7 +657,7 @@ do_unprotect (const char *passphrase,
 
 /* Callback function to try the unprotection from the passphrase query
    code.  */
-static int
+static gpg_error_t
 try_do_unprotect_cb (struct pin_entry_info_s *pi)
 {
   gpg_error_t err;
@@ -829,15 +838,13 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp,
       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
       if (!value || !valuelen)
         goto bad_seckey;
-      if (is_enc || curve)
+      if (is_enc)
         {
-          /* Encrypted parameters and ECC parameters need or can be
-             stored as opaque.  */
+          /* Encrypted parameters need to be stored as opaque.  */
           skey[skeyidx] = gcry_mpi_set_opaque_copy (NULL, value, valuelen*8);
           if (!skey[skeyidx])
             goto outofmem;
-          if (is_enc)
-            gcry_mpi_set_flag (skey[skeyidx], GCRYMPI_FLAG_USER1);
+          gcry_mpi_set_flag (skey[skeyidx], GCRYMPI_FLAG_USER1);
         }
       else
         {
@@ -909,10 +916,10 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp,
       struct pin_entry_info_s *pi;
       struct try_do_unprotect_arg_s pi_arg;
 
-      pi = xtrycalloc_secure (1, sizeof (*pi) + 100);
+      pi = xtrycalloc_secure (1, sizeof (*pi) + MAX_PASSPHRASE_LEN + 1);
       if (!pi)
         return gpg_error_from_syserror ();
-      pi->max_length = 100;
+      pi->max_length = MAX_PASSPHRASE_LEN + 1;
       pi->min_digits = 0;  /* We want a real passphrase.  */
       pi->max_digits = 16;
       pi->max_tries = 3;
@@ -961,7 +968,7 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp,
           err = try_do_unprotect_cb (pi);
         }
       if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE && !from_native)
-        err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
+        err = agent_askpin (ctrl, prompt, NULL, NULL, pi, NULL, 0);
       skeyidx = pi_arg.skeyidx;
       if (!err && r_passphrase && is_protected)
         {
@@ -1105,36 +1112,14 @@ apply_protection (gcry_mpi_t *array, int npkey, int nskey,
   ndata = 20; /* Space for the SHA-1 checksum.  */
   for (i = npkey, j = 0; i < nskey; i++, j++ )
     {
-      if (gcry_mpi_get_flag (array[i], GCRYMPI_FLAG_OPAQUE))
-        {
-          const void *s;
-          unsigned int n;
-
-          s = gcry_mpi_get_opaque (array[i], &n);
-          nbits[j] = n;
-          n = (n+7)/8;
-          narr[j] = n;
-          bufarr[j] = gcry_is_secure (s)? xtrymalloc_secure (n):xtrymalloc (n);
-          if (!bufarr[j])
-            {
-              err = gpg_error_from_syserror ();
-              for (i = 0; i < j; i++)
-                xfree (bufarr[i]);
-              return err;
-            }
-          memcpy (bufarr[j], s, n);
-        }
-      else
+      err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j, narr+j, array[i]);
+      if (err)
         {
-          err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j, narr+j, array[i]);
-          if (err)
-            {
-              for (i = 0; i < j; i++)
-                xfree (bufarr[i]);
-              return err;
-            }
-          nbits[j] = gcry_mpi_get_nbits (array[i]);
+          for (i = 0; i < j; i++)
+            xfree (bufarr[i]);
+          return err;
         }
+      nbits[j] = gcry_mpi_get_nbits (array[i]);
       ndata += 2 + narr[j];
     }
 
@@ -1289,53 +1274,13 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
   else if (!strcmp (name, "ecc"))
     {
       algoname = "ecc";
-      format = "/qd?";
+      format = "qd?";
       npkey = 1;
       nskey = 2;
       curve = gcry_sexp_find_token (list, "curve", 0);
       flags = gcry_sexp_find_token (list, "flags", 0);
       err = gcry_sexp_extract_param (list, NULL, format,
                                      array+0, array+1, NULL);
-      if (flags)
-        {
-          gcry_sexp_t param = gcry_sexp_find_token (flags, "param", 0);
-          if (param)
-            {
-              gcry_sexp_release (param);
-              array[6] = array[0];
-              array[7] = array[1];
-              err = gcry_sexp_extract_param (list, NULL, "pabgnh?",
-                                             array+0, array+1, array+2, array+3,
-                                             array+4, array+5, NULL);
-              if (array[5] == NULL)
-                {
-                  array[5] = GCRYMPI_CONST_ONE;
-                  npkey += 6;
-                  nskey += 6;
-                }
-              format = "pabgnhqd?";
-            }
-        }
-    }
-  else if (!strcmp (name, "ecdsa"))
-    {
-      algoname = "ecdsa";
-      format = "pabgnqd?";
-      npkey = 6;
-      nskey = 7;
-      err = gcry_sexp_extract_param (list, NULL, format,
-                                     array+0, array+1, array+2, array+3,
-                                     array+4, array+5, array+6, NULL);
-    }
-  else if (!strcmp (name, "ecdh"))
-    {
-      algoname = "ecdh";
-      format = "pabgnqd?";
-      npkey = 6;
-      nskey= 7;
-      err = gcry_sexp_extract_param (list, NULL, format,
-                                     array+0, array+1, array+2, array+3,
-                                     array+4, array+5, array+6, NULL);
     }
   else
     {
@@ -1353,12 +1298,7 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
     {
       *r_algoname = algoname;
       if (r_elems)
-        {
-          if (format[0] == '/') /* It is opaque data qualifier, skip it.  */
-            *r_elems = format+1;
-          else
-            *r_elems = format;
-        }
+        *r_elems = format;
       *r_npkey = npkey;
       if (r_nskey)
         *r_nskey = nskey;