mirror of https://github.com/ctz/rustls
Test detection of truncated handshake messages
This commit is contained in:
parent
59ee30545e
commit
cb397f0e15
|
@ -4,7 +4,7 @@ import os
|
|||
import glob
|
||||
import subprocess
|
||||
|
||||
LLVM_PATH = glob.glob('/usr/lib/llvm-3.8/lib/clang/3.8.[0-9]/lib/linux/')[0]
|
||||
LLVM_PATH = glob.glob('/usr/lib/llvm-3.*/lib/clang/3.*.[0-9]/lib/linux/')[0]
|
||||
COVERAGE_OPTIONS = '-Ccodegen-units=1 -Clink-dead-code -Cpasses=insert-gcov-profiling -Cpanic=abort -Zpanic-abort-tests -L%s -lclang_rt.profile-x86_64' % LLVM_PATH
|
||||
LCOVOPTS = '--gcov-tool ./admin/llvm-gcov --rc lcov_excl_line=assert'.split()
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::handshake::*;
|
||||
use super::enums::*;
|
||||
use super::base::{Payload, PayloadU8, PayloadU16, PayloadU24};
|
||||
use super::codec::{Reader, Codec};
|
||||
use super::codec::{Reader, Codec, put_u16};
|
||||
use webpki::DNSNameRef;
|
||||
use crate::key::Certificate;
|
||||
|
||||
|
@ -409,6 +409,38 @@ fn client_has_duplicate_extensions_works() {
|
|||
assert!(!chp.has_duplicate_extension());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncated_client_extension_is_detected() {
|
||||
let chp = get_sample_clienthellopayload();
|
||||
|
||||
for ext in &chp.extensions {
|
||||
let mut enc = ext.get_encoding();
|
||||
println!("testing {:?} enc {:?}", ext, enc);
|
||||
|
||||
// "outer" truncation, ie, where the extension-level length is longer than
|
||||
// the input
|
||||
for l in 0..enc.len() {
|
||||
assert!(ClientExtension::read_bytes(&enc[..l]).is_none());
|
||||
}
|
||||
|
||||
// these extension types don't have any internal encoding that rustls validates:
|
||||
match ext.get_type() {
|
||||
ExtensionType::TransportParameters | ExtensionType::Unknown(_) => {
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// "inner" truncation, where the extension-level length agrees with the input
|
||||
// length, but isn't long enough for the type of extension
|
||||
for l in 0..(enc.len()-4) {
|
||||
put_u16(l as u16, &mut enc[2..]);
|
||||
println!(" encoding {:?} len {:?}", enc, l);
|
||||
assert!(ClientExtension::read_bytes(&enc).is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_client_extension_getter(typ: ExtensionType, getter: fn(&ClientHelloPayload) -> bool) {
|
||||
let mut chp = get_sample_clienthellopayload();
|
||||
let ext = chp.find_extension(typ).unwrap().clone();
|
||||
|
@ -488,6 +520,38 @@ fn client_get_psk_modes() {
|
|||
|chp| chp.get_psk_modes().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncated_helloretry_extension_is_detected() {
|
||||
let hrr = get_sample_helloretryrequest();
|
||||
|
||||
for ext in &hrr.extensions {
|
||||
let mut enc = ext.get_encoding();
|
||||
println!("testing {:?} enc {:?}", ext, enc);
|
||||
|
||||
// "outer" truncation, ie, where the extension-level length is longer than
|
||||
// the input
|
||||
for l in 0..enc.len() {
|
||||
assert!(HelloRetryExtension::read_bytes(&enc[..l]).is_none());
|
||||
}
|
||||
|
||||
// these extension types don't have any internal encoding that rustls validates:
|
||||
match ext.get_type() {
|
||||
ExtensionType::Unknown(_) => {
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// "inner" truncation, where the extension-level length agrees with the input
|
||||
// length, but isn't long enough for the type of extension
|
||||
for l in 0..(enc.len()-4) {
|
||||
put_u16(l as u16, &mut enc[2..]);
|
||||
println!(" encoding {:?} len {:?}", enc, l);
|
||||
assert!(HelloRetryExtension::read_bytes(&enc).is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_helloretry_extension_getter(typ: ExtensionType, getter: fn(&HelloRetryRequest) -> bool) {
|
||||
let mut hrr = get_sample_helloretryrequest();
|
||||
let mut exts = mem::replace(&mut hrr.extensions, vec![]);
|
||||
|
@ -525,6 +589,38 @@ fn helloretry_get_supported_versions() {
|
|||
|hrr| hrr.get_supported_versions().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncated_server_extension_is_detected() {
|
||||
let shp = get_sample_serverhellopayload();
|
||||
|
||||
for ext in &shp.extensions {
|
||||
let mut enc = ext.get_encoding();
|
||||
println!("testing {:?} enc {:?}", ext, enc);
|
||||
|
||||
// "outer" truncation, ie, where the extension-level length is longer than
|
||||
// the input
|
||||
for l in 0..enc.len() {
|
||||
assert!(ServerExtension::read_bytes(&enc[..l]).is_none());
|
||||
}
|
||||
|
||||
// these extension types don't have any internal encoding that rustls validates:
|
||||
match ext.get_type() {
|
||||
ExtensionType::TransportParameters | ExtensionType::Unknown(_) => {
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// "inner" truncation, where the extension-level length agrees with the input
|
||||
// length, but isn't long enough for the type of extension
|
||||
for l in 0..(enc.len()-4) {
|
||||
put_u16(l as u16, &mut enc[2..]);
|
||||
println!(" encoding {:?} len {:?}", enc, l);
|
||||
assert!(ServerExtension::read_bytes(&enc).is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_server_extension_getter(typ: ExtensionType, getter: fn(&ServerHelloPayload) -> bool) {
|
||||
let mut shp = get_sample_serverhellopayload();
|
||||
let ext = shp.find_extension(typ).unwrap().clone();
|
||||
|
|
Loading…
Reference in New Issue