diff options
Diffstat (limited to 'g10/build-packet.c')
-rw-r--r-- | g10/build-packet.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/g10/build-packet.c b/g10/build-packet.c index 83d6c7a73..3a2c206c8 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -178,6 +178,16 @@ mpi_write (iobuf_t out, gcry_mpi_t a) return rc; } +/* + * Write the name OID, encoded as an mpi, to OUT. The format of the content of the MPI is + * one byte LEN, following by LEN bytes that are DER representation of an ASN.1 OID. + * This is true for each of the 3 following functions. + */ +#define iobuf_name_oid_write iobuf_write_size_body_mpi +/* Write the value of KEK fields for ECDH. */ +#define ecdh_kek_params_write iobuf_write_size_body_mpi +/* Write the value of encrypted filed for ECDH. */ +#define ecdh_esk_write iobuf_write_size_body_mpi /**************** @@ -290,10 +300,24 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } assert (npkey < nskey); - /* Writing the public parameters is easy. */ - for (i=0; i < npkey; i++ ) - if ((err = mpi_write (a, pk->pkey[i]))) - goto leave; + if( pk->pubkey_algo != PUBKEY_ALGO_ECDSA && pk->pubkey_algo != PUBKEY_ALGO_ECDH ) { + /* Writing the public parameters is easy, */ + for (i=0; i < npkey; i++ ) + if ((err = mpi_write (a, pk->pkey[i]))) + goto leave; + } + else { + /* ... except we do an adjustment for ECC OID and possibly KEK params for ECDH */ + if( (err=iobuf_name_oid_write(a, pk->pkey[0])) || /* DER of OID with preceeding length byte */ + (err = mpi_write (a, pk->pkey[1])) ) /* point Q, the public key */ + { + goto leave; + } + if( pk->pubkey_algo == PUBKEY_ALGO_ECDH && (err=ecdh_kek_params_write(a,pk->pkey[2]))) { /* one more public field for ECDH */ + goto leave; + } + /* followed by possibly protected private scalar */ + } if (pk->seckey_info) { @@ -458,8 +482,18 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) n = pubkey_get_nenc( enc->pubkey_algo ); if ( !n ) write_fake_data( a, enc->data[0] ); - for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, enc->data[i] ); + + if( enc->pubkey_algo != PUBKEY_ALGO_ECDH ) { + for (i=0; i < n && !rc ; i++ ) + rc = mpi_write(a, enc->data[i] ); + } + else { + /* the second field persists as a LEN+field structure, even though it is + * stored for uniformity as an MPI internally */ + assert( n==2 ); + rc = mpi_write(a, enc->data[0] ); + if( !rc ) rc = ecdh_esk_write(a, enc->data[1] ); + } if (!rc) { |