github.com/greenpau/go-authcrunch@v1.1.4/pkg/idp/oauth/jwks_test.go (about) 1 // Copyright 2022 Paul Greenberg greenpau@outlook.com 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package oauth 16 17 import ( 18 "fmt" 19 "github.com/greenpau/go-authcrunch/internal/tests" 20 "github.com/greenpau/go-authcrunch/pkg/errors" 21 "testing" 22 ) 23 24 func TestValidateJwksKey(t *testing.T) { 25 var testcases = []struct { 26 name string 27 input *JwksKey 28 want map[string]interface{} 29 shouldErr bool 30 err error 31 }{ 32 { 33 name: "empty key", 34 input: &JwksKey{}, 35 shouldErr: true, 36 err: errors.ErrJwksKeyIDEmpty, 37 }, 38 { 39 name: "unsupported algorithm with rsa keys", 40 input: &JwksKey{ 41 KeyID: "0", 42 KeyType: "RSA", 43 Algorithm: "FOO", 44 }, 45 shouldErr: true, 46 err: errors.ErrJwksKeyAlgoUnsupported.WithArgs("FOO", "0"), 47 }, 48 { 49 name: "unsupported algorithm with shared keys", 50 input: &JwksKey{ 51 KeyID: "0", 52 KeyType: "oct", 53 Algorithm: "FOO", 54 SharedSecret: "FdFYFzERwC2uCBB46pZQi4GG85LujR8obt-KWRBICVQ", 55 }, 56 shouldErr: true, 57 err: errors.ErrJwksKeyAlgoUnsupported.WithArgs("FOO", "0"), 58 }, 59 { 60 name: "key type is empty", 61 input: &JwksKey{ 62 KeyID: "0", 63 Algorithm: "RS256", 64 }, 65 shouldErr: true, 66 err: errors.ErrJwksKeyTypeEmpty.WithArgs("0"), 67 }, 68 { 69 name: "key type is unsupported", 70 input: &JwksKey{ 71 KeyID: "0", 72 Algorithm: "RS256", 73 KeyType: "FOO", 74 }, 75 shouldErr: true, 76 err: errors.ErrJwksKeyTypeUnsupported.WithArgs("FOO", "0"), 77 }, 78 { 79 name: "key usage is unsupported", 80 input: &JwksKey{ 81 KeyID: "0", 82 Algorithm: "RS256", 83 KeyType: "RSA", 84 PublicKeyUse: "FOO", 85 }, 86 shouldErr: true, 87 err: errors.ErrJwksKeyUsageUnsupported.WithArgs("FOO", "0"), 88 }, 89 { 90 name: "key exponent is empty", 91 input: &JwksKey{ 92 KeyID: "0", 93 Algorithm: "RS256", 94 KeyType: "RSA", 95 PublicKeyUse: "sig", 96 }, 97 shouldErr: true, 98 err: errors.ErrJwksKeyExponentEmpty.WithArgs("0"), 99 }, 100 { 101 name: "key modulus is empty", 102 input: &JwksKey{ 103 KeyID: "0", 104 Algorithm: "RS256", 105 KeyType: "RSA", 106 PublicKeyUse: "sig", 107 Exponent: "foo", 108 }, 109 shouldErr: true, 110 err: errors.ErrJwksKeyModulusEmpty.WithArgs("0"), 111 }, 112 { 113 name: "key exponent decoding failure", 114 input: &JwksKey{ 115 KeyID: "0", 116 Algorithm: "RS256", 117 KeyType: "RSA", 118 PublicKeyUse: "sig", 119 Exponent: "foo", 120 Modulus: "bar", 121 }, 122 shouldErr: true, 123 err: errors.ErrJwksKeyDecodeExponent.WithArgs("0", "illegal base64 data at input byte 0"), 124 }, 125 { 126 name: "key exponent decoding failure", 127 input: &JwksKey{ 128 KeyID: "0", 129 Algorithm: "RS256", 130 KeyType: "RSA", 131 PublicKeyUse: "sig", 132 Exponent: "foo", 133 Modulus: "/", 134 }, 135 shouldErr: true, 136 err: errors.ErrJwksKeyDecodeModulus.WithArgs("0", "/===", "illegal base64 data at input byte 1"), 137 }, 138 { 139 name: "valid RSA256 key", 140 input: &JwksKey{ 141 KeyID: "wyMwK4A6CL9Qw11uofVeyQ119XyX-xykymkkXygZ5OM", 142 Algorithm: "RS256", 143 KeyType: "RSA", 144 PublicKeyUse: "sig", 145 Exponent: "AQAB", 146 Modulus: "ok6rvXu95337IxsDXrKzlIqw_I_zPDG8JyEw2CTOtNMoDi1QzpXQVMGj2snNEmvNYaCTmFf51" + 147 "I-EDgeFLLexr40jzBXlg72quV4aw4yiNuxkigW0gMA92OmaT2jMRIdDZM8mVokoxyPfLub2YnXHFq0XuUUgkX_" + 148 "TlutVhgGbyPN0M12teYZtMYo2AUzIRggONhHvnibHP0CPWDjCwSfp3On1Recn4DPxbn3DuGslF2myalmCtkujNcrhHLhwY" + 149 "PP-yZFb8e0XSNTcQvXaQxAqmnWH6NXcOtaeWMQe43PNTAyNinhndgI8ozG3Hz-1NzHssDH_yk6UYFSszhDbWAzyqw", 150 }, 151 }, 152 { 153 name: "valid RSA256 key2", 154 input: &JwksKey{ 155 KeyID: "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk", 156 Algorithm: "RS256", 157 KeyType: "RSA", 158 PublicKeyUse: "sig", 159 Exponent: "AQAB", 160 Modulus: "tVKUtcx_n9rt5afY_2WFNvU6PlFMggCatsZ3l4RjKxH0jgdLq6CScb0P3ZGX" + 161 "YbPzXvmmLiWZizpb-h0qup5jznOvOr-Dhw9908584BSgC83YacjWNqEK3urxhyE2jWjwRm" + 162 "2N95WGgb5mzE5XmZIvkvyXnn7X8dvgFPF5QwIngGsDG8LyHuJWlaDhr_EPLMW4wHvH0zZCu" + 163 "RMARIJmmqiMy3VD4ftq4nS5s8vJL0pVSrkuNojtokp84AtkADCDU_BUhrc2sIgfnvZ03ko" + 164 "CQRoZmWiHu86SuJZYkDFstVTVSR0hiXudFlfQ2rOhPlpObmku68lXw-7V-P7jwrQRFfQVXw", 165 }, 166 }, 167 { 168 name: "ec key curve is empty", 169 input: &JwksKey{ 170 KeyID: "0", 171 KeyType: "EC", 172 }, 173 shouldErr: true, 174 err: errors.ErrJwksKeyCurveEmpty.WithArgs("0"), 175 }, 176 { 177 name: "ec key curve is unsupported", 178 input: &JwksKey{ 179 KeyID: "0", 180 KeyType: "EC", 181 Curve: "FOO", 182 }, 183 shouldErr: true, 184 err: errors.ErrJwksKeyCurveUnsupported.WithArgs("FOO", "0"), 185 }, 186 { 187 name: "ec key curve has no coordinates", 188 input: &JwksKey{ 189 KeyID: "0", 190 KeyType: "EC", 191 Curve: "P-256", 192 }, 193 shouldErr: true, 194 err: errors.ErrJwksKeyCurveCoordNotFound.WithArgs("0"), 195 }, 196 { 197 name: "valid ES256 key", 198 input: &JwksKey{ 199 KeyID: "0", 200 KeyType: "EC", 201 Curve: "P-256", 202 CoordX: "5lhEug5xK4xBDZ2nAbaxLtaLiv85bxJ7ePd1dkO23HQ", 203 CoordY: "4aiK72sBeUAGkv0TaLsmwokYUYyNxGsS5EMIKwsNIKk", 204 }, 205 }, 206 { 207 name: "valid ES384 key", 208 input: &JwksKey{ 209 KeyID: "0", 210 KeyType: "EC", 211 Curve: "P-384", 212 CoordX: "Wyidjnd4VBA3nih1RZCJJ1EkKgHSApODejS_JCReqg6K0RhxaIzr9jh_NRslfjnd", 213 CoordY: "kcGQFUrRDHqcj1dTwL_SOyaf6cnkp8dL5NX70WiV3Ti97bFLrCE1dfRGpnCPW4R6", 214 }, 215 }, 216 { 217 name: "valid ES512 key", 218 input: &JwksKey{ 219 KeyID: "0", 220 KeyType: "EC", 221 Curve: "P-521", 222 CoordX: "AekpBQ8ST8a8VcfVOTNl353vSrDCLLJXmPk06wTjxrrjcBpXp5EOnYG_NjFZ6OvLFV1jSfS9tsz4qUxcWceqwQGk", 223 CoordY: "ADSmRA43Z1DSNx_RvcLI87cdL07l6jQyyBXMoxVg_l2Th-x3S1WDhjDly79ajL4Kkd0AZMaZmh9ubmf63e3kyMj2", 224 }, 225 }, 226 { 227 name: "shared secret key is empty", 228 input: &JwksKey{ 229 KeyID: "0", 230 KeyType: "oct", 231 }, 232 shouldErr: true, 233 err: errors.ErrJwksKeySharedSecretEmpty.WithArgs("0"), 234 }, 235 { 236 name: "valid HS256 key", 237 input: &JwksKey{ 238 KeyID: "fcd54a6f-9708-4805-ba9c-c05356066a56", 239 Algorithm: "HS256", 240 KeyType: "oct", 241 SharedSecret: "FdFYFzERwC2uCBB46pZQi4GG85LujR8obt-KWRBICVQ", 242 }, 243 }, 244 } 245 for _, tc := range testcases { 246 t.Run(tc.name, func(t *testing.T) { 247 msgs := []string{fmt.Sprintf("test name: %s", tc.name)} 248 msgs = append(msgs, fmt.Sprintf("config: %v", tc.input)) 249 err := tc.input.Validate() 250 if tests.EvalErrWithLog(t, err, nil, tc.shouldErr, tc.err, msgs) { 251 return 252 } 253 // got := make(map[string]interface{}) 254 // got["config"] = config 255 // tests.EvalObjectsWithLog(t, "config", tc.want, got, msgs) 256 }) 257 } 258 }