@@ -10,7 +10,7 @@ import (
1010 "encoding/pem"
1111 "errors"
1212 "fmt"
13- "log"
13+ "log/slog "
1414 "net/http"
1515 "sync"
1616 "time"
@@ -42,7 +42,7 @@ type AcmeProxyConfig struct {
4242 HmacKey string `json:"eab_hmac_key"`
4343
4444 // Certificate lifetime in days
45- ValidFor int `json:"validity ,omitempty"`
45+ CertLifetime int `json:"certlifetime ,omitempty"`
4646
4747 // Prometheus metrics endpoint
4848 Metrics Metrics `json:"metrics"`
@@ -91,7 +91,7 @@ func (c *ExternalCAS) Type() apiv1.Type {
9191
9292func (c * ExternalCAS ) initClient () error {
9393 c .initOnce .Do (func () {
94- log . Println ( "Initializing ACME client... " )
94+ slog . Info ( "initializing ACME client" )
9595
9696 privateKey , err := rsa .GenerateKey (rand .Reader , 2048 )
9797 if err != nil {
@@ -102,7 +102,9 @@ func (c *ExternalCAS) initClient() error {
102102 // Unmarshal EAB config from ca.json
103103 var eab AcmeProxyConfig
104104 if err = json .Unmarshal (c .config , & eab ); err != nil {
105- log .Fatal ("Error unmarshalling EAB config from ca.json" , err )
105+ slog .Error ("failed to unmarshal EAB config" , "error" , err )
106+ c .initError = fmt .Errorf ("failed to unmarshal EAB config: %w" , err )
107+ return
106108 }
107109
108110 user := User {
@@ -138,7 +140,7 @@ func (c *ExternalCAS) initClient() error {
138140 }
139141 c .user .Registration = reg
140142
141- log . Println ("ACME client initialized successfully " )
143+ slog . Info ("ACME client initialized" )
142144 })
143145 return c .initError
144146}
@@ -158,14 +160,14 @@ func (c *ExternalCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*a
158160 return nil , fmt .Errorf ("failed to initialize ACME client: %w" , err )
159161 }
160162
161- log . Printf ( "Processing certificate request for domains: %v " , req .CSR .DNSNames )
163+ slog . Info ( "processing certificate request" , " domains" , req .CSR .DNSNames )
162164
163165 resultChan := make (chan * certificateResult , 1 )
164166
165167 go func () {
166168 defer func () {
167169 if r := recover (); r != nil {
168- log . Printf ( "Recovered from panic in processCertificateRequest: %v " , r )
170+ slog . Error ( "recovered from panic in processCertificateRequest" , "panic " , r )
169171 resultChan <- & certificateResult {
170172 err : fmt .Errorf ("internal error: %v" , r ),
171173 }
@@ -176,7 +178,7 @@ func (c *ExternalCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*a
176178 select {
177179 case resultChan <- result :
178180 case <- ctx .Done ():
179- log . Printf ( "Certificate request timed out or cancelled for domains: %v " , req .CSR .DNSNames )
181+ slog . Warn ( "certificate request timed out or cancelled" , " domains" , req .CSR .DNSNames )
180182 }
181183 }()
182184
@@ -192,7 +194,7 @@ func (c *ExternalCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*a
192194}
193195
194196func (c * ExternalCAS ) processCertificateRequest (ctx context.Context , req * apiv1.CreateCertificateRequest ) * certificateResult {
195- log . Printf ( "Starting certificate request processing for domains: %v " , req .CSR .DNSNames )
197+ slog . Debug ( "starting certificate request processing" , " domains" , req .CSR .DNSNames )
196198
197199 select {
198200 case <- ctx .Done ():
@@ -202,18 +204,31 @@ func (c *ExternalCAS) processCertificateRequest(ctx context.Context, req *apiv1.
202204 default :
203205 }
204206
205- cert , err := c .client .Certificate .ObtainForCSR (certificate.ObtainForCSRRequest {
206- CSR : req .CSR ,
207- Bundle : true ,
208- NotAfter : time .Now ().Add (1 * 24 * time .Hour ),
209- })
207+ var cfg AcmeProxyConfig
208+ if err := json .Unmarshal (c .config , & cfg ); err != nil {
209+ return & certificateResult {
210+ err : fmt .Errorf ("failed to parse acmeproxy config: %v" , err ),
211+ }
212+ }
213+
214+ // Build certificate request - only set NotAfter if CertLifetime is configured
215+ csrRequest := certificate.ObtainForCSRRequest {
216+ CSR : req .CSR ,
217+ Bundle : true ,
218+ }
219+ if cfg .CertLifetime > 0 {
220+ csrRequest .NotAfter = time .Now ().Add (time .Duration (cfg .CertLifetime ) * 24 * time .Hour )
221+ slog .Debug ("using configured certificate lifetime" , "days" , cfg .CertLifetime )
222+ }
223+
224+ cert , err := c .client .Certificate .ObtainForCSR (csrRequest )
210225 if err != nil {
211226 return & certificateResult {
212227 err : fmt .Errorf ("failed to obtain certificate from InCommon: %v" , err ),
213228 }
214229 }
215230
216- log . Printf ( "Successfully obtained certificate from InCommon for domains: %v " , req .CSR .DNSNames )
231+ slog . Info ( " obtained certificate from external CA" , " domains" , req .CSR .DNSNames )
217232
218233 leaf , intermediates , err := c .splitCertificateBundle (cert .Certificate )
219234 if err != nil {
@@ -271,6 +286,38 @@ func (c *ExternalCAS) RenewCertificate(req *apiv1.RenewCertificateRequest) (*api
271286}
272287
273288func (c * ExternalCAS ) RevokeCertificate (req * apiv1.RevokeCertificateRequest ) (* apiv1.RevokeCertificateResponse , error ) {
274- c .client .Certificate .Revoke (req .Certificate .Raw )
275- return nil , apiv1.NotImplementedError {}
289+ if req == nil || req .Certificate == nil {
290+ return nil , errors .New ("certificate cannot be nil" )
291+ }
292+
293+ if err := c .initClient (); err != nil {
294+ return nil , fmt .Errorf ("failed to initialize ACME client: %w" , err )
295+ }
296+
297+ // Convert DER-encoded certificate to PEM (lego expects PEM)
298+ pemBytes := pem .EncodeToMemory (& pem.Block {
299+ Type : "CERTIFICATE" ,
300+ Bytes : req .Certificate .Raw ,
301+ })
302+
303+ slog .Info ("revoking certificate" ,
304+ "serial" , req .Certificate .SerialNumber .String (),
305+ "subject" , req .Certificate .Subject .CommonName ,
306+ )
307+
308+ if err := c .client .Certificate .Revoke (pemBytes ); err != nil {
309+ slog .Error ("failed to revoke certificate" ,
310+ "serial" , req .Certificate .SerialNumber .String (),
311+ "error" , err ,
312+ )
313+ return nil , fmt .Errorf ("failed to revoke certificate: %w" , err )
314+ }
315+
316+ slog .Info ("certificate revoked successfully" ,
317+ "serial" , req .Certificate .SerialNumber .String (),
318+ )
319+
320+ return & apiv1.RevokeCertificateResponse {
321+ Certificate : req .Certificate ,
322+ }, nil
276323}
0 commit comments