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);
|
||||
}
|
||||
|
||||
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 {
|
||||
if let Some(session_id_inner) = self.session_id {
|
||||
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>)
|
||||
{
|
||||
if let Some((private_key, client_certificate)) = &self.cert_private_key {
|
||||
|
@ -1709,36 +1727,39 @@ impl<'a> Session<'a> {
|
|||
|
||||
match 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 verify_hash: Vec<u8, U64> = match sig_alg {
|
||||
rsa_pkcs1_sha256 | rsa_pss_rsae_sha256 | rsa_pss_pss_sha256 => {
|
||||
Vec::from_slice(
|
||||
&sha2::Sha256::new()
|
||||
.chain(&[0x20; 64])
|
||||
.chain("TLS 1.3, client CertificateVerify")
|
||||
.chain(&[0x00])
|
||||
.chain(&transcript_hash)
|
||||
.finalize()
|
||||
&make_transcript_hash!(Sha256)
|
||||
).unwrap()
|
||||
},
|
||||
rsa_pkcs1_sha384 | rsa_pss_rsae_sha384 | rsa_pss_pss_sha384 => {
|
||||
Vec::from_slice(
|
||||
&sha2::Sha384::new()
|
||||
.chain(&[0x20; 64])
|
||||
.chain("TLS 1.3, client CertificateVerify")
|
||||
.chain(&[0x00])
|
||||
.chain(&transcript_hash)
|
||||
.finalize()
|
||||
&make_transcript_hash!(Sha384)
|
||||
).unwrap()
|
||||
},
|
||||
rsa_pkcs1_sha512 | rsa_pss_rsae_sha512 | rsa_pss_pss_sha512 => {
|
||||
Vec::from_slice(
|
||||
&sha2::Sha512::new()
|
||||
.chain(&[0x20; 64])
|
||||
.chain("TLS 1.3, client CertificateVerify")
|
||||
.chain(&[0x00])
|
||||
.chain(&transcript_hash)
|
||||
.finalize()
|
||||
&make_transcript_hash!(Sha512)
|
||||
).unwrap()
|
||||
},
|
||||
_ => unreachable!()
|
||||
|
|
119
src/tls.rs
119
src/tls.rs
|
@ -365,7 +365,10 @@ impl<'s> TlsSocket<'s> {
|
|||
{
|
||||
let session = self.session.borrow();
|
||||
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();
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue