mirror of https://github.com/ctz/rustls
server: reject Cookie extension in initial ClientHello
This commit is contained in:
parent
575b9bd11e
commit
ade34d5be6
|
@ -1042,6 +1042,11 @@ impl ClientHelloPayload {
|
|||
self.find_extension(ExtensionType::EarlyData)
|
||||
.is_some()
|
||||
}
|
||||
|
||||
pub fn has_cookie_extension(&self) -> bool {
|
||||
self.find_extension(ExtensionType::Cookie)
|
||||
.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -403,6 +403,17 @@ impl State for ExpectClientHello {
|
|||
));
|
||||
}
|
||||
|
||||
if version == ProtocolVersion::TLSv1_3
|
||||
&& !self.done_retry
|
||||
&& client_hello.has_cookie_extension()
|
||||
{
|
||||
// RFC 8446 - 4.2.2 Cookie
|
||||
// Clients MUST NOT use cookies in their initial ClientHello in subsequent connections.
|
||||
return Err(Error::PeerMisbehavedError(
|
||||
"initial ClientHello contained cookie extension".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// We communicate to the upper layer what kind of key they should choose
|
||||
// via the sigschemes value. Clients tend to treat this extension
|
||||
// orthogonally to offered ciphersuites (even though, in TLS1.2 it is not).
|
||||
|
|
|
@ -3412,6 +3412,62 @@ mod test_quic {
|
|||
}
|
||||
} // mod test_quic
|
||||
|
||||
#[test]
|
||||
fn test_reject_cookie_in_initial_client_hello() {
|
||||
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_2,
|
||||
payload: MessagePayload::Handshake(HandshakeMessagePayload {
|
||||
typ: HandshakeType::ClientHello,
|
||||
payload: HandshakePayload::ClientHello(ClientHelloPayload {
|
||||
client_version: ProtocolVersion::TLSv1_2,
|
||||
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(
|
||||
"initial ClientHello contained cookie extension".into(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_client_does_not_offer_sha1() {
|
||||
use rustls::internal::msgs::{
|
||||
|
|
Loading…
Reference in New Issue