mirror of
https://github.com/coredns/coredns.git
synced 2025-11-01 10:43:17 -04:00
Drop caddy from vendor (#700)
* Removed caddy * new stuff * Now need to go get caddy * Duh
This commit is contained in:
4
vendor/github.com/coreos/etcd/README.md
generated
vendored
4
vendor/github.com/coreos/etcd/README.md
generated
vendored
@@ -78,7 +78,7 @@ That's it! etcd is now running and serving client requests. For more
|
||||
|
||||
The [official etcd ports][iana-ports] are 2379 for client requests, and 2380 for peer communication.
|
||||
|
||||
[iana-ports]: https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=etcd
|
||||
[iana-ports]: http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
|
||||
|
||||
### Running a local etcd cluster
|
||||
|
||||
@@ -136,5 +136,3 @@ See [reporting bugs](Documentation/reporting_bugs.md) for details about reportin
|
||||
### License
|
||||
|
||||
etcd is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
|
||||
|
||||
|
||||
|
||||
150
vendor/github.com/coreos/go-oidc/gen.go
generated
vendored
150
vendor/github.com/coreos/go-oidc/gen.go
generated
vendored
@@ -1,150 +0,0 @@
|
||||
// +build ignore
|
||||
|
||||
// This file is used to generate keys for tests.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"text/template"
|
||||
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
type key struct {
|
||||
name string
|
||||
new func() (crypto.Signer, error)
|
||||
}
|
||||
|
||||
var keys = []key{
|
||||
{
|
||||
"ECDSA_256", func() (crypto.Signer, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
},
|
||||
},
|
||||
{
|
||||
"ECDSA_384", func() (crypto.Signer, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
},
|
||||
},
|
||||
{
|
||||
"ECDSA_521", func() (crypto.Signer, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
},
|
||||
},
|
||||
{
|
||||
"RSA_1024", func() (crypto.Signer, error) {
|
||||
return rsa.GenerateKey(rand.Reader, 1024)
|
||||
},
|
||||
},
|
||||
{
|
||||
"RSA_2048", func() (crypto.Signer, error) {
|
||||
return rsa.GenerateKey(rand.Reader, 2048)
|
||||
},
|
||||
},
|
||||
{
|
||||
"RSA_4096", func() (crypto.Signer, error) {
|
||||
return rsa.GenerateKey(rand.Reader, 4096)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func newJWK(k key, prefix, ident string) (privBytes, pubBytes []byte, err error) {
|
||||
priv, err := k.new()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("generate %s: %v", k.name, err)
|
||||
}
|
||||
pub := priv.Public()
|
||||
|
||||
privKey := &jose.JSONWebKey{Key: priv}
|
||||
thumbprint, err := privKey.Thumbprint(crypto.SHA256)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("computing thumbprint: %v", err)
|
||||
}
|
||||
|
||||
keyID := hex.EncodeToString(thumbprint)
|
||||
privKey.KeyID = keyID
|
||||
pubKey := &jose.JSONWebKey{Key: pub, KeyID: keyID}
|
||||
|
||||
privBytes, err = json.MarshalIndent(privKey, prefix, ident)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pubBytes, err = json.MarshalIndent(pubKey, prefix, ident)
|
||||
return
|
||||
}
|
||||
|
||||
type keyData struct {
|
||||
Name string
|
||||
Priv string
|
||||
Pub string
|
||||
}
|
||||
|
||||
var tmpl = template.Must(template.New("").Parse(`// +build !golint
|
||||
|
||||
// This file contains statically created JWKs for tests created by gen.go
|
||||
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
func mustLoadJWK(s string) jose.JSONWebKey {
|
||||
var jwk jose.JSONWebKey
|
||||
if err := json.Unmarshal([]byte(s), &jwk); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return jwk
|
||||
}
|
||||
|
||||
var (
|
||||
{{- range $i, $key := .Keys }}
|
||||
testKey{{ $key.Name }} = mustLoadJWK(` + "`" + `{{ $key.Pub }}` + "`" + `)
|
||||
testKey{{ $key.Name }}_Priv = mustLoadJWK(` + "`" + `{{ $key.Priv }}` + "`" + `)
|
||||
{{ end -}}
|
||||
)
|
||||
`))
|
||||
|
||||
func main() {
|
||||
var tmplData struct {
|
||||
Keys []keyData
|
||||
}
|
||||
for _, k := range keys {
|
||||
for i := 0; i < 4; i++ {
|
||||
log.Printf("generating %s", k.name)
|
||||
priv, pub, err := newJWK(k, "\t", "\t")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
name := fmt.Sprintf("%s_%d", k.name, i)
|
||||
|
||||
tmplData.Keys = append(tmplData.Keys, keyData{
|
||||
Name: name,
|
||||
Priv: string(priv),
|
||||
Pub: string(pub),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
buff := new(bytes.Buffer)
|
||||
if err := tmpl.Execute(buff, tmplData); err != nil {
|
||||
log.Fatalf("excuting template: %v", err)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile("jose_test.go", buff.Bytes(), 0644); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
405
vendor/github.com/coreos/go-oidc/jose_test.go
generated
vendored
405
vendor/github.com/coreos/go-oidc/jose_test.go
generated
vendored
@@ -1,405 +0,0 @@
|
||||
// +build !golint
|
||||
|
||||
// This file contains statically created JWKs for tests created by gen.go
|
||||
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
func mustLoadJWK(s string) jose.JSONWebKey {
|
||||
var jwk jose.JSONWebKey
|
||||
if err := json.Unmarshal([]byte(s), &jwk); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return jwk
|
||||
}
|
||||
|
||||
var (
|
||||
testKeyECDSA_256_0 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bd06f3e11f523e310f8c2c8b20a892727fb558e0e23602312568b20a41e11188",
|
||||
"crv": "P-256",
|
||||
"x": "xK5N69f0-SAgWbjw2otcQeCGs3qqYMyqOWk4Os5Z_Xc",
|
||||
"y": "AXSaOPcMklJY9UKZhkGzVevqhAIUEzE3cfZ8o-ML5xE"
|
||||
}`)
|
||||
testKeyECDSA_256_0_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bd06f3e11f523e310f8c2c8b20a892727fb558e0e23602312568b20a41e11188",
|
||||
"crv": "P-256",
|
||||
"x": "xK5N69f0-SAgWbjw2otcQeCGs3qqYMyqOWk4Os5Z_Xc",
|
||||
"y": "AXSaOPcMklJY9UKZhkGzVevqhAIUEzE3cfZ8o-ML5xE",
|
||||
"d": "L7jynYt-fMRPqw1e9vgXCGTg4yhGU4tlLxiFyNVimG4"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_256_1 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "27ebd2f5bf6723e4de06caaab03703be458a37bf28a9fa748576a0826acb6ec2",
|
||||
"crv": "P-256",
|
||||
"x": "KZisP6wLCph4q6056jr7BH_asiX9RcLcS3HrNjdCpkw",
|
||||
"y": "5DrW-kEge0sePHlKmh1d2kqd10r32JEW6eyyewy18j8"
|
||||
}`)
|
||||
testKeyECDSA_256_1_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "27ebd2f5bf6723e4de06caaab03703be458a37bf28a9fa748576a0826acb6ec2",
|
||||
"crv": "P-256",
|
||||
"x": "KZisP6wLCph4q6056jr7BH_asiX9RcLcS3HrNjdCpkw",
|
||||
"y": "5DrW-kEge0sePHlKmh1d2kqd10r32JEW6eyyewy18j8",
|
||||
"d": "r6CiIpv0icIq5U4LYO39nBDVhCHCLObDFYC5IG9Y8Hk"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_256_2 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "2c7d179db6006c90ece4d91f554791ff35156693c693102c00f66f473d15df17",
|
||||
"crv": "P-256",
|
||||
"x": "oDwcKp7SqgeRvycK5GgYjrlW4fbHn2Ybfd5iG7kDiPc",
|
||||
"y": "qazib9UwdUdbHSFzdy_HN10xZEItLvufPw0v7nIJOWA"
|
||||
}`)
|
||||
testKeyECDSA_256_2_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "2c7d179db6006c90ece4d91f554791ff35156693c693102c00f66f473d15df17",
|
||||
"crv": "P-256",
|
||||
"x": "oDwcKp7SqgeRvycK5GgYjrlW4fbHn2Ybfd5iG7kDiPc",
|
||||
"y": "qazib9UwdUdbHSFzdy_HN10xZEItLvufPw0v7nIJOWA",
|
||||
"d": "p79U6biKrOyrKzg-i3C7FVJiqzlqBhYQqmyOiZ9bhVM"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_256_3 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "aba0a256999af470c8b2449103ae75b257d907da4d1cbfc73c1d45ab1098f544",
|
||||
"crv": "P-256",
|
||||
"x": "CKRYWVt1R7FzuJ43vEprfIzgB-KgIhRDhxLmd5ixiXY",
|
||||
"y": "QCxTVmK31ee710OYkNqdqEgHH3rqRQNQj3Wyq0xtYq0"
|
||||
}`)
|
||||
testKeyECDSA_256_3_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "aba0a256999af470c8b2449103ae75b257d907da4d1cbfc73c1d45ab1098f544",
|
||||
"crv": "P-256",
|
||||
"x": "CKRYWVt1R7FzuJ43vEprfIzgB-KgIhRDhxLmd5ixiXY",
|
||||
"y": "QCxTVmK31ee710OYkNqdqEgHH3rqRQNQj3Wyq0xtYq0",
|
||||
"d": "c_WflwwUxT_B5izk4iET49qoob0RH5hccnEScfBS9Qk"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_0 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bc271d0a68251171e0c5edfd384b32d154e1717af27c5089bda8fb598a474b7b",
|
||||
"crv": "P-384",
|
||||
"x": "FZEhxw06oB86xCAZCtKTfX3ze9tgxkdN199g-cWrpQTWF-2m6Blg1MN5D60Z9KoX",
|
||||
"y": "EyWjZ46gLlqfoU08iv0zcDWut1nbfoUoTd-7La2VY4PqQeDSFrxPCOyplxFMGJIW"
|
||||
}`)
|
||||
testKeyECDSA_384_0_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bc271d0a68251171e0c5edfd384b32d154e1717af27c5089bda8fb598a474b7b",
|
||||
"crv": "P-384",
|
||||
"x": "FZEhxw06oB86xCAZCtKTfX3ze9tgxkdN199g-cWrpQTWF-2m6Blg1MN5D60Z9KoX",
|
||||
"y": "EyWjZ46gLlqfoU08iv0zcDWut1nbfoUoTd-7La2VY4PqQeDSFrxPCOyplxFMGJIW",
|
||||
"d": "t6oJHJBH2rvH3uyQkK_JwoUEwE1QHjwTnGLSDMZbNEDrEaR8BBiAo3s0p8rzGz5-"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_1 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "58ef375d6e63cedc637fed59f4012a779cd749a83373237cf3972bba74ebd738",
|
||||
"crv": "P-384",
|
||||
"x": "Gj3zkiRR4RCJb0Tke3lD2spG2jzuXgX50fEwDZTRjlQIzz3Rc96Fw32FCSDectxQ",
|
||||
"y": "6alqN7ilqJAmqCU1BFrJJeivJiM0s1-RqBewRoNkTQinOLLbaiZlBAQxS4iq2dRv"
|
||||
}`)
|
||||
testKeyECDSA_384_1_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "58ef375d6e63cedc637fed59f4012a779cd749a83373237cf3972bba74ebd738",
|
||||
"crv": "P-384",
|
||||
"x": "Gj3zkiRR4RCJb0Tke3lD2spG2jzuXgX50fEwDZTRjlQIzz3Rc96Fw32FCSDectxQ",
|
||||
"y": "6alqN7ilqJAmqCU1BFrJJeivJiM0s1-RqBewRoNkTQinOLLbaiZlBAQxS4iq2dRv",
|
||||
"d": "-4eaoElyb_YANRownMtId_-glX2o45oc4_L_vgo3YOW5hxCq3KIBIdrhvBx1nw8B"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_2 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "a8bab6f438b6cd2080711404549c978d1c00dd77a3c532bba12c964c4883b2ec",
|
||||
"crv": "P-384",
|
||||
"x": "CBKwYgZFLdTBBFnWD20q2YNUnRnOsDgTxG3y-dzCUrb65kOKm0ZFaZQPe5ZPjvDS",
|
||||
"y": "WlubxLv2qH-Aw-LsESKXAwm4HF3l4H1rVn3DZRpqcac6p-QSrXmfKCtxJVHDaTNi"
|
||||
}`)
|
||||
testKeyECDSA_384_2_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "a8bab6f438b6cd2080711404549c978d1c00dd77a3c532bba12c964c4883b2ec",
|
||||
"crv": "P-384",
|
||||
"x": "CBKwYgZFLdTBBFnWD20q2YNUnRnOsDgTxG3y-dzCUrb65kOKm0ZFaZQPe5ZPjvDS",
|
||||
"y": "WlubxLv2qH-Aw-LsESKXAwm4HF3l4H1rVn3DZRpqcac6p-QSrXmfKCtxJVHDaTNi",
|
||||
"d": "XfoOcxV3yfoAcRquJ9eaBvcY-H71B0XzXwx2eidolHDKLK7GHygEt9ToYSY_DvxO"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_3 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "32f0cfc686455840530d727fb029002b9757ffff15272f98f53be9f77560718a",
|
||||
"crv": "P-384",
|
||||
"x": "xxED1z8EUCOUQ_jwS9nuVUDVzxs-U1rl19y8jMWrv4TdPeGHTRTgNUE57-YAL3ly",
|
||||
"y": "OsCN6-HmM-LP1itE5eW15WsSQoe3dZBX7AoHyKJUKtjzWKCJNUcyu3Np07xta1Cr"
|
||||
}`)
|
||||
testKeyECDSA_384_3_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "32f0cfc686455840530d727fb029002b9757ffff15272f98f53be9f77560718a",
|
||||
"crv": "P-384",
|
||||
"x": "xxED1z8EUCOUQ_jwS9nuVUDVzxs-U1rl19y8jMWrv4TdPeGHTRTgNUE57-YAL3ly",
|
||||
"y": "OsCN6-HmM-LP1itE5eW15WsSQoe3dZBX7AoHyKJUKtjzWKCJNUcyu3Np07xta1Cr",
|
||||
"d": "gfQA6wn4brWVT3OkeGiaCXGsQyTybZB9SdqTULsiSg8n6FS2T8hvK0doPwMTT5Gw"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_0 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "f7b325c848a6c9fc5b72f131f179d2f37296837262797983c632597a4927726e",
|
||||
"crv": "P-521",
|
||||
"x": "AUaLqCAMEWPqiYgd-D_6F5kxpOgqnbQnjIHZ-NhjRnKKYuij9Iz7bq9pZU4F79wsODFpWxMFfISrveUfgEGt4Hy2",
|
||||
"y": "AeAKfmFsfcFttwQqv2B-fUfgLhw837YoGoNWh5qNE_LqTBxbYKRUkbSLxVRHEcVNnU1t3z9yMMdYXtuMlfJ0bhjr"
|
||||
}`)
|
||||
testKeyECDSA_521_0_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "f7b325c848a6c9fc5b72f131f179d2f37296837262797983c632597a4927726e",
|
||||
"crv": "P-521",
|
||||
"x": "AUaLqCAMEWPqiYgd-D_6F5kxpOgqnbQnjIHZ-NhjRnKKYuij9Iz7bq9pZU4F79wsODFpWxMFfISrveUfgEGt4Hy2",
|
||||
"y": "AeAKfmFsfcFttwQqv2B-fUfgLhw837YoGoNWh5qNE_LqTBxbYKRUkbSLxVRHEcVNnU1t3z9yMMdYXtuMlfJ0bhjr",
|
||||
"d": "AbD3guIvlVd8CZD0xUNuebgnQkE24XJnxCQ69P5VL3etEMmdr4HPJLPMQfMs10Gz8RTmrGKo-bdsU-cjS3d7dKIC"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_1 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "4ea260ba2c9ed5fe9d6adeb998bb68b3edbab839d8bfd2be09fa628680793b90",
|
||||
"crv": "P-521",
|
||||
"x": "AE8-53o64GiywneanVZAHb96NcPbq0Ml6zynIcgLdKUiHGVs2te7SABq_9keFZJC6wooACeNWWT7VDK3kY77fjdh",
|
||||
"y": "AAnrIu0-D7JEd3-mqTR8Rdz53kw7DLAIypv0-_u4rqn0glwTZCkMpQ17wFH71bMInXaTi2Z_uq67NuVxFvUCaTvS"
|
||||
}`)
|
||||
testKeyECDSA_521_1_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "4ea260ba2c9ed5fe9d6adeb998bb68b3edbab839d8bfd2be09fa628680793b90",
|
||||
"crv": "P-521",
|
||||
"x": "AE8-53o64GiywneanVZAHb96NcPbq0Ml6zynIcgLdKUiHGVs2te7SABq_9keFZJC6wooACeNWWT7VDK3kY77fjdh",
|
||||
"y": "AAnrIu0-D7JEd3-mqTR8Rdz53kw7DLAIypv0-_u4rqn0glwTZCkMpQ17wFH71bMInXaTi2Z_uq67NuVxFvUCaTvS",
|
||||
"d": "AVVL9TIWcJCYH5r3QUhHXtsbkVXhLQSpp4sL1ta_H2_3bpRb9ZdVv10YOA-xN7Yz2wa-FMhIhj1ULe9z18ZM8dDF"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_2 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "d69caddc821807ea63a46519b538a7d2f3135dbdda1ba628781f8567a47893d8",
|
||||
"crv": "P-521",
|
||||
"x": "AO618rH8GP78-mi9Z5FaPGqpyc_OVMK-BajZK-pwL89ZQdOvFa0fY0ENpB_KaRf5ELw9IP17lQh3T-O9O7jePDFj",
|
||||
"y": "AT1x9pCMbY-BXqAJPQDQxp6j8Gca7IpdxL8OS4td_XPiwXtX4JKcj_VKxtOw6k64yr_VuFYCs6wImOc72jNRBjA7"
|
||||
}`)
|
||||
testKeyECDSA_521_2_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "d69caddc821807ea63a46519b538a7d2f3135dbdda1ba628781f8567a47893d8",
|
||||
"crv": "P-521",
|
||||
"x": "AO618rH8GP78-mi9Z5FaPGqpyc_OVMK-BajZK-pwL89ZQdOvFa0fY0ENpB_KaRf5ELw9IP17lQh3T-O9O7jePDFj",
|
||||
"y": "AT1x9pCMbY-BXqAJPQDQxp6j8Gca7IpdxL8OS4td_XPiwXtX4JKcj_VKxtOw6k64yr_VuFYCs6wImOc72jNRBjA7",
|
||||
"d": "AYmtaW9ojb0Gb8zSqrlRnEKzRVIBIM5dsb1qWkd3mfr4Wl5tbPuiEctGLN9s6LDtY0JOL3nukOVoDbrmS4qCW64"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_3 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "7193cba4fd9c72153133ce5cffc423857517ab8eb176a827e1a002eb5621edca",
|
||||
"crv": "P-521",
|
||||
"x": "AQfpLehZCER3ZTw1V1pN0RsX8-4WEW4IDxFDSGwrULQ79YHiLNmubrOSlSxiOSv2S-tHq-hxgma1PZlQRghJfemx",
|
||||
"y": "AAF41XT7jptLsy8FAaVRnex2WcSfdebcjjXMGO4rn6IlD3u9qnvrpR8MBp1gz5G1C5S7_NVgIeLSIYbdfd_wjVkd"
|
||||
}`)
|
||||
testKeyECDSA_521_3_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "7193cba4fd9c72153133ce5cffc423857517ab8eb176a827e1a002eb5621edca",
|
||||
"crv": "P-521",
|
||||
"x": "AQfpLehZCER3ZTw1V1pN0RsX8-4WEW4IDxFDSGwrULQ79YHiLNmubrOSlSxiOSv2S-tHq-hxgma1PZlQRghJfemx",
|
||||
"y": "AAF41XT7jptLsy8FAaVRnex2WcSfdebcjjXMGO4rn6IlD3u9qnvrpR8MBp1gz5G1C5S7_NVgIeLSIYbdfd_wjVkd",
|
||||
"d": "hzh0loqrhYFUik86SYBv3CC_GKNYankLMK95-Cfr1gLBD1l0M6W-7gn3XlyaQEInz0TBIbaQ1fL78HHjbVsNLrY"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_0 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "979d62e7114052027b11bcb51282d8228790134ef34e746f6372fa5aadaa9bf2",
|
||||
"n": "6zxmGE5X74SUBWfDEo8Tl-YxrkVfvxljQG9vKmNPQ2RhEmJ8eplZpKn9_nlxVDHGLzfJMqqUBS19EarIfDnOqyFBRkyKRbsQdUVU9XLjDIXqImJ8aN-UmShAYoeOClJVDsBJuxBGgS3pdgG7u3YQpvTV_hGuMoJr7UYgIrqb0qc",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_0_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "979d62e7114052027b11bcb51282d8228790134ef34e746f6372fa5aadaa9bf2",
|
||||
"n": "6zxmGE5X74SUBWfDEo8Tl-YxrkVfvxljQG9vKmNPQ2RhEmJ8eplZpKn9_nlxVDHGLzfJMqqUBS19EarIfDnOqyFBRkyKRbsQdUVU9XLjDIXqImJ8aN-UmShAYoeOClJVDsBJuxBGgS3pdgG7u3YQpvTV_hGuMoJr7UYgIrqb0qc",
|
||||
"e": "AQAB",
|
||||
"d": "IARggP5oyZjp7LJqwqPmrs4OBQI8Pe5eq-5-2u4ZY7rN24q8FpO4t8jLYU92NVdw-gxFvjepXesLEtSD5SSZFD7s-5rqmX9tW_t5t1a1sBY6IKz_YBSf2p2LtdTyrqgo4nRD0nYH3sMvGtOKCTV4K_vwfWPD3elXq752trG-HwE",
|
||||
"p": "9tgo12L3earNNrJfyIIDD2dqgKuNfWhQzhbe-Ju17dF37uGF6xnLqR0WXU-agGpUdYTMOd7IQi_bX_xkjQBYlw",
|
||||
"q": "8_YDvufPdccjGM2rAXs-2LbeP_LrzLUk1uGNpEjIt2lXEm6sQKjIfNLcAfVKh9zsqwqroveL2iI1ijsDgNAIcQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_1 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4a3a37dc10aec5f427509e4014683102a0fafa32bec2ff9921ff19e1a55c79e8",
|
||||
"n": "sn7sU7dBEkU1RBIz_LKgrswSS7-68vTlOe7n-lanAqAlczm01_6IWrvcIC7lPv1iHQqWngusskANZirCZGTv6kK8kJLHBVRSROB9VkPTPNFYnSB6dacyPa0ty0otsaYOVM2RFvcCX7lBKKat2Tmst8vITdpvnoEzTgT_eGOKGAs",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_1_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4a3a37dc10aec5f427509e4014683102a0fafa32bec2ff9921ff19e1a55c79e8",
|
||||
"n": "sn7sU7dBEkU1RBIz_LKgrswSS7-68vTlOe7n-lanAqAlczm01_6IWrvcIC7lPv1iHQqWngusskANZirCZGTv6kK8kJLHBVRSROB9VkPTPNFYnSB6dacyPa0ty0otsaYOVM2RFvcCX7lBKKat2Tmst8vITdpvnoEzTgT_eGOKGAs",
|
||||
"e": "AQAB",
|
||||
"d": "KTXqpE1sBaba7HNzc0Vemdzd4IVMyWlHPz_saTz2ZEHLQ7YwDapjmudCpF-PaCKiM2hNbAHwBluJfGwk4372cPHcJyri3Gs4GGj-cOlbXJh9aUp5o8fqn904B1UcPxMZ2DrZAKjseuLj3zyJgCsSJOGU1kJFRAkM8UN4a9cE8sE",
|
||||
"p": "3ntHMGDJEXwqldLNR-DucKGp32aJVAaKnn4j9qy1Tj6KhH70o3HyFVO_TKYxGg-pG3zTV-VzyMqmeh9hDdnyKw",
|
||||
"q": "zWMxEjyxvp-P-mNxhWQe1pJXZi6iPpcnt0SZLfweT3AtAzEaoSs4-4D1jT911LD4xDI8_a7-gYHgD8ME62PhoQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_2 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d1c32aaea6c9527038e589dd94a546ca1beedb90f90e073228986cc258cf1fda",
|
||||
"n": "3mZrDaB5-7e29zok9XkGuu6FXYB00FqFgnGTJAGCMpql5uHz1h9p0DljZL4vsGkkYOZUMvqFS1pCEuzdSsupPNClf0NKMRux6yLv6iIR9C4pE9RBKPUrinzJuYs634rq5JOEP4IpP_fJfKxMw4Na85otd9KposKwP14cCkOibYM",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_2_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d1c32aaea6c9527038e589dd94a546ca1beedb90f90e073228986cc258cf1fda",
|
||||
"n": "3mZrDaB5-7e29zok9XkGuu6FXYB00FqFgnGTJAGCMpql5uHz1h9p0DljZL4vsGkkYOZUMvqFS1pCEuzdSsupPNClf0NKMRux6yLv6iIR9C4pE9RBKPUrinzJuYs634rq5JOEP4IpP_fJfKxMw4Na85otd9KposKwP14cCkOibYM",
|
||||
"e": "AQAB",
|
||||
"d": "Ft2M0B_ZqsmepBh0SFCjIoD3cT-NwwYrh9fJewA0tKM1v2EnwrIEHQZpc6giGw8UUGod6gfbwH2NIYj8z33U7lyrKWPR7F8gJRm1KR5NLCBCnAnz0ukhsg24ktB25LZLZRCStRRhtCev95Vvmew0ip5081hv730Z2T_PsEyOU6E",
|
||||
"p": "8moFzLKJSQuhaIYTo1qNX0w8o4NBFb1atOlthHmq6Y6rdYTm_nyM9Q3mrNBolPS7LHTiBXtCEJ_m4V5hWDuGKw",
|
||||
"q": "6t0_mZKOoZ5NAE--MxkuOCcRhuqNo9VoacfPEH39CeoKAam4v5k56R7aQcb_raQK396pgV-evM2dpfdUaasiCQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_3 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "838742d0e3195b19f974fa30352db79070fa19aaaeb678ec95c499de7bd48d52",
|
||||
"n": "17Uc89-QvCjqBLXDJSCWxUoohjwFPI63Gub8g-lH1GSK3flXqiohz33KfKhqrdKsLrpRjskGTMg3Vo0IcLBnMYdp1i1nceORghtYLQsDNS7tqlHiKx725fLmWldGgiuP_0Ak0Knisw-j_q7Jx3OVAJnuS1o3vPLfJxJdyq6yV1k",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_3_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "838742d0e3195b19f974fa30352db79070fa19aaaeb678ec95c499de7bd48d52",
|
||||
"n": "17Uc89-QvCjqBLXDJSCWxUoohjwFPI63Gub8g-lH1GSK3flXqiohz33KfKhqrdKsLrpRjskGTMg3Vo0IcLBnMYdp1i1nceORghtYLQsDNS7tqlHiKx725fLmWldGgiuP_0Ak0Knisw-j_q7Jx3OVAJnuS1o3vPLfJxJdyq6yV1k",
|
||||
"e": "AQAB",
|
||||
"d": "B8cM-zIVauNixLa1CZKqPQTWfziMy8ktivfHJQ51O5BAfY5u_cC1JWEYuvPrnMba1Hh9VlOjOYOCk0lUg5OotMx5hxym6M5y_2rIrW90a8r3gGttPlZmyHQnFIgj2QZHlEyZGU1SIPTOtoECW5RGk7cYpA1s1_zfz8uyG-MiCPE",
|
||||
"p": "2dwia5iWWLZwFcCVylPh_7QDr3Wxt3kW_TmHIbaRT10Rborj1lAwltyEx7aVpHq-aNfvrYIEBbOXWwUU8PDUrQ",
|
||||
"q": "_XiDT55hn-Txi2C_peMVSDgXozf01qHKvdLirXM2uT_CI8kruYZYjWYn6_cSUptJ60eioM3WNTxjrSxWRS923Q"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_0 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "13b668c7b4f5d46d53de65e4b9f9c522fad4870e4d1656e459c88de6e90984d6",
|
||||
"n": "1j-CxBxkn20C_M24t6ueLp02T4MMAiPLXf5yaDcj7EcsXGbnsGEhrAUwCZwdEJAxeZ0PolmlE0XBOhQfRtsCVJmwu918aknptToyDbOUBr6WtPIK_c_BuGVanLCx3SnczV4jle9Bz7tGfpj2vAXytSBrfnZhdCHNEFeefQTQMnavfMhfWf_njiTa76BRyAHjb-XZIJHKovwBu0y3glmzhSKYNsUrW11RsWx6DbueWEbE3FpsHTiEdnJipcP3UKl3Z2z6t6n9ZYtFWkx4zCVVBQu-RWUQwjr2XnR1LFwXgL9xQocDBmS1O-wMTHqL3_oosNUdV3vuMPdxs_SEoys2rQ",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_0_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "13b668c7b4f5d46d53de65e4b9f9c522fad4870e4d1656e459c88de6e90984d6",
|
||||
"n": "1j-CxBxkn20C_M24t6ueLp02T4MMAiPLXf5yaDcj7EcsXGbnsGEhrAUwCZwdEJAxeZ0PolmlE0XBOhQfRtsCVJmwu918aknptToyDbOUBr6WtPIK_c_BuGVanLCx3SnczV4jle9Bz7tGfpj2vAXytSBrfnZhdCHNEFeefQTQMnavfMhfWf_njiTa76BRyAHjb-XZIJHKovwBu0y3glmzhSKYNsUrW11RsWx6DbueWEbE3FpsHTiEdnJipcP3UKl3Z2z6t6n9ZYtFWkx4zCVVBQu-RWUQwjr2XnR1LFwXgL9xQocDBmS1O-wMTHqL3_oosNUdV3vuMPdxs_SEoys2rQ",
|
||||
"e": "AQAB",
|
||||
"d": "C8F4X2Jfcw_8Nfrjw9A64bvmmv5JzmRAaGvpwyYjZneRS5Cp7demjVXLiPtz7NC8pjuj-_iHQkN1ksY_4RdrTVERjX1dskdT94m17WKJIMWcZ1lQmRSpQIDvM-HOIKCHaQ1dToDOT6Oq_o9OGosJAj9BJrNALasdIWRtYda9xcb7roLl_U3AtOlK9RiFygtt5uVBIPh1rsxaT0Y1MvMk4EMbFnv7NXXk65UM_3p2leSoPpO7LvlYs3WoRRX9ABH7zI-ppwLGEDuxfnwKzAOaRBe9oUh5rTYdazaY9XqofvekBc9Xqa2HpjkYX-L4Zy3oj04u-u5zX8KTh25jFC2a0Q",
|
||||
"p": "6L6icXqV7jLSXHrhMyLpW-tdFFp2XRQ_uKk972jmUJ-sEeh1YYSx_JpK6oaUnYshGbRLfEAOLy03iweAL4uMZJcASOR44TwSnn_qJZ72PkwhD42uKhE0eJRpxVht6jf5qhsynaMNUWc_FIW5ESpQIf6j4rqFV5WrKHAt0ypChTc",
|
||||
"q": "66fAza4rLvyjqQAIGQ07RiRYW4no1h4cK8RH_CDUgI3CCFQSuqTB8ZqM38r2u0tZoKzCNgHcnde6Jk07X6-LSQW2kypMXt3idbgaeVSYSbdZndgG_jTibJvoybxSjo6HfLpPvCrfsihXo7O5M13LE7VqBLbGTLI5iubOxcrfFTs"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_1 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "6d2b0efff0011bbbbf694de684b5b97cf454fd4086fa53b9af92545f3fa65459",
|
||||
"n": "1CmSBUbxU1jjnmaBG0r0cLLmyZgCOMbfpG6Z3HwfVDgCK6P-rU3F6QQazrOgGJJ0sz6vP50VK5u7BR6vSrPBBX5CicJPM2iNdz2JuV9ODEIkDQBLeI6TfIGhNOls-14tXKOPExY8b6JdyDMP31Hwo_0pF1FaunZ7yY1bgoKCtDV5-RKGd2EgylDGNPu0Ilr92MqCsAntBC8eQSkO4CcTcti4t9cX45VY5nPtwQRmp5zIgUHnU4LV3QVTLJnU-uidaAxRVQbS1pVql5xR6nYZHYvFk1IU-wTY6gGk5WvGWWQ440UTTaMAfnJP6VFDggUXeGSlKfKkDcz7JLT2Ma2KXQ",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_1_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "6d2b0efff0011bbbbf694de684b5b97cf454fd4086fa53b9af92545f3fa65459",
|
||||
"n": "1CmSBUbxU1jjnmaBG0r0cLLmyZgCOMbfpG6Z3HwfVDgCK6P-rU3F6QQazrOgGJJ0sz6vP50VK5u7BR6vSrPBBX5CicJPM2iNdz2JuV9ODEIkDQBLeI6TfIGhNOls-14tXKOPExY8b6JdyDMP31Hwo_0pF1FaunZ7yY1bgoKCtDV5-RKGd2EgylDGNPu0Ilr92MqCsAntBC8eQSkO4CcTcti4t9cX45VY5nPtwQRmp5zIgUHnU4LV3QVTLJnU-uidaAxRVQbS1pVql5xR6nYZHYvFk1IU-wTY6gGk5WvGWWQ440UTTaMAfnJP6VFDggUXeGSlKfKkDcz7JLT2Ma2KXQ",
|
||||
"e": "AQAB",
|
||||
"d": "DYJcHuPmh-UYEUT7oY5DRE3P7jQ0qALZyLGWMHji0c0DLl4x4D0chfrR7il33zisH6G1LPrGl1FCNlA-3yXU-5GPkRADVQWqRFZxx5Du-k7X1tAW_iUt9PaYGjNm0hasEsMDYDbBQGZ5TD8cGp8wEHEVRbvTaB4VQb8zfXrr8ad8XCFdtYQF5Sw_VuvUBcn-50kdl7S0MmQiwLx5xkisJHkVdVsrWbq-JJPMYrjYzPGo07kt8pQH2ecxrQD2waTzkLiAg-nytPBkAyMIFQ-XCulWCNiI-V_HJ0pqNctgVpdaSihlPCYhfllxUSU8yg4UvcfFEAN2S5yjvPyrJeJLAQ",
|
||||
"p": "4db4J-vxAyb_3otKidzYISIo8NuPxPXuYeImbvVbY6CWHdAYAkPgbwADh592D1vM6kwqZLot4VQ4XUVtX7Vf8tCaq5BAzcVAslK0rhK86kSmzuvtpS1ruzm1DGwJcQWOl_9qYnaAov8Ny0NG8fTm8iwvWJH7rVa3XNtPL0t_fx0",
|
||||
"q": "8H7_sX4kY3_4t90HbA8IvVkTf3-OGaIjtcDn2J3HLq1wMKAtdxwsbMtjhLYP70PPBe_FBNpcWhE7p-tOVhH1i0N0wwFqwlRQy-3Z4oiLeSsy0Npl29cfP7teO5UTrbrqfmHB0j2u_nEqA4n4iDF5QhPr_9yzxSR4Pg56z4PgFEE"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_2 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "7988e9dea9647281b04d094e4dc5737eaf739a412a570aa4d6deed7ee5640c30",
|
||||
"n": "wWOFgHHiJ54ZjQEKxvfqYDuhYymbfvYxvreroqx7E-cAuU4QBsOvKV3HNnH_vDRQE1AlqihNWmPFLptp7wxdMrLEtDnRFqTxyTXJ7wLCaaaB6Wwx1dhpr9QEG5-8rxLGFYv2w5i0-o76JPHG0tuqf0YNmHp9oWcv524XnDBuji4-u6km1KynT1EQKHYgy57JWgUpukgJGImBEvf0hC2Y5s5mHvVby3xAD9-cFa2o9Vj3G-SBYFsrRIVR8GcVNwo88oj8F7-2nGD_wOOu_qT_5I3vfToUYGj5-2rAK1ja0bZpXFibrkPrW4w9paG-3F7I0sPeL3e_BDC_rQ8TgL03uQ",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_2_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "7988e9dea9647281b04d094e4dc5737eaf739a412a570aa4d6deed7ee5640c30",
|
||||
"n": "wWOFgHHiJ54ZjQEKxvfqYDuhYymbfvYxvreroqx7E-cAuU4QBsOvKV3HNnH_vDRQE1AlqihNWmPFLptp7wxdMrLEtDnRFqTxyTXJ7wLCaaaB6Wwx1dhpr9QEG5-8rxLGFYv2w5i0-o76JPHG0tuqf0YNmHp9oWcv524XnDBuji4-u6km1KynT1EQKHYgy57JWgUpukgJGImBEvf0hC2Y5s5mHvVby3xAD9-cFa2o9Vj3G-SBYFsrRIVR8GcVNwo88oj8F7-2nGD_wOOu_qT_5I3vfToUYGj5-2rAK1ja0bZpXFibrkPrW4w9paG-3F7I0sPeL3e_BDC_rQ8TgL03uQ",
|
||||
"e": "AQAB",
|
||||
"d": "RPC4j-CJUbw_uY-Miv-oMuQvFU2o3Crh8u5BJn28ZozsKiMU_YRW9jUzJkqfczVm8muY8b7qTHXSvlmy-v_6XW9zRhhyXFMyypr9QNJIAifUmiTy4xwCGSdIy5w3RGY57UZ3EqVmpwe_TtpOGa8rabHMePX5wUcqwaLykcCGOPLOFKfPF93GqZYi2StS1IaiijLi2IAMhxQGqS6Ct3dA7yacQwegPiDzjb4Is3V9UQ9k_aS3I1w56tz5qspVmfDEuuWToc-2Qyk-eMKWl1tTDJuGTCiS5IFtMPerRpPq9GCpycV0csIW-6AnW79b038DxWjDAUsNnDPnX0y1dQ1G3Q",
|
||||
"p": "yh2KH_JqU29L2SLG5-ul1EBbaSbt3F5UUZbCvm_MIsiH1TzafVyBd8FeG1d-pMR8bgGjaDSA-DNkOEDAeAlLx-UCTl2Uk2ySoMnZr5JjVLW2DTuF7e8ySKrKQSSLe63aQyKuIZh9P1RNrwrmFwvJgXdzudVjirmdTwxAN0lijE8",
|
||||
"q": "9PJitAE_kk6SoKvJisXbDb7Xursj26xiYIdWuzlzQ1CbwYcJ1oORDpo0bEpy0BfIbZDiJJ79Xrh5Lo1BVysQ-IZJCXK7mavqiSa8g3B8rmqLXmAtjDbwLGsJOayCpYnsGgOLT7XIUYXCFH7C-tSSydhJ1j8JAbsJveMiBPKnUXc"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_3 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d214aea9b78d15dd2667f5d19c36df6647fa50023140fd4f5866d285718b897c",
|
||||
"n": "qFnqWpBOZ_5jnIr_XkXnonmHII5gKzxPhUBfvWBhGN2eH8nmnGh6aUnKyKuCLP_qfYLU7cf9bah-e00451iGite8Tg9ZMYAPFX4NM5j0rGWNv9Z6lSn1xXezJv-FU9VUwXm0DG5eVcB8OV99JWxHivQUSBzY0Q3DUlgrD7FhMd7BrrcmTUO07KnW6SxN3oTbT7fNMxfJSTRxmvU-t-6sLhYP4Wbg39zEUgI8M7b7tvHp34klSqOn2DibVBhvWGF1-IgNT7ng6pS5iAZN7Cz7NjPc9ZM_IWyngPKZV49Tf-ikX2O8uiCb4ccgRur6znwkE7MPrDTXSMHALn10sUcO_w",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_3_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d214aea9b78d15dd2667f5d19c36df6647fa50023140fd4f5866d285718b897c",
|
||||
"n": "qFnqWpBOZ_5jnIr_XkXnonmHII5gKzxPhUBfvWBhGN2eH8nmnGh6aUnKyKuCLP_qfYLU7cf9bah-e00451iGite8Tg9ZMYAPFX4NM5j0rGWNv9Z6lSn1xXezJv-FU9VUwXm0DG5eVcB8OV99JWxHivQUSBzY0Q3DUlgrD7FhMd7BrrcmTUO07KnW6SxN3oTbT7fNMxfJSTRxmvU-t-6sLhYP4Wbg39zEUgI8M7b7tvHp34klSqOn2DibVBhvWGF1-IgNT7ng6pS5iAZN7Cz7NjPc9ZM_IWyngPKZV49Tf-ikX2O8uiCb4ccgRur6znwkE7MPrDTXSMHALn10sUcO_w",
|
||||
"e": "AQAB",
|
||||
"d": "cCIT2uarktD6gFaE6cIeGzZfLuwmWiX9wX-zRWxgwDM9E2dj12IvxtmD3E2Ak4CSK69tLEQ9JUFJnc89y7pHQ0uW_VdzzWjCo0omeOu0bO_njpPJanlcXn7wMVWY9NHvdj8eEfmhk_R1ybE0piyNKpyQtcehEv3bz4kyhW1ck936zafn5GWxCEWKIF-7OcotxtOl6z1GrJ7WqglMk8ooLucnAXzaPtcvD6seUhVH0vG60yI2AEInI_jMHR-mfDxrebG2xPPJLsqH3GChqTsxG5vjuaq71sNBiY_TbaUDbmWZxV66zdjhN93Rw-lc3vCPwG5vmuA2igWH7SKsHmQOAQ",
|
||||
"p": "xvTQi8nCJGyZQm3fr7HU23FkSUYkKFUN1FRDWqjyz7kFj5rJxq5dSsNrrgVBvIBNY4TwDDcYia4rvx7KSRRwfV_rsU2-TCOxBebqVlbeV0HI7xMcVZXsv61Eugz-dznUU4wqmP_rCQ8vyNcVvCBbBLBW92n-IRQXsfuSUfuHnT8",
|
||||
"q": "2J64YbgvH62PB4h-0iYuaykgUzWVSrXENg3_GaF8877AMTe98gjcH7HzTDW1fOhIcNZtmYTwlA2SgFudLsIJLoOn0-kmHzZjZJTWcsZsfTVwKhHD8Lzic7QkrrlbTIZlVu4mfT2f0kvaQiZp6zDCke3SLvVjlD-ebqTFCDIlXkE"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_0 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4941c1e95df518587e54ddde3510c084fedf92098473537fb3fe022eaece9b42",
|
||||
"n": "ypJYaH9_PLdEgGN3WFPL1V9qhC2BRXr24f1kGocaQe7wORFlZGX6gRpOCQ1lLmziLafERoSqZuBWF4vSGLeanCRQ7UKObYalMRR_rTJk6D_VD95LNOmtR4DrucdZvjQrAuLXhM5dNLGVoSq_zQowLDMeLWDUBB_TK4WlofoxI0RVoUOt4UXnSev8M_6yIYASpOAk8gG4FAqRfmU-3JhgkZOQCD0BhKYZVw_kEhRBrS3aik-1pQkan9hYIxWwc4KKtrLHNls7--vk5xDk2Vod5sZYRLlimbqHavN2IBeAeJGJqt1grXOVlnagKqmyq2MoPKufwptJBiVrVsTplyUB9FZe9FxUfxrkkxYJHufwP-3wXhaXpPFdL86TCUuOz-jTfng1rsTpwzmwm3RqFzz01yMc1RhaeWininQqj42bhW4bgFGVRP2QqSFbCbRZ4WMW3qWr3aR2QpJ7b8ac7JUhAJoh7-UtMmyGx9UJP0gjA8Wm-O81UENoDjMMdNUaVTfpSUKB7xZppg244jNZDIm1ptq4QyvvWkr0brp9Ymxpu0e3g2HyywyPjbeyNrIelb4E2tU5vCR4Fs_zGFG71AieruJGfzPTXE7ZaiLhP8n1652NCzIH76Y7OGz4ap2D55-RKpUkSI3KqWxUKxkM0tuZ7LS2F-1wEVs8P01K6RuQpxE",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_0_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4941c1e95df518587e54ddde3510c084fedf92098473537fb3fe022eaece9b42",
|
||||
"n": "ypJYaH9_PLdEgGN3WFPL1V9qhC2BRXr24f1kGocaQe7wORFlZGX6gRpOCQ1lLmziLafERoSqZuBWF4vSGLeanCRQ7UKObYalMRR_rTJk6D_VD95LNOmtR4DrucdZvjQrAuLXhM5dNLGVoSq_zQowLDMeLWDUBB_TK4WlofoxI0RVoUOt4UXnSev8M_6yIYASpOAk8gG4FAqRfmU-3JhgkZOQCD0BhKYZVw_kEhRBrS3aik-1pQkan9hYIxWwc4KKtrLHNls7--vk5xDk2Vod5sZYRLlimbqHavN2IBeAeJGJqt1grXOVlnagKqmyq2MoPKufwptJBiVrVsTplyUB9FZe9FxUfxrkkxYJHufwP-3wXhaXpPFdL86TCUuOz-jTfng1rsTpwzmwm3RqFzz01yMc1RhaeWininQqj42bhW4bgFGVRP2QqSFbCbRZ4WMW3qWr3aR2QpJ7b8ac7JUhAJoh7-UtMmyGx9UJP0gjA8Wm-O81UENoDjMMdNUaVTfpSUKB7xZppg244jNZDIm1ptq4QyvvWkr0brp9Ymxpu0e3g2HyywyPjbeyNrIelb4E2tU5vCR4Fs_zGFG71AieruJGfzPTXE7ZaiLhP8n1652NCzIH76Y7OGz4ap2D55-RKpUkSI3KqWxUKxkM0tuZ7LS2F-1wEVs8P01K6RuQpxE",
|
||||
"e": "AQAB",
|
||||
"d": "VQagPRxm16FFC260hUqG4ASwvNIs1HEMd0bYYZobl1knU4zNthpnzxCveHU65wWk2ez1IXRF4fB_slpp0R4fszI7FZs-FRLS-4rTHGtul11TnNl9T7RVmxGt38ihDojvFMMKGyBTVu7DE2bSIsoH9kVugTWHSEPjav0pzJcrUNY56vpxXYDt18VJkrlxI0aSjMnYOAwoq6DT-O2eORFsVy5M4mhY3sipEjYFUOFXv8zjUfKrF55-omE4fWF5MsK0XoMjwtkAkHkvFx2sMN72dgsCubXmgQgeFvIhvs6eifzsf99z2NoPC5y3FbEs4Ws5VF3lLNXpDL9gEoeMVHigHKNoztIzbJnFLjzEag4wOBqbig4nWIlYEcLwd5-E0oQ8GHAhWtJn5AJQKOwTcasRWiUnRAulCcI8f9R2ATTSjAGU-juFUfhProp4w3ZlnUbO6U3tbh90KdFSJa-Bapts6ijPgEp6MHubVCHIxh1KGmod_CuGGjze1GuISEwI_4Yh0SrFlp4Wy6ecg7mKNnXvkBMd6h90LJaTzubnts33cCs-5UzCtYqmWHwXrMA6dRJuicY6su3NXxStuZn2bxU_Dn8LrS1vx_lhDU__NqMNbYj5ZvHkPvZiJNBI6Z1R5SY3pQzpH6vh9W2KRKF8cKOkushIaHNnHo7W5o4eZ9HjJFE",
|
||||
"p": "7Bxd2wTrXfeSZAEGZEnfoJaMh6hKFG-fx0wLmF9U-Myq1fCIQ-gdl_Atqy0xQxYtQl2lOPUWfySegJSxpdRF8pwvLq9Yt7xFQDrV0B8d5-FjYJ_Mk2bbyHv_PhNmnfcYHqE_VdADeSaU-MRV1iknvjdbxSxYUF-U2C6llfJhn-ZbGPmZJyz8fTWHSh8aKLPJkuYV84wcNL04hpFPJq7Bhy7HAFhRYNpxXyDO3I36DCU94uvUCY758VKLl8IYMMSqjh-thluKJSkWibo85ZOJR38XFksMr70pH-DkT0WMv3PpLtNu6ac6Ry4CEkZexSWmbVk-pduRooo0On1CMsrsLw",
|
||||
"q": "26K4gFJ0Ygqr4KaJ4QcRGN29XcjDpX5XTlHy3hCs_wEWc5wedydVgIH4tadiZcu0WinTtl0I6FYewWNpI8nFh8XJXsLOLepdKKR798zW8kEhzxdYdP1MTtGfy12KUCMeS2RQRsBJlmNdgrI0_m0JvW2LlGeK0EqvrqeS06L8bKGXkfY2aFGHl6ipSfUd5OpuSUqgfrj4-HgB8zywm-yAvn7UK-ySyQrP3K4PuOiY5QZmcPDxl8yqDAjorStrjPieYrlMqREHMsyq2FtAXhx4FzpKN7OljbE3EpgyFKkFN-wDTWRGxu3au0hQJx0-XthZ9i5r8zGcEbArQ5jZH7CQvw"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_1 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d01929d205e83facdc5080a0a4ade80853978298a5c73780e863c035d32127c9",
|
||||
"n": "ve_rSTi1vwfV2Oj7YNu1kv8Xz2ImAEqf7qo2RehTYW4FJpbj0wkMBVGmAulm4dz-1knnaPdpbrrIwkEYr1XR6kSIeB8aXkCZqDGZATxLSRqGEzu2J8Xt9z_qTQLWYD-NuMEf9H3B1CiP3Q2RnoWUlGvOr_KI5h6anzeqgZxlQLgqQujXscwqWpX7MVh3sheZ5SbyTkDcFWvQS_NEPaBGso-Au9X-yhZsHU1Ky02Nd_DPOrrRzl7uymE07hy3bIbxmrh4ZeEz6P2ixsHHYbd15GNMRlr1cWbg91RBB-akSxX0VYoLjjuqwo33UHk1hBbSATbobfpOKRruuZPZ_xOiPi-m0tUdD1Pj-h6xRcA5sZ1d55IdL8IY_9kgLc_WyU2RWFTXV6zA2SDDdE6EdEB_8q6U0oLU5T-YRxd-V2qOTqW1388qUaL5BalSvqM0g8kVfBYIM3uwLqQI_hCer4CL7_0DGlUtheye3qcoyqWVJd9iqfcWC-1S8NljAJwM9sehx6kOSM85UuUTH89VM35oAVp0rSPcLy20dPzEVQ0LAcy_iRHTkqy9nZ1z6mo-IWQE2ZyPCuESEfG7nFJ3YlUfwBJ5uZnk0N1FVYX5zgEKdkP322vShrv1blB_JtUedpbCcuS-qCaywpwjL0pzTDKpJMEqHds0-DFT7AbULcujw_U",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_1_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d01929d205e83facdc5080a0a4ade80853978298a5c73780e863c035d32127c9",
|
||||
"n": "ve_rSTi1vwfV2Oj7YNu1kv8Xz2ImAEqf7qo2RehTYW4FJpbj0wkMBVGmAulm4dz-1knnaPdpbrrIwkEYr1XR6kSIeB8aXkCZqDGZATxLSRqGEzu2J8Xt9z_qTQLWYD-NuMEf9H3B1CiP3Q2RnoWUlGvOr_KI5h6anzeqgZxlQLgqQujXscwqWpX7MVh3sheZ5SbyTkDcFWvQS_NEPaBGso-Au9X-yhZsHU1Ky02Nd_DPOrrRzl7uymE07hy3bIbxmrh4ZeEz6P2ixsHHYbd15GNMRlr1cWbg91RBB-akSxX0VYoLjjuqwo33UHk1hBbSATbobfpOKRruuZPZ_xOiPi-m0tUdD1Pj-h6xRcA5sZ1d55IdL8IY_9kgLc_WyU2RWFTXV6zA2SDDdE6EdEB_8q6U0oLU5T-YRxd-V2qOTqW1388qUaL5BalSvqM0g8kVfBYIM3uwLqQI_hCer4CL7_0DGlUtheye3qcoyqWVJd9iqfcWC-1S8NljAJwM9sehx6kOSM85UuUTH89VM35oAVp0rSPcLy20dPzEVQ0LAcy_iRHTkqy9nZ1z6mo-IWQE2ZyPCuESEfG7nFJ3YlUfwBJ5uZnk0N1FVYX5zgEKdkP322vShrv1blB_JtUedpbCcuS-qCaywpwjL0pzTDKpJMEqHds0-DFT7AbULcujw_U",
|
||||
"e": "AQAB",
|
||||
"d": "mCjZ3wDVaMJIKMsMhx28KpS9aGACfX1K_pHRhNOH6KeQ7Mc4oFnBDYnJas-8ofi_FsCB6G88QX7VUfmAYwZncjuQ8FpKb3NlJX8GSh0ZWukqu8G8PcSszMShWSyKvPRs_rOIe_87BlGwXrB-FfaBfx2WqRGtZlziFecsa0T1QJHJGW0bTs52p7c7Ut7ClSOfIBrBRrtjFK4YYp_x7US3HlkkElZvFUo9NoQzBQeN66Y4_Z2ocqFOv0Z8drz-nKzGZOKfYU62nVKD0qJurfOhOGPsOPipZD28v6b5qfC1cYmXAefjNgDK3a2JkShpHPaDKoHoViKN9xQiZvzxSQ1bjQCgB6xQWk61YwmiB44gFLshXvXkx_wcccO2XC4m-Pk0r-Uj9Ugvgizk8HYp1H9eqnp8A6sqU44mrmdt14vM68SGzEqYpLoUkcxPttHvNoORAzgQfuK3SOIFyuwFqKTMBupR4A42XvxLj_PuKEKFekS2JEK8fON2t_LuUDVemjMxwXD0gjljHSKD9HnguihI5IEd6Kgr-HlTwiiDQfzcmWQdoFUs_Je4tVCSbGRrJYju01gLouDu7gzN14pZcEyoBLPkj-_MDiiymvlBLOBU2s5nQRZCaC_0IKgHLaT_rzQaXwmVhU-OURdwdoViMVc_cdXtle4TqU1g41nNE_0tiwE",
|
||||
"p": "2h_9HZCOpf3S9qpAkNS2ncMsRjBlWCpRltoCs-XBF_IgOJlCkJ-42k_V1zaf6YrgMy00XD4Ij5MMiUOharvc3w_WKJF-AwGu9JEpi38Wzj1nkY86sdB1ZPu4ihSRZm81jIjuLZ2siILqkupXaY0S_0CeNLKPoVpvfPWCb3psCWuLVRDhYECPCx9FYg2tzisbFpVAPPqNCFswMYNvhyJ2NQ0hzueKDc1uHBUanCSG6gIbeY1bQvYYFGySYkWZcQg98RSeDbLysHalCSQCgPjss3likTT9OjWLv23vpXURFhgywv6Phx4He0yWB8ZRrnskfW0S76kZ325SPUlnOhf31Q",
|
||||
"q": "3urwELOa7TDpwLMeMEOf2aspz1gkMjoN-V4SMzRGxIoPy93-bQ62Z8nPduma1gK0zHOIs0gU8dDqjy8P8Z7vudJqRFJIrzjD-RnDqQDz7KM_6x0kbEN4GLQiNGVAckRhoEmYjDXXkG3teD2ST5NqlYwxGvFmCvw5RCJZG7eNjXY3KnJQrDyx61NIFEvSm3sBlJkOVhSanuqHBL6T-efaBkUcQ7mY7_iYtCt7cjMG8qQtF0KovVsMF6BUc9KDobpUvDsvPrSTAzsYJvVNkzGJtF8Strr-61VA6qZnRcDW3ukYvmJp_SdAcv3KzSkWwEmJEaAtaiOh2jWkRG9QpV_LoQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_2 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "822512e8098b9fa56c9152a56d2607bda912c89f6f4fe1b6ccf41627bf06de29",
|
||||
"n": "3bcg0diA0TPvK283P02o5UT8cBf5q48uUsfuCkIbLqNFtskGuoft8OJLmik7c7pLNSK3Jad_-xRlfsrcV1fDBs8EJDFnoY-4r_xk_-GQl-OsHzuz7HMvjVYUSYeVZMtzPAfCIFJxSIaiIW9MEwCwYyrtRefedfKUV7Ax6hjOUXtyRZ5DRHj2FnNl6MjE8mTSJ8OQI9ETErg0wF448fJb6hYCidVHfeBSCOceljXMg8a9iDYHVnzsUb9ETl7xlRZDvUpIoG0jU-aC3oZdM0YgXspvw4FcXg1-ad-TbgRjEm_iJ-4KUhAYso6-Y6eimDT_TMhbKBLGE86pUjRPIXVNl6odjkXmcmh7bz9v0-gIfHB9zVbrqE8i8iIwkux-Uhq_VMiIFikjtjmDo5W-7qA_cjvq1dA1QqOJ54ijbdvglUtneuA5CnwfGHAvf94lEPebgP5eCMZjz_Dtl0FTX0u5lOVBs4qeyEfV1XANOq_h1gHmwJDlspGZVuPfSk4-YMCeBy5Ua_gNDqOIQo3EQbmjyN5yD9byFh3WDSQJN1kKT3BZSou-Q8-KT2lu9KT_CpTfVMaNXnPpXJ_H0S9Q7sbUzA6dF1h0Q_mu_bOlWTRlH3vXfZ3_3Vikjk-jhQdaRv8yjTdhX33wAVHk7omKlo76G3QJdnvjysJ6aagFPZ3qhmc",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_2_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "822512e8098b9fa56c9152a56d2607bda912c89f6f4fe1b6ccf41627bf06de29",
|
||||
"n": "3bcg0diA0TPvK283P02o5UT8cBf5q48uUsfuCkIbLqNFtskGuoft8OJLmik7c7pLNSK3Jad_-xRlfsrcV1fDBs8EJDFnoY-4r_xk_-GQl-OsHzuz7HMvjVYUSYeVZMtzPAfCIFJxSIaiIW9MEwCwYyrtRefedfKUV7Ax6hjOUXtyRZ5DRHj2FnNl6MjE8mTSJ8OQI9ETErg0wF448fJb6hYCidVHfeBSCOceljXMg8a9iDYHVnzsUb9ETl7xlRZDvUpIoG0jU-aC3oZdM0YgXspvw4FcXg1-ad-TbgRjEm_iJ-4KUhAYso6-Y6eimDT_TMhbKBLGE86pUjRPIXVNl6odjkXmcmh7bz9v0-gIfHB9zVbrqE8i8iIwkux-Uhq_VMiIFikjtjmDo5W-7qA_cjvq1dA1QqOJ54ijbdvglUtneuA5CnwfGHAvf94lEPebgP5eCMZjz_Dtl0FTX0u5lOVBs4qeyEfV1XANOq_h1gHmwJDlspGZVuPfSk4-YMCeBy5Ua_gNDqOIQo3EQbmjyN5yD9byFh3WDSQJN1kKT3BZSou-Q8-KT2lu9KT_CpTfVMaNXnPpXJ_H0S9Q7sbUzA6dF1h0Q_mu_bOlWTRlH3vXfZ3_3Vikjk-jhQdaRv8yjTdhX33wAVHk7omKlo76G3QJdnvjysJ6aagFPZ3qhmc",
|
||||
"e": "AQAB",
|
||||
"d": "wcO4mAxJUAu-OsxgkR9SusPWhjQ9y5Q_XLNDso1hahng5ES9b6k55mouvlTIk3Q9I_vp6auAKrMBnJS3ilG1rK6hJOxUcBrFwm-m6QV9s3CSzV0E-mEULsYKxtQKWOOBGvaAznSeck7PRL8a0gSpIpGyeYSRo6zTverLRJZXQVjMXlFY4m-ASdCiQJWtoVVBYOUFhHfE3nhECdaOl8xCTcrcfw75AuZXa1ZpIcd0q7m1jGQDd6-HbE3m6UMKiEvD-ZsA68tVs45h0w3ER_pCcfUjRc45Ji1OzEJLezu0RbmoAVOEi4FrxCkB9N_dNn4inD0BhX0axNa4nZH_kfMNUh06081FaBiBq5bNBPQF7lWIYxAhtd2VgsUTZtNxMfHDTllt5fvbCogYngU5-Wj3UM33R_es_aakt_CFndJPmyenP0J7KEBmf4qnlrbxun-jQNV_cbEzgQA_Pt5RIhB5jgofYzT72Ib-lViZUolXpxg8mFQ5BPghqriuaX8eSc85y5rbu-nEvheDkIC7xjTtDBShXMvKKokx6t4d-x_W4sWDuLKsVNn3Veg6mbbl3O74Fr-joEM9unMg-9KCapAuBKmMv4GejOVOIj43i0lm8dsuMslNKsThWpjApE50-VBuySi1f0jD2HNEzjMTt5ZrlNi9bRFzAht46kdc_g4TWLE",
|
||||
"p": "7cl5QebQldiOrfe2Z7E2aP4d1GIuX4b3u-kXUDa73HI4S2u9TooJF8lfsbrtzJIG60iIzio9Pej8R4ss2_1TPC_F7gQS67ST5yY2zuwUH6jwpt8KtVO3NKd9SNfVJse_mZLp7eAeH8CMq4bqkDig8ZI_Sp1LQtWXvhvhju40i0h1ef-MD36wbc26BE1L6tQMAoJIU-pMDawmWMGG3Q5_LxKHb1cxvV8gVfFgsJbAHMPXxcmpCdp1FqeqpvRs3bch3AMxHwjy1SFRK6lhvliS2ZvD7fdupA09PGJ-cNO3S9iHdCvsnyOHg9pMbxxcYW8Io_t1ihk6JYFvZlDIYvukXw",
|
||||
"q": "7rKFf6190MlunvlLSdMvN_E2Xuow35_EThaxQ9e_7FS32LKPy847vFreXzVivVW1IVXrRSDgU8VIEyBQzftliLSriefKYdx2jtd_A84baha4p6CAK9SwfZcVEcIuU2Ul8XcUpbg53_bxUWDv4mYewZW_AqaZ0ZR1Ug14gCGHELvjs7MmWkCkJB6lEenRQZvzwcmA8tWzZ6Dlqb_RyLtxcVPbeSuc3t6YxbB1-pquwXoQLB9-XvgR_4L6vuGZrp1D-C0lzboUPoftkC_hKYb_xY6LPJTsL8LUypATcTrAnD0TBrqj5-Oy_4dMin6OcsXrfdxflxaJqkh7B-kz20oa-Q"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_3 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "ad60df152305985e6bdd8cb1d1f496f766aed097b7464b8b821a09b27f054dcb",
|
||||
"n": "q8mHub9-A7LH2ykklO52CRQ9KYeM9FlHaoLJCMokmwdb8FF8cAMOPDQ4lx7rB107vwX5oHS6T4uhOUH6ppgZnvB083-f5cBfvZPSwvKg1csOPI3Llp-hIO3vnu7v4M-dXRJevmNdTAoHINXP8mJ1KfGL6BuxckxLEOoIX0suSmyudAE_lc6ioMAfwehkH7qTWwllIuReGwxHHYapM0AFIYysJ0z96l-WNkO3ssLm6Q7txpumM_b0d58OkdezBLujEfn0t5H8hsml_LUSE4TfWcGwm3oDBB2q5tsI2_QmVwdV6BcP43Sm8R7EbJvTQq3YXKLlC-Et4-3CDGaMV6z1eFmHBs_FMGzto-kg9MUFockOe0vkfjHj6AafNw7AFyBJRvV3EdMM-O1ysiC5cs45aowbfQIz_9H9RVbR9iMiEjq6nM34bhgfu-FvOmAcliCOJnDlBy2wWe2XyXTLQVkmn1C_w2mitcQAkP-LiktypUwSIbyDqfBai1_imO1SIVzomRLvzSju5qGrcm0ROV6o9zKXCVc546g9la9FUTTPZsI0_s3hcVRVMaF3fa122hE848serjCqNJ0Nb3CYOlVCc6JrkUdeuCj0Y-on6V6aeCFAQxFb1z_p88STsNJkrcNZp87f1JUaSB4POF01dLNQ2HTe7xJCMRmK-fpNuDCOzNM",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_3_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "ad60df152305985e6bdd8cb1d1f496f766aed097b7464b8b821a09b27f054dcb",
|
||||
"n": "q8mHub9-A7LH2ykklO52CRQ9KYeM9FlHaoLJCMokmwdb8FF8cAMOPDQ4lx7rB107vwX5oHS6T4uhOUH6ppgZnvB083-f5cBfvZPSwvKg1csOPI3Llp-hIO3vnu7v4M-dXRJevmNdTAoHINXP8mJ1KfGL6BuxckxLEOoIX0suSmyudAE_lc6ioMAfwehkH7qTWwllIuReGwxHHYapM0AFIYysJ0z96l-WNkO3ssLm6Q7txpumM_b0d58OkdezBLujEfn0t5H8hsml_LUSE4TfWcGwm3oDBB2q5tsI2_QmVwdV6BcP43Sm8R7EbJvTQq3YXKLlC-Et4-3CDGaMV6z1eFmHBs_FMGzto-kg9MUFockOe0vkfjHj6AafNw7AFyBJRvV3EdMM-O1ysiC5cs45aowbfQIz_9H9RVbR9iMiEjq6nM34bhgfu-FvOmAcliCOJnDlBy2wWe2XyXTLQVkmn1C_w2mitcQAkP-LiktypUwSIbyDqfBai1_imO1SIVzomRLvzSju5qGrcm0ROV6o9zKXCVc546g9la9FUTTPZsI0_s3hcVRVMaF3fa122hE848serjCqNJ0Nb3CYOlVCc6JrkUdeuCj0Y-on6V6aeCFAQxFb1z_p88STsNJkrcNZp87f1JUaSB4POF01dLNQ2HTe7xJCMRmK-fpNuDCOzNM",
|
||||
"e": "AQAB",
|
||||
"d": "QFcw8I8aQYRaemlEfEt8BhaAeed9EZ_GscveQ96CK1ZsRuweMU3TrRTaBS_dU1rGH9u7DS_rABQKBIoDuRXKss7Y3sJ0Pvb4ZObSz5VUS_7LjD6HfBi5nr2_O8W-LnNUOyHAPoq0zOAMn221ftEFlPoVLpAAvBB7JRCiph5gbhuak3RMPm2wV4jd3CCQL5oPys8QBCuIW5UTpalkAf_-a_xmFiouB_RZLGXcjaWWGsAuqm5tp5TdJ1h5eoJRWHp2ryrxTzfsXwdzldyzsn_Xr6Rt4y2lp4r9EY4EGW2uVnY25MCOgOCWDkU5yHvselLmcHvKUdK6_11zinV2Jvhuz1FaW10P6lRXxhjuuT4bT7XmY6WkJCUvWf8w_NYrGwDbRvQa6YZcZZWKZ1l2Enkgd_P4qwtrnROQSCe0dJdNG3lSq90lrAwuvb8AhKhpQ8nJSaSQc_h2pa4NJZ-R__9m0_7CRUuEEg9k47AtgdIe09KLSpcACc3W5cBXEw2pL8ihqcf9AVgM0TFQQVrUdIst3YjUiB6r2zLVCRx8KjtT8Pmz6YtMQwDIFTrUopwwai5PEP3QEdxdNF39W1iwkqjA8uw4IlXgZAr4-9s3x617XUL0BQ4TgMpTsEghpV1U8U2HQfYGUKBcAlSqIlAi0MU4QRwcsAJrcoTIi-e34NFMbHE",
|
||||
"p": "xvZ1BKzaRfrmQT2mmbK1MzKdr4amHrx4EJ_4fRsCRBj8MqB92y4Bp0iuO8rZ3iK_yOOgQQTcr4UP5UEACLOqGDPNa92UUpHu1U5XR3MiIY0kGcdovpkkGU8fq78VRpyofc1b9kvZsy4eL0e7W7jApjGu479D_evnpT7lqSOGRl1Z0QHdI3ctKmKw48-AmQWL4BibXTyaXOfRgTHm4AtbrvFshwCZ43QgzrCrwbhZlOfiIIW9wXa_OqqOhV11BLF72qTglecfTgUOxY0W5GWgbwXCVZ8Lwr6cxYKGrKjmny9UNOIjABGsJjZm5egwDNUhhoaEeXXyzXbCKynvUCDxZw",
|
||||
"q": "3Qi1bRzj3TYW3Iw9KSDCuuHWBJRO_3Ke-JLB7PHEXc1hsPwF_XDqXPaBbIUtgKaqNzUehYAQbtHHhJVGqZadTKjsNkO4sO_r5nRoxUpFuGgUEmKNN0QeJa_llHzAZ9JpvUrtoyzVZX-2Em_3aAhtV5pZ6t22YToPDjZIBgqL96MQRCyKsv2FS_dbpoYKdXlG6phzkzKPn3oaWkh-VwmgAsFg7uXdiquQEsXYcOq3-77Umiuke6SBbaHLryLflTzOV7YvY7Kw3s3NycS9MDBESKYXqqX3YKvS25ZFFjYbrVOx5AluLiwajZu2biIPZb9rNbSXE77Hll3tAbmA5syJtQ"
|
||||
}`)
|
||||
)
|
||||
198
vendor/github.com/coreos/go-oidc/jwks.go
generated
vendored
198
vendor/github.com/coreos/go-oidc/jwks.go
generated
vendored
@@ -3,6 +3,7 @@ package oidc
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -38,147 +39,158 @@ type remoteKeySet struct {
|
||||
// guard all other fields
|
||||
mu sync.Mutex
|
||||
|
||||
// inflightCtx suppresses parallel execution of updateKeys and allows
|
||||
// inflight suppresses parallel execution of updateKeys and allows
|
||||
// multiple goroutines to wait for its result.
|
||||
// Its Err() method returns any errors encountered during updateKeys.
|
||||
//
|
||||
// If nil, there is no inflight updateKeys request.
|
||||
inflightCtx *inflight
|
||||
inflight *inflight
|
||||
|
||||
// A set of cached keys and their expiry.
|
||||
cachedKeys []jose.JSONWebKey
|
||||
expiry time.Time
|
||||
}
|
||||
|
||||
// inflight is used to wait on some in-flight request from multiple goroutines
|
||||
// inflight is used to wait on some in-flight request from multiple goroutines.
|
||||
type inflight struct {
|
||||
done chan struct{}
|
||||
doneCh chan struct{}
|
||||
|
||||
keys []jose.JSONWebKey
|
||||
err error
|
||||
}
|
||||
|
||||
// Done returns a channel that is closed when the inflight request finishes.
|
||||
func (i *inflight) Done() <-chan struct{} {
|
||||
return i.done
|
||||
func newInflight() *inflight {
|
||||
return &inflight{doneCh: make(chan struct{})}
|
||||
}
|
||||
|
||||
// Err returns any error encountered during request execution. May be nil.
|
||||
func (i *inflight) Err() error {
|
||||
return i.err
|
||||
// wait returns a channel that multiple goroutines can receive on. Once it returns
|
||||
// a value, the inflight request is done and result() can be inspected.
|
||||
func (i *inflight) wait() <-chan struct{} {
|
||||
return i.doneCh
|
||||
}
|
||||
|
||||
// Cancel signals completion of the inflight request with error err.
|
||||
// Must be called only once for particular inflight instance.
|
||||
func (i *inflight) Cancel(err error) {
|
||||
// done can only be called by a single goroutine. It records the result of the
|
||||
// inflight request and signals other goroutines that the result is safe to
|
||||
// inspect.
|
||||
func (i *inflight) done(keys []jose.JSONWebKey, err error) {
|
||||
i.keys = keys
|
||||
i.err = err
|
||||
close(i.done)
|
||||
close(i.doneCh)
|
||||
}
|
||||
|
||||
func (r *remoteKeySet) keysWithIDFromCache(keyIDs []string) ([]jose.JSONWebKey, bool) {
|
||||
r.mu.Lock()
|
||||
keys, expiry := r.cachedKeys, r.expiry
|
||||
r.mu.Unlock()
|
||||
// result cannot be called until the wait() channel has returned a value.
|
||||
func (i *inflight) result() ([]jose.JSONWebKey, error) {
|
||||
return i.keys, i.err
|
||||
}
|
||||
|
||||
// Have the keys expired?
|
||||
if expiry.Add(keysExpiryDelta).Before(r.now()) {
|
||||
return nil, false
|
||||
func (r *remoteKeySet) verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) {
|
||||
// We don't support JWTs signed with multiple signatures.
|
||||
keyID := ""
|
||||
for _, sig := range jws.Signatures {
|
||||
keyID = sig.Header.KeyID
|
||||
break
|
||||
}
|
||||
|
||||
var signingKeys []jose.JSONWebKey
|
||||
keys, expiry := r.keysFromCache()
|
||||
|
||||
// Don't check expiry yet. This optimizes for when the provider is unavailable.
|
||||
for _, key := range keys {
|
||||
if contains(keyIDs, key.KeyID) {
|
||||
signingKeys = append(signingKeys, key)
|
||||
if keyID == "" || key.KeyID == keyID {
|
||||
if payload, err := jws.Verify(&key); err == nil {
|
||||
return payload, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(signingKeys) == 0 {
|
||||
// Are the keys about to expire?
|
||||
if r.now().Add(keysExpiryDelta).After(expiry) {
|
||||
return nil, false
|
||||
}
|
||||
if !r.now().Add(keysExpiryDelta).After(expiry) {
|
||||
// Keys haven't expired, don't refresh.
|
||||
return nil, errors.New("failed to verify id token signature")
|
||||
}
|
||||
|
||||
return signingKeys, true
|
||||
keys, err := r.keysFromRemote(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetching keys %v", err)
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
if keyID == "" || key.KeyID == keyID {
|
||||
if payload, err := jws.Verify(&key); err == nil {
|
||||
return payload, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, errors.New("failed to verify id token signature")
|
||||
}
|
||||
func (r *remoteKeySet) keysWithID(ctx context.Context, keyIDs []string) ([]jose.JSONWebKey, error) {
|
||||
keys, ok := r.keysWithIDFromCache(keyIDs)
|
||||
if ok {
|
||||
return keys, nil
|
||||
|
||||
func (r *remoteKeySet) keysFromCache() (keys []jose.JSONWebKey, expiry time.Time) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
return r.cachedKeys, r.expiry
|
||||
}
|
||||
|
||||
// keysFromRemote syncs the key set from the remote set, records the values in the
|
||||
// cache, and returns the key set.
|
||||
func (r *remoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, error) {
|
||||
// Need to lock to inspect the inflight request field.
|
||||
r.mu.Lock()
|
||||
// If there's not a current inflight request, create one.
|
||||
if r.inflight == nil {
|
||||
r.inflight = newInflight()
|
||||
|
||||
// This goroutine has exclusive ownership over the current inflight
|
||||
// request. It releases the resource by nil'ing the inflight field
|
||||
// once the goroutine is done.
|
||||
go func() {
|
||||
// Sync keys and finish inflight when that's done.
|
||||
keys, expiry, err := r.updateKeys()
|
||||
|
||||
r.inflight.done(keys, err)
|
||||
|
||||
// Lock to update the keys and indicate that there is no longer an
|
||||
// inflight request.
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if err == nil {
|
||||
r.cachedKeys = keys
|
||||
r.expiry = expiry
|
||||
}
|
||||
|
||||
// Free inflight so a different request can run.
|
||||
r.inflight = nil
|
||||
}()
|
||||
}
|
||||
|
||||
var inflightCtx *inflight
|
||||
func() {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
// If there's not a current inflight request, create one.
|
||||
if r.inflightCtx == nil {
|
||||
inflightCtx := &inflight{make(chan struct{}), nil}
|
||||
r.inflightCtx = inflightCtx
|
||||
|
||||
go func() {
|
||||
// TODO(ericchiang): Upstream Kubernetes request that we recover every time
|
||||
// we spawn a goroutine, because panics in a goroutine will bring down the
|
||||
// entire program. There's no way to recover from another goroutine's panic.
|
||||
//
|
||||
// Most users actually want to let the panic propagate and bring down the
|
||||
// program because it implies some unrecoverable state.
|
||||
//
|
||||
// Add a context key to allow the recover behavior.
|
||||
//
|
||||
// See: https://github.com/coreos/go-oidc/issues/89
|
||||
|
||||
// Sync keys and close inflightCtx when that's done.
|
||||
// Use the remoteKeySet's context instead of the requests context
|
||||
// because a re-sync is unique to the keys set and will span multiple
|
||||
// requests.
|
||||
inflightCtx.Cancel(r.updateKeys(r.ctx))
|
||||
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.inflightCtx = nil
|
||||
}()
|
||||
}
|
||||
|
||||
inflightCtx = r.inflightCtx
|
||||
}()
|
||||
inflight := r.inflight
|
||||
r.mu.Unlock()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-inflightCtx.Done():
|
||||
if err := inflightCtx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case <-inflight.wait():
|
||||
return inflight.result()
|
||||
}
|
||||
|
||||
// Since we've just updated keys, we don't care about the cache miss.
|
||||
keys, _ = r.keysWithIDFromCache(keyIDs)
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (r *remoteKeySet) updateKeys(ctx context.Context) error {
|
||||
func (r *remoteKeySet) updateKeys() ([]jose.JSONWebKey, time.Time, error) {
|
||||
req, err := http.NewRequest("GET", r.jwksURL, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oidc: can't create request: %v", err)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: can't create request: %v", err)
|
||||
}
|
||||
|
||||
resp, err := doRequest(ctx, req)
|
||||
resp, err := doRequest(r.ctx, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oidc: get keys failed %v", err)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: get keys failed %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oidc: read response body: %v", err)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: read response body: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("oidc: get keys failed: %s %s", resp.Status, body)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: get keys failed: %s %s", resp.Status, body)
|
||||
}
|
||||
|
||||
var keySet jose.JSONWebKeySet
|
||||
if err := json.Unmarshal(body, &keySet); err != nil {
|
||||
return fmt.Errorf("oidc: failed to decode keys: %v %s", err, body)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: failed to decode keys: %v %s", err, body)
|
||||
}
|
||||
|
||||
// If the server doesn't provide cache control headers, assume the
|
||||
@@ -189,11 +201,5 @@ func (r *remoteKeySet) updateKeys(ctx context.Context) error {
|
||||
if err == nil && e.After(expiry) {
|
||||
expiry = e
|
||||
}
|
||||
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.cachedKeys = keySet.Keys
|
||||
r.expiry = expiry
|
||||
|
||||
return nil
|
||||
return keySet.Keys, expiry, nil
|
||||
}
|
||||
|
||||
293
vendor/github.com/coreos/go-oidc/jwks_test.go
generated
vendored
293
vendor/github.com/coreos/go-oidc/jwks_test.go
generated
vendored
@@ -1,99 +1,250 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
type keyServer struct {
|
||||
keys jose.JSONWebKeySet
|
||||
keys jose.JSONWebKeySet
|
||||
setHeaders func(h http.Header)
|
||||
}
|
||||
|
||||
func newKeyServer(keys ...jose.JSONWebKey) keyServer {
|
||||
return keyServer{
|
||||
keys: jose.JSONWebKeySet{Keys: keys},
|
||||
func (k *keyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if k.setHeaders != nil {
|
||||
k.setHeaders(w.Header())
|
||||
}
|
||||
}
|
||||
|
||||
func (k keyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewEncoder(w).Encode(k.keys); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeysFormID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
keys []jose.JSONWebKey
|
||||
keyIDs []string
|
||||
wantKeys []jose.JSONWebKey
|
||||
}{
|
||||
{
|
||||
name: "single key",
|
||||
keys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
testKeyECDSA_256_0,
|
||||
},
|
||||
keyIDs: []string{
|
||||
testKeyRSA_2048_0.KeyID,
|
||||
},
|
||||
wantKeys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one key id matches",
|
||||
keys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
testKeyECDSA_256_0,
|
||||
},
|
||||
keyIDs: []string{
|
||||
testKeyRSA_2048_0.KeyID,
|
||||
testKeyRSA_2048_1.KeyID,
|
||||
},
|
||||
wantKeys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no valid keys",
|
||||
keys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_1,
|
||||
testKeyECDSA_256_0,
|
||||
},
|
||||
keyIDs: []string{
|
||||
testKeyRSA_2048_0.KeyID,
|
||||
},
|
||||
},
|
||||
type signingKey struct {
|
||||
keyID string // optional
|
||||
priv interface{}
|
||||
pub interface{}
|
||||
alg jose.SignatureAlgorithm
|
||||
}
|
||||
|
||||
// sign creates a JWS using the private key from the provided payload.
|
||||
func (s *signingKey) sign(t *testing.T, payload []byte) string {
|
||||
privKey := &jose.JSONWebKey{Key: s.priv, Algorithm: string(s.alg), KeyID: s.keyID}
|
||||
|
||||
signer, err := jose.NewSigner(jose.SigningKey{Algorithm: s.alg, Key: privKey}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jws, err := signer.Sign(payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t0 := time.Now()
|
||||
now := func() time.Time { return t0 }
|
||||
data, err := jws.CompactSerialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
func() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
// jwk returns the public part of the signing key.
|
||||
func (s *signingKey) jwk() jose.JSONWebKey {
|
||||
return jose.JSONWebKey{Key: s.pub, Use: "sig", Algorithm: string(s.alg), KeyID: s.keyID}
|
||||
}
|
||||
|
||||
server := httptest.NewServer(newKeyServer(test.keys...))
|
||||
defer server.Close()
|
||||
func newRSAKey(t *testing.T) *signingKey {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 1028)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return &signingKey{"", priv, priv.Public(), jose.RS256}
|
||||
}
|
||||
|
||||
keySet := newRemoteKeySet(ctx, server.URL, now)
|
||||
gotKeys, err := keySet.keysWithID(ctx, test.keyIDs)
|
||||
if err != nil {
|
||||
t.Errorf("%s: %v", test.name, err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(gotKeys, test.wantKeys) {
|
||||
t.Errorf("%s: expected keys=%#v, got=%#v", test.name, test.wantKeys, gotKeys)
|
||||
}
|
||||
}()
|
||||
func newECDSAKey(t *testing.T) *signingKey {
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return &signingKey{"", priv, priv.Public(), jose.ES256}
|
||||
}
|
||||
|
||||
func TestRSAVerify(t *testing.T) {
|
||||
good := newRSAKey(t)
|
||||
bad := newRSAKey(t)
|
||||
|
||||
testKeyVerify(t, good, bad, good)
|
||||
}
|
||||
|
||||
func TestECDSAVerify(t *testing.T) {
|
||||
good := newECDSAKey(t)
|
||||
bad := newECDSAKey(t)
|
||||
testKeyVerify(t, good, bad, good)
|
||||
}
|
||||
|
||||
func TestMultipleKeysVerify(t *testing.T) {
|
||||
key1 := newRSAKey(t)
|
||||
key2 := newRSAKey(t)
|
||||
bad := newECDSAKey(t)
|
||||
|
||||
key1.keyID = "key1"
|
||||
key2.keyID = "key2"
|
||||
bad.keyID = "key3"
|
||||
|
||||
testKeyVerify(t, key2, bad, key1, key2)
|
||||
}
|
||||
|
||||
func TestMismatchedKeyID(t *testing.T) {
|
||||
key1 := newRSAKey(t)
|
||||
key2 := newRSAKey(t)
|
||||
|
||||
// shallow copy
|
||||
bad := new(signingKey)
|
||||
*bad = *key1
|
||||
|
||||
// The bad key is a valid key this time, but has a different Key ID.
|
||||
// It shouldn't match key1 because of the mismatched ID, even though
|
||||
// it would confirm the signature just fine.
|
||||
bad.keyID = "key3"
|
||||
|
||||
key1.keyID = "key1"
|
||||
key2.keyID = "key2"
|
||||
|
||||
testKeyVerify(t, key2, bad, key1, key2)
|
||||
}
|
||||
|
||||
func testKeyVerify(t *testing.T, good, bad *signingKey, verification ...*signingKey) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
keySet := jose.JSONWebKeySet{}
|
||||
for _, v := range verification {
|
||||
keySet.Keys = append(keySet.Keys, v.jwk())
|
||||
}
|
||||
|
||||
payload := []byte("a secret")
|
||||
|
||||
jws, err := jose.ParseSigned(good.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
badJWS, err := jose.ParseSigned(bad.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s := httptest.NewServer(&keyServer{keys: keySet})
|
||||
defer s.Close()
|
||||
|
||||
rks := newRemoteKeySet(ctx, s.URL, nil)
|
||||
|
||||
// Ensure the token verifies.
|
||||
gotPayload, err := rks.verify(ctx, jws)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(gotPayload, payload) {
|
||||
t.Errorf("expected payload %s got %s", payload, gotPayload)
|
||||
}
|
||||
|
||||
// Ensure the token verifies from the cache.
|
||||
gotPayload, err = rks.verify(ctx, jws)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(gotPayload, payload) {
|
||||
t.Errorf("expected payload %s got %s", payload, gotPayload)
|
||||
}
|
||||
|
||||
// Ensure item signed by wrong token doesn't verify.
|
||||
if _, err := rks.verify(context.Background(), badJWS); err == nil {
|
||||
t.Errorf("incorrectly verified signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheControl(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
key1 := newRSAKey(t)
|
||||
key2 := newRSAKey(t)
|
||||
|
||||
key1.keyID = "key1"
|
||||
key2.keyID = "key2"
|
||||
|
||||
payload := []byte("a secret")
|
||||
jws1, err := jose.ParseSigned(key1.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jws2, err := jose.ParseSigned(key2.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cacheForSeconds := 1200
|
||||
now := time.Now()
|
||||
|
||||
server := &keyServer{
|
||||
keys: jose.JSONWebKeySet{
|
||||
Keys: []jose.JSONWebKey{key1.jwk()},
|
||||
},
|
||||
setHeaders: func(h http.Header) {
|
||||
h.Set("Cache-Control", "max-age="+strconv.Itoa(cacheForSeconds))
|
||||
},
|
||||
}
|
||||
s := httptest.NewServer(server)
|
||||
defer s.Close()
|
||||
|
||||
rks := newRemoteKeySet(ctx, s.URL, func() time.Time { return now })
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err == nil {
|
||||
t.Errorf("incorrectly verified signature")
|
||||
}
|
||||
|
||||
// Add second key to public list.
|
||||
server.keys = jose.JSONWebKeySet{
|
||||
Keys: []jose.JSONWebKey{key1.jwk(), key2.jwk()},
|
||||
}
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err == nil {
|
||||
t.Errorf("incorrectly verified signature, still within cache limit")
|
||||
}
|
||||
|
||||
// Move time forward. Remote key set should not query the remote server.
|
||||
now = now.Add(time.Duration(cacheForSeconds) * time.Second)
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
|
||||
// Kill server and move time forward again. Keys should still verify.
|
||||
s.Close()
|
||||
now = now.Add(time.Duration(cacheForSeconds) * time.Second)
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
14
vendor/github.com/coreos/go-oidc/oidc.go
generated
vendored
14
vendor/github.com/coreos/go-oidc/oidc.go
generated
vendored
@@ -232,7 +232,8 @@ type IDToken struct {
|
||||
|
||||
// Initial nonce provided during the authentication redirect.
|
||||
//
|
||||
// If present, this package ensures this is a valid nonce.
|
||||
// This package does NOT provided verification on the value of this field
|
||||
// and it's the user's responsibility to ensure it contains a valid value.
|
||||
Nonce string
|
||||
|
||||
// Raw payload of the id_token.
|
||||
@@ -285,13 +286,6 @@ func (a *audience) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a audience) MarshalJSON() ([]byte, error) {
|
||||
if len(a) == 1 {
|
||||
return json.Marshal(a[0])
|
||||
}
|
||||
return json.Marshal([]string(a))
|
||||
}
|
||||
|
||||
type jsonTime time.Time
|
||||
|
||||
func (j *jsonTime) UnmarshalJSON(b []byte) error {
|
||||
@@ -313,7 +307,3 @@ func (j *jsonTime) UnmarshalJSON(b []byte) error {
|
||||
*j = jsonTime(time.Unix(unix, 0))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j jsonTime) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(time.Time(j).Unix())
|
||||
}
|
||||
|
||||
1
vendor/github.com/coreos/go-oidc/test
generated
vendored
1
vendor/github.com/coreos/go-oidc/test
generated
vendored
@@ -13,3 +13,4 @@ go test -v -i -race github.com/coreos/go-oidc/...
|
||||
go test -v -race github.com/coreos/go-oidc/...
|
||||
golint $LINTABLE
|
||||
go vet github.com/coreos/go-oidc/...
|
||||
go build -v ./example/...
|
||||
|
||||
74
vendor/github.com/coreos/go-oidc/verify.go
generated
vendored
74
vendor/github.com/coreos/go-oidc/verify.go
generated
vendored
@@ -19,9 +19,15 @@ const (
|
||||
issuerGoogleAccountsNoScheme = "accounts.google.com"
|
||||
)
|
||||
|
||||
// keySet is an interface that lets us stub out verification policies for
|
||||
// testing. Outside of testing, it's always backed by a remoteKeySet.
|
||||
type keySet interface {
|
||||
verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error)
|
||||
}
|
||||
|
||||
// IDTokenVerifier provides verification for ID Tokens.
|
||||
type IDTokenVerifier struct {
|
||||
keySet *remoteKeySet
|
||||
keySet keySet
|
||||
config *Config
|
||||
issuer string
|
||||
}
|
||||
@@ -34,12 +40,6 @@ type Config struct {
|
||||
//
|
||||
// If not provided, users must explicitly set SkipClientIDCheck.
|
||||
ClientID string
|
||||
// Method to verify the ID Token nonce. If a nonce is present and this method
|
||||
// is nil, users must explicitly set SkipNonceCheck.
|
||||
//
|
||||
// If the ID Token nonce is empty, for example if the client didn't provide a nonce in
|
||||
// the initial redirect, this may be nil.
|
||||
ClaimNonce func(nonce string) error
|
||||
// If specified, only this set of algorithms may be used to sign the JWT.
|
||||
//
|
||||
// Since many providers only support RS256, SupportedSigningAlgs defaults to this value.
|
||||
@@ -49,8 +49,6 @@ type Config struct {
|
||||
SkipClientIDCheck bool
|
||||
// If true, token expiry is not checked.
|
||||
SkipExpiryCheck bool
|
||||
// If true, nonce claim is not checked. Must be true if ClaimNonce field is empty.
|
||||
SkipNonceCheck bool
|
||||
|
||||
// Time function to check Token expiry. Defaults to time.Now
|
||||
Now func() time.Time
|
||||
@@ -65,7 +63,7 @@ func (p *Provider) Verifier(config *Config) *IDTokenVerifier {
|
||||
return newVerifier(p.remoteKeySet, config, p.issuer)
|
||||
}
|
||||
|
||||
func newVerifier(keySet *remoteKeySet, config *Config, issuer string) *IDTokenVerifier {
|
||||
func newVerifier(keySet keySet, config *Config, issuer string) *IDTokenVerifier {
|
||||
// If SupportedSigningAlgs is empty defaults to only support RS256.
|
||||
if len(config.SupportedSigningAlgs) == 0 {
|
||||
config.SupportedSigningAlgs = []string{RS256}
|
||||
@@ -102,6 +100,8 @@ func contains(sli []string, ele string) bool {
|
||||
// Verify parses a raw ID Token, verifies it's been signed by the provider, preforms
|
||||
// any additional checks depending on the Config, and returns the payload.
|
||||
//
|
||||
// Verify does NOT do nonce validation, which is the callers responsibility.
|
||||
//
|
||||
// See: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
|
||||
//
|
||||
// oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
|
||||
@@ -181,37 +181,22 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
|
||||
}
|
||||
}
|
||||
|
||||
// If a set of required algorithms has been provided, ensure that the signatures use those.
|
||||
var keyIDs, gotAlgs []string
|
||||
for _, sig := range jws.Signatures {
|
||||
if len(v.config.SupportedSigningAlgs) == 0 || contains(v.config.SupportedSigningAlgs, sig.Header.Algorithm) {
|
||||
keyIDs = append(keyIDs, sig.Header.KeyID)
|
||||
} else {
|
||||
gotAlgs = append(gotAlgs, sig.Header.Algorithm)
|
||||
}
|
||||
}
|
||||
if len(keyIDs) == 0 {
|
||||
return nil, fmt.Errorf("oidc: no signatures use a supported algorithm, expected %q got %q", v.config.SupportedSigningAlgs, gotAlgs)
|
||||
switch len(jws.Signatures) {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("oidc: id token not signed")
|
||||
case 1:
|
||||
default:
|
||||
return nil, fmt.Errorf("oidc: multiple signatures on id token not supported")
|
||||
}
|
||||
|
||||
// Get keys from the remote key set. This may trigger a re-sync.
|
||||
keys, err := v.keySet.keysWithID(ctx, keyIDs)
|
||||
sig := jws.Signatures[0]
|
||||
if len(v.config.SupportedSigningAlgs) != 0 && !contains(v.config.SupportedSigningAlgs, sig.Header.Algorithm) {
|
||||
return nil, fmt.Errorf("oidc: id token signed with unsupported algorithm, expected %q got %q", v.config.SupportedSigningAlgs, sig.Header.Algorithm)
|
||||
}
|
||||
|
||||
gotPayload, err := v.keySet.verify(ctx, jws)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oidc: get keys for id token: %v", err)
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return nil, fmt.Errorf("oidc: no keys match signature ID(s) %q", keyIDs)
|
||||
}
|
||||
|
||||
// Try to use a key to validate the signature.
|
||||
var gotPayload []byte
|
||||
for _, key := range keys {
|
||||
if p, err := jws.Verify(&key); err == nil {
|
||||
gotPayload = p
|
||||
}
|
||||
}
|
||||
if len(gotPayload) == 0 {
|
||||
return nil, fmt.Errorf("oidc: failed to verify id token")
|
||||
return nil, fmt.Errorf("failed to verify signature: %v", err)
|
||||
}
|
||||
|
||||
// Ensure that the payload returned by the square actually matches the payload parsed earlier.
|
||||
@@ -219,19 +204,6 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
|
||||
return nil, errors.New("oidc: internal error, payload parsed did not match previous payload")
|
||||
}
|
||||
|
||||
// Check the nonce after we've verified the token. We don't want to allow unverified
|
||||
// payloads to trigger a nonce lookup.
|
||||
// If SkipNonceCheck is not set ClaimNonce cannot be Nil.
|
||||
if !v.config.SkipNonceCheck && t.Nonce != "" {
|
||||
if v.config.ClaimNonce != nil {
|
||||
if err := v.config.ClaimNonce(t.Nonce); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("oidc: Invalid configuration. ClaimNonce must be provided or SkipNonceCheck must be set.")
|
||||
}
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
||||
274
vendor/github.com/coreos/go-oidc/verify_test.go
generated
vendored
274
vendor/github.com/coreos/go-oidc/verify_test.go
generated
vendored
@@ -1,311 +1,229 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"context"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
type testVerifier struct {
|
||||
jwk jose.JSONWebKey
|
||||
}
|
||||
|
||||
func (t *testVerifier) verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) {
|
||||
return jws.Verify(&t.jwk)
|
||||
}
|
||||
|
||||
func TestVerify(t *testing.T) {
|
||||
tests := []verificationTest{
|
||||
{
|
||||
name: "good token",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "good token",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "invalid issuer",
|
||||
idToken: idToken{
|
||||
Issuer: "foo",
|
||||
},
|
||||
name: "invalid issuer",
|
||||
issuer: "https://bar",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "google accounts without scheme",
|
||||
issuer: "https://accounts.google.com",
|
||||
idToken: idToken{
|
||||
Issuer: "accounts.google.com",
|
||||
},
|
||||
name: "invalid sig",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
verificationKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "expired token",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Expiry: jsonTime(time.Now().Add(-time.Hour)),
|
||||
},
|
||||
name: "google accounts without scheme",
|
||||
issuer: "https://accounts.google.com",
|
||||
idToken: `{"iss":"accounts.google.com"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "expired token",
|
||||
idToken: `{"iss":"https://foo","exp":` + strconv.FormatInt(time.Now().Add(-time.Hour).Unix(), 10) + `}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
},
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid signature",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "unexpired token",
|
||||
idToken: `{"iss":"https://foo","exp":` + strconv.FormatInt(time.Now().Add(time.Hour).Unix(), 10) + `}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_1},
|
||||
wantErr: true,
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "expiry as float",
|
||||
idToken: `{"iss":"https://foo","exp":` +
|
||||
strconv.FormatFloat(float64(time.Now().Add(time.Hour).Unix()), 'E', -1, 64) +
|
||||
`}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test.run(t)
|
||||
t.Run(test.name, test.run)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyAudience(t *testing.T) {
|
||||
tests := []verificationTest{
|
||||
{
|
||||
name: "good audience",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Audience: []string{"client1"},
|
||||
},
|
||||
name: "good audience",
|
||||
idToken: `{"iss":"https://foo","aud":"client1"}`,
|
||||
config: Config{
|
||||
ClientID: "client1",
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "mismatched audience",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Audience: []string{"client2"},
|
||||
},
|
||||
name: "mismatched audience",
|
||||
idToken: `{"iss":"https://foo","aud":"client2"}`,
|
||||
config: Config{
|
||||
ClientID: "client1",
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "multiple audiences, one matches",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Audience: []string{"client2", "client1"},
|
||||
},
|
||||
name: "multiple audiences, one matches",
|
||||
idToken: `{"iss":"https://foo","aud":["client1","client2"]}`,
|
||||
config: Config{
|
||||
ClientID: "client1",
|
||||
SkipNonceCheck: true,
|
||||
ClientID: "client2",
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test.run(t)
|
||||
t.Run(test.name, test.run)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifySigningAlg(t *testing.T) {
|
||||
tests := []verificationTest{
|
||||
{
|
||||
name: "default signing alg",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "default signing alg",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
signAlg: RS256, // By default we only support RS256.
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "bad signing alg",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "bad signing alg",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
signAlg: RS512,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newECDSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "ecdsa signing",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "ecdsa signing",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SupportedSigningAlgs: []string{ES384},
|
||||
SupportedSigningAlgs: []string{ES256},
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signAlg: ES384,
|
||||
signKey: testKeyECDSA_384_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyECDSA_384_0},
|
||||
signKey: newECDSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "one of many supported",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "one of many supported",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
SupportedSigningAlgs: []string{RS256, ES384},
|
||||
SupportedSigningAlgs: []string{RS256, ES256},
|
||||
},
|
||||
signAlg: ES384,
|
||||
signKey: testKeyECDSA_384_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyECDSA_384_0},
|
||||
signKey: newECDSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "not in requiredAlgs",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "not in requiredAlgs",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SupportedSigningAlgs: []string{RS256, ES512},
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signAlg: ES384,
|
||||
signKey: testKeyECDSA_384_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyECDSA_384_0},
|
||||
signKey: newECDSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test.run(t)
|
||||
t.Run(test.name, test.run)
|
||||
}
|
||||
}
|
||||
|
||||
type verificationTest struct {
|
||||
// Name of the subtest.
|
||||
name string
|
||||
|
||||
// if not provided defaults to "https://foo"
|
||||
// If not provided defaults to "https://foo"
|
||||
issuer string
|
||||
|
||||
// ID token claims and a signing key to create the JWT.
|
||||
idToken idToken
|
||||
signKey jose.JSONWebKey
|
||||
// If supplied use this signing algorithm. If not, guess
|
||||
// from the signingKey.
|
||||
signAlg string
|
||||
// JWT payload (just the claims).
|
||||
idToken string
|
||||
|
||||
// Key to sign the ID Token with.
|
||||
signKey *signingKey
|
||||
// If not provided defaults to signKey. Only useful when
|
||||
// testing invalid signatures.
|
||||
verificationKey *signingKey
|
||||
|
||||
config Config
|
||||
pubKeys []jose.JSONWebKey
|
||||
|
||||
wantErr bool
|
||||
}
|
||||
|
||||
func algForKey(t *testing.T, k jose.JSONWebKey) string {
|
||||
switch key := k.Key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return RS256
|
||||
case *ecdsa.PrivateKey:
|
||||
name := key.PublicKey.Params().Name
|
||||
switch name {
|
||||
case elliptic.P256().Params().Name:
|
||||
return ES256
|
||||
case elliptic.P384().Params().Name:
|
||||
return ES384
|
||||
case elliptic.P521().Params().Name:
|
||||
return ES512
|
||||
}
|
||||
t.Fatalf("unsupported ecdsa curve: %s", name)
|
||||
default:
|
||||
t.Fatalf("unsupported key type %T", key)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v verificationTest) run(t *testing.T) {
|
||||
payload, err := json.Marshal(v.idToken)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
signingAlg := v.signAlg
|
||||
if signingAlg == "" {
|
||||
signingAlg = algForKey(t, v.signKey)
|
||||
}
|
||||
|
||||
signer, err := jose.NewSigner(jose.SigningKey{
|
||||
Algorithm: jose.SignatureAlgorithm(signingAlg),
|
||||
Key: &v.signKey,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
jws, err := signer.Sign(payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
token, err := jws.CompactSerialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t0 := time.Now()
|
||||
now := func() time.Time { return t0 }
|
||||
token := v.signKey.sign(t, []byte(v.idToken))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
server := httptest.NewServer(newKeyServer(v.pubKeys...))
|
||||
defer server.Close()
|
||||
|
||||
issuer := "https://foo"
|
||||
if v.issuer != "" {
|
||||
issuer = v.issuer
|
||||
}
|
||||
verifier := newVerifier(newRemoteKeySet(ctx, server.URL, now), &v.config, issuer)
|
||||
var ks keySet
|
||||
if v.verificationKey == nil {
|
||||
ks = &testVerifier{v.signKey.jwk()}
|
||||
} else {
|
||||
ks = &testVerifier{v.verificationKey.jwk()}
|
||||
}
|
||||
verifier := newVerifier(ks, &v.config, issuer)
|
||||
|
||||
if _, err := verifier.Verify(ctx, token); err != nil {
|
||||
if !v.wantErr {
|
||||
|
||||
Reference in New Issue
Block a user