aboutsummaryrefslogtreecommitdiffstats
path: root/g10/parse-packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r--g10/parse-packet.c135
1 files changed, 108 insertions, 27 deletions
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 3714739d4..334a9a82b 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -939,20 +939,47 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
}
else
{
- for (i = 0; i < ndata; i++)
- {
- n = pktlen;
- k->data[i] = mpi_read (inp, &n, 0);
- pktlen -= n;
- if (list_mode)
- {
- es_fprintf (listfp, "\tdata: ");
- mpi_print (listfp, k->data[i], mpi_print_mode);
- es_putc ('\n', listfp);
- }
- if (!k->data[i])
- rc = gpg_error (GPG_ERR_INV_PACKET);
- }
+ if (k->pubkey_algo == PUBKEY_ALGO_ECDH)
+ {
+ byte encr_buf[255];
+
+ assert (ndata == 2);
+ n = pktlen;
+ k->data[0] = mpi_read (inp, &n, 0);
+ pktlen -= n;
+ rc = iobuf_read_size_body (inp, encr_buf, sizeof(encr_buf),
+ pktlen, k->data+1);
+ if (rc)
+ goto leave;
+
+ if (list_mode)
+ {
+ es_fprintf (listfp, "\tdata: ");
+ mpi_print (listfp, k->data[0], mpi_print_mode );
+ es_putc ('\n', listfp);
+ es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1);
+ mpi_print (listfp, k->data[1], mpi_print_mode );
+ es_putc ('\n', listfp);
+ }
+ pktlen -= (encr_buf[0]+1);
+ }
+ else
+ {
+ for (i = 0; i < ndata; i++)
+ {
+ n = pktlen;
+ k->data[i] = mpi_read (inp, &n, 0);
+ pktlen -= n;
+ if (list_mode)
+ {
+ es_fprintf (listfp, "\tdata: ");
+ mpi_print (listfp, k->data[i], mpi_print_mode);
+ es_putc ('\n', listfp);
+ }
+ if (!k->data[i])
+ rc = gpg_error (GPG_ERR_INV_PACKET);
+ }
+ }
}
leave:
@@ -1926,20 +1953,74 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
else
{
/* Fill in public key parameters. */
- for (i = 0; i < npkey; i++)
- {
- n = pktlen;
- pk->pkey[i] = mpi_read (inp, &n, 0);
- pktlen -= n;
- if (list_mode)
- {
- es_fprintf (listfp, "\tpkey[%d]: ", i);
- mpi_print (listfp, pk->pkey[i], mpi_print_mode);
- es_putc ('\n', listfp);
+ if (algorithm == PUBKEY_ALGO_ECDSA || algorithm == PUBKEY_ALGO_ECDH)
+ {
+ /* FIXME: The code in this function ignores the errors. */
+ byte name_oid[256];
+
+ err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid),
+ pktlen, pk->pkey+0);
+ if (err)
+ goto leave;
+ n = name_oid[0];
+ if (list_mode)
+ es_fprintf (listfp, "\tpkey[0]: curve OID [%d] ...%02x %02x\n",
+ n, name_oid[1+n-2], name_oid[1+n-1]);
+ pktlen -= (n+1);
+ /* Set item [1], which corresponds to the public key; these
+ two fields are all we need to uniquely define the key/ */
+ n = pktlen;
+ pk->pkey[1] = mpi_read( inp, &n, 0 );
+ pktlen -=n;
+ if (!pk->pkey[1])
+ err = gpg_error (GPG_ERR_INV_PACKET);
+ else if (list_mode)
+ {
+ es_fprintf (listfp, "\tpkey[1]: ");
+ mpi_print (listfp, pk->pkey[1], mpi_print_mode);
+ es_putc ('\n', listfp);
}
- if (!pk->pkey[i])
- err = gpg_error (GPG_ERR_INV_PACKET);
- }
+ /* One more field for ECDH. */
+ if (algorithm == PUBKEY_ALGO_ECDH)
+ {
+ /* (NAMEOID holds the KEK params.) */
+ err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid),
+ pktlen, pk->pkey+2);
+ if (err)
+ goto leave;
+ n = name_oid[0];
+ if (name_oid[1] != 1)
+ {
+ log_error ("invalid ecdh KEK parameters field type in "
+ "private key: understand type 1, "
+ "but found 0x%02x\n", name_oid[1]);
+ err = gpg_error (GPG_ERR_INV_PACKET);
+ goto leave;
+ }
+ if (list_mode)
+ es_fprintf (listfp, "\tpkey[2]: KEK params type=01 "
+ "hash:%d sym-algo:%d\n",
+ name_oid[1+n-2], name_oid[1+n-1]);
+ pktlen -= (n+1);
+ }
+ }
+ else
+ {
+ for (i = 0; i < npkey; i++)
+ {
+ n = pktlen;
+ pk->pkey[i] = mpi_read (inp, &n, 0);
+ pktlen -= n;
+ if (list_mode)
+ {
+ es_fprintf (listfp, "\tpkey[%d]: ", i);
+ mpi_print (listfp, pk->pkey[i], mpi_print_mode);
+ es_putc ('\n', listfp);
+ }
+ if (!pk->pkey[i])
+ err = gpg_error (GPG_ERR_INV_PACKET);
+ }
+ }
if (err)
goto leave;
}