aboutsummaryrefslogtreecommitdiff
path: root/signer.go
diff options
context:
space:
mode:
Diffstat (limited to 'signer.go')
-rw-r--r--signer.go67
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
+}