server: reject 1.3 ClientHello with non-1.2 legacy_version

This commit is contained in:
Dirkjan Ochtman 2021-06-11 17:22:12 +02:00
parent ade34d5be6
commit 4a268a8fa2
2 changed files with 70 additions and 1 deletions

View File

@ -362,6 +362,19 @@ impl State for ExpectClientHello {
ProtocolVersion::TLSv1_2
};
if version == ProtocolVersion::TLSv1_3
&& client_hello.client_version != ProtocolVersion::TLSv1_2
{
// RFC 8446 - 4.1.2
// In TLS 1.3, the client indicates its version preferences in the
// "supported_versions" extension (Section 4.2.1) and the
// legacy_version field MUST be set to 0x0303, which is the version
// number for TLS 1.2.
return Err(Error::PeerMisbehavedError(
"TLS 1.3 ClientHello must set legacy_version to TLS 0x0303".to_string(),
));
}
cx.common.negotiated_version = Some(version);
// --- Common to TLS1.2 and TLS1.3: ciphersuite and certificate selection.

View File

@ -3293,7 +3293,7 @@ mod test_quic {
payload: MessagePayload::Handshake(HandshakeMessagePayload {
typ: HandshakeType::ClientHello,
payload: HandshakePayload::ClientHello(ClientHelloPayload {
client_version: ProtocolVersion::TLSv1_3,
client_version: ProtocolVersion::TLSv1_2,
random,
session_id: SessionID::random().unwrap(),
cipher_suites: vec![CipherSuite::TLS13_AES_128_GCM_SHA256],
@ -3468,6 +3468,62 @@ fn test_reject_cookie_in_initial_client_hello() {
);
}
#[test]
fn test_tls13_reject_client_hello_with_non_tls12_legacy_version() {
let mut server_config = make_server_config(KeyType::ED25519);
server_config
.versions
.replace(&[&rustls::version::TLS13]);
server_config.alpn_protocols = vec!["foo".into()];
let server_config = Arc::new(server_config);
let mut server = ServerConnection::new(server_config).unwrap();
use ring::rand::SecureRandom;
use rustls::internal::msgs::base::PayloadU16;
use rustls::internal::msgs::enums::{CipherSuite, Compression, HandshakeType};
use rustls::internal::msgs::handshake::{
ClientHelloPayload, HandshakeMessagePayload, Random, SessionID,
};
use rustls::internal::msgs::message::PlainMessage;
let rng = ring::rand::SystemRandom::new();
let mut random = [0; 32];
rng.fill(&mut random).unwrap();
let random = Random::from(random);
let client_hello = Message {
version: ProtocolVersion::TLSv1_1,
payload: MessagePayload::Handshake(HandshakeMessagePayload {
typ: HandshakeType::ClientHello,
payload: HandshakePayload::ClientHello(ClientHelloPayload {
client_version: ProtocolVersion::TLSv1_3,
random,
session_id: SessionID::random().unwrap(),
cipher_suites: vec![CipherSuite::TLS13_AES_128_GCM_SHA256],
compression_methods: vec![Compression::Null],
extensions: vec![
ClientExtension::SupportedVersions(vec![ProtocolVersion::TLSv1_3]),
ClientExtension::Cookie(PayloadU16(b"foo".to_vec())),
],
}),
}),
};
let buf = PlainMessage::from(client_hello)
.into_unencrypted_opaque()
.encode();
server
.read_tls(&mut buf.as_slice())
.unwrap();
assert_eq!(
server.process_new_packets().err(),
Some(Error::PeerMisbehavedError(
"TLS 1.3 ClientHello must set legacy_version to TLS 0x0303".into(),
)),
);
}
#[test]
fn test_client_does_not_offer_sha1() {
use rustls::internal::msgs::{