diff options
author | NIIBE Yutaka <[email protected]> | 2019-11-19 10:06:22 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2020-05-04 01:57:07 +0000 |
commit | 93bcc87bd0d90cfeb6fde59e64aaa7d2a4ba8524 (patch) | |
tree | 201b6d551cc7effcc9a6529ee895deac62671e35 | |
parent | gpg: Use opaque byte MPI interface for ECC key. (diff) | |
download | gnupg-93bcc87bd0d90cfeb6fde59e64aaa7d2a4ba8524.tar.gz gnupg-93bcc87bd0d90cfeb6fde59e64aaa7d2a4ba8524.zip |
Add sos_read.
Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r-- | g10/build-packet.c | 12 | ||||
-rw-r--r-- | g10/parse-packet.c | 96 |
2 files changed, 98 insertions, 10 deletions
diff --git a/g10/build-packet.c b/g10/build-packet.c index 06f3884e6..c1e5137cd 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -623,8 +623,11 @@ 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 + else if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH) err = gpg_sos_write (a, pk->pkey[i], NULL); + else + err = gpg_mpi_write (a, pk->pkey[i], NULL); if (err) goto leave; } @@ -865,6 +868,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 = gpg_sos_write (a, enc->data[i], NULL); else rc = gpg_mpi_write (a, enc->data[i], NULL); } @@ -1749,7 +1754,10 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) rc = gpg_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 (sig->pubkey_algo == PUBKEY_ALGO_EDDSA) + rc = gpg_sos_write (a, sig->data[i], NULL); + else + rc = gpg_mpi_write (a, sig->data[i], NULL); if (!rc) { diff --git a/g10/parse-packet.c b/g10/parse-packet.c index fc37c095d..c6037d755 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -188,6 +188,64 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int 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); + *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,11 +1386,22 @@ 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) { - size_t n; - rc = read_size_body (inp, pktlen, &n, k->data+i); - pktlen -= n; + 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 { @@ -2282,7 +2351,10 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, for (i = 0; i < ndata; i++) { n = pktlen; - sig->data[i] = mpi_read (inp, &n, 0); + if (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 +2582,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,7 +2590,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, else { unsigned int n = pktlen; - pk->pkey[i] = mpi_read (inp, &n, 0); + if ( (algorithm == PUBKEY_ALGO_EDDSA && (i == 1)) + || (algorithm == PUBKEY_ALGO_ECDH && (i == 1))) + pk->pkey[i] = sos_read (inp, &n, 0); + else + pk->pkey[i] = mpi_read (inp, &n, 0); pktlen -= n; if (!pk->pkey[i]) err = gpg_error (GPG_ERR_INV_PACKET); @@ -2830,7 +2906,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, goto leave; } n = pktlen; - pk->pkey[i] = mpi_read (inp, &n, 0); + if (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) { |