1/*- 2 * Copyright 2018 Square Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package jose 18 19import ( 20 "fmt" 21 "testing" 22) 23 24type signWrapper struct { 25 pk *JSONWebKey 26 wrapped payloadSigner 27 algs []SignatureAlgorithm 28} 29 30var _ = OpaqueSigner(&signWrapper{}) 31 32func (sw *signWrapper) Algs() []SignatureAlgorithm { 33 return sw.algs 34} 35 36func (sw *signWrapper) Public() *JSONWebKey { 37 return sw.pk 38} 39 40func (sw *signWrapper) SignPayload(payload []byte, alg SignatureAlgorithm) ([]byte, error) { 41 sig, err := sw.wrapped.signPayload(payload, alg) 42 if err != nil { 43 return nil, err 44 } 45 return sig.Signature, nil 46} 47 48type verifyWrapper struct { 49 wrapped []payloadVerifier 50} 51 52var _ = OpaqueVerifier(&verifyWrapper{}) 53 54func (vw *verifyWrapper) VerifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { 55 if len(vw.wrapped) == 0 { 56 return fmt.Errorf("error: verifier had no keys") 57 } 58 var err error 59 for _, v := range vw.wrapped { 60 err = v.verifyPayload(payload, signature, alg) 61 if err == nil { 62 return nil 63 } 64 } 65 return err 66} 67 68func TestRoundtripsJWSOpaque(t *testing.T) { 69 sigAlgs := []SignatureAlgorithm{RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, EdDSA} 70 71 serializers := []func(*JSONWebSignature) (string, error){ 72 func(obj *JSONWebSignature) (string, error) { return obj.CompactSerialize() }, 73 func(obj *JSONWebSignature) (string, error) { return obj.FullSerialize(), nil }, 74 } 75 76 corrupter := func(obj *JSONWebSignature) {} 77 78 for _, alg := range sigAlgs { 79 signingKey, verificationKey := GenerateSigningTestKey(alg) 80 81 for i, serializer := range serializers { 82 sw := makeOpaqueSigner(t, signingKey, alg) 83 vw := makeOpaqueVerifier(t, []interface{}{verificationKey}, alg) 84 85 err := RoundtripJWS(alg, serializer, corrupter, sw, verificationKey, "test_nonce") 86 if err != nil { 87 t.Error(err, alg, i) 88 } 89 90 err = RoundtripJWS(alg, serializer, corrupter, signingKey, vw, "test_nonce") 91 if err != nil { 92 t.Error(err, alg, i) 93 } 94 95 err = RoundtripJWS(alg, serializer, corrupter, sw, vw, "test_nonce") 96 if err != nil { 97 t.Error(err, alg, i) 98 } 99 } 100 } 101} 102 103func makeOpaqueSigner(t *testing.T, signingKey interface{}, alg SignatureAlgorithm) *signWrapper { 104 ri, err := makeJWSRecipient(alg, signingKey) 105 if err != nil { 106 t.Fatal(err) 107 } 108 return &signWrapper{ 109 wrapped: ri.signer, 110 algs: []SignatureAlgorithm{alg}, 111 pk: &JSONWebKey{Key: ri.publicKey()}, 112 } 113} 114 115func makeOpaqueVerifier(t *testing.T, verificationKey []interface{}, alg SignatureAlgorithm) *verifyWrapper { 116 var verifiers []payloadVerifier 117 for _, vk := range verificationKey { 118 verifier, err := newVerifier(vk) 119 if err != nil { 120 t.Fatal(err) 121 } 122 verifiers = append(verifiers, verifier) 123 } 124 return &verifyWrapper{wrapped: verifiers} 125} 126 127func TestOpaqueSignerKeyRotation(t *testing.T) { 128 129 sigAlgs := []SignatureAlgorithm{RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, EdDSA} 130 131 serializers := []func(*JSONWebSignature) (string, error){ 132 func(obj *JSONWebSignature) (string, error) { return obj.CompactSerialize() }, 133 func(obj *JSONWebSignature) (string, error) { return obj.FullSerialize(), nil }, 134 } 135 136 for _, alg := range sigAlgs { 137 for i, serializer := range serializers { 138 sk1, pk1 := GenerateSigningTestKey(alg) 139 sk2, pk2 := GenerateSigningTestKey(alg) 140 141 sw := makeOpaqueSigner(t, sk1, alg) 142 sw.pk.KeyID = "first" 143 vw := makeOpaqueVerifier(t, []interface{}{pk1, pk2}, alg) 144 145 signer, err := NewSigner( 146 SigningKey{Algorithm: alg, Key: sw}, 147 &SignerOptions{NonceSource: staticNonceSource("test_nonce")}, 148 ) 149 if err != nil { 150 t.Fatal(err, alg, i) 151 } 152 153 jws1, err := signer.Sign([]byte("foo bar baz")) 154 if err != nil { 155 t.Fatal(err, alg, i) 156 } 157 jws1 = rtSerialize(t, serializer, jws1, vw) 158 if kid := jws1.Signatures[0].Protected.KeyID; kid != "first" { 159 t.Errorf("expected kid %q but got %q", "first", kid) 160 } 161 162 swNext := makeOpaqueSigner(t, sk2, alg) 163 swNext.pk.KeyID = "next" 164 sw.wrapped = swNext.wrapped 165 sw.pk = swNext.pk 166 167 jws2, err := signer.Sign([]byte("foo bar baz next")) 168 if err != nil { 169 t.Error(err, alg, i) 170 } 171 jws2 = rtSerialize(t, serializer, jws2, vw) 172 if kid := jws2.Signatures[0].Protected.KeyID; kid != "next" { 173 t.Errorf("expected kid %q but got %q", "next", kid) 174 } 175 } 176 } 177} 178 179func rtSerialize(t *testing.T, serializer func(*JSONWebSignature) (string, error), sig *JSONWebSignature, vk interface{}) *JSONWebSignature { 180 b, err := serializer(sig) 181 if err != nil { 182 t.Fatal(err) 183 } 184 sig, err = ParseSigned(b) 185 if err != nil { 186 t.Fatal(err) 187 } 188 if _, err := sig.Verify(vk); err != nil { 189 t.Fatal(err) 190 } 191 return sig 192} 193