forked from trustbloc/vcs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: [OIDC4VP] Request Attestation VC by Verifier
Signed-off-by: Mykhailo Sizov <[email protected]>
- Loading branch information
1 parent
af4b18c
commit f62c5fa
Showing
25 changed files
with
897 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# | ||
# Copyright Avast Software. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
|
||
ARG GO_VER | ||
ARG GO_IMAGE | ||
ARG ALPINE_VER | ||
|
||
FROM ${GO_IMAGE}:${GO_VER}-alpine${ALPINE_VER} as builder | ||
|
||
RUN apk update && apk add git && apk add ca-certificates | ||
RUN adduser -D -g '' appuser | ||
COPY . $GOPATH/src/github.com/trustbloc/vcs/test/bdd/trustregistry/ | ||
WORKDIR $GOPATH/src/github.com/trustbloc/vcs/test/bdd/trustregistry/ | ||
ARG GO_PROXY | ||
RUN GOPROXY=${GO_PROXY} CGO_ENABLED=0 go build -o /usr/bin/mock-trustregistry | ||
|
||
FROM scratch | ||
|
||
LABEL org.opencontainers.image.source https://github.com/trustbloc/vcs/test/bdd/trustregistry | ||
|
||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ | ||
COPY --from=builder /etc/passwd /etc/passwd | ||
COPY --from=builder /usr/bin/mock-trustregistry /usr/bin/mock-trustregistry | ||
USER appuser | ||
|
||
ENTRYPOINT ["/usr/bin/mock-trustregistry"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
Copyright Gen Digital Inc. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package trustregistry | ||
|
||
type VerifierValidationConfig struct { | ||
VerifierDID string `json:"verifier_did"` | ||
Metadata []*CredentialMetadata `json:"metadata"` | ||
} | ||
|
||
type PresentationValidationConfig struct { | ||
PolicyID string `json:"policy_id"` | ||
AttestationVC interface{} `json:"attestation_vc"` | ||
Metadata []*CredentialMetadata `json:"metadata"` | ||
} | ||
|
||
type CredentialMetadata struct { | ||
CredentialID string `json:"credential_id"` | ||
Types []string `json:"types"` | ||
Issuer string `json:"issuer"` | ||
Issued string `json:"issued"` | ||
Expired string `json:"expired"` | ||
} | ||
|
||
type Response struct { | ||
Allowed bool `json:"allowed"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
Copyright Gen Digital Inc. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package trustregistry | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/samber/lo" | ||
|
||
"github.com/trustbloc/logutil-go/pkg/log" | ||
"github.com/trustbloc/vc-go/verifiable" | ||
) | ||
|
||
var ( | ||
ErrInteractionRestricted = errors.New("interaction restricted") | ||
logger = log.New("trustregistry") | ||
) | ||
|
||
const ( | ||
walletAttestationVCType = "WalletAttestationCredential" | ||
) | ||
|
||
type Service struct { | ||
url string | ||
httpClient *http.Client | ||
} | ||
|
||
type Config struct { | ||
TrustRegistryURL string | ||
HTTPClient *http.Client | ||
} | ||
|
||
func New(conf *Config) *Service { | ||
return &Service{ | ||
url: conf.TrustRegistryURL, | ||
httpClient: conf.HTTPClient, | ||
} | ||
} | ||
|
||
func (s *Service) ValidateVerifier(verifierDID string, presentationCredentials []*verifiable.Credential) error { | ||
logger.Debug("ValidateVerifier begin") | ||
verifierValidationConfig := &VerifierValidationConfig{ | ||
VerifierDID: verifierDID, | ||
Metadata: make([]*CredentialMetadata, len(presentationCredentials)), | ||
} | ||
|
||
for i, credential := range presentationCredentials { | ||
content := credential.Contents() | ||
|
||
verifierValidationConfig.Metadata[i] = s.getCredentialMetadata(content) | ||
} | ||
|
||
req, err := json.Marshal(verifierValidationConfig) | ||
if err != nil { | ||
return fmt.Errorf("encode verifier config: %w", err) | ||
} | ||
|
||
responseDecoded, err := s.doRequest(req) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !responseDecoded.Allowed { | ||
return ErrInteractionRestricted | ||
} | ||
|
||
logger.Debug("ValidateVerifier succeed") | ||
|
||
return nil | ||
} | ||
|
||
func (s *Service) ValidatePresentation(policyID string, presentationCredentials []*verifiable.Credential) error { | ||
logger.Debug("ValidatePresentation begin") | ||
|
||
presentationValidationConfig := &PresentationValidationConfig{ | ||
PolicyID: policyID, | ||
Metadata: make([]*CredentialMetadata, len(presentationCredentials)), | ||
} | ||
|
||
for i, credential := range presentationCredentials { | ||
content := credential.Contents() | ||
|
||
if lo.Contains(content.Types, walletAttestationVCType) { | ||
attestationVC, err := credential.ToUniversalForm() | ||
if err == nil { | ||
presentationValidationConfig.AttestationVC = attestationVC | ||
} | ||
} | ||
|
||
presentationValidationConfig.Metadata[i] = s.getCredentialMetadata(content) | ||
} | ||
|
||
req, err := json.Marshal(presentationValidationConfig) | ||
if err != nil { | ||
return fmt.Errorf("encode presentation config: %w", err) | ||
} | ||
|
||
responseDecoded, err := s.doRequest(req) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !responseDecoded.Allowed { | ||
return ErrInteractionRestricted | ||
} | ||
|
||
logger.Debug("ValidatePresentation succeed") | ||
|
||
return nil | ||
} | ||
|
||
func (s *Service) doRequest(req []byte) (*Response, error) { | ||
resp, err := s.httpClient.Post(s.url, "application/json", bytes.NewReader(req)) //nolint:noctx | ||
if err != nil { | ||
return nil, fmt.Errorf("send request: %w", err) | ||
} | ||
|
||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) | ||
} | ||
|
||
var responseDecoded *Response | ||
err = json.NewDecoder(resp.Body).Decode(&responseDecoded) | ||
if err != nil { | ||
return nil, fmt.Errorf("read response: %w", err) | ||
} | ||
|
||
return responseDecoded, nil | ||
} | ||
|
||
func (s *Service) getCredentialMetadata(content verifiable.CredentialContents) *CredentialMetadata { | ||
var iss, exp string | ||
if content.Issued != nil { | ||
iss = content.Issued.FormatToString() | ||
} | ||
|
||
if content.Expired != nil { | ||
exp = content.Expired.FormatToString() | ||
} | ||
|
||
return &CredentialMetadata{ | ||
CredentialID: content.ID, | ||
Types: content.Types, | ||
Issuer: content.Issuer.ID, | ||
Issued: iss, | ||
Expired: exp, | ||
} | ||
} |
Oops, something went wrong.