Decouple client contracts and close private role registries

This commit is contained in:
ms2k 2026-07-19 03:44:30 +09:00
commit 22325aa76a

View file

@ -10,6 +10,8 @@ use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, MutexGuard};
use ed25519_dalek::SigningKey;
pub use lazaret_control_client::{CONTROL_ALPN, CONTROL_SERVER_NAME, PendingClientEnrollment};
use lazaret_control_client::{ControlClient, ControlClientError};
use lazaret_core::codec::{CodecError, decode, encode};
use lazaret_core::configuration::ConfinedPathPlan;
use lazaret_core::identity::{
@ -38,7 +40,7 @@ use rcgen::{
use rustix::fs::{Mode, OFlags, fchmod, openat};
use rustix::net::sockopt::socket_peercred;
use rustls::pki_types::{
CertificateDer, CertificateSigningRequestDer, PrivateKeyDer, PrivatePkcs8KeyDer, ServerName,
CertificateDer, CertificateSigningRequestDer, PrivateKeyDer, PrivatePkcs8KeyDer,
};
use rustls::server::{NoServerSessionStorage, WebPkiClientVerifier};
use rustls::{ClientConfig, ClientConnection, RootCertStore, ServerConfig, ServerConnection};
@ -53,12 +55,9 @@ use lazaret_linux::filesystem::mount_identity;
use lazaret_linux::process::{ProcessExit, TargetCommand, child_broker};
use lazaret_runtime_supervisor::sandbox::RunscCommand;
pub const CONTROL_ALPN: &[u8] = b"lazaret-control/1";
pub const CONTROL_SERVER_NAME: &str = "coordinator.lazaret.invalid";
pub const MAX_ENROLLMENT_BYTES: usize = 8_192;
const MAX_CONTROL_BYTES: usize = 65_536;
pub(crate) const CONTROL_SOCKET_NAME: &str = "c.sock";
pub(crate) const PUBLICATION_IDENTITY_NAME: &str = "protocol-identity.postcard";
pub(crate) use lazaret_control_client::{CONTROL_SOCKET_NAME, PUBLICATION_IDENTITY_NAME};
pub(crate) const STAGED_CONTROL_SOCKET_NAME: &str = ".c.staged";
pub(crate) const STAGED_PUBLICATION_IDENTITY_NAME: &str = ".protocol-identity.staged";
@ -69,6 +68,7 @@ pub enum ControlError {
Certificate(rcgen::Error),
Tls(rustls::Error),
Protocol(ProtocolValidationError),
Client(ControlClientError),
DomainStore(DomainStoreError),
InvalidPath(&'static str),
InvalidPublication(&'static str),
@ -90,6 +90,7 @@ impl fmt::Display for ControlError {
Self::Certificate(error) => write!(formatter, "certificate operation failed: {error}"),
Self::Tls(error) => write!(formatter, "TLS failed: {error}"),
Self::Protocol(error) => write!(formatter, "protocol validation failed: {error}"),
Self::Client(error) => write!(formatter, "{error}"),
Self::DomainStore(error) => write!(formatter, "session persistence failed: {error}"),
Self::InvalidPath(reason) => write!(formatter, "invalid control path: {reason}"),
Self::InvalidPublication(reason) => {
@ -124,6 +125,7 @@ impl std::error::Error for ControlError {
Self::Certificate(error) => Some(error),
Self::Tls(error) => Some(error),
Self::Protocol(error) => Some(error),
Self::Client(error) => Some(error),
Self::DomainStore(error) => Some(error),
_ => None,
}
@ -145,6 +147,7 @@ from_error!(CodecError, Codec);
from_error!(rcgen::Error, Certificate);
from_error!(rustls::Error, Tls);
from_error!(ProtocolValidationError, Protocol);
from_error!(ControlClientError, Client);
from_error!(DomainStoreError, DomainStore);
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@ -162,50 +165,6 @@ impl FileIdentity {
}
}
pub struct PendingClientEnrollment {
request: ClientEnrollmentRequest,
private_key: PrivatePkcs8KeyDer<'static>,
}
impl PendingClientEnrollment {
/// Creates an Ed25519 CSR whose signed subject binds the exact generation and Client CLI ID.
///
/// # Errors
/// Returns an error when key generation, encoding, or CSR signing fails.
pub fn create(
generation_identity: GenerationIdentity,
cli_id: ClientId,
) -> Result<Self, ControlError> {
let binding = enrollment_binding(&generation_identity, cli_id)?;
let mut params = CertificateParams::default();
params.distinguished_name = DistinguishedName::new();
params.distinguished_name.push(DnType::CommonName, binding);
params.key_usages = vec![KeyUsagePurpose::DigitalSignature];
params.extended_key_usages = vec![ExtendedKeyUsagePurpose::ClientAuth];
let key = KeyPair::generate_for(&PKCS_ED25519)?;
let csr = params.serialize_request(&key)?;
Ok(Self {
request: ClientEnrollmentRequest {
protocol_version: ProtocolVersion::V1,
generation_identity,
cli_id,
certificate_signing_request_der: csr.der().to_vec(),
},
private_key: PrivatePkcs8KeyDer::from(key.serialize_der()),
})
}
#[must_use]
pub const fn request(&self) -> &ClientEnrollmentRequest {
&self.request
}
#[must_use]
pub fn private_key(&self) -> PrivateKeyDer<'static> {
PrivateKeyDer::Pkcs8(self.private_key.clone_key())
}
}
pub struct TrustAnchor {
generation_identity: GenerationIdentity,
tls_ca: CertifiedIssuer<'static, KeyPair>,