Skip to content

Commit

Permalink
certs: Adding additional functionality.
Browse files Browse the repository at this point in the history
- Made X509 within Certificate pub.
- Added in a bunch of additional support for translating between
  `Certificate`, `openssl::X509`, `ca::Chain`, and `Chain`

Signed-off-by: Larry Dewey <[email protected]>
  • Loading branch information
larrydewey committed Jul 26, 2024
1 parent 5c50a8a commit 184de63
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sev"
version = "3.2.0"
version = "4.0.0"
authors = [
"Nathaniel McCallum <[email protected]>",
"The VirTEE Project Developers",
Expand Down
59 changes: 59 additions & 0 deletions src/certs/snp/ca/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: Apache-2.0

use openssl::x509::X509;

use super::*;

/// Operations for a Certificate Authority (CA) chain.
Expand Down Expand Up @@ -29,6 +31,63 @@ impl<'a> Verifiable for &'a Chain {
}
}

impl From<(X509, X509)> for Chain {
fn from(value: (X509, X509)) -> Self {
Self {
ark: value.1.into(),
ask: value.0.into(),
}
}
}

impl From<(&X509, &X509)> for Chain {
fn from(value: (&X509, &X509)) -> Self {
(value.0.clone(), value.1.clone()).into()
}
}

impl<'a: 'b, 'b> From<&'a Chain> for (&'b X509, &'b X509) {
fn from(value: &'a Chain) -> Self {
(&value.ask.0, &value.ark.0)
}
}

impl From<&[X509]> for Chain {
fn from(value: &[X509]) -> Self {
(&value[0], &value[1]).into()
}
}

impl From<(Certificate, Certificate)> for Chain {
fn from(value: (Certificate, Certificate)) -> Self {
Self {
ark: value.1,
ask: value.0,
}
}
}

impl From<(&Certificate, &Certificate)> for Chain {
fn from(value: (&Certificate, &Certificate)) -> Self {
Self {
ark: value.1.clone(),
ask: value.0.clone(),
}
}
}

impl<'a: 'b, 'b> From<&'a Chain> for (&'b Certificate, &'b Certificate) {
fn from(value: &'a Chain) -> Self {
(&value.ask, &value.ark)
}
}

impl From<&[Certificate]> for Chain {
fn from(value: &[Certificate]) -> Self {
(&value[0], &value[1]).into()
}
}

impl Chain {
/// Deserialize a PEM-encoded ARK and ASK pair to a CA chain.
pub fn from_pem(ark: &[u8], ask: &[u8]) -> Result<Self> {
Expand Down
21 changes: 20 additions & 1 deletion src/certs/snp/cert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use openssl::x509::X509;
/// Structures/interfaces for SEV-SNP certificates.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Certificate(X509);
pub struct Certificate(pub X509);

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CertFormat {
Expand Down Expand Up @@ -59,6 +59,25 @@ impl From<&Certificate> for X509 {
}
}

impl From<&X509> for Certificate {
fn from(value: &X509) -> Self {
Self(value.clone())
}
}

impl From<&[X509]> for Certificate {
/// Retrieves only the first value from the hash, ignoring all other values.
fn from(value: &[X509]) -> Self {
value[0].clone().into()
}
}

impl<'a: 'b, 'b> From<&'a Certificate> for &'b X509 {
fn from(value: &'a Certificate) -> Self {
&value.0
}
}

/// Verify if the public key of one Certificate signs another Certificate.
impl Verifiable for (&Certificate, &Certificate) {
type Output = ();
Expand Down
66 changes: 66 additions & 0 deletions src/certs/snp/chain.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// SPDX-License-Identifier: Apache-2.0

use openssl::x509::X509;

use super::*;

use crate::firmware::host::{CertTableEntry, CertType};

/// Interfaces for a complete SEV-SNP certificate chain.
#[derive(Debug, Clone)]
pub struct Chain {
/// The Certificate Authority (CA) chain.
pub ca: ca::Chain,
Expand Down Expand Up @@ -37,6 +40,69 @@ enum ChainEncodingFormat {
Pem,
}

impl From<(X509, X509, X509)> for Chain {
/// Will presume the provided data is formated as (ASK,ARK,VCEK) or (ASVK,ARK,VLEK).
fn from(value: (X509, X509, X509)) -> Self {
Self {
ca: ca::Chain {
ark: value.1.into(),
ask: value.0.into(),
},
vek: value.2.into(),
}
}
}

impl<'a: 'b, 'b> From<&'a Chain> for (&'b X509, &'b X509, &'b X509) {
/// Will presume the provided data is formated as (ASK,ARK,VCEK) or (ASVK,ARK,VLEK).
fn from(value: &'a Chain) -> Self {
(&value.ca.ask.0, &value.ca.ark.0, &value.vek.0)
}
}

impl From<(&X509, &X509, &X509)> for Chain {
fn from(value: (&X509, &X509, &X509)) -> Self {
(value.0.clone(), value.1.clone(), value.2.clone()).into()
}
}

impl<'a: 'b, 'b> From<&'a Chain> for (&'b Certificate, &'b Certificate, &'b Certificate) {
fn from(value: &'a Chain) -> Self {
(&value.ca.ask, &value.ca.ark, &value.vek)
}
}

impl From<(Certificate, Certificate, Certificate)> for Chain {
fn from(value: (Certificate, Certificate, Certificate)) -> Self {
value.into()
}
}

impl From<(&Certificate, &Certificate, &Certificate)> for Chain {
fn from(value: (&Certificate, &Certificate, &Certificate)) -> Self {
value.into()
}
}

impl From<&Chain> for (Certificate, Certificate, Certificate) {
/// Will presume the user wants the format of (ASK,ARK,VCEK) or (ASVK,ARK,VLEK).
fn from(value: &Chain) -> Self {
(
value.ca.ask.clone(),
value.ca.ark.clone(),
value.vek.clone(),
)
}
}

impl From<&[Certificate]> for Chain {
/// Assumes the Format of ASK/ARK/VCEK or ASVK/ARK/VLEK. Any additional
/// certificates are ignored.
fn from(value: &[Certificate]) -> Self {
(value[1].clone(), value[0].clone(), value[2].clone()).into()
}
}

impl Chain {
/// Derive a chain from a DER-encoded FFI Certificate table.
pub fn from_cert_table_der(entries: Vec<CertTableEntry>) -> Result<Self> {
Expand Down

0 comments on commit 184de63

Please sign in to comment.