package certificates import ( "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/x509" "encoding/pem" "errors" "os" "github.com/go-acme/lego/v4/registration" ) // acmeUser implements lego's registration.User for our single ACME // account. The private key never leaves this process and is stored on // disk with 0600 permissions, separate from any issued certificate keys. type acmeUser struct { Email string Registration *registration.Resource key crypto.PrivateKey } func newACMEUser(email string, key crypto.PrivateKey) *acmeUser { return &acmeUser{Email: email, key: key} } func (u *acmeUser) GetEmail() string { return u.Email } func (u *acmeUser) GetRegistration() *registration.Resource { return u.Registration } func (u *acmeUser) GetPrivateKey() crypto.PrivateKey { return u.key } func newACMEAccountKey() (*ecdsa.PrivateKey, error) { return ecdsa.GenerateKey(elliptic.P256(), rand.Reader) } func writeECDSAKeyPEM(path string, key *ecdsa.PrivateKey) error { der, err := x509.MarshalECPrivateKey(key) if err != nil { return err } block := &pem.Block{Type: "EC PRIVATE KEY", Bytes: der} return os.WriteFile(path, pem.EncodeToMemory(block), 0o600) } func readECDSAKeyPEM(path string) (*ecdsa.PrivateKey, error) { data, err := os.ReadFile(path) if err != nil { return nil, err } block, _ := pem.Decode(data) if block == nil { return nil, errors.New("invalid PEM account key") } return x509.ParseECPrivateKey(block.Bytes) }