Re-enable replay protection for JWK provisioner.

This commit is contained in:
Mariano Cano 2019-03-06 17:00:45 -08:00
parent ab1cca03d7
commit 602a42813c

View file

@ -4,6 +4,7 @@ import (
"crypto/x509" "crypto/x509"
"net/http" "net/http"
"net/url" "net/url"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/authority/provisioner" "github.com/smallstep/certificates/authority/provisioner"
@ -18,7 +19,9 @@ type idUsed struct {
// Claims extends jose.Claims with step attributes. // Claims extends jose.Claims with step attributes.
type Claims struct { type Claims struct {
jose.Claims jose.Claims
SANs []string `json:"sans,omitempty"` SANs []string `json:"sans,omitempty"`
Email string `json:"email,omitempty"`
Nonce string `json:"nonce,omitempty"`
} }
// matchesAudience returns true if A and B share at least one element. // matchesAudience returns true if A and B share at least one element.
@ -50,7 +53,7 @@ func stripPort(rawurl string) string {
// Authorize authorizes a signature request by validating and authenticating // Authorize authorizes a signature request by validating and authenticating
// a OTT that must be sent w/ the request. // a OTT that must be sent w/ the request.
// TODO(mariano): restore protection against reuse // TODO(mariano): protection against reuse for oidc
func (a *Authority) Authorize(ott string) ([]provisioner.SignOption, error) { func (a *Authority) Authorize(ott string) ([]provisioner.SignOption, error) {
var errContext = map[string]interface{}{"ott": ott} var errContext = map[string]interface{}{"ott": ott}
@ -64,7 +67,7 @@ func (a *Authority) Authorize(ott string) ([]provisioner.SignOption, error) {
// Get claims w/out verification. We need to look up the provisioner // Get claims w/out verification. We need to look up the provisioner
// key in order to verify the claims and we need the issuer from the claims // key in order to verify the claims and we need the issuer from the claims
// before we can look up the provisioner. // before we can look up the provisioner.
var claims jose.Claims var claims Claims
if err = token.UnsafeClaimsWithoutVerification(&claims); err != nil { if err = token.UnsafeClaimsWithoutVerification(&claims); err != nil {
return nil, &apiError{err, http.StatusUnauthorized, errContext} return nil, &apiError{err, http.StatusUnauthorized, errContext}
} }
@ -78,20 +81,22 @@ func (a *Authority) Authorize(ott string) ([]provisioner.SignOption, error) {
} }
} }
p, ok := a.provisioners.LoadByToken(token, &claims) p, ok := a.provisioners.LoadByToken(token, &claims.Claims)
if !ok { if !ok {
return nil, &apiError{errors.Errorf("authorize: provisioner not found"), return nil, &apiError{errors.Errorf("authorize: provisioner not found"),
http.StatusUnauthorized, errContext} http.StatusUnauthorized, errContext}
} }
// Store the token to protect against reuse. // Store the token to protect against reuse.
// if _, ok := a.ottMap.LoadOrStore(claims.ID, &idUsed{ if p.GetType() == provisioner.TypeJWK && claims.ID != "" {
// UsedAt: time.Now().Unix(), if _, ok := a.ottMap.LoadOrStore(claims.ID, &idUsed{
// Subject: claims.Subject, UsedAt: time.Now().Unix(),
// }); ok { Subject: claims.Subject,
// return nil, &apiError{errors.Errorf("token already used"), http.StatusUnauthorized, }); ok {
// errContext} return nil, &apiError{errors.Errorf("token already used"), http.StatusUnauthorized,
// } errContext}
}
}
return p.Authorize(ott) return p.Authorize(ott)
} }