diff options
Diffstat (limited to 'signer.go')
-rw-r--r-- | signer.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/signer.go b/signer.go new file mode 100644 index 0000000..a513d6e --- /dev/null +++ b/signer.go @@ -0,0 +1,67 @@ +package acme + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "encoding/base64" + "io" + "strings" + + "github.com/square/go-jose" +) + +// KeySize is a default RSA key size +const KeySize = 2048 + +// Signer ... +type Signer struct { + signer jose.Signer + thumb string +} + +func NewSigner(privKey crypto.PrivateKey) (*Signer, error) { + thumb := func(alg string, pubKey crypto.PublicKey) (string, error) { + wk := &jose.JsonWebKey{Key: pubKey, Algorithm: alg} + t, err := wk.Thumbprint(crypto.SHA256) + return base64.RawURLEncoding.EncodeToString(t), err + } + switch k := privKey.(type) { + case *rsa.PrivateKey: + s, err := jose.NewSigner(jose.RS256, k) + if err != nil { + return nil, err + } + t, err := thumb("RSA", k.Public()) + if err != nil { + return nil, err + } + return &Signer{signer: s, thumb: t}, nil + case *ecdsa.PrivateKey: + s, err := jose.NewSigner(jose.ES384, k) + if err != nil { + return nil, err + } + t, err := thumb("EC", k.Public()) + if err != nil { + return nil, err + } + return &Signer{signer: s, thumb: t}, nil + default: + return nil, errKeyType + } +} + +// Sign implements Signer interface +func (s Signer) Sign(msg []byte, n jose.NonceSource) (io.Reader, error) { + s.signer.SetNonceSource(n) + obj, err := s.signer.Sign(msg) + if err != nil { + return nil, err + } + return strings.NewReader(obj.FullSerialize()), nil +} + +func (s Signer) KeyAuth(token string) string { + return token + "." + s.thumb +} |