Rearrange SSLKeyShare::Serialize.

It's strange to have Serialize/Deserialize methods not inverses of each
other. Split the operation up and move the common parts out of the
subclass.

Change-Id: Iadfa57de19faca411c64b64d2568a78d2eb982e8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46529
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/internal.h b/ssl/internal.h
index 7bb11f1..e733e67 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1066,6 +1066,10 @@
   // |Serialize|.
   static UniquePtr<SSLKeyShare> Create(CBS *in);
 
+  // Serializes writes the group ID and private key, in a format that can be
+  // read by |Create|.
+  bool Serialize(CBB *out);
+
   // GroupID returns the group ID.
   virtual uint16_t GroupID() const PURE_VIRTUAL;
 
@@ -1090,13 +1094,13 @@
   virtual bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
                       Span<const uint8_t> peer_key) PURE_VIRTUAL;
 
-  // Serialize writes the state of the key exchange to |out|, returning true if
-  // successful and false otherwise.
-  virtual bool Serialize(CBB *out) { return false; }
+  // SerializePrivateKey writes the private key to |out|, returning true if
+  // successful and false otherwise. It should be called after |Offer|.
+  virtual bool SerializePrivateKey(CBB *out) { return false; }
 
-  // Deserialize initializes the state of the key exchange from |in|, returning
-  // true if successful and false otherwise.  It is called by |Create|.
-  virtual bool Deserialize(CBS *in) { return false; }
+  // DeserializePrivateKey initializes the state of the key exchange from |in|,
+  // returning true if successful and false otherwise.
+  virtual bool DeserializePrivateKey(CBS *in) { return false; }
 };
 
 struct NamedGroup {
diff --git a/ssl/ssl_key_share.cc b/ssl/ssl_key_share.cc
index 6cac3cf..d9a09c7 100644
--- a/ssl/ssl_key_share.cc
+++ b/ssl/ssl_key_share.cc
@@ -124,29 +124,17 @@
     return true;
   }
 
-  bool Serialize(CBB *out) override {
+  bool SerializePrivateKey(CBB *out) override {
     assert(private_key_);
-    CBB cbb;
     UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(nid_));
     // Padding is added to avoid leaking the length.
     size_t len = BN_num_bytes(EC_GROUP_get0_order(group.get()));
-    if (!CBB_add_asn1_uint64(out, group_id_) ||
-        !CBB_add_asn1(out, &cbb, CBS_ASN1_OCTETSTRING) ||
-        !BN_bn2cbb_padded(&cbb, len, private_key_.get()) ||
-        !CBB_flush(out)) {
-      return false;
-    }
-    return true;
+    return BN_bn2cbb_padded(out, len, private_key_.get());
   }
 
-  bool Deserialize(CBS *in) override {
+  bool DeserializePrivateKey(CBS *in) override {
     assert(!private_key_);
-    CBS private_key;
-    if (!CBS_get_asn1(in, &private_key, CBS_ASN1_OCTETSTRING)) {
-      return false;
-    }
-    private_key_.reset(BN_bin2bn(CBS_data(&private_key),
-                                 CBS_len(&private_key), nullptr));
+    private_key_.reset(BN_bin2bn(CBS_data(in), CBS_len(in), nullptr));
     return private_key_ != nullptr;
   }
 
@@ -189,16 +177,13 @@
     return true;
   }
 
-  bool Serialize(CBB *out) override {
-    return (CBB_add_asn1_uint64(out, GroupID()) &&
-            CBB_add_asn1_octet_string(out, private_key_, sizeof(private_key_)));
+  bool SerializePrivateKey(CBB *out) override {
+    return CBB_add_bytes(out, private_key_, sizeof(private_key_));
   }
 
-  bool Deserialize(CBS *in) override {
-    CBS key;
-    if (!CBS_get_asn1(in, &key, CBS_ASN1_OCTETSTRING) ||
-        CBS_len(&key) != sizeof(private_key_) ||
-        !CBS_copy_bytes(&key, private_key_, sizeof(private_key_))) {
+  bool DeserializePrivateKey(CBS *in) override {
+    if (CBS_len(in) != sizeof(private_key_) ||
+        !CBS_copy_bytes(in, private_key_, sizeof(private_key_))) {
       return false;
     }
     return true;
@@ -339,16 +324,28 @@
 
 UniquePtr<SSLKeyShare> SSLKeyShare::Create(CBS *in) {
   uint64_t group;
-  if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff) {
+  CBS private_key;
+  if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff ||
+      !CBS_get_asn1(in, &private_key, CBS_ASN1_OCTETSTRING)) {
     return nullptr;
   }
   UniquePtr<SSLKeyShare> key_share = Create(static_cast<uint16_t>(group));
-  if (!key_share || !key_share->Deserialize(in)) {
+  if (!key_share || !key_share->DeserializePrivateKey(&private_key)) {
     return nullptr;
   }
   return key_share;
 }
 
+bool SSLKeyShare::Serialize(CBB *out) {
+  CBB private_key;
+  if (!CBB_add_asn1_uint64(out, GroupID()) ||
+      !CBB_add_asn1(out, &private_key, CBS_ASN1_OCTETSTRING) ||
+      !SerializePrivateKey(&private_key) ||  //
+      !CBB_flush(out)) {
+    return false;
+  }
+  return true;
+}
 
 bool SSLKeyShare::Accept(CBB *out_public_key, Array<uint8_t> *out_secret,
                          uint8_t *out_alert, Span<const uint8_t> peer_key) {