rdata: store wire-encoded form of ECH configs
Previously the hickory-dns representation of ECH configs found in SVCB/HTTPS records held and exposed its own non-standard representation of the encoded ECH configs. Notably, it stripped the TLS-encoded list length prefix from the remaining data. Similarly, it's presentation format was the BASE64 encoding of this non-standard form. Downstream consumers are likely to want the wire-encoding format unmodified, because ECH is of most use to TLS libraries where they will have already implemented a generic TLS-encoded list decoder that expects the length prefix. In practice, popular tools like `dig` are also encoding the presentation format BASE64 of the data in DNS for some popular test servers with the prefix included. This commit updates hickory-dns's representation to not do the pre-processing it was before. This is trivial for a consumer to do if they need it, and avoids having to restore it manually in order to use other pre-existing TLS encoder/decoders with the value from hickory-dns. Again, since ECH adoption is in very early days it doesn't seem worthwhile to try and come up with a backwards compatible interface for those that need the old behaviour. It should be straightforward to remove the length prefix manually if required.
This commit is contained in:

committed by
Dirkjan Ochtman

parent
ffc51d7369
commit
5e23b5e587
@@ -836,14 +836,8 @@ impl<'r> BinDecodable<'r> for EchConfigList {
|
||||
/// Base 64 is used here to simplify integration with TLS server software.
|
||||
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
|
||||
fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
|
||||
let redundant_len = decoder
|
||||
.read_u16()?
|
||||
.map(|len| len as usize)
|
||||
.verify_unwrap(|len| *len <= decoder.len())
|
||||
.map_err(|_| ProtoError::from("ECH value length exceeds max size of u16::MAX"))?;
|
||||
|
||||
let data =
|
||||
decoder.read_vec(redundant_len)?.unverified(/*up to consumer to validate this data*/);
|
||||
decoder.read_vec(decoder.len())?.unverified(/*up to consumer to validate this data*/);
|
||||
|
||||
Ok(Self(data))
|
||||
}
|
||||
@@ -856,11 +850,6 @@ impl BinEncodable for EchConfigList {
|
||||
/// Base 64 is used here to simplify integration with TLS server software.
|
||||
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
|
||||
fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
|
||||
let len = u16::try_from(self.0.len())
|
||||
.map_err(|_| ProtoError::from("ECH value length exceeds max size of u16::MAX"))?;
|
||||
|
||||
// redundant length...
|
||||
encoder.emit_u16(len)?;
|
||||
encoder.emit_vec(&self.0)?;
|
||||
|
||||
Ok(())
|
||||
@@ -878,10 +867,6 @@ impl fmt::Display for EchConfigList {
|
||||
/// TLS server software. To enable simpler parsing, this SvcParam MUST NOT
|
||||
/// contain escape sequences.
|
||||
/// ```
|
||||
///
|
||||
/// *note* while the on the wire the EchConfig has a redundant length,
|
||||
/// the RFC is not explicit about including it in the BASE64 encoded value,
|
||||
/// hickory-dns will encode the data as it is stored, i.e. without the length encoding.
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
write!(f, "\"{}\"", data_encoding::BASE64.encode(&self.0))
|
||||
}
|
||||
|
Reference in New Issue
Block a user