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

@ -479,30 +479,7 @@ impl PublishedControlFace {
publication: &ProtocolPublicationIdentity,
client: Option<(&TlsCredential, PrivateKeyDer<'static>)>,
) -> Result<ClientConfig, ControlError> {
let mut roots = RootCertStore::empty();
roots.add(CertificateDer::from(
publication.tls_ca_certificate_der.clone(),
))?;
let builder = ClientConfig::builder_with_protocol_versions(&[&rustls::version::TLS13])
.with_root_certificates(roots);
let mut config = if let Some((credential, private_key)) = client {
verify_tls_credential(
credential,
&publication.generation_identity,
TlsRole::ClientCli,
credential.subject_id(),
)?;
builder.with_client_auth_cert(
vec![CertificateDer::from(credential.certificate_der.clone())],
private_key,
)?
} else {
builder.with_no_client_auth()
};
config.alpn_protocols = vec![CONTROL_ALPN.to_vec()];
config.enable_early_data = false;
config.resumption = rustls::client::Resumption::disabled();
Ok(config)
ControlClient::config(publication, client).map_err(ControlError::from)
}
/// Connects a rustls stream to the fixed control socket using an existing configuration.
@ -515,24 +492,7 @@ impl PublishedControlFace {
publication: &ProtocolPublicationIdentity,
) -> Result<rustls::StreamOwned<ClientConnection, std::os::unix::net::UnixStream>, ControlError>
{
let socket = std::os::unix::net::UnixStream::connect(socket_path)?;
let server_name = ServerName::try_from(CONTROL_SERVER_NAME)
.map_err(|_| ControlError::InvalidCertificateProfile)?;
let mut connection = ClientConnection::new(Arc::new(config), server_name)?;
let mut socket = socket;
while connection.is_handshaking() {
connection.complete_io(&mut socket)?;
}
let [certificate] = connection.peer_certificates().unwrap_or_default() else {
return Err(ControlError::InvalidCertificateProfile);
};
if connection.protocol_version() != Some(rustls::ProtocolVersion::TLSv1_3)
|| connection.alpn_protocol() != Some(CONTROL_ALPN)
|| certificate_digest(certificate) != publication.coordinator_tls_certificate_sha256
{
return Err(ControlError::InvalidCertificateProfile);
}
Ok(rustls::StreamOwned::new(connection, socket))
ControlClient::connect(socket_path, config, publication).map_err(ControlError::from)
}
/// Writes one length-delimited control record.
@ -543,7 +503,7 @@ impl PublishedControlFace {
stream: &mut impl Write,
request: &Request,
) -> Result<(), ControlError> {
write_frame(stream, request)
ControlClient::send(stream, request).map_err(ControlError::from)
}
/// Reads one length-delimited control record.
@ -553,7 +513,7 @@ impl PublishedControlFace {
pub fn receive<Response: serde::de::DeserializeOwned + serde::Serialize>(
stream: &mut impl Read,
) -> Result<Response, ControlError> {
read_frame(stream, MAX_CONTROL_BYTES)
ControlClient::receive(stream).map_err(ControlError::from)
}
}
@ -696,8 +656,8 @@ fn enrollment_binding(
generation_identity: &GenerationIdentity,
cli_id: ClientId,
) -> Result<String, ControlError> {
let encoded = encode(&(generation_identity, cli_id))?;
Ok(format!("lazaret-client-{}", hex(&sha256(&encoded))))
lazaret_core::protocol::client_enrollment_binding(generation_identity, cli_id)
.map_err(ControlError::from)
}
fn certificate_digest(certificate: impl AsRef<[u8]>) -> CertificateDigest {