aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-05-22 16:48:10 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-05-22 16:48:10 +0200
commitddd02682605ebad46cd36714981a6859c69f349e (patch)
treea2f12fee5118e6480fdfb0a0bb4a8bebf974f052
parent9664c9a60a10cf7a91fbf9e93b595f2155a9543a (diff)
Refactor signer
-rw-r--r--provider.go39
-rw-r--r--signer.go49
2 files changed, 51 insertions, 37 deletions
diff --git a/provider.go b/provider.go
index 78855f0..5c43655 100644
--- a/provider.go
+++ b/provider.go
@@ -1,6 +1,7 @@
package acme
import (
+ "crypto"
"encoding/json"
"errors"
"io/ioutil"
@@ -47,12 +48,10 @@ type Meta struct {
// Provider ...
type Provider struct {
Directory
- nonces chan string
http.Client
}
var (
- errNoNonces = errors.New("out of nonces")
errContentType = errors.New("unknown content type")
errChalType = errors.New("unknown challenge")
errStatus = errors.New("unexpected status")
@@ -67,37 +66,17 @@ const (
poll = time.Second
)
-// RoundTrip extracts nonces from HTTP reponse
-func (p *Provider) RoundTrip(req *http.Request) (*http.Response, error) {
- resp, err := http.DefaultTransport.RoundTrip(req)
+// DialProvider fetches directory and initializes first nonce
+func DialProvider(directory string, key crypto.PrivateKey) (*Provider, error) {
+ sig, err := NewSigner(key)
if err != nil {
return nil, err
}
- nonce := resp.Header.Get("Replay-Nonce")
- if nonce == "" {
- return nil, errNoNonces
- }
- if len(p.nonces) == cap(p.nonces) {
- <-p.nonces // drop oldest
- }
- p.nonces <- nonce
- return resp, nil
-}
-
-// Nonce implements jose nonce provider
-func (p *Provider) Nonce() (string, error) {
- select {
- case nonce := <-p.nonces:
- return nonce, nil
- case <-time.After(timeout):
- return "", errNoNonces
+ p := &Provider{
+ Client: http.Client{
+ Transport: sig,
+ },
}
-}
-
-// DialProvider fetches directory and initializes first nonce
-func DialProvider(directory string) (*Provider, error) {
- p := &Provider{nonces: make(chan string, 100)}
- p.Client = http.Client{Transport: p}
if directory == "" {
directory = LE1
}
@@ -113,7 +92,7 @@ func (p *Provider) post(uri string, s *Signer, v interface{}) (*http.Response, e
if err != nil {
return nil, err
}
- signed, err := s.Sign(msg, p)
+ signed, err := s.Sign(msg)
if err != nil {
return nil, err
}
diff --git a/signer.go b/signer.go
index 2ee0ed4..6829995 100644
--- a/signer.go
+++ b/signer.go
@@ -5,7 +5,9 @@ import (
"crypto/ecdsa"
"crypto/rsa"
"encoding/base64"
+ "errors"
"io"
+ "net/http"
"strings"
"github.com/square/go-jose"
@@ -14,14 +16,17 @@ import (
// KeySize is a default RSA key size
const KeySize = 2048
+var errNoNonces = errors.New("out of nonces")
+
// Signer ...
type Signer struct {
signer jose.Signer
thumb string
+ nonces chan string
}
func NewSigner(privKey crypto.PrivateKey) (*Signer, error) {
- thumb := func(alg string, pubKey crypto.PublicKey) (string, error) {
+ thumb := func(pubKey crypto.PublicKey, alg string) (string, error) {
wk := &jose.JsonWebKey{Key: pubKey, Algorithm: alg}
t, err := wk.Thumbprint(crypto.SHA256)
return base64.RawURLEncoding.EncodeToString(t), err
@@ -32,29 +37,59 @@ func NewSigner(privKey crypto.PrivateKey) (*Signer, error) {
if err != nil {
return nil, err
}
- t, err := thumb("RSA", k.Public())
+ t, err := thumb(k.Public(), "RSA")
if err != nil {
return nil, err
}
- return &Signer{signer: s, thumb: t}, nil
+ sig := &Signer{signer: s, thumb: t, nonces: make(chan string, 100)}
+ sig.signer.SetNonceSource(sig)
+ return sig, nil
case *ecdsa.PrivateKey:
s, err := jose.NewSigner(jose.ES384, k)
if err != nil {
return nil, err
}
- t, err := thumb("EC", k.Public())
+ t, err := thumb(k.Public(), "EC")
if err != nil {
return nil, err
}
- return &Signer{signer: s, thumb: t}, nil
+ sig := &Signer{signer: s, thumb: t, nonces: make(chan string, 100)}
+ sig.signer.SetNonceSource(sig)
+ return sig, nil
default:
return nil, ErrKeyType
}
}
+// Nonce implements jose nonce provider
+func (s Signer) Nonce() (string, error) {
+ select {
+ case nonce := <-s.nonces:
+ return nonce, nil
+ default:
+ return "", errNoNonces
+ }
+}
+
+// RoundTrip extracts nonces from HTTP response
+func (s Signer) RoundTrip(req *http.Request) (*http.Response, error) {
+ resp, err := http.DefaultTransport.RoundTrip(req)
+ if err != nil {
+ return nil, err
+ }
+ nonce := resp.Header.Get("Replay-Nonce")
+ if nonce == "" {
+ return nil, errNoNonces
+ }
+ if len(s.nonces) == cap(s.nonces) {
+ <-s.nonces // drop oldest
+ }
+ s.nonces <- nonce
+ return resp, nil
+}
+
// Sign implements Signer interface
-func (s Signer) Sign(msg []byte, n jose.NonceSource) (io.Reader, error) {
- s.signer.SetNonceSource(n)
+func (s Signer) Sign(msg []byte) (io.Reader, error) {
obj, err := s.signer.Sign(msg)
if err != nil {
return nil, err