blob: c2239273cbece6d6c14354db2fbf3b5643333ba5 [file] [log] [blame]
// Copyright 2017 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package openid
import (
"context"
"crypto/rsa"
"testing"
"go.chromium.org/luci/server/auth/signing/signingtest"
. "github.com/smartystreets/goconvey/convey"
. "go.chromium.org/luci/common/testing/assertions"
)
func TestParseJSONWebKeySet(t *testing.T) {
t.Parallel()
Convey("Happy path", t, func() {
keys, err := NewJSONWebKeySet(&JSONWebKeySetStruct{
Keys: []JSONWebKeyStruct{
{
Kty: "RSA",
Alg: "RS256",
Use: "sig",
Kid: "key-1",
N: "sJ46htmsgvo99FyibDKBh6zHGr2hldxfHt-6y9VTrDo3jfuFeA8xFG3Lb9LkJE4qlCvC9QRv3S0TWhQcTg9uGN2mY7B7ccIRaD2AL2hh87mFAkQzoRPxg5lvS6QisgiFQcH-oea-4iBYlBHyMemoXR8pRSwTeQKxzvZ2zohl5c-yE77vhrmDV9_n3viJH1YBYJk2weAj9Pqcfj7_cLF6tR1vd4voTL29WrWJwkO2KG6FcXrc0DQQba8nXPc-TFJd1Z9aSyzxS91rxnj8wnMbPdXPfG2jryT1Dg_LhWtDjIG7m2ZVN-_wL1hHhxC6m7yl4jSIaAO5rjKMToq5wrlgVQ",
E: "AQAB",
},
{
Kty: "SOMETHING-ELSE",
},
},
})
So(err, ShouldBeNil)
So(len(keys.keys), ShouldEqual, 1)
So(keys.keys["key-1"].E, ShouldEqual, 65537)
})
Convey("No key ID", t, func() {
_, err := NewJSONWebKeySet(&JSONWebKeySetStruct{
Keys: []JSONWebKeyStruct{
{
Kty: "RSA",
Alg: "RS256",
Use: "sig",
N: "sJ46htmsgvo99FyibD",
E: "AQAB",
},
},
})
So(err, ShouldErrLike, "missing 'kid' field")
})
Convey("Bad e", t, func() {
_, err := NewJSONWebKeySet(&JSONWebKeySetStruct{
Keys: []JSONWebKeyStruct{
{
Kty: "RSA",
Alg: "RS256",
Use: "sig",
Kid: "key-1",
N: "sJ46htmsgvo99FyibD",
E: "????",
},
},
})
So(err, ShouldErrLike, "bad exponent encoding")
})
Convey("Bad n", t, func() {
_, err := NewJSONWebKeySet(&JSONWebKeySetStruct{
Keys: []JSONWebKeyStruct{
{
Kty: "RSA",
Alg: "RS256",
Use: "sig",
Kid: "key-1",
N: "????",
E: "AQAB",
},
},
})
So(err, ShouldErrLike, "bad modulus encoding")
})
Convey("No signing keys", t, func() {
_, err := NewJSONWebKeySet(&JSONWebKeySetStruct{
Keys: []JSONWebKeyStruct{
{
Kty: "RSA",
Alg: "RS256",
Use: "encrypt",
Kid: "key-1",
N: "sJ46htmsgvo99FyibD",
E: "AQAB",
},
},
})
So(err, ShouldErrLike, "didn't have any signing keys")
})
}
func TestCheckSignature(t *testing.T) {
t.Parallel()
Convey("With signed blob", t, func() {
ctx := context.Background()
signer := signingtest.NewSigner(nil)
keys := JSONWebKeySet{
keys: map[string]rsa.PublicKey{
"key-1": signer.KeyForTest().PublicKey,
},
}
var blob = []byte("blah blah")
_, sig, err := signer.SignBytes(ctx, blob)
So(err, ShouldBeNil)
Convey("Good signature", func() {
So(keys.CheckSignature("key-1", blob, sig), ShouldBeNil)
})
Convey("Bad signature", func() {
So(keys.CheckSignature("key-1", []byte("something else"), sig), ShouldErrLike, "bad signature")
})
Convey("Unknown key", func() {
So(keys.CheckSignature("unknown", blob, sig), ShouldErrLike, "unknown signing key")
})
})
}