trz_gateway_common/x509/
common_fields.rs

1use axum::http::StatusCode;
2use nameth::NamedEnumValues as _;
3use nameth::nameth;
4use openssl::error::ErrorStack;
5use openssl::x509::X509Builder;
6use openssl::x509::X509NameRef;
7use openssl::x509::X509Ref;
8use openssl::x509::extension::AuthorityKeyIdentifier;
9use openssl::x509::extension::SubjectKeyIdentifier;
10use x509_parser::x509::X509Version;
11
12use super::serial_number::SetSerialNumberError;
13use super::serial_number::set_serial_number;
14use super::time::SystemToAsn1TimeError;
15use super::validity::Validity;
16use super::validity::ValidityError;
17use super::validity::set_validity;
18use crate::http_error::IsHttpError;
19
20pub fn set_common_fields(
21    builder: &mut X509Builder,
22    issuer_name: &X509NameRef,
23    subject_name: &X509NameRef,
24    validity: Validity,
25) -> Result<(), SetCommonFieldsError> {
26    builder
27        .set_version(X509Version::V3.0 as i32)
28        .map_err(SetCommonFieldsError::SetVersion)?;
29    builder
30        .set_subject_name(subject_name)
31        .map_err(SetCommonFieldsError::SetSubject)?;
32    builder
33        .set_issuer_name(issuer_name)
34        .map_err(SetCommonFieldsError::SetIssuer)?;
35    set_validity(builder, validity.try_into()?)?;
36    set_serial_number(builder)?;
37
38    (|| {
39        let skid = SubjectKeyIdentifier::new().build(&builder.x509v3_context(None, None))?;
40        builder.append_extension(skid)?;
41        Ok(())
42    })()
43    .map_err(SetCommonFieldsError::SubjectKeyIdentifier)?;
44
45    Ok(())
46}
47
48#[nameth]
49#[derive(thiserror::Error, Debug)]
50pub enum SetCommonFieldsError {
51    #[error("[{n}] Failed to set the X509 version: {0}", n = self.name())]
52    SetVersion(ErrorStack),
53
54    #[error("[{n}] Failed to set the subject name: {0}", n = self.name())]
55    SetSubject(ErrorStack),
56
57    #[error("[{n}] Failed to set the issuer name: {0}", n = self.name())]
58    SetIssuer(ErrorStack),
59
60    #[error("[{n}] {0}", n = self.name())]
61    ConvertValidity(#[from] ValidityError<SystemToAsn1TimeError>),
62
63    #[error("[{n}] {0}", n = self.name())]
64    SetValidity(#[from] ValidityError<ErrorStack>),
65
66    #[error("[{n}] {0}", n = self.name())]
67    SetSerialNumber(#[from] SetSerialNumberError),
68
69    #[error("[{n}] Failed to set SKID: {0}", n = self.name())]
70    SubjectKeyIdentifier(ErrorStack),
71}
72
73impl IsHttpError for SetCommonFieldsError {
74    fn status_code(&self) -> StatusCode {
75        StatusCode::INTERNAL_SERVER_ERROR
76    }
77}
78
79pub(super) fn set_akid(issuer: &X509Ref, builder: &mut X509Builder) -> Result<(), ErrorStack> {
80    let akid = AuthorityKeyIdentifier::new()
81        .issuer(true)
82        .keyid(true)
83        .build(&builder.x509v3_context(Some(issuer), None))?;
84    builder.append_extension(akid)?;
85    Ok(())
86}