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 <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2020-06-09 10:32:47 +09:00
parent 5c2080f467
commit f5bc945554
9 changed files with 316 additions and 59 deletions

View File

@ -364,7 +364,71 @@ gpg_mpi_write (iobuf_t out, gcry_mpi_t a, unsigned int *r_nwritten)
/* /*
* Write an opaque MPI to the output stream without length info. * Write the mpi A to the output stream OUT as "SOS" (Strange Octet
* String). If R_NWRITTEN is not NULL the number of bytes written is
* stored there. To only get the number of bytes which would be
* written, NULL may be passed for OUT.
*/
static gpg_error_t
sos_write (iobuf_t out, gcry_mpi_t a, unsigned int *r_nwritten)
{
gpg_error_t err;
unsigned int nwritten = 0;
if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
{
unsigned int nbits;
const unsigned char *p;
unsigned char lenhdr[2];
/* gcry_log_debugmpi ("a", a); */
p = gcry_mpi_get_opaque (a, &nbits);
/* gcry_log_debug (" [%u bit]\n", nbits); */
/* gcry_log_debughex (" ", p, (nbits+7)/8); */
if (p && *p)
{
nbits = ((nbits + 7) / 8) * 8;
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;
}
lenhdr[0] = nbits >> 8;
lenhdr[1] = nbits;
err = out? iobuf_write (out, lenhdr, 2) : 0;
if (!err)
{
nwritten += 2;
if (p)
{
err = out? iobuf_write (out, p, (nbits+7)/8) : 0;
if (!err)
nwritten += (nbits+7)/8;
}
}
}
else
{
log_info ("non-opaque MPI (%u bits) for SOS\n", gcry_mpi_get_nbits (a));
err = gpg_error (GPG_ERR_INV_DATA);
}
if (r_nwritten)
*r_nwritten = nwritten;
return err;
}
/*
* Write an opaque string to the output stream without length info.
*/ */
gpg_error_t gpg_error_t
gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a) gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a)
@ -575,6 +639,10 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
|| (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0)) || (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0))
|| (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2))) || (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)))
err = gpg_mpi_write_nohdr (a, pk->pkey[i]); err = gpg_mpi_write_nohdr (a, pk->pkey[i]);
else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
err = sos_write (a, pk->pkey[i], NULL);
else else
err = gpg_mpi_write (a, pk->pkey[i], NULL); err = gpg_mpi_write (a, pk->pkey[i], NULL);
if (err) if (err)
@ -691,8 +759,18 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
for (j=i; j < nskey; j++ ) for (j=i; j < nskey; j++ )
{ {
if ((err = gpg_mpi_write (NULL, pk->pkey[j], &n))) if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
goto leave; || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{
if ((err = sos_write (NULL, pk->pkey[j], &n)))
goto leave;
}
else
{
if ( (err = gpg_mpi_write (a, pk->pkey[i], NULL)))
goto leave;
}
skbytes += n; skbytes += n;
} }
@ -700,8 +778,16 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
} }
for ( ; i < nskey; i++ ) for ( ; i < nskey; i++ )
if ( (err = gpg_mpi_write (a, pk->pkey[i], NULL))) if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
goto leave; || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{
if ((err = sos_write (a, pk->pkey[i], NULL)))
goto leave;
}
else
if ((err = gpg_mpi_write (a, pk->pkey[i], NULL)))
goto leave;
write_16 (a, ski->csum ); write_16 (a, ski->csum );
} }
@ -817,6 +903,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
{ {
if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1) if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
rc = gpg_mpi_write_nohdr (a, enc->data[i]); rc = gpg_mpi_write_nohdr (a, enc->data[i]);
else if (enc->pubkey_algo == PUBKEY_ALGO_ECDH)
rc = sos_write (a, enc->data[i], NULL);
else else
rc = gpg_mpi_write (a, enc->data[i], NULL); rc = gpg_mpi_write (a, enc->data[i], NULL);
} }
@ -1696,8 +1784,13 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
n = pubkey_get_nsig( sig->pubkey_algo ); n = pubkey_get_nsig( sig->pubkey_algo );
if ( !n ) if ( !n )
write_fake_data( a, sig->data[0] ); write_fake_data( a, sig->data[0] );
for (i=0; i < n && !rc ; i++ ) if (sig->pubkey_algo == PUBKEY_ALGO_ECDSA
rc = gpg_mpi_write (a, sig->data[i], NULL); || sig->pubkey_algo == PUBKEY_ALGO_EDDSA)
for (i=0; i < n && !rc ; i++ )
rc = sos_write (a, sig->data[i], NULL);
else
for (i=0; i < n && !rc ; i++ )
rc = gpg_mpi_write (a, sig->data[i], NULL);
if (!rc) if (!rc)
{ {

View File

@ -42,6 +42,7 @@
#include "trustdb.h" #include "trustdb.h"
#include "call-agent.h" #include "call-agent.h"
#include "key-clean.h" #include "key-clean.h"
#include "pkglue.h"
/* An object to keep track of subkeys. */ /* An object to keep track of subkeys. */
@ -750,10 +751,8 @@ cleartext_secret_key_to_openpgp (gcry_sexp_t s_key, PKT_public_key *pk)
err = match_curve_skey_pk (key, pk); err = match_curve_skey_pk (key, pk);
if (err) if (err)
goto leave; goto leave;
if (!err) else
err = gcry_sexp_extract_param (key, NULL, "q", err = sexp_extract_param_sos (key, "q", &pub_params[0]);
&pub_params[0],
NULL);
if (!err && (gcry_mpi_cmp(pk->pkey[1], pub_params[0]))) if (!err && (gcry_mpi_cmp(pk->pkey[1], pub_params[0])))
err = gpg_error (GPG_ERR_BAD_PUBKEY); err = gpg_error (GPG_ERR_BAD_PUBKEY);
@ -764,9 +763,7 @@ cleartext_secret_key_to_openpgp (gcry_sexp_t s_key, PKT_public_key *pk)
{ {
gcry_mpi_release (pk->pkey[sec_start]); gcry_mpi_release (pk->pkey[sec_start]);
pk->pkey[sec_start] = NULL; pk->pkey[sec_start] = NULL;
err = gcry_sexp_extract_param (key, NULL, "d", err = sexp_extract_param_sos (key, "d", &pk->pkey[sec_start]);
&pk->pkey[sec_start],
NULL);
} }
if (!err) if (!err)
@ -978,15 +975,16 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
value = gcry_sexp_nth_data (list, ++idx, &valuelen); value = gcry_sexp_nth_data (list, ++idx, &valuelen);
if (!value || !valuelen) if (!value || !valuelen)
goto bad_seckey; goto bad_seckey;
if (is_enc) if (is_enc
|| pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
void *p = xtrymalloc (valuelen); skey[skeyidx] = gcry_mpi_set_opaque_copy (NULL, value, valuelen*8);
if (!p)
goto outofmem;
memcpy (p, value, valuelen);
skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
if (!skey[skeyidx]) if (!skey[skeyidx])
goto outofmem; goto outofmem;
if (is_enc)
gcry_mpi_set_flag (skey[skeyidx], GCRYMPI_FLAG_USER1);
} }
else else
{ {
@ -1144,7 +1142,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
/* Check that the first secret key parameter in SKEY is encrypted /* Check that the first secret key parameter in SKEY is encrypted
and that there are no more secret key parameters. The latter is and that there are no more secret key parameters. The latter is
guaranteed by the v4 packet format. */ guaranteed by the v4 packet format. */
if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE)) if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_USER1))
goto bad_seckey; goto bad_seckey;
if (npkey+1 < DIM (skey) && skey[npkey+1]) if (npkey+1 < DIM (skey) && skey[npkey+1])
goto bad_seckey; goto bad_seckey;

View File

@ -1329,19 +1329,10 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
if (err) if (err)
goto leave; goto leave;
l2 = gcry_sexp_find_token (list, "q", 0); err = sexp_extract_param_sos (list, "q", &array[1]);
if (!l2) if (err)
{ goto leave;
err = gpg_error (GPG_ERR_NO_OBJ);
goto leave;
}
array[1] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
gcry_sexp_release (l2);
if (!array[1])
{
err = gpg_error (GPG_ERR_INV_OBJ);
goto leave;
}
gcry_sexp_release (list); gcry_sexp_release (list);
if (algo == PUBKEY_ALGO_ECDH) if (algo == PUBKEY_ALGO_ECDH)

View File

@ -181,14 +181,23 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
{ {
const void *p; const void *p;
int is_sos = 0;
if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_USER2))
is_sos = 2;
p = gcry_mpi_get_opaque (pk->pkey[i], &nbits); p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
pp[i] = xmalloc ((nbits+7)/8); pp[i] = xmalloc ((nbits+7)/8 + is_sos);
if (p) if (p)
memcpy (pp[i], p, (nbits+7)/8); memcpy (pp[i] + is_sos, p, (nbits+7)/8);
else else
pp[i] = NULL; pp[i] = NULL;
nn[i] = (nbits+7)/8; if (is_sos)
{
pp[i][0] = (nbits >> 8);
pp[i][1] = nbits;
}
nn[i] = (nbits+7)/8 + is_sos;
n += nn[i]; n += nn[i];
} }
else else

View File

@ -188,6 +188,76 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure)
} }
/* Read an external representation of an SOS and return the opaque MPI
with GCRYMPI_FLAG_USER2. The external format is a 16-bit unsigned
value stored in network byte order giving information for the
following octets.
The caller must set *RET_NREAD to the maximum number of bytes to
read from the pipeline INP. This function sets *RET_NREAD to be
the number of bytes actually read from the pipeline.
If SECURE is true, the integer is stored in secure memory
(allocated using gcry_xmalloc_secure). */
static gcry_mpi_t
sos_read (iobuf_t inp, unsigned int *ret_nread, int secure)
{
int c, c1, c2, i;
unsigned int nmax = *ret_nread;
unsigned int nbits, nbytes;
size_t nread = 0;
gcry_mpi_t a = NULL;
byte *buf = NULL;
byte *p;
if (!nmax)
goto overflow;
if ((c = c1 = iobuf_get (inp)) == -1)
goto leave;
if (++nread == nmax)
goto overflow;
nbits = c << 8;
if ((c = c2 = iobuf_get (inp)) == -1)
goto leave;
++nread;
nbits |= c;
if (nbits > MAX_EXTERN_MPI_BITS)
{
log_error ("mpi too large (%u bits)\n", nbits);
goto leave;
}
nbytes = (nbits + 7) / 8;
buf = secure ? gcry_xmalloc_secure (nbytes) : gcry_xmalloc (nbytes);
p = buf;
for (i = 0; i < nbytes; i++)
{
if (nread == nmax)
goto overflow;
c = iobuf_get (inp);
if (c == -1)
goto leave;
p[i] = c;
nread ++;
}
a = gcry_mpi_set_opaque (NULL, buf, nbits);
gcry_mpi_set_flag (a, GCRYMPI_FLAG_USER2);
*ret_nread = nread;
return a;
overflow:
log_error ("mpi larger than indicated length (%u bits)\n", 8*nmax);
leave:
*ret_nread = nread;
gcry_free(buf);
return a;
}
/* Register STRING as a known critical notation name. */ /* Register STRING as a known critical notation name. */
void void
register_known_notation (const char *string) register_known_notation (const char *string)
@ -1328,11 +1398,22 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
{ {
for (i = 0; i < ndata; i++) for (i = 0; i < ndata; i++)
{ {
if (k->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1) if (k->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
size_t n; if (i == 1)
rc = read_size_body (inp, pktlen, &n, k->data+i); {
pktlen -= n; size_t n;
rc = read_size_body (inp, pktlen, &n, k->data+i);
pktlen -= n;
}
else
{
int n = pktlen;
k->data[i] = sos_read (inp, &n, 0);
pktlen -= n;
if (!k->data[i])
rc = gpg_error (GPG_ERR_INV_PACKET);
}
} }
else else
{ {
@ -2282,7 +2363,11 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen,
for (i = 0; i < ndata; i++) for (i = 0; i < ndata; i++)
{ {
n = pktlen; n = pktlen;
sig->data[i] = mpi_read (inp, &n, 0); if (sig->pubkey_algo == PUBKEY_ALGO_ECDSA
|| sig->pubkey_algo == PUBKEY_ALGO_EDDSA)
sig->data[i] = sos_read (inp, &n, 0);
else
sig->data[i] = mpi_read (inp, &n, 0);
pktlen -= n; pktlen -= n;
if (list_mode) if (list_mode)
{ {
@ -2510,7 +2595,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
|| (algorithm == PUBKEY_ALGO_EDDSA && (i == 0)) || (algorithm == PUBKEY_ALGO_EDDSA && (i == 0))
|| (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2))) || (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)))
{ {
/* Read the OID (i==1) or the KDF params (i==2). */ /* Read the OID (i==0) or the KDF params (i==2). */
size_t n; size_t n;
err = read_size_body (inp, pktlen, &n, pk->pkey+i); err = read_size_body (inp, pktlen, &n, pk->pkey+i);
pktlen -= n; pktlen -= n;
@ -2518,7 +2603,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
else else
{ {
unsigned int n = pktlen; unsigned int n = pktlen;
pk->pkey[i] = mpi_read (inp, &n, 0); if (algorithm == PUBKEY_ALGO_ECDSA
|| algorithm == PUBKEY_ALGO_EDDSA
|| algorithm == PUBKEY_ALGO_ECDH)
pk->pkey[i] = sos_read (inp, &n, 0);
else
pk->pkey[i] = mpi_read (inp, &n, 0);
pktlen -= n; pktlen -= n;
if (!pk->pkey[i]) if (!pk->pkey[i])
err = gpg_error (GPG_ERR_INV_PACKET); err = gpg_error (GPG_ERR_INV_PACKET);
@ -2830,7 +2920,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
goto leave; goto leave;
} }
n = pktlen; n = pktlen;
pk->pkey[i] = mpi_read (inp, &n, 0); if (algorithm == PUBKEY_ALGO_ECDSA
|| algorithm == PUBKEY_ALGO_EDDSA
|| algorithm == PUBKEY_ALGO_ECDH)
pk->pkey[i] = sos_read (inp, &n, 0);
else
pk->pkey[i] = mpi_read (inp, &n, 0);
pktlen -= n; pktlen -= n;
if (list_mode) if (list_mode)
{ {

View File

@ -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 * 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]; gcry_mpi_t s = data[1];
size_t rlen, slen, n; /* (bytes) */ size_t rlen, slen, n; /* (bytes) */
char buf[64]; char buf[64];
unsigned int nbits;
log_assert (neededfixedlen <= sizeof buf); log_assert (neededfixedlen <= sizeof buf);
@ -182,6 +233,17 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
memset (buf, 0, neededfixedlen - n); memset (buf, 0, neededfixedlen - n);
r = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8); 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 if (slen < neededfixedlen
&& !gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE) && !gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE)
&& !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, s))) && !(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); memset (buf, 0, neededfixedlen - n);
s = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8); 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) if (!rc)
rc = gcry_sexp_build (&s_sig, NULL, 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. */ /* Get the shared point and the ephemeral public key. */
shared = get_mpi_from_sexp (s_ciph, "s", GCRYMPI_FMT_USG); 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); gcry_sexp_release (s_ciph);
s_ciph = NULL; s_ciph = NULL;
if (DBG_CRYPTO) 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); fingerprint_from_pk (pk, fp, &fpn);
if (fpn != 20) if (fpn != 20)
rc = gpg_error (GPG_ERR_INV_LENGTH); rc = gpg_error (GPG_ERR_INV_LENGTH);
else
if (!rc)
rc = pk_ecdh_encrypt_with_shared_point (shared, rc = pk_ecdh_encrypt_with_shared_point (shared,
fp, data, pkey, &result); fp, data, pkey, &result);
gcry_mpi_release (shared); gcry_mpi_release (shared);

View File

@ -24,6 +24,8 @@
/*-- pkglue.c --*/ /*-- pkglue.c --*/
gcry_mpi_t get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt); gcry_mpi_t get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt);
gpg_error_t sexp_extract_param_sos (gcry_sexp_t sexp, const char *param,
gcry_mpi_t *r_sos);
int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data, int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data,
gcry_mpi_t *pkey); gcry_mpi_t *pkey);

View File

@ -82,7 +82,6 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits)
byte *frame; byte *frame;
int i,n; int i,n;
u16 csum; u16 csum;
gcry_mpi_t a;
if (DBG_CRYPTO) if (DBG_CRYPTO)
log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen); log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen);
@ -124,10 +123,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits)
(int) nframe, frame[0], frame[1], frame[2], (int) nframe, frame[0], frame[1], frame[2],
frame[nframe-3], frame[nframe-2], frame[nframe-1]); frame[nframe-3], frame[nframe-2], frame[nframe-1]);
if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) return gcry_mpi_set_opaque (NULL, frame, 8*nframe);
BUG();
xfree(frame);
return a;
} }
/* The current limitation is that we can only use a session key /* The current limitation is that we can only use a session key
@ -195,10 +191,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits)
frame[n++] = csum >>8; frame[n++] = csum >>8;
frame[n++] = csum; frame[n++] = csum;
log_assert (n == nframe); log_assert (n == nframe);
if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe)) return gcry_mpi_set_opaque (NULL, frame, 8*n);
BUG();
xfree (frame);
return a;
} }

View File

@ -505,10 +505,12 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
else if (pksk->pubkey_algo == GCRY_PK_RSA else if (pksk->pubkey_algo == GCRY_PK_RSA
|| pksk->pubkey_algo == GCRY_PK_RSA_S) || pksk->pubkey_algo == GCRY_PK_RSA_S)
sig->data[0] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_USG); sig->data[0] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_USG);
else if (openpgp_oid_is_ed25519 (pksk->pkey[0])) else if (pksk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pksk->pubkey_algo == PUBKEY_ALGO_EDDSA)
{ {
sig->data[0] = get_mpi_from_sexp (s_sigval, "r", GCRYMPI_FMT_OPAQUE); err = sexp_extract_param_sos (s_sigval, "r", &sig->data[0]);
sig->data[1] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_OPAQUE); if (!err)
err = sexp_extract_param_sos (s_sigval, "s", &sig->data[1]);
} }
else else
{ {