44use miette:: { IntoDiagnostic , Result , WrapErr } ;
55use rcgen:: { BasicConstraints , CertificateParams , DnType , Ia5String , IsCa , KeyPair , SanType } ;
66use std:: net:: IpAddr ;
7+ use time:: { Duration , OffsetDateTime } ;
78
89/// All PEM-encoded materials produced by [`generate_pki`].
910#[ allow( clippy:: struct_field_names) ]
@@ -20,35 +21,35 @@ pub struct PkiBundle {
2021/// Default SANs always included on the server certificate.
2122const DEFAULT_SERVER_SANS : & [ & str ] = & [
2223 "openshell" ,
23- "openshell.openshell.svc" ,
24- "openshell.openshell.svc.cluster.local" ,
2524 "localhost" ,
26- "host.docker .internal" ,
25+ "host.containers .internal" ,
2726 "127.0.0.1" ,
2827] ;
2928
30- /// SANs for the container bridge daemon certificate (macOS host).
31- ///
32- /// `host.containers.internal` is the hostname Apple Container VMs use to reach
33- /// the host, analogous to Docker's `host.docker.internal`.
29+ /// SANs for the server certificate. `host.containers.internal` is the hostname
30+ /// Apple Container VMs use to reach the macOS host.
3431
3532/// Generate a complete PKI bundle: CA, server cert, and client cert.
3633///
3734/// `extra_sans` are additional Subject Alternative Names to add to the server
3835/// certificate (e.g. the remote host's IP or hostname for remote deployments).
3936///
40- /// Certificate validity uses the `rcgen` defaults (1975–4096), which effectively
41- /// never expire. This is appropriate for an internal dev-cluster PKI where certs
42- /// are ephemeral to the cluster's lifetime.
37+ /// Certificates are valid for 365 days from generation. Regenerate the PKI
38+ /// bundle before expiry.
4339pub fn generate_pki ( extra_sans : & [ String ] ) -> Result < PkiBundle > {
40+ let now = OffsetDateTime :: now_utc ( ) ;
41+ let expiry = now + Duration :: days ( 365 ) ;
42+
4443 // --- CA ---
4544 let ca_key = KeyPair :: generate ( )
4645 . into_diagnostic ( )
4746 . wrap_err ( "failed to generate CA key" ) ?;
4847 let mut ca_params = CertificateParams :: new ( Vec :: < String > :: new ( ) )
4948 . into_diagnostic ( )
5049 . wrap_err ( "failed to create CA params" ) ?;
51- ca_params. is_ca = IsCa :: Ca ( BasicConstraints :: Unconstrained ) ;
50+ ca_params. is_ca = IsCa :: Ca ( BasicConstraints :: Constrained ( 0 ) ) ;
51+ ca_params. not_before = now;
52+ ca_params. not_after = expiry;
5253 ca_params
5354 . distinguished_name
5455 . push ( DnType :: OrganizationName , "openshell" ) ;
@@ -70,6 +71,8 @@ pub fn generate_pki(extra_sans: &[String]) -> Result<PkiBundle> {
7071 . into_diagnostic ( )
7172 . wrap_err ( "failed to create server cert params" ) ?;
7273 server_params. subject_alt_names = server_sans;
74+ server_params. not_before = now;
75+ server_params. not_after = expiry;
7376 server_params
7477 . distinguished_name
7578 . push ( DnType :: CommonName , "openshell-server" ) ;
@@ -86,6 +89,8 @@ pub fn generate_pki(extra_sans: &[String]) -> Result<PkiBundle> {
8689 let mut client_params = CertificateParams :: new ( Vec :: < String > :: new ( ) )
8790 . into_diagnostic ( )
8891 . wrap_err ( "failed to create client cert params" ) ?;
92+ client_params. not_before = now;
93+ client_params. not_after = expiry;
8994 client_params
9095 . distinguished_name
9196 . push ( DnType :: CommonName , "openshell-client" ) ;
0 commit comments