From 16edba2de8e266a2fc248df3468b3b527bafd486 Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Fri, 26 Aug 2016 16:35:12 -0700 Subject: [PATCH] vendor: update go-oidc This change updates the github.com/coreos/go-oidc package. Notable changes: - Throw out JWTs with invalid claims early (coreos/go-oidc#97, brougt up in #30457) - Remove the capnslog dependency (coreos/go-oidc#95) - Support for Azure AD oddities (coreos/go-oidc#87) --- Godeps/Godeps.json | 10 ++++---- vendor/github.com/coreos/go-oidc/http/http.go | 11 ++++----- .../coreos/go-oidc/http/middleware.go | 14 ----------- vendor/github.com/coreos/go-oidc/key/key.go | 14 +++++------ .../github.com/coreos/go-oidc/key/rotate.go | 14 ++++------- vendor/github.com/coreos/go-oidc/key/sync.go | 6 ++--- .../coreos/go-oidc/oauth2/oauth2.go | 24 +++++++++---------- .../coreos/go-oidc/oidc/provider.go | 24 ++++++++++--------- .../coreos/go-oidc/oidc/verification.go | 18 +++++++------- 9 files changed, 58 insertions(+), 77 deletions(-) delete mode 100644 vendor/github.com/coreos/go-oidc/http/middleware.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 66144137ac6..5b5733007db 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -607,23 +607,23 @@ }, { "ImportPath": "github.com/coreos/go-oidc/http", - "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" + "Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d" }, { "ImportPath": "github.com/coreos/go-oidc/jose", - "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" + "Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d" }, { "ImportPath": "github.com/coreos/go-oidc/key", - "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" + "Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d" }, { "ImportPath": "github.com/coreos/go-oidc/oauth2", - "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" + "Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d" }, { "ImportPath": "github.com/coreos/go-oidc/oidc", - "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" + "Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d" }, { "ImportPath": "github.com/coreos/go-semver/semver", diff --git a/vendor/github.com/coreos/go-oidc/http/http.go b/vendor/github.com/coreos/go-oidc/http/http.go index f0d051b5f2b..c3f51215133 100644 --- a/vendor/github.com/coreos/go-oidc/http/http.go +++ b/vendor/github.com/coreos/go-oidc/http/http.go @@ -4,18 +4,13 @@ import ( "encoding/base64" "encoding/json" "errors" + "log" "net/http" "net/url" "path" "strconv" "strings" "time" - - "github.com/coreos/pkg/capnslog" -) - -var ( - log = capnslog.NewPackageLogger("github.com/coreos/go-oidc", "http") ) func WriteError(w http.ResponseWriter, code int, msg string) { @@ -26,7 +21,9 @@ func WriteError(w http.ResponseWriter, code int, msg string) { } b, err := json.Marshal(e) if err != nil { - log.Errorf("Failed marshaling %#v to JSON: %v", e, err) + log.Printf("go-oidc: failed to marshal %#v: %v", e, err) + code = http.StatusInternalServerError + b = []byte(`{"error":"server_error"}`) } w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) diff --git a/vendor/github.com/coreos/go-oidc/http/middleware.go b/vendor/github.com/coreos/go-oidc/http/middleware.go deleted file mode 100644 index 270b3bc0854..00000000000 --- a/vendor/github.com/coreos/go-oidc/http/middleware.go +++ /dev/null @@ -1,14 +0,0 @@ -package http - -import ( - "net/http" -) - -type LoggingMiddleware struct { - Next http.Handler -} - -func (l *LoggingMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { - log.Infof("HTTP %s %v", r.Method, r.URL) - l.Next.ServeHTTP(w, r) -} diff --git a/vendor/github.com/coreos/go-oidc/key/key.go b/vendor/github.com/coreos/go-oidc/key/key.go index d0142a9e0e0..208c1fc1492 100644 --- a/vendor/github.com/coreos/go-oidc/key/key.go +++ b/vendor/github.com/coreos/go-oidc/key/key.go @@ -3,9 +3,9 @@ package key import ( "crypto/rand" "crypto/rsa" - "encoding/base64" + "encoding/hex" "encoding/json" - "math/big" + "io" "time" "github.com/coreos/go-oidc/jose" @@ -139,15 +139,15 @@ func GeneratePrivateKey() (*PrivateKey, error) { if err != nil { return nil, err } + keyID := make([]byte, 20) + if _, err := io.ReadFull(rand.Reader, keyID); err != nil { + return nil, err + } k := PrivateKey{ - KeyID: base64BigInt(pk.PublicKey.N), + KeyID: hex.EncodeToString(keyID), PrivateKey: pk, } return &k, nil } - -func base64BigInt(b *big.Int) string { - return base64.URLEncoding.EncodeToString(b.Bytes()) -} diff --git a/vendor/github.com/coreos/go-oidc/key/rotate.go b/vendor/github.com/coreos/go-oidc/key/rotate.go index 9c5508bc1f8..bc6cdfb1bd8 100644 --- a/vendor/github.com/coreos/go-oidc/key/rotate.go +++ b/vendor/github.com/coreos/go-oidc/key/rotate.go @@ -2,16 +2,14 @@ package key import ( "errors" + "log" "time" - "github.com/coreos/pkg/capnslog" ptime "github.com/coreos/pkg/timeutil" "github.com/jonboulle/clockwork" ) var ( - log = capnslog.NewPackageLogger("github.com/coreos/go-oidc", "key") - ErrorPrivateKeysExpired = errors.New("private keys have expired") ) @@ -67,7 +65,6 @@ func (r *PrivateKeyRotator) privateKeySet() (*PrivateKeySet, error) { func (r *PrivateKeyRotator) nextRotation() (time.Duration, error) { pks, err := r.privateKeySet() if err == ErrorNoKeys { - log.Infof("No keys in private key set; must rotate immediately") return 0, nil } if err != nil { @@ -94,17 +91,15 @@ func (r *PrivateKeyRotator) Run() chan struct{} { attempt := func() { k, err := r.generateKey() if err != nil { - log.Errorf("Failed generating signing key: %v", err) + log.Printf("go-oidc: failed generating signing key: %v", err) return } exp := r.expiresAt() if err := rotatePrivateKeys(r.repo, k, r.keep, exp); err != nil { - log.Errorf("Failed key rotation: %v", err) + log.Printf("go-oidc: key rotation failed: %v", err) return } - - log.Infof("Rotated signing keys: id=%s expiresAt=%s", k.ID(), exp) } stop := make(chan struct{}) @@ -118,11 +113,10 @@ func (r *PrivateKeyRotator) Run() chan struct{} { break } sleep = ptime.ExpBackoff(sleep, time.Minute) - log.Errorf("error getting nextRotation, retrying in %v: %v", sleep, err) + log.Printf("go-oidc: error getting nextRotation, retrying in %v: %v", sleep, err) time.Sleep(sleep) } - log.Infof("will rotate keys in %v", nextRotation) select { case <-r.clock.After(nextRotation): attempt() diff --git a/vendor/github.com/coreos/go-oidc/key/sync.go b/vendor/github.com/coreos/go-oidc/key/sync.go index e8d5d03d881..b887f7b5a56 100644 --- a/vendor/github.com/coreos/go-oidc/key/sync.go +++ b/vendor/github.com/coreos/go-oidc/key/sync.go @@ -2,6 +2,7 @@ package key import ( "errors" + "log" "time" "github.com/jonboulle/clockwork" @@ -38,15 +39,14 @@ func (s *KeySetSyncer) Run() chan struct{} { next = timeutil.ExpBackoff(next, time.Minute) } if exp == 0 { - log.Errorf("Synced to already expired key set, retrying in %v: %v", next, err) + log.Printf("Synced to already expired key set, retrying in %v: %v", next, err) } else { - log.Errorf("Failed syncing key set, retrying in %v: %v", next, err) + log.Printf("Failed syncing key set, retrying in %v: %v", next, err) } } else { failing = false next = exp / 2 - log.Infof("Synced key set, checking again in %v", next) } select { diff --git a/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go b/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go index 1c68293a0a8..72d1d6715bf 100644 --- a/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go +++ b/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go @@ -332,16 +332,16 @@ func parseTokenResponse(resp *http.Response) (result TokenResponse, err error) { result.Scope = vals.Get("scope") } else { var r struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - IDToken string `json:"id_token"` - RefreshToken string `json:"refresh_token"` - Scope string `json:"scope"` - State string `json:"state"` - ExpiresIn int `json:"expires_in"` - Expires int `json:"expires"` - Error string `json:"error"` - Desc string `json:"error_description"` + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + IDToken string `json:"id_token"` + RefreshToken string `json:"refresh_token"` + Scope string `json:"scope"` + State string `json:"state"` + ExpiresIn json.Number `json:"expires_in"` // Azure AD returns string + Expires int `json:"expires"` + Error string `json:"error"` + Desc string `json:"error_description"` } if err = json.Unmarshal(body, &r); err != nil { return @@ -355,10 +355,10 @@ func parseTokenResponse(resp *http.Response) (result TokenResponse, err error) { result.IDToken = r.IDToken result.RefreshToken = r.RefreshToken result.Scope = r.Scope - if r.ExpiresIn == 0 { + if expiresIn, err := r.ExpiresIn.Int64(); err != nil { result.Expires = r.Expires } else { - result.Expires = r.ExpiresIn + result.Expires = int(expiresIn) } } return diff --git a/vendor/github.com/coreos/go-oidc/oidc/provider.go b/vendor/github.com/coreos/go-oidc/oidc/provider.go index 1235890c0c2..ca2838440b3 100644 --- a/vendor/github.com/coreos/go-oidc/oidc/provider.go +++ b/vendor/github.com/coreos/go-oidc/oidc/provider.go @@ -4,13 +4,13 @@ import ( "encoding/json" "errors" "fmt" + "log" "net/http" "net/url" "strings" "sync" "time" - "github.com/coreos/pkg/capnslog" "github.com/coreos/pkg/timeutil" "github.com/jonboulle/clockwork" @@ -18,10 +18,6 @@ import ( "github.com/coreos/go-oidc/oauth2" ) -var ( - log = capnslog.NewPackageLogger("github.com/coreos/go-oidc", "http") -) - const ( // Subject Identifier types defined by the OIDC spec. Specifies if the provider // should provide the same sub claim value to all clients (public) or a unique @@ -69,6 +65,8 @@ type ProviderConfig struct { UserInfoEndpoint *url.URL KeysEndpoint *url.URL // Required RegistrationEndpoint *url.URL + EndSessionEndpoint *url.URL + CheckSessionIFrame *url.URL // Servers MAY choose not to advertise some supported scope values even when this // parameter is used, although those defined in OpenID Core SHOULD be listed, if supported. @@ -170,6 +168,8 @@ type encodableProviderConfig struct { UserInfoEndpoint string `json:"userinfo_endpoint,omitempty"` KeysEndpoint string `json:"jwks_uri"` RegistrationEndpoint string `json:"registration_endpoint,omitempty"` + EndSessionEndpoint string `json:"end_session_endpoint,omitempty"` + CheckSessionIFrame string `json:"check_session_iframe,omitempty"` // Use 'omitempty' for all slices as per OIDC spec: // "Claims that return multiple values are represented as JSON arrays. @@ -219,6 +219,8 @@ func (cfg ProviderConfig) toEncodableStruct() encodableProviderConfig { UserInfoEndpoint: uriToString(cfg.UserInfoEndpoint), KeysEndpoint: uriToString(cfg.KeysEndpoint), RegistrationEndpoint: uriToString(cfg.RegistrationEndpoint), + EndSessionEndpoint: uriToString(cfg.EndSessionEndpoint), + CheckSessionIFrame: uriToString(cfg.CheckSessionIFrame), ScopesSupported: cfg.ScopesSupported, ResponseTypesSupported: cfg.ResponseTypesSupported, ResponseModesSupported: cfg.ResponseModesSupported, @@ -260,6 +262,8 @@ func (e encodableProviderConfig) toStruct() (ProviderConfig, error) { UserInfoEndpoint: p.parseURI(e.UserInfoEndpoint, "userinfo_endpoint"), KeysEndpoint: p.parseURI(e.KeysEndpoint, "jwks_uri"), RegistrationEndpoint: p.parseURI(e.RegistrationEndpoint, "registration_endpoint"), + EndSessionEndpoint: p.parseURI(e.EndSessionEndpoint, "end_session_endpoint"), + CheckSessionIFrame: p.parseURI(e.CheckSessionIFrame, "check_session_iframe"), ScopesSupported: e.ScopesSupported, ResponseTypesSupported: e.ResponseTypesSupported, ResponseModesSupported: e.ResponseModesSupported, @@ -364,6 +368,8 @@ func (p ProviderConfig) Valid() error { {p.UserInfoEndpoint, "userinfo_endpoint", false}, {p.KeysEndpoint, "jwks_uri", true}, {p.RegistrationEndpoint, "registration_endpoint", false}, + {p.EndSessionEndpoint, "end_session_endpoint", false}, + {p.CheckSessionIFrame, "check_session_iframe", false}, {p.ServiceDocs, "service_documentation", false}, {p.Policy, "op_policy_uri", false}, {p.TermsOfService, "op_tos_uri", false}, @@ -537,8 +543,6 @@ func (s *ProviderConfigSyncer) sync() (time.Duration, error) { s.initialSyncDone = true } - log.Infof("Updating provider config: config=%#v", cfg) - return nextSyncAfter(cfg.ExpiresAt, s.clock), nil } @@ -561,10 +565,9 @@ func (n *pcsStepNext) step(fn pcsStepFunc) (next pcsStepper) { ttl, err := fn() if err == nil { next = &pcsStepNext{aft: ttl} - log.Debugf("Synced provider config, next attempt in %v", next.after()) } else { next = &pcsStepRetry{aft: time.Second} - log.Errorf("Provider config sync failed, retrying in %v: %v", next.after(), err) + log.Printf("go-oidc: provider config sync falied, retyring in %v: %v", next.after(), err) } return } @@ -581,10 +584,9 @@ func (r *pcsStepRetry) step(fn pcsStepFunc) (next pcsStepper) { ttl, err := fn() if err == nil { next = &pcsStepNext{aft: ttl} - log.Infof("Provider config sync no longer failing") } else { next = &pcsStepRetry{aft: timeutil.ExpBackoff(r.aft, time.Minute)} - log.Errorf("Provider config sync still failing, retrying in %v: %v", next.after(), err) + log.Printf("go-oidc: provider config sync falied, retyring in %v: %v", next.after(), err) } return } diff --git a/vendor/github.com/coreos/go-oidc/oidc/verification.go b/vendor/github.com/coreos/go-oidc/oidc/verification.go index 00241304794..d9c6afa6974 100644 --- a/vendor/github.com/coreos/go-oidc/oidc/verification.go +++ b/vendor/github.com/coreos/go-oidc/oidc/verification.go @@ -161,11 +161,18 @@ func NewJWTVerifier(issuer, clientID string, syncFunc func() error, keysFunc fun } func (v *JWTVerifier) Verify(jwt jose.JWT) error { + // Verify claims before verifying the signature. This is an optimization to throw out + // tokens we know are invalid without undergoing an expensive signature check and + // possibly a re-sync event. + if err := VerifyClaims(jwt, v.issuer, v.clientID); err != nil { + return fmt.Errorf("oidc: JWT claims invalid: %v", err) + } + ok, err := VerifySignature(jwt, v.keysFunc()) - if ok { - goto SignatureVerified - } else if err != nil { + if err != nil { return fmt.Errorf("oidc: JWT signature verification failed: %v", err) + } else if ok { + return nil } if err = v.syncFunc(); err != nil { @@ -179,10 +186,5 @@ func (v *JWTVerifier) Verify(jwt jose.JWT) error { return errors.New("oidc: unable to verify JWT signature: no matching keys") } -SignatureVerified: - if err := VerifyClaims(jwt, v.issuer, v.clientID); err != nil { - return fmt.Errorf("oidc: JWT claims invalid: %v", err) - } - return nil }