From e0972d3d962548972872d889b362560e499340d1 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 5 Jan 2011 17:33:17 -0800 Subject: Integrating http://code.google.com/p/gnupg-ecc/source/detail?r=15 . The following works: gpg2 --gen-key (ECC) gpg2 --list-keys gpg2 --list-packets ~/.gnupg/pubring.gpg gpg2 --list-packets ECDH doesn't work yet as the code must be re-written to adjust for gpg-agent refactoring. --- g10/parse-packet.c | 115 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 88 insertions(+), 27 deletions(-) (limited to 'g10/parse-packet.c') diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 3714739d4..42d680ac5 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -939,20 +939,40 @@ 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 ) { + 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); + } + } + else + { + 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]); + mpi_print(listfp, k->data[1], mpi_print_mode ); + es_putc ('\n', listfp); + } + pktlen -= (encr_buf[0]+1); + } } leave: @@ -1926,20 +1946,61 @@ 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 ) { + 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); + } + } + else { + /* note that 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 */ + // log_debug("Parsing ecc public key in the public packet, pktlen=%lu\n", pktlen); + n = pktlen; pk->pkey[1] = mpi_read( inp, &n, 0 ); pktlen -=n; + if( pk->pkey[1]==NULL ) + err = gpg_error(G10ERR_INVALID_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 ) { +#define kek_params name_oid + err = iobuf_read_size_body( inp, kek_params, sizeof(kek_params), pktlen, pk->pkey+2 ); + if( err ) + goto leave; + n = kek_params[0]; + if( kek_params[1] != 1 ) { + log_error("invalid ecdh KEK parameters field type in private key: understand type 1, but found 0x%02x\n", kek_params[1]); + err = gpg_error(G10ERR_INVALID_PACKET); + goto leave; + } + if( list_mode ) + es_fprintf (listfp, "\tpkey[2]: KEK params type=01 hash:%d sym-algo:%d\n", kek_params[1+n-2], kek_params[1+n-1] ); + pktlen -= (n+1); +#undef kek_params + } + } if (err) goto leave; } -- cgit v1.2.3 From ded546b4b5cc2caafa654d94ac8f69a23960427e Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Thu, 6 Jan 2011 15:44:01 -0800 Subject: Milestone: Data signing/verification and key signing/verification work with ECDSA. --- g10/parse-packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'g10/parse-packet.c') diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 42d680ac5..d43ab2cba 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -967,7 +967,7 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, 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]); + es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1); mpi_print(listfp, k->data[1], mpi_print_mode ); es_putc ('\n', listfp); } -- cgit v1.2.3 From 90b0ff23b7e51332592668e4034967c1aac1c593 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 12:00:57 +0100 Subject: Editorial changes and allow building with old libgcrypts. Changed order of some conditional to make to put the special case into the true branch. Indentation changes. Minor other changes to make the ECC code more similar to the rest of our code. It builds but many sefltests still fail. Need to fix that before using it with an ECDH enabled libgcrypt. [/] 2011-01-21 Werner Koch * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP. (HAVE_GCRY_PK_ECDH): Add new test. [agent/] 2011-01-21 Werner Koch * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New. [include/] 2011-01-21 Werner Koch * cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros because we now require libgcrypt 1.4.6. (GCRY_PK_ECDH): Add replacement. --- g10/parse-packet.c | 194 +++++++++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 87 deletions(-) (limited to 'g10/parse-packet.c') diff --git a/g10/parse-packet.c b/g10/parse-packet.c index d43ab2cba..5df336e55 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -939,40 +939,47 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } else { - if( k->pubkey_algo != PUBKEY_ALGO_ECDH ) { - 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); - } - } - else + 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); - } + 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: @@ -1946,61 +1953,74 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, else { /* Fill in public key parameters. */ - if( algorithm != PUBKEY_ALGO_ECDSA && algorithm != PUBKEY_ALGO_ECDH ) { - 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); - } - } - else { - /* note that 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 */ - // log_debug("Parsing ecc public key in the public packet, pktlen=%lu\n", pktlen); - n = pktlen; pk->pkey[1] = mpi_read( inp, &n, 0 ); pktlen -=n; - if( pk->pkey[1]==NULL ) - err = gpg_error(G10ERR_INVALID_PACKET); - else if( list_mode ) { - es_fprintf (listfp, "\tpkey[1]: "); - mpi_print(listfp, pk->pkey[1], 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); } - /* One more field for ECDH */ - if( algorithm == PUBKEY_ALGO_ECDH ) { -#define kek_params name_oid - err = iobuf_read_size_body( inp, kek_params, sizeof(kek_params), pktlen, pk->pkey+2 ); - if( err ) - goto leave; - n = kek_params[0]; - if( kek_params[1] != 1 ) { - log_error("invalid ecdh KEK parameters field type in private key: understand type 1, but found 0x%02x\n", kek_params[1]); - err = gpg_error(G10ERR_INVALID_PACKET); - goto leave; - } - if( list_mode ) - es_fprintf (listfp, "\tpkey[2]: KEK params type=01 hash:%d sym-algo:%d\n", kek_params[1+n-2], kek_params[1+n-1] ); - pktlen -= (n+1); -#undef kek_params - } - } + /* 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; } -- cgit v1.2.3 From b3adbb576e88a12ee9e7ea790a72ad5f1bff4c78 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 24 Jan 2011 12:02:35 +0100 Subject: Fix regression introduced by "editing only change". Signing and verification using a new key works again. --- g10/parse-packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'g10/parse-packet.c') diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 5df336e55..334a9a82b 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1953,7 +1953,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, else { /* Fill in public key parameters. */ - if (algorithm == PUBKEY_ALGO_ECDSA && algorithm == PUBKEY_ALGO_ECDH) + if (algorithm == PUBKEY_ALGO_ECDSA || algorithm == PUBKEY_ALGO_ECDH) { /* FIXME: The code in this function ignores the errors. */ byte name_oid[256]; -- cgit v1.2.3 From 358afc0dc8980d5ae0cb700efbb61499625a4625 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 26 Jan 2011 17:17:43 +0100 Subject: Function name cleanups Also nuked some trailing spaces. --- g10/parse-packet.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) (limited to 'g10/parse-packet.c') diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 334a9a82b..a0844c7ac 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -741,6 +741,55 @@ read_rest (IOBUF inp, size_t pktlen, int partial) } +/* + * Read a special size+body from inp into body[body_max_size] and + * return it in a buffer and as MPI. On success the number of + * consumed bytes will body[0]+1. The format of the content of the + * returned MPI is one byte LEN, following by LEN bytes. Caller is + * expected to pre-allocate fixed-size 255 byte buffer (or smaller + * when appropriate). + */ +static int +read_size_body (iobuf_t inp, byte *body, int body_max_size, + int pktlen, gcry_mpi_t *out ) +{ + unsigned int n; + int rc; + gcry_mpi_t result; + + *out = NULL; + + if( (n = iobuf_readbyte(inp)) == -1 ) + { + return G10ERR_INVALID_PACKET; + } + if ( n >= body_max_size || n < 2) + { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } + body[0] = n; + if ((n = iobuf_read(inp, body+1, n)) == -1) + { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } + if (n+1 > pktlen) + { + log_error("size+body field is larger than the packet\n"); + return G10ERR_INVALID_PACKET; + } + rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL); + if (rc) + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc)); + + *out = result; + + return rc; +} + + +/* Parse a marker packet. */ static int parse_marker (IOBUF inp, int pkttype, unsigned long pktlen) { @@ -947,8 +996,8 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, 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); + rc = read_size_body (inp, encr_buf, sizeof(encr_buf), + pktlen, k->data+1); if (rc) goto leave; @@ -1958,8 +2007,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, /* 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); + err = read_size_body (inp, name_oid, sizeof(name_oid), + pktlen, pk->pkey+0); if (err) goto leave; n = name_oid[0]; @@ -1984,8 +2033,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, 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); + err = read_size_body (inp, name_oid, sizeof(name_oid), + pktlen, pk->pkey+2); if (err) goto leave; n = name_oid[0]; -- cgit v1.2.3 From 0fb0bb8d9a960a2473ab70a021d20639a43227e0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 09:27:06 +0100 Subject: Reworked the ECC changes to better fit into the Libgcrypt API. See ChangeLog for details. Key generation, signing and verification works. Encryption does not yet work. Requires latest Libgcrypt changes. --- g10/parse-packet.c | 201 +++++++++++++++++++---------------------------------- 1 file changed, 71 insertions(+), 130 deletions(-) (limited to 'g10/parse-packet.c') diff --git a/g10/parse-packet.c b/g10/parse-packet.c index a0844c7ac..83be15d8c 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -741,51 +741,57 @@ read_rest (IOBUF inp, size_t pktlen, int partial) } -/* - * Read a special size+body from inp into body[body_max_size] and - * return it in a buffer and as MPI. On success the number of - * consumed bytes will body[0]+1. The format of the content of the - * returned MPI is one byte LEN, following by LEN bytes. Caller is - * expected to pre-allocate fixed-size 255 byte buffer (or smaller - * when appropriate). - */ -static int -read_size_body (iobuf_t inp, byte *body, int body_max_size, - int pktlen, gcry_mpi_t *out ) +/* Read a special size+body from INP. On success store an opaque MPI + with it at R_DATA. On error return an error code and store NULL at + R_DATA. Even in the error case store the number of read bytes at + R_NREAD. The caller shall pass the remaining size of the packet in + PKTLEN. */ +static gpg_error_t +read_size_body (iobuf_t inp, int pktlen, size_t *r_nread, + gcry_mpi_t *r_data) { - unsigned int n; - int rc; - gcry_mpi_t result; + char buffer[256]; + char *tmpbuf; + int i, c, nbytes; + + *r_nread = 0; + *r_data = NULL; + + if (!pktlen) + return gpg_error (GPG_ERR_INV_PACKET); + c = iobuf_readbyte (inp); + if (c < 0) + return gpg_error (GPG_ERR_INV_PACKET); + pktlen--; + ++*r_nread; + nbytes = c; + if (nbytes < 2 || nbytes > 254) + return gpg_error (GPG_ERR_INV_PACKET); + if (nbytes > pktlen) + return gpg_error (GPG_ERR_INV_PACKET); - *out = NULL; + buffer[0] = nbytes; - if( (n = iobuf_readbyte(inp)) == -1 ) - { - return G10ERR_INVALID_PACKET; - } - if ( n >= body_max_size || n < 2) - { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; - } - body[0] = n; - if ((n = iobuf_read(inp, body+1, n)) == -1) + for (i = 0; i < nbytes; i++) { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; + c = iobuf_get (inp); + if (c < 0) + return gpg_error (GPG_ERR_INV_PACKET); + ++*r_nread; + buffer[1+i] = c; } - if (n+1 > pktlen) + + tmpbuf = xtrymalloc (1 + nbytes); + if (!tmpbuf) + return gpg_error_from_syserror (); + memcpy (tmpbuf, buffer, 1 + nbytes); + *r_data = gcry_mpi_set_opaque (NULL, tmpbuf, 8 * (1 + nbytes)); + if (!*r_data) { - log_error("size+body field is larger than the packet\n"); - return G10ERR_INVALID_PACKET; + xfree (tmpbuf); + return gpg_error_from_syserror (); } - rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL); - if (rc) - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc)); - - *out = result; - - return rc; + return 0; } @@ -988,46 +994,29 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } else { - if (k->pubkey_algo == PUBKEY_ALGO_ECDH) + for (i = 0; i < ndata; i++) { - byte encr_buf[255]; - - assert (ndata == 2); - n = pktlen; - k->data[0] = mpi_read (inp, &n, 0); - pktlen -= n; - rc = read_size_body (inp, encr_buf, sizeof(encr_buf), - pktlen, k->data+1); - if (rc) - goto leave; - - if (list_mode) + if (k->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1) { - 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); + rc = read_size_body (inp, pktlen, &n, k->data+i); + pktlen -= n; } - pktlen -= (encr_buf[0]+1); - } - else - { - for (i = 0; i < ndata; i++) + else { 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 (rc) + goto leave; + if (list_mode) + { + es_fprintf (listfp, "\tdata: "); + mpi_print (listfp, k->data[i], mpi_print_mode); + es_putc ('\n', listfp); + } } } @@ -1989,7 +1978,6 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, unknown_pubkey_warning (algorithm); } - if (!npkey) { /* Unknown algorithm - put data into an opaque MPI. */ @@ -2001,79 +1989,32 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, } else { - /* Fill in public key parameters. */ - if (algorithm == PUBKEY_ALGO_ECDSA || algorithm == PUBKEY_ALGO_ECDH) + for (i = 0; i < npkey; i++) { - /* FIXME: The code in this function ignores the errors. */ - byte name_oid[256]; - - err = 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) + if ((algorithm == PUBKEY_ALGO_ECDSA + || algorithm == PUBKEY_ALGO_ECDH) && (i==0 || i == 2)) { - es_fprintf (listfp, "\tpkey[1]: "); - mpi_print (listfp, pk->pkey[1], mpi_print_mode); - es_putc ('\n', listfp); - } - /* One more field for ECDH. */ - if (algorithm == PUBKEY_ALGO_ECDH) - { - /* (NAMEOID holds the KEK params.) */ - err = 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); + err = read_size_body (inp, pktlen, &n, pk->pkey+i); + pktlen -= n; } - } - else - { - for (i = 0; i < npkey; i++) + else { 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; + if (list_mode) + { + es_fprintf (listfp, "\tpkey[%d]: ", i); + mpi_print (listfp, pk->pkey[i], mpi_print_mode); + es_putc ('\n', listfp); + } } - if (err) - goto leave; } - if (list_mode) keyid_from_pk (pk, keyid); -- cgit v1.2.3