Skip to content

Commit

Permalink
chore: refactor test certs, unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Zak <richard@profian.com>
  • Loading branch information
rjzak authored and rvolosatovs committed Jun 29, 2022
1 parent 5b324f3 commit ed234c3
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 112 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ toml = { version = "0.5.9", default-features = false }

[dev-dependencies]
tower = { version = "^0.4.11", features = ["util"] }
axum = "^0.5.1"
http = "^0.2.6"
memoffset = "0.6.4"
testaso = "0.1"
Expand Down
Binary file removed certs/test/crt.der
Binary file not shown.
Binary file removed certs/test/key.der
Binary file not shown.
156 changes: 117 additions & 39 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct Args {
}

#[derive(Debug)]
#[cfg_attr(test, derive(Clone))]
struct State {
key: Zeroizing<Vec<u8>>,
crt: Vec<u8>,
Expand Down Expand Up @@ -364,19 +365,17 @@ mod tests {
use x509::request::CertReqInfo;
use x509::{ext::Extension, name::RdnSequence};

use axum::response::Response;
use http::{header::CONTENT_TYPE, Request};
use hyper::Body;
use tower::ServiceExt; // for `app.oneshot()`

const CRT: &[u8] = include_bytes!("../certs/test/crt.der");
const KEY: &[u8] = include_bytes!("../certs/test/key.der");
fn certificates_state() -> State {
State::load(None, "testdata/ca.key", "testdata/ca.crt").unwrap()
}

fn state() -> State {
State {
key: KEY.to_owned().into(),
crt: CRT.into(),
san: None,
}
fn hostname_state() -> State {
State::generate(None, "localhost").unwrap()
}

fn cr(curve: ObjectIdentifier, exts: Vec<Extension<'_>>) -> Vec<u8> {
Expand All @@ -403,6 +402,15 @@ mod tests {
cri.sign(&pki).unwrap()
}

async fn attest_response(state: State, response: Response) {
let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
let path = PkiPath::from_der(&body).unwrap();
let issr = Certificate::from_der(&state.crt).unwrap();
assert_eq!(2, path.0.len());
assert_eq!(issr, path.0[0]);
issr.tbs_certificate.verify_crt(&path.0[1]).unwrap();
}

#[test]
fn reencode() {
let encoded = cr(SECP_256_R_1, vec![]);
Expand All @@ -418,7 +426,7 @@ mod tests {
}

#[tokio::test]
async fn kvm() {
async fn kvm_certs() {
let ext = Extension {
extn_id: Kvm::OID,
critical: false,
Expand All @@ -432,19 +440,59 @@ mod tests {
.body(Body::from(cr(SECP_256_R_1, vec![ext])))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
attest_response(certificates_state(), response).await;
}

let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
let path = PkiPath::from_der(&body).unwrap();
let issr = Certificate::from_der(CRT).unwrap();
assert_eq!(2, path.0.len());
assert_eq!(issr, path.0[0]);
issr.tbs_certificate.verify_crt(&path.0[1]).unwrap();
#[tokio::test]
async fn kvm_hostname() {
let ext = Extension {
extn_id: Kvm::OID,
critical: false,
extn_value: &[],
};

let request = Request::builder()
.method("POST")
.uri("/")
.header(CONTENT_TYPE, PKCS10)
.body(Body::from(cr(SECP_256_R_1, vec![ext])))
.unwrap();

let state = hostname_state();
let response = app(state.clone()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
attest_response(state, response).await;
}

#[tokio::test]
async fn sgx_certs() {
for quote in [
include_bytes!("ext/sgx/quote.unknown").as_slice(),
include_bytes!("ext/sgx/quote.icelake").as_slice(),
] {
let ext = Extension {
extn_id: Sgx::OID,
critical: false,
extn_value: quote,
};

let request = Request::builder()
.method("POST")
.uri("/")
.header(CONTENT_TYPE, PKCS10)
.body(Body::from(cr(SECP_256_R_1, vec![ext])))
.unwrap();

let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
attest_response(certificates_state(), response).await;
}
}

#[tokio::test]
async fn sgx() {
async fn sgx_hostname() {
for quote in [
include_bytes!("ext/sgx/quote.unknown").as_slice(),
include_bytes!("ext/sgx/quote.icelake").as_slice(),
Expand All @@ -462,20 +510,42 @@ mod tests {
.body(Body::from(cr(SECP_256_R_1, vec![ext])))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let state = hostname_state();
let response = app(state.clone()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
attest_response(state, response).await;
}
}

let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
let path = PkiPath::from_der(&body).unwrap();
let issr = Certificate::from_der(CRT).unwrap();
assert_eq!(2, path.0.len());
assert_eq!(issr, path.0[0]);
issr.tbs_certificate.verify_crt(&path.0[1]).unwrap();
#[tokio::test]
async fn snp_certs() {
let evidence = ext::snp::Evidence {
vcek: Certificate::from_der(include_bytes!("ext/snp/milan.vcek")).unwrap(),
report: include_bytes!("ext/snp/milan.rprt"),
}
.to_vec()
.unwrap();

let ext = Extension {
extn_id: Snp::OID,
critical: false,
extn_value: &evidence,
};

let request = Request::builder()
.method("POST")
.uri("/")
.header(CONTENT_TYPE, PKCS10)
.body(Body::from(cr(SECP_384_R_1, vec![ext])))
.unwrap();

let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
attest_response(certificates_state(), response).await;
}

#[tokio::test]
async fn snp() {
async fn snp_hostname() {
let evidence = ext::snp::Evidence {
vcek: Certificate::from_der(include_bytes!("ext/snp/milan.vcek")).unwrap(),
report: include_bytes!("ext/snp/milan.rprt"),
Expand All @@ -496,27 +566,35 @@ mod tests {
.body(Body::from(cr(SECP_384_R_1, vec![ext])))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let state = hostname_state();
let response = app(state.clone()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
attest_response(state, response).await;
}

let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
let path = PkiPath::from_der(&body).unwrap();
let issr = Certificate::from_der(CRT).unwrap();
assert_eq!(2, path.0.len());
assert_eq!(issr, path.0[0]);
issr.tbs_certificate.verify_crt(&path.0[1]).unwrap();
#[tokio::test]
async fn err_no_attestation_certs() {
let request = Request::builder()
.method("POST")
.uri("/")
.header(CONTENT_TYPE, PKCS10)
.body(Body::from(cr(SECP_256_R_1, vec![])))
.unwrap();

let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
}

#[tokio::test]
async fn err_no_attestation() {
async fn err_no_attestation_hostname() {
let request = Request::builder()
.method("POST")
.uri("/")
.header(CONTENT_TYPE, PKCS10)
.body(Body::from(cr(SECP_256_R_1, vec![])))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let response = app(hostname_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
}

Expand All @@ -528,7 +606,7 @@ mod tests {
.body(Body::from(cr(SECP_256_R_1, vec![])))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}

Expand All @@ -541,7 +619,7 @@ mod tests {
.body(Body::from(cr(SECP_256_R_1, vec![])))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}

Expand All @@ -554,7 +632,7 @@ mod tests {
.body(Body::empty())
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}

Expand All @@ -567,7 +645,7 @@ mod tests {
.body(Body::from(vec![0x01, 0x02, 0x03, 0x04]))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}

Expand All @@ -584,7 +662,7 @@ mod tests {
.body(Body::from(cr))
.unwrap();

let response = app(state()).oneshot(request).await.unwrap();
let response = app(certificates_state()).oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}
}
Expand Down
1 change: 0 additions & 1 deletion testdata/ca.srl

This file was deleted.

15 changes: 0 additions & 15 deletions testdata/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,3 @@ printf "\nGenerating CA certificate\n"
openssl req -new -x509 -config ca.conf -key ca.key -out ca.crt
printf "\nCA "
openssl x509 -noout -text -in ca.crt

printf "\nGenerating Server key\n"
openssl ecparam -genkey -name prime256v1 | openssl pkcs8 -topk8 -nocrypt -out server.key
printf "\nServer "
openssl pkey -noout -text -in server.key

printf "\nGenerating Server Certificate Signing Request\n"
openssl req -new -config server.conf -key server.key -out server.csr
printf "\nServer "
openssl req -text -in server.csr

printf "\nGenerating Server Certificate\n"
openssl x509 -req -days 9999 -CAcreateserial -CA ca.crt -CAkey ca.key -in server.csr -out server.crt -extfile server.conf -extensions server_crt
printf "\nServer "
openssl x509 -noout -text -in server.crt
28 changes: 0 additions & 28 deletions testdata/server.conf

This file was deleted.

14 changes: 0 additions & 14 deletions testdata/server.crt

This file was deleted.

10 changes: 0 additions & 10 deletions testdata/server.csr

This file was deleted.

5 changes: 0 additions & 5 deletions testdata/server.key

This file was deleted.

0 comments on commit ed234c3

Please sign in to comment.