1mod validations;
4
5use crate::cert::errors::{CertificateError, PrivateKeyError};
6use crate::cert::parsing::to_certificate_vec;
7use crate::cert::{Certificate, PrivateKey};
8use crate::spiffe_id::{SpiffeId, SpiffeIdError};
9use crate::svid::x509::validations::{validate_leaf_certificate, validate_signing_certificates};
10use crate::svid::Svid;
11use std::convert::TryFrom;
12
13#[derive(Debug, Clone, Eq, PartialEq)]
18pub struct X509Svid {
19 spiffe_id: SpiffeId,
20 cert_chain: Vec<Certificate>,
21 private_key: PrivateKey,
22}
23
24impl Svid for X509Svid {}
25
26#[derive(Debug, thiserror::Error, PartialEq)]
29#[non_exhaustive]
30pub enum X509SvidError {
31 #[error("no certificates found in chain")]
33 EmptyChain,
34
35 #[error("leaf certificate must not have CA flag set to true")]
37 LeafCertificateHasCaFlag,
38
39 #[error("leaf certificate must not have 'cRLSign' set as key usage")]
41 LeafCertificateHasCrlSign,
42
43 #[error("leaf certificate must not have 'keyCertSign' set as key usage")]
45 LeafCertificateHasKeyCertSign,
46
47 #[error("leaf certificate must have 'digitalSignature' set as key usage")]
49 LeafCertificatedNoDigitalSignature,
50
51 #[error("signing certificate must have CA flag set to true")]
53 SigningCertificatedNoCa,
54
55 #[error("signing certificate must have 'keyCertSign' set as key usage")]
57 SigningCertificatedNoKeyCertSign,
58
59 #[error("leaf certificate misses the SPIFFE-ID in the URI SAN")]
61 MissingSpiffeId,
62
63 #[error("failed parsing SPIFFE ID from certificate URI SAN")]
65 InvalidSpiffeId(#[from] SpiffeIdError),
66
67 #[error(transparent)]
69 Certificate(#[from] CertificateError),
70
71 #[error(transparent)]
73 PrivateKey(#[from] PrivateKeyError),
74}
75
76impl X509Svid {
77 pub fn parse_from_der(
90 cert_chain_der: &[u8],
91 private_key_der: &[u8],
92 ) -> Result<Self, X509SvidError> {
93 let cert_chain = to_certificate_vec(cert_chain_der)?;
94
95 let leaf = match cert_chain.first() {
96 None => return Err(X509SvidError::EmptyChain),
97 Some(c) => c,
98 };
99
100 let spiffe_id = validate_leaf_certificate(leaf)?;
101 validate_signing_certificates(&cert_chain[1..])?;
102 let private_key = PrivateKey::try_from(private_key_der)?;
103
104 Ok(X509Svid {
105 spiffe_id,
106 cert_chain,
107 private_key,
108 })
109 }
110
111 pub fn spiffe_id(&self) -> &SpiffeId {
113 &self.spiffe_id
114 }
115
116 pub fn cert_chain(&self) -> &Vec<Certificate> {
119 &self.cert_chain
120 }
121
122 pub fn leaf(&self) -> &Certificate {
124 &self.cert_chain[0]
125 }
126
127 pub fn private_key(&self) -> &PrivateKey {
129 &self.private_key
130 }
131}