package letsencrypt import ( internalcertapi "envoy-control-plane/internal/pkg/cert/api" "fmt" "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/registration" ) // ------------------------------------------------------------------------------------------------ // RenewCertificate renews an existing certificate using go-acme/lego. func (l *LetsEncryptIssuer) RenewCertificate(oldCert *internalcertapi.Certificate, webrootPath string, email string) (*internalcertapi.Certificate, error) { // FIX 1: Load the ACME Account Private Key from the D-value stored in AccountKey. acmePrivateKey, err := loadACMEKeyFromDValue(oldCert.AccountKey) if err != nil { return nil, fmt.Errorf("failed to load ACME account key: %w", err) } // 2. Setup ACME User (LEOptions) with the loaded account key acmeUser := &LEOptions{ Email: email, key: acmePrivateKey, // FIX 2: Provide the Registration URI (KID) to the client for JWS signing. // ASSUMPTION: The stored oldCert.AccountURL contains the ACME account URI (KID). Registration: ®istration.Resource{ URI: oldCert.AccountURL, }, } // 3. Configure and create the ACME client client, err := createClient(acmeUser, webrootPath, l.UseStaging) if err != nil { return nil, err } // 4. Reconstruct the certificate.Resource for renewal certResource := certificate.Resource{ Domain: oldCert.Domain, Certificate: oldCert.CertPEM, // The PrivateKey here is the DOMAIN's old private key. PrivateKey: oldCert.KeyPEM, } // 5. Renew the certificate newCertResources, err := client.Certificate.Renew(certResource, false, false, "") if err != nil { return nil, fmt.Errorf("failed to renew certificate: %w", err) } // 6. Map the results return &internalcertapi.Certificate{ Domain: oldCert.Domain, CertPEM: newCertResources.Certificate, // The renewed key (newCertResources.PrivateKey) is the domain's NEW private key. KeyPEM: newCertResources.PrivateKey, FullChain: newCertResources.Certificate, // The ACME account key and URL remain the same. AccountKey: oldCert.AccountKey, AccountURL: oldCert.AccountURL, }, nil }