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  }