github.com/lestrrat-go/jwx/v2@v2.0.21/jwe/headers_test.go (about) 1 package jwe_test 2 3 import ( 4 "context" 5 "reflect" 6 "testing" 7 8 "github.com/lestrrat-go/jwx/v2/cert" 9 "github.com/lestrrat-go/jwx/v2/internal/jwxtest" 10 "github.com/lestrrat-go/jwx/v2/jwa" 11 "github.com/lestrrat-go/jwx/v2/jwe" 12 "github.com/lestrrat-go/jwx/v2/jwk" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 var zeroval reflect.Value 17 18 func TestHeaders(t *testing.T) { 19 certSrc := []string{ 20 "MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYwMTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3HKrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQmVZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpRSgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRTcDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEuMB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDSkdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0fBD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUHAgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IGOgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMUA2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTXRE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuHqDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWVU+4=", 21 "MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoXDTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHUTBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMbVmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwgSW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlvbiBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEgMB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUwAwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdvZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUdIAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4OWBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0VmsfSxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==", 22 "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd", 23 } 24 var certs cert.Chain 25 for _, src := range certSrc { 26 _ = certs.AddString(src) 27 } 28 29 rawKey, err := jwxtest.GenerateEcdsaKey(jwa.P521) 30 if !assert.NoError(t, err, `jwxtest.GenerateEcdsaKey should succeed`) { 31 return 32 } 33 privKey, err := jwk.FromRaw(rawKey) 34 if !assert.NoError(t, err, `jwk.FromRaw should succeed`) { 35 return 36 } 37 38 pubKey, err := jwk.FromRaw(rawKey.PublicKey) 39 if !assert.NoError(t, err, `jwk.FromRaw should succeed`) { 40 return 41 } 42 43 data := []struct { 44 Key string 45 Value interface{} 46 Expected interface{} 47 Method string 48 }{ 49 { 50 Key: jwe.AgreementPartyUInfoKey, 51 Value: []byte("apu foobarbaz"), 52 Method: "AgreementPartyUInfo", 53 }, 54 {Key: jwe.AgreementPartyVInfoKey, Value: []byte("apv foobarbaz")}, 55 {Key: jwe.CompressionKey, Value: jwa.Deflate}, 56 {Key: jwe.ContentEncryptionKey, Value: jwa.A128GCM}, 57 { 58 Key: jwe.ContentTypeKey, 59 Value: "application/json", 60 Method: "ContentType", 61 }, 62 { 63 Key: jwe.CriticalKey, 64 Value: []string{"crit blah"}, 65 Method: "Critical", 66 }, 67 { 68 Key: jwe.EphemeralPublicKeyKey, 69 Value: pubKey, 70 Method: "EphemeralPublicKey", 71 }, 72 { 73 Key: jwe.JWKKey, 74 Value: privKey, 75 Method: "JWK", 76 }, 77 { 78 Key: jwe.JWKSetURLKey, 79 Value: "http://github.com/lestrrat-go/jwx/v2", 80 Method: "JWKSetURL", 81 }, 82 { 83 Key: jwe.KeyIDKey, 84 Value: "kid blah", 85 Method: "KeyID", 86 }, 87 { 88 Key: jwe.TypeKey, 89 Value: "typ blah", 90 Method: "Type", 91 }, 92 { 93 Key: jwe.X509CertChainKey, 94 Value: &certs, 95 Method: "X509CertChain", 96 }, 97 { 98 Key: jwe.X509CertThumbprintKey, 99 Value: "x5t blah", 100 Method: "X509CertThumbprint", 101 }, 102 { 103 Key: jwe.X509CertThumbprintS256Key, 104 Value: "x5t#256 blah", 105 Method: "X509CertThumbprintS256", 106 }, 107 { 108 Key: jwe.X509URLKey, 109 Value: "http://github.com/lestrrat-go/jwx/v2", 110 Method: "X509URL", 111 }, 112 {Key: "private", Value: "boofoo"}, 113 } 114 115 base := jwe.NewHeaders() 116 117 t.Run("Set values", func(t *testing.T) { 118 // DO NOT RUN THIS IN PARALLEL. THIS IS AN INITIALIZER 119 for _, tc := range data { 120 if !assert.NoError(t, base.Set(tc.Key, tc.Value), "Headers.Set should succeed") { 121 return 122 } 123 } 124 }) 125 126 t.Run("Set/Get", func(t *testing.T) { 127 h := jwe.NewHeaders() 128 ctx := context.Background() 129 130 for iter := base.Iterate(ctx); iter.Next(ctx); { 131 pair := iter.Pair() 132 if !assert.NoError(t, h.Set(pair.Key.(string), pair.Value), `h.Set should be successful`) { 133 return 134 } 135 } 136 for _, tc := range data { 137 var values []interface{} 138 viaGet, ok := h.Get(tc.Key) 139 if !assert.True(t, ok, "value for %s should exist", tc.Key) { 140 return 141 } 142 values = append(values, viaGet) 143 144 if method := tc.Method; method != "" { 145 m := reflect.ValueOf(h).MethodByName(method) 146 if !assert.NotEqual(t, m, zeroval, "method %s should be available", method) { 147 return 148 } 149 150 ret := m.Call(nil) 151 if !assert.Len(t, ret, 1, `should get exactly 1 value as return value`) { 152 return 153 } 154 values = append(values, ret[0].Interface()) 155 } 156 157 expected := tc.Expected 158 if expected == nil { 159 expected = tc.Value 160 } 161 for i, got := range values { 162 if !assert.Equal(t, expected, got, "value %d should match", i) { 163 return 164 } 165 } 166 } 167 }) 168 t.Run("PrivateParams", func(t *testing.T) { 169 h := base 170 pp, err := h.AsMap(context.Background()) 171 if !assert.NoError(t, err, `h.AsMap should succeed`) { 172 return 173 } 174 175 v, ok := pp["private"] 176 if !assert.True(t, ok, "key 'private' should exists") { 177 return 178 } 179 180 if !assert.Equal(t, v, "boofoo", "value for 'private' should match") { 181 return 182 } 183 }) 184 t.Run("Encode", func(t *testing.T) { 185 h1 := jwe.NewHeaders() 186 h1.Set(jwe.AlgorithmKey, jwa.A128GCMKW) 187 h1.Set("foo", "bar") 188 189 buf, err := h1.Encode() 190 if !assert.NoError(t, err, `h1.Encode should succeed`) { 191 return 192 } 193 194 h2 := jwe.NewHeaders() 195 if !assert.NoError(t, h2.Decode(buf), `h2.Decode should succeed`) { 196 return 197 } 198 199 if !assert.Equal(t, h1, h2, `objects should match`) { 200 return 201 } 202 }) 203 204 t.Run("Iterator", func(t *testing.T) { 205 expected := map[string]interface{}{} 206 for _, tc := range data { 207 v := tc.Value 208 if expected := tc.Expected; expected != nil { 209 v = expected 210 } 211 expected[tc.Key] = v 212 } 213 214 v := base 215 t.Run("Iterate", func(t *testing.T) { 216 seen := make(map[string]interface{}) 217 for iter := v.Iterate(context.TODO()); iter.Next(context.TODO()); { 218 pair := iter.Pair() 219 seen[pair.Key.(string)] = pair.Value 220 221 getV, ok := v.Get(pair.Key.(string)) 222 if !assert.True(t, ok, `v.Get should succeed for key %#v`, pair.Key) { 223 return 224 } 225 if !assert.Equal(t, pair.Value, getV, `pair.Value should match value from v.Get()`) { 226 return 227 } 228 } 229 if !assert.Equal(t, expected, seen, `values should match`) { 230 return 231 } 232 }) 233 t.Run("Walk", func(t *testing.T) { 234 seen := make(map[string]interface{}) 235 v.Walk(context.TODO(), jwk.HeaderVisitorFunc(func(key string, value interface{}) error { 236 seen[key] = value 237 return nil 238 })) 239 if !assert.Equal(t, expected, seen, `values should match`) { 240 return 241 } 242 }) 243 t.Run("AsMap", func(t *testing.T) { 244 m, err := v.AsMap(context.TODO()) 245 if !assert.NoError(t, err, `v.AsMap should succeed`) { 246 return 247 } 248 if !assert.Equal(t, expected, m, `values should match`) { 249 return 250 } 251 }) 252 t.Run("Remove", func(t *testing.T) { 253 h := base 254 for iter := h.Iterate(context.TODO()); iter.Next(context.TODO()); { 255 pair := iter.Pair() 256 h.Remove(pair.Key.(string)) 257 } 258 259 m, err := h.AsMap(context.TODO()) 260 if !assert.NoError(t, err, `h.AsMap should succeed`) { 261 return 262 } 263 if !assert.Len(t, m, 0, `len should be zero`) { 264 return 265 } 266 }) 267 }) 268 }