Integrating http://code.google.com/p/gnupg-ecc/source/detail?r=15 .
[gnupg.git] / g10 / build-packet.c
index 83d6c7a..3a2c206 100644 (file)
@@ -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)
     {