Skip to content

Commit

Permalink
move ValidateWrappingToken back to wrappingVerificationFunc
Browse files Browse the repository at this point in the history
  • Loading branch information
calvn committed Jul 4, 2019
1 parent 37556fb commit 732d3b5
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 48 deletions.
19 changes: 19 additions & 0 deletions http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,25 @@ func WrapForwardedForHandler(h http.Handler, authorizedAddrs []*sockaddr.SockAdd
})
}

// A lookup on a token that is about to expire returns nil, which means by the
// time we can validate a wrapping token lookup will return nil since it will
// be revoked after the call. So we have to do the validation here.
func wrappingVerificationFunc(ctx context.Context, core *vault.Core, req *logical.Request) error {
if req == nil {
return fmt.Errorf("invalid request")
}

valid, err := core.ValidateWrappingToken(ctx, req)
if err != nil {
return errwrap.Wrapf("error validating wrapping token: {{err}}", err)
}
if !valid {
return fmt.Errorf("wrapping token is not valid or does not exist")
}

return nil
}

// stripPrefix is a helper to strip a prefix from the path. It will
// return false from the second return value if it the prefix doesn't exist.
func stripPrefix(prefix, path string) (string, bool) {
Expand Down
7 changes: 7 additions & 0 deletions http/logical.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ func handleLogicalInternal(core *vault.Core, injectDataIntoTopLevel bool) http.H
// Route the token wrapping request to its respective sys NS
case "sys/wrapping/lookup", "sys/wrapping/rewrap", "sys/wrapping/unwrap":
r = r.WithContext(newCtx)
if err := wrappingVerificationFunc(r.Context(), core, req); err != nil {
if errwrap.Contains(err, logical.ErrPermissionDenied.Error()) {
respondError(w, http.StatusForbidden, err)
} else {
respondError(w, http.StatusBadRequest, err)
}
}

// The -self paths have no meaning outside of the token NS, so
// requests for these paths always go to the token NS
Expand Down
30 changes: 0 additions & 30 deletions vault/request_handling.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,21 +584,6 @@ func (c *Core) handleRequest(ctx context.Context, req *logical.Request) (retResp
return
}

// If this is a wrapping request that contains a wrapping token, check for
// token validity. We perform this before c.checkToken since wrapping token
// validation performs a token store lookup, and can potentially modify
// logical.Request's token-related fields.
switch req.Path {
case "sys/wrapping/rewrap", "sys/wrapping/unwrap":
valid, wtAuth, err := c.validateWrappingToken(ctx, req, nonHMACReqDataKeys)
if err != nil {
return nil, wtAuth, errwrap.Wrapf("error validating wrapping token: {{err}}", err)
}
if !valid {
return logical.ErrorResponse(consts.ErrInvalidWrappingToken.Error()), wtAuth, logical.ErrInvalidRequest
}
}

// Validate the token
auth, te, ctErr := c.checkToken(ctx, req, false)
if ctErr == logical.ErrPerfStandbyPleaseForward {
Expand Down Expand Up @@ -931,21 +916,6 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re
}
}

// If this is a wrapping token lookup, validate the token and produce an
// audit log. We perform this before c.checkToken since wrapping token
// validation performs a token store lookup, and can potentially modify
// logical.Request's token-related fields.
switch req.Path {
case "sys/wrapping/lookup":
valid, wtAuth, err := c.validateWrappingToken(ctx, req, nonHMACReqDataKeys)
if err != nil {
return nil, wtAuth, errwrap.Wrapf("error validating wrapping token: {{err}}", err)
}
if !valid {
return logical.ErrorResponse(consts.ErrInvalidWrappingToken.Error()), wtAuth, logical.ErrInvalidRequest
}
}

req.Unauthenticated = true

// Do an unauth check. This will cause EGP policies to be checked
Expand Down
46 changes: 28 additions & 18 deletions vault/wrapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,14 +312,24 @@ DONELISTHANDLING:
// validateWrappingToken checks whether a token is a wrapping token. The passed
// in logical request will be updated if the wrapping token was provided within
// a JWT token.
func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request, nonHMACReqDataKeys []string) (valid bool, auth *logical.Auth, err error) {
func (c *Core) ValidateWrappingToken(ctx context.Context, req *logical.Request) (valid bool, err error) {
defer func() {
// Perform audit logging before returning if there's an issue with checking
// the wrapping token
if err != nil || !valid {
// Get non-HMAC'ed request data keys
var nonHMACReqDataKeys []string
entry := c.router.MatchingMountEntry(ctx, req.Path)
if entry != nil {
// Get and set ignored HMAC'd value.
if rawVals, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok {
nonHMACReqDataKeys = rawVals.([]string)
}
}

// We log the Auth object like so here since the wrapping token can
// come from the header, which gets set as the ClientToken
auth = &logical.Auth{
auth := &logical.Auth{
ClientToken: req.ClientToken,
Accessor: req.ClientTokenAccessor,
}
Expand All @@ -336,7 +346,7 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request,
}()

if req == nil {
return false, nil, fmt.Errorf("invalid request")
return false, fmt.Errorf("invalid request")
}

var token string
Expand All @@ -347,9 +357,9 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request,
if req.Data != nil && req.Data["token"] != nil {
thirdParty = true
if tokenStr, ok := req.Data["token"].(string); !ok {
return false, nil, fmt.Errorf("could not decode token in request body")
return false, fmt.Errorf("could not decode token in request body")
} else if tokenStr == "" {
return false, nil, fmt.Errorf("empty token in request body")
return false, fmt.Errorf("empty token in request body")
} else {
token = tokenStr
}
Expand All @@ -367,23 +377,23 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request,
// Implement the jose library way
parsedJWT, err := squarejwt.ParseSigned(token)
if err != nil {
return false, nil, errwrap.Wrapf("wrapping token could not be parsed: {{err}}", err)
return false, errwrap.Wrapf("wrapping token could not be parsed: {{err}}", err)
}
var claims squarejwt.Claims
var allClaims = make(map[string]interface{})
if err = parsedJWT.Claims(&c.wrappingJWTKey.PublicKey, &claims, &allClaims); err != nil {
return false, nil, errwrap.Wrapf("wrapping token signature could not be validated: {{err}}", err)
return false, errwrap.Wrapf("wrapping token signature could not be validated: {{err}}", err)
}
typeClaimRaw, ok := allClaims["type"]
if !ok {
return false, nil, errors.New("could not validate type claim")
return false, errors.New("could not validate type claim")
}
typeClaim, ok := typeClaimRaw.(string)
if !ok {
return false, nil, errors.New("could not parse type claim")
return false, errors.New("could not parse type claim")
}
if typeClaim != "wrapping" {
return false, nil, errors.New("unexpected type claim")
return false, errors.New("unexpected type claim")
}
if !thirdParty {
req.ClientToken = claims.ID
Expand All @@ -395,33 +405,33 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request,
}

if token == "" {
return false, nil, fmt.Errorf("token is empty")
return false, fmt.Errorf("token is empty")
}

if c.Sealed() {
return false, nil, consts.ErrSealed
return false, consts.ErrSealed
}

c.stateLock.RLock()
defer c.stateLock.RUnlock()
if c.standby && !c.perfStandby {
return false, nil, consts.ErrStandby
return false, consts.ErrStandby
}

te, err := c.tokenStore.Lookup(ctx, token)
if err != nil {
return false, nil, err
return false, err
}
if te == nil {
return false, nil, nil
return false, nil
}

if len(te.Policies) != 1 {
return false, nil, nil
return false, nil
}

if te.Policies[0] != responseWrappingPolicyName && te.Policies[0] != controlGroupPolicyName {
return false, nil, nil
return false, nil
}

if !thirdParty {
Expand All @@ -430,5 +440,5 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request,
req.SetTokenEntry(te)
}

return true, nil, nil
return true, nil
}

0 comments on commit 732d3b5

Please sign in to comment.