upgrade ratls to latest

This commit is contained in:
Valentyn Faychuk 2024-08-20 16:08:33 +02:00
parent 682d8ddd6e
commit e36329c4be
Signed by: valy
GPG Key ID: F1AB995E20FEADC5
8 changed files with 220 additions and 153 deletions

@ -1,31 +1,28 @@
# Copyright (c) 2024 DeTEE, LLC.
# All rights reserved.
[package]
name = "occlum-ratls"
version = "0.4.5"
version = "0.1.0"
edition = "2021"
authors = ["Ivan Chirkin <chirkin.ivan@gmail.com>"]
description = "Lib for remote attestation between occlum instances"
authors = ["Valentyn Faychuk <faitchouk.valentyn@gmail.com>", "Ivan Chirkin <chirkin.ivan@gmail.com>"]
description = "Remote attestation for Intel SGX"
license = "MIT OR Apache-2.0"
repository = "https://github.com/aggregion/occlum-ratls"
keywords = ["occlum", "rustls", "ratls"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# Inspired by https://github.com/aggregion/occlum-ratls
[dependencies]
x509-parser = "0.15.0"
#rustls = { version = "0.21", features = [
rustls = { version = "0.20.9", features = [
"dangerous_configuration",
"logging"
] }
log = "0.4.17"
rcgen = "0.12.1"
occlum-sgx = "^0.1.12"
ring = "0.17.8"
rustls = "0.23"
x509-parser = "0.16"
occlum-sgx = "0.1" # get/verify quote
ring = "0.17" # hash256
rcgen = "0.13"
log = "0.4"
hex = "0.4"
[dependencies.actix-web]
version = "4.3.1"
features = ["rustls-0_20"]
version = "4.3"
features = ["rustls-0_23"]
optional = true
[dependencies.actix-http]
@ -38,13 +35,13 @@ version = "2"
optional = true
[dependencies.reqwest]
version = "=0.11.10"
version = "0.12"
default-features = false
features = ["__rustls"]
optional = true
[dev-dependencies.env_logger]
version = "0.10.0"
version = "0.11"
[dev-dependencies.tokio]
version = "1"

@ -4,40 +4,76 @@ use crate::{
racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder},
RaTlsConfig, RaTlsConfigBuilder, RaTlsError,
};
use rustls::client::danger::HandshakeSignatureValid;
use rustls::crypto::{aws_lc_rs, verify_tls12_signature, verify_tls13_signature, CryptoProvider};
use rustls::pki_types::{CertificateDer, ServerName, UnixTime};
use rustls::{
client::{ResolvesClientCert, ServerCertVerified, ServerCertVerifier},
client::{danger::ServerCertVerified, danger::ServerCertVerifier, ResolvesClientCert},
sign::CertifiedKey,
ClientConfig,
ClientConfig, DigitallySignedStruct, Error, SignatureScheme,
};
#[derive(Debug)]
pub struct RaTlsServerCertVerifier {
config: RaTlsConfig,
provider: CryptoProvider,
}
impl RaTlsServerCertVerifier {
pub fn new(config: RaTlsConfig) -> Self {
Self { config }
Self {
config,
provider: aws_lc_rs::default_provider(), // FIPS certified provider
}
}
}
impl ServerCertVerifier for RaTlsServerCertVerifier {
fn verify_server_cert(
&self,
end_entity: &rustls::Certificate,
_intermediates: &[rustls::Certificate],
_server_name: &rustls::ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
end_entity: &CertificateDer,
_intermediates: &[CertificateDer],
_server_name: &ServerName,
_ocsp_response: &[u8],
_now: std::time::SystemTime,
) -> Result<ServerCertVerified, rustls::Error> {
_now: UnixTime,
) -> Result<ServerCertVerified, Error> {
end_entity
.verify_quote(&self.config)
.map_err(|e| rustls::Error::General(e.to_string()))?;
.map_err(|e| Error::General(e.to_string()))?;
Ok(ServerCertVerified::assertion())
}
// TLS 1.2 signature verification from the AWS libcrypto
fn verify_tls12_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
let supported_schemes = self.provider.signature_verification_algorithms;
verify_tls12_signature(message, cert, dss, &supported_schemes)
}
// TLS 1.3 signature verification from the AWS libcrypto
fn verify_tls13_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
let supported_schemes = self.provider.signature_verification_algorithms;
verify_tls13_signature(message, cert, dss, &supported_schemes)
}
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
self.provider
.signature_verification_algorithms
.supported_schemes()
}
}
#[derive(Debug)]
pub struct RaTlsClientCertResolver {
cert: Arc<CertifiedKey>,
}
@ -67,7 +103,7 @@ impl ResolvesClientCert for RaTlsClientCertResolver {
impl RaTlsConfigBuilder<ClientConfig> for ClientConfig {
fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> {
Ok(Self::builder()
.with_safe_defaults()
.dangerous()
.with_custom_certificate_verifier(Arc::new(RaTlsServerCertVerifier::new(config)))
.with_client_cert_resolver(Arc::new(RaTlsClientCertResolver::new()?)))
}

@ -3,17 +3,19 @@ use crate::{RaTlsConfigBuilder, RaTlsError};
#[cfg(feature = "occlum")]
use occlum_sgx::SGXQuote;
// FIXME: this only suppresses the warnings
#[allow(unused_imports)]
pub use occlum_sgx::SGXMeasurement;
use rustls::{ClientConfig, ServerConfig};
#[derive(Default)]
#[derive(Default, Debug)]
pub struct RaTlsConfig {
#[cfg(feature = "occlum")]
pub(crate) allowed_instances: Vec<InstanceMeasurement>,
}
#[cfg(feature = "occlum")]
#[derive(Default, Clone)]
#[derive(Default, Debug, Clone)]
pub struct InstanceMeasurement {
pub(crate) mrsigners: Option<Vec<SGXMeasurement>>,
pub(crate) mrenclaves: Option<Vec<SGXMeasurement>>,

@ -40,9 +40,8 @@ where
addr: A,
config: RaTlsConfig,
) -> Result<Self, std::io::Error> {
let config = ServerConfig::from_ratls_config(config).map_err(|e|
std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e))
)?;
self.bind_rustls(addr, config)
let config = ServerConfig::from_ratls_config(config)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e)))?;
self.bind_rustls_0_23(addr, config)
}
}

@ -7,14 +7,10 @@ use log::error;
#[cfg(feature = "occlum")]
use occlum_sgx::SGXQuote;
use rustls::{
sign::{any_supported_type, CertifiedKey},
Certificate, PrivateKey,
};
use rcgen::{
Certificate as GenCertificate, CertificateParams, CustomExtension, DistinguishedName, KeyPair,
};
use rcgen::{CertificateParams, CustomExtension, DistinguishedName, KeyPair};
use rustls::crypto::aws_lc_rs::sign::any_supported_type;
use rustls::pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer};
use rustls::{pki_types::CertificateDer, sign::CertifiedKey};
#[cfg(feature = "occlum")]
use x509_parser::{nom::Parser, oid_registry::Oid, prelude::X509CertificateParser, public_key};
@ -55,27 +51,21 @@ impl RaTlsCertificateBuilder {
fn build_internal(&self) -> Result<RaTlsCertifiedKey, Box<dyn Error>> {
let mut distinguished_name = DistinguishedName::new();
distinguished_name.push(rcgen::DnType::CommonName, self.common_name.clone());
distinguished_name.push(rcgen::DnType::CountryName, "US");
distinguished_name.push(rcgen::DnType::CountryName, "EU");
distinguished_name.push(rcgen::DnType::OrganizationName, "DeTEE");
let mut params = CertificateParams::default();
let key_pair = KeyPair::generate(params.alg)?;
let key_pair = KeyPair::generate()?;
let quote = self.get_quote(&key_pair)?;
params.key_pair = Some(key_pair);
let mut params = CertificateParams::default();
params.distinguished_name = distinguished_name;
params.custom_extensions = vec![CustomExtension::from_oid_content(&REPORT_OID, quote)];
let crt = params.self_signed(&key_pair)?;
let crt = GenCertificate::from_params(params)?;
Ok(RaTlsCertifiedKey {
cert_der: crt.serialize_der()?,
key_der: crt.serialize_private_key_der(),
})
let cert_der = crt.der().to_vec();
let key_der = key_pair.serialize_der();
Ok(RaTlsCertifiedKey { cert_der, key_der })
}
#[cfg(not(feature = "occlum"))]
@ -95,17 +85,23 @@ impl RaTlsCertificateBuilder {
impl CertificateBuilder for RaTlsCertificateBuilder {
fn build(&self) -> Result<CertifiedKey, RaTlsError> {
self.build_internal()
.map(|k| {
let sign_key = any_supported_type(&PrivateKey(k.key_der)).unwrap();
let cert_key = self.build_internal().map_err(|e| {
let err = RaTlsError::CertificateBuildError(e.to_string());
error!("{}", err);
err
})?;
CertifiedKey::new(vec![Certificate(k.cert_der)], sign_key)
})
.map_err(|e| {
let err = RaTlsError::CertificateBuildError(e.to_string());
error!("{}", err);
err
})
let private_key_der = PrivateKeyDer::from(PrivatePkcs8KeyDer::from(cert_key.key_der));
let signing_key = any_supported_type(&private_key_der).map_err(|e| {
let err = RaTlsError::CertificateBuildError(e.to_string());
error!("{}", err);
err
})?;
Ok(CertifiedKey::new(
vec![CertificateDer::from(cert_key.cert_der)],
signing_key,
))
}
}
@ -113,7 +109,7 @@ pub trait RaTlsCertificate {
fn verify_quote(&self, config: &RaTlsConfig) -> Result<(), Box<dyn Error>>;
}
impl RaTlsCertificate for rustls::Certificate {
impl RaTlsCertificate for CertificateDer<'_> {
#[cfg(not(feature = "occlum"))]
fn verify_quote(&self, _: &RaTlsConfig) -> Result<(), Box<dyn Error>> {
Ok(())

@ -1,41 +1,81 @@
use rustls::{server::{ClientCertVerified, ClientCertVerifier, ResolvesServerCert}, sign::CertifiedKey, Certificate, Error, ServerConfig, DistinguishedNames};
use std::{sync::Arc, time::SystemTime};
use crate::{
racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder},
RaTlsConfig, RaTlsConfigBuilder, RaTlsError,
};
use rustls::client::danger::HandshakeSignatureValid;
use rustls::crypto::{aws_lc_rs, verify_tls12_signature, verify_tls13_signature, CryptoProvider};
use rustls::pki_types::{CertificateDer, UnixTime};
use rustls::{
server::{danger::ClientCertVerified, danger::ClientCertVerifier, ResolvesServerCert},
sign::CertifiedKey,
DigitallySignedStruct, DistinguishedName, Error, ServerConfig, SignatureScheme,
};
use std::sync::Arc;
#[derive(Debug)]
pub struct RaTlsClientCertVerifier {
config: RaTlsConfig,
provider: CryptoProvider,
}
impl RaTlsClientCertVerifier {
pub fn new(config: RaTlsConfig) -> Self {
Self { config }
Self {
config,
provider: aws_lc_rs::default_provider(), // FIPS certified provider
}
}
}
impl ClientCertVerifier for RaTlsClientCertVerifier {
fn root_hint_subjects(&self) -> &[DistinguishedName] {
&[] // TODO: check if any names are needed
}
fn verify_client_cert(
&self,
end_entity: &Certificate,
_intermediates: &[Certificate],
_now: SystemTime,
end_entity: &CertificateDer,
_intermediates: &[CertificateDer],
_now: UnixTime,
) -> Result<ClientCertVerified, Error> {
end_entity.verify_quote(&self.config).map_err(|e| {
println!("{:?}", e);
rustls::Error::General(e.to_string())
log::log!(log::Level::Error, "{}", e);
Error::General(e.to_string())
})?;
Ok(ClientCertVerified::assertion())
}
fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
Some(DistinguishedNames::new())
// TLS 1.2 signature verification from the AWS libcrypto
fn verify_tls12_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
let supported_schemes = self.provider.signature_verification_algorithms;
verify_tls12_signature(message, cert, dss, &supported_schemes)
}
// TLS 1.3 signature verification from the AWS libcrypto
fn verify_tls13_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
let supported_schemes = self.provider.signature_verification_algorithms;
verify_tls13_signature(message, cert, dss, &supported_schemes)
}
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
self.provider
.signature_verification_algorithms
.supported_schemes()
}
}
#[derive(Debug)]
pub struct RaTlsServerCertResolver {
cert: Arc<CertifiedKey>,
}
@ -49,10 +89,7 @@ impl RaTlsServerCertResolver {
}
impl ResolvesServerCert for RaTlsServerCertResolver {
fn resolve(
&self,
_client_hello: rustls::server::ClientHello,
) -> Option<std::sync::Arc<CertifiedKey>> {
fn resolve(&self, _client_hello: rustls::server::ClientHello) -> Option<Arc<CertifiedKey>> {
Some(self.cert.clone())
}
}
@ -60,7 +97,6 @@ impl ResolvesServerCert for RaTlsServerCertResolver {
impl RaTlsConfigBuilder<ServerConfig> for ServerConfig {
fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> {
Ok(Self::builder()
.with_safe_defaults()
.with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config)))
.with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?)))
}

@ -1,67 +1,67 @@
use rustls::{server::{ClientCertVerified, ClientCertVerifier, ResolvesServerCert}, sign::CertifiedKey, Certificate, Error, ServerConfig, DistinguishedNames};
use std::{sync::Arc, time::SystemTime};
use crate::{
racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder},
RaTlsConfig, RaTlsConfigBuilder, RaTlsError,
};
pub struct RaTlsClientCertVerifier {
config: RaTlsConfig,
}
impl RaTlsClientCertVerifier {
pub fn new(config: RaTlsConfig) -> Self {
Self { config }
}
}
impl ClientCertVerifier for RaTlsClientCertVerifier {
fn verify_client_cert(
&self,
end_entity: &Certificate,
_intermediates: &[Certificate],
_now: SystemTime,
) -> Result<ClientCertVerified, Error> {
end_entity.verify_quote(&self.config).map_err(|e| {
println!("{:?}", e);
rustls::Error::General(e.to_string())
})?;
Ok(ClientCertVerified::assertion())
}
fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
Some(DistinguishedNames::new())
}
}
pub struct RaTlsServerCertResolver {
cert: Arc<CertifiedKey>,
}
impl RaTlsServerCertResolver {
pub fn new() -> Result<Self, RaTlsError> {
let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string());
let cert = builder.build().map(Arc::new)?;
Ok(Self { cert })
}
}
impl ResolvesServerCert for RaTlsServerCertResolver {
fn resolve(
&self,
_client_hello: rustls::server::ClientHello,
) -> Option<std::sync::Arc<CertifiedKey>> {
Some(self.cert.clone())
}
}
impl RaTlsConfigBuilder<ServerConfig> for ServerConfig {
fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> {
Ok(Self::builder()
.with_safe_defaults()
.with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config)))
.with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?)))
}
}
// use rustls::{server::{ClientCertVerified, ClientCertVerifier, ResolvesServerCert}, sign::CertifiedKey, Certificate, Error, ServerConfig, DistinguishedNames};
// use std::{sync::Arc, time::SystemTime};
//
// use crate::{
// racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder},
// RaTlsConfig, RaTlsConfigBuilder, RaTlsError,
// };
//
// pub struct RaTlsClientCertVerifier {
// config: RaTlsConfig,
// }
//
// impl RaTlsClientCertVerifier {
// pub fn new(config: RaTlsConfig) -> Self {
// Self { config }
// }
// }
//
// impl ClientCertVerifier for RaTlsClientCertVerifier {
// fn verify_client_cert(
// &self,
// end_entity: &Certificate,
// _intermediates: &[Certificate],
// _now: SystemTime,
// ) -> Result<ClientCertVerified, Error> {
// end_entity.verify_quote(&self.config).map_err(|e| {
// println!("{:?}", e);
// rustls::Error::General(e.to_string())
// })?;
//
// Ok(ClientCertVerified::assertion())
// }
//
// fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
// Some(DistinguishedNames::new())
// }
// }
//
// pub struct RaTlsServerCertResolver {
// cert: Arc<CertifiedKey>,
// }
//
// impl RaTlsServerCertResolver {
// pub fn new() -> Result<Self, RaTlsError> {
// let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string());
// let cert = builder.build().map(Arc::new)?;
// Ok(Self { cert })
// }
// }
//
// impl ResolvesServerCert for RaTlsServerCertResolver {
// fn resolve(
// &self,
// _client_hello: rustls::server::ClientHello,
// ) -> Option<std::sync::Arc<CertifiedKey>> {
// Some(self.cert.clone())
// }
// }
//
// impl RaTlsConfigBuilder<ServerConfig> for ServerConfig {
// fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> {
// Ok(Self::builder()
// .with_safe_defaults()
// .with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config)))
// .with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?)))
// }
// }

@ -1,5 +1,6 @@
use ring::digest::{Context, SHA512};
// TODO: make sure this function is correct
pub fn hash_sha512(input: Vec<u8>) -> [u8; 64] {
let mut context = Context::new(&SHA512);
context.update(input.as_ref());