Skip to content

Commit

Permalink
oauth2 errors
Browse files Browse the repository at this point in the history
  • Loading branch information
reinkrul committed Oct 3, 2023
1 parent 74ce672 commit a3d6af4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 15 deletions.
2 changes: 2 additions & 0 deletions auth/api/iam/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const (
UnsupportedGrantType ErrorCode = "unsupported_grant_type"
// UnsupportedResponseType is returned when the authorization server does not support obtaining an authorization code using this method.
UnsupportedResponseType ErrorCode = "unsupported_response_type"
// InvalidScope is returned when the requested scope is invalid, unknown, or malformed.
InvalidScope ErrorCode = "invalid_scope"
// ServerError is returned when the Authorization Server encounters an unexpected condition that prevents it from fulfilling the request.
ServerError ErrorCode = "server_error"
)
Expand Down
57 changes: 42 additions & 15 deletions auth/api/iam/s2s_vptoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ func (s Wrapper) handleS2SAccessTokenRequest(ctx context.Context, issuer did.DID
scope := params[scopeParam]
assertionEncoded := params["assertion"]
if submissionEncoded == "" || scope == "" || assertionEncoded == "" {
// TODO: OAuth2 error
return nil, errors.New("missing required parameters")
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "missing required parameters",
}
}

// Unmarshal VP, which can be in URL-encoded JSON or JWT format
Expand All @@ -66,34 +68,49 @@ func (s Wrapper) handleS2SAccessTokenRequest(ctx context.Context, issuer did.DID
// (VP as URL-encoded JSON)
assertionDecoded, err := url.QueryUnescape(assertionEncoded)
if err != nil {
// TODO: OAuth2 error
return nil, fmt.Errorf("assertion parameter is invalid: %w", err)
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "assertion parameter is invalid: invalid query escaping",
InternalError: err,
}
}
var vp vc.VerifiablePresentation
err = json.Unmarshal([]byte(assertionDecoded), &vp)
if err != nil {
// TODO: OAuth2 error
return nil, fmt.Errorf("assertion parameter is invalid: %w", err)
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "assertion parameter is invalid: invalid JSON",
InternalError: err,
}
}

// Unmarshal presentation submission
var submission pe.PresentationSubmission
submissionDecoded, err := url.QueryUnescape(submissionEncoded)
if err != nil {
// TODO: OAuth2 error
return nil, fmt.Errorf("presentation_submission parameter is invalid: %w", err)
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "presentation_submission parameter is invalid: invalid query escaping",
InternalError: err,
}
}
if err = json.Unmarshal([]byte(submissionDecoded), &submission); err != nil {
// TODO: OAuth2 error
return nil, fmt.Errorf("presentation_submission parameter is invalid: %w", err)
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "presentation_submission parameter is invalid: invalid JSON",
InternalError: err,
}
}

// Check signatures and VC issuer trust
issueTime := time.Now()
_, err = s.vcr.Verifier().VerifyVP(vp, true, false, &issueTime)
if err != nil {
// TODO: OAuth2 error
return nil, fmt.Errorf("verifiable presentation verification failed: %w", err)
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "verifiable presentation is invalid",
InternalError: err,
}
}

// Validate the presentation submission:
Expand All @@ -103,7 +120,10 @@ func (s Wrapper) handleS2SAccessTokenRequest(ctx context.Context, issuer did.DID
// This actually creates a new submission.
presentationDefinition := s.auth.PresentationDefinitions().ByScope(scope)
if presentationDefinition == nil {
return nil, fmt.Errorf("unsupported scope for presentation exchange: %s", scope)
return nil, OAuth2Error{
Code: InvalidScope,
Description: fmt.Sprintf("unsupported scope for presentation exchange: %s", scope),
}
}
submissionCredentials, err := submission.Credentials(vp)
if err != nil {
Expand All @@ -112,12 +132,19 @@ func (s Wrapper) handleS2SAccessTokenRequest(ctx context.Context, issuer did.DID
// Match the credentials from the presentation submission with the presentation definition we got through the scope
_, matchedCredentials, err := presentationDefinition.Match(submissionCredentials)
if err != nil {
return nil, fmt.Errorf("presentation_submission parameter is invalid: re-evaluation of the credentials against the presentation definition fails: %w", err)
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "presentation_submission parameter is invalid: re-evaluation of the credentials against the presentation definition fails",
InternalError: err,
}
}
submissionCredentialsJSON, _ := json.Marshal(submissionCredentials)
matchedCredentialsJSON, _ := json.Marshal(matchedCredentials)
if !bytes.Equal(submissionCredentialsJSON, matchedCredentialsJSON) {
return nil, errors.New("presentation_submission parameter is invalid: re-evaluation of the credentials against the presentation definition yields different credentials (bug or attempted hack)")
return nil, OAuth2Error{
Code: InvalidRequest,
Description: "presentation_submission parameter is invalid: re-evaluation of the credentials against the presentation definition yields different credentials (bug or attempted hack)",
}
}

// TODO: Check that the returned credentials fulfill the presentation definition of the scope.
Expand Down

0 comments on commit a3d6af4

Please sign in to comment.