Skip to content

Commit 6cb24ac

Browse files
committed
Refactor code: Include AgentIdentity structure
Add agent_registration.rs to include all code relevant to this kind of operation Signed-off-by: Sergio Arroutbi <[email protected]>
1 parent 3b6c0ff commit 6cb24ac

File tree

2 files changed

+144
-91
lines changed

2 files changed

+144
-91
lines changed
+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2025 Keylime Authors
3+
use crate::config;
4+
use crate::error::{Error, Result};
5+
use base64::{engine::general_purpose, Engine as _};
6+
use keylime::{
7+
crypto::{self, x509::CertificateBuilder},
8+
registrar_client::RegistrarClientBuilder,
9+
tpm::{self, IAKResult, IDevIDResult},
10+
};
11+
use log::{error, info};
12+
use openssl::x509::X509;
13+
use tss_esapi::handles::KeyHandle;
14+
use tss_esapi::structures::PublicBuffer;
15+
use tss_esapi::traits::Marshall;
16+
17+
#[derive(Debug)]
18+
pub struct AgentRegistration {
19+
pub ak: tpm::AKResult,
20+
pub ek_result: tpm::EKResult,
21+
pub api_versions: Vec<String>,
22+
pub agent: config::AgentConfig,
23+
pub agent_uuid: String,
24+
pub mtls_cert: Option<X509>,
25+
pub device_id: Option<keylime::device_id::DeviceID>,
26+
pub attest: Option<tss_esapi::structures::Attest>,
27+
pub signature: Option<tss_esapi::structures::Signature>,
28+
pub ak_handle: KeyHandle,
29+
}
30+
31+
pub async fn register_agent(
32+
mut aa: AgentRegistration,
33+
mut ctx: &mut tpm::Context<'_>,
34+
) -> Result<()> {
35+
let iak_pub;
36+
let idevid_pub;
37+
let ak_pub = &PublicBuffer::try_from(aa.ak.public)?.marshall()?;
38+
let ek_pub =
39+
&PublicBuffer::try_from(aa.ek_result.public.clone())?.marshall()?;
40+
41+
// Create a RegistrarClientBuilder and set the parameters
42+
let mut builder = RegistrarClientBuilder::new()
43+
.ak_pub(ak_pub)
44+
.ek_pub(ek_pub)
45+
.enabled_api_versions(
46+
aa.api_versions.iter().map(|ver| ver.as_ref()).collect(),
47+
)
48+
.registrar_ip(aa.agent.registrar_ip.clone())
49+
.registrar_port(aa.agent.registrar_port)
50+
.uuid(&aa.agent_uuid)
51+
.ip(aa.agent.contact_ip.clone())
52+
.port(aa.agent.contact_port);
53+
54+
if let Some(mtls_cert) = aa.mtls_cert {
55+
builder = builder.mtls_cert(mtls_cert);
56+
}
57+
58+
// If the certificate is not None add it to the builder
59+
if let Some(ek_cert) = aa.ek_result.ek_cert {
60+
builder = builder.ek_cert(ek_cert);
61+
}
62+
63+
// Set the IAK/IDevID related fields, if enabled
64+
if aa.agent.enable_iak_idevid {
65+
let (Some(dev_id), Some(attest), Some(signature)) =
66+
(&aa.device_id, aa.attest, aa.signature)
67+
else {
68+
error!("IDevID and IAK are enabled but could not be generated");
69+
return Err(Error::Configuration(
70+
config::KeylimeConfigError::Generic(
71+
"IDevID and IAK are enabled but could not be generated"
72+
.to_string(),
73+
),
74+
));
75+
};
76+
77+
iak_pub =
78+
PublicBuffer::try_from(dev_id.iak_pubkey.clone())?.marshall()?;
79+
idevid_pub = PublicBuffer::try_from(dev_id.idevid_pubkey.clone())?
80+
.marshall()?;
81+
builder = builder
82+
.iak_attest(attest.marshall()?)
83+
.iak_sign(signature.marshall()?)
84+
.iak_pub(&iak_pub)
85+
.idevid_pub(&idevid_pub);
86+
87+
// If the IAK certificate was provided, set it
88+
if let Some(iak_cert) = dev_id.iak_cert.clone() {
89+
builder = builder.iak_cert(iak_cert);
90+
}
91+
92+
// If the IDevID certificate was provided, set it
93+
if let Some(idevid_cert) = dev_id.idevid_cert.clone() {
94+
builder = builder.idevid_cert(idevid_cert);
95+
}
96+
}
97+
98+
// Build the registrar client
99+
let mut registrar_client = builder.build().await?;
100+
101+
// Request keyblob material
102+
let keyblob = registrar_client.register_agent().await?;
103+
104+
info!("SUCCESS: Agent {} registered", &aa.agent_uuid);
105+
106+
let key = ctx.activate_credential(
107+
keyblob,
108+
aa.ak_handle,
109+
aa.ek_result.key_handle,
110+
)?;
111+
112+
// Flush EK if we created it
113+
if aa.agent.ek_handle.is_empty() {
114+
ctx.flush_context(aa.ek_result.key_handle.into())?;
115+
}
116+
117+
let mackey = general_purpose::STANDARD.encode(key.value());
118+
let auth_tag =
119+
crypto::compute_hmac(mackey.as_bytes(), aa.agent_uuid.as_bytes())?;
120+
let auth_tag = hex::encode(&auth_tag);
121+
122+
registrar_client.activate_agent(&auth_tag).await?;
123+
124+
info!("SUCCESS: Agent {} activated", &aa.agent_uuid);
125+
Ok(())
126+
}

keylime-agent/src/main.rs

+18-91
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#![allow(unused, missing_docs)]
3333

3434
mod agent_handler;
35+
mod agent_registration;
3536
mod api;
3637
mod common;
3738
mod config;
@@ -46,6 +47,7 @@ mod revocation;
4647
mod secure_mount;
4748

4849
use actix_web::{dev::Service, http, middleware, rt, web, App, HttpServer};
50+
use agent_registration::AgentRegistration;
4951
use base64::{engine::general_purpose, Engine as _};
5052
use clap::{Arg, Command as ClapApp};
5153
use common::*;
@@ -609,98 +611,23 @@ async fn main() -> Result<()> {
609611
warn!("mTLS disabled, Tenant and Verifier will reach out to agent via HTTP");
610612
}
611613

612-
{
613-
// Declare here as these must live longer than the builder
614-
let iak_pub;
615-
let idevid_pub;
616-
let ak_pub = &PublicBuffer::try_from(ak.public)?.marshall()?;
617-
let ek_pub =
618-
&PublicBuffer::try_from(ek_result.public.clone())?.marshall()?;
619-
620-
// Create a RegistrarClientBuilder and set the parameters
621-
let mut builder = RegistrarClientBuilder::new()
622-
.ak_pub(ak_pub)
623-
.ek_pub(ek_pub)
624-
.enabled_api_versions(
625-
api_versions.iter().map(|ver| ver.as_ref()).collect(),
626-
)
627-
.registrar_ip(config.agent.registrar_ip.clone())
628-
.registrar_port(config.agent.registrar_port)
629-
.uuid(&agent_uuid)
630-
.ip(config.agent.contact_ip.clone())
631-
.port(config.agent.contact_port);
632-
633-
if let Some(mtls_cert) = mtls_cert {
634-
builder = builder.mtls_cert(mtls_cert);
635-
}
636-
637-
// If the certificate is not None add it to the builder
638-
if let Some(ek_cert) = ek_result.ek_cert {
639-
builder = builder.ek_cert(ek_cert);
640-
}
641-
642-
// Set the IAK/IDevID related fields, if enabled
643-
if config.agent.enable_iak_idevid {
644-
let (Some(dev_id), Some(attest), Some(signature)) =
645-
(&device_id, attest, signature)
646-
else {
647-
error!(
648-
"IDevID and IAK are enabled but could not be generated"
649-
);
650-
return Err(Error::Configuration(config::KeylimeConfigError::Generic(
651-
"IDevID and IAK are enabled but could not be generated"
652-
.to_string(),
653-
)));
654-
};
655-
656-
iak_pub = PublicBuffer::try_from(dev_id.iak_pubkey.clone())?
657-
.marshall()?;
658-
idevid_pub =
659-
PublicBuffer::try_from(dev_id.idevid_pubkey.clone())?
660-
.marshall()?;
661-
builder = builder
662-
.iak_attest(attest.marshall()?)
663-
.iak_sign(signature.marshall()?)
664-
.iak_pub(&iak_pub)
665-
.idevid_pub(&idevid_pub);
666-
667-
// If the IAK certificate was provided, set it
668-
if let Some(iak_cert) = dev_id.iak_cert.clone() {
669-
builder = builder.iak_cert(iak_cert);
670-
}
671-
672-
// If the IDevID certificate was provided, set it
673-
if let Some(idevid_cert) = dev_id.idevid_cert.clone() {
674-
builder = builder.idevid_cert(idevid_cert);
675-
}
676-
}
677-
678-
// Build the registrar client
679-
let mut registrar_client = builder.build().await?;
680-
681-
// Request keyblob material
682-
let keyblob = registrar_client.register_agent().await?;
683-
684-
info!("SUCCESS: Agent {} registered", &agent_uuid);
685-
686-
let key = ctx.activate_credential(
687-
keyblob,
688-
ak_handle,
689-
ek_result.key_handle,
690-
)?;
691-
692-
// Flush EK if we created it
693-
if config.agent.ek_handle.is_empty() {
694-
ctx.flush_context(ek_result.key_handle.into())?;
614+
let aa = AgentRegistration {
615+
ak,
616+
ek_result,
617+
api_versions: api_versions.clone(),
618+
agent: config.agent.clone(),
619+
agent_uuid: agent_uuid.clone(),
620+
mtls_cert,
621+
device_id,
622+
attest,
623+
signature,
624+
ak_handle,
625+
};
626+
match agent_registration::register_agent(aa, &mut ctx).await {
627+
Ok(()) => (),
628+
Err(e) => {
629+
error!("Failed to register agent: {}", e);
695630
}
696-
697-
let mackey = general_purpose::STANDARD.encode(key.value());
698-
let auth_tag =
699-
crypto::compute_hmac(mackey.as_bytes(), agent_uuid.as_bytes())?;
700-
let auth_tag = hex::encode(&auth_tag);
701-
702-
registrar_client.activate_agent(&auth_tag).await?;
703-
info!("SUCCESS: Agent {} activated", &agent_uuid);
704631
}
705632

706633
let (mut payload_tx, mut payload_rx) =

0 commit comments

Comments
 (0)