1 package jwk_test
2
3 import (
4 "context"
5 "fmt"
6 "testing"
7
8 "github.com/lestrrat-go/jwx/internal/json"
9
10 "github.com/lestrrat-go/jwx/jwa"
11 "github.com/lestrrat-go/jwx/jwk"
12 "github.com/stretchr/testify/assert"
13 )
14
15 func TestIterator(t *testing.T) {
16 commonValues := map[string]interface{}{
17 jwk.AlgorithmKey: "dummy",
18 jwk.KeyIDKey: "dummy-kid",
19 jwk.KeyUsageKey: "dummy-usage",
20 jwk.KeyOpsKey: jwk.KeyOperationList{jwk.KeyOpSign, jwk.KeyOpVerify, jwk.KeyOpEncrypt, jwk.KeyOpDecrypt, jwk.KeyOpWrapKey, jwk.KeyOpUnwrapKey, jwk.KeyOpDeriveKey, jwk.KeyOpDeriveBits},
21 "private": "dummy-private",
22 }
23
24 verifyIterators := func(t *testing.T, v jwk.Key, expected map[string]interface{}) {
25 t.Helper()
26 t.Run("Iterate", func(t *testing.T) {
27 seen := make(map[string]interface{})
28 for iter := v.Iterate(context.TODO()); iter.Next(context.TODO()); {
29 pair := iter.Pair()
30 seen[pair.Key.(string)] = pair.Value
31
32 getV, ok := v.Get(pair.Key.(string))
33 if !assert.True(t, ok, `v.Get should succeed for key %#v`, pair.Key) {
34 return
35 }
36 if !assert.Equal(t, pair.Value, getV, `pair.Value should match value from v.Get()`) {
37 return
38 }
39 }
40 if !assert.Equal(t, expected, seen, `values should match`) {
41 return
42 }
43 })
44 t.Run("Walk", func(t *testing.T) {
45 seen := make(map[string]interface{})
46 v.Walk(context.TODO(), jwk.HeaderVisitorFunc(func(key string, value interface{}) error {
47 seen[key] = value
48 return nil
49 }))
50 if !assert.Equal(t, expected, seen, `values should match`) {
51 return
52 }
53 })
54 t.Run("AsMap", func(t *testing.T) {
55 seen, err := v.AsMap(context.TODO())
56 if !assert.NoError(t, err, `v.AsMap should succeed`) {
57 return
58 }
59 if !assert.Equal(t, expected, seen, `values should match`) {
60 return
61 }
62 })
63 }
64
65 type iterTestCase struct {
66 Extras map[string]interface{}
67 Func func() jwk.Key
68 }
69
70 testcases := []iterTestCase{
71 {
72 Extras: map[string]interface{}{
73 jwk.RSANKey: []byte("0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"),
74 jwk.RSAEKey: []byte("AQAB"),
75 jwk.RSADKey: []byte("X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q"),
76 jwk.RSAPKey: []byte("83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs"),
77 jwk.RSAQKey: []byte("3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk"),
78 jwk.RSADPKey: []byte("G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0"),
79 jwk.RSADQKey: []byte("s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk"),
80 jwk.RSAQIKey: []byte("GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU"),
81 },
82 Func: func() jwk.Key {
83 return jwk.NewRSAPrivateKey()
84 },
85 },
86 {
87 Extras: map[string]interface{}{
88 jwk.RSANKey: []byte("0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"),
89 jwk.RSAEKey: []byte("AQAB"),
90 },
91 Func: func() jwk.Key {
92 return jwk.NewRSAPublicKey()
93 },
94 },
95 {
96 Extras: map[string]interface{}{
97 jwk.ECDSACrvKey: jwa.P256,
98 jwk.ECDSAXKey: []byte("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4"),
99 jwk.ECDSAYKey: []byte("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"),
100 jwk.ECDSADKey: []byte("870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE"),
101 },
102 Func: func() jwk.Key {
103 return jwk.NewECDSAPrivateKey()
104 },
105 },
106 {
107 Extras: map[string]interface{}{
108 jwk.ECDSACrvKey: jwa.P256,
109 jwk.ECDSAXKey: []byte("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4"),
110 jwk.ECDSAYKey: []byte("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"),
111 },
112 Func: func() jwk.Key {
113 return jwk.NewECDSAPublicKey()
114 },
115 },
116 {
117 Extras: map[string]interface{}{
118 jwk.SymmetricOctetsKey: []byte("abcd"),
119 },
120 Func: func() jwk.Key {
121 return jwk.NewSymmetricKey()
122 },
123 },
124 }
125 for _, test := range testcases {
126 key := test.Func()
127 key2 := test.Func()
128 expected := make(map[string]interface{})
129 expected[jwk.KeyTypeKey] = key.KeyType()
130 for k, v := range commonValues {
131 if !assert.NoError(t, key.Set(k, v), `key.Set %#v should succeed`, k) {
132 return
133 }
134 expected[k] = v
135 }
136 for k, v := range test.Extras {
137 if !assert.NoError(t, key.Set(k, v), `key.Set %#v should succeed`, k) {
138 return
139 }
140 expected[k] = v
141 }
142
143 t.Run(fmt.Sprintf("%T", key), func(t *testing.T) {
144 verifyIterators(t, key, expected)
145 })
146 t.Run(fmt.Sprintf("%T (after json roundtripping)", key), func(t *testing.T) {
147 buf, err := json.Marshal(key)
148 if !assert.NoError(t, err, `json.Marshal should succeed`) {
149 return
150 }
151
152 if !assert.NoError(t, json.Unmarshal(buf, key2), `json.Unmarshal should succeed`) {
153 return
154 }
155
156 verifyIterators(t, key2, expected)
157 })
158 }
159 }
160
View as plain text