trz_gateway_common/security_configuration/certificate/
pem.rs1use std::sync::Arc;
2
3use nameth::NamedEnumValues as _;
4use nameth::nameth;
5use openssl::error::ErrorStack;
6use openssl::pkey::PKey;
7use openssl::x509::X509;
8
9use super::CertificateConfig;
10use super::X509CertificateInfo;
11use crate::certificate_info::CertificateInfo;
12use crate::security_configuration::common::parse_pem_certificates;
13
14#[nameth]
16#[derive(Clone, Default, PartialEq, Eq)]
17pub struct PemCertificate {
18 pub intermediates_pem: String,
19 pub certificate_pem: String,
20 pub private_key_pem: String,
21}
22
23impl CertificateConfig for PemCertificate {
24 type Error = PemCertificateError;
25
26 fn certificate(&self) -> Result<Arc<X509CertificateInfo>, Self::Error> {
27 let certificate = X509::from_pem(self.certificate_pem.as_bytes())
28 .map_err(PemCertificateError::InvalidLeafPemCertificate)?;
29 let private_key = PKey::private_key_from_pem(self.private_key_pem.as_bytes())
30 .map_err(PemCertificateError::InvalidPemPrivateKey)?;
31 Ok(X509CertificateInfo {
32 certificate,
33 private_key,
34 }
35 .into())
36 }
37
38 fn intermediates(&self) -> Result<Arc<Vec<X509>>, Self::Error> {
39 let mut intermediates = vec![];
40 for intermediate in parse_pem_certificates(&self.intermediates_pem) {
41 let intermediate =
42 intermediate.map_err(PemCertificateError::InvalidIntermediatePemCertificate)?;
43 intermediates.push(intermediate);
44 }
45 Ok(intermediates.into())
46 }
47}
48
49#[nameth]
50#[derive(thiserror::Error, Debug)]
51pub enum PemCertificateError {
52 #[error("[{n}] Invalid leaf PEM certificate: {0}", n = self.name())]
53 InvalidLeafPemCertificate(ErrorStack),
54
55 #[error("[{n}] Invalid intermediate PEM certificate: {0}", n = self.name())]
56 InvalidIntermediatePemCertificate(ErrorStack),
57
58 #[error("[{n}] Invalid X509 certificate: {0}", n = self.name())]
59 InvalidPemPrivateKey(ErrorStack),
60}
61
62impl From<CertificateInfo<String>> for PemCertificate {
66 fn from(value: CertificateInfo<String>) -> Self {
67 Self {
68 intermediates_pem: String::default(),
69 certificate_pem: value.certificate,
70 private_key_pem: value.private_key,
71 }
72 }
73}
74
75mod debug {
76 use std::fmt::Debug;
77 use std::fmt::Formatter;
78
79 use nameth::NamedType as _;
80
81 use super::PemCertificate;
82
83 impl Debug for PemCertificate {
84 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
85 f.debug_struct(PemCertificate::type_name()).finish()
86 }
87 }
88}