Protocol: freeze device proof and browser CSRF contracts
This commit is contained in:
@@ -59,6 +59,44 @@ let transcript = "versevdi/tunnel-admission/v17:session7:gateway8:audience43:" +
|
||||
guard String(data: request.deviceAdmissionTranscript(), encoding: .utf8) == transcript else {
|
||||
fatalError("unexpected device admission transcript")
|
||||
}
|
||||
let proofServerID = Data(repeating: 1, count: 16)
|
||||
let proofPrincipalID = Data(repeating: 2, count: 16)
|
||||
let proofDeviceID = Data(repeating: 3, count: 16)
|
||||
let proofChallenge = Data(repeating: 4, count: 32)
|
||||
let proofTranscript = try deviceRegistrationProofTranscript(
|
||||
serverID: proofServerID, principalID: proofPrincipalID, deviceID: proofDeviceID,
|
||||
challenge: proofChallenge, expiryUnixMilliseconds: 1
|
||||
)
|
||||
guard proofTranscript.count == 112,
|
||||
String(data: proofTranscript.prefix(24), encoding: .utf8) == "versevdi-device-proof-v1",
|
||||
Array(proofTranscript.suffix(8)) == [0, 0, 0, 0, 0, 0, 0, 1] else {
|
||||
fatalError("unexpected device registration proof transcript")
|
||||
}
|
||||
let invalidProofInputs: [(String, String, Data, Data, Data, Data, Int64)] = [
|
||||
("server-short", "server_id", Data(repeating: 0, count: 15), proofPrincipalID, proofDeviceID, proofChallenge, 0),
|
||||
("server-long", "server_id", Data(repeating: 0, count: 17), proofPrincipalID, proofDeviceID, proofChallenge, 0),
|
||||
("principal-short", "principal_id", proofServerID, Data(repeating: 0, count: 15), proofDeviceID, proofChallenge, 0),
|
||||
("principal-long", "principal_id", proofServerID, Data(repeating: 0, count: 17), proofDeviceID, proofChallenge, 0),
|
||||
("device-short", "device_id", proofServerID, proofPrincipalID, Data(repeating: 0, count: 15), proofChallenge, 0),
|
||||
("device-long", "device_id", proofServerID, proofPrincipalID, Data(repeating: 0, count: 17), proofChallenge, 0),
|
||||
("challenge-short", "challenge", proofServerID, proofPrincipalID, proofDeviceID, Data(repeating: 0, count: 31), 0),
|
||||
("challenge-long", "challenge", proofServerID, proofPrincipalID, proofDeviceID, Data(repeating: 0, count: 33), 0),
|
||||
("negative-expiry", "expiry_unix_milliseconds", proofServerID, proofPrincipalID, proofDeviceID, proofChallenge, -1),
|
||||
]
|
||||
for (name, field, serverID, principalID, deviceID, challenge, expiry) in invalidProofInputs {
|
||||
do {
|
||||
_ = try deviceRegistrationProofTranscript(
|
||||
serverID: serverID, principalID: principalID, deviceID: deviceID,
|
||||
challenge: challenge, expiryUnixMilliseconds: expiry
|
||||
)
|
||||
fatalError("\(name) was accepted")
|
||||
} catch let error as ContractValidationError {
|
||||
guard error.field == field,
|
||||
error.code == (field == "expiry_unix_milliseconds" ? "minimum" : "invalid_length") else {
|
||||
fatalError("\(name) returned the wrong validation error")
|
||||
}
|
||||
}
|
||||
}
|
||||
let incompatible = try CapabilityProfile(
|
||||
transport: "quic-tls13", framing: "datagram-v1", media: "encoded",
|
||||
audio: "encoded", sourceRateControl: "server", clientDecode: ["hevc-opus"]
|
||||
@@ -272,6 +310,32 @@ fn main() {
|
||||
+ &"g".repeat(43) + "1:016:" + &"n".repeat(16)
|
||||
+ "10:quic-tls1311:datagram-v17:encoded7:encoded6:server1:19:h264-opus";
|
||||
assert_eq!(request.device_admission_transcript(), transcript.into_bytes());
|
||||
let proof_server_id = vec![1u8; 16];
|
||||
let proof_principal_id = vec![2u8; 16];
|
||||
let proof_device_id = vec![3u8; 16];
|
||||
let proof_challenge = vec![4u8; 32];
|
||||
let proof = device_registration_proof_transcript(
|
||||
&proof_server_id, &proof_principal_id, &proof_device_id, &proof_challenge, 1,
|
||||
).unwrap();
|
||||
assert_eq!(proof.len(), 112);
|
||||
assert_eq!(&proof[..24], b"versevdi-device-proof-v1");
|
||||
assert_eq!(&proof[104..], &[0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
for (server_id, principal_id, device_id, challenge, expiry, field, code) in [
|
||||
(vec![0; 15], proof_principal_id.clone(), proof_device_id.clone(), proof_challenge.clone(), 0, "server_id", "invalid_length"),
|
||||
(vec![0; 17], proof_principal_id.clone(), proof_device_id.clone(), proof_challenge.clone(), 0, "server_id", "invalid_length"),
|
||||
(proof_server_id.clone(), vec![0; 15], proof_device_id.clone(), proof_challenge.clone(), 0, "principal_id", "invalid_length"),
|
||||
(proof_server_id.clone(), vec![0; 17], proof_device_id.clone(), proof_challenge.clone(), 0, "principal_id", "invalid_length"),
|
||||
(proof_server_id.clone(), proof_principal_id.clone(), vec![0; 15], proof_challenge.clone(), 0, "device_id", "invalid_length"),
|
||||
(proof_server_id.clone(), proof_principal_id.clone(), vec![0; 17], proof_challenge.clone(), 0, "device_id", "invalid_length"),
|
||||
(proof_server_id.clone(), proof_principal_id.clone(), proof_device_id.clone(), vec![0; 31], 0, "challenge", "invalid_length"),
|
||||
(proof_server_id.clone(), proof_principal_id.clone(), proof_device_id.clone(), vec![0; 33], 0, "challenge", "invalid_length"),
|
||||
(proof_server_id.clone(), proof_principal_id.clone(), proof_device_id.clone(), proof_challenge.clone(), -1, "expiry_unix_milliseconds", "minimum"),
|
||||
] {
|
||||
assert_eq!(
|
||||
device_registration_proof_transcript(&server_id, &principal_id, &device_id, &challenge, expiry),
|
||||
Err(ValidationError::new(field, code)),
|
||||
);
|
||||
}
|
||||
assert!(TunnelAdmissionRequest::new(
|
||||
"2".into(), "session".into(), "gateway".into(), "audience".into(),
|
||||
"g".repeat(43), 0, "n".repeat(16), "s".repeat(86), capabilities.clone(),
|
||||
|
||||
Reference in New Issue
Block a user