1
16
17 package cryptosigner
18
19 import (
20 "bytes"
21 "crypto"
22 "crypto/ecdsa"
23 "crypto/elliptic"
24 "crypto/rand"
25 "crypto/rsa"
26 "fmt"
27 "testing"
28
29 "golang.org/x/crypto/ed25519"
30 "gopkg.in/square/go-jose.v2"
31 )
32
33 func TestRoundtripsJWSCryptoSigner(t *testing.T) {
34 sigAlgs := []jose.SignatureAlgorithm{jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512, jose.ES256, jose.ES384, jose.ES512, jose.EdDSA}
35
36 serializers := []func(*jose.JSONWebSignature) (string, error){
37 func(obj *jose.JSONWebSignature) (string, error) { return obj.CompactSerialize() },
38 func(obj *jose.JSONWebSignature) (string, error) { return obj.FullSerialize(), nil },
39 }
40
41 for _, alg := range sigAlgs {
42 signingKey, verificationKey := generateSigningTestKey(alg)
43
44 for i, serializer := range serializers {
45 err := roundtripJWS(alg, serializer, Opaque(signingKey.(crypto.Signer)), verificationKey)
46 if err != nil {
47 t.Error(err, alg, i)
48 }
49 }
50 }
51 }
52
53 type staticNonceSource string
54
55 func (sns staticNonceSource) Nonce() (string, error) {
56 return string(sns), nil
57 }
58
59 func roundtripJWS(sigAlg jose.SignatureAlgorithm, serializer func(*jose.JSONWebSignature) (string, error), signingKey interface{}, verificationKey interface{}) error {
60 nonce := "test_nonce"
61 opts := &jose.SignerOptions{
62 NonceSource: staticNonceSource(nonce),
63 }
64
65 signer, err := jose.NewSigner(jose.SigningKey{Algorithm: sigAlg, Key: signingKey}, opts)
66 if err != nil {
67 return fmt.Errorf("error on new signer: %s", err)
68 }
69
70 input := []byte("Lorem ipsum dolor sit amet")
71 obj, err := signer.Sign(input)
72 if err != nil {
73 return fmt.Errorf("error on sign: %s", err)
74 }
75
76 msg, err := serializer(obj)
77 if err != nil {
78 return fmt.Errorf("error on serialize: %s", err)
79 }
80
81 obj, err = jose.ParseSigned(msg)
82 if err != nil {
83 return fmt.Errorf("error on parse: %s", err)
84 }
85
86 output, err := obj.Verify(verificationKey)
87 if err != nil {
88 return fmt.Errorf("error on verify: %s", err)
89 }
90
91
92 for i, sig := range obj.Signatures {
93 if sig.Header.JSONWebKey != nil {
94 _, err = obj.Verify(sig.Header.JSONWebKey)
95 if err != nil {
96 return fmt.Errorf("error on verify with embedded key %d: %s", i, err)
97 }
98 }
99
100
101 if sig.Header.Nonce != nonce {
102 return fmt.Errorf("Incorrect nonce returned: [%s]", sig.Header.Nonce)
103 }
104 }
105
106 if bytes.Compare(output, input) != 0 {
107 return fmt.Errorf("input/output do not match, got '%s', expected '%s'", output, input)
108 }
109
110 return nil
111 }
112
113 func generateSigningTestKey(sigAlg jose.SignatureAlgorithm) (sig, ver interface{}) {
114 switch sigAlg {
115 case jose.EdDSA:
116 ver, sig, _ = ed25519.GenerateKey(rand.Reader)
117 case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
118 rsaTestKey, _ := rsa.GenerateKey(rand.Reader, 2048)
119 sig = rsaTestKey
120 ver = &rsaTestKey.PublicKey
121 case jose.ES256:
122 key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
123 sig = key
124 ver = &key.PublicKey
125 case jose.ES384:
126 key, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
127 sig = key
128 ver = &key.PublicKey
129 case jose.ES512:
130 key, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
131 sig = key
132 ver = &key.PublicKey
133 default:
134 panic("Must update test case")
135 }
136 return
137 }
138
View as plain text