server certificate: handled
This commit is contained in:
parent
81d52e9ec4
commit
ccc257aeb9
@ -1561,6 +1561,20 @@ impl<'a> Session<'a> {
|
|||||||
self.hash.update(encryption_extension_slice);
|
self.hash.update(encryption_extension_slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn server_update_for_sent_certificate(
|
||||||
|
&mut self,
|
||||||
|
certificate_slice: &[u8]
|
||||||
|
) {
|
||||||
|
self.hash.update(certificate_slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn server_update_for_sent_certificate_verify(
|
||||||
|
&mut self,
|
||||||
|
certificate_verify_slice: &[u8]
|
||||||
|
) {
|
||||||
|
self.hash.update(certificate_verify_slice);
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -1635,7 +1649,11 @@ impl<'a> Session<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_client_certificate_verify_signature<R: rand_core::RngCore>(&self, rng: &mut R)
|
pub(crate) fn get_certificate_verify_signature<R: rand_core::RngCore>(
|
||||||
|
&self,
|
||||||
|
rng: &mut R,
|
||||||
|
role: TlsRole
|
||||||
|
)
|
||||||
-> (crate::tls_packet::SignatureScheme, alloc::vec::Vec<u8>)
|
-> (crate::tls_packet::SignatureScheme, alloc::vec::Vec<u8>)
|
||||||
{
|
{
|
||||||
if let Some((private_key, client_certificate)) = &self.cert_private_key {
|
if let Some((private_key, client_certificate)) = &self.cert_private_key {
|
||||||
@ -1709,36 +1727,39 @@ impl<'a> Session<'a> {
|
|||||||
|
|
||||||
match private_key {
|
match private_key {
|
||||||
CertificatePrivateKey::RSA { cert_rsa_private_key } => {
|
CertificatePrivateKey::RSA { cert_rsa_private_key } => {
|
||||||
|
macro_rules! make_transcript_hash {
|
||||||
|
($hash: ty) => {
|
||||||
|
{
|
||||||
|
<$hash>::new()
|
||||||
|
.chain(&[0x20; 64])
|
||||||
|
.chain({
|
||||||
|
match role {
|
||||||
|
TlsRole::Client => "TLS 1.3, client CertificateVerify",
|
||||||
|
TlsRole::Server => "TLS 1.3, server CertificateVerify",
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.chain(&[0x00])
|
||||||
|
.chain(&transcript_hash)
|
||||||
|
.finalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let sig_alg = self.client_cert_verify_sig_alg.unwrap();
|
let sig_alg = self.client_cert_verify_sig_alg.unwrap();
|
||||||
let verify_hash: Vec<u8, U64> = match sig_alg {
|
let verify_hash: Vec<u8, U64> = match sig_alg {
|
||||||
rsa_pkcs1_sha256 | rsa_pss_rsae_sha256 | rsa_pss_pss_sha256 => {
|
rsa_pkcs1_sha256 | rsa_pss_rsae_sha256 | rsa_pss_pss_sha256 => {
|
||||||
Vec::from_slice(
|
Vec::from_slice(
|
||||||
&sha2::Sha256::new()
|
&make_transcript_hash!(Sha256)
|
||||||
.chain(&[0x20; 64])
|
|
||||||
.chain("TLS 1.3, client CertificateVerify")
|
|
||||||
.chain(&[0x00])
|
|
||||||
.chain(&transcript_hash)
|
|
||||||
.finalize()
|
|
||||||
).unwrap()
|
).unwrap()
|
||||||
},
|
},
|
||||||
rsa_pkcs1_sha384 | rsa_pss_rsae_sha384 | rsa_pss_pss_sha384 => {
|
rsa_pkcs1_sha384 | rsa_pss_rsae_sha384 | rsa_pss_pss_sha384 => {
|
||||||
Vec::from_slice(
|
Vec::from_slice(
|
||||||
&sha2::Sha384::new()
|
&make_transcript_hash!(Sha384)
|
||||||
.chain(&[0x20; 64])
|
|
||||||
.chain("TLS 1.3, client CertificateVerify")
|
|
||||||
.chain(&[0x00])
|
|
||||||
.chain(&transcript_hash)
|
|
||||||
.finalize()
|
|
||||||
).unwrap()
|
).unwrap()
|
||||||
},
|
},
|
||||||
rsa_pkcs1_sha512 | rsa_pss_rsae_sha512 | rsa_pss_pss_sha512 => {
|
rsa_pkcs1_sha512 | rsa_pss_rsae_sha512 | rsa_pss_pss_sha512 => {
|
||||||
Vec::from_slice(
|
Vec::from_slice(
|
||||||
&sha2::Sha512::new()
|
&make_transcript_hash!(Sha512)
|
||||||
.chain(&[0x20; 64])
|
|
||||||
.chain("TLS 1.3, client CertificateVerify")
|
|
||||||
.chain(&[0x00])
|
|
||||||
.chain(&transcript_hash)
|
|
||||||
.finalize()
|
|
||||||
).unwrap()
|
).unwrap()
|
||||||
},
|
},
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
|
119
src/tls.rs
119
src/tls.rs
@ -365,7 +365,10 @@ impl<'s> TlsSocket<'s> {
|
|||||||
{
|
{
|
||||||
let session = self.session.borrow();
|
let session = self.session.borrow();
|
||||||
let (sig_alg, signature) = session
|
let (sig_alg, signature) = session
|
||||||
.get_client_certificate_verify_signature(&mut self.rng);
|
.get_certificate_verify_signature(
|
||||||
|
&mut self.rng,
|
||||||
|
TlsRole::Client
|
||||||
|
);
|
||||||
|
|
||||||
let signature_length: u16 = u16::try_from(signature.len()).unwrap();
|
let signature_length: u16 = u16::try_from(signature.len()).unwrap();
|
||||||
NetworkEndian::write_u24(
|
NetworkEndian::write_u24(
|
||||||
@ -513,6 +516,120 @@ impl<'s> TlsSocket<'s> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Option to allow a certificate request
|
||||||
|
|
||||||
|
// Construct and send server certificate handshake content
|
||||||
|
let mut inner_plaintext = {
|
||||||
|
let mut inner_plaintext: Vec<u8> = Vec::new();
|
||||||
|
let session = self.session.borrow();
|
||||||
|
let certificates = session.get_private_certificate_slices().clone();
|
||||||
|
|
||||||
|
// Handshake level, client certificate byte followed by length (u24)
|
||||||
|
// Certificate struct:
|
||||||
|
// request_context = X509: 0 (u8),
|
||||||
|
// certificate_list to be determined (u24)
|
||||||
|
let mut certificates_total_length: u32 = 0;
|
||||||
|
|
||||||
|
// Append place holder bytes (8 of them) in the buffer vector
|
||||||
|
// Simpily copy the the headers back into the vector
|
||||||
|
// when all certificates are appended into the vector
|
||||||
|
inner_plaintext.extend_from_slice(&[11, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
|
// Certificate Entry struct(s)
|
||||||
|
if let Some(certificate_list) = certificates {
|
||||||
|
for cert in certificate_list.iter() {
|
||||||
|
// cert_data length, to be determined (u24)
|
||||||
|
let mut cert_data_length: [u8; 3] = [0, 0, 0];
|
||||||
|
// extensions: no extension needed
|
||||||
|
let extension: [u8; 2] = [0, 0];
|
||||||
|
|
||||||
|
let certificate_length: u32 = u32::try_from(cert.len()).unwrap();
|
||||||
|
|
||||||
|
NetworkEndian::write_u24(
|
||||||
|
&mut cert_data_length,
|
||||||
|
certificate_length
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update length in Certificate struct
|
||||||
|
certificates_total_length +=
|
||||||
|
// cert_data (len & data) AND extension (len & data)
|
||||||
|
3 + certificate_length + 2 + 0;
|
||||||
|
|
||||||
|
inner_plaintext.extend_from_slice(&cert_data_length);
|
||||||
|
inner_plaintext.extend_from_slice(cert);
|
||||||
|
inner_plaintext.extend_from_slice(&extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write total certificate length into Certificate struct
|
||||||
|
NetworkEndian::write_u24(
|
||||||
|
&mut inner_plaintext[5..8],
|
||||||
|
certificates_total_length
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write the length of the entire handshake
|
||||||
|
NetworkEndian::write_u24(
|
||||||
|
&mut inner_plaintext[1..4],
|
||||||
|
// 4 bytes for the Certificate struct header
|
||||||
|
certificates_total_length + 4
|
||||||
|
);
|
||||||
|
|
||||||
|
// Inner plaintext: record type
|
||||||
|
inner_plaintext.push(22);
|
||||||
|
inner_plaintext
|
||||||
|
};
|
||||||
|
|
||||||
|
self.send_application_slice(sockets, &mut inner_plaintext.clone())?;
|
||||||
|
|
||||||
|
// Update session
|
||||||
|
{
|
||||||
|
self.session.borrow_mut()
|
||||||
|
.server_update_for_sent_certificate(&inner_plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct and send certificate verify
|
||||||
|
let mut inner_plaintext = {
|
||||||
|
let mut inner_plaintext = Vec::new();
|
||||||
|
inner_plaintext.extend_from_slice(&[
|
||||||
|
15,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0,
|
||||||
|
0, 0
|
||||||
|
]);
|
||||||
|
let session = self.session.borrow();
|
||||||
|
let (sig_alg, signature) = session.get_certificate_verify_signature(
|
||||||
|
&mut self.rng,
|
||||||
|
TlsRole::Server
|
||||||
|
);
|
||||||
|
let signature_length: u16 = u16::try_from(signature.len()).unwrap();
|
||||||
|
NetworkEndian::write_u24(
|
||||||
|
&mut inner_plaintext[1..4],
|
||||||
|
(signature_length + 4).into()
|
||||||
|
);
|
||||||
|
NetworkEndian::write_u16(
|
||||||
|
&mut inner_plaintext[4..6],
|
||||||
|
sig_alg.try_into().unwrap()
|
||||||
|
);
|
||||||
|
NetworkEndian::write_u16(
|
||||||
|
&mut inner_plaintext[6..8],
|
||||||
|
signature_length
|
||||||
|
);
|
||||||
|
inner_plaintext.extend_from_slice(&signature);
|
||||||
|
inner_plaintext.push(22); // Content type byte
|
||||||
|
inner_plaintext
|
||||||
|
};
|
||||||
|
|
||||||
|
self.send_application_slice(
|
||||||
|
sockets,
|
||||||
|
&mut inner_plaintext.clone()
|
||||||
|
)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
self.session.borrow_mut()
|
||||||
|
.server_update_for_sent_certificate_verify(
|
||||||
|
&inner_plaintext[..]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other states regarding server role
|
// Other states regarding server role
|
||||||
|
Loading…
Reference in New Issue
Block a user