Skip to content

Commit 16bd20b

Browse files
sarroutbiansasaki
authored andcommitted
Set X509 SAN with local DNSname/IP/IPv6
Set X509 Subject Alternative Name with local DNS names (localhost, localhost.domain) and local IPs (127.0.0.1, ::1). It will also include the contact IP stored in configuration Resolves: #327 Signed-off-by: Sergio Arroutbi <[email protected]>
1 parent 9d4e406 commit 16bd20b

File tree

3 files changed

+69
-10
lines changed

3 files changed

+69
-10
lines changed

keylime-agent/src/main.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -586,10 +586,16 @@ async fn main() -> Result<()> {
586586
let mtls_cert;
587587
let ssl_context;
588588
if config.agent.enable_agent_mtls {
589+
let contact_ips = vec![config.agent.contact_ip.clone()];
589590
cert = match config.agent.server_cert.as_ref() {
590591
"" => {
591592
debug!("The server_cert option was not set in the configuration file");
592-
crypto::generate_x509(&nk_priv, &agent_uuid)?
593+
594+
crypto::generate_x509(
595+
&nk_priv,
596+
&agent_uuid,
597+
Some(contact_ips),
598+
)?
593599
}
594600
path => {
595601
let cert_path = Path::new(&path);
@@ -601,7 +607,11 @@ async fn main() -> Result<()> {
601607
crypto::load_x509_pem(cert_path)?
602608
} else {
603609
debug!("Generating new mTLS certificate");
604-
let cert = crypto::generate_x509(&nk_priv, &agent_uuid)?;
610+
let cert = crypto::generate_x509(
611+
&nk_priv,
612+
&agent_uuid,
613+
Some(contact_ips),
614+
)?;
605615
// Write the generated certificate
606616
crypto::write_x509(&cert, cert_path)?;
607617
cert

keylime-agent/src/registrar_agent.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,12 @@ mod tests {
233233

234234
let mock_data = [0u8; 1];
235235
let priv_key = crypto::testing::rsa_generate(2048).unwrap(); //#[allow_ci]
236-
let cert = crypto::generate_x509(&priv_key, "uuid").unwrap(); //#[allow_ci]
236+
let cert = crypto::generate_x509(
237+
&priv_key,
238+
"uuid",
239+
Some(vec!["1.2.3.4".to_string()]),
240+
)
241+
.unwrap(); //#[allow_ci]
237242
let response = do_register_agent(
238243
ip,
239244
port,
@@ -248,7 +253,7 @@ mod tests {
248253
None,
249254
None,
250255
Some(&cert),
251-
"",
256+
"1.2.3.4",
252257
0,
253258
)
254259
.await;
@@ -281,7 +286,12 @@ mod tests {
281286

282287
let mock_data = [0u8; 1];
283288
let priv_key = crypto::testing::rsa_generate(2048).unwrap(); //#[allow_ci]
284-
let cert = crypto::generate_x509(&priv_key, "uuid").unwrap(); //#[allow_ci]
289+
let cert = crypto::generate_x509(
290+
&priv_key,
291+
"uuid",
292+
Some(vec!["1.2.3.4".to_string(), "1.2.3.5".to_string()]),
293+
)
294+
.unwrap(); //#[allow_ci]
285295
let response = do_register_agent(
286296
ip,
287297
port,
@@ -325,7 +335,7 @@ mod tests {
325335

326336
let mock_data = [0u8; 1];
327337
let priv_key = crypto::testing::rsa_generate(2048).unwrap(); //#[allow_ci]
328-
let cert = crypto::generate_x509(&priv_key, "uuid").unwrap(); //#[allow_ci]
338+
let cert = crypto::generate_x509(&priv_key, "uuid", None).unwrap(); //#[allow_ci]
329339
let response = do_register_agent(
330340
ip,
331341
port,

keylime/src/crypto.rs

+43-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use openssl::{
1717
ssl::{SslAcceptor, SslAcceptorBuilder, SslMethod, SslVerifyMode},
1818
symm::Cipher,
1919
x509::store::X509StoreBuilder,
20-
x509::{X509Name, X509},
20+
x509::{extension, X509Name, X509},
2121
};
2222
use picky_asn1_x509::SubjectPublicKeyInfo;
2323
use std::{
@@ -33,6 +33,9 @@ pub const AES_128_KEY_LEN: usize = 16;
3333
pub const AES_256_KEY_LEN: usize = 32;
3434
pub const AES_BLOCK_SIZE: usize = 16;
3535

36+
static LOCAL_IPS: &[&str] = &["127.0.0.1", "::1"];
37+
static LOCAL_DNS_NAMES: &[&str] = &["localhost", "localhost.domain"];
38+
3639
#[derive(Error, Debug)]
3740
pub enum CryptoError {
3841
/// Error getting ASN.1 Time from days from now
@@ -673,6 +676,7 @@ pub fn pkey_pub_to_pem(pubkey: &PKey<Public>) -> Result<String, CryptoError> {
673676
pub fn generate_x509(
674677
key: &PKey<Private>,
675678
uuid: &str,
679+
additional_ips: Option<Vec<String>>,
676680
) -> Result<X509, CryptoError> {
677681
let mut name =
678682
X509Name::builder().map_err(|source| CryptoError::X509NameError {
@@ -725,7 +729,7 @@ pub fn generate_x509(
725729
})?;
726730
builder.set_not_after(&valid_to).map_err(|source| {
727731
CryptoError::X509BuilderError {
728-
message: "failed to set X509 certificate Nof After date".into(),
732+
message: "failed to set X509 certificate Not After date".into(),
729733
source,
730734
}
731735
})?;
@@ -735,6 +739,37 @@ pub fn generate_x509(
735739
source,
736740
}
737741
})?;
742+
let mut san = &mut extension::SubjectAlternativeName::new();
743+
for local_domain_name in LOCAL_DNS_NAMES.iter() {
744+
san = san.dns(local_domain_name);
745+
}
746+
for local_ip in LOCAL_IPS.iter() {
747+
san = san.ip(local_ip);
748+
}
749+
match additional_ips {
750+
None => {}
751+
Some(ips) => {
752+
for ip in ips.iter() {
753+
if !LOCAL_IPS.iter().any(|e| ip.contains(e)) {
754+
san = san.ip(ip);
755+
}
756+
}
757+
}
758+
}
759+
let x509 =
760+
san.build(&builder.x509v3_context(None, None))
761+
.map_err(|source| CryptoError::X509BuilderError {
762+
message: "failed to build Subject Alternative Name".into(),
763+
source,
764+
})?;
765+
builder.append_extension(x509).map_err(|source| {
766+
CryptoError::X509BuilderError {
767+
message:
768+
"failed to append X509 certificate Subject Alternative Name extension"
769+
.into(),
770+
source,
771+
}
772+
})?;
738773
builder
739774
.sign(key, MessageDigest::sha256())
740775
.map_err(|source| CryptoError::X509BuilderError {
@@ -1439,15 +1474,19 @@ mod tests {
14391474
fn test_x509(privkey: PKey<Private>, pubkey: PKey<Public>) {
14401475
let tempdir = tempfile::tempdir().unwrap(); //#[allow_ci]
14411476

1442-
let r = generate_x509(&privkey, "uuidA");
1477+
let r = generate_x509(&privkey, "uuidA", None);
14431478
assert!(r.is_ok());
14441479
let cert_a = r.unwrap(); //#[allow_ci]
14451480
let cert_a_path = tempdir.path().join("cert_a.pem");
14461481
let r = write_x509(&cert_a, &cert_a_path);
14471482
assert!(r.is_ok());
14481483
assert!(cert_a_path.exists());
14491484

1450-
let r = generate_x509(&privkey, "uuidB");
1485+
let r = generate_x509(
1486+
&privkey,
1487+
"uuidB",
1488+
Some(vec!["1.2.3.4".to_string(), "1.2.3.5".to_string()]),
1489+
);
14511490
assert!(r.is_ok());
14521491
let cert_b = r.unwrap(); //#[allow_ci]
14531492
let cert_b_path = tempdir.path().join("cert_b.pem");

0 commit comments

Comments
 (0)