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) {