mirror of
https://github.com/go-acme/lego
synced 2026-03-14 22:45:48 +01:00
feat: replace crypto.PrivateKey with crypto.Signer
This commit is contained in:
parent
14d20b23f3
commit
bce7264bfc
17 changed files with 40 additions and 39 deletions
|
|
@ -91,7 +91,7 @@ func (a *AccountService) Deactivate(ctx context.Context, accountURL string) erro
|
|||
}
|
||||
|
||||
// KeyChange Changes the account key.
|
||||
func (a *AccountService) KeyChange(ctx context.Context, newKey crypto.PrivateKey) error {
|
||||
func (a *AccountService) KeyChange(ctx context.Context, newKey crypto.Signer) error {
|
||||
uri := a.core.GetDirectory().KeyChangeURL
|
||||
|
||||
eabJWS, err := a.core.jws().SignKeyChange(uri, newKey)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ type Core struct {
|
|||
|
||||
HTTPClient *http.Client
|
||||
|
||||
privateKey crypto.PrivateKey
|
||||
privateKey crypto.Signer
|
||||
kid string
|
||||
|
||||
common service // Reuse a single struct instead of allocating one for each service on the heap.
|
||||
|
|
@ -38,7 +38,7 @@ type Core struct {
|
|||
}
|
||||
|
||||
// New Creates a new Core.
|
||||
func New(httpClient *http.Client, userAgent, caDirURL, kid string, privateKey crypto.PrivateKey) (*Core, error) {
|
||||
func New(httpClient *http.Client, userAgent, caDirURL, kid string, privateKey crypto.Signer) (*Core, error) {
|
||||
doer := sender.NewDoer(httpClient, userAgent)
|
||||
|
||||
// NOTE(ldez) add context as a parameter of the constructor?
|
||||
|
|
@ -85,7 +85,7 @@ func (a *Core) GetKid() string {
|
|||
return a.kid
|
||||
}
|
||||
|
||||
func (a *Core) setPrivateKey(privateKey crypto.PrivateKey) {
|
||||
func (a *Core) setPrivateKey(privateKey crypto.Signer) {
|
||||
a.privateKey = privateKey
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ type nonceSourceCreator interface {
|
|||
|
||||
// JWS Represents a JWS.
|
||||
type JWS struct {
|
||||
privKey crypto.PrivateKey
|
||||
privKey crypto.Signer
|
||||
kid string // Key identifier
|
||||
nonces nonceSourceCreator
|
||||
}
|
||||
|
||||
// NewJWS Create a new JWS.
|
||||
func NewJWS(privateKey crypto.PrivateKey, kid string, nonceManager nonceSourceCreator) *JWS {
|
||||
func NewJWS(privateKey crypto.Signer, kid string, nonceManager nonceSourceCreator) *JWS {
|
||||
return &JWS{
|
||||
privKey: privateKey,
|
||||
nonces: nonceManager,
|
||||
|
|
@ -82,12 +82,7 @@ func (j *JWS) SignEAB(url, kid string, hmac []byte) (*jose.JSONWebSignature, err
|
|||
|
||||
// GetKeyAuthorization Gets the key authorization for a token.
|
||||
func (j *JWS) GetKeyAuthorization(token string) (string, error) {
|
||||
var publicKey crypto.PublicKey
|
||||
|
||||
signer, ok := j.privKey.(crypto.Signer)
|
||||
if ok {
|
||||
publicKey = signer.Public()
|
||||
}
|
||||
publicKey := j.privKey.Public()
|
||||
|
||||
// Generate the Key Authorization for the challenge
|
||||
jwk := &jose.JSONWebKey{Key: publicKey}
|
||||
|
|
@ -103,7 +98,7 @@ func (j *JWS) GetKeyAuthorization(token string) (string, error) {
|
|||
return token + "." + keyThumb, nil
|
||||
}
|
||||
|
||||
func (j *JWS) SignKeyChange(url string, newKey crypto.PrivateKey) (*jose.JSONWebSignature, error) {
|
||||
func (j *JWS) SignKeyChange(url string, newKey crypto.Signer) (*jose.JSONWebSignature, error) {
|
||||
if j.kid == "" {
|
||||
return nil, errors.New("missing kid")
|
||||
}
|
||||
|
|
@ -151,7 +146,7 @@ func sign(content []byte, signKey jose.SigningKey, options *jose.SignerOptions)
|
|||
return signed, nil
|
||||
}
|
||||
|
||||
func signatureAlgorithm(privKey crypto.PrivateKey) jose.SignatureAlgorithm {
|
||||
func signatureAlgorithm(privKey crypto.Signer) jose.SignatureAlgorithm {
|
||||
var alg jose.SignatureAlgorithm
|
||||
|
||||
switch k := privKey.(type) {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ func ParsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
|
|||
// Borrowed from Go standard library, to handle various private key and PEM block types.
|
||||
// https://github.com/golang/go/blob/693748e9fa385f1e2c3b91ca9acbb6c0ad2d133d/src/crypto/tls/tls.go#L291-L308
|
||||
// https://github.com/golang/go/blob/693748e9fa385f1e2c3b91ca9acbb6c0ad2d133d/src/crypto/tls/tls.go#L238
|
||||
func ParsePEMPrivateKey(key []byte) (crypto.PrivateKey, error) {
|
||||
func ParsePEMPrivateKey(key []byte) (crypto.Signer, error) {
|
||||
keyBlockDER, _ := pem.Decode(key)
|
||||
if keyBlockDER == nil {
|
||||
return nil, errors.New("invalid PEM block")
|
||||
|
|
@ -92,7 +92,11 @@ func ParsePEMPrivateKey(key []byte) (crypto.PrivateKey, error) {
|
|||
|
||||
if key, err := x509.ParsePKCS8PrivateKey(keyBlockDER.Bytes); err == nil {
|
||||
switch key := key.(type) {
|
||||
case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
|
||||
case *rsa.PrivateKey:
|
||||
return key, nil
|
||||
case *ecdsa.PrivateKey:
|
||||
return key, nil
|
||||
case ed25519.PrivateKey:
|
||||
return key, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("found unknown private key type in PKCS#8 wrapping: %T", key)
|
||||
|
|
@ -106,7 +110,7 @@ func ParsePEMPrivateKey(key []byte) (crypto.PrivateKey, error) {
|
|||
return nil, errors.New("failed to parse private key")
|
||||
}
|
||||
|
||||
func GeneratePrivateKey(keyType KeyType) (crypto.PrivateKey, error) {
|
||||
func GeneratePrivateKey(keyType KeyType) (crypto.Signer, error) {
|
||||
switch keyType {
|
||||
case EC256:
|
||||
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
|
|
@ -132,7 +136,7 @@ type CSROptions struct {
|
|||
EmailAddresses []string
|
||||
}
|
||||
|
||||
func CreateCSR(privateKey crypto.PrivateKey, opts CSROptions) ([]byte, error) {
|
||||
func CreateCSR(privateKey crypto.Signer, opts CSROptions) ([]byte, error) {
|
||||
var (
|
||||
dnsNames []string
|
||||
ipAddresses []net.IP
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func TestGenerateCSR(t *testing.T) {
|
|||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
privateKey crypto.PrivateKey
|
||||
privateKey crypto.Signer
|
||||
opts CSROptions
|
||||
expected expected
|
||||
}{
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ type Resource struct {
|
|||
// See https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2.
|
||||
type ObtainRequest struct {
|
||||
Domains []string
|
||||
PrivateKey crypto.PrivateKey
|
||||
PrivateKey crypto.Signer
|
||||
MustStaple bool
|
||||
EmailAddresses []string
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ type ObtainRequest struct {
|
|||
type ObtainForCSRRequest struct {
|
||||
CSR *x509.CertificateRequest
|
||||
|
||||
PrivateKey crypto.PrivateKey
|
||||
PrivateKey crypto.Signer
|
||||
|
||||
NotBefore time.Time
|
||||
NotAfter time.Time
|
||||
|
|
@ -548,7 +548,7 @@ func (c *Certifier) Renew(ctx context.Context, certRes Resource, options *RenewO
|
|||
return c.ObtainForCSR(ctx, request)
|
||||
}
|
||||
|
||||
var privateKey crypto.PrivateKey
|
||||
var privateKey crypto.Signer
|
||||
if certRes.PrivateKey != nil {
|
||||
privateKey, err = certcrypto.ParsePEMPrivateKey(certRes.PrivateKey)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ func getKeyType(srcKeyPath string) (certcrypto.KeyType, error) {
|
|||
return kt, nil
|
||||
}
|
||||
|
||||
func guessKeyType(key crypto.PrivateKey) (certcrypto.KeyType, error) {
|
||||
func guessKeyType(key crypto.Signer) (certcrypto.KeyType, error) {
|
||||
switch k := key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
switch k.Size() {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ type Account struct {
|
|||
KeyType certcrypto.KeyType `json:"keyType"`
|
||||
Registration *acme.ExtendedAccount `json:"registration"`
|
||||
|
||||
key crypto.PrivateKey
|
||||
key crypto.Signer
|
||||
}
|
||||
|
||||
func NewAccount(email, id string, keyType certcrypto.KeyType, key crypto.PrivateKey) *Account {
|
||||
func NewAccount(email, id string, keyType certcrypto.KeyType, key crypto.Signer) *Account {
|
||||
return &Account{Email: email, ID: id, KeyType: keyType, key: key}
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ func (a *Account) GetKeyType() certcrypto.KeyType {
|
|||
}
|
||||
|
||||
// GetPrivateKey returns the private account key.
|
||||
func (a *Account) GetPrivateKey() crypto.PrivateKey {
|
||||
func (a *Account) GetPrivateKey() crypto.Signer {
|
||||
return a.key
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ func (s *AccountsStorage) getAccount(ctx context.Context, keyType certcrypto.Key
|
|||
}
|
||||
|
||||
// createPrivateKey generates a new private key and saves it to a file.
|
||||
func (s *AccountsStorage) createPrivateKey(keyType certcrypto.KeyType, effectiveAccountID string) (crypto.PrivateKey, error) {
|
||||
func (s *AccountsStorage) createPrivateKey(keyType certcrypto.KeyType, effectiveAccountID string) (crypto.Signer, error) {
|
||||
keysPath := s.getKeyPath(keyType, effectiveAccountID)
|
||||
|
||||
accKeyPath := filepath.Join(keysPath, effectiveAccountID+".key")
|
||||
|
|
@ -242,7 +242,7 @@ func (s *AccountsStorage) createPrivateKey(keyType certcrypto.KeyType, effective
|
|||
}
|
||||
|
||||
// readPrivateKey reads the private key from a file.
|
||||
func (s *AccountsStorage) readPrivateKey(keyType certcrypto.KeyType, effectiveAccountID string) (crypto.PrivateKey, error) {
|
||||
func (s *AccountsStorage) readPrivateKey(keyType certcrypto.KeyType, effectiveAccountID string) (crypto.Signer, error) {
|
||||
keysPath := s.getKeyPath(keyType, effectiveAccountID)
|
||||
|
||||
accKeyPath := filepath.Join(keysPath, effectiveAccountID+".key")
|
||||
|
|
@ -293,7 +293,7 @@ func (s *AccountsStorage) getRootUserPath(effectiveAccountID string) string {
|
|||
}
|
||||
|
||||
// tryRecoverRegistration tries to recover the registration from the private key.
|
||||
func (s *AccountsStorage) tryRecoverRegistration(ctx context.Context, privateKey crypto.PrivateKey) (*acme.ExtendedAccount, error) {
|
||||
func (s *AccountsStorage) tryRecoverRegistration(ctx context.Context, privateKey crypto.Signer) (*acme.ExtendedAccount, error) {
|
||||
// couldn't load account but got a key. Try to look the account up.
|
||||
config := lego.NewConfig(&Account{key: privateKey})
|
||||
config.CADirURL = s.server.String()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
|
@ -41,6 +40,9 @@ func TestAccountsStorage_Save(t *testing.T) {
|
|||
accountID := "test@example.com"
|
||||
keyType := certcrypto.RSA4096
|
||||
|
||||
privateKey, err := certcrypto.GeneratePrivateKey(keyType)
|
||||
require.NoError(t, err)
|
||||
|
||||
account := &Account{
|
||||
Email: "account@example.com",
|
||||
ID: accountID,
|
||||
|
|
@ -56,7 +58,7 @@ func TestAccountsStorage_Save(t *testing.T) {
|
|||
},
|
||||
Location: "https://ame.example.com",
|
||||
},
|
||||
key: crypto.PrivateKey(""),
|
||||
key: privateKey,
|
||||
}
|
||||
|
||||
accountFilePath := storage.getAccountFilePath(keyType, accountID)
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ func SanitizedName(name string) string {
|
|||
}
|
||||
|
||||
// ReadPrivateKeyFile reads a private key file.
|
||||
func ReadPrivateKeyFile(filename string) (crypto.PrivateKey, error) {
|
||||
func ReadPrivateKeyFile(filename string) (crypto.Signer, error) {
|
||||
keyBytes, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading the private key: %w", err)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func (s *CertificatesStorage) ReadCertificate(certID string) ([]*x509.Certificat
|
|||
return ReadCertificateFile(s.GetFileName(certID, ExtCert))
|
||||
}
|
||||
|
||||
func (s *CertificatesStorage) ReadPrivateKey(certID string) (crypto.PrivateKey, error) {
|
||||
func (s *CertificatesStorage) ReadPrivateKey(certID string) (crypto.Signer, error) {
|
||||
privateKey, err := ReadPrivateKeyFile(s.GetFileName(certID, ExtKey))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while parsing the private key for %q: %w", certID, err)
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import (
|
|||
|
||||
type FakeUser struct {
|
||||
Email string
|
||||
PrivateKey crypto.PrivateKey
|
||||
PrivateKey crypto.Signer
|
||||
Registration *acme.ExtendedAccount
|
||||
}
|
||||
|
||||
func (f *FakeUser) GetEmail() string { return f.Email }
|
||||
func (f *FakeUser) GetRegistration() *acme.ExtendedAccount { return f.Registration }
|
||||
func (f *FakeUser) GetPrivateKey() crypto.PrivateKey { return f.PrivateKey }
|
||||
func (f *FakeUser) GetPrivateKey() crypto.Signer { return f.PrivateKey }
|
||||
|
|
|
|||
|
|
@ -42,4 +42,4 @@ type mockUser struct {
|
|||
|
||||
func (u mockUser) GetEmail() string { return u.email }
|
||||
func (u mockUser) GetRegistration() *acme.ExtendedAccount { return u.regres }
|
||||
func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey }
|
||||
func (u mockUser) GetPrivateKey() crypto.Signer { return u.privatekey }
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ func (r *Registrar) ResolveAccountByKey(ctx context.Context) (*acme.ExtendedAcco
|
|||
}
|
||||
|
||||
// KeyRollover will attempt to change the account key.
|
||||
func (r *Registrar) KeyRollover(ctx context.Context, newKey crypto.PrivateKey) error {
|
||||
func (r *Registrar) KeyRollover(ctx context.Context, newKey crypto.Signer) error {
|
||||
return r.core.Accounts.KeyChange(ctx, newKey)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ import (
|
|||
type User interface {
|
||||
GetEmail() string
|
||||
GetRegistration() *acme.ExtendedAccount
|
||||
GetPrivateKey() crypto.PrivateKey
|
||||
GetPrivateKey() crypto.Signer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ type mockUser struct {
|
|||
|
||||
func (u mockUser) GetEmail() string { return u.email }
|
||||
func (u mockUser) GetRegistration() *acme.ExtendedAccount { return u.regres }
|
||||
func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey }
|
||||
func (u mockUser) GetPrivateKey() crypto.Signer { return u.privatekey }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue