aboutsummaryrefslogtreecommitdiffstats
path: root/g10/build-packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/build-packet.c')
-rw-r--r--g10/build-packet.c69
1 files changed, 58 insertions, 11 deletions
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 83d6c7a73..d138e0614 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -178,11 +178,20 @@ 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
-/****************
- * calculate the length of a packet described by PKT
- */
+/* Write the value of encrypted filed for ECDH. */
+#define ecdh_esk_write iobuf_write_size_body_mpi
+
+
+/* Calculate the length of a packet described by PKT. */
u32
calc_packet_length( PACKET *pkt )
{
@@ -290,10 +299,35 @@ 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;
+ /* Writing the public parameters is easy. Except if we do an
+ adjustment for ECC OID and possibly KEK params for ECDH. */
+ if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
+ || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+ {
+ /* Write DER of OID with preceeding length byte. */
+ err = iobuf_name_oid_write (a, pk->pkey[0]);
+ if (err)
+ goto leave;
+ /* Write point Q, the public key. */
+ err = mpi_write (a, pk->pkey[1]);
+ if (err)
+ goto leave;
+
+ /* Write one more public field for ECDH. */
+ if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+ {
+ err = ecdh_kek_params_write(a,pk->pkey[2]);
+ if (err)
+ goto leave;
+ }
+ }
+ else
+ {
+ for (i=0; i < npkey; i++ )
+ if ((err = mpi_write (a, pk->pkey[i])))
+ goto leave;
+ }
+
if (pk->seckey_info)
{
@@ -458,13 +492,26 @@ 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 )
+ {
+ /* 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]);
+ }
+ else
+ {
+ for (i=0; i < n && !rc ; i++ )
+ rc = mpi_write(a, enc->data[i] );
+ }
if (!rc)
{
- write_header(out, ctb, iobuf_get_temp_length(a) );
- rc = iobuf_write_temp( out, a );
+ write_header (out, ctb, iobuf_get_temp_length(a) );
+ rc = iobuf_write_temp (out, a);
}
iobuf_close(a);
return rc;