Skip to content

Commit

Permalink
validation: add Rust-side certificate validation helpers (#9757)
Browse files Browse the repository at this point in the history
* validation: add Rust-side certificate validation helpers

* rust: Add unit test for certification validation helpers

* rust: Add comment explaining why we're allowing dead code

* rust: Get remaining coverage for self-issued case

* rust: Add test case for when we fail to retrieve public key

* rust: Rename tests to be less verbose

* rust: Get remaining coverage in `PublicKeyErrorOps`
  • Loading branch information
tetsuo-cpp authored Oct 26, 2023
1 parent 1cb847a commit 16a969e
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
109 changes: 109 additions & 0 deletions src/rust/cryptography-x509-validation/src/certificate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// This file is dual licensed under the terms of the Apache License, Version
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

//! Validation-specific certificate functionality.
use cryptography_x509::certificate::Certificate;

use crate::ops::CryptoOps;

// TODO: Remove these attributes once we start using these helpers.
#[allow(dead_code)]
pub(crate) fn cert_is_self_issued(cert: &Certificate<'_>) -> bool {
cert.issuer() == cert.subject()
}

#[allow(dead_code)]
pub(crate) fn cert_is_self_signed<B: CryptoOps>(cert: &Certificate<'_>, ops: &B) -> bool {
match ops.public_key(cert) {
Ok(pk) => cert_is_self_issued(cert) && ops.verify_signed_by(cert, pk).is_ok(),
Err(_) => false,
}
}

#[cfg(test)]
mod tests {
use crate::certificate::Certificate;
use crate::ops::tests::{cert, v1_cert_pem, NullOps};
use crate::ops::CryptoOps;

use super::{cert_is_self_issued, cert_is_self_signed};

#[test]
fn test_certificate_v1() {
let cert_pem = v1_cert_pem();
let cert = cert(&cert_pem);
let ops = NullOps {};

assert!(!cert_is_self_issued(&cert));
assert!(!cert_is_self_signed(&cert, &ops));
}

fn ca_pem() -> pem::Pem {
// From vectors/cryptography_vectors/x509/custom/ca/ca.pem
pem::parse(
"-----BEGIN CERTIFICATE-----
MIIBUTCB96ADAgECAgIDCTAKBggqhkjOPQQDAjAnMQswCQYDVQQGEwJVUzEYMBYG
A1UEAwwPY3J5cHRvZ3JhcGh5IENBMB4XDTE3MDEwMTEyMDEwMFoXDTM4MTIzMTA4
MzAwMFowJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeSBDQTBZ
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABBj/z7v5Obj13cPuwECLBnUGq0/N2CxS
JE4f4BBGZ7VfFblivTvPDG++Gve0oQ+0uctuhrNQ+WxRv8GC177F+QWjEzARMA8G
A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhANES742XWm64tkGnz8Dn
pG6u2lHkZFQr3oaVvPcemvlbAiEA0WGGzmYx5C9UvfXIK7NEziT4pQtyESE0uRVK
Xw4nMqk=
-----END CERTIFICATE-----",
)
.unwrap()
}

#[test]
fn test_certificate_ca() {
let cert_pem = ca_pem();
let cert = cert(&cert_pem);
let ops = NullOps {};

assert!(cert_is_self_issued(&cert));
assert!(cert_is_self_signed(&cert, &ops));
}

struct PublicKeyErrorOps {}
impl CryptoOps for PublicKeyErrorOps {
type Key = ();
type Err = ();

fn public_key(&self, _cert: &Certificate<'_>) -> Result<Self::Key, Self::Err> {
// Simulate failing to retrieve a public key.
Err(())
}

fn verify_signed_by(
&self,
_cert: &Certificate<'_>,
_key: Self::Key,
) -> Result<(), Self::Err> {
Ok(())
}
}

#[test]
fn test_certificate_public_key_error() {
let cert_pem = ca_pem();
let cert = cert(&cert_pem);
let ops = PublicKeyErrorOps {};

assert!(cert_is_self_issued(&cert));
assert!(!cert_is_self_signed(&cert, &ops));
}

#[test]
fn test_certificate_public_key_error_ops() {
// Just to get coverage on the `PublicKeyErrorOps` helper.
let cert_pem = ca_pem();
let cert = cert(&cert_pem);
let ops = PublicKeyErrorOps {};

assert!(ops.public_key(&cert).is_err());
assert!(ops.verify_signed_by(&cert, ()).is_ok());
}
}
1 change: 1 addition & 0 deletions src/rust/cryptography-x509-validation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#![forbid(unsafe_code)]
#![deny(rust_2018_idioms, clippy::undocumented_unsafe_blocks)]

pub mod certificate;
pub mod ops;
pub mod policy;
pub mod trust_store;
Expand Down

0 comments on commit 16a969e

Please sign in to comment.