-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathconvert.rs
More file actions
87 lines (78 loc) · 2.55 KB
/
Copy pathconvert.rs
File metadata and controls
87 lines (78 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use openssl::{pkcs12::Pkcs12, pkey::PKey, stack::Stack, x509::X509};
use snafu::{ResultExt, Snafu};
use stackable_secret_operator_utils::{
pem::split_pem_certificates,
pkcs12::{TlsToPkcs12Error, pkcs12_truststore},
};
use super::{
SecretFormat, WellKnownSecretData,
well_known::{CompatibilityOptions, TlsPem, TlsPkcs12},
};
pub fn convert(
from: WellKnownSecretData,
to: SecretFormat,
compat: CompatibilityOptions,
) -> Result<WellKnownSecretData, ConvertError> {
match (from, to) {
// Converting into the current format is always a no-op
(from, to) if SecretFormat::from(&from) == to => Ok(from),
(WellKnownSecretData::TlsPem(pem), SecretFormat::TlsPkcs12) => {
Ok(WellKnownSecretData::TlsPkcs12(convert_tls_to_pkcs12(
pem,
compat
.tls_pkcs12_password
.as_deref()
.map_or("", String::as_str),
)?))
}
(from, to) => NoValidConversionSnafu { from, to }.fail(),
}
}
#[derive(Snafu, Debug)]
pub enum ConvertError {
#[snafu(display("no conversion defined from {from:?} to {to:?}"))]
NoValidConversion {
from: SecretFormat,
to: SecretFormat,
},
#[snafu(
display("failed to convert from PEM certificate to PKCS#12"),
context(false)
)]
TlsToPkcs12 { source: TlsToPkcs12Error },
}
pub fn convert_tls_to_pkcs12(
pem: TlsPem,
p12_password: &str,
) -> Result<TlsPkcs12, TlsToPkcs12Error> {
use stackable_secret_operator_utils::pkcs12::tls_to_pkcs12_error::*;
let cert = pem
.certificate_pem
.map(|cert| X509::from_pem(&cert).context(LoadCertSnafu))
.transpose()?;
let key = pem
.key_pem
.map(|key| PKey::private_key_from_pem(&key).context(LoadKeySnafu))
.transpose()?;
let mut ca_stack = Stack::<X509>::new().context(LoadCaSnafu)?;
for ca in split_pem_certificates(&pem.ca_pem) {
X509::from_pem(ca)
.and_then(|ca| ca_stack.push(ca))
.context(LoadCertSnafu)?;
}
Ok(TlsPkcs12 {
truststore: pkcs12_truststore(&ca_stack, p12_password)?,
keystore: cert
.zip(key)
.map(|(cert, key)| {
Pkcs12::builder()
.ca(ca_stack)
.cert(&cert)
.pkey(&key)
.build2(p12_password)
.and_then(|store| store.to_der())
.context(BuildKeystoreSnafu)
})
.transpose()?,
})
}