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.
|
/// Base 64 is used here to simplify integration with TLS server software.
|
||||||
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
|
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
|
||||||
fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
|
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 =
|
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))
|
Ok(Self(data))
|
||||||
}
|
}
|
||||||
@@ -856,11 +850,6 @@ impl BinEncodable for EchConfigList {
|
|||||||
/// Base 64 is used here to simplify integration with TLS server software.
|
/// Base 64 is used here to simplify integration with TLS server software.
|
||||||
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
|
/// To enable simpler parsing, this SvcParam MUST NOT contain escape sequences.
|
||||||
fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
|
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)?;
|
encoder.emit_vec(&self.0)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -878,10 +867,6 @@ impl fmt::Display for EchConfigList {
|
|||||||
/// TLS server software. To enable simpler parsing, this SvcParam MUST NOT
|
/// TLS server software. To enable simpler parsing, this SvcParam MUST NOT
|
||||||
/// contain escape sequences.
|
/// 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> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
write!(f, "\"{}\"", data_encoding::BASE64.encode(&self.0))
|
write!(f, "\"{}\"", data_encoding::BASE64.encode(&self.0))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user