package acme import ( "crypto" "crypto/rsa" "encoding/base64" "io" "net/mail" "strings" "github.com/square/go-jose" ) // KeySize is a default RSA key size const KeySize = 2048 // Account ... type Account struct { contact Contacts privKey *rsa.PrivateKey signer jose.Signer nonce chan string } // NewAccount ... func NewAccount(key *rsa.PrivateKey) (*Account, error) { signer, err := jose.NewSigner(jose.RS256, key) if err != nil { return nil, err } return &Account{privKey: key, signer: signer}, nil } func (a *Account) AddMail(email string) error { m, err := mail.ParseAddress(email) if err != nil { return err } a.contact = append(a.contact, Mail(m.Address)) return nil } func (a *Account) AddPhone(phone string) error { if ph := strings.TrimSpace(phone); ph != "" { a.contact = append(a.contact, Phone(ph)) } return nil } // Signer describes a signing interface type Signer interface { Sign([]byte, jose.NonceSource) (io.Reader, error) } type Thumber interface { Thumb(string) (string, error) } type ThumbSigner interface { Signer Thumber } // Sign implements Signer interface func (a *Account) Sign(msg []byte, n jose.NonceSource) (io.Reader, error) { a.signer.SetNonceSource(n) obj, err := a.signer.Sign(msg) if err != nil { return nil, err } return strings.NewReader(obj.FullSerialize()), nil } func (a *Account) Thumb(token string) (string, error) { k := &jose.JsonWebKey{Key: a.privKey.Public(), Algorithm: "RSA"} thumb, err := k.Thumbprint(crypto.SHA256) if err != nil { return "", err } return token + "." + base64.RawURLEncoding.EncodeToString(thumb), nil }