Sign channel IDs with ECDSA_do_sign.

Rather than parse with d2i_ECDSA_SIG and reserialize, this is cleaner.
It's also clearer that i2d_PublicKey isn't being used for DER.

Change-Id: Iac57fb6badd1dfed1e66984e95a31f609b1538a4
Reviewed-on: https://boringssl-review.googlesource.com/5263
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 6571c2e..1d9b164 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -152,16 +152,18 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <openssl/bn.h>
 #include <openssl/buf.h>
 #include <openssl/bytestring.h>
-#include <openssl/rand.h>
-#include <openssl/obj.h>
+#include <openssl/dh.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
-#include <openssl/mem.h>
 #include <openssl/md5.h>
-#include <openssl/dh.h>
-#include <openssl/bn.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+#include <openssl/rand.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
@@ -2218,7 +2220,6 @@
   uint8_t *d;
   int ret = -1, public_key_len;
   EVP_MD_CTX md_ctx;
-  size_t sig_len;
   ECDSA_SIG *sig = NULL;
   uint8_t *public_key = NULL, *derp, *der_sig = NULL;
 
@@ -2240,6 +2241,12 @@
   }
   s->rwstate = SSL_NOTHING;
 
+  if (EVP_PKEY_id(s->tlsext_channel_id_private) != EVP_PKEY_EC) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_INTERNAL_ERROR);
+    return -1;
+  }
+  EC_KEY *ec_key = s->tlsext_channel_id_private->pkey.ec;
+
   d = ssl_handshake_start(s);
   if (s->s3->tlsext_channel_id_new) {
     s2n(TLSEXT_TYPE_channel_id_new, d);
@@ -2250,14 +2257,14 @@
 
   EVP_MD_CTX_init(&md_ctx);
 
-  public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
+  public_key_len = i2o_ECPublicKey(ec_key, NULL);
   if (public_key_len <= 0) {
     OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
                       SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
     goto err;
   }
 
-  /* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
+  /* i2o_ECPublicKey will produce an ANSI X9.62 public key which, for a
    * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
    * field elements as 32-byte, big-endian numbers. */
   if (public_key_len != 65) {
@@ -2271,41 +2278,18 @@
   }
 
   derp = public_key;
-  i2d_PublicKey(s->tlsext_channel_id_private, &derp);
+  i2o_ECPublicKey(ec_key, &derp);
 
-  if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
-                         s->tlsext_channel_id_private) != 1) {
-    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
-                      SSL_R_EVP_DIGESTSIGNINIT_FAILED);
+  uint8_t digest[EVP_MAX_MD_SIZE];
+  unsigned digest_len;
+  if (!EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL) ||
+      !tls1_channel_id_hash(&md_ctx, s) ||
+      !EVP_DigestFinal_ex(&md_ctx, digest, &digest_len)) {
     goto err;
   }
 
-  if (!tls1_channel_id_hash(&md_ctx, s)) {
-    goto err;
-  }
-
-  if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) {
-    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
-                      SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
-    goto err;
-  }
-
-  der_sig = OPENSSL_malloc(sig_len);
-  if (!der_sig) {
-    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
-  if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len)) {
-    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
-                      SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
-    goto err;
-  }
-
-  derp = der_sig;
-  sig = d2i_ECDSA_SIG(NULL, (const uint8_t **)&derp, sig_len);
+  sig = ECDSA_do_sign(digest, digest_len, ec_key);
   if (sig == NULL) {
-    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_D2I_ECDSA_SIG);
     goto err;
   }