aboutsummaryrefslogtreecommitdiffstats
path: root/g10/pkglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/pkglue.c')
-rw-r--r--g10/pkglue.c180
1 files changed, 98 insertions, 82 deletions
diff --git a/g10/pkglue.c b/g10/pkglue.c
index eda13009b..cd6e90838 100644
--- a/g10/pkglue.c
+++ b/g10/pkglue.c
@@ -131,7 +131,6 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
{
gcry_sexp_t s_sig, s_hash, s_pkey;
int rc;
- unsigned int neededfixedlen = 0;
/* Make a sexp from pkey. */
if (pkalgo == PUBKEY_ALGO_DSA)
@@ -171,15 +170,16 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
rc = gpg_error_from_syserror ();
else
{
- rc = gcry_sexp_build (&s_pkey, NULL,
- "(public-key(ecc(curve %s)"
- "(flags eddsa)(q%m)))",
- curve, pkey[1]);
+ const char *fmt;
+
+ if (openpgp_oid_is_ed25519 (pkey[0]))
+ fmt = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))";
+ else
+ fmt = "(public-key(ecc(curve %s)(q%m)))";
+
+ rc = gcry_sexp_build (&s_pkey, NULL, fmt, curve, pkey[1]);
xfree (curve);
}
-
- if (openpgp_oid_is_ed25519 (pkey[0]))
- neededfixedlen = 256 / 8;
}
else
return GPG_ERR_PUBKEY_ALGO;
@@ -190,9 +190,14 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
/* Put hash into a S-Exp s_hash. */
if (pkalgo == PUBKEY_ALGO_EDDSA)
{
- if (gcry_sexp_build (&s_hash, NULL,
- "(data(flags eddsa)(hash-algo sha512)(value %m))",
- hash))
+ const char *fmt;
+
+ if (openpgp_oid_is_ed25519 (pkey[0]))
+ fmt = "(data(flags eddsa)(hash-algo sha512)(value %m))";
+ else
+ fmt = "(data(value %m))";
+
+ if (gcry_sexp_build (&s_hash, NULL, fmt, hash))
BUG (); /* gcry_sexp_build should never fail. */
}
else
@@ -223,80 +228,87 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
{
gcry_mpi_t r = data[0];
gcry_mpi_t s = data[1];
- size_t rlen, slen, n; /* (bytes) */
- char buf[64];
- unsigned int nbits;
-
- log_assert (neededfixedlen <= sizeof buf);
- if (!r || !s)
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else if ((rlen = (gcry_mpi_get_nbits (r)+7)/8) > neededfixedlen || !rlen)
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else if ((slen = (gcry_mpi_get_nbits (s)+7)/8) > neededfixedlen || !slen)
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else
+ if (openpgp_oid_is_ed25519 (pkey[0]))
{
- /* We need to fixup the length in case of leading zeroes.
- * OpenPGP does not allow leading zeroes and the parser for
- * the signature packet has no information on the use curve,
- * thus we need to do it here. We won't do it for opaque
- * MPIs under the assumption that they are known to be fine;
- * we won't see them here anyway but the check is anyway
- * required. Fixme: A nifty feature for gcry_sexp_build
- * would be a format to left pad the value (e.g. "%*M"). */
- rc = 0;
-
- if (rlen < neededfixedlen
- && !gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE)
- && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, r)))
- {
- log_assert (n < neededfixedlen);
- memmove (buf + (neededfixedlen - n), buf, n);
- memset (buf, 0, neededfixedlen - n);
- r = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8);
- }
- else if (rlen < neededfixedlen
- && gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE))
- {
- const unsigned char *p;
+ size_t rlen, slen, n; /* (bytes) */
+ char buf[64];
+ unsigned int nbits;
+ unsigned int neededfixedlen = 256 / 8;
- p = gcry_mpi_get_opaque (r, &nbits);
- n = (nbits+7)/8;
- memcpy (buf + (neededfixedlen - n), p, n);
- memset (buf, 0, neededfixedlen - n);
- gcry_mpi_set_opaque_copy (r, buf, neededfixedlen * 8);
- }
- if (slen < neededfixedlen
- && !gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE)
- && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, s)))
- {
- log_assert (n < neededfixedlen);
- memmove (buf + (neededfixedlen - n), buf, n);
- memset (buf, 0, neededfixedlen - n);
- s = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8);
- }
- else if (slen < neededfixedlen
- && gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE))
- {
- const unsigned char *p;
+ log_assert (neededfixedlen <= sizeof buf);
- p = gcry_mpi_get_opaque (s, &nbits);
- n = (nbits+7)/8;
- memcpy (buf + (neededfixedlen - n), p, n);
- memset (buf, 0, neededfixedlen - n);
- gcry_mpi_set_opaque_copy (s, buf, neededfixedlen * 8);
+ if (!r || !s)
+ rc = gpg_error (GPG_ERR_BAD_MPI);
+ else if ((rlen = (gcry_mpi_get_nbits (r)+7)/8) > neededfixedlen || !rlen)
+ rc = gpg_error (GPG_ERR_BAD_MPI);
+ else if ((slen = (gcry_mpi_get_nbits (s)+7)/8) > neededfixedlen || !slen)
+ rc = gpg_error (GPG_ERR_BAD_MPI);
+ else
+ {
+ /* We need to fixup the length in case of leading zeroes.
+ * OpenPGP does not allow leading zeroes and the parser for
+ * the signature packet has no information on the use curve,
+ * thus we need to do it here. We won't do it for opaque
+ * MPIs under the assumption that they are known to be fine;
+ * we won't see them here anyway but the check is anyway
+ * required. Fixme: A nifty feature for gcry_sexp_build
+ * would be a format to left pad the value (e.g. "%*M"). */
+ rc = 0;
+
+ if (rlen < neededfixedlen
+ && !gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE)
+ && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, r)))
+ {
+ log_assert (n < neededfixedlen);
+ memmove (buf + (neededfixedlen - n), buf, n);
+ memset (buf, 0, neededfixedlen - n);
+ r = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8);
+ }
+ else if (rlen < neededfixedlen
+ && gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE))
+ {
+ const unsigned char *p;
+
+ p = gcry_mpi_get_opaque (r, &nbits);
+ n = (nbits+7)/8;
+ memcpy (buf + (neededfixedlen - n), p, n);
+ memset (buf, 0, neededfixedlen - n);
+ gcry_mpi_set_opaque_copy (r, buf, neededfixedlen * 8);
+ }
+ if (slen < neededfixedlen
+ && !gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE)
+ && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, s)))
+ {
+ log_assert (n < neededfixedlen);
+ memmove (buf + (neededfixedlen - n), buf, n);
+ memset (buf, 0, neededfixedlen - n);
+ s = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8);
+ }
+ else if (slen < neededfixedlen
+ && gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE))
+ {
+ const unsigned char *p;
+
+ p = gcry_mpi_get_opaque (s, &nbits);
+ n = (nbits+7)/8;
+ memcpy (buf + (neededfixedlen - n), p, n);
+ memset (buf, 0, neededfixedlen - n);
+ gcry_mpi_set_opaque_copy (s, buf, neededfixedlen * 8);
+ }
}
+ }
+ else
+ rc = 0;
- if (!rc)
- rc = gcry_sexp_build (&s_sig, NULL,
- "(sig-val(eddsa(r%M)(s%M)))", r, s);
+ if (!rc)
+ rc = gcry_sexp_build (&s_sig, NULL,
+ "(sig-val(eddsa(r%M)(s%M)))", r, s);
- if (r != data[0])
- gcry_mpi_release (r);
- if (s != data[1])
- gcry_mpi_release (s);
- }
+ if (r != data[0])
+ gcry_mpi_release (r);
+ if (s != data[1])
+ gcry_mpi_release (s);
}
else if (pkalgo == PUBKEY_ALGO_ELGAMAL || pkalgo == PUBKEY_ALGO_ELGAMAL_E)
{
@@ -506,10 +518,14 @@ pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey)
rc = gpg_error_from_syserror ();
else
{
- rc = gcry_sexp_build (&s_skey, NULL,
- "(private-key(ecc(curve %s)"
- "(flags eddsa)(q%m)(d%m)))",
- curve, skey[1], skey[2]);
+ const char *fmt;
+
+ if (openpgp_oid_is_ed25519 (skey[0]))
+ fmt = "(private-key(ecc(curve %s)(flags eddsa)(q%m)(d%m)))";
+ else
+ fmt = "(private-key(ecc(curve %s)(q%m)(d%m)))";
+
+ rc = gcry_sexp_build (&s_skey, NULL, fmt, curve, skey[1], skey[2]);
xfree (curve);
}
}