This document provides detailed technical information about RustMQ's certificate signing implementation, including the recent fixes that resolved critical authentication issues.
RustMQ implements proper X.509 certificate signing chains to ensure enterprise-grade security for mTLS authentication. This implementation was significantly improved in August 2025 to resolve critical certificate validation issues.
Problem: All certificates, including end-entity certificates, were being created as self-signed certificates using RcgenCertificate::from_params(). This caused the authentication manager to fail validation with "Invalid certificate signature" errors.
Impact:
- 9 authentication tests failing
- mTLS authentication not working
- Certificate chain validation failures
- Production deployment blocked
The certificate manager was using RcgenCertificate::from_params() for all certificate types:
- Root CA certificates (correct - should be self-signed)
- Intermediate CA certificates (incorrect - should be signed by root CA)
- End-entity certificates (incorrect - should be signed by issuing CA)
This created a situation where the authentication manager expected proper certificate chains but received self-signed certificates.
// Root CA Certificate (Self-Signed)
let root_ca = RcgenCertificate::from_params(ca_params)?; // Correct
// Intermediate CA Certificate (Signed by Root CA)
let intermediate_ca = RcgenCertificate::from_params(ca_params)?;
let signed_der = intermediate_ca.serialize_der_with_signer(&root_ca)?; // Fixed
// End-Entity Certificate (Signed by CA)
let end_entity = RcgenCertificate::from_params(cert_params)?;
let signed_der = end_entity.serialize_der_with_signer(&issuer_ca)?; // Fixedgenerate_root_ca()
- Creates self-signed root CA certificate (unchanged - correct behavior)
- Uses
RcgenCertificate::from_params()and stores directly
generate_intermediate_ca() - Fixed
- Retrieves issuer (root CA) certificate using
reconstruct_rcgen_certificate() - Creates intermediate CA parameters
- Signs with issuer using
serialize_der_with_signer() - Stores signed certificate
issue_certificate() - Fixed
- Retrieves issuer CA certificate using
reconstruct_rcgen_certificate() - Creates end-entity certificate parameters
- Signs with issuer CA using
serialize_der_with_signer() - Stores signed certificate
reconstruct_rcgen_certificate()
fn reconstruct_rcgen_certificate(&self, cert_id: &str) -> Result<RcgenCertificate> {
// 1. Retrieve certificate PEM data from storage
let cert_info = self.get_certificate_by_id(cert_id)?;
let cert_pem = cert_info.certificate_pem.ok_or(...)?;
// 2. Retrieve private key PEM data
let private_key_pem = cert_info.private_key_pem.ok_or(...)?;
// 3. Parse certificate and private key
let cert_der = rustls_pemfile::certs(&mut cert_pem.as_bytes())?;
let private_key_der = rustls_pemfile::pkcs8_private_keys(&mut private_key_pem.as_bytes())?;
// 4. Create KeyPair from private key
let key_pair = KeyPair::from_der(&private_key_der[0])?;
// 5. Parse certificate to extract parameters
let parsed_cert = X509Certificate::from_der(&cert_der[0])?.1;
// 6. Reconstruct CertificateParams
let params = CertificateParams {
distinguished_name: extract_distinguished_name(&parsed_cert),
subject_alt_names: extract_san(&parsed_cert),
not_before: parsed_cert.validity().not_before,
not_after: parsed_cert.validity().not_after,
key_pair: Some(key_pair),
// ... other parameters
};
// 7. Create RcgenCertificate
RcgenCertificate::from_params(params)
}store_signed_certificate()
async fn store_signed_certificate(
&self,
signed_der: Vec<u8>,
role: CertificateRole,
issuer_id: Option<String>,
created_by: &str,
) -> Result<CertificateInfo> {
// 1. Parse signed DER to extract metadata
let parsed_cert = X509Certificate::from_der(&signed_der)?.1;
// 2. Create certificate info with proper metadata
let cert_info = CertificateInfo {
id: Uuid::new_v4().to_string(),
subject: extract_subject(&parsed_cert),
issuer: extract_issuer(&parsed_cert),
serial_number: extract_serial(&parsed_cert),
not_before: parsed_cert.validity().not_before.to_system_time(),
not_after: parsed_cert.validity().not_after.to_system_time(),
fingerprint: calculate_fingerprint(&signed_der),
role,
status: CertificateStatus::Active,
issuer_id,
// ... other fields
};
// 3. Convert DER to PEM for storage
let cert_pem = pem::encode(&pem::Pem::new("CERTIFICATE", signed_der));
// 4. Store certificate data
self.store_certificate_data(cert_info, cert_pem).await
}The authentication manager now properly validates certificate chains:
pub async fn validate_certificate_chain(&self, certificates: &[Certificate]) -> Result<()> {
// 1. Parse client certificate
let client_cert = &certificates[0];
let parsed_cert = self.parse_certificate(&client_cert.0)?;
// 2. Retrieve CA certificate for validation
let ca_cert = self.get_ca_certificate_for_validation()?;
// 3. Validate signature using CA public key
self.validate_certificate_signature(&parsed_cert, &ca_cert)?;
// 4. Validate certificate chain hierarchy
self.validate_issuer_subject_relationship(&parsed_cert, &ca_cert)?;
// 5. Check certificate validity period
self.validate_certificate_validity(&parsed_cert)?;
// 6. Check revocation status
self.check_certificate_revocation(&parsed_cert)?;
Ok(())
}After implementing the certificate signing fix:
- ✅ All 175 security tests pass (previously 9 failing)
- ✅ Certificate chain validation working
- ✅ mTLS authentication functional
- ✅ Production-ready security infrastructure
You can verify proper certificate signing using OpenSSL:
# 1. Check certificate chain
openssl verify -CAfile root-ca.pem intermediate-ca.pem
openssl verify -CAfile root-ca.pem -untrusted intermediate-ca.pem client-cert.pem
# 2. Verify certificate details
openssl x509 -in client-cert.pem -noout -issuer -subject
# Should show: issuer=CN=RustMQ Intermediate CA, subject=CN=client@company.com
# 3. Check signature
openssl verify -verbose -CAfile root-ca.pem -untrusted intermediate-ca.pem client-cert.pem
# Should show: client-cert.pem: OKThe certificate signing implementation is covered by comprehensive tests:
Unit Tests:
test_generate_root_ca()- Verifies self-signed root CA creationtest_generate_intermediate_ca()- Verifies intermediate CA signing by root CAtest_issue_client_certificate()- Verifies end-entity certificate signingtest_certificate_chain_validation()- Verifies authentication manager validation
Integration Tests:
test_end_to_end_authentication_flow()- Complete mTLS authentication flowtest_certificate_lifecycle_integration()- Full certificate lifecycle with signing
The proper certificate signing implementation addresses several security concerns:
- Certificate Forgery Prevention: Proper CA signing prevents creation of unauthorized certificates
- Trust Chain Validation: Complete certificate chain validation ensures trust relationships
- Cryptographic Integrity: Proper signature verification ensures certificate authenticity
- PKI Compliance: Standards-compliant X.509 certificate implementation
The fixed certificate signing enables:
- ✅ Enterprise PKI Integration: Certificates can be properly integrated with existing PKI infrastructure
- ✅ Compliance: Meets enterprise and regulatory certificate requirements
- ✅ Scalability: Proper CA hierarchy supports large-scale deployments
- ✅ Security: Full cryptographic validation of certificate chains
If you have RustMQ deployments with the previous (self-signed) certificate implementation:
-
Backup Existing Certificates
rustmq-admin certs export --all --output certificates-backup.tar.gz -
Regenerate Certificate Infrastructure
# Initialize new root CA rustmq-admin ca init --cn "RustMQ Root CA" --org "YourOrg" # Create intermediate CAs rustmq-admin ca intermediate --parent-ca root_ca_1 --cn "Production CA" # Issue new properly-signed certificates rustmq-admin certs issue --principal "broker-01" --role broker --ca-id prod_ca_1
-
Update Client Configurations
- Update client trust stores with new CA certificates
- Replace client certificates with newly issued ones
- Test connectivity before full deployment
-
Gradual Rollout
- Deploy new certificates alongside old ones
- Update client configurations
- Remove old certificates after verification
- Hardware Security Module (HSM) Support: Integration with HSMs for CA private key protection
- Certificate Transparency: Support for Certificate Transparency logging
- Automated Certificate Rotation: Enhanced automation for certificate lifecycle management
- Cross-Certification: Support for cross-certification with external CAs
- Certificate Caching: Enhanced caching for certificate validation
- Batch Operations: Batch certificate operations for better performance
- Async Certificate Generation: Non-blocking certificate generation operations
The certificate signing implementation fix represents a critical improvement to RustMQ's security infrastructure. By implementing proper X.509 certificate chains, RustMQ now provides enterprise-grade certificate management that meets industry standards and security requirements.
The implementation ensures:
- ✅ Correct Certificate Chains: Proper issuer-subject relationships
- ✅ Standards Compliance: Full X.509 specification compliance
- ✅ Security Validation: Complete authentication manager validation
- ✅ Production Readiness: Enterprise-grade certificate infrastructure
This foundation enables secure, scalable, and compliant deployments of RustMQ in enterprise environments.