mirror of https://github.com/ctz/rustls
Updated for Ring 0.16
This commit is contained in:
parent
ffe97de665
commit
14b2126298
|
@ -13,10 +13,9 @@ categories = ["network-programming", "cryptography"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
log = { version = "0.4.4", optional = true }
|
log = { version = "0.4.4", optional = true }
|
||||||
ring = "0.15.0-alpha4"
|
ring = "0.16.0"
|
||||||
sct = { path = "../sct.rs", version = "0.5" }
|
sct = { path = "../sct.rs", version = "0.6.0-alpha.0" }
|
||||||
untrusted = "0.7.0-alpha1"
|
webpki = "0.21.0"
|
||||||
webpki = "0.20.0-alpha1"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["logging"]
|
default = ["logging"]
|
||||||
|
@ -28,7 +27,7 @@ quic = []
|
||||||
env_logger = "0.6.1"
|
env_logger = "0.6.1"
|
||||||
log = "0.4.4"
|
log = "0.4.4"
|
||||||
tempfile = "3.0"
|
tempfile = "3.0"
|
||||||
webpki-roots = { version = "0.16", path = "../webpki-roots" }
|
webpki-roots = { path = "../webpki-roots", version = "0.17.0-alpha.0" }
|
||||||
criterion = "0.2.11"
|
criterion = "0.2.11"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use webpki;
|
use webpki;
|
||||||
use untrusted;
|
|
||||||
|
|
||||||
pub use crate::msgs::handshake::{DistinguishedName, DistinguishedNames};
|
pub use crate::msgs::handshake::{DistinguishedName, DistinguishedNames};
|
||||||
use crate::pemfile;
|
use crate::pemfile;
|
||||||
|
@ -79,10 +78,7 @@ impl RootCertStore {
|
||||||
|
|
||||||
/// Add a single DER-encoded certificate to the store.
|
/// Add a single DER-encoded certificate to the store.
|
||||||
pub fn add(&mut self, der: &key::Certificate) -> Result<(), webpki::Error> {
|
pub fn add(&mut self, der: &key::Certificate) -> Result<(), webpki::Error> {
|
||||||
let ta = {
|
let ta = webpki::trust_anchor_util::cert_der_as_trust_anchor(&der.0)?;
|
||||||
let inp = untrusted::Input::from(&der.0);
|
|
||||||
webpki::trust_anchor_util::cert_der_as_trust_anchor(inp)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let ota = OwnedTrustAnchor::from_trust_anchor(&ta);
|
let ota = OwnedTrustAnchor::from_trust_anchor(&ta);
|
||||||
self.roots.push(ota);
|
self.roots.push(ota);
|
||||||
|
|
|
@ -168,10 +168,10 @@ impl MessageDecrypter for GCMMessageDecrypter {
|
||||||
make_tls12_aad(seq, msg.typ, msg.version, buf.len() - GCM_OVERHEAD, &mut aad);
|
make_tls12_aad(seq, msg.typ, msg.version, buf.len() - GCM_OVERHEAD, &mut aad);
|
||||||
let aad = aead::Aad::from(&aad);
|
let aad = aead::Aad::from(&aad);
|
||||||
|
|
||||||
let plain_len = self.dec_key.open_in_place(nonce,
|
let plain_len = self.dec_key.open_within(nonce,
|
||||||
aad,
|
aad,
|
||||||
GCM_EXPLICIT_NONCE_LEN,
|
&mut buf,
|
||||||
&mut buf)
|
GCM_EXPLICIT_NONCE_LEN..)
|
||||||
.map_err(|_| TLSError::DecryptError)?
|
.map_err(|_| TLSError::DecryptError)?
|
||||||
.len();
|
.len();
|
||||||
|
|
||||||
|
@ -207,25 +207,26 @@ impl MessageEncrypter for GCMMessageEncrypter {
|
||||||
aead::Nonce::assume_unique_for_key(nonce)
|
aead::Nonce::assume_unique_for_key(nonce)
|
||||||
};
|
};
|
||||||
|
|
||||||
// make output buffer with room for nonce/tag
|
let total_len = msg.payload.len() + self.alg.tag_len();
|
||||||
let tag_len = self.alg.tag_len();
|
|
||||||
let total_len = 8 + msg.payload.len() + tag_len;
|
|
||||||
let mut buf = Vec::with_capacity(total_len);
|
let mut buf = Vec::with_capacity(total_len);
|
||||||
buf.extend_from_slice(&nonce.as_ref()[4..]);
|
buf.extend_from_slice(&msg.payload);
|
||||||
buf.extend_from_slice(msg.payload);
|
|
||||||
buf.resize(total_len, 0u8);
|
|
||||||
|
|
||||||
let mut aad = [0u8; TLS12_AAD_SIZE];
|
let mut aad = [0u8; TLS12_AAD_SIZE];
|
||||||
make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len(), &mut aad);
|
make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len(), &mut aad);
|
||||||
let aad = aead::Aad::from(&aad);
|
let aad = aead::Aad::from(&aad);
|
||||||
|
|
||||||
self.enc_key.seal_in_place(nonce, aad, &mut buf[8..], tag_len)
|
let mut payload = Vec::with_capacity(GCM_EXPLICIT_NONCE_LEN + total_len);
|
||||||
|
payload.extend_from_slice(&nonce.as_ref()[4..]);
|
||||||
|
|
||||||
|
self.enc_key.seal_in_place(nonce, aad, &mut buf)
|
||||||
.map_err(|_| TLSError::General("encrypt failed".to_string()))?;
|
.map_err(|_| TLSError::General("encrypt failed".to_string()))?;
|
||||||
|
|
||||||
|
payload.extend_from_slice(&buf);
|
||||||
|
|
||||||
Ok(Message {
|
Ok(Message {
|
||||||
typ: msg.typ,
|
typ: msg.typ,
|
||||||
version: msg.version,
|
version: msg.version,
|
||||||
payload: MessagePayload::new_opaque(buf),
|
payload: MessagePayload::new_opaque(payload),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,18 +314,15 @@ impl MessageEncrypter for TLS13MessageEncrypter {
|
||||||
aead::Nonce::assume_unique_for_key(nonce)
|
aead::Nonce::assume_unique_for_key(nonce)
|
||||||
};
|
};
|
||||||
|
|
||||||
// make output buffer with room for content type and tag
|
let total_len = msg.payload.len() + 1 + self.alg.tag_len();
|
||||||
let tag_len = self.alg.tag_len();
|
|
||||||
let total_len = msg.payload.len() + 1 + tag_len;
|
|
||||||
let mut buf = Vec::with_capacity(total_len);
|
let mut buf = Vec::with_capacity(total_len);
|
||||||
buf.extend_from_slice(msg.payload);
|
buf.extend_from_slice(&msg.payload);
|
||||||
msg.typ.encode(&mut buf);
|
msg.typ.encode(&mut buf);
|
||||||
buf.resize(total_len, 0u8);
|
|
||||||
let mut aad = [0u8; TLS13_AAD_SIZE];
|
let mut aad = [0u8; TLS13_AAD_SIZE];
|
||||||
make_tls13_aad(total_len, &mut aad);
|
make_tls13_aad(total_len, &mut aad);
|
||||||
|
|
||||||
self.enc_key.seal_in_place(nonce, aead::Aad::from(&aad), &mut buf,
|
self.enc_key.seal_in_place(nonce, aead::Aad::from(&aad), &mut buf)
|
||||||
tag_len)
|
|
||||||
.map_err(|_| TLSError::General("encrypt failed".to_string()))?;
|
.map_err(|_| TLSError::General("encrypt failed".to_string()))?;
|
||||||
|
|
||||||
Ok(Message {
|
Ok(Message {
|
||||||
|
@ -355,7 +353,7 @@ impl MessageDecrypter for TLS13MessageDecrypter {
|
||||||
let mut aad = [0u8; TLS13_AAD_SIZE];
|
let mut aad = [0u8; TLS13_AAD_SIZE];
|
||||||
make_tls13_aad(buf.len(), &mut aad);
|
make_tls13_aad(buf.len(), &mut aad);
|
||||||
let aad = aead::Aad::from(&aad);
|
let aad = aead::Aad::from(&aad);
|
||||||
let plain_len = self.dec_key.open_in_place(nonce, aad, 0, &mut buf)
|
let plain_len = self.dec_key.open_in_place(nonce, aad, &mut buf)
|
||||||
.map_err(|_| TLSError::DecryptError)?
|
.map_err(|_| TLSError::DecryptError)?
|
||||||
.len();
|
.len();
|
||||||
|
|
||||||
|
@ -491,7 +489,7 @@ impl MessageDecrypter for ChaCha20Poly1305MessageDecrypter {
|
||||||
make_tls12_aad(seq, msg.typ, msg.version, buf.len() - CHACHAPOLY1305_OVERHEAD, &mut aad);
|
make_tls12_aad(seq, msg.typ, msg.version, buf.len() - CHACHAPOLY1305_OVERHEAD, &mut aad);
|
||||||
let aad = aead::Aad::from(&aad);
|
let aad = aead::Aad::from(&aad);
|
||||||
|
|
||||||
let plain_len = self.dec_key.open_in_place(nonce, aad, 0, &mut buf)
|
let plain_len = self.dec_key.open_in_place(nonce, aad, &mut buf)
|
||||||
.map_err(|_| TLSError::DecryptError)?
|
.map_err(|_| TLSError::DecryptError)?
|
||||||
.len();
|
.len();
|
||||||
|
|
||||||
|
@ -522,14 +520,11 @@ impl MessageEncrypter for ChaCha20Poly1305MessageEncrypter {
|
||||||
make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len(), &mut aad);
|
make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len(), &mut aad);
|
||||||
let aad = aead::Aad::from(&aad);
|
let aad = aead::Aad::from(&aad);
|
||||||
|
|
||||||
// make result buffer with room for tag, etc.
|
let total_len = msg.payload.len() + self.alg.tag_len();
|
||||||
let tag_len = self.alg.tag_len();
|
|
||||||
let total_len = msg.payload.len() + tag_len;
|
|
||||||
let mut buf = Vec::with_capacity(total_len);
|
let mut buf = Vec::with_capacity(total_len);
|
||||||
buf.extend_from_slice(msg.payload);
|
buf.extend_from_slice(&msg.payload);
|
||||||
buf.resize(total_len, 0u8);
|
|
||||||
|
|
||||||
self.enc_key.seal_in_place(nonce, aad, &mut buf, tag_len)
|
self.enc_key.seal_in_place(nonce, aad, &mut buf)
|
||||||
.map_err(|_| TLSError::General("encrypt failed".to_string()))?;
|
.map_err(|_| TLSError::General("encrypt failed".to_string()))?;
|
||||||
|
|
||||||
Ok(Message {
|
Ok(Message {
|
||||||
|
|
|
@ -17,7 +17,6 @@ use std::fmt;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::collections;
|
use std::collections;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use untrusted;
|
|
||||||
use webpki;
|
use webpki;
|
||||||
|
|
||||||
macro_rules! declare_u8_vec(
|
macro_rules! declare_u8_vec(
|
||||||
|
@ -261,8 +260,7 @@ impl ServerNamePayload {
|
||||||
fn read_hostname(r: &mut Reader) -> Option<ServerNamePayload> {
|
fn read_hostname(r: &mut Reader) -> Option<ServerNamePayload> {
|
||||||
let len = u16::read(r)? as usize;
|
let len = u16::read(r)? as usize;
|
||||||
let name = r.take(len)?;
|
let name = r.take(len)?;
|
||||||
let dns_name = match webpki::DNSNameRef::try_from_ascii(
|
let dns_name = match webpki::DNSNameRef::try_from_ascii(name) {
|
||||||
untrusted::Input::from(name)) {
|
|
||||||
Ok(dns_name) => dns_name,
|
Ok(dns_name) => dns_name,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
warn!("Illegal SNI hostname received {:?}", name);
|
warn!("Illegal SNI hostname received {:?}", name);
|
||||||
|
|
|
@ -5,7 +5,6 @@ use crate::msgs::handshake::CertificatePayload;
|
||||||
use crate::msgs::base::{PayloadU8, PayloadU16};
|
use crate::msgs::base::{PayloadU8, PayloadU16};
|
||||||
|
|
||||||
use webpki;
|
use webpki;
|
||||||
use untrusted;
|
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
@ -207,7 +206,7 @@ impl Codec for ServerSessionValue {
|
||||||
let sni = if has_sni == 1 {
|
let sni = if has_sni == 1 {
|
||||||
let dns_name = PayloadU8::read(r)?;
|
let dns_name = PayloadU8::read(r)?;
|
||||||
let dns_name = webpki::DNSNameRef::try_from_ascii(
|
let dns_name = webpki::DNSNameRef::try_from_ascii(
|
||||||
untrusted::Input::from(&dns_name.0)).ok()?;
|
&dns_name.0).ok()?;
|
||||||
Some(dns_name.into())
|
Some(dns_name.into())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -3,8 +3,6 @@ use crate::util;
|
||||||
use crate::key;
|
use crate::key;
|
||||||
use crate::error::TLSError;
|
use crate::error::TLSError;
|
||||||
|
|
||||||
use untrusted;
|
|
||||||
|
|
||||||
use ring::{self, signature::{self, EcdsaKeyPair, RsaKeyPair}};
|
use ring::{self, signature::{self, EcdsaKeyPair, RsaKeyPair}};
|
||||||
use webpki;
|
use webpki;
|
||||||
|
|
||||||
|
@ -111,8 +109,7 @@ impl CertifiedKey {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Reject syntactically-invalid end-entity certificates.
|
// Reject syntactically-invalid end-entity certificates.
|
||||||
let end_entity_cert = webpki::EndEntityCert::from(
|
let end_entity_cert = webpki::EndEntityCert::from(end_entity_cert.as_ref()).map_err(|_| {
|
||||||
untrusted::Input::from(end_entity_cert.as_ref())).map_err(|_| {
|
|
||||||
TLSError::General("End-entity certificate in certificate \
|
TLSError::General("End-entity certificate in certificate \
|
||||||
chain is syntactically invalid".to_string())
|
chain is syntactically invalid".to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -68,19 +68,16 @@ impl ProducesTickets for AEADTicketer {
|
||||||
rand::fill_random(&mut nonce);
|
rand::fill_random(&mut nonce);
|
||||||
ring::aead::Nonce::assume_unique_for_key(nonce)
|
ring::aead::Nonce::assume_unique_for_key(nonce)
|
||||||
};
|
};
|
||||||
let nonce_len = nonce.as_ref().len();
|
|
||||||
let aad = ring::aead::Aad::empty();
|
let aad = ring::aead::Aad::empty();
|
||||||
|
|
||||||
let mut out = Vec::new();
|
let total_len = nonce.as_ref().len() + message.len() + self.alg.tag_len();
|
||||||
|
let mut out = Vec::with_capacity(total_len);
|
||||||
out.extend_from_slice(nonce.as_ref());
|
out.extend_from_slice(nonce.as_ref());
|
||||||
out.extend_from_slice(message);
|
out.extend_from_slice(message);
|
||||||
let out_len = out.len() + self.alg.tag_len();
|
|
||||||
out.resize(out_len, 0u8);
|
|
||||||
|
|
||||||
let rc = self.key.seal_in_place(nonce,
|
let rc = self.key.seal_in_place(nonce,
|
||||||
aad,
|
aad,
|
||||||
&mut out[nonce_len..],
|
&mut out);
|
||||||
self.alg.tag_len());
|
|
||||||
if rc.is_err() { None } else { Some(out) }
|
if rc.is_err() { None } else { Some(out) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +96,7 @@ impl ProducesTickets for AEADTicketer {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
out.extend_from_slice(&ciphertext[nonce_len..]);
|
out.extend_from_slice(&ciphertext[nonce_len..]);
|
||||||
|
|
||||||
let plain_len = match self.key.open_in_place(nonce, aad, 0, &mut out) {
|
let plain_len = match self.key.open_in_place(nonce, aad, &mut out) {
|
||||||
Ok(plaintext) => plaintext.len(),
|
Ok(plaintext) => plaintext.len(),
|
||||||
Err(..) => { return None; }
|
Err(..) => { return None; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use webpki;
|
use webpki;
|
||||||
use untrusted;
|
|
||||||
use sct;
|
use sct;
|
||||||
use std;
|
use std;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -128,20 +127,19 @@ impl WebPKIVerifier {
|
||||||
|
|
||||||
fn prepare<'a, 'b>(roots: &'b RootCertStore, presented_certs: &'a [Certificate])
|
fn prepare<'a, 'b>(roots: &'b RootCertStore, presented_certs: &'a [Certificate])
|
||||||
-> Result<(webpki::EndEntityCert<'a>,
|
-> Result<(webpki::EndEntityCert<'a>,
|
||||||
Vec<untrusted::Input<'a>>,
|
Vec<&'a [u8]>,
|
||||||
Vec<webpki::TrustAnchor<'b>>), TLSError> {
|
Vec<webpki::TrustAnchor<'b>>), TLSError> {
|
||||||
if presented_certs.is_empty() {
|
if presented_certs.is_empty() {
|
||||||
return Err(TLSError::NoCertificatesPresented);
|
return Err(TLSError::NoCertificatesPresented);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EE cert must appear first.
|
// EE cert must appear first.
|
||||||
let cert_der = untrusted::Input::from(&presented_certs[0].0);
|
let cert = webpki::EndEntityCert::from(&presented_certs[0].0)
|
||||||
let cert =
|
.map_err(TLSError::WebPKIError)?;
|
||||||
webpki::EndEntityCert::from(cert_der).map_err(TLSError::WebPKIError)?;
|
|
||||||
|
|
||||||
let chain: Vec<untrusted::Input> = presented_certs.iter()
|
let chain: Vec<&'a [u8]> = presented_certs.iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|cert| untrusted::Input::from(&cert.0))
|
.map(|cert| cert.0.as_ref())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let trustroots: Vec<webpki::TrustAnchor> = roots.roots
|
let trustroots: Vec<webpki::TrustAnchor> = roots.roots
|
||||||
|
@ -291,9 +289,7 @@ fn verify_sig_using_any_alg(cert: &webpki::EndEntityCert,
|
||||||
// TLS doesn't itself give us enough info to map to a single webpki::SignatureAlgorithm.
|
// TLS doesn't itself give us enough info to map to a single webpki::SignatureAlgorithm.
|
||||||
// Therefore, convert_algs maps to several and we try them all.
|
// Therefore, convert_algs maps to several and we try them all.
|
||||||
for alg in algs {
|
for alg in algs {
|
||||||
match cert.verify_signature(alg,
|
match cert.verify_signature(alg, message, sig) {
|
||||||
untrusted::Input::from(message),
|
|
||||||
untrusted::Input::from(sig)) {
|
|
||||||
Err(webpki::Error::UnsupportedSignatureAlgorithmForPublicKey) => continue,
|
Err(webpki::Error::UnsupportedSignatureAlgorithmForPublicKey) => continue,
|
||||||
res => return res,
|
res => return res,
|
||||||
}
|
}
|
||||||
|
@ -313,8 +309,7 @@ pub fn verify_signed_struct(message: &[u8],
|
||||||
-> Result<HandshakeSignatureValid, TLSError> {
|
-> Result<HandshakeSignatureValid, TLSError> {
|
||||||
|
|
||||||
let possible_algs = convert_scheme(dss.scheme)?;
|
let possible_algs = convert_scheme(dss.scheme)?;
|
||||||
let cert_in = untrusted::Input::from(&cert.0);
|
let cert = webpki::EndEntityCert::from(&cert.0)
|
||||||
let cert = webpki::EndEntityCert::from(cert_in)
|
|
||||||
.map_err(TLSError::WebPKIError)?;
|
.map_err(TLSError::WebPKIError)?;
|
||||||
|
|
||||||
verify_sig_using_any_alg(&cert, possible_algs, message, &dss.sig.0)
|
verify_sig_using_any_alg(&cert, possible_algs, message, &dss.sig.0)
|
||||||
|
@ -351,13 +346,10 @@ pub fn verify_tls13(cert: &Certificate,
|
||||||
msg.extend_from_slice(context_string_with_0);
|
msg.extend_from_slice(context_string_with_0);
|
||||||
msg.extend_from_slice(handshake_hash);
|
msg.extend_from_slice(handshake_hash);
|
||||||
|
|
||||||
let cert_in = untrusted::Input::from(&cert.0);
|
let cert = webpki::EndEntityCert::from(&cert.0)
|
||||||
let cert = webpki::EndEntityCert::from(cert_in)
|
|
||||||
.map_err(TLSError::WebPKIError)?;
|
.map_err(TLSError::WebPKIError)?;
|
||||||
|
|
||||||
cert.verify_signature(alg,
|
cert.verify_signature(alg, &msg, &dss.sig.0)
|
||||||
untrusted::Input::from(&msg),
|
|
||||||
untrusted::Input::from(&dss.sig.0))
|
|
||||||
.map_err(TLSError::WebPKIError)
|
.map_err(TLSError::WebPKIError)
|
||||||
.map(|_| HandshakeSignatureValid::assertion())
|
.map(|_| HandshakeSignatureValid::assertion())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue