boring2/quinn-boring/src/version.rs

152 lines
5.2 KiB
Rust

use quinn_proto::crypto;
use std::result::Result as StdResult;
/// QUIC protocol version
///
/// Governs version-specific behavior in the TLS layer
// TODO: add support for draft version 2.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum QuicVersion {
V1Draft29,
V1Draft30,
V1Draft31,
V1Draft32,
V1Draft33,
V1Draft34,
/// First stable RFC version.
V1,
}
impl Default for QuicVersion {
fn default() -> Self {
Self::V1
}
}
impl QuicVersion {
const DRAFT_INDICATOR: u32 = 0xff00_0000;
const VERSION_1_DRAFT_29: u32 = Self::DRAFT_INDICATOR | 29;
const VERSION_1_DRAFT_30: u32 = Self::DRAFT_INDICATOR | 30;
const VERSION_1_DRAFT_31: u32 = Self::DRAFT_INDICATOR | 31;
const VERSION_1_DRAFT_32: u32 = Self::DRAFT_INDICATOR | 32;
const VERSION_1_DRAFT_33: u32 = Self::DRAFT_INDICATOR | 33;
const VERSION_1_DRAFT_34: u32 = Self::DRAFT_INDICATOR | 34;
const VERSION_1: u32 = 1;
/// Returns the default list of supported quic versions.
pub fn default_supported_versions() -> Vec<u32> {
let mut out = Vec::new();
for v in [
Self::V1,
Self::V1Draft34,
Self::V1Draft33,
Self::V1Draft32,
Self::V1Draft31,
Self::V1Draft30,
Self::V1Draft29,
] {
out.push(v.label());
}
out
}
pub(crate) fn parse(version: u32) -> StdResult<Self, crypto::UnsupportedVersion> {
match version {
Self::VERSION_1_DRAFT_29 => Ok(Self::V1Draft29),
Self::VERSION_1_DRAFT_30 => Ok(Self::V1Draft30),
Self::VERSION_1_DRAFT_31 => Ok(Self::V1Draft31),
Self::VERSION_1_DRAFT_32 => Ok(Self::V1Draft32),
Self::VERSION_1_DRAFT_33 => Ok(Self::V1Draft33),
Self::VERSION_1_DRAFT_34 => Ok(Self::V1Draft34),
Self::VERSION_1 => Ok(Self::V1),
_ => Err(crypto::UnsupportedVersion),
}
}
pub(crate) fn label(&self) -> u32 {
match self {
Self::V1Draft29 => Self::VERSION_1_DRAFT_29,
Self::V1Draft30 => Self::VERSION_1_DRAFT_30,
Self::V1Draft31 => Self::VERSION_1_DRAFT_31,
Self::V1Draft32 => Self::VERSION_1_DRAFT_32,
Self::V1Draft33 => Self::VERSION_1_DRAFT_33,
Self::V1Draft34 => Self::VERSION_1_DRAFT_34,
Self::V1 => Self::VERSION_1,
}
}
pub(crate) fn initial_salt(&self) -> &'static [u8] {
match self {
Self::V1Draft29 | Self::V1Draft30 | Self::V1Draft31 | Self::V1Draft32 => &[
// https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-32#section-5.2
0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
],
Self::V1Draft33 | Self::V1Draft34 | Self::V1 => &[
// https://www.rfc-editor.org/rfc/rfc9001.html#name-initial-secrets
0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
],
}
}
pub(crate) fn retry_integrity_key(&self) -> &'static [u8] {
match self {
Self::V1Draft29 | Self::V1Draft30 | Self::V1Draft31 | Self::V1Draft32 => &[
// https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-32#section-5.8
0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a, 0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a, 0x6c, 0xb9,
0x6b, 0xe1,
],
Self::V1Draft33 | Self::V1Draft34 | Self::V1 => &[
// https://datatracker.ietf.org/doc/html/rfc9001#name-retry-packet-integrity
0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68,
0xc8, 0x4e,
],
}
}
pub(crate) fn retry_integrity_nonce(&self) -> &'static [u8] {
match self {
Self::V1Draft29 | Self::V1Draft30 | Self::V1Draft31 | Self::V1Draft32 => &[
// https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-32#section-5.8
0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c,
],
Self::V1Draft33 | Self::V1Draft34 | Self::V1 => &[
// https://datatracker.ietf.org/doc/html/rfc9001#name-retry-packet-integrity
0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb,
],
}
}
/// Indicates whether this version uses the legacy TLS extension codepoint.
pub(crate) fn uses_legacy_extension(&self) -> bool {
match self {
Self::V1Draft29
| Self::V1Draft30
| Self::V1Draft31
| Self::V1Draft32
| Self::V1Draft33
| Self::V1Draft34 => true,
Self::V1 => false,
}
}
pub(crate) fn key_label(&self) -> &'static [u8] {
b"quic key"
}
pub(crate) fn iv_label(&self) -> &'static [u8] {
b"quic iv"
}
pub(crate) fn header_key_label(&self) -> &'static [u8] {
b"quic hp"
}
pub(crate) fn key_update_label(&self) -> &'static [u8] {
b"quic ku"
}
}