session: add client finished processing
This commit is contained in:
parent
4b644aafe9
commit
c50894ad7f
936
src/session.rs
936
src/session.rs
@ -495,180 +495,6 @@ impl<'a> Session<'a> {
|
|||||||
hmac.update(&transcript_hash);
|
hmac.update(&transcript_hash);
|
||||||
hmac.verify(server_verify_data).unwrap();
|
hmac.verify(server_verify_data).unwrap();
|
||||||
|
|
||||||
// Update hash for key computation
|
|
||||||
self.hash.update(server_finished_slice);
|
|
||||||
|
|
||||||
// Derive application traffic secret, key, IV on client's side
|
|
||||||
// 1. Derive secret from "Handshake Secret"
|
|
||||||
let hkdf = Hkdf::<Sha256>::from_prk(
|
|
||||||
// TLS requires the removal of secret if such secret is not of any use
|
|
||||||
// Replace "latest_secret" with None
|
|
||||||
self.latest_secret.as_ref().unwrap()
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
let empty_hash = Sha256::new().chain("");
|
|
||||||
let derived_secret = derive_secret(&hkdf, "derived", empty_hash);
|
|
||||||
|
|
||||||
// 2. HKDF-extract "Master Secret"
|
|
||||||
let zero_ikm: GenericArray<u8, <Sha256 as FixedOutput>::OutputSize>
|
|
||||||
= Default::default();
|
|
||||||
let (master_secret, master_secret_hkdf) = Hkdf::<Sha256>::extract(
|
|
||||||
Some(&derived_secret),
|
|
||||||
&zero_ikm
|
|
||||||
);
|
|
||||||
|
|
||||||
// Replace latest secret with "master_secret"
|
|
||||||
self.latest_secret.replace(
|
|
||||||
Vec::from_slice(&master_secret).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 3. Get application traffic secret
|
|
||||||
let client_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"c ap traffic",
|
|
||||||
self.hash.get_sha256_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
let server_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"s ap traffic",
|
|
||||||
self.hash.get_sha256_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
self.client_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&client_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
self.server_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&server_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 4. Replace cipher and IV
|
|
||||||
let client_application_traffic_hkdf = Hkdf::<Sha256>::from_prk(
|
|
||||||
&client_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
let server_application_traffic_hkdf = Hkdf::<Sha256>::from_prk(
|
|
||||||
&server_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
// Init key and IV holders
|
|
||||||
let cipher_suite = self.client_handshake_cipher.as_ref().unwrap().get_cipher_suite_type();
|
|
||||||
|
|
||||||
let (mut client_key_holder, mut client_iv_holder,
|
|
||||||
mut server_key_holder, mut server_iv_holder):
|
|
||||||
(Vec::<u8, U64>, Vec::<u8, U12>, Vec::<u8, U64>, Vec::<u8, U12>) =
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
// TLS_AES_128_CCM_8_SHA256 is not offered
|
|
||||||
// TLS_AES_256_GCM_SHA384 should not have SHA256 as hash
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Derive Key and IV for both server and client
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut client_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut client_iv_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut server_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut server_iv_holder
|
|
||||||
);
|
|
||||||
|
|
||||||
// Store IV/nonce
|
|
||||||
self.client_application_nonce.replace(client_iv_holder);
|
|
||||||
self.server_application_nonce.replace(server_iv_holder);
|
|
||||||
|
|
||||||
// Instantiate new ciphers
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Aes128Gcm {
|
|
||||||
aes128gcm: Aes128Gcm::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Aes128Gcm {
|
|
||||||
aes128gcm: Aes128Gcm::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Chacha20poly1305 {
|
|
||||||
chacha20poly1305: ChaCha20Poly1305::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Chacha20poly1305 {
|
|
||||||
chacha20poly1305: ChaCha20Poly1305::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Ccm {
|
|
||||||
ccm: Aes128Ccm::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Ccm {
|
|
||||||
ccm: Aes128Ccm::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if let Ok(sha384) = self.hash.get_sha384_clone() {
|
} else if let Ok(sha384) = self.hash.get_sha384_clone() {
|
||||||
let hkdf = Hkdf::<Sha384>::from_prk(
|
let hkdf = Hkdf::<Sha384>::from_prk(
|
||||||
self.server_handshake_traffic_secret.as_ref().unwrap()
|
self.server_handshake_traffic_secret.as_ref().unwrap()
|
||||||
@ -687,134 +513,15 @@ impl<'a> Session<'a> {
|
|||||||
hmac.update(&transcript_hash);
|
hmac.update(&transcript_hash);
|
||||||
hmac.verify(server_verify_data).unwrap();
|
hmac.verify(server_verify_data).unwrap();
|
||||||
|
|
||||||
// Update hash for key computation
|
|
||||||
self.hash.update(server_finished_slice);
|
|
||||||
|
|
||||||
// Derive application traffic secret, key, IV on client's side
|
|
||||||
// 1. Derive secret from "Handshake Secret"
|
|
||||||
let hkdf = Hkdf::<Sha384>::from_prk(
|
|
||||||
self.latest_secret.as_ref().unwrap()
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
let empty_hash = Sha384::new().chain("");
|
|
||||||
let derived_secret = derive_secret(&hkdf, "derived", empty_hash);
|
|
||||||
|
|
||||||
// 2. HKDF-extract "Master Secret"
|
|
||||||
let zero_ikm: GenericArray<u8, <Sha384 as FixedOutput>::OutputSize>
|
|
||||||
= Default::default();
|
|
||||||
let (master_secret, master_secret_hkdf) = Hkdf::<Sha384>::extract(
|
|
||||||
Some(&derived_secret),
|
|
||||||
&zero_ikm
|
|
||||||
);
|
|
||||||
|
|
||||||
// Replace latest secret with "master_secret"
|
|
||||||
self.latest_secret.replace(
|
|
||||||
Vec::from_slice(&master_secret).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 3. Get application traffic secret
|
|
||||||
let client_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"c ap traffic",
|
|
||||||
self.hash.get_sha384_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
let server_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"s ap traffic",
|
|
||||||
self.hash.get_sha384_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
self.client_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&client_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
self.server_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&server_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 4. Replace cipher and IV
|
|
||||||
let client_application_traffic_hkdf = Hkdf::<Sha384>::from_prk(
|
|
||||||
&client_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
let server_application_traffic_hkdf = Hkdf::<Sha384>::from_prk(
|
|
||||||
&server_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
// Init key and IV holders
|
|
||||||
let cipher_suite = self.client_handshake_cipher.as_ref().unwrap().get_cipher_suite_type();
|
|
||||||
|
|
||||||
let (mut client_key_holder, mut client_iv_holder,
|
|
||||||
mut server_key_holder, mut server_iv_holder):
|
|
||||||
(Vec::<u8, U64>, Vec::<u8, U12>, Vec::<u8, U64>, Vec::<u8, U12>) =
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_256_GCM_SHA384 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
// TLS_AES_128_CCM_8_SHA256 is not offered
|
|
||||||
// Only TLS_AES_256_GCM_SHA384 should have SHA384 as hash
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Derive Key and IV for both server and client
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut client_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut client_iv_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut server_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut server_iv_holder
|
|
||||||
);
|
|
||||||
|
|
||||||
// Store IV/nonce
|
|
||||||
self.client_application_nonce.replace(client_iv_holder);
|
|
||||||
self.server_application_nonce.replace(server_iv_holder);
|
|
||||||
|
|
||||||
// Instantiate new ciphers
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_256_GCM_SHA384 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Aes256Gcm {
|
|
||||||
aes256gcm: Aes256Gcm::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Aes256Gcm {
|
|
||||||
aes256gcm: Aes256Gcm::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
// Hash was updated for key computation
|
|
||||||
|
// Update hash for key computation
|
||||||
|
self.hash.update(server_finished_slice);
|
||||||
|
|
||||||
|
// Compute application keys
|
||||||
|
self.find_application_keying_info();
|
||||||
|
|
||||||
// At last, update client state
|
// At last, update client state
|
||||||
self.state = TlsState::SERVER_COMPLETED;
|
self.state = TlsState::SERVER_COMPLETED;
|
||||||
@ -960,302 +667,67 @@ impl<'a> Session<'a> {
|
|||||||
self.hash.update(server_finished_slice);
|
self.hash.update(server_finished_slice);
|
||||||
|
|
||||||
// Key calculation
|
// Key calculation
|
||||||
|
self.find_application_keying_info();
|
||||||
|
|
||||||
|
// Change state
|
||||||
|
self.state = TlsState::SERVER_WAIT_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn server_update_for_wait_finished(
|
||||||
|
&mut self,
|
||||||
|
client_finished_slice: &[u8],
|
||||||
|
client_verify_data: &[u8],
|
||||||
|
) {
|
||||||
|
// Take hash from session
|
||||||
if let Ok(sha256) = self.hash.get_sha256_clone() {
|
if let Ok(sha256) = self.hash.get_sha256_clone() {
|
||||||
// Derive application traffic secret, key, IV on client's side
|
|
||||||
// 1. Derive secret from "Handshake Secret"
|
|
||||||
let hkdf = Hkdf::<Sha256>::from_prk(
|
let hkdf = Hkdf::<Sha256>::from_prk(
|
||||||
// TLS requires the removal of secret if such secret is not of any use
|
self.client_handshake_traffic_secret.as_ref().unwrap()
|
||||||
// Replace "latest_secret" with None
|
|
||||||
self.latest_secret.as_ref().unwrap()
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
let empty_hash = Sha256::new().chain("");
|
// Compute finished_key
|
||||||
let derived_secret = derive_secret(&hkdf, "derived", empty_hash);
|
let mut okm: GenericArray::<u8, <Sha256 as Digest>::OutputSize> =
|
||||||
|
Default::default();
|
||||||
|
hkdf_expand_label(&hkdf, "finished", "", &mut okm);
|
||||||
|
|
||||||
// 2. HKDF-extract "Master Secret"
|
// Get transcript hash
|
||||||
let zero_ikm: GenericArray<u8, <Sha256 as FixedOutput>::OutputSize>
|
let transcript_hash = sha256.finalize();
|
||||||
= Default::default();
|
|
||||||
let (master_secret, master_secret_hkdf) = Hkdf::<Sha256>::extract(
|
|
||||||
Some(&derived_secret),
|
|
||||||
&zero_ikm
|
|
||||||
);
|
|
||||||
|
|
||||||
// Replace latest secret with "master_secret"
|
// Compute verify_data
|
||||||
self.latest_secret.replace(
|
let mut hmac = Hmac::<Sha256>::new_varkey(&okm).unwrap();
|
||||||
Vec::from_slice(&master_secret).unwrap()
|
hmac.update(&transcript_hash);
|
||||||
);
|
hmac.verify(client_verify_data).unwrap();
|
||||||
|
|
||||||
// 3. Get application traffic secret
|
|
||||||
let client_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"c ap traffic",
|
|
||||||
self.hash.get_sha256_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
let server_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"s ap traffic",
|
|
||||||
self.hash.get_sha256_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
self.client_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&client_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
self.server_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&server_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 4. Replace cipher and IV
|
|
||||||
let client_application_traffic_hkdf = Hkdf::<Sha256>::from_prk(
|
|
||||||
&client_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
let server_application_traffic_hkdf = Hkdf::<Sha256>::from_prk(
|
|
||||||
&server_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
// Init key and IV holders
|
|
||||||
let cipher_suite = self.client_handshake_cipher.as_ref().unwrap().get_cipher_suite_type();
|
|
||||||
|
|
||||||
let (mut client_key_holder, mut client_iv_holder,
|
|
||||||
mut server_key_holder, mut server_iv_holder):
|
|
||||||
(Vec::<u8, U64>, Vec::<u8, U12>, Vec::<u8, U64>, Vec::<u8, U12>) =
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 16]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
// TLS_AES_128_CCM_8_SHA256 is not offered
|
|
||||||
// TLS_AES_256_GCM_SHA384 should not have SHA256 as hash
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Derive Key and IV for both server and client
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut client_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut client_iv_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut server_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut server_iv_holder
|
|
||||||
);
|
|
||||||
|
|
||||||
// Store IV/nonce
|
|
||||||
self.client_application_nonce.replace(client_iv_holder);
|
|
||||||
self.server_application_nonce.replace(server_iv_holder);
|
|
||||||
|
|
||||||
// Instantiate new ciphers
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Aes128Gcm {
|
|
||||||
aes128gcm: Aes128Gcm::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Aes128Gcm {
|
|
||||||
aes128gcm: Aes128Gcm::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Chacha20poly1305 {
|
|
||||||
chacha20poly1305: ChaCha20Poly1305::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Chacha20poly1305 {
|
|
||||||
chacha20poly1305: ChaCha20Poly1305::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Ccm {
|
|
||||||
ccm: Aes128Ccm::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Ccm {
|
|
||||||
ccm: Aes128Ccm::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
} else if let Ok(sha384) = self.hash.get_sha384_clone() {
|
} else if let Ok(sha384) = self.hash.get_sha384_clone() {
|
||||||
// Derive application traffic secret, key, IV on client's side
|
|
||||||
// 1. Derive secret from "Handshake Secret"
|
|
||||||
let hkdf = Hkdf::<Sha384>::from_prk(
|
let hkdf = Hkdf::<Sha384>::from_prk(
|
||||||
self.latest_secret.as_ref().unwrap()
|
self.client_handshake_traffic_secret.as_ref().unwrap()
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
let empty_hash = Sha384::new().chain("");
|
// Compute finished_key
|
||||||
let derived_secret = derive_secret(&hkdf, "derived", empty_hash);
|
let mut okm: GenericArray::<u8, <Sha384 as Digest>::OutputSize> =
|
||||||
|
Default::default();
|
||||||
|
hkdf_expand_label(&hkdf, "finished", "", &mut okm);
|
||||||
|
|
||||||
// 2. HKDF-extract "Master Secret"
|
// Get transcript hash
|
||||||
let zero_ikm: GenericArray<u8, <Sha384 as FixedOutput>::OutputSize>
|
let transcript_hash = sha384.finalize();
|
||||||
= Default::default();
|
|
||||||
let (master_secret, master_secret_hkdf) = Hkdf::<Sha384>::extract(
|
|
||||||
Some(&derived_secret),
|
|
||||||
&zero_ikm
|
|
||||||
);
|
|
||||||
|
|
||||||
// Replace latest secret with "master_secret"
|
// Compute verify_data using HMAC
|
||||||
self.latest_secret.replace(
|
let mut hmac = Hmac::<Sha384>::new_varkey(&okm).unwrap();
|
||||||
Vec::from_slice(&master_secret).unwrap()
|
hmac.update(&transcript_hash);
|
||||||
);
|
hmac.verify(client_verify_data).unwrap();
|
||||||
|
|
||||||
// 3. Get application traffic secret
|
|
||||||
let client_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"c ap traffic",
|
|
||||||
self.hash.get_sha384_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
let server_application_traffic_secret = derive_secret(
|
|
||||||
&master_secret_hkdf,
|
|
||||||
"s ap traffic",
|
|
||||||
self.hash.get_sha384_clone().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
self.client_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&client_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
self.server_application_traffic_secret.replace(
|
|
||||||
Vec::from_slice(&server_application_traffic_secret).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 4. Replace cipher and IV
|
|
||||||
let client_application_traffic_hkdf = Hkdf::<Sha384>::from_prk(
|
|
||||||
&client_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
let server_application_traffic_hkdf = Hkdf::<Sha384>::from_prk(
|
|
||||||
&server_application_traffic_secret
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
// Init key and IV holders
|
|
||||||
let cipher_suite = self.client_handshake_cipher.as_ref().unwrap().get_cipher_suite_type();
|
|
||||||
|
|
||||||
let (mut client_key_holder, mut client_iv_holder,
|
|
||||||
mut server_key_holder, mut server_iv_holder):
|
|
||||||
(Vec::<u8, U64>, Vec::<u8, U12>, Vec::<u8, U64>, Vec::<u8, U12>) =
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_256_GCM_SHA384 => {
|
|
||||||
(
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 32]).unwrap(),
|
|
||||||
Vec::from_slice(&[0; 12]).unwrap()
|
|
||||||
)
|
|
||||||
},
|
|
||||||
// TLS_AES_128_CCM_8_SHA256 is not offered
|
|
||||||
// Only TLS_AES_256_GCM_SHA384 should have SHA384 as hash
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Derive Key and IV for both server and client
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut client_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&client_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut client_iv_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"key",
|
|
||||||
"",
|
|
||||||
&mut server_key_holder
|
|
||||||
);
|
|
||||||
hkdf_expand_label(
|
|
||||||
&server_application_traffic_hkdf,
|
|
||||||
"iv",
|
|
||||||
"",
|
|
||||||
&mut server_iv_holder
|
|
||||||
);
|
|
||||||
|
|
||||||
// Store IV/nonce
|
|
||||||
self.client_application_nonce.replace(client_iv_holder);
|
|
||||||
self.server_application_nonce.replace(server_iv_holder);
|
|
||||||
|
|
||||||
// Instantiate new ciphers
|
|
||||||
match cipher_suite {
|
|
||||||
CipherSuite::TLS_AES_256_GCM_SHA384 => {
|
|
||||||
self.client_application_cipher.replace(
|
|
||||||
Cipher::Aes256Gcm {
|
|
||||||
aes256gcm: Aes256Gcm::new(
|
|
||||||
&GenericArray::from_slice(&client_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
self.server_application_cipher.replace(
|
|
||||||
Cipher::Aes256Gcm {
|
|
||||||
aes256gcm: Aes256Gcm::new(
|
|
||||||
&GenericArray::from_slice(&server_key_holder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Update hash for key computation
|
||||||
|
self.hash.update(client_finished_slice);
|
||||||
|
|
||||||
|
// At last, update client state
|
||||||
|
self.state = TlsState::SERVER_CONNECTED;
|
||||||
|
|
||||||
|
// Reset sequence number at the end of handshakes
|
||||||
|
self.server_sequence_number = 0;
|
||||||
|
self.client_sequence_number = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_handshake_keying_info(&mut self, shared_secret_bytes: &[u8], cipher_suite: CipherSuite) {
|
fn find_handshake_keying_info(&mut self, shared_secret_bytes: &[u8], cipher_suite: CipherSuite) {
|
||||||
@ -1579,6 +1051,306 @@ impl<'a> Session<'a> {
|
|||||||
self.client_sequence_number = 0;
|
self.client_sequence_number = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_application_keying_info(&mut self) {
|
||||||
|
// Key calculation
|
||||||
|
if let Ok(sha256) = self.hash.get_sha256_clone() {
|
||||||
|
// Derive application traffic secret, key, IV on client's side
|
||||||
|
// 1. Derive secret from "Handshake Secret"
|
||||||
|
let hkdf = Hkdf::<Sha256>::from_prk(
|
||||||
|
// TLS requires the removal of secret if such secret is not of any use
|
||||||
|
// Replace "latest_secret" with None
|
||||||
|
self.latest_secret.as_ref().unwrap()
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let empty_hash = Sha256::new().chain("");
|
||||||
|
let derived_secret = derive_secret(&hkdf, "derived", empty_hash);
|
||||||
|
|
||||||
|
// 2. HKDF-extract "Master Secret"
|
||||||
|
let zero_ikm: GenericArray<u8, <Sha256 as FixedOutput>::OutputSize>
|
||||||
|
= Default::default();
|
||||||
|
let (master_secret, master_secret_hkdf) = Hkdf::<Sha256>::extract(
|
||||||
|
Some(&derived_secret),
|
||||||
|
&zero_ikm
|
||||||
|
);
|
||||||
|
|
||||||
|
// Replace latest secret with "master_secret"
|
||||||
|
self.latest_secret.replace(
|
||||||
|
Vec::from_slice(&master_secret).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// 3. Get application traffic secret
|
||||||
|
let client_application_traffic_secret = derive_secret(
|
||||||
|
&master_secret_hkdf,
|
||||||
|
"c ap traffic",
|
||||||
|
self.hash.get_sha256_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let server_application_traffic_secret = derive_secret(
|
||||||
|
&master_secret_hkdf,
|
||||||
|
"s ap traffic",
|
||||||
|
self.hash.get_sha256_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
self.client_application_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&client_application_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
self.server_application_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&server_application_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// 4. Replace cipher and IV
|
||||||
|
let client_application_traffic_hkdf = Hkdf::<Sha256>::from_prk(
|
||||||
|
&client_application_traffic_secret
|
||||||
|
).unwrap();
|
||||||
|
let server_application_traffic_hkdf = Hkdf::<Sha256>::from_prk(
|
||||||
|
&server_application_traffic_secret
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
// Init key and IV holders
|
||||||
|
let cipher_suite = self.client_handshake_cipher.as_ref().unwrap().get_cipher_suite_type();
|
||||||
|
|
||||||
|
let (mut client_key_holder, mut client_iv_holder,
|
||||||
|
mut server_key_holder, mut server_iv_holder):
|
||||||
|
(Vec::<u8, U64>, Vec::<u8, U12>, Vec::<u8, U64>, Vec::<u8, U12>) =
|
||||||
|
match cipher_suite {
|
||||||
|
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
||||||
|
(
|
||||||
|
Vec::from_slice(&[0; 16]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 16]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
||||||
|
(
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
||||||
|
(
|
||||||
|
Vec::from_slice(&[0; 16]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 16]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// TLS_AES_128_CCM_8_SHA256 is not offered
|
||||||
|
// TLS_AES_256_GCM_SHA384 should not have SHA256 as hash
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Derive Key and IV for both server and client
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_application_traffic_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut client_key_holder
|
||||||
|
);
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_application_traffic_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut client_iv_holder
|
||||||
|
);
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_application_traffic_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut server_key_holder
|
||||||
|
);
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_application_traffic_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut server_iv_holder
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store IV/nonce
|
||||||
|
self.client_application_nonce.replace(client_iv_holder);
|
||||||
|
self.server_application_nonce.replace(server_iv_holder);
|
||||||
|
|
||||||
|
// Instantiate new ciphers
|
||||||
|
match cipher_suite {
|
||||||
|
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
||||||
|
self.client_application_cipher.replace(
|
||||||
|
Cipher::Aes128Gcm {
|
||||||
|
aes128gcm: Aes128Gcm::new(
|
||||||
|
&GenericArray::from_slice(&client_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_application_cipher.replace(
|
||||||
|
Cipher::Aes128Gcm {
|
||||||
|
aes128gcm: Aes128Gcm::new(
|
||||||
|
&GenericArray::from_slice(&server_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
||||||
|
self.client_application_cipher.replace(
|
||||||
|
Cipher::Chacha20poly1305 {
|
||||||
|
chacha20poly1305: ChaCha20Poly1305::new(
|
||||||
|
&GenericArray::from_slice(&client_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_application_cipher.replace(
|
||||||
|
Cipher::Chacha20poly1305 {
|
||||||
|
chacha20poly1305: ChaCha20Poly1305::new(
|
||||||
|
&GenericArray::from_slice(&server_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
||||||
|
self.client_application_cipher.replace(
|
||||||
|
Cipher::Ccm {
|
||||||
|
ccm: Aes128Ccm::new(
|
||||||
|
&GenericArray::from_slice(&client_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_application_cipher.replace(
|
||||||
|
Cipher::Ccm {
|
||||||
|
ccm: Aes128Ccm::new(
|
||||||
|
&GenericArray::from_slice(&server_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
} else if let Ok(sha384) = self.hash.get_sha384_clone() {
|
||||||
|
// Derive application traffic secret, key, IV on client's side
|
||||||
|
// 1. Derive secret from "Handshake Secret"
|
||||||
|
let hkdf = Hkdf::<Sha384>::from_prk(
|
||||||
|
self.latest_secret.as_ref().unwrap()
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let empty_hash = Sha384::new().chain("");
|
||||||
|
let derived_secret = derive_secret(&hkdf, "derived", empty_hash);
|
||||||
|
|
||||||
|
// 2. HKDF-extract "Master Secret"
|
||||||
|
let zero_ikm: GenericArray<u8, <Sha384 as FixedOutput>::OutputSize>
|
||||||
|
= Default::default();
|
||||||
|
let (master_secret, master_secret_hkdf) = Hkdf::<Sha384>::extract(
|
||||||
|
Some(&derived_secret),
|
||||||
|
&zero_ikm
|
||||||
|
);
|
||||||
|
|
||||||
|
// Replace latest secret with "master_secret"
|
||||||
|
self.latest_secret.replace(
|
||||||
|
Vec::from_slice(&master_secret).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// 3. Get application traffic secret
|
||||||
|
let client_application_traffic_secret = derive_secret(
|
||||||
|
&master_secret_hkdf,
|
||||||
|
"c ap traffic",
|
||||||
|
self.hash.get_sha384_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let server_application_traffic_secret = derive_secret(
|
||||||
|
&master_secret_hkdf,
|
||||||
|
"s ap traffic",
|
||||||
|
self.hash.get_sha384_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
self.client_application_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&client_application_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
self.server_application_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&server_application_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// 4. Replace cipher and IV
|
||||||
|
let client_application_traffic_hkdf = Hkdf::<Sha384>::from_prk(
|
||||||
|
&client_application_traffic_secret
|
||||||
|
).unwrap();
|
||||||
|
let server_application_traffic_hkdf = Hkdf::<Sha384>::from_prk(
|
||||||
|
&server_application_traffic_secret
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
// Init key and IV holders
|
||||||
|
let cipher_suite = self.client_handshake_cipher.as_ref().unwrap().get_cipher_suite_type();
|
||||||
|
|
||||||
|
let (mut client_key_holder, mut client_iv_holder,
|
||||||
|
mut server_key_holder, mut server_iv_holder):
|
||||||
|
(Vec::<u8, U64>, Vec::<u8, U12>, Vec::<u8, U64>, Vec::<u8, U12>) =
|
||||||
|
match cipher_suite {
|
||||||
|
CipherSuite::TLS_AES_256_GCM_SHA384 => {
|
||||||
|
(
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap(),
|
||||||
|
Vec::from_slice(&[0; 12]).unwrap()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// TLS_AES_128_CCM_8_SHA256 is not offered
|
||||||
|
// Only TLS_AES_256_GCM_SHA384 should have SHA384 as hash
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Derive Key and IV for both server and client
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_application_traffic_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut client_key_holder
|
||||||
|
);
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_application_traffic_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut client_iv_holder
|
||||||
|
);
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_application_traffic_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut server_key_holder
|
||||||
|
);
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_application_traffic_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut server_iv_holder
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store IV/nonce
|
||||||
|
self.client_application_nonce.replace(client_iv_holder);
|
||||||
|
self.server_application_nonce.replace(server_iv_holder);
|
||||||
|
|
||||||
|
// Instantiate new ciphers
|
||||||
|
match cipher_suite {
|
||||||
|
CipherSuite::TLS_AES_256_GCM_SHA384 => {
|
||||||
|
self.client_application_cipher.replace(
|
||||||
|
Cipher::Aes256Gcm {
|
||||||
|
aes256gcm: Aes256Gcm::new(
|
||||||
|
&GenericArray::from_slice(&client_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_application_cipher.replace(
|
||||||
|
Cipher::Aes256Gcm {
|
||||||
|
aes256gcm: Aes256Gcm::new(
|
||||||
|
&GenericArray::from_slice(&server_key_holder)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn verify_session_id_echo(&self, session_id_echo: &[u8]) -> bool {
|
pub(crate) fn verify_session_id_echo(&self, session_id_echo: &[u8]) -> bool {
|
||||||
if let Some(session_id_inner) = self.session_id {
|
if let Some(session_id_inner) = self.session_id {
|
||||||
session_id_inner == session_id_echo
|
session_id_inner == session_id_echo
|
||||||
@ -2156,14 +1928,6 @@ impl<'a> Session<'a> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn increment_client_sequence_number(&mut self) {
|
|
||||||
self.client_sequence_number += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn increment_server_sequence_number(&mut self) {
|
|
||||||
self.server_sequence_number += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn increment_local_sequence_number(&mut self) {
|
pub(crate) fn increment_local_sequence_number(&mut self) {
|
||||||
match self.role {
|
match self.role {
|
||||||
TlsRole::Client => {
|
TlsRole::Client => {
|
||||||
|
54
src/tls.rs
54
src/tls.rs
@ -650,13 +650,19 @@ impl<'s> TlsSocket<'s> {
|
|||||||
self.send_application_slice(sockets, &mut inner_plaintext.clone())?;
|
self.send_application_slice(sockets, &mut inner_plaintext.clone())?;
|
||||||
|
|
||||||
let inner_plaintext_length = inner_plaintext.len();
|
let inner_plaintext_length = inner_plaintext.len();
|
||||||
// {
|
{
|
||||||
// self.session.borrow_mut()
|
self.session.borrow_mut()
|
||||||
// .server_update_for_server_finished(&inner_plaintext[..(inner_plaintext_length-1)]);
|
.server_update_for_server_finished(&inner_plaintext[..(inner_plaintext_length-1)]);
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other states regarding server role
|
// There is no need to care about handshake if it was completed
|
||||||
|
// This is to prevent accidental dequeing of application data
|
||||||
|
TlsState::SERVER_CONNECTED => {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other states
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,7 +734,7 @@ impl<'s> TlsSocket<'s> {
|
|||||||
&associated_data,
|
&associated_data,
|
||||||
&mut app_data
|
&mut app_data
|
||||||
).unwrap();
|
).unwrap();
|
||||||
session.increment_server_sequence_number();
|
session.increment_remote_sequence_number();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard last 16 bytes (auth tag)
|
// Discard last 16 bytes (auth tag)
|
||||||
@ -1387,6 +1393,32 @@ impl<'s> TlsSocket<'s> {
|
|||||||
|
|
||||||
log::info!("Processed client hello")
|
log::info!("Processed client hello")
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
TlsState::SERVER_WAIT_FINISHED => {
|
||||||
|
// Ensure that it is Finished
|
||||||
|
let might_be_client_finished = repr.handshake.take().unwrap();
|
||||||
|
if might_be_client_finished.get_msg_type() != HandshakeType::Finished {
|
||||||
|
// Process the other handshakes in "handshake_vec"
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take out the portion for server Finished
|
||||||
|
// Length of handshake header is 4
|
||||||
|
let (_handshake_slice, client_finished_slice) =
|
||||||
|
take::<_, _, (&[u8], ErrorKind)>(
|
||||||
|
might_be_client_finished.length + 4
|
||||||
|
)(handshake_slice)
|
||||||
|
.map_err(|_| Error::Unrecognized)?;
|
||||||
|
|
||||||
|
// Perform verification, update TLS state if successful
|
||||||
|
// Update traffic secret, reset sequence number
|
||||||
|
self.session.borrow_mut()
|
||||||
|
.server_update_for_wait_finished(
|
||||||
|
client_finished_slice,
|
||||||
|
might_be_client_finished.get_verify_data().unwrap()
|
||||||
|
);
|
||||||
|
log::info!("Received client FIN");
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {},
|
_ => {},
|
||||||
@ -1450,7 +1482,8 @@ impl<'s> TlsSocket<'s> {
|
|||||||
// If the handshake is not completed, do not pull bytes out of the buffer
|
// If the handshake is not completed, do not pull bytes out of the buffer
|
||||||
// through TlsSocket.recv_slice()
|
// through TlsSocket.recv_slice()
|
||||||
// Handshake recv should be through TCPSocket directly.
|
// Handshake recv should be through TCPSocket directly.
|
||||||
if session.get_tls_state() != TlsState::CLIENT_CONNECTED {
|
if session.get_tls_state() != TlsState::CLIENT_CONNECTED &&
|
||||||
|
session.get_tls_state() != TlsState::SERVER_CONNECTED {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1498,7 +1531,7 @@ impl<'s> TlsSocket<'s> {
|
|||||||
&associated_data,
|
&associated_data,
|
||||||
&mut data[5..recv_slice_size]
|
&mut data[5..recv_slice_size]
|
||||||
).unwrap();
|
).unwrap();
|
||||||
session.increment_server_sequence_number();
|
session.increment_remote_sequence_number();
|
||||||
|
|
||||||
// Make sure it is application data
|
// Make sure it is application data
|
||||||
let (content_type, padding_start_index) =
|
let (content_type, padding_start_index) =
|
||||||
@ -1533,7 +1566,8 @@ impl<'s> TlsSocket<'s> {
|
|||||||
// through TlsSocket.send_slice()
|
// through TlsSocket.send_slice()
|
||||||
// Handshake send should be through TCPSocket directly.
|
// Handshake send should be through TCPSocket directly.
|
||||||
let mut session = self.session.borrow_mut();
|
let mut session = self.session.borrow_mut();
|
||||||
if session.get_tls_state() != TlsState::CLIENT_CONNECTED {
|
if session.get_tls_state() != TlsState::CLIENT_CONNECTED &&
|
||||||
|
session.get_tls_state() != TlsState::SERVER_CONNECTED {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1560,7 +1594,7 @@ impl<'s> TlsSocket<'s> {
|
|||||||
&associated_data,
|
&associated_data,
|
||||||
&mut vec
|
&mut vec
|
||||||
).unwrap();
|
).unwrap();
|
||||||
session.increment_client_sequence_number();
|
session.increment_local_sequence_number();
|
||||||
|
|
||||||
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
||||||
if !tcp_socket.can_send() {
|
if !tcp_socket.can_send() {
|
||||||
|
Loading…
Reference in New Issue
Block a user