go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/auth/openid/json_web_keys_test.go (about) 1 // Copyright 2017 The LUCI Authors. 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 openid 16 17 import ( 18 "context" 19 "crypto/rsa" 20 "testing" 21 22 "go.chromium.org/luci/server/auth/signing/signingtest" 23 24 . "github.com/smartystreets/goconvey/convey" 25 . "go.chromium.org/luci/common/testing/assertions" 26 ) 27 28 func TestParseJSONWebKeySet(t *testing.T) { 29 t.Parallel() 30 31 Convey("Happy path", t, func() { 32 keys, err := NewJSONWebKeySet(&JSONWebKeySetStruct{ 33 Keys: []JSONWebKeyStruct{ 34 { 35 Kty: "RSA", 36 Alg: "RS256", 37 Use: "sig", 38 Kid: "key-1", 39 N: "sJ46htmsgvo99FyibDKBh6zHGr2hldxfHt-6y9VTrDo3jfuFeA8xFG3Lb9LkJE4qlCvC9QRv3S0TWhQcTg9uGN2mY7B7ccIRaD2AL2hh87mFAkQzoRPxg5lvS6QisgiFQcH-oea-4iBYlBHyMemoXR8pRSwTeQKxzvZ2zohl5c-yE77vhrmDV9_n3viJH1YBYJk2weAj9Pqcfj7_cLF6tR1vd4voTL29WrWJwkO2KG6FcXrc0DQQba8nXPc-TFJd1Z9aSyzxS91rxnj8wnMbPdXPfG2jryT1Dg_LhWtDjIG7m2ZVN-_wL1hHhxC6m7yl4jSIaAO5rjKMToq5wrlgVQ", 40 E: "AQAB", 41 }, 42 { 43 Kty: "SOMETHING-ELSE", 44 }, 45 }, 46 }) 47 So(err, ShouldBeNil) 48 So(len(keys.keys), ShouldEqual, 1) 49 So(keys.keys["key-1"].E, ShouldEqual, 65537) 50 }) 51 52 Convey("No key ID", t, func() { 53 _, err := NewJSONWebKeySet(&JSONWebKeySetStruct{ 54 Keys: []JSONWebKeyStruct{ 55 { 56 Kty: "RSA", 57 Alg: "RS256", 58 Use: "sig", 59 N: "sJ46htmsgvo99FyibD", 60 E: "AQAB", 61 }, 62 }, 63 }) 64 So(err, ShouldErrLike, "missing 'kid' field") 65 }) 66 67 Convey("Bad e", t, func() { 68 _, err := NewJSONWebKeySet(&JSONWebKeySetStruct{ 69 Keys: []JSONWebKeyStruct{ 70 { 71 Kty: "RSA", 72 Alg: "RS256", 73 Use: "sig", 74 Kid: "key-1", 75 N: "sJ46htmsgvo99FyibD", 76 E: "????", 77 }, 78 }, 79 }) 80 So(err, ShouldErrLike, "bad exponent encoding") 81 }) 82 83 Convey("Bad n", t, func() { 84 _, err := NewJSONWebKeySet(&JSONWebKeySetStruct{ 85 Keys: []JSONWebKeyStruct{ 86 { 87 Kty: "RSA", 88 Alg: "RS256", 89 Use: "sig", 90 Kid: "key-1", 91 N: "????", 92 E: "AQAB", 93 }, 94 }, 95 }) 96 So(err, ShouldErrLike, "bad modulus encoding") 97 }) 98 99 Convey("No signing keys", t, func() { 100 _, err := NewJSONWebKeySet(&JSONWebKeySetStruct{ 101 Keys: []JSONWebKeyStruct{ 102 { 103 Kty: "RSA", 104 Alg: "RS256", 105 Use: "encrypt", 106 Kid: "key-1", 107 N: "sJ46htmsgvo99FyibD", 108 E: "AQAB", 109 }, 110 }, 111 }) 112 So(err, ShouldErrLike, "didn't have any signing keys") 113 }) 114 } 115 116 func TestCheckSignature(t *testing.T) { 117 t.Parallel() 118 119 Convey("With signed blob", t, func() { 120 ctx := context.Background() 121 signer := signingtest.NewSigner(nil) 122 keys := JSONWebKeySet{ 123 keys: map[string]rsa.PublicKey{ 124 "key-1": signer.KeyForTest().PublicKey, 125 }, 126 } 127 128 var blob = []byte("blah blah") 129 _, sig, err := signer.SignBytes(ctx, blob) 130 So(err, ShouldBeNil) 131 132 Convey("Good signature", func() { 133 So(keys.CheckSignature("key-1", blob, sig), ShouldBeNil) 134 }) 135 136 Convey("Bad signature", func() { 137 So(keys.CheckSignature("key-1", []byte("something else"), sig), ShouldErrLike, "bad signature") 138 }) 139 140 Convey("Unknown key", func() { 141 So(keys.CheckSignature("unknown", blob, sig), ShouldErrLike, "unknown signing key") 142 }) 143 }) 144 }