Skip to content

Commit

Permalink
WIP: Set X509 SAN with local DNSname/ip
Browse files Browse the repository at this point in the history
Set X509 Subject Alternative Name with local
DNS names (localhost, localhost.domain) and
local IPs (127.0.0.1, ::1)

Resolves: #327

Signed-off-by: Sergio Arroutbi <sarroutb@redhat.com>
  • Loading branch information
sarroutbi committed Feb 15, 2024
1 parent 1501cf1 commit 6fd08a6
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
37 changes: 33 additions & 4 deletions keylime-agent/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use openssl::{
ssl::{SslAcceptor, SslAcceptorBuilder, SslMethod, SslVerifyMode},
symm::Cipher,
x509::store::X509StoreBuilder,
x509::{X509Name, X509},
x509::{extension, X509Name, X509},
};
use picky_asn1_x509::SubjectPublicKeyInfo;
use std::{
Expand All @@ -31,6 +31,9 @@ use crate::{
Error, Result, AES_128_KEY_LEN, AES_256_KEY_LEN, AES_BLOCK_SIZE,
};

static LOCAL_IPS: &[&str] = &["127.0.0.1", "::1"];
static LOCAL_DNS_NAMES: &[&str] = &["localhost", "localhost.domain"];

// Read a X509 cert in DER format from path
pub(crate) fn load_x509_der(input_cert_path: &Path) -> Result<X509> {
let contents = std::fs::read(input_cert_path).map_err(Error::from)?;
Expand Down Expand Up @@ -251,7 +254,11 @@ pub(crate) fn pkey_pub_to_pem(pubkey: &PKey<Public>) -> Result<String> {
.and_then(|s| String::from_utf8(s).map_err(Error::from))
}

pub(crate) fn generate_x509(key: &PKey<Private>, uuid: &str) -> Result<X509> {
pub(crate) fn generate_x509(
key: &PKey<Private>,
uuid: &str,
additional_ips: Option<Vec<String>>,
) -> Result<X509> {
let mut name = X509Name::builder()?;
name.append_entry_by_nid(Nid::COMMONNAME, uuid)?;
let name = name.build();
Expand All @@ -266,6 +273,27 @@ pub(crate) fn generate_x509(key: &PKey<Private>, uuid: &str) -> Result<X509> {
builder.set_not_before(&valid_from)?;
builder.set_not_after(&valid_to)?;
builder.set_pubkey(key)?;

let mut san = &mut extension::SubjectAlternativeName::new();
for local_domain_name in LOCAL_DNS_NAMES.iter() {
san = san.dns(local_domain_name);
}
for local_ip in LOCAL_IPS.iter() {
san = san.ip(local_ip);
}
match additional_ips {
None => {}
Some(ips) => {
for ip in ips.iter() {
if !LOCAL_IPS.iter().any(|e| ip.contains(e)) {
san = san.ip(ip);
}
}
}
}
let x509 = san.build(&builder.x509v3_context(None, None))?;
builder.append_extension(x509)?;

builder.sign(key, MessageDigest::sha256())?;

Ok(builder.build())
Expand Down Expand Up @@ -774,15 +802,16 @@ mod tests {

let (pubkey, privkey) = rsa_generate_pair(2048).unwrap(); //#[allow_ci]

let r = generate_x509(&privkey, "uuidA");
let r = generate_x509(&privkey, "uuidA", None);
assert!(r.is_ok());
let cert_a = r.unwrap(); //#[allow_ci]
let cert_a_path = tempdir.path().join("cert_a.pem");
let r = write_x509(&cert_a, &cert_a_path);
assert!(r.is_ok());
assert!(cert_a_path.exists());

let r = generate_x509(&privkey, "uuidB");
let contact_ips = vec!["1.2.3.4".to_string(), "1.2.3.5".to_string()];
let r = generate_x509(&privkey, "uuidB", Some(contact_ips));
assert!(r.is_ok());
let cert_b = r.unwrap(); //#[allow_ci]
let cert_b_path = tempdir.path().join("cert_b.pem");
Expand Down
14 changes: 12 additions & 2 deletions keylime-agent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,16 @@ async fn main() -> Result<()> {
let mtls_cert;
let ssl_context;
if config.agent.enable_agent_mtls {
let contact_ips = vec![config.agent.contact_ip.clone()];
cert = match config.agent.server_cert.as_ref() {
"" => {
debug!("The server_cert option was not set in the configuration file");
crypto::generate_x509(&nk_priv, &agent_uuid)?

crypto::generate_x509(
&nk_priv,
&agent_uuid,
Some(contact_ips),
)?
}
path => {
let cert_path = Path::new(&path);
Expand All @@ -602,7 +608,11 @@ async fn main() -> Result<()> {
crypto::load_x509(cert_path)?
} else {
debug!("Generating new mTLS certificate");
let cert = crypto::generate_x509(&nk_priv, &agent_uuid)?;
let cert = crypto::generate_x509(
&nk_priv,
&agent_uuid,
Some(contact_ips),
)?;
// Write the generated certificate
crypto::write_x509(&cert, cert_path)?;
cert
Expand Down
11 changes: 7 additions & 4 deletions keylime-agent/src/registrar_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,10 @@ mod tests {

let mock_data = [0u8; 1];
let priv_key = crypto::testing::rsa_generate(2048).unwrap(); //#[allow_ci]
let cert = crypto::generate_x509(&priv_key, "uuid").unwrap(); //#[allow_ci]
let contact_ips = vec!["1.2.3.4".to_string()];
let cert =
crypto::generate_x509(&priv_key, "uuid", Some(contact_ips))
.unwrap(); //#[allow_ci]
let response = do_register_agent(
ip,
port,
Expand All @@ -248,7 +251,7 @@ mod tests {
None,
None,
Some(&cert),
"",
"1.2.3.4",
0,
)
.await;
Expand Down Expand Up @@ -281,7 +284,7 @@ mod tests {

let mock_data = [0u8; 1];
let priv_key = crypto::testing::rsa_generate(2048).unwrap(); //#[allow_ci]
let cert = crypto::generate_x509(&priv_key, "uuid").unwrap(); //#[allow_ci]
let cert = crypto::generate_x509(&priv_key, "uuid", None).unwrap(); //#[allow_ci]
let response = do_register_agent(
ip,
port,
Expand Down Expand Up @@ -325,7 +328,7 @@ mod tests {

let mock_data = [0u8; 1];
let priv_key = crypto::testing::rsa_generate(2048).unwrap(); //#[allow_ci]
let cert = crypto::generate_x509(&priv_key, "uuid").unwrap(); //#[allow_ci]
let cert = crypto::generate_x509(&priv_key, "uuid", None).unwrap(); //#[allow_ci]
let response = do_register_agent(
ip,
port,
Expand Down

0 comments on commit 6fd08a6

Please sign in to comment.