diff options
author | NIIBE Yutaka <[email protected]> | 2020-06-09 01:32:47 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2020-06-09 01:32:47 +0000 |
commit | f5bc94555458123f93d8b07816a68fb7485421e1 (patch) | |
tree | d2e27f1eb0c027721847acc498affb536981e1e1 /g10/pkglue.c | |
parent | gpg: If possible TRUST values now depend on signer's UID or --sender. (diff) | |
download | gnupg-f5bc94555458123f93d8b07816a68fb7485421e1.tar.gz gnupg-f5bc94555458123f93d8b07816a68fb7485421e1.zip |
gpg,ecc: Handle external representation as SOS with opaque MPI.
* g10/pkglue.h (sexp_extract_param_sos): New.
* g10/build-packet.c (sos_write): New.
(do_key, do_pubkey_enc, do_signature): Use sos_write for ECC.
* g10/export.c (cleartext_secret_key_to_openpgp): Use
sexp_extract_param_sos.
(transfer_format_to_openpgp): Use opaque MPI for ECC.
* g10/keygen.c (ecckey_from_sexp): Use sexp_extract_param_sos.
* g10/keyid.c (hash_public_key): Handle opaque MPI for SOS.
* g10/parse-packet.c (sos_read): New.
(parse_pubkeyenc,parse_signature,parse_key): Use sos_read for ECC.
* g10/pkglue.c (sexp_extract_param_sos): New.
(pk_verify): Handle opaque MPI for SOS.
(pk_encrypt): Use sexp_extract_param_sos.
* g10/seskey.c (encode_session_key): Use opaque MPI.
* g10/sign.c (do_sign): Use sexp_extract_param_sos.
Signed-off-by: NIIBE Yutaka <[email protected]>
Diffstat (limited to 'g10/pkglue.c')
-rw-r--r-- | g10/pkglue.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/g10/pkglue.c b/g10/pkglue.c index d266fef61..741a93735 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -47,6 +47,56 @@ get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt) } +/* Extract SOS representation from SEXP for PARAM, return the result + in R_SOS. */ +gpg_error_t +sexp_extract_param_sos (gcry_sexp_t sexp, const char *param, gcry_mpi_t *r_sos) +{ + gpg_error_t err; + gcry_sexp_t l2 = gcry_sexp_find_token (sexp, param, 0); + + *r_sos = NULL; + if (!l2) + err = gpg_error (GPG_ERR_NO_OBJ); + else + { + size_t buflen; + void *p0 = gcry_sexp_nth_buffer (l2, 1, &buflen); + + if (!p0) + err = gpg_error_from_syserror (); + else + { + gcry_mpi_t sos; + unsigned int nbits = buflen*8; + unsigned char *p = p0; + + if (nbits >= 8 && !(*p & 0x80)) + if (--nbits >= 7 && !(*p & 0x40)) + if (--nbits >= 6 && !(*p & 0x20)) + if (--nbits >= 5 && !(*p & 0x10)) + if (--nbits >= 4 && !(*p & 0x08)) + if (--nbits >= 3 && !(*p & 0x04)) + if (--nbits >= 2 && !(*p & 0x02)) + if (--nbits >= 1 && !(*p & 0x01)) + --nbits; + + sos = gcry_mpi_set_opaque (NULL, p0, nbits); + if (sos) + { + gcry_mpi_set_flag (sos, GCRYMPI_FLAG_USER2); + *r_sos = sos; + err = 0; + } + else + err = gpg_error_from_syserror (); + } + gcry_sexp_release (l2); + } + + return err; +} + /**************** * Emulate our old PK interface here - sometime in the future we might @@ -152,6 +202,7 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, gcry_mpi_t s = data[1]; size_t rlen, slen, n; /* (bytes) */ char buf[64]; + unsigned int nbits; log_assert (neededfixedlen <= sizeof buf); @@ -182,6 +233,17 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, 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))) @@ -191,6 +253,17 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, 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); + } if (!rc) rc = gcry_sexp_build (&s_sig, NULL, @@ -315,7 +388,7 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, /* Get the shared point and the ephemeral public key. */ shared = get_mpi_from_sexp (s_ciph, "s", GCRYMPI_FMT_USG); - public = get_mpi_from_sexp (s_ciph, "e", GCRYMPI_FMT_USG); + rc = sexp_extract_param_sos (s_ciph, "e", &public); gcry_sexp_release (s_ciph); s_ciph = NULL; if (DBG_CRYPTO) @@ -329,7 +402,8 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, fingerprint_from_pk (pk, fp, &fpn); if (fpn != 20) rc = gpg_error (GPG_ERR_INV_LENGTH); - else + + if (!rc) rc = pk_ecdh_encrypt_with_shared_point (shared, fp, data, pkey, &result); gcry_mpi_release (shared); |