Skip to content

Commit

Permalink
chore: greater protection for release mode
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Zak <richard@profian.com>
  • Loading branch information
rjzak committed Oct 10, 2022
1 parent 2311adc commit 7778951
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/ext/kvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl ExtVerifier for Kvm {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.58270.1.1");
const ATT: bool = true;

fn verify(&self, _cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: bool) -> Result<bool> {
fn verify(&self, _cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: &bool) -> Result<bool> {
if ext.critical {
return Err(anyhow!("kvm extension cannot be critical"));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ext/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ pub trait ExtVerifier {
/// certificate. Returning `Ok(false)` will allow the certification request
/// to continue, but this particular extension will not be included
/// in the resulting certificate.
fn verify(&self, cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: bool) -> Result<bool>;
fn verify(&self, cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: &bool) -> Result<bool>;
}
2 changes: 1 addition & 1 deletion src/ext/sgx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl ExtVerifier for Sgx {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.58270.1.2");
const ATT: bool = true;

fn verify(&self, cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: bool) -> Result<bool> {
fn verify(&self, cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: &bool) -> Result<bool> {
if ext.critical {
return Err(anyhow!("sgx extension cannot be critical"));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ext/snp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl ExtVerifier for Snp {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.58270.1.3");
const ATT: bool = true;

fn verify(&self, cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: bool) -> Result<bool> {
fn verify(&self, cri: &CertReqInfo<'_>, ext: &Extension<'_>, dbg: &bool) -> Result<bool> {
if ext.critical {
return Err(anyhow!("snp extension cannot be critical"));
}
Expand Down
55 changes: 43 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ use axum::routing::{get, post};
use axum::Router;
use clap::Parser;
use confargs::{prefix_char_filter, Toml};
#[cfg(debug_assertions)]
use const_oid::db::rfc5280::{ID_CE_BASIC_CONSTRAINTS, ID_CE_KEY_USAGE};
use const_oid::db::rfc5280::{
ID_CE_BASIC_CONSTRAINTS, ID_CE_EXT_KEY_USAGE, ID_CE_KEY_USAGE, ID_CE_SUBJECT_ALT_NAME,
ID_KP_CLIENT_AUTH, ID_KP_SERVER_AUTH,
ID_CE_EXT_KEY_USAGE, ID_CE_SUBJECT_ALT_NAME, ID_KP_CLIENT_AUTH, ID_KP_SERVER_AUTH,
};
use const_oid::db::rfc5912::ID_EXTENSION_REQ;
use der::asn1::{GeneralizedTime, Ia5StringRef, UIntRef};
#[cfg(debug_assertions)]
use der::asn1::GeneralizedTime;
use der::asn1::{Ia5StringRef, UIntRef};
use der::{Decode, Encode, Sequence};
use ext::kvm::Kvm;
use ext::sgx::Sgx;
Expand All @@ -48,7 +51,9 @@ use tower_http::LatencyUnit;
use tracing::{debug, Level};
use x509::attr::Attribute;
use x509::ext::pkix::name::GeneralName;
use x509::ext::pkix::{BasicConstraints, ExtendedKeyUsage, KeyUsage, KeyUsages, SubjectAltName};
#[cfg(debug_assertions)]
use x509::ext::pkix::{BasicConstraints, KeyUsage, KeyUsages};
use x509::ext::pkix::{ExtendedKeyUsage, SubjectAltName};
use x509::name::RdnSequence;
use x509::request::{CertReq, ExtensionReq};
use x509::time::{Time, Validity};
Expand Down Expand Up @@ -80,6 +85,7 @@ struct Args {
#[clap(short, long, env = "ROCKET_ADDRESS", default_value = "::")]
addr: IpAddr,

#[cfg(debug_assertions)]
#[clap(short, long, env = "RENDER_EXTERNAL_HOSTNAME")]
host: Option<String>,

Expand Down Expand Up @@ -141,11 +147,22 @@ impl State {

// Validate the syntax of the files.
PrivateKeyInfo::from_der(key.as_ref())?;
#[cfg(debug_assertions)]
Certificate::from_der(crt.as_ref())?;
#[cfg(not(debug_assertions))]
{
let cert = Certificate::from_der(crt.as_ref())?;
let iss = &cert.tbs_certificate;
if iss.issuer_unique_id == iss.subject_unique_id && iss.issuer == iss.subject {
// A self-signed certificate is not appropriate for Release mode.
return Err(anyhow!("invalid certificate"));
}
}

Ok(State { crt, san, key })
}

#[cfg(debug_assertions)]
pub fn generate(san: Option<String>, hostname: &str) -> anyhow::Result<Self> {
use const_oid::db::rfc5912::SECP_256_R_1 as P256;

Expand Down Expand Up @@ -219,6 +236,8 @@ async fn main() -> anyhow::Result<()> {
let args = confargs::args::<Toml>(prefix_char_filter::<'@'>)
.context("Failed to parse config")
.map(Args::parse_from)?;

#[cfg(debug_assertions)]
let state = match (args.key, args.crt, args.host) {
(None, None, Some(host)) => State::generate(args.san, &host)?,
(Some(key), Some(crt), _) => State::load(args.san, key, crt)?,
Expand All @@ -228,6 +247,15 @@ async fn main() -> anyhow::Result<()> {
}
};

#[cfg(not(debug_assertions))]
let state = match (args.key, args.crt) {
(Some(key), Some(crt)) => State::load(args.san, key, crt)?,
_ => {
eprintln!("Specify the public key `--crt` and private key `--key`.\nRun with `--help` for more information.");
return Err(anyhow!("invalid configuration"));
}
};

#[cfg(not(target_os = "wasi"))]
{
use std::net::SocketAddr;
Expand Down Expand Up @@ -316,6 +344,14 @@ fn attest_request(
StatusCode::BAD_REQUEST
})?;

let dbg = if cfg!(debug_assertions) {
// If the issuer is self-signed, we are in debug mode.
let iss = &issuer.tbs_certificate;
iss.issuer_unique_id == iss.subject_unique_id && iss.issuer == iss.subject
} else {
false
};

let mut extensions = Vec::new();
let mut attested = false;
for Attribute { oid, values } in info.attributes.iter() {
Expand All @@ -329,16 +365,11 @@ fn attest_request(
StatusCode::BAD_REQUEST
})?;
for ext in Vec::from(ereq) {
// If the issuer is self-signed, we are in debug mode.
let iss = &issuer.tbs_certificate;
let dbg = iss.issuer_unique_id == iss.subject_unique_id;
let dbg = dbg && iss.issuer == iss.subject;

// Validate the extension.
let (copy, att) = match ext.extn_id {
Kvm::OID => (Kvm::default().verify(&info, &ext, dbg), Kvm::ATT),
Sgx::OID => (Sgx::default().verify(&info, &ext, dbg), Sgx::ATT),
Snp::OID => (Snp::default().verify(&info, &ext, dbg), Snp::ATT),
Kvm::OID => (Kvm::default().verify(&info, &ext, &dbg), Kvm::ATT),
Sgx::OID => (Sgx::default().verify(&info, &ext, &dbg), Sgx::ATT),
Snp::OID => (Snp::default().verify(&info, &ext, &dbg), Snp::ATT),
oid => {
debug!("extension `{oid}` is unsupported");
return Err(StatusCode::BAD_REQUEST);
Expand Down

0 comments on commit 7778951

Please sign in to comment.