mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
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:
parent
5c2080f467
commit
f5bc945554
@ -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_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_ECDH && (i == 0 || i == 2)))
|
||||
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
|
||||
err = gpg_mpi_write (a, pk->pkey[i], NULL);
|
||||
if (err)
|
||||
@ -691,8 +759,18 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
|
||||
|
||||
for (j=i; j < nskey; j++ )
|
||||
{
|
||||
if ((err = gpg_mpi_write (NULL, pk->pkey[j], &n)))
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
|| 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;
|
||||
}
|
||||
|
||||
@ -700,6 +778,14 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
|
||||
}
|
||||
|
||||
for ( ; i < nskey; i++ )
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
|| 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;
|
||||
|
||||
@ -817,6 +903,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
|
||||
{
|
||||
if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
|
||||
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
|
||||
rc = gpg_mpi_write (a, enc->data[i], NULL);
|
||||
}
|
||||
@ -1696,6 +1784,11 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
|
||||
n = pubkey_get_nsig( sig->pubkey_algo );
|
||||
if ( !n )
|
||||
write_fake_data( a, sig->data[0] );
|
||||
if (sig->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
|| 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);
|
||||
|
||||
|
26
g10/export.c
26
g10/export.c
@ -42,6 +42,7 @@
|
||||
#include "trustdb.h"
|
||||
#include "call-agent.h"
|
||||
#include "key-clean.h"
|
||||
#include "pkglue.h"
|
||||
|
||||
|
||||
/* 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);
|
||||
if (err)
|
||||
goto leave;
|
||||
if (!err)
|
||||
err = gcry_sexp_extract_param (key, NULL, "q",
|
||||
&pub_params[0],
|
||||
NULL);
|
||||
else
|
||||
err = sexp_extract_param_sos (key, "q", &pub_params[0]);
|
||||
if (!err && (gcry_mpi_cmp(pk->pkey[1], pub_params[0])))
|
||||
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]);
|
||||
pk->pkey[sec_start] = NULL;
|
||||
err = gcry_sexp_extract_param (key, NULL, "d",
|
||||
&pk->pkey[sec_start],
|
||||
NULL);
|
||||
err = sexp_extract_param_sos (key, "d", &pk->pkey[sec_start]);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!value || !valuelen)
|
||||
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);
|
||||
if (!p)
|
||||
goto outofmem;
|
||||
memcpy (p, value, valuelen);
|
||||
skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
|
||||
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);
|
||||
}
|
||||
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
|
||||
and that there are no more secret key parameters. The latter is
|
||||
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;
|
||||
if (npkey+1 < DIM (skey) && skey[npkey+1])
|
||||
goto bad_seckey;
|
||||
|
15
g10/keygen.c
15
g10/keygen.c
@ -1329,19 +1329,10 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
l2 = gcry_sexp_find_token (list, "q", 0);
|
||||
if (!l2)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_NO_OBJ);
|
||||
err = sexp_extract_param_sos (list, "q", &array[1]);
|
||||
if (err)
|
||||
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);
|
||||
|
||||
if (algo == PUBKEY_ALGO_ECDH)
|
||||
|
15
g10/keyid.c
15
g10/keyid.c
@ -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))
|
||||
{
|
||||
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);
|
||||
pp[i] = xmalloc ((nbits+7)/8);
|
||||
pp[i] = xmalloc ((nbits+7)/8 + is_sos);
|
||||
if (p)
|
||||
memcpy (pp[i], p, (nbits+7)/8);
|
||||
memcpy (pp[i] + is_sos, p, (nbits+7)/8);
|
||||
else
|
||||
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];
|
||||
}
|
||||
else
|
||||
|
@ -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. */
|
||||
void
|
||||
register_known_notation (const char *string)
|
||||
@ -1328,12 +1398,23 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
{
|
||||
for (i = 0; i < ndata; i++)
|
||||
{
|
||||
if (k->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
|
||||
if (k->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
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
|
||||
{
|
||||
int n = pktlen;
|
||||
@ -2282,6 +2363,10 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
for (i = 0; i < ndata; i++)
|
||||
{
|
||||
n = pktlen;
|
||||
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;
|
||||
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_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;
|
||||
err = read_size_body (inp, pktlen, &n, pk->pkey+i);
|
||||
pktlen -= n;
|
||||
@ -2518,6 +2603,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
else
|
||||
{
|
||||
unsigned int n = pktlen;
|
||||
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;
|
||||
if (!pk->pkey[i])
|
||||
@ -2830,6 +2920,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
goto leave;
|
||||
}
|
||||
n = pktlen;
|
||||
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;
|
||||
if (list_mode)
|
||||
|
78
g10/pkglue.c
78
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);
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
/*-- pkglue.c --*/
|
||||
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,
|
||||
gcry_mpi_t *pkey);
|
||||
|
11
g10/seskey.c
11
g10/seskey.c
@ -82,7 +82,6 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits)
|
||||
byte *frame;
|
||||
int i,n;
|
||||
u16 csum;
|
||||
gcry_mpi_t a;
|
||||
|
||||
if (DBG_CRYPTO)
|
||||
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],
|
||||
frame[nframe-3], frame[nframe-2], frame[nframe-1]);
|
||||
|
||||
if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe))
|
||||
BUG();
|
||||
xfree(frame);
|
||||
return a;
|
||||
return gcry_mpi_set_opaque (NULL, frame, 8*nframe);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
log_assert (n == nframe);
|
||||
if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
|
||||
BUG();
|
||||
xfree (frame);
|
||||
return a;
|
||||
return gcry_mpi_set_opaque (NULL, frame, 8*n);
|
||||
}
|
||||
|
||||
|
||||
|
@ -505,10 +505,12 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
|
||||
else if (pksk->pubkey_algo == GCRY_PK_RSA
|
||||
|| pksk->pubkey_algo == GCRY_PK_RSA_S)
|
||||
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);
|
||||
sig->data[1] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_OPAQUE);
|
||||
err = sexp_extract_param_sos (s_sigval, "r", &sig->data[0]);
|
||||
if (!err)
|
||||
err = sexp_extract_param_sos (s_sigval, "s", &sig->data[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user