mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 23:09:58 +00:00
TUN-7586: Upgrade go-jose/go-jose/v3 and core-os/go-oidc/v3
Removes usages of gopkg.in/square/go-jose.v2 and gopkg.in/coreos/go-oidc.v2 packages.
This commit is contained in:
1
vendor/github.com/coreos/go-oidc/v3/oidc/jose.go
generated
vendored
1
vendor/github.com/coreos/go-oidc/v3/oidc/jose.go
generated
vendored
@@ -13,4 +13,5 @@ const (
|
||||
PS256 = "PS256" // RSASSA-PSS using SHA256 and MGF1-SHA256
|
||||
PS384 = "PS384" // RSASSA-PSS using SHA384 and MGF1-SHA384
|
||||
PS512 = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512
|
||||
EdDSA = "EdDSA" // Ed25519 using SHA-512
|
||||
)
|
||||
|
6
vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go
generated
vendored
6
vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go
generated
vendored
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
)
|
||||
|
||||
// StaticKeySet is a verifier that validates JWT against a static set of public keys.
|
||||
@@ -32,6 +33,7 @@ func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte,
|
||||
switch pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
case *ecdsa.PublicKey:
|
||||
case ed25519.PublicKey:
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid public key type provided: %T", pub)
|
||||
}
|
||||
@@ -60,7 +62,7 @@ func newRemoteKeySet(ctx context.Context, jwksURL string, now func() time.Time)
|
||||
if now == nil {
|
||||
now = time.Now
|
||||
}
|
||||
return &RemoteKeySet{jwksURL: jwksURL, ctx: cloneContext(ctx), now: now}
|
||||
return &RemoteKeySet{jwksURL: jwksURL, ctx: ctx, now: now}
|
||||
}
|
||||
|
||||
// RemoteKeySet is a KeySet implementation that validates JSON web tokens against
|
||||
|
133
vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go
generated
vendored
133
vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go
generated
vendored
@@ -14,6 +14,7 @@ import (
|
||||
"mime"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@@ -48,39 +49,34 @@ var issuerURLKey contextKey
|
||||
// This method sets the same context key used by the golang.org/x/oauth2 package,
|
||||
// so the returned context works for that package too.
|
||||
//
|
||||
// myClient := &http.Client{}
|
||||
// ctx := oidc.ClientContext(parentContext, myClient)
|
||||
//
|
||||
// // This will use the custom client
|
||||
// provider, err := oidc.NewProvider(ctx, "https://accounts.example.com")
|
||||
// myClient := &http.Client{}
|
||||
// ctx := oidc.ClientContext(parentContext, myClient)
|
||||
//
|
||||
// // This will use the custom client
|
||||
// provider, err := oidc.NewProvider(ctx, "https://accounts.example.com")
|
||||
func ClientContext(ctx context.Context, client *http.Client) context.Context {
|
||||
return context.WithValue(ctx, oauth2.HTTPClient, client)
|
||||
}
|
||||
|
||||
// cloneContext copies a context's bag-of-values into a new context that isn't
|
||||
// associated with its cancellation. This is used to initialize remote keys sets
|
||||
// which run in the background and aren't associated with the initial context.
|
||||
func cloneContext(ctx context.Context) context.Context {
|
||||
cp := context.Background()
|
||||
func getClient(ctx context.Context) *http.Client {
|
||||
if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok {
|
||||
cp = ClientContext(cp, c)
|
||||
return c
|
||||
}
|
||||
return cp
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsecureIssuerURLContext allows discovery to work when the issuer_url reported
|
||||
// by upstream is mismatched with the discovery URL. This is meant for integration
|
||||
// with off-spec providers such as Azure.
|
||||
//
|
||||
// discoveryBaseURL := "https://login.microsoftonline.com/organizations/v2.0"
|
||||
// issuerURL := "https://login.microsoftonline.com/my-tenantid/v2.0"
|
||||
// discoveryBaseURL := "https://login.microsoftonline.com/organizations/v2.0"
|
||||
// issuerURL := "https://login.microsoftonline.com/my-tenantid/v2.0"
|
||||
//
|
||||
// ctx := oidc.InsecureIssuerURLContext(parentContext, issuerURL)
|
||||
// ctx := oidc.InsecureIssuerURLContext(parentContext, issuerURL)
|
||||
//
|
||||
// // Provider will be discovered with the discoveryBaseURL, but use issuerURL
|
||||
// // for future issuer validation.
|
||||
// provider, err := oidc.NewProvider(ctx, discoveryBaseURL)
|
||||
// // Provider will be discovered with the discoveryBaseURL, but use issuerURL
|
||||
// // for future issuer validation.
|
||||
// provider, err := oidc.NewProvider(ctx, discoveryBaseURL)
|
||||
//
|
||||
// This is insecure because validating the correct issuer is critical for multi-tenant
|
||||
// proivders. Any overrides here MUST be carefully reviewed.
|
||||
@@ -90,7 +86,7 @@ func InsecureIssuerURLContext(ctx context.Context, issuerURL string) context.Con
|
||||
|
||||
func doRequest(ctx context.Context, req *http.Request) (*http.Response, error) {
|
||||
client := http.DefaultClient
|
||||
if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok {
|
||||
if c := getClient(ctx); c != nil {
|
||||
client = c
|
||||
}
|
||||
return client.Do(req.WithContext(ctx))
|
||||
@@ -102,12 +98,33 @@ type Provider struct {
|
||||
authURL string
|
||||
tokenURL string
|
||||
userInfoURL string
|
||||
jwksURL string
|
||||
algorithms []string
|
||||
|
||||
// Raw claims returned by the server.
|
||||
rawClaims []byte
|
||||
|
||||
remoteKeySet KeySet
|
||||
// Guards all of the following fields.
|
||||
mu sync.Mutex
|
||||
// HTTP client specified from the initial NewProvider request. This is used
|
||||
// when creating the common key set.
|
||||
client *http.Client
|
||||
// A key set that uses context.Background() and is shared between all code paths
|
||||
// that don't have a convinent way of supplying a unique context.
|
||||
commonRemoteKeySet KeySet
|
||||
}
|
||||
|
||||
func (p *Provider) remoteKeySet() KeySet {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
if p.commonRemoteKeySet == nil {
|
||||
ctx := context.Background()
|
||||
if p.client != nil {
|
||||
ctx = ClientContext(ctx, p.client)
|
||||
}
|
||||
p.commonRemoteKeySet = NewRemoteKeySet(ctx, p.jwksURL)
|
||||
}
|
||||
return p.commonRemoteKeySet
|
||||
}
|
||||
|
||||
type providerJSON struct {
|
||||
@@ -132,6 +149,7 @@ var supportedAlgorithms = map[string]bool{
|
||||
PS256: true,
|
||||
PS384: true,
|
||||
PS512: true,
|
||||
EdDSA: true,
|
||||
}
|
||||
|
||||
// ProviderConfig allows creating providers when discovery isn't supported. It's
|
||||
@@ -167,12 +185,13 @@ type ProviderConfig struct {
|
||||
// through discovery.
|
||||
func (p *ProviderConfig) NewProvider(ctx context.Context) *Provider {
|
||||
return &Provider{
|
||||
issuer: p.IssuerURL,
|
||||
authURL: p.AuthURL,
|
||||
tokenURL: p.TokenURL,
|
||||
userInfoURL: p.UserInfoURL,
|
||||
algorithms: p.Algorithms,
|
||||
remoteKeySet: NewRemoteKeySet(cloneContext(ctx), p.JWKSURL),
|
||||
issuer: p.IssuerURL,
|
||||
authURL: p.AuthURL,
|
||||
tokenURL: p.TokenURL,
|
||||
userInfoURL: p.UserInfoURL,
|
||||
jwksURL: p.JWKSURL,
|
||||
algorithms: p.Algorithms,
|
||||
client: getClient(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,26 +240,27 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
|
||||
}
|
||||
}
|
||||
return &Provider{
|
||||
issuer: issuerURL,
|
||||
authURL: p.AuthURL,
|
||||
tokenURL: p.TokenURL,
|
||||
userInfoURL: p.UserInfoURL,
|
||||
algorithms: algs,
|
||||
rawClaims: body,
|
||||
remoteKeySet: NewRemoteKeySet(cloneContext(ctx), p.JWKSURL),
|
||||
issuer: issuerURL,
|
||||
authURL: p.AuthURL,
|
||||
tokenURL: p.TokenURL,
|
||||
userInfoURL: p.UserInfoURL,
|
||||
jwksURL: p.JWKSURL,
|
||||
algorithms: algs,
|
||||
rawClaims: body,
|
||||
client: getClient(ctx),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Claims unmarshals raw fields returned by the server during discovery.
|
||||
//
|
||||
// var claims struct {
|
||||
// ScopesSupported []string `json:"scopes_supported"`
|
||||
// ClaimsSupported []string `json:"claims_supported"`
|
||||
// }
|
||||
// var claims struct {
|
||||
// ScopesSupported []string `json:"scopes_supported"`
|
||||
// ClaimsSupported []string `json:"claims_supported"`
|
||||
// }
|
||||
//
|
||||
// if err := provider.Claims(&claims); err != nil {
|
||||
// // handle unmarshaling error
|
||||
// }
|
||||
// if err := provider.Claims(&claims); err != nil {
|
||||
// // handle unmarshaling error
|
||||
// }
|
||||
//
|
||||
// For a list of fields defined by the OpenID Connect spec see:
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
@@ -256,6 +276,12 @@ func (p *Provider) Endpoint() oauth2.Endpoint {
|
||||
return oauth2.Endpoint{AuthURL: p.authURL, TokenURL: p.tokenURL}
|
||||
}
|
||||
|
||||
// UserInfoEndpoint returns the OpenID Connect userinfo endpoint for the given
|
||||
// provider.
|
||||
func (p *Provider) UserInfoEndpoint() string {
|
||||
return p.userInfoURL
|
||||
}
|
||||
|
||||
// UserInfo represents the OpenID Connect userinfo claims.
|
||||
type UserInfo struct {
|
||||
Subject string `json:"sub"`
|
||||
@@ -317,7 +343,7 @@ func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource)
|
||||
ct := resp.Header.Get("Content-Type")
|
||||
mediaType, _, parseErr := mime.ParseMediaType(ct)
|
||||
if parseErr == nil && mediaType == "application/jwt" {
|
||||
payload, err := p.remoteKeySet.VerifySignature(ctx, string(body))
|
||||
payload, err := p.remoteKeySet().VerifySignature(ctx, string(body))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oidc: invalid userinfo jwt signature %v", err)
|
||||
}
|
||||
@@ -391,18 +417,17 @@ type IDToken struct {
|
||||
|
||||
// Claims unmarshals the raw JSON payload of the ID Token into a provided struct.
|
||||
//
|
||||
// idToken, err := idTokenVerifier.Verify(rawIDToken)
|
||||
// if err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
// var claims struct {
|
||||
// Email string `json:"email"`
|
||||
// EmailVerified bool `json:"email_verified"`
|
||||
// }
|
||||
// if err := idToken.Claims(&claims); err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// idToken, err := idTokenVerifier.Verify(rawIDToken)
|
||||
// if err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
// var claims struct {
|
||||
// Email string `json:"email"`
|
||||
// EmailVerified bool `json:"email_verified"`
|
||||
// }
|
||||
// if err := idToken.Claims(&claims); err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
func (i *IDToken) Claims(v interface{}) error {
|
||||
if i.claims == nil {
|
||||
return errors.New("oidc: claims not set")
|
||||
@@ -424,7 +449,7 @@ func (i *IDToken) VerifyAccessToken(accessToken string) error {
|
||||
h = sha256.New()
|
||||
case RS384, ES384, PS384:
|
||||
h = sha512.New384()
|
||||
case RS512, ES512, PS512:
|
||||
case RS512, ES512, PS512, EdDSA:
|
||||
h = sha512.New()
|
||||
default:
|
||||
return fmt.Errorf("oidc: unsupported signing algorithm %q", i.sigAlgorithm)
|
||||
|
48
vendor/github.com/coreos/go-oidc/v3/oidc/verify.go
generated
vendored
48
vendor/github.com/coreos/go-oidc/v3/oidc/verify.go
generated
vendored
@@ -12,8 +12,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
"golang.org/x/oauth2"
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -64,14 +64,13 @@ type IDTokenVerifier struct {
|
||||
// This constructor can be used to create a verifier directly using the issuer URL and
|
||||
// JSON Web Key Set URL without using discovery:
|
||||
//
|
||||
// keySet := oidc.NewRemoteKeySet(ctx, "https://www.googleapis.com/oauth2/v3/certs")
|
||||
// verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config)
|
||||
// keySet := oidc.NewRemoteKeySet(ctx, "https://www.googleapis.com/oauth2/v3/certs")
|
||||
// verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config)
|
||||
//
|
||||
// Or a static key set (e.g. for testing):
|
||||
//
|
||||
// keySet := &oidc.StaticKeySet{PublicKeys: []crypto.PublicKey{pub1, pub2}}
|
||||
// verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config)
|
||||
//
|
||||
// keySet := &oidc.StaticKeySet{PublicKeys: []crypto.PublicKey{pub1, pub2}}
|
||||
// verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config)
|
||||
func NewVerifier(issuerURL string, keySet KeySet, config *Config) *IDTokenVerifier {
|
||||
return &IDTokenVerifier{keySet: keySet, config: config, issuer: issuerURL}
|
||||
}
|
||||
@@ -120,8 +119,22 @@ type Config struct {
|
||||
InsecureSkipSignatureCheck bool
|
||||
}
|
||||
|
||||
// VerifierContext returns an IDTokenVerifier that uses the provider's key set to
|
||||
// verify JWTs. As opposed to Verifier, the context is used for all requests to
|
||||
// the upstream JWKs endpoint.
|
||||
func (p *Provider) VerifierContext(ctx context.Context, config *Config) *IDTokenVerifier {
|
||||
return p.newVerifier(NewRemoteKeySet(ctx, p.jwksURL), config)
|
||||
}
|
||||
|
||||
// Verifier returns an IDTokenVerifier that uses the provider's key set to verify JWTs.
|
||||
//
|
||||
// The returned verifier uses a background context for all requests to the upstream
|
||||
// JWKs endpoint. To control that context, use VerifierContext instead.
|
||||
func (p *Provider) Verifier(config *Config) *IDTokenVerifier {
|
||||
return p.newVerifier(p.remoteKeySet(), config)
|
||||
}
|
||||
|
||||
func (p *Provider) newVerifier(keySet KeySet, config *Config) *IDTokenVerifier {
|
||||
if len(config.SupportedSigningAlgs) == 0 && len(p.algorithms) > 0 {
|
||||
// Make a copy so we don't modify the config values.
|
||||
cp := &Config{}
|
||||
@@ -129,7 +142,7 @@ func (p *Provider) Verifier(config *Config) *IDTokenVerifier {
|
||||
cp.SupportedSigningAlgs = p.algorithms
|
||||
config = cp
|
||||
}
|
||||
return NewVerifier(p.issuer, p.remoteKeySet, config)
|
||||
return NewVerifier(p.issuer, keySet, config)
|
||||
}
|
||||
|
||||
func parseJWT(p string) ([]byte, error) {
|
||||
@@ -193,19 +206,18 @@ func resolveDistributedClaim(ctx context.Context, verifier *IDTokenVerifier, src
|
||||
//
|
||||
// See: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
|
||||
//
|
||||
// oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
|
||||
// if err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
// oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
|
||||
// if err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// // Extract the ID Token from oauth2 token.
|
||||
// rawIDToken, ok := oauth2Token.Extra("id_token").(string)
|
||||
// if !ok {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// token, err := verifier.Verify(ctx, rawIDToken)
|
||||
// // Extract the ID Token from oauth2 token.
|
||||
// rawIDToken, ok := oauth2Token.Extra("id_token").(string)
|
||||
// if !ok {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// token, err := verifier.Verify(ctx, rawIDToken)
|
||||
func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDToken, error) {
|
||||
// Throw out tokens with invalid claims before trying to verify the token. This lets
|
||||
// us do cheap checks before possibly re-syncing keys.
|
||||
|
Reference in New Issue
Block a user