Skip to content

Commit

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

- Adding fixes per Tyler's suggestions

Signed-off-by: Larry Dewey <larry.dewey@amd.com>
  • Loading branch information
larrydewey committed Jul 29, 2024
1 parent 5c50a8a commit a99b0fd
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 2 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 = "3.3.0"
authors = [
"Nathaniel McCallum <npmccallum@redhat.com>",
"The VirTEE Project Developers",
Expand Down
73 changes: 73 additions & 0 deletions src/certs/snp/ca/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
#[cfg(feature = "openssl")]
use openssl::x509::X509;

use super::*;

Expand Down Expand Up @@ -29,6 +31,77 @@ impl<'a> Verifiable for &'a Chain {
}
}

#[cfg(feature = "openssl")]
impl From<(X509, X509)> for Chain {
/// Assumes the structure of ASK/ARK or ASVK/ARK
fn from(value: (X509, X509)) -> Self {
Self {
ark: value.1.into(),
ask: value.0.into(),
}
}
}

#[cfg(feature = "openssl")]
impl From<(&X509, &X509)> for Chain {
/// Assumes the structure of &ASK/&ARK or &ASVK/&ARK
fn from(value: (&X509, &X509)) -> Self {
(value.0.clone(), value.1.clone()).into()
}
}

#[cfg(feature = "openssl")]
impl<'a: 'b, 'b> From<&'a Chain> for (&'b X509, &'b X509) {
/// Will always assume the tuple type to be (&ASK, &ARK) or (&ASVK, &ARK).
fn from(value: &'a Chain) -> Self {
((&value.ask).into(), (&value.ark).into())
}
}

#[cfg(feature = "openssl")]
impl From<&[X509]> for Chain {
/// Will only retrieve the first two certificates, ignoring the rest. Also
/// assumes the structure to be (&ASK, &ARK) or (&ASVK, &ARK)
fn from(value: &[X509]) -> Self {
(&value[0], &value[1]).into()
}
}

impl From<(Certificate, Certificate)> for Chain {
/// Assumes the structure of ASK/ARK or ASVK/ARK
fn from(value: (Certificate, Certificate)) -> Self {
Self {
ark: value.1,
ask: value.0,
}
}
}

impl From<(&Certificate, &Certificate)> for Chain {
/// Assumes the structure of &ASK/&ARK or &ASVK/&ARK
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) {
/// Will always assume the tuple type to be (&ASK, &ARK) or (&ASVK, &ARK).
fn from(value: &'a Chain) -> Self {
(&value.ask, &value.ark)
}
}

impl From<&[Certificate]> for Chain {
/// Will only retrieve the first two certificates, ignoring the rest. Also
/// assumes the structure to be (&ASK, &ARK) or (&ASVK, &ARK)
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
19 changes: 19 additions & 0 deletions src/certs/snp/cert.rs
Original file line number Diff line number Diff line change
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
86 changes: 86 additions & 0 deletions src/certs/snp/chain.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// SPDX-License-Identifier: Apache-2.0

#[cfg(feature = "openssl")]
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 +41,88 @@ enum ChainEncodingFormat {
Pem,
}

#[cfg(feature = "openssl")]
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(),
}
}
}

#[cfg(feature = "openssl")]
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).into(),
(&value.ca.ark).into(),
(&value.vek).into(),
)
}
}

#[cfg(feature = "openssl")]
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 {
Self {
ca: ca::Chain {
ark: value.1,
ask: value.0,
},
vek: value.2,
}
}
}

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

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[0].clone(), value[1].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 a99b0fd

Please sign in to comment.