Skip to content

Latest commit

 

History

History
287 lines (210 loc) · 10.7 KB

File metadata and controls

287 lines (210 loc) · 10.7 KB

RustMQ Certificate Signing Implementation

This document provides detailed technical information about RustMQ's certificate signing implementation, including the recent fixes that resolved critical authentication issues.

Overview

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.

Historical Context

Previous Issue (Resolved August 2025)

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

Root Cause Analysis

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.

Current Implementation

Certificate Signing Architecture

// 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)?; // Fixed

Key Implementation Details

1. Certificate Manager Methods

generate_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

2. Helper Methods Added

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
}

Certificate Chain Validation

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(())
}

Verification and Testing

Test Results

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

Manual Verification

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: OK

Test Coverage

The certificate signing implementation is covered by comprehensive tests:

Unit Tests:

  • test_generate_root_ca() - Verifies self-signed root CA creation
  • test_generate_intermediate_ca() - Verifies intermediate CA signing by root CA
  • test_issue_client_certificate() - Verifies end-entity certificate signing
  • test_certificate_chain_validation() - Verifies authentication manager validation

Integration Tests:

  • test_end_to_end_authentication_flow() - Complete mTLS authentication flow
  • test_certificate_lifecycle_integration() - Full certificate lifecycle with signing

Security Implications

Threat Model Updates

The proper certificate signing implementation addresses several security concerns:

  1. Certificate Forgery Prevention: Proper CA signing prevents creation of unauthorized certificates
  2. Trust Chain Validation: Complete certificate chain validation ensures trust relationships
  3. Cryptographic Integrity: Proper signature verification ensures certificate authenticity
  4. PKI Compliance: Standards-compliant X.509 certificate implementation

Production Deployment

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

Migration Guide

Upgrading from Previous Versions

If you have RustMQ deployments with the previous (self-signed) certificate implementation:

  1. Backup Existing Certificates

    rustmq-admin certs export --all --output certificates-backup.tar.gz
  2. 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
  3. Update Client Configurations

    • Update client trust stores with new CA certificates
    • Replace client certificates with newly issued ones
    • Test connectivity before full deployment
  4. Gradual Rollout

    • Deploy new certificates alongside old ones
    • Update client configurations
    • Remove old certificates after verification

Future Enhancements

Planned Improvements

  1. Hardware Security Module (HSM) Support: Integration with HSMs for CA private key protection
  2. Certificate Transparency: Support for Certificate Transparency logging
  3. Automated Certificate Rotation: Enhanced automation for certificate lifecycle management
  4. Cross-Certification: Support for cross-certification with external CAs

Performance Optimizations

  1. Certificate Caching: Enhanced caching for certificate validation
  2. Batch Operations: Batch certificate operations for better performance
  3. Async Certificate Generation: Non-blocking certificate generation operations

Conclusion

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.