├── .codecov.yaml ├── .gitattributes ├── .github └── workflows │ ├── build.yml │ ├── publish-mocks.yaml │ └── publish.yaml ├── .gitignore ├── .golangci.yml ├── LICENSE ├── Makefile ├── README.md ├── api └── spec │ ├── openapi.cfg.yaml │ ├── openapi.gen.go │ └── openapi.spec.go ├── cmd ├── common │ ├── common.go │ └── common_test.go └── vc-rest │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── main_test.go │ └── startcmd │ ├── configuration.go │ ├── oauth_provider.go │ ├── oauth_provider_test.go │ ├── params.go │ ├── ready.go │ ├── skipper.go │ ├── skipper_test.go │ ├── start.go │ └── start_test.go ├── component ├── credentialstatus │ ├── credentialstatus_service.go │ ├── credentialstatus_service_test.go │ ├── go.mod │ ├── go.sum │ ├── identityhub.go │ ├── identityhub_test.go │ └── internal │ │ └── testutil │ │ ├── contexts │ │ ├── citizenship_v1.jsonld │ │ ├── credentials-examples_v1.jsonld │ │ ├── credentials-examples_v2.jsonld │ │ ├── examples_v1.jsonld │ │ ├── lds-jws2020-v1.jsonld │ │ ├── odrl.jsonld │ │ └── vc-status-list-2021-v1.jsonld │ │ ├── document_loader.go │ │ └── testdata │ │ ├── identity_hub_response_jwt.json │ │ └── sample_vc.jwt ├── echo │ ├── go.mod │ ├── go.sum │ └── prometheus.go ├── event │ ├── bus.go │ ├── bus_test.go │ ├── event.go │ ├── go.mod │ ├── go.sum │ ├── mocks │ │ ├── publisher.gen.go │ │ └── subscriber.gen.go │ ├── publisher.go │ ├── publisher_test.go │ ├── subscriber.go │ └── subscriber_test.go ├── healthchecks │ ├── get.go │ ├── get_test.go │ ├── go.mod │ └── go.sum ├── oidc │ ├── fosite │ │ ├── README.md │ │ ├── dto │ │ │ └── types.go │ │ ├── go.mod │ │ ├── go.sum │ │ ├── mongo │ │ │ ├── access_token.go │ │ │ ├── access_token_test.go │ │ │ ├── assertions.go │ │ │ ├── assertions_test.go │ │ │ ├── auth_code.go │ │ │ ├── auth_code_test.go │ │ │ ├── client.go │ │ │ ├── client_test.go │ │ │ ├── common.go │ │ │ ├── common_test.go │ │ │ ├── fosite_mongo.go │ │ │ ├── fosite_mongo_test.go │ │ │ ├── par.go │ │ │ ├── par_test.go │ │ │ ├── pkce.go │ │ │ ├── pkce_test.go │ │ │ ├── refresh_token.go │ │ │ ├── refresh_token_test.go │ │ │ ├── types.go │ │ │ └── util_test.go │ │ └── redis │ │ │ ├── access_token.go │ │ │ ├── access_token_test.go │ │ │ ├── assertions.go │ │ │ ├── assertions_test.go │ │ │ ├── auth_code.go │ │ │ ├── auth_code_test.go │ │ │ ├── client.go │ │ │ ├── client_test.go │ │ │ ├── common.go │ │ │ ├── common_test.go │ │ │ ├── fosite_redis.go │ │ │ ├── par.go │ │ │ ├── par_test.go │ │ │ ├── pkce.go │ │ │ ├── pkce_test.go │ │ │ ├── refresh_token.go │ │ │ ├── refresh_token_test.go │ │ │ ├── types.go │ │ │ └── util_test.go │ └── vp │ │ ├── requestobjectstore.go │ │ └── requestobjectstore_test.go ├── otp │ ├── go.mod │ ├── go.sum │ ├── pin.go │ └── pin_test.go ├── profile │ └── reader │ │ └── file │ │ ├── creator.go │ │ ├── go.mod │ │ ├── go.sum │ │ ├── internal.go │ │ ├── reader.go │ │ ├── reader_test.go │ │ └── version.go └── wallet-cli │ ├── README.md │ ├── cmd │ ├── attest_wallet_cmd.go │ ├── create_wallet_cmd.go │ ├── init_wallet.go │ ├── oidc4vci_cmd.go │ ├── oidc4vp_cmd.go │ ├── refresh_cmd.go │ └── util.go │ ├── go.mod │ ├── go.sum │ ├── internal │ ├── formatter │ │ └── jwt.go │ ├── ldutil │ │ ├── contexts │ │ │ ├── citizenship-v1.jsonld │ │ │ ├── data-integrity-v1.jsonld │ │ │ ├── data-integrity-v2.jsonld │ │ │ ├── examples-crude-product-v1.jsonld │ │ │ ├── examples-ext-v1.jsonld │ │ │ ├── examples-v1.jsonld │ │ │ ├── lds-jws2020-v1.jsonld │ │ │ ├── odrl.jsonld │ │ │ └── revocation-list-2021.jsonld │ │ └── ldutil.go │ ├── presentation │ │ └── vp_token.go │ ├── storage │ │ ├── leveldb │ │ │ ├── leveldb.go │ │ │ └── leveldb_test.go │ │ ├── mongodb │ │ │ ├── store.go │ │ │ └── store_test.go │ │ ├── provider.go │ │ └── test │ │ │ └── test.go │ └── vdrutil │ │ ├── registry.go │ │ └── vdrutil.go │ ├── main.go │ ├── pkg │ ├── attestation │ │ ├── attestation_service.go │ │ └── models.go │ ├── consent │ │ ├── cognito.go │ │ ├── cognito_test.go │ │ └── interfaces.go │ ├── credentialoffer │ │ └── credential_offer_parser.go │ ├── oidc4vci │ │ ├── models.go │ │ ├── oidc4vci_flow.go │ │ └── proof.go │ ├── oidc4vp │ │ ├── models.go │ │ └── oidc4vp_flow.go │ ├── refresh │ │ └── refresh_flow.go │ ├── signer │ │ └── jws_signer.go │ ├── tracing │ │ └── tracing.go │ ├── trustregistry │ │ ├── models.go │ │ └── trustregistry.go │ ├── wallet │ │ └── wallet.go │ └── wellknown │ │ └── wellknown.go │ └── testdata │ ├── example │ └── qrcode.png │ └── vcs │ ├── certified_mill_test_report.json │ ├── crude_product.json │ ├── permanent_resident_card.json │ └── university_degree.json ├── doc.go ├── docs ├── build.md ├── index.html └── v1 │ ├── common.yaml │ └── openapi.yaml ├── go.mod ├── go.sum ├── images ├── mocks │ ├── attestation │ │ └── Dockerfile │ ├── cognito-auth │ │ └── Dockerfile │ ├── loginconsent │ │ └── Dockerfile │ ├── trustregistry │ │ └── Dockerfile │ └── webhook │ │ └── Dockerfile ├── vc-rest │ └── Dockerfile └── vcs-stress │ └── Dockerfile ├── internal ├── claims │ ├── claims.go │ └── claims_test.go ├── logfields │ ├── fields.go │ └── fields_test.go ├── mock │ └── vcskms │ │ └── vcskms.go └── utils │ ├── map.go │ └── map_test.go ├── pkg ├── cslmanager │ ├── cslmanager.go │ └── cslmanager_test.go ├── dataprotect │ ├── aes.go │ ├── aes_test.go │ ├── api.go │ ├── dataprotect.go │ ├── dataprotect_test.go │ ├── gzip.go │ ├── gzip_test.go │ ├── nilcrypto.go │ ├── nilcrypto_test.go │ ├── nilzip.go │ ├── nilzip_test.go │ ├── zip.go │ ├── zip_test.go │ ├── zstd.go │ └── zstd_test.go ├── doc │ ├── validator │ │ └── jsonschema │ │ │ ├── jsonschema.go │ │ │ ├── jsonschema_test.go │ │ │ └── testdata │ │ │ ├── invalid.schema.json │ │ │ ├── sample_invalid_university_degree.jsonld │ │ │ ├── sample_university_degree.jsonld │ │ │ └── universitydegree.schema.json │ ├── vc │ │ ├── bitstring │ │ │ ├── bitstring.go │ │ │ └── bitstring_test.go │ │ ├── crypto │ │ │ ├── crypto.go │ │ │ ├── crypto_test.go │ │ │ ├── dataIntegrity.go │ │ │ ├── dataIntegrity_test.go │ │ │ ├── util.go │ │ │ └── util_test.go │ │ ├── dataIntegrity.go │ │ ├── jws │ │ │ ├── signer.go │ │ │ └── signer_test.go │ │ ├── sdjwt.go │ │ ├── signer.go │ │ ├── status.go │ │ ├── statustype │ │ │ ├── common.go │ │ │ ├── revocationlist2020.go │ │ │ ├── revocationlist2020_test.go │ │ │ ├── revocationlist2021.go │ │ │ ├── revocationlist2021_test.go │ │ │ ├── statuslist2021.go │ │ │ ├── statuslist2021_test.go │ │ │ ├── statuslist_bitstring.go │ │ │ ├── statuslist_bitstring_test.go │ │ │ ├── statusprocessor.go │ │ │ └── statusprocessor_test.go │ │ ├── testdata │ │ │ ├── sample_vc.jsonld │ │ │ ├── sample_vc.jwt │ │ │ ├── sample_vc.sdjwt │ │ │ ├── sample_vc_expired.jwt │ │ │ └── sample_vc_invalid.jwt │ │ ├── validate.go │ │ ├── validate_test.go │ │ └── vcutil │ │ │ ├── vcutil.go │ │ │ └── vcutil_test.go │ ├── verifiable │ │ ├── format.go │ │ ├── format_test.go │ │ ├── signaturetype.go │ │ └── signaturetype_test.go │ └── vp │ │ ├── testdata │ │ ├── sample_vp.jsonld │ │ └── sample_vp.jwt │ │ ├── validate.go │ │ └── validate_test.go ├── event │ └── spi │ │ ├── spi.go │ │ └── spi_test.go ├── internal │ ├── common │ │ ├── diddoc │ │ │ ├── util.go │ │ │ └── util_test.go │ │ └── support │ │ │ ├── httphandler.go │ │ │ └── httphandler_test.go │ ├── mock │ │ ├── status │ │ │ └── status.go │ │ └── storage │ │ │ └── store.go │ └── testutil │ │ ├── contexts │ │ ├── citizenship-v2.jsonld │ │ ├── citizenship_v1.jsonld │ │ ├── credentials-examples_v1.jsonld │ │ ├── credentials-examples_v2.jsonld │ │ ├── examples_v1.jsonld │ │ ├── lds-jws2020-v1.jsonld │ │ ├── odrl.jsonld │ │ ├── vc-data-integrity-v1.jsonld │ │ ├── vc-data-integrity-v2.jsonld │ │ ├── vc-status-list-2021-v1.jsonld │ │ ├── vc-v2.jsonld │ │ └── wallet_attestation_vc_v1.jsonld │ │ ├── credential.go │ │ ├── cwt.go │ │ ├── document_loader.go │ │ ├── jwt.go │ │ └── presentation.go ├── kms │ ├── arieskms.go │ ├── arieskms_test.go │ ├── aws │ │ ├── opts.go │ │ ├── opts_test.go │ │ ├── service.go │ │ ├── service_mocks.go │ │ ├── service_test.go │ │ └── wrapper.go │ ├── key │ │ ├── creator.go │ │ └── creator_test.go │ ├── kms.go │ ├── mocks │ │ └── kms_mocks.go │ ├── registry.go │ ├── registry_test.go │ ├── resolver.go │ ├── resolver_test.go │ └── signer │ │ ├── arieskms.go │ │ └── arieskms_test.go ├── ld │ ├── cached_context_store.go │ ├── cached_context_store_test.go │ ├── contexts │ │ └── lds-jws2020-v1.jsonld │ ├── document_loader.go │ ├── document_loader_test.go │ ├── store_provider.go │ └── store_provider_test.go ├── lifecycle │ ├── lifecycle.go │ └── lifecycle_test.go ├── oauth2client │ └── api.go ├── observability │ ├── health │ │ ├── healthutil │ │ │ ├── json_result_writer.go │ │ │ ├── json_result_writer_test.go │ │ │ ├── response_time_interceptor.go │ │ │ └── response_time_interceptor_test.go │ │ ├── mongo │ │ │ ├── check.go │ │ │ └── check_test.go │ │ └── redis │ │ │ ├── check.go │ │ │ └── check_test.go │ ├── metrics │ │ ├── noop │ │ │ ├── provider.go │ │ │ └── provider_test.go │ │ ├── prometheus │ │ │ ├── provider.go │ │ │ └── provider_test.go │ │ └── provider.go │ └── tracing │ │ ├── attributeutil │ │ ├── attribute_util.go │ │ └── attribute_util_test.go │ │ ├── tracing.go │ │ ├── tracing_test.go │ │ └── wrappers │ │ ├── credentialstatus │ │ ├── component │ │ │ ├── credentialstatus_wrapper.go │ │ │ └── credentialstatus_wrapper_test.go │ │ └── eventhandler │ │ │ ├── eventhandler_wrapper.go │ │ │ └── eventhandler_wrapper_test.go │ │ ├── issuecredential │ │ ├── issuecredential_wrapper.go │ │ └── issuecredential_wrapper_test.go │ │ ├── oauth2provider │ │ ├── oauth2provider_wrapper.go │ │ └── oauth2provider_wrapper_test.go │ │ ├── oidc4ci │ │ ├── oidc4ci_wrapper.go │ │ └── oidc4ci_wrapper_test.go │ │ ├── oidc4vp │ │ ├── oidc4vp_wrapper.go │ │ └── oidc4vp_wrapper_test.go │ │ ├── verifycredential │ │ ├── verifycredential_wrapper.go │ │ └── verifycredential_wrapper_test.go │ │ └── verifypresentation │ │ ├── verifypresentation_wrapper.go │ │ └── verifypresentation_wrapper_test.go ├── profile │ └── api.go ├── restapi │ ├── common │ │ └── common.go │ ├── handlers │ │ ├── error_handler.go │ │ ├── error_handler_test.go │ │ ├── preauthorize.go │ │ └── preauthorize_test.go │ ├── resterr │ │ ├── component.go │ │ ├── error.go │ │ ├── event_error_codes.go │ │ ├── fosite.go │ │ ├── fosite_test.go │ │ ├── oidc4ci │ │ │ ├── credential_status_endpoint.go │ │ │ ├── credentials_endpoint.go │ │ │ ├── error.go │ │ │ ├── error_test.go │ │ │ ├── initiate_interaction.go │ │ │ ├── notification_endpoint.go │ │ │ └── request_object_endpoint.go │ │ ├── oidc4vp │ │ │ ├── error.go │ │ │ └── error_test.go │ │ ├── rfc6749 │ │ │ ├── error.go │ │ │ └── error_test.go │ │ ├── rfc7591 │ │ │ ├── error.go │ │ │ └── error_test.go │ │ ├── rfc_error.go │ │ └── rfc_error_test.go │ └── v1 │ │ ├── common │ │ ├── common.go │ │ ├── common_test.go │ │ ├── openapi.cfg.yaml │ │ └── openapi.gen.go │ │ ├── devapi │ │ ├── controller.go │ │ └── controller_test.go │ │ ├── issuer │ │ ├── controller.go │ │ ├── controller_test.go │ │ ├── openapi.cfg.yaml │ │ ├── openapi.gen.go │ │ └── testdata │ │ │ ├── sample_invalid_vc_v2.jsonld │ │ │ ├── sample_vc.jsonld │ │ │ ├── sample_vc.jwt │ │ │ ├── sample_vc_invalid_university_degree.jsonld │ │ │ ├── sample_vc_university_degree.jsonld │ │ │ ├── sample_vc_v2.jsonld │ │ │ └── universitydegree.schema.json │ │ ├── logapi │ │ ├── controller.go │ │ └── controller_test.go │ │ ├── mw │ │ ├── api_key_auth.go │ │ └── api_key_auth_test.go │ │ ├── oidc4ci │ │ ├── controller.go │ │ ├── controller_e2e_flows_test.go │ │ ├── controller_test.go │ │ ├── ldp_proof.go │ │ ├── models.go │ │ ├── openapi.cfg.yaml │ │ ├── openapi.gen.go │ │ ├── testdata │ │ │ ├── ldp_proof.json │ │ │ ├── ldp_proof_2.json │ │ │ └── ldp_proof_invalid_date.json │ │ └── types.go │ │ ├── oidc4vp │ │ ├── controller.go │ │ ├── controller_test.go │ │ ├── openapi.cfg.yaml │ │ └── openapi.gen.go │ │ ├── refresh │ │ ├── controller.go │ │ ├── controller_test.go │ │ ├── interfaces.go │ │ ├── openapi.cfg.yaml │ │ ├── openapi.gen.go │ │ └── testdata │ │ │ └── requested_credentials_vp.jsonld │ │ ├── util │ │ ├── auth.go │ │ ├── bind.go │ │ ├── validate.go │ │ └── validate_test.go │ │ ├── verifier │ │ ├── controller.go │ │ ├── controller_test.go │ │ ├── openapi.cfg.yaml │ │ ├── openapi.gen.go │ │ └── testdata │ │ │ ├── sample_vc_jsonld_request.json │ │ │ ├── sample_vc_jwt_request.json │ │ │ ├── sample_vp.jsonld │ │ │ ├── sample_vp.jwt │ │ │ └── sample_vp_jsonld_request.json │ │ └── version │ │ ├── controller.go │ │ └── controller_test.go ├── service │ ├── clientidscheme │ │ ├── api.go │ │ ├── clientidscheme_service.go │ │ └── clientidscheme_service_test.go │ ├── clientmanager │ │ ├── api.go │ │ ├── client_manager.go │ │ └── client_manager_test.go │ ├── credentialstatus │ │ ├── cslservice │ │ │ ├── cslservice.go │ │ │ └── cslservice_test.go │ │ ├── eventhandler │ │ │ ├── eventhandler_service.go │ │ │ └── eventhandler_service_test.go │ │ ├── store.go │ │ └── types.go │ ├── didconfiguration │ │ ├── didconfiguration_service.go │ │ └── didconfiguration_service_test.go │ ├── issuecredential │ │ ├── composer.go │ │ ├── composer_test.go │ │ ├── interfaces.go │ │ ├── issuecredential_service.go │ │ ├── issuecredential_service_test.go │ │ ├── prepare_credential.go │ │ ├── prepare_credential_test.go │ │ ├── testdata │ │ │ └── university_degree.jsonld │ │ ├── types.go │ │ └── types_test.go │ ├── oidc4ci │ │ ├── api.go │ │ ├── claims.go │ │ ├── claims_test.go │ │ ├── interfaces.go │ │ ├── oidc4ci_acknowledgement.go │ │ ├── oidc4ci_acknowledgement_test.go │ │ ├── oidc4ci_service.go │ │ ├── oidc4ci_service_exchange_code.go │ │ ├── oidc4ci_service_exchange_code_test.go │ │ ├── oidc4ci_service_initiate_issuance.go │ │ ├── oidc4ci_service_initiate_issuance_test.go │ │ ├── oidc4ci_service_state.go │ │ ├── oidc4ci_service_state_test.go │ │ ├── oidc4ci_service_store_auth_code.go │ │ ├── oidc4ci_service_store_auth_code_test.go │ │ ├── oidc4ci_service_test.go │ │ ├── regex.go │ │ └── testdata │ │ │ ├── issuer_profile.json │ │ │ └── issuer_profile_without_template.json │ ├── oidc4vp │ │ ├── api.go │ │ ├── attachments.go │ │ ├── attachments_test.go │ │ ├── claims.go │ │ ├── event.go │ │ ├── event_test.go │ │ ├── oidc4vp_service.go │ │ ├── oidc4vp_service_test.go │ │ ├── oidc4vp_wallet_notification.go │ │ ├── oidc4vp_wallet_notification_test.go │ │ ├── testdata │ │ │ ├── sample_vc_v2.jsonld │ │ │ ├── university_degree.jsonld │ │ │ ├── university_degree.jwt │ │ │ ├── university_degree_embedded_attachment.jsonld │ │ │ ├── university_degree_evidence_attachment.jsonld │ │ │ ├── university_degree_remote_attachment.jsonld │ │ │ └── university_degree_with_attachments.jsonld │ │ ├── txmanager.go │ │ └── txmanager_test.go │ ├── refresh │ │ ├── interfaces.go │ │ ├── refresh.go │ │ ├── refresh_test.go │ │ ├── testdata │ │ │ └── requested_credentials_vp.jsonld │ │ └── types.go │ ├── requestobject │ │ └── types.go │ ├── trustregistry │ │ ├── api.go │ │ ├── trustregistry_service.go │ │ └── trustregistry_service_test.go │ ├── verifycredential │ │ ├── api.go │ │ ├── linkeddomain.go │ │ ├── linkeddomain_test.go │ │ ├── testdata │ │ │ ├── revocation.jsonld │ │ │ ├── university_degree.jsonld │ │ │ └── university_degree.jwt │ │ ├── verifycredential_service.go │ │ └── verifycredential_service_test.go │ ├── verifypresentation │ │ ├── api.go │ │ ├── testdata │ │ │ ├── client_attestation_vp.jsonld │ │ │ └── requested_credentials_vp.jsonld │ │ ├── verifypresentation_service.go │ │ └── verifypresentation_service_test.go │ └── wellknown │ │ ├── fetcher │ │ ├── wellknown_service.go │ │ └── wellknown_service_test.go │ │ └── provider │ │ ├── api.go │ │ ├── interfaces.go │ │ ├── testdata │ │ └── profile.json │ │ ├── wellknown_service.go │ │ └── wellknown_service_test.go └── storage │ ├── awsecret │ └── arieskmsstore │ │ ├── aries_kms_store.go │ │ ├── aries_kms_store_test.go │ │ └── interfaces.go │ ├── mongodb │ ├── arieskmsstore │ │ ├── aries_kms_store.go │ │ └── aries_kms_store_test.go │ ├── client.go │ ├── client_test.go │ ├── clientmanager │ │ ├── api.go │ │ ├── clientmanager_store.go │ │ └── clientmanager_store_test.go │ ├── cslindexstore │ │ ├── csl_index_store.go │ │ ├── csl_index_store_test.go │ │ └── testdata │ │ │ ├── university_degree.jsonld │ │ │ └── university_degree.jwt │ ├── cslvcstore │ │ ├── csl_vc_store.go │ │ ├── csl_vc_store_test.go │ │ └── testdata │ │ │ ├── university_degree.jsonld │ │ │ └── university_degree.jwt │ ├── internal │ │ └── util.go │ ├── ldstore │ │ ├── context_store.go │ │ ├── context_store_test.go │ │ ├── remote_provider_store.go │ │ └── remote_provider_store_test.go │ ├── oidc4ciclaimdatastore │ │ ├── claim_data_store.go │ │ └── claim_data_store_test.go │ ├── oidc4cinoncestore │ │ ├── oidc4vc_store.go │ │ └── oidc4vc_store_test.go │ ├── oidc4cistatestore │ │ ├── oidc4vc_state_store.go │ │ └── oidc4vc_state_store_test.go │ ├── oidc4vpclaimsstore │ │ ├── oidc4vp_claims_store.go │ │ └── oidc4vp_claims_store_test.go │ ├── oidc4vpnoncestore │ │ ├── tx_nonce_store.go │ │ └── tx_nonce_store_test.go │ ├── oidc4vptxstore │ │ ├── oidc4vp_tx_store.go │ │ └── oidc4vp_tx_store_test.go │ ├── requestobjectstore │ │ ├── request_object_store.go │ │ └── request_object_store_test.go │ ├── util.go │ ├── util_test.go │ ├── vcissuancehistorystore │ │ ├── vc_issuance_histsory_store.go │ │ └── vc_issuance_histsory_store_test.go │ └── vcstatusstore │ │ ├── testdata │ │ ├── multi_status.jsonld │ │ └── university_degree.jsonld │ │ ├── vc_status_store.go │ │ └── vc_status_store_test.go │ ├── redis │ ├── ackstore │ │ ├── ackstore.go │ │ ├── ackstore_test.go │ │ └── interfaces.go │ ├── client.go │ ├── client_test.go │ ├── dynamicwellknown │ │ ├── dynamicwellknown.go │ │ ├── dynamicwellknown_test.go │ │ └── interfaces.go │ ├── oidc4ciclaimdatastore │ │ ├── claim_data_store.go │ │ ├── claim_data_store_test.go │ │ └── doc.go │ ├── oidc4cinoncestore │ │ ├── doc.go │ │ ├── oidc4vc_store.go │ │ └── oidc4vc_store_test.go │ ├── oidc4cistatestore │ │ ├── doc.go │ │ ├── oidc4vc_state_store.go │ │ └── oidc4vc_state_store_test.go │ ├── oidc4vpclaimsstore │ │ ├── doc.go │ │ ├── oidc4vp_claims_store.go │ │ └── oidc4vp_claims_store_test.go │ ├── oidc4vpnoncestore │ │ ├── doc.go │ │ ├── tx_nonce_store.go │ │ └── tx_nonce_store_test.go │ └── oidc4vptxstore │ │ ├── doc.go │ │ ├── oidc4vp_tx_store.go │ │ └── oidc4vp_tx_store_test.go │ └── s3 │ ├── credentialoffer │ ├── credential_offer_store.go │ └── credential_offer_store_test.go │ ├── cslvcstore │ ├── csl_vc_store.go │ ├── csl_vc_store_test.go │ └── testdata │ │ ├── university_degree.jsonld │ │ └── university_degree.jwt │ └── requestobjectstore │ ├── request_object_store.go │ └── request_object_store_test.go ├── scripts ├── build-cli.sh ├── check_integration.sh ├── check_license.sh ├── check_lint.sh ├── check_unit.sh └── generate_test_keys.sh └── test ├── bdd ├── attestation │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── models.go │ └── server.go ├── bddtests_test.go ├── cognito-auth │ ├── main.go │ └── resolver.go ├── features │ ├── README.md │ ├── oidc4vc_api.feature │ ├── vc_dev_api.feature │ ├── vc_echo_api.feature │ ├── vc_log_api.feature │ ├── vc_stress.feature │ ├── vc_v1_issue_verify_revoke_api.feature │ └── vc_version_api.feature ├── fixtures │ ├── .env │ ├── aws-kms │ │ └── seed.yaml │ ├── cognito-config │ │ ├── config.json │ │ └── db │ │ │ ├── clients.json │ │ │ └── local_5a9GzRvB.json │ ├── did-resolver │ │ └── config.json │ ├── docker-compose.yml │ ├── file-server │ │ ├── .well-known │ │ │ └── oauth-client │ │ └── ld-contexts.json │ ├── krakend-config │ │ ├── generate-configs.sh │ │ ├── krakend.tmpl │ │ ├── partials │ │ │ └── x_api_key_header.tmpl │ │ ├── settings │ │ │ ├── endpoint.json │ │ │ └── service.json │ │ └── templates │ │ │ └── auth_validator.tmpl │ ├── mysql-config │ │ └── mysql_config.sql │ ├── nginx-config │ │ ├── data │ │ │ └── .gitignore │ │ └── nginx.conf │ ├── oauth-clients │ │ └── clients.json │ ├── profile │ │ └── profiles.json │ ├── prometheus-config │ │ └── prometheus.yml │ └── universal-resolver │ │ ├── config.json │ │ └── run-uni-resolver-web.sh ├── go.mod ├── go.sum ├── krakend-plugins │ └── http-client-no-redirect │ │ ├── go.mod │ │ ├── go.sum │ │ └── main.go ├── loginconsent │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── server.go │ └── tls │ │ ├── certpool.go │ │ └── certpool_test.go ├── pkg │ ├── bddutil │ │ ├── contexts │ │ │ ├── citizenship-mod-v2.jsonld │ │ │ ├── citizenship-v1.jsonld │ │ │ ├── examples-crude-product-v1.jsonld │ │ │ ├── examples-crude-product-v2.jsonld │ │ │ ├── examples-ext-v1.jsonld │ │ │ ├── examples-v1.jsonld │ │ │ ├── examples-v2.jsonld │ │ │ ├── lds-jws2020-v1.jsonld │ │ │ ├── odrl.jsonld │ │ │ ├── revocation-list-2021.jsonld │ │ │ ├── vc-data-integrity-v1.jsonld │ │ │ └── vc-data-integrity-v2.jsonld │ │ ├── util.go │ │ └── workerpool.go │ ├── common │ │ └── common_steps.go │ ├── context │ │ └── context.go │ ├── v1 │ │ ├── model │ │ │ └── model.go │ │ ├── oidc4vc │ │ │ ├── models.go │ │ │ ├── oidc4vci.go │ │ │ ├── oidc4vp.go │ │ │ ├── refresh.go │ │ │ └── steps.go │ │ └── vc │ │ │ ├── credential.go │ │ │ ├── stress_steps.go │ │ │ ├── types.go │ │ │ └── vc_steps.go │ ├── vc-devapi │ │ └── vc_devapi_steps.go │ ├── vc-echo │ │ └── vc_echo_steps.go │ └── vc-version │ │ └── vc_version_steps.go ├── testdata │ ├── attestation_vc.jwt │ ├── certified_mill_test_report.json │ ├── crude_product.json │ ├── crude_product_vcdm2.json │ ├── danubetech_vc1.json │ ├── danubetech_vc2.json │ ├── digitalbazaar_vc1.json │ ├── factom_vc1.json │ ├── factom_vc2.json │ ├── factom_vc3.json │ ├── factom_vc4.json │ ├── mavennet_vc1.json │ ├── mavennet_vc2.json │ ├── mavennet_vc3.json │ ├── mavennet_vc4.json │ ├── mavennet_vp1.json │ ├── mavennet_vp2.json │ ├── mavennet_vp3.json │ ├── mavennet_vp4.json │ ├── permanent_resident_card.json │ ├── profile_request_template.json │ ├── sicpa_vc1.json │ ├── sicpa_vc2.json │ ├── sicpa_vc3.json │ ├── transmute_vc1.json │ ├── transmute_vc2.json │ ├── transmute_vc3.json │ ├── transmute_vc4.json │ ├── transmute_vp1.json │ ├── transmute_vp2.json │ ├── transmute_vp3.json │ ├── transmute_vp4.json │ ├── university_certificate.json │ ├── university_degree.json │ ├── university_degree.jwt │ └── university_degree_invalid_claims.json ├── trustregistry │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── models.go │ └── server.go └── webhook │ └── main.go └── stress ├── bdd └── docker-compose.yml ├── cmd ├── cluster.go ├── main.go └── types.go ├── go.mod ├── go.sum └── pkg └── stress ├── mitm.go ├── providers.go ├── stress.go ├── stress_test_case.go └── types.go /.codecov.yaml: -------------------------------------------------------------------------------- 1 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | 5 | coverage: 6 | status: 7 | project: 8 | default: 9 | target: 70% 10 | patch: 11 | default: 12 | target: 75% 13 | only_pulls: true 14 | 15 | ignore: 16 | - "test/bdd" # ignore bdd tests 17 | - "component/walletcli" # ignore walletcli testing tool 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | # Binaries for programs and plugins 8 | *.exe 9 | *.exe~ 10 | *.dll 11 | *.so 12 | *.dylib 13 | 14 | # Editor and go temporary files & folders 15 | .swp 16 | vendor 17 | 18 | # Test binary, build with `go test -c` 19 | *.test 20 | 21 | # Output of the go coverage tool, specifically when used with LiteIDE 22 | *.out 23 | .idea 24 | .DS_Store 25 | 26 | coverage.out 27 | coverage.txt 28 | 29 | # Exclude build directory 30 | .build 31 | *.log 32 | build/ 33 | 34 | test/bdd/fixtures/keys/tls 35 | test/bdd/fixtures/spec/ 36 | 37 | # Auto-generated mock files 38 | *_mocks_test.go 39 | gomocks_test.go 40 | cmd/vc-rest/.env 41 | 42 | test/stress/cmd/.env 43 | 44 | test/stress/.env 45 | 46 | component/wallet-cli/wallet-cli 47 | -------------------------------------------------------------------------------- /api/spec/openapi.cfg.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | package: spec 8 | output: openapi.gen.go 9 | generate: 10 | models: false 11 | echo-server: false 12 | embedded-spec: true 13 | import-mapping: 14 | ./common.yaml: github.com/trustbloc/vcs/pkg/restapi/v1/common 15 | -------------------------------------------------------------------------------- /api/spec/openapi.spec.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | //go:generate oapi-codegen --config=openapi.cfg.yaml ../../docs/v1/openapi.yaml 8 | 9 | package spec 10 | -------------------------------------------------------------------------------- /cmd/common/common_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package common 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/require" 13 | 14 | "github.com/trustbloc/logutil-go/pkg/log" 15 | ) 16 | 17 | const testLogModuleName = "test" 18 | 19 | var logger = log.New(testLogModuleName) 20 | 21 | func TestSetLogLevel(t *testing.T) { 22 | t.Run("Success", func(t *testing.T) { 23 | resetLoggingLevels() 24 | 25 | SetDefaultLogLevel(logger, "debug") 26 | 27 | require.Equal(t, log.DEBUG, log.GetLevel("")) 28 | }) 29 | t.Run("Invalid log level", func(t *testing.T) { 30 | resetLoggingLevels() 31 | 32 | SetDefaultLogLevel(logger, "mango") 33 | 34 | // Should remain unchanged 35 | require.Equal(t, log.INFO, log.GetLevel("")) 36 | }) 37 | } 38 | 39 | func resetLoggingLevels() { 40 | log.SetLevel("", log.INFO) 41 | } 42 | -------------------------------------------------------------------------------- /cmd/vc-rest/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package main 8 | 9 | import ( 10 | "os" 11 | 12 | "github.com/spf13/cobra" 13 | "github.com/trustbloc/logutil-go/pkg/log" 14 | 15 | "github.com/trustbloc/vcs/cmd/vc-rest/startcmd" 16 | ) 17 | 18 | var logger = log.New("vc-rest") 19 | var Version string // will be embeded during build 20 | 21 | func main() { 22 | rootCmd := &cobra.Command{ 23 | Use: "vc-rest", 24 | Run: func(cmd *cobra.Command, args []string) { 25 | cmd.HelpFunc()(cmd, args) 26 | }, 27 | } 28 | 29 | rootCmd.AddCommand(startcmd.GetStartCmd( 30 | startcmd.WithVersion(Version), 31 | startcmd.WithServerVersion(os.Getenv("VC_SYSTEM_VERSION")), 32 | )) 33 | 34 | if err := rootCmd.Execute(); err != nil { 35 | logger.Fatal("Failed to run vc-rest", log.WithError(err)) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /cmd/vc-rest/main_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package main 7 | 8 | import ( 9 | "os" 10 | "testing" 11 | ) 12 | 13 | // Correct behaviour is for main to finish with exit code 0. 14 | // This test fails otherwise. However, this can't be checked by the unit test framework. The *testing.T argument is 15 | // only there so that this test gets picked up by the framework but otherwise we don't need it. 16 | func TestWithoutUserAgs(_ *testing.T) { 17 | setUpArgs() 18 | main() 19 | } 20 | 21 | // Strips out the extra args that the unit test framework adds 22 | // This allows main() to execute as if it was called directly from the command line 23 | func setUpArgs() { 24 | os.Args = os.Args[:1] 25 | } 26 | -------------------------------------------------------------------------------- /cmd/vc-rest/startcmd/ready.go: -------------------------------------------------------------------------------- 1 | package startcmd 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/labstack/echo/v4" 7 | ) 8 | 9 | const ( 10 | readinessEndpoint = "/ready" 11 | ) 12 | 13 | type readiness struct { 14 | isReady bool 15 | } 16 | 17 | func newReadinessController(internalEcho *echo.Echo) *readiness { 18 | r := &readiness{ 19 | isReady: false, 20 | } 21 | 22 | internalEcho.GET(readinessEndpoint, func(c echo.Context) error { 23 | if r.isReady { 24 | return c.NoContent(http.StatusOK) 25 | } 26 | 27 | return c.NoContent(http.StatusForbidden) 28 | }) 29 | 30 | return r 31 | } 32 | 33 | func (r *readiness) Ready(isReady bool) { 34 | r.isReady = isReady 35 | } 36 | -------------------------------------------------------------------------------- /cmd/vc-rest/startcmd/skipper.go: -------------------------------------------------------------------------------- 1 | package startcmd 2 | 3 | import ( 4 | "github.com/labstack/echo/v4" 5 | echomw "github.com/labstack/echo/v4/middleware" 6 | "strings" 7 | ) 8 | 9 | func OApiSkipper(c echo.Context) bool { 10 | if c.Path() == devApiRequestObjectEndpoint || c.Path() == devApiDidConfigEndpoint { 11 | return true 12 | } 13 | if c.Path() == versionEndpoint || c.Path() == versionSystemEndpoint { 14 | return true 15 | } 16 | 17 | if c.Path() == logLevelsEndpoint { 18 | return true 19 | } 20 | if strings.Contains(c.Path(), profilerEndpoints) { 21 | return true 22 | } 23 | 24 | return echomw.DefaultSkipper(c) 25 | } 26 | -------------------------------------------------------------------------------- /cmd/vc-rest/startcmd/skipper_test.go: -------------------------------------------------------------------------------- 1 | package startcmd 2 | 3 | import ( 4 | "github.com/labstack/echo/v4" 5 | "net/http" 6 | "net/http/httptest" 7 | "testing" 8 | ) 9 | 10 | func TestOApiSkipper(t *testing.T) { 11 | tests := []struct { 12 | name string 13 | path string 14 | result bool 15 | }{ 16 | { 17 | name: "version endpoint", 18 | path: "/version/system", 19 | result: true, 20 | }, 21 | { 22 | name: "versionSystem endpoint", 23 | path: "/version", 24 | result: true, 25 | }, 26 | { 27 | name: "devApiRequestObject endpoint", 28 | path: "/request-object/:uuid", 29 | result: true, 30 | }, 31 | { 32 | name: "logLevels endpoint", 33 | path: "/loglevels", 34 | result: true, 35 | }, 36 | { 37 | name: "profiler endpoint", 38 | path: "/debug/pprof/some/other/path", 39 | result: true, 40 | }, 41 | { 42 | name: "other endpoint", 43 | path: "/some/other/path", 44 | result: false, 45 | }, 46 | } 47 | 48 | for _, tt := range tests { 49 | t.Run(tt.name, func(t *testing.T) { 50 | req := httptest.NewRequest(http.MethodGet, tt.path, nil) 51 | ctx := echo.New().NewContext(req, httptest.NewRecorder()) 52 | ctx.SetPath(tt.path) 53 | 54 | if got := OApiSkipper(ctx); got != tt.result { 55 | t.Errorf("OApiSkipper() = %v, want %v", got, tt.result) 56 | } 57 | }) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /component/credentialstatus/internal/testutil/contexts/credentials-examples_v2.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@vocab": "https://www.w3.org/ns/credentials/examples#" 4 | } 5 | } -------------------------------------------------------------------------------- /component/credentialstatus/internal/testutil/contexts/examples_v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@version": 1.1, 4 | 5 | "id": "@id", 6 | "type": "@type", 7 | 8 | "ex": "https://example.org/examples#", 9 | 10 | "image": {"@id": "http://schema.org/image", "@type": "@id"}, 11 | 12 | "CredentialStatusList2017": "ex:CredentialStatusList2017", 13 | "DocumentVerification": "ex:DocumentVerification", 14 | "SupportingActivity": "ex:SupportingActivity" 15 | } 16 | } -------------------------------------------------------------------------------- /component/echo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/trustbloc/vcs/component/echo 2 | 3 | go 1.21 4 | 5 | toolchain go1.22.4 6 | 7 | require ( 8 | github.com/labstack/echo/v4 v4.10.2 9 | github.com/prometheus/client_golang v1.15.1 10 | ) 11 | 12 | require ( 13 | github.com/beorn7/perks v1.0.1 // indirect 14 | github.com/cespare/xxhash/v2 v2.2.0 // indirect 15 | github.com/golang/protobuf v1.5.3 // indirect 16 | github.com/labstack/gommon v0.4.0 // indirect 17 | github.com/mattn/go-colorable v0.1.13 // indirect 18 | github.com/mattn/go-isatty v0.0.17 // indirect 19 | github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect 20 | github.com/prometheus/client_model v0.4.0 // indirect 21 | github.com/prometheus/common v0.44.0 // indirect 22 | github.com/prometheus/procfs v0.9.0 // indirect 23 | github.com/valyala/bytebufferpool v1.0.0 // indirect 24 | github.com/valyala/fasttemplate v1.2.2 // indirect 25 | golang.org/x/crypto v0.6.0 // indirect 26 | golang.org/x/net v0.10.0 // indirect 27 | golang.org/x/sys v0.8.0 // indirect 28 | golang.org/x/text v0.9.0 // indirect 29 | google.golang.org/protobuf v1.30.0 // indirect 30 | ) 31 | -------------------------------------------------------------------------------- /component/event/publisher.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package event 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/trustbloc/vcs/pkg/event/spi" 13 | ) 14 | 15 | // NewEventPublisher creates event publisher. 16 | func NewEventPublisher(pub eventPublisher) *Publisher { 17 | return &Publisher{ 18 | publisher: pub, 19 | } 20 | } 21 | 22 | type eventPublisher interface { 23 | Publish(ctx context.Context, topic string, events ...*spi.Event) error 24 | } 25 | 26 | type Publisher struct { 27 | publisher eventPublisher 28 | } 29 | 30 | func (p *Publisher) Publish(ctx context.Context, topic string, events ...*spi.Event) error { 31 | return p.publisher.Publish(ctx, topic, events...) 32 | } 33 | -------------------------------------------------------------------------------- /component/healthchecks/get_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package healthchecks_test 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/require" 13 | 14 | "github.com/trustbloc/vcs/component/healthchecks" 15 | ) 16 | 17 | func TestGet(t *testing.T) { 18 | require.Len(t, healthchecks.Get(&healthchecks.Config{ 19 | RedisParameters: &healthchecks.RedisParameters{ 20 | Addrs: []string{"redis.example.com"}, 21 | }, 22 | }), 2) 23 | } 24 | -------------------------------------------------------------------------------- /component/oidc/fosite/dto/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dto 8 | 9 | import ( 10 | "errors" 11 | "net/url" 12 | "time" 13 | 14 | "github.com/ory/fosite" 15 | "golang.org/x/text/language" 16 | ) 17 | 18 | const ( 19 | ParSegment = "fosite_par" 20 | AuthCodeSegment = "fosite_auth_code" 21 | PkceSessionSegment = "fosite_pkce_sessions" 22 | RefreshTokenSegment = "fosite_refresh_token_sessions" //nolint: gosec 23 | AccessTokenSegment = "fosite_access_token_sessions" 24 | ) 25 | 26 | var ErrDataNotFound = errors.New("data not found") 27 | 28 | type AuthorizeRequest struct { 29 | ResponseTypes fosite.Arguments 30 | RedirectURI *url.URL 31 | State string 32 | HandledResponseTypes fosite.Arguments 33 | ResponseMode fosite.ResponseModeType 34 | DefaultResponseMode fosite.ResponseModeType 35 | ClientID string 36 | } 37 | 38 | type Request struct { 39 | ID string 40 | RequestedAt time.Time 41 | RequestedScope fosite.Arguments 42 | GrantedScope fosite.Arguments 43 | Form url.Values 44 | RequestedAudience fosite.Arguments 45 | GrantedAudience fosite.Arguments 46 | Lang language.Tag 47 | ClientID string 48 | SessionExtra map[string]interface{} 49 | } 50 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/access_token.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/ory/fosite" 13 | "go.mongodb.org/mongo-driver/bson" 14 | 15 | "github.com/trustbloc/vcs/component/oidc/fosite/dto" 16 | ) 17 | 18 | func (s *Store) CreateAccessTokenSession(ctx context.Context, signature string, request fosite.Requester) error { 19 | return s.createSession(ctx, dto.AccessTokenSegment, signature, request, defaultTTL) 20 | } 21 | 22 | func (s *Store) GetAccessTokenSession( 23 | ctx context.Context, 24 | signature string, 25 | session fosite.Session, 26 | ) (fosite.Requester, error) { 27 | return s.getSession(ctx, dto.AccessTokenSegment, signature, session) 28 | } 29 | 30 | func (s *Store) DeleteAccessTokenSession(ctx context.Context, signature string) error { 31 | collection := s.mongoClient.Database().Collection(dto.AccessTokenSegment) 32 | 33 | _, err := collection.DeleteOne(ctx, bson.M{"_lookupId": signature}) 34 | return err 35 | } 36 | 37 | func (s *Store) RevokeAccessToken(ctx context.Context, requestID string) error { 38 | collection := s.mongoClient.Database().Collection(dto.AccessTokenSegment) 39 | 40 | _, err := collection.DeleteOne(ctx, bson.M{"record.id": requestID}) 41 | return err 42 | } 43 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/assertions.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "github.com/ory/fosite" 11 | "github.com/ory/fosite/handler/oauth2" 12 | "github.com/ory/fosite/handler/pkce" 13 | ) 14 | 15 | func (s *Store) assertInterface() fosite.Storage { 16 | return s 17 | } 18 | 19 | func (s *Store) assertInterface2() oauth2.CoreStorage { 20 | return s 21 | } 22 | 23 | func (s *Store) assertInterface3() oauth2.TokenRevocationStorage { 24 | return s 25 | } 26 | 27 | func (s *Store) assertInterface4() pkce.PKCERequestStorage { 28 | return s 29 | } 30 | 31 | func (s *Store) assertInterface5() fosite.PARStorage { 32 | return s 33 | } 34 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/assertions_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestAssertions(t *testing.T) { 16 | s := Store{} 17 | 18 | assert.NotNil(t, s.assertInterface()) 19 | assert.NotNil(t, s.assertInterface2()) 20 | assert.NotNil(t, s.assertInterface3()) 21 | assert.NotNil(t, s.assertInterface4()) 22 | assert.NotNil(t, s.assertInterface5()) 23 | } 24 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/auth_code.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/ory/fosite" 13 | "go.mongodb.org/mongo-driver/bson" 14 | 15 | "github.com/trustbloc/vcs/component/oidc/fosite/dto" 16 | ) 17 | 18 | func (s *Store) CreateAuthorizeCodeSession(ctx context.Context, code string, request fosite.Requester) error { 19 | return s.createSession(ctx, dto.AuthCodeSegment, code, request, defaultTTL) 20 | } 21 | 22 | func (s *Store) GetAuthorizeCodeSession( 23 | ctx context.Context, 24 | code string, 25 | session fosite.Session, 26 | ) (fosite.Requester, error) { 27 | return s.getSession(ctx, dto.AuthCodeSegment, code, session) 28 | } 29 | 30 | func (s *Store) InvalidateAuthorizeCodeSession(ctx context.Context, code string) error { 31 | collection := s.mongoClient.Database().Collection(dto.AuthCodeSegment) 32 | 33 | _, err := collection.DeleteOne(ctx, bson.M{"_lookupId": code}) 34 | 35 | return err 36 | } 37 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "context" 11 | "time" 12 | 13 | "github.com/ory/fosite" 14 | ) 15 | 16 | // GetClient loads the client by its ID or returns an error 17 | // if the client does not exist or another error occurred. 18 | func (s *Store) GetClient(ctx context.Context, id string) (fosite.Client, error) { 19 | return s.clientManager.GetClient(ctx, id) 20 | } 21 | 22 | // ClientAssertionJWTValid returns an error if the JTI is 23 | // known or the DB check failed and nil if the JTI is not known. 24 | func (s *Store) ClientAssertionJWTValid(ctx context.Context, jti string) error { 25 | return s.clientManager.ClientAssertionJWTValid(ctx, jti) 26 | } 27 | 28 | // SetClientAssertionJWT marks a JTI as known for the given 29 | // expiry time. Before inserting the new JTI, it will clean 30 | // up any existing JTIs that have expired as those tokens can 31 | // not be replayed due to the expiry. 32 | func (s *Store) SetClientAssertionJWT(ctx context.Context, jti string, exp time.Time) error { 33 | return s.clientManager.SetClientAssertionJWT(ctx, jti, exp) 34 | } 35 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/fosite_mongo_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "context" 11 | "testing" 12 | "time" 13 | 14 | "github.com/stretchr/testify/assert" 15 | 16 | "github.com/trustbloc/vcs/pkg/storage/mongodb" 17 | "github.com/trustbloc/vcs/pkg/storage/mongodb/clientmanager" 18 | ) 19 | 20 | func TestFailMigration(t *testing.T) { 21 | pool, mongoDBResource := startMongoDBContainer(t) 22 | 23 | defer func() { 24 | assert.NoError(t, pool.Purge(mongoDBResource), "failed to purge MongoDB resource") 25 | }() 26 | 27 | client, mongoErr := mongodb.New(mongoDBConnString, "testdb", mongodb.WithTimeout(time.Second*10)) 28 | assert.NoError(t, mongoErr) 29 | 30 | clientManager, storeErr := clientmanager.NewStore(context.Background(), client) 31 | assert.NoError(t, storeErr) 32 | 33 | ctx, cancel := context.WithCancel(context.TODO()) 34 | cancel() 35 | 36 | s, err := NewStore(ctx, client, clientManager) 37 | assert.Nil(t, s) 38 | assert.ErrorContains(t, err, "context canceled") 39 | } 40 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/pkce.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/ory/fosite" 13 | "go.mongodb.org/mongo-driver/bson" 14 | 15 | "github.com/trustbloc/vcs/component/oidc/fosite/dto" 16 | ) 17 | 18 | func (s *Store) CreatePKCERequestSession(ctx context.Context, signature string, requester fosite.Requester) error { 19 | return s.createSession(ctx, dto.PkceSessionSegment, signature, requester, defaultTTL) 20 | } 21 | 22 | func (s *Store) DeletePKCERequestSession(ctx context.Context, signature string) error { 23 | collection := s.mongoClient.Database().Collection(dto.PkceSessionSegment) 24 | 25 | _, err := collection.DeleteOne(ctx, bson.M{"_lookupId": signature}) 26 | return err 27 | } 28 | 29 | func (s *Store) GetPKCERequestSession( 30 | ctx context.Context, 31 | signature string, 32 | session fosite.Session, 33 | ) (fosite.Requester, error) { 34 | return s.getSession(ctx, dto.PkceSessionSegment, signature, session) 35 | } 36 | -------------------------------------------------------------------------------- /component/oidc/fosite/mongo/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "time" 11 | 12 | "go.mongodb.org/mongo-driver/bson/primitive" 13 | ) 14 | 15 | type genericDocument[T any] struct { 16 | ID primitive.ObjectID `bson:"_id,omitempty"` 17 | Record T `bson:"record"` 18 | LookupID string `bson:"_lookupId"` 19 | ExpireAt *time.Time `bson:"expireAt,omitempty"` 20 | } 21 | -------------------------------------------------------------------------------- /component/oidc/fosite/redis/assertions.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package redis 8 | 9 | import ( 10 | "github.com/ory/fosite" 11 | "github.com/ory/fosite/handler/oauth2" 12 | "github.com/ory/fosite/handler/pkce" 13 | ) 14 | 15 | func (s *Store) assertInterface() fosite.Storage { 16 | return s 17 | } 18 | 19 | func (s *Store) assertInterface2() oauth2.CoreStorage { 20 | return s 21 | } 22 | 23 | func (s *Store) assertInterface3() oauth2.TokenRevocationStorage { 24 | return s 25 | } 26 | 27 | func (s *Store) assertInterface4() pkce.PKCERequestStorage { 28 | return s 29 | } 30 | 31 | func (s *Store) assertInterface5() fosite.PARStorage { 32 | return s 33 | } 34 | -------------------------------------------------------------------------------- /component/oidc/fosite/redis/assertions_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package redis 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestAssertions(t *testing.T) { 16 | s := Store{} 17 | 18 | assert.NotNil(t, s.assertInterface()) 19 | assert.NotNil(t, s.assertInterface2()) 20 | assert.NotNil(t, s.assertInterface3()) 21 | assert.NotNil(t, s.assertInterface4()) 22 | assert.NotNil(t, s.assertInterface5()) 23 | } 24 | -------------------------------------------------------------------------------- /component/oidc/fosite/redis/auth_code.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package redis 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/ory/fosite" 13 | 14 | "github.com/trustbloc/vcs/component/oidc/fosite/dto" 15 | ) 16 | 17 | func (s *Store) CreateAuthorizeCodeSession(ctx context.Context, code string, request fosite.Requester) error { 18 | return s.createSession(ctx, dto.AuthCodeSegment, code, request, defaultTTL) 19 | } 20 | 21 | func (s *Store) GetAuthorizeCodeSession( 22 | ctx context.Context, 23 | code string, 24 | session fosite.Session, 25 | ) (fosite.Requester, error) { 26 | return s.getSession(ctx, dto.AuthCodeSegment, code, session) 27 | } 28 | 29 | func (s *Store) InvalidateAuthorizeCodeSession(ctx context.Context, code string) error { 30 | key := resolveRedisKey(dto.AuthCodeSegment, code) 31 | 32 | return s.redisClient.API().Del(ctx, key).Err() 33 | } 34 | -------------------------------------------------------------------------------- /component/oidc/fosite/redis/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package redis 8 | 9 | import ( 10 | "context" 11 | "time" 12 | 13 | "github.com/ory/fosite" 14 | ) 15 | 16 | // GetClient loads the client by its ID or returns an error 17 | // if the client does not exist or another error occurred. 18 | func (s *Store) GetClient(ctx context.Context, id string) (fosite.Client, error) { 19 | return s.clientManager.GetClient(ctx, id) 20 | } 21 | 22 | // ClientAssertionJWTValid returns an error if the JTI is 23 | // known or the DB check failed and nil if the JTI is not known. 24 | func (s *Store) ClientAssertionJWTValid(ctx context.Context, jti string) error { 25 | return s.clientManager.ClientAssertionJWTValid(ctx, jti) 26 | } 27 | 28 | // SetClientAssertionJWT marks a JTI as known for the given 29 | // expiry time. Before inserting the new JTI, it will clean 30 | // up any existing JTIs that have expired as those tokens can 31 | // not be replayed due to the expiry. 32 | func (s *Store) SetClientAssertionJWT(ctx context.Context, jti string, exp time.Time) error { 33 | return s.clientManager.SetClientAssertionJWT(ctx, jti, exp) 34 | } 35 | -------------------------------------------------------------------------------- /component/oidc/fosite/redis/fosite_redis.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | //go:generate mockgen -destination client_mocks_test.go -package redis -source=fosite_redis.go -mock_names mockClientManager=MockClientManager 8 | 9 | package redis 10 | 11 | import ( 12 | "time" 13 | 14 | "github.com/ory/fosite" 15 | "github.com/ory/fosite/handler/oauth2" 16 | "github.com/ory/fosite/handler/pkce" 17 | 18 | "github.com/trustbloc/vcs/pkg/storage/redis" 19 | ) 20 | 21 | var ( 22 | _ fosite.Storage = (*Store)(nil) 23 | _ fosite.PARStorage = (*Store)(nil) 24 | _ pkce.PKCERequestStorage = (*Store)(nil) 25 | _ oauth2.CoreStorage = (*Store)(nil) 26 | _ oauth2.TokenRevocationStorage = (*Store)(nil) 27 | ) 28 | 29 | const defaultTTL = 24 * time.Hour 30 | 31 | type mockClientManager interface { //nolint:unused // used to generate mock 32 | fosite.ClientManager 33 | } 34 | 35 | type Store struct { 36 | redisClient *redis.Client 37 | clientManager fosite.ClientManager 38 | } 39 | 40 | func NewStore(client *redis.Client, clientManager fosite.ClientManager) *Store { 41 | return &Store{ 42 | redisClient: client, 43 | clientManager: clientManager, 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /component/oidc/fosite/redis/pkce.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package redis 8 | 9 | import ( 10 | "context" 11 | "errors" 12 | 13 | "github.com/ory/fosite" 14 | "github.com/redis/go-redis/v9" 15 | 16 | "github.com/trustbloc/vcs/component/oidc/fosite/dto" 17 | ) 18 | 19 | func (s *Store) CreatePKCERequestSession(ctx context.Context, signature string, requester fosite.Requester) error { 20 | return s.createSession(ctx, dto.PkceSessionSegment, signature, requester, defaultTTL) 21 | } 22 | 23 | func (s *Store) DeletePKCERequestSession(ctx context.Context, signature string) error { 24 | signatureBasedKey := resolveRedisKey(dto.PkceSessionSegment, signature) 25 | 26 | intermediateKey, err := s.redisClient.API().Get(ctx, signatureBasedKey).Result() 27 | if err != nil { 28 | if errors.Is(err, redis.Nil) { 29 | // If intermediateKey is not accessible - consider that the session is already deleted. 30 | return nil 31 | } 32 | 33 | return err 34 | } 35 | 36 | return s.redisClient.API().Del(ctx, intermediateKey, signatureBasedKey).Err() 37 | } 38 | 39 | func (s *Store) GetPKCERequestSession( 40 | ctx context.Context, 41 | signature string, 42 | session fosite.Session, 43 | ) (fosite.Requester, error) { 44 | return s.getSession(ctx, dto.PkceSessionSegment, signature, session) 45 | } 46 | -------------------------------------------------------------------------------- /component/oidc/fosite/redis/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package redis 8 | 9 | import ( 10 | "encoding/json" 11 | "time" 12 | ) 13 | 14 | type genericDocument[T any] struct { 15 | Record T `json:"record"` 16 | ExpireAt time.Time `json:"expireAt,omitempty"` 17 | } 18 | 19 | func (d *genericDocument[T]) MarshalBinary() ([]byte, error) { 20 | return json.Marshal(d) 21 | } 22 | 23 | func (d *genericDocument[T]) UnmarshalBinary(data []byte) error { 24 | return json.Unmarshal(data, d) 25 | } 26 | -------------------------------------------------------------------------------- /component/otp/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/trustbloc/vcs/component/otp 2 | 3 | go 1.22 4 | 5 | require github.com/stretchr/testify v1.8.1 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.1 // indirect 9 | github.com/pmezard/go-difflib v1.0.0 // indirect 10 | gopkg.in/yaml.v3 v3.0.1 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /component/otp/pin.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package otp 8 | 9 | import ( 10 | "fmt" 11 | "math/rand" 12 | "strings" 13 | ) 14 | 15 | const ( 16 | maxNumber = 10 17 | ) 18 | 19 | // PinGenerator implements logic for generating and verifying otp pin codes. 20 | type PinGenerator struct { 21 | } 22 | 23 | // NewPinGenerator creates a new instance of PinGenerator. 24 | func NewPinGenerator() *PinGenerator { 25 | return &PinGenerator{} 26 | } 27 | 28 | // Generate generates a new pin based on challenge 29 | func (p *PinGenerator) Generate(_ string) string { 30 | var finalPin strings.Builder 31 | 32 | for i := 0; i < 6; i++ { 33 | finalPin.WriteString(fmt.Sprint(rand.Int31n(maxNumber))) //nolint:gosec 34 | } 35 | 36 | return finalPin.String() 37 | } 38 | 39 | // Validate validates pin 40 | func (p *PinGenerator) Validate(challenge string, userInput string) bool { // in future there will be more implementations 41 | return challenge == userInput 42 | } 43 | -------------------------------------------------------------------------------- /component/otp/pin_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package otp 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestPinGenerator(t *testing.T) { 16 | gen := NewPinGenerator() 17 | for i := 0; i < 100; i++ { 18 | assert.Len(t, gen.Generate(""), 6) 19 | } 20 | } 21 | 22 | func TestPinGeneratorVerify(t *testing.T) { 23 | gen := NewPinGenerator() 24 | 25 | t.Run("success", func(t *testing.T) { 26 | assert.True(t, gen.Validate("123", "123")) 27 | }) 28 | 29 | t.Run("fail", func(t *testing.T) { 30 | assert.False(t, gen.Validate("1234", "123")) 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /component/profile/reader/file/internal.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package file 8 | 9 | import profileapi "github.com/trustbloc/vcs/pkg/profile" 10 | 11 | var createdIssuers = map[string]*profileapi.Issuer{} // nolint:gochecknoglobals 12 | -------------------------------------------------------------------------------- /component/wallet-cli/internal/formatter/jwt.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package formatter 8 | 9 | import ( 10 | "fmt" 11 | "io" 12 | "strings" 13 | ) 14 | 15 | type JWTFormatter struct{} 16 | 17 | // Match JSON media type. 18 | func (j *JWTFormatter) Match(mediatype string) bool { 19 | return strings.HasPrefix(mediatype, "application/jwt") 20 | } 21 | 22 | // Format JSON content. 23 | func (j *JWTFormatter) Format(w io.Writer, src []byte) error { 24 | _, err := w.Write(src) 25 | if err != nil { 26 | return fmt.Errorf("unable to write JWT: %w", err) 27 | } 28 | 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /component/wallet-cli/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package main 8 | 9 | import ( 10 | "log/slog" 11 | 12 | "github.com/spf13/cobra" 13 | 14 | "github.com/trustbloc/vcs/component/wallet-cli/cmd" 15 | ) 16 | 17 | func main() { 18 | rootCmd := &cobra.Command{ 19 | Use: "wallet-cli", 20 | Short: "Wallet CLI", 21 | Long: "Wallet CLI is a testing tool that emulates Wallet in OIDC4VCI/OIDC4VP flows.", 22 | Run: func(cmd *cobra.Command, args []string) { 23 | cmd.HelpFunc()(cmd, args) 24 | }, 25 | } 26 | 27 | rootCmd.AddCommand(cmd.NewCreateWalletCommand()) 28 | rootCmd.AddCommand(cmd.NewAttestWalletCommand()) 29 | rootCmd.AddCommand(cmd.NewOIDC4VCICommand()) 30 | rootCmd.AddCommand(cmd.NewOIDC4VPCommand()) 31 | rootCmd.AddCommand(cmd.NewRefreshCmd()) 32 | 33 | if err := rootCmd.Execute(); err != nil { 34 | slog.Error("failed to run wallet-cli", "err", err) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /component/wallet-cli/pkg/attestation/models.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Gen Digital Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package attestation 8 | 9 | type AttestWalletInitRequest struct { 10 | Payload map[string]interface{} `json:"payload"` 11 | } 12 | 13 | type AttestWalletInitResponse struct { 14 | Challenge string `json:"challenge"` 15 | SessionID string `json:"session_id"` 16 | } 17 | 18 | type AttestWalletCompleteRequest struct { 19 | AssuranceLevel string `json:"assurance_level"` 20 | Proof Proof `json:"proof"` 21 | SessionID string `json:"session_id"` 22 | } 23 | 24 | type Proof struct { 25 | Jwt string `json:"jwt,omitempty"` 26 | ProofType string `json:"proof_type"` 27 | } 28 | 29 | type JwtProofClaims struct { 30 | Issuer string `json:"iss,omitempty"` 31 | Audience string `json:"aud,omitempty"` 32 | IssuedAt int64 `json:"iat,omitempty"` 33 | Nonce string `json:"nonce,omitempty"` 34 | Exp int64 `json:"exp,omitempty"` 35 | } 36 | 37 | type AttestWalletCompleteResponse struct { 38 | WalletAttestationVC string `json:"wallet_attestation_vc"` 39 | } 40 | 41 | type GetAttestationRequest struct { 42 | Audience string 43 | Nonce string 44 | AttestationType string 45 | AuthorizationHeaderValue string 46 | } 47 | -------------------------------------------------------------------------------- /component/wallet-cli/pkg/consent/interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package consent 8 | 9 | import "net/http" 10 | 11 | //go:generate mockgen -destination interfaces_mocks_test.go -package consent_test -source=interfaces.go 12 | type httpClient interface { 13 | Do(req *http.Request) (*http.Response, error) 14 | } 15 | -------------------------------------------------------------------------------- /component/wallet-cli/pkg/signer/jws_signer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Gen Digital Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package signer 8 | 9 | import ( 10 | "github.com/trustbloc/kms-go/doc/jose" 11 | 12 | "github.com/trustbloc/vcs/pkg/doc/vc" 13 | ) 14 | 15 | type JWSSigner struct { 16 | keyID string 17 | signingAlgorithm string 18 | signer vc.SignerAlgorithm 19 | } 20 | 21 | func NewJWSSigner(keyID string, signingAlgorithm string, signer vc.SignerAlgorithm) *JWSSigner { 22 | return &JWSSigner{ 23 | keyID: keyID, 24 | signingAlgorithm: signingAlgorithm, 25 | signer: signer, 26 | } 27 | } 28 | 29 | // Sign signs data. 30 | func (s *JWSSigner) Sign(data []byte) ([]byte, error) { 31 | return s.signer.Sign(data) 32 | } 33 | 34 | // Headers provides JWS headers. 35 | // "alg" header must be provided (see https://tools.ietf.org/html/rfc7515#section-4.1). 36 | func (s *JWSSigner) Headers() jose.Headers { 37 | return jose.Headers{ 38 | jose.HeaderKeyID: s.keyID, 39 | jose.HeaderAlgorithm: s.signingAlgorithm, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /component/wallet-cli/testdata/example/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustbloc/vcs/e8fcdb8eddaafa8f40485d979b360dd359245d16/component/wallet-cli/testdata/example/qrcode.png -------------------------------------------------------------------------------- /component/wallet-cli/testdata/vcs/permanent_resident_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/citizenship/v1" 5 | ], 6 | "id": "https://issuer.oidp.uscis.gov/credentials/83627465", 7 | "type": [ 8 | "VerifiableCredential", 9 | "PermanentResidentCard" 10 | ], 11 | "name": "Permanent Resident Card", 12 | "description": "Permanent Resident Card", 13 | "issuer": "did:example:28394728934792387", 14 | "issuanceDate": "2019-12-03T12:19:52Z", 15 | "expirationDate": "2029-12-03T12:19:52Z", 16 | "credentialSubject": { 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "givenName": "JOHN", 23 | "familyName": "SMITH", 24 | "gender": "Male", 25 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 26 | "residentSince": "2015-01-01", 27 | "lprCategory": "C09", 28 | "lprNumber": "999-999-999", 29 | "commuterClassification": "C1", 30 | "birthCountry": "Bahamas", 31 | "birthDate": "1958-07-17" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /component/wallet-cli/testdata/vcs/university_degree.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1" 5 | ], 6 | "type": [ 7 | "VerifiableCredential", 8 | "UniversityDegreeCredential" 9 | ], 10 | "id": "http://example.gov/credentials/3732", 11 | "issuanceDate": "2020-03-16T22:37:26.544Z", 12 | "issuer": { 13 | "id": "did:example:oakek12as93mas91220dapop092", 14 | "name": "University" 15 | }, 16 | "credentialSubject": { 17 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 18 | "degree": { 19 | "type": "BachelorDegree", 20 | "degree": "MIT" 21 | }, 22 | "name": "Jayden Doe", 23 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 24 | } 25 | } -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vcs 8 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | VCS API 7 | 8 | 9 |
10 | 28 | 29 | -------------------------------------------------------------------------------- /images/mocks/attestation/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright Avast Software. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | ARG GO_VER 8 | ARG GO_IMAGE 9 | ARG ALPINE_VER 10 | 11 | FROM ${GO_IMAGE}:${GO_VER}-alpine${ALPINE_VER} as builder 12 | 13 | RUN apk update && apk add git && apk add ca-certificates 14 | RUN adduser -D -g '' appuser 15 | COPY . $GOPATH/src/github.com/trustbloc/vcs/test/bdd/attestation/ 16 | WORKDIR $GOPATH/src/github.com/trustbloc/vcs/test/bdd/attestation/ 17 | ARG GO_PROXY 18 | RUN GOPROXY=${GO_PROXY} CGO_ENABLED=0 go build -o /usr/bin/mock-attestation 19 | 20 | FROM scratch 21 | 22 | LABEL org.opencontainers.image.source https://github.com/trustbloc/vcs/test/bdd/attestation 23 | 24 | COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 25 | COPY --from=builder /etc/passwd /etc/passwd 26 | COPY --from=builder /usr/bin/mock-attestation /usr/bin/mock-attestation 27 | USER appuser 28 | 29 | ENTRYPOINT ["/usr/bin/mock-attestation"] 30 | -------------------------------------------------------------------------------- /images/mocks/cognito-auth/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | ARG GO_VER 8 | ARG GO_IMAGE 9 | ARG ALPINE_VER 10 | ARG ALPINE_IMAGE 11 | 12 | FROM ${GO_IMAGE}:${GO_VER}-alpine${ALPINE_VER} as golang 13 | RUN apk add --no-cache \ 14 | gcc \ 15 | musl-dev \ 16 | git \ 17 | libtool \ 18 | bash \ 19 | make; 20 | ADD . $GOPATH/src/github.com/trustbloc/vcs 21 | WORKDIR $GOPATH/src/github.com/trustbloc/vcs 22 | ENV EXECUTABLES go git 23 | 24 | FROM golang as vcs 25 | ARG GO_TAGS 26 | ARG GO_PROXY 27 | RUN GO_TAGS=${GO_TAGS} GOPROXY=${GO_PROXY} make sample-cognito-auth 28 | 29 | 30 | FROM ${ALPINE_IMAGE}:${ALPINE_VER} as base 31 | COPY --from=vcs /go/src/github.com/trustbloc/vcs/build/bin/cognito-auth-server /usr/local/bin 32 | CMD COGNITO_CLIENT_ID=${COGNITO_CLIENT_ID} \ 33 | COGNITO_CLIENT_SECRET=${COGNITO_CLIENT_SECRET} \ 34 | COGNITO_ENDPOINT=${COGNITO_ENDPOINT} \ 35 | AWS_REGION=${AWS_REGION} \ 36 | HOST_URL=${HOST_URL} \ 37 | cognito-auth-server 38 | -------------------------------------------------------------------------------- /images/mocks/loginconsent/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright Avast Software. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | ARG GO_VER 8 | ARG GO_IMAGE 9 | ARG ALPINE_VER 10 | 11 | FROM ${GO_IMAGE}:${GO_VER}-alpine${ALPINE_VER} as builder 12 | 13 | RUN apk update && apk add git && apk add ca-certificates 14 | RUN adduser -D -g '' appuser 15 | COPY . $GOPATH/src/github.com/trustbloc/vcs/test/bdd/loginconsent/ 16 | WORKDIR $GOPATH/src/github.com/trustbloc/vcs/test/bdd/loginconsent/ 17 | ARG GO_PROXY 18 | RUN GOPROXY=${GO_PROXY} CGO_ENABLED=0 go build -o /usr/bin/mock-login-consent 19 | 20 | FROM scratch 21 | 22 | LABEL org.opencontainers.image.source https://github.com/trustbloc/vcs/test/bdd/loginconsent 23 | 24 | COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 25 | COPY --from=builder /etc/passwd /etc/passwd 26 | COPY --from=builder /usr/bin/mock-login-consent /usr/bin/mock-login-consent 27 | USER appuser 28 | 29 | ENTRYPOINT ["/usr/bin/mock-login-consent"] 30 | -------------------------------------------------------------------------------- /images/mocks/trustregistry/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright Avast Software. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | ARG GO_VER 8 | ARG GO_IMAGE 9 | ARG ALPINE_VER 10 | 11 | FROM ${GO_IMAGE}:${GO_VER}-alpine${ALPINE_VER} as builder 12 | 13 | RUN apk update && apk add git && apk add ca-certificates 14 | RUN adduser -D -g '' appuser 15 | COPY . $GOPATH/src/github.com/trustbloc/vcs/test/bdd/trustregistry/ 16 | WORKDIR $GOPATH/src/github.com/trustbloc/vcs/test/bdd/trustregistry/ 17 | ARG GO_PROXY 18 | RUN GOPROXY=${GO_PROXY} CGO_ENABLED=0 go build -o /usr/bin/mock-trustregistry 19 | 20 | FROM scratch 21 | 22 | LABEL org.opencontainers.image.source https://github.com/trustbloc/vcs/test/bdd/trustregistry 23 | 24 | COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 25 | COPY --from=builder /etc/passwd /etc/passwd 26 | COPY --from=builder /usr/bin/mock-trustregistry /usr/bin/mock-trustregistry 27 | USER appuser 28 | 29 | ENTRYPOINT ["/usr/bin/mock-trustregistry"] 30 | -------------------------------------------------------------------------------- /images/mocks/webhook/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | ARG GO_VER 8 | ARG GO_IMAGE 9 | ARG ALPINE_VER 10 | ARG ALPINE_IMAGE 11 | 12 | FROM ${GO_IMAGE}:${GO_VER}-alpine${ALPINE_VER} as golang 13 | RUN apk add --no-cache \ 14 | gcc \ 15 | musl-dev \ 16 | git \ 17 | libtool \ 18 | bash \ 19 | make; 20 | ADD . $GOPATH/src/github.com/trustbloc/vcs 21 | WORKDIR $GOPATH/src/github.com/trustbloc/vcs 22 | ENV EXECUTABLES go git 23 | 24 | FROM golang as vcs 25 | ARG GO_TAGS 26 | ARG GO_PROXY 27 | RUN GO_TAGS=${GO_TAGS} GOPROXY=${GO_PROXY} make sample-webhook 28 | 29 | 30 | FROM ${ALPINE_IMAGE}:${ALPINE_VER} as base 31 | COPY --from=vcs /go/src/github.com/trustbloc/vcs/build/bin/webhook-server /usr/local/bin 32 | CMD WEBHOOK_PORT=${WEBHOOK_PORT} webhook-server 33 | -------------------------------------------------------------------------------- /images/vc-rest/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | ARG GO_VER 8 | ARG GO_ALPINE_VER 9 | ARG ALPINE_VER 10 | 11 | FROM golang:${GO_VER}-alpine${GO_ALPINE_VER} as golang 12 | RUN apk add --no-cache \ 13 | gcc \ 14 | musl-dev \ 15 | git \ 16 | libtool \ 17 | bash \ 18 | make; 19 | ADD . src/github.com/trustbloc/vcs 20 | WORKDIR src/github.com/trustbloc/vcs 21 | ENV EXECUTABLES go git 22 | 23 | FROM golang as vcs 24 | ARG GO_PROXY 25 | RUN GOPROXY=${GO_PROXY} make vc-rest 26 | 27 | 28 | FROM alpine:${ALPINE_VER} as base 29 | LABEL org.opencontainers.image.source https://github.com/trustbloc/vcs 30 | COPY --from=vcs /go/src/github.com/trustbloc/vcs/.build/bin/vc-rest /usr/local/bin 31 | 32 | ENTRYPOINT ["vc-rest"] -------------------------------------------------------------------------------- /images/vcs-stress/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | ARG GO_VER 8 | ARG GO_ALPINE_VER 9 | ARG ALPINE_VER 10 | 11 | FROM golang:${GO_VER}-alpine${GO_ALPINE_VER} as golang 12 | RUN apk add --no-cache \ 13 | gcc \ 14 | musl-dev \ 15 | git \ 16 | libtool \ 17 | bash \ 18 | make; 19 | ADD . src/github.com/trustbloc/vcs 20 | WORKDIR src/github.com/trustbloc/vcs 21 | ENV EXECUTABLES go git 22 | 23 | FROM golang as vcs 24 | ARG GO_PROXY 25 | RUN GOPROXY=${GO_PROXY} make vcs-stress 26 | 27 | 28 | FROM alpine:${ALPINE_VER} as base 29 | LABEL org.opencontainers.image.source https://github.com/trustbloc/vcs-stress 30 | 31 | COPY --from=vcs /go/src/github.com/trustbloc/vcs/.build/bin/vcs-stress /usr/local/bin 32 | 33 | ENTRYPOINT ["vcs-stress"] 34 | -------------------------------------------------------------------------------- /internal/utils/map.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package utils 8 | 9 | import "encoding/json" 10 | 11 | func ExtractKeys(prefix string, m map[string]interface{}) []string { 12 | var keys []string 13 | for k, v := range m { 14 | fullKey := prefix + "." + k 15 | keys = append(keys, fullKey) 16 | 17 | switch nestedVal := v.(type) { //nolint:gocritic 18 | case map[string]interface{}: 19 | subKeys := ExtractKeys(fullKey, nestedVal) 20 | keys = append(keys, subKeys...) 21 | } 22 | } 23 | return keys 24 | } 25 | 26 | func StructureToMap(obj interface{}) (map[string]interface{}, error) { 27 | b, err := json.Marshal(obj) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | var result map[string]interface{} 33 | 34 | err = json.Unmarshal(b, &result) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | return result, nil 40 | } 41 | -------------------------------------------------------------------------------- /internal/utils/map_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package utils_test 8 | 9 | import ( 10 | "sort" 11 | "testing" 12 | 13 | "github.com/stretchr/testify/assert" 14 | 15 | "github.com/trustbloc/vcs/internal/utils" 16 | ) 17 | 18 | func TestExtract(t *testing.T) { 19 | claimData := map[string]interface{}{ 20 | "claim": map[string]interface{}{ 21 | "value": map[string]interface{}{ 22 | "xx": "example", 23 | "yy": map[string]interface{}{ 24 | "zz": "nested example", 25 | }, 26 | }, 27 | "anotherKey": "anotherValue", 28 | }, 29 | } 30 | 31 | keys := utils.ExtractKeys("$", claimData) 32 | 33 | sort.Strings(keys) 34 | 35 | assert.EqualValues(t, []string{ 36 | "$.claim", 37 | "$.claim.anotherKey", 38 | "$.claim.value", 39 | "$.claim.value.xx", 40 | "$.claim.value.yy", 41 | "$.claim.value.yy.zz", 42 | }, keys) 43 | } 44 | 45 | func TestStructureToMap(t *testing.T) { 46 | type testStruct struct { 47 | Field1 string `json:"field1"` 48 | Field2 int `json:"field2"` 49 | } 50 | 51 | m, err := utils.StructureToMap(testStruct{Field1: "value1", Field2: 100}) 52 | assert.NoError(t, err) 53 | assert.EqualValues(t, map[string]interface{}{ 54 | "field1": "value1", 55 | "field2": float64(100), 56 | }, m) 57 | } 58 | -------------------------------------------------------------------------------- /pkg/dataprotect/aes_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect_test 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | 14 | "github.com/trustbloc/vcs/pkg/dataprotect" 15 | ) 16 | 17 | func TestEncryptDecrypt(t *testing.T) { 18 | aes := dataprotect.NewAES(256) 19 | var finalData []byte 20 | for len(finalData) < 2000000 { 21 | finalData = append(finalData, []byte("This is a secret message")...) 22 | } 23 | 24 | ciphertext, key, err := aes.Encrypt(finalData) 25 | if err != nil { 26 | t.Fatalf("Error encrypting data: %v", err) 27 | } 28 | 29 | plaintext, err := aes.Decrypt(ciphertext, key) 30 | if err != nil { 31 | t.Fatalf("Error decrypting data: %v", err) 32 | } 33 | 34 | assert.Equal(t, finalData, plaintext) 35 | } 36 | 37 | func TestTooLongKey(t *testing.T) { 38 | aes := dataprotect.NewAES(512) 39 | ciphertext, key, err := aes.Encrypt([]byte("This is a secret message")) 40 | assert.Empty(t, ciphertext) 41 | assert.Empty(t, key) 42 | assert.ErrorContains(t, err, "invalid key size 64") 43 | } 44 | -------------------------------------------------------------------------------- /pkg/dataprotect/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect 8 | 9 | import "context" 10 | 11 | type Protector interface { 12 | Encrypt(ctx context.Context, msg []byte) (*EncryptedData, error) 13 | Decrypt(ctx context.Context, encryptedData *EncryptedData) ([]byte, error) 14 | } 15 | -------------------------------------------------------------------------------- /pkg/dataprotect/gzip.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect 8 | 9 | import ( 10 | "bytes" 11 | "compress/gzip" 12 | "io" 13 | ) 14 | 15 | type GZip struct { 16 | } 17 | 18 | func NewGzip() *GZip { 19 | return &GZip{} 20 | } 21 | 22 | // Compress takes a byte slice and returns a gzip compressed byte slice. 23 | func (g *GZip) Compress(input []byte) ([]byte, error) { 24 | var compressedData bytes.Buffer 25 | gzipWriter := gzip.NewWriter(&compressedData) 26 | 27 | _, err := gzipWriter.Write(input) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | err = gzipWriter.Close() 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | return compressedData.Bytes(), nil 38 | } 39 | 40 | // Decompress takes a gzip compressed byte slice and returns a decompressed byte slice. 41 | func (g *GZip) Decompress(input []byte) ([]byte, error) { 42 | gzipReader, err := gzip.NewReader(bytes.NewReader(input)) 43 | if err != nil { 44 | return nil, err 45 | } 46 | defer func() { 47 | _ = gzipReader.Close() 48 | }() 49 | 50 | data, err := io.ReadAll(gzipReader) 51 | if err != nil { 52 | return nil, err 53 | } 54 | 55 | return data, nil 56 | } 57 | -------------------------------------------------------------------------------- /pkg/dataprotect/gzip_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect_test 8 | 9 | import ( 10 | "bytes" 11 | "testing" 12 | 13 | "github.com/trustbloc/vcs/pkg/dataprotect" 14 | ) 15 | 16 | func TestGZipCompressDecompress(t *testing.T) { 17 | gzipProcessor := &dataprotect.GZip{} 18 | testData := []byte("This is a sample text to demonstrate GZip compression and decompression in Golang." + 19 | "p[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['") 20 | 21 | compressedData, err := gzipProcessor.Compress(testData) 22 | if err != nil { 23 | t.Errorf("Failed to compress data: %v", err) 24 | } 25 | 26 | if len(compressedData) >= len(testData) { 27 | t.Errorf("Compressed data should be smaller than original data") 28 | } 29 | 30 | decompressedData, err := gzipProcessor.Decompress(compressedData) 31 | if err != nil { 32 | t.Errorf("Failed to decompress data: %v", err) 33 | } 34 | 35 | if !bytes.Equal(decompressedData, testData) { 36 | t.Errorf("Decompressed data does not match original data") 37 | } 38 | } 39 | 40 | func TestGZipDecompressError(t *testing.T) { 41 | gzipProcessor := &dataprotect.GZip{} 42 | testData := []byte("This is not a valid compressed data") 43 | 44 | _, err := gzipProcessor.Decompress(testData) 45 | if err == nil { 46 | t.Errorf("Decompress should return an error when decompressing invalid data") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pkg/dataprotect/nilcrypto.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect 8 | 9 | import "context" 10 | 11 | type NilDataProtector struct { 12 | } 13 | 14 | func NewNilDataProtector() *NilDataProtector { 15 | return &NilDataProtector{} 16 | } 17 | 18 | func (n *NilDataProtector) Encrypt(_ context.Context, msg []byte) (*EncryptedData, error) { 19 | return &EncryptedData{ 20 | Encrypted: msg, 21 | EncryptedKey: nil, 22 | EncryptedNonce: nil, 23 | }, nil 24 | } 25 | 26 | func (n *NilDataProtector) Decrypt(_ context.Context, encryptedData *EncryptedData) ([]byte, error) { 27 | return encryptedData.Encrypted, nil 28 | } 29 | -------------------------------------------------------------------------------- /pkg/dataprotect/nilcrypto_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect_test 8 | 9 | import ( 10 | "context" 11 | "testing" 12 | 13 | "github.com/stretchr/testify/assert" 14 | 15 | "github.com/trustbloc/vcs/pkg/dataprotect" 16 | ) 17 | 18 | func TestNilDataProtectorEncryptDecrypt(t *testing.T) { 19 | nilDataProtector := dataprotect.NewNilDataProtector() 20 | testData := []byte("This is a sample text to demonstrate the NilDataProtector encryption and decryption process.") 21 | 22 | encryptedData, err := nilDataProtector.Encrypt(context.Background(), testData) 23 | assert.NoError(t, err, "Failed to encrypt data") 24 | assert.Equal(t, testData, encryptedData.Encrypted, "Encrypted data should be the same as original data") 25 | 26 | decryptedData, err := nilDataProtector.Decrypt(context.Background(), encryptedData) 27 | assert.NoError(t, err, "Failed to decrypt data") 28 | assert.Equal(t, testData, decryptedData, "Decrypted data should be the same as original data") 29 | } 30 | -------------------------------------------------------------------------------- /pkg/dataprotect/nilzip.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect 8 | 9 | type NilZip struct { 10 | } 11 | 12 | func NewNilZip() *NilZip { 13 | return &NilZip{} 14 | } 15 | 16 | func (g *NilZip) Compress(input []byte) ([]byte, error) { 17 | return input, nil 18 | } 19 | 20 | func (g *NilZip) Decompress(input []byte) ([]byte, error) { 21 | return input, nil 22 | } 23 | -------------------------------------------------------------------------------- /pkg/dataprotect/nilzip_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect_test 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | 14 | "github.com/trustbloc/vcs/pkg/dataprotect" 15 | ) 16 | 17 | func TestNullZipCompress(t *testing.T) { 18 | data := []byte("Your test data here...") 19 | 20 | nullZip := dataprotect.NewNilZip() 21 | compressed, err := nullZip.Compress(data) 22 | 23 | assert.NoError(t, err, "Compress should not return an error") 24 | assert.Equal(t, data, compressed, "Compressed data should be equal to the input data") 25 | } 26 | 27 | func TestNullZipDecompress(t *testing.T) { 28 | data := []byte("Your test data here...") 29 | 30 | nullZip := dataprotect.NewNilZip() 31 | decompressed, err := nullZip.Decompress(data) 32 | 33 | assert.NoError(t, err, "Decompress should not return an error") 34 | assert.Equal(t, data, decompressed, "Decompressed data should be equal to the input data") 35 | } 36 | -------------------------------------------------------------------------------- /pkg/dataprotect/zip.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect 8 | 9 | import "strings" 10 | 11 | func NewCompressor(algo string) DataCompressor { 12 | switch strings.ToLower(algo) { 13 | case "gzip": 14 | return NewGzip() 15 | case "zstd": 16 | return NewZStd() 17 | default: 18 | return NewNilZip() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pkg/dataprotect/zip_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect_test 8 | 9 | import ( 10 | "fmt" 11 | "testing" 12 | 13 | "github.com/stretchr/testify/assert" 14 | 15 | "github.com/trustbloc/vcs/pkg/dataprotect" 16 | ) 17 | 18 | // Rest of the tests (TestNullZipCompress, TestNullZipDecompress, TestZStdCompress, TestZStdDecompress) 19 | 20 | func TestNewCompressor(t *testing.T) { 21 | tests := []struct { 22 | name string 23 | algo string 24 | wantType string 25 | }{ 26 | {"NilZip", "unknown", "*dataprotect.NilZip"}, 27 | {"Gzip", "gzip", "*dataprotect.GZip"}, 28 | {"ZStd", "zstd", "*dataprotect.ZStd"}, 29 | } 30 | 31 | for _, tt := range tests { 32 | t.Run(tt.name, func(t *testing.T) { 33 | compressor := dataprotect.NewCompressor(tt.algo) 34 | assert.NotNil(t, compressor, "Compressor should not be nil") 35 | assert.Equal(t, tt.wantType, fmt.Sprintf("%T", compressor), "Compressor type should match the expected type") 36 | }) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pkg/dataprotect/zstd.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect 8 | 9 | import ( 10 | "fmt" 11 | 12 | "github.com/klauspost/compress/zstd" 13 | ) 14 | 15 | type ZStd struct { 16 | } 17 | 18 | func NewZStd() *ZStd { 19 | return &ZStd{} 20 | } 21 | 22 | func (g *ZStd) Compress(input []byte) ([]byte, error) { 23 | compressor, err := zstd.NewWriter(nil) 24 | if err != nil { 25 | return nil, err 26 | } 27 | 28 | return compressor.EncodeAll(input, nil), nil 29 | } 30 | 31 | func (g *ZStd) Decompress(input []byte) ([]byte, error) { 32 | decompressor, err := zstd.NewReader(nil) 33 | if err != nil { 34 | return nil, fmt.Errorf("error creating zstd decompressor: %w", err) 35 | } 36 | defer decompressor.Close() 37 | 38 | decompressedData, err := decompressor.DecodeAll(input, nil) 39 | if err != nil { 40 | return nil, fmt.Errorf("error reading decompressed data: %w", err) 41 | } 42 | 43 | return decompressedData, nil 44 | } 45 | -------------------------------------------------------------------------------- /pkg/dataprotect/zstd_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dataprotect_test 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | 14 | "github.com/trustbloc/vcs/pkg/dataprotect" 15 | ) 16 | 17 | func TestZStdCompress(t *testing.T) { 18 | data := []byte("Your test data here...") 19 | 20 | zstd := dataprotect.NewZStd() 21 | compressed, err := zstd.Compress(data) 22 | 23 | assert.NoError(t, err, "Compress should not return an error") 24 | assert.NotEqual(t, data, compressed, "Compressed data should not be equal to the input data") 25 | 26 | resp, err := zstd.Decompress(compressed) 27 | assert.NoError(t, err) 28 | assert.Equal(t, data, resp) 29 | } 30 | 31 | func TestZStdDecompress(t *testing.T) { 32 | data := []byte("Your test data here...") 33 | 34 | zstd := dataprotect.NewZStd() 35 | compressed, _ := zstd.Compress(data) 36 | decompressed, err := zstd.Decompress(compressed) 37 | 38 | assert.NoError(t, err, "Decompress should not return an error") 39 | assert.Equal(t, data, decompressed, "Decompressed data should be equal to the input data") 40 | } 41 | -------------------------------------------------------------------------------- /pkg/doc/validator/jsonschema/testdata/invalid.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$id": "https://trustbloc.com/universitydegree.schema.json", 3 | "$schema": "https://json-schema.org/draft/2020-12/schema", 4 | "title": "UniversityDegreeCredential", 5 | "type": "object", 6 | "properties": { 7 | "alumniOf": { 8 | "type": "invalid" 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /pkg/doc/validator/jsonschema/testdata/sample_invalid_university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "alumniOf": { 3 | "id": "did:example:c276e12ec21ebfeb1f712ebc6f1" 4 | }, 5 | "degree": { 6 | "type": "BachelorDegree", 7 | "name": "Bachelor of Science and Arts" 8 | } 9 | } -------------------------------------------------------------------------------- /pkg/doc/validator/jsonschema/testdata/sample_university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "alumniOf": { 3 | "id": "did:example:c276e12ec21ebfeb1f712ebc6f1", 4 | "name": [ 5 | { 6 | "value": "Example University", 7 | "lang": "en" 8 | }, 9 | { 10 | "value": "Exemple d'Université", 11 | "lang": "fr" 12 | } 13 | ] 14 | }, 15 | "degree": { 16 | "type": "BachelorDegree", 17 | "name": "Bachelor of Science and Arts" 18 | } 19 | } -------------------------------------------------------------------------------- /pkg/doc/validator/jsonschema/testdata/universitydegree.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$id": "https://trustbloc.com/universitydegree.schema.json", 3 | "$schema": "https://json-schema.org/draft/2020-12/schema", 4 | "title": "UniversityDegreeCredential", 5 | "type": "object", 6 | "properties": { 7 | "alumniOf": { 8 | "type": "object", 9 | "description": "Describes the university.", 10 | "properties": { 11 | "id": { 12 | "type": "string" 13 | }, 14 | "name": { 15 | "type": "array", 16 | "description": "A list of language-specific names.", 17 | "items": { 18 | "type": "object", 19 | "properties": { 20 | "value": { 21 | "type": "string" 22 | }, 23 | "lang": { 24 | "type": "string" 25 | } 26 | }, 27 | "required": ["value", "lang"] 28 | }, 29 | "minItems": 1 30 | } 31 | }, 32 | "required": ["id", "name"] 33 | }, 34 | "degree": { 35 | "type": "object", 36 | "description": "Describes the degree.", 37 | "properties": { 38 | "type": { 39 | "type": "string" 40 | }, 41 | "name": { 42 | "type": "string" 43 | } 44 | }, 45 | "required": ["type","name"] 46 | } 47 | }, 48 | "required": ["alumniOf","degree"] 49 | } -------------------------------------------------------------------------------- /pkg/doc/vc/dataIntegrity.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vc 8 | 9 | // DataIntegrityProofConfig represents the Data Integrity LDP config. 10 | type DataIntegrityProofConfig struct { 11 | // Enable flag enables Data Integrity Proof feature. 12 | Enable bool `json:"enable"` 13 | // SuiteType is the data integrity Type identifier for the suite. 14 | SuiteType string `json:"suiteType"` 15 | } 16 | -------------------------------------------------------------------------------- /pkg/doc/vc/jws/signer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package jws 8 | 9 | import ( 10 | "github.com/trustbloc/kms-go/doc/jose" 11 | ) 12 | 13 | type signer interface { 14 | Sign(data []byte) ([]byte, error) 15 | } 16 | 17 | type Signer struct { 18 | keyID string 19 | jwsAlgorithm string 20 | signer signer 21 | } 22 | 23 | func NewSigner(keyID string, jwsAlgorithm string, signer signer) *Signer { 24 | return &Signer{ 25 | keyID: keyID, 26 | jwsAlgorithm: jwsAlgorithm, 27 | signer: signer, 28 | } 29 | } 30 | 31 | // Sign signs data. 32 | func (s *Signer) Sign(data []byte) ([]byte, error) { 33 | return s.signer.Sign(data) 34 | } 35 | 36 | // Headers provides JWS headers. "alg" header must be provided (see https://tools.ietf.org/html/rfc7515#section-4.1) 37 | func (s *Signer) Headers() jose.Headers { 38 | return jose.Headers{ 39 | jose.HeaderKeyID: s.keyID, 40 | jose.HeaderAlgorithm: s.jwsAlgorithm, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pkg/doc/vc/sdjwt.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vc 8 | 9 | import ( 10 | "crypto" 11 | 12 | "github.com/trustbloc/vc-go/sdjwt/common" 13 | ) 14 | 15 | // SDJWT represents the SD-JWT configuration. 16 | type SDJWT struct { 17 | Enable bool `json:"enable,omitempty"` 18 | HashAlg crypto.Hash `json:"hashAlg,omitempty"` 19 | Version common.SDJWTVersion `json:"version,omitempty"` 20 | } 21 | -------------------------------------------------------------------------------- /pkg/doc/vc/signer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vc 8 | 9 | import ( 10 | "github.com/trustbloc/kms-go/spi/kms" 11 | "github.com/trustbloc/vc-go/verifiable" 12 | 13 | vcsverifiable "github.com/trustbloc/vcs/pkg/doc/verifiable" 14 | ) 15 | 16 | type keyManager interface { 17 | NewVCSigner(creator string, signatureType vcsverifiable.SignatureType) (SignerAlgorithm, error) 18 | } 19 | 20 | type SignerAlgorithm interface { 21 | Sign(data []byte) ([]byte, error) 22 | Alg() string 23 | } 24 | 25 | // Signer contains information about vc signer, usually this is credential issuer. 26 | type Signer struct { 27 | DID string // didResolution.DIDDocument.ID. 28 | Creator string // didResolution.DIDDocument.ID + "#" + authentication.ID. 29 | KMSKeyID string // authentication.ID. 30 | SignatureType vcsverifiable.SignatureType // issuer.vcConfig.signingAlgorithm. 31 | KeyType kms.KeyType 32 | Format vcsverifiable.Format // VC format - LDP/JWT. 33 | SignatureRepresentation verifiable.SignatureRepresentation // For LDP only - proof/JWS. 34 | KMS keyManager 35 | VCStatusListType StatusType // Type of VC status list 36 | SDJWT SDJWT 37 | DataIntegrityProof DataIntegrityProofConfig 38 | } 39 | -------------------------------------------------------------------------------- /pkg/doc/vc/testdata/sample_vc.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/ns/credentials/v2", 4 | "https://w3id.org/citizenship/v2" 5 | ], 6 | "validFrom": "2019-12-03T12:19:52Z", 7 | "validUntil": "2029-12-03T12:19:52Z", 8 | "credentialSubject": { 9 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 10 | "lprNumber": "999-999-999", 11 | "gender": "Male", 12 | "residentSince": "2015-01-01", 13 | "givenName": "JOHN", 14 | "familyName": "SMITH", 15 | "birthCountry": "Bahamas", 16 | "id": "did:example:b34ca6cd37bbf23", 17 | "commuterClassification": "C1", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "birthDate": "1958-07-17", 23 | "lprCategory": "C09" 24 | }, 25 | "name": "Permanent Resident Card", 26 | "description": "Permanent Resident Card", 27 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c#13250913-eb53-4418-9077-fb429f6b033f", 28 | "type": [ 29 | "VerifiableCredential", 30 | "PermanentResidentCard" 31 | ], 32 | "issuer": "did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN" 33 | } 34 | -------------------------------------------------------------------------------- /pkg/doc/vc/testdata/sample_vc.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIn0.eyJleHAiOjIxNDc0ODM2NDAsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L2Jicy92MSJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiZXhwaXJhdGlvbkRhdGUiOiIyMDM4LTAxLTE5VDAzOjE0OjAwWiIsImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImlzc3VlciI6eyJpZCI6ImRpZDpleGFtcGxlOjc2ZTEyZWM3MTJlYmM2ZjFjMjIxZWJmZWIxZiIsIm5hbWUiOiJFeGFtcGxlIFVuaXZlcnNpdHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ. -------------------------------------------------------------------------------- /pkg/doc/vc/testdata/sample_vc.sdjwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpleGFtcGxlOjc2ZTEyZWM3MTJlYmM2ZjFjMjIxZWJmZWIxZiNrZXlzLTEifQ.eyJleHAiOjEuNTc3OTA2NjA0ZSswOSwiaWF0IjoxLjI2MjM3MzgwNGUrMDksImlzcyI6ImRpZDpleGFtcGxlOjc2ZTEyZWM3MTJlYmM2ZjFjMjIxZWJmZWIxZiIsIm5iZiI6MS4yNjIzNzM4MDRlKzA5LCJzdWIiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sIl9zZF9hbGciOiJzaGEtMjU2IiwiY3JlZGVudGlhbFN1YmplY3QiOnsiX3NkIjpudWxsLCJkZWdyZWUiOnsiX3NkIjpbIlhKdlNVc1hwdmhOZ053MHJIOGExQWRVSUZId19COWtKUHVXYzZNSG5PbWMiXX0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIn0sImV4cGlyYXRpb25EYXRlIjoiMjAyMC0wMS0wMVQxOToyMzoyNFoiLCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImlzc3VlciI6eyJpZCI6ImRpZDpleGFtcGxlOjc2ZTEyZWM3MTJlYmM2ZjFjMjIxZWJmZWIxZiIsIm5hbWUiOiJFeGFtcGxlIFVuaXZlcnNpdHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ.xrOH-DZKflOK2GYWdR9-MgZUu7-0d_I1W3AE_IzlKjjgsNkveNKSrSnpJbOlJbze4TZjK9Z4oynkQmAhYOc_Ag~WyJ0X0tGNTBiY18tU1J0cUl0YmdWdzh3IiwidHlwZSIsIkJhY2hlbG9yRGVncmVlIl0 -------------------------------------------------------------------------------- /pkg/doc/vc/testdata/sample_vc_expired.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJleHAiOjE1Nzc5MDY2MDQsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L2Jicy92MSJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwidW5pdmVyc2l0eSI6Ik1JVCJ9LCJpZCI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsIm5hbWUiOiJKYXlkZW4gRG9lIiwic3BvdXNlIjoiZGlkOmV4YW1wbGU6YzI3NmUxMmVjMjFlYmZlYjFmNzEyZWJjNmYxIn0sImV4cGlyYXRpb25EYXRlIjoiMjAyMC0wMS0wMVQxOToyMzoyNFoiLCJpZCI6Imh0dHA6Ly9leGFtcGxlLmVkdS9jcmVkZW50aWFscy8xODcyIiwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQxOToyMzoyNFoiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6ZXhhbXBsZTo3NmUxMmVjNzEyZWJjNmYxYzIyMWViZmViMWYiLCJuYW1lIjoiRXhhbXBsZSBVbml2ZXJzaXR5In0sInJlZmVyZW5jZU51bWJlciI6OC4zMjk0ODQ3ZSswNywidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ. -------------------------------------------------------------------------------- /pkg/doc/vc/testdata/sample_vc_invalid.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIn0.eyJleHAiOjE3MDc2NTgzOTcsImlhdCI6MTY3NjEyMjQwOSwiaXNzIjoiZGlkOm9yYjp1QUFBOkVpRFV4UURkbWlSWHh5c25xNnk1M21ETHhjVkNWS1BiVWJ0YlZkaE5WM0V1VGciLCJqdGkiOiJ1cm46dXVpZDpiMWQ0ZjBhMC03YTg2LTQ1MzctOGYwNS04NzM5MTNjMGE4ZTkiLCJuYmYiOjE2NzYxMjI0MDksInN1YiI6ImRpZDpvcmI6dUFBQTpFaUFnTE5QY0hXeVRScENmbnBUdk1vbG5TUFI1QzczWFJRVWtLMEhKTmF5QWtnIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy9leGFtcGxlcy92MSJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOiJNSVQiLCJkZWdyZWVTY2hvb2wiOiJNSVQgc2Nob29sIiwiZGlzcGxheU5hbWUiOiJKb2huIERvZSIsImdpdmVuTmFtZSI6IkpvaG4iLCJpZCI6ImRpZDpvcmI6dUFBQTpFaUFnTE5QY0hXeVRScENmbnBUdk1vbG5TUFI1QzczWFJRVWtLMEhKTmF5QWtnIn0sImV4cGlyYXRpb25EYXRlIjoiMjAyNC0wMi0xMVQxMzozMzoxNy4xNDJaIiwiaWQiOiJ1cm46dXVpZDpiMWQ0ZjBhMC03YTg2LTQ1MzctOGYwNS04NzM5MTNjMGE4ZTkiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTAyLTExVDEzOjMzOjI5LjcyNzE2NzU0NloiLCJpc3N1ZXIiOiJkaWQ6b3JiOnVBQUE6RWlEVXhRRGRtaVJYeHlzbnE2eTUzbURMeGNWQ1ZLUGJVYnRiVmRoTlYzRXVUZyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJWZXJpZmllZEVtcGxveWVlIl19fQ. -------------------------------------------------------------------------------- /pkg/doc/vp/testdata/sample_vp.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1", 5 | "https://trustbloc.github.io/context/vc/examples-v1.jsonld", 6 | "https://w3id.org/vc/status-list/2021/v1", 7 | "https://w3id.org/security/suites/jws-2020/v1" 8 | ], 9 | "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", 10 | "type": "VerifiablePresentation", 11 | "verifiableCredential": [ 12 | { 13 | "@context": [ 14 | "https://www.w3.org/2018/credentials/v1", 15 | "https://www.w3.org/2018/credentials/examples/v1" 16 | ], 17 | "id": "http://example.edu/credentials/58473", 18 | "type": ["VerifiableCredential", "UniversityDegreeCredential"], 19 | "issuer": "https://example.edu/issuers/14", 20 | "issuanceDate": "2010-01-01T19:23:24Z", 21 | "credentialSubject": { 22 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 23 | "alumniOf": "Example University" 24 | }, 25 | "proof": { 26 | "type": "RsaSignature2018" 27 | } 28 | } 29 | ], 30 | "holder": "did:trustblock:abc" 31 | } -------------------------------------------------------------------------------- /pkg/doc/vp/testdata/sample_vp.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIn0.eyJpc3MiOiJkaWQ6dHJ1c3RibG9jazphYmMiLCJqdGkiOiJ1cm46dXVpZDozOTc4MzQ0Zi04NTk2LTRjM2EtYTk3OC04ZmNhYmEzOTAzYzUiLCJ2cCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIiwiaHR0cHM6Ly90cnVzdGJsb2MuZ2l0aHViLmlvL2NvbnRleHQvdmMvZXhhbXBsZXMtdjEuanNvbmxkIiwiaHR0cHM6Ly93M2lkLm9yZy92Yy9zdGF0dXMtbGlzdC8yMDIxL3YxIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwiaG9sZGVyIjoiZGlkOnRydXN0YmxvY2s6YWJjIiwiaWQiOiJ1cm46dXVpZDozOTc4MzQ0Zi04NTk2LTRjM2EtYTk3OC04ZmNhYmEzOTAzYzUiLCJ0eXBlIjoiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiIsInZlcmlmaWFibGVDcmVkZW50aWFsIjpbeyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImFsdW1uaU9mIjoiRXhhbXBsZSBVbml2ZXJzaXR5IiwiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEifSwiaWQiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvNTg0NzMiLCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImlzc3VlciI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvaXNzdWVycy8xNCIsInByb29mIjp7InR5cGUiOiJSc2FTaWduYXR1cmUyMDE4In0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVbml2ZXJzaXR5RGVncmVlQ3JlZGVudGlhbCJdfV19fQ. -------------------------------------------------------------------------------- /pkg/doc/vp/validate.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vp 8 | 9 | import ( 10 | "fmt" 11 | 12 | "github.com/trustbloc/vc-go/verifiable" 13 | 14 | vcsverifiable "github.com/trustbloc/vcs/pkg/doc/verifiable" 15 | ) 16 | 17 | func ValidatePresentation(pres interface{}, formats []vcsverifiable.Format, 18 | opts ...verifiable.PresentationOpt) (*verifiable.Presentation, error) { 19 | vpBytes, err := vcsverifiable.ValidateFormat(pres, formats) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | presentation, err := verifiable.ParsePresentation(vpBytes, opts...) 25 | if err != nil { 26 | return nil, fmt.Errorf("parse presentation: %w", err) 27 | } 28 | 29 | return presentation, nil 30 | } 31 | -------------------------------------------------------------------------------- /pkg/event/spi/spi_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package spi 8 | 9 | import ( 10 | "encoding/json" 11 | "testing" 12 | 13 | "github.com/stretchr/testify/require" 14 | ) 15 | 16 | func TestEvent(t *testing.T) { 17 | event := NewEvent("id", "source", "type") 18 | require.NotNil(t, event) 19 | 20 | payload, err := json.Marshal(map[string]interface{}{"k1": "v1"}) 21 | require.NoError(t, err) 22 | 23 | eventWithPayload := NewEventWithPayload("id", "source", "type", payload) 24 | require.NotNil(t, eventWithPayload) 25 | 26 | eventCopy := event.Copy() 27 | require.NotNil(t, eventCopy) 28 | } 29 | -------------------------------------------------------------------------------- /pkg/internal/common/support/httphandler.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package support 8 | 9 | import ( 10 | "net/http" 11 | ) 12 | 13 | // Handler http handler for each controller API endpoint. 14 | type Handler interface { 15 | Path() string 16 | Method() string 17 | Handle() http.HandlerFunc 18 | } 19 | 20 | // NewHTTPHandler returns instance of HTTPHandler which can be used to handle http requests. 21 | func NewHTTPHandler(path, method string, handle http.HandlerFunc) *HTTPHandler { 22 | return &HTTPHandler{path: path, method: method, handle: handle} 23 | } 24 | 25 | // HTTPHandler contains REST API handling details which can be used to build routers 26 | // for http requests for given path. 27 | type HTTPHandler struct { 28 | path string 29 | method string 30 | handle http.HandlerFunc 31 | } 32 | 33 | // Path returns http request path. 34 | func (h *HTTPHandler) Path() string { 35 | return h.path 36 | } 37 | 38 | // Method returns http request method type. 39 | func (h *HTTPHandler) Method() string { 40 | return h.method 41 | } 42 | 43 | // Handle returns http request handle func. 44 | func (h *HTTPHandler) Handle() http.HandlerFunc { 45 | return h.handle 46 | } 47 | -------------------------------------------------------------------------------- /pkg/internal/common/support/httphandler_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package support 8 | 9 | import ( 10 | "net/http" 11 | "testing" 12 | "time" 13 | 14 | "github.com/stretchr/testify/require" 15 | ) 16 | 17 | func TestNewHTTPHandler(t *testing.T) { 18 | path := "/sample-path" 19 | method := "GET" 20 | handled := make(chan bool) 21 | handlerFn := func(_ http.ResponseWriter, _ *http.Request) { 22 | // do nothing 23 | handled <- true 24 | } 25 | 26 | handler := NewHTTPHandler(path, method, handlerFn) 27 | require.Equal(t, path, handler.Path()) 28 | require.Equal(t, method, handler.Method()) 29 | require.NotNil(t, handler.Handle()) 30 | 31 | go handler.Handle()(nil, nil) 32 | 33 | select { 34 | case res := <-handled: 35 | require.True(t, res) 36 | case <-time.After(2 * time.Second): 37 | t.Fatal("handler function didn't get executed") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /pkg/internal/mock/storage/store.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package storage 8 | 9 | import ( 10 | "github.com/trustbloc/kms-go/spi/storage" 11 | ) 12 | 13 | // MockProvider is a mock edge storage provider that can hold several stores, not just one. 14 | type MockProvider struct { 15 | Stores map[string]storage.Store 16 | OpenErr error 17 | CloseErr error 18 | } 19 | 20 | // OpenStore opens the store. 21 | func (m *MockProvider) OpenStore(name string) (storage.Store, error) { 22 | if m.OpenErr != nil { 23 | return nil, m.OpenErr 24 | } 25 | 26 | s, exists := m.Stores[name] 27 | if !exists { 28 | return nil, storage.ErrStoreNotFound 29 | } 30 | 31 | return s, nil 32 | } 33 | 34 | // SetStoreConfig is not implemented. 35 | func (m *MockProvider) SetStoreConfig(_ string, _ storage.StoreConfiguration) error { 36 | panic("implement me") 37 | } 38 | 39 | // GetStoreConfig is not implemented. 40 | func (m *MockProvider) GetStoreConfig(_ string) (storage.StoreConfiguration, error) { 41 | panic("implement me") 42 | } 43 | 44 | // GetOpenStores is not implemented. 45 | func (m *MockProvider) GetOpenStores() []storage.Store { 46 | panic("implement me") 47 | } 48 | 49 | // Close all stores. 50 | func (m *MockProvider) Close() error { 51 | return m.CloseErr 52 | } 53 | -------------------------------------------------------------------------------- /pkg/internal/testutil/contexts/credentials-examples_v2.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@vocab": "https://www.w3.org/ns/credentials/examples#" 4 | } 5 | } -------------------------------------------------------------------------------- /pkg/internal/testutil/contexts/examples_v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@version": 1.1, 4 | 5 | "id": "@id", 6 | "type": "@type", 7 | 8 | "ex": "https://example.org/examples#", 9 | 10 | "image": {"@id": "http://schema.org/image", "@type": "@id"}, 11 | 12 | "CredentialStatusList2017": "ex:CredentialStatusList2017", 13 | "DocumentVerification": "ex:DocumentVerification", 14 | "SupportingActivity": "ex:SupportingActivity" 15 | } 16 | } -------------------------------------------------------------------------------- /pkg/internal/testutil/contexts/wallet_attestation_vc_v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@version": 1.1, 4 | "id": "@id", 5 | "type": "@type", 6 | "WalletAttestationCredential": "ex:WalletAttestationCredential", 7 | 8 | "key_type": "ex:key_type", 9 | "user_authentication": "ex:user_authentication", 10 | "assurance_level": "ex:assurance_level" 11 | } 12 | } -------------------------------------------------------------------------------- /pkg/kms/kms.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | //go:generate mockgen -destination mocks/kms_mocks.go -self_package mocks -package mocks -source=kms.go -mock_names VCSKeyManager=MockVCSKeyManager 8 | 9 | package kms 10 | 11 | import ( 12 | "net/http" 13 | 14 | "github.com/trustbloc/kms-go/doc/jose/jwk" 15 | "github.com/trustbloc/kms-go/spi/kms" 16 | 17 | "github.com/trustbloc/vcs/pkg/doc/vc" 18 | vcsverifiable "github.com/trustbloc/vcs/pkg/doc/verifiable" 19 | ) 20 | 21 | type Type string 22 | 23 | const ( 24 | AWS Type = "aws" 25 | Local Type = "local" 26 | Web Type = "web" 27 | ) 28 | 29 | // Config configure kms that stores signing keys. 30 | type Config struct { 31 | KMSType Type `json:"kmsType"` 32 | Endpoint string 33 | Region string 34 | AliasPrefix string 35 | HTTPClient *http.Client 36 | 37 | SecretLockKeyPath string 38 | DBType string 39 | DBURL string 40 | DBName string 41 | MasterKey string 42 | } 43 | 44 | type VCSKeyManager interface { 45 | SupportedKeyTypes() []kms.KeyType 46 | CreateJWKKey(keyType kms.KeyType) (string, *jwk.JWK, error) 47 | CreateCryptoKey(keyType kms.KeyType) (string, interface{}, error) 48 | NewVCSigner(creator string, signatureType vcsverifiable.SignatureType) (vc.SignerAlgorithm, error) 49 | } 50 | -------------------------------------------------------------------------------- /pkg/kms/registry.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package kms 8 | 9 | type Registry struct { 10 | defaultVCSKeyManager VCSKeyManager 11 | defaultConfig Config 12 | defaultMetricProvider metricsProvider 13 | } 14 | 15 | func NewRegistry( 16 | defaultVCSKeyManager VCSKeyManager, 17 | defaultKmsConfig Config, 18 | defaultMetricProvider metricsProvider, 19 | ) *Registry { 20 | return &Registry{ 21 | defaultConfig: defaultKmsConfig, 22 | defaultVCSKeyManager: defaultVCSKeyManager, 23 | defaultMetricProvider: defaultMetricProvider, 24 | } 25 | } 26 | 27 | func (r *Registry) GetKeyManager(config *Config) (VCSKeyManager, error) { 28 | if config == nil { 29 | return r.defaultVCSKeyManager, nil 30 | } 31 | 32 | cfgCopy := r.defaultConfig 33 | cfgCopy.KMSType = config.KMSType 34 | if config.MasterKey != "" { 35 | cfgCopy.MasterKey = config.MasterKey 36 | } 37 | 38 | return NewAriesKeyManager(&cfgCopy, r.defaultMetricProvider) 39 | } 40 | -------------------------------------------------------------------------------- /pkg/kms/registry_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package kms_test 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/require" 13 | 14 | "github.com/trustbloc/vcs/pkg/kms" 15 | ) 16 | 17 | func TestNewRegistry(t *testing.T) { 18 | r := kms.NewRegistry(nil, kms.Config{}, nil) 19 | require.NotNil(t, r) 20 | } 21 | 22 | func TestRegistry_GetKeyManager(t *testing.T) { 23 | t.Run("Default config local kms", func(t *testing.T) { 24 | r := kms.NewRegistry(nil, kms.Config{KMSType: kms.Local}, nil) 25 | require.NotNil(t, r) 26 | 27 | _, err := r.GetKeyManager(nil) 28 | require.NoError(t, err) 29 | }) 30 | 31 | t.Run("Fallback kms", func(t *testing.T) { 32 | r := kms.NewRegistry(nil, kms.Config{KMSType: kms.Local}, nil) 33 | require.NotNil(t, r) 34 | 35 | _, err := r.GetKeyManager(&kms.Config{ 36 | KMSType: "aws", 37 | }) 38 | 39 | require.NoError(t, err) 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/kms/resolver.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package kms 8 | 9 | import ( 10 | "context" 11 | "net/url" 12 | 13 | "github.com/aws/aws-sdk-go-v2/service/kms" 14 | transport "github.com/aws/smithy-go/endpoints" 15 | ) 16 | 17 | // EndpointResolver resolves the endpoint. 18 | type EndpointResolver struct { 19 | Endpoint string 20 | } 21 | 22 | // ResolveEndpoint resolves the endpoint. 23 | func (e *EndpointResolver) ResolveEndpoint( 24 | _ context.Context, 25 | _ kms.EndpointParameters, 26 | ) (transport.Endpoint, error) { 27 | targetURL, err := url.Parse(e.Endpoint) 28 | if err != nil { 29 | return transport.Endpoint{}, err 30 | } 31 | 32 | return transport.Endpoint{ 33 | URI: *targetURL, 34 | }, nil 35 | } 36 | -------------------------------------------------------------------------------- /pkg/kms/resolver_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package kms_test 8 | 9 | import ( 10 | "context" 11 | "testing" 12 | 13 | "github.com/aws/aws-sdk-go-v2/service/kms" 14 | "github.com/stretchr/testify/assert" 15 | 16 | kms2 "github.com/trustbloc/vcs/pkg/kms" 17 | ) 18 | 19 | func TestResolver(t *testing.T) { 20 | ep := &kms2.EndpointResolver{ 21 | Endpoint: "http://localhost", 22 | } 23 | 24 | resp, err := ep.ResolveEndpoint(context.TODO(), kms.EndpointParameters{}) 25 | assert.NoError(t, err) 26 | assert.NotNil(t, resp) 27 | 28 | assert.Equal(t, "localhost", resp.URI.Host) 29 | } 30 | -------------------------------------------------------------------------------- /pkg/ld/document_loader.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package ld 8 | 9 | import ( 10 | _ "embed" //nolint:gci // required for go:embed 11 | "fmt" 12 | 13 | jsonld "github.com/piprate/json-gold/ld" 14 | ldcontext "github.com/trustbloc/did-go/doc/ld/context" 15 | lddocloader "github.com/trustbloc/did-go/doc/ld/documentloader" 16 | ldstore "github.com/trustbloc/did-go/doc/ld/store" 17 | ) 18 | 19 | // nolint:gochecknoglobals //embedded contexts 20 | var ( 21 | //go:embed contexts/lds-jws2020-v1.jsonld 22 | jws2020V1Vocab []byte 23 | ) 24 | 25 | var embedContexts = []ldcontext.Document{ //nolint:gochecknoglobals 26 | { 27 | URL: "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 28 | Content: jws2020V1Vocab, 29 | }, 30 | } 31 | 32 | // provider contains dependencies for the JSON-LD document loader. 33 | type provider interface { 34 | JSONLDContextStore() ldstore.ContextStore 35 | JSONLDRemoteProviderStore() ldstore.RemoteProviderStore 36 | } 37 | 38 | // NewDocumentLoader returns a JSON-LD document loader with preloaded contexts. 39 | func NewDocumentLoader(p provider, opts ...lddocloader.Opts) (jsonld.DocumentLoader, error) { 40 | loader, err := lddocloader.NewDocumentLoader(p, append(opts, lddocloader.WithExtraContexts(embedContexts...))...) 41 | if err != nil { 42 | return nil, fmt.Errorf("new document loader: %w", err) 43 | } 44 | 45 | return loader, nil 46 | } 47 | -------------------------------------------------------------------------------- /pkg/lifecycle/lifecycle_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package lifecycle 8 | 9 | import ( 10 | "testing" 11 | 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestLifecycle(t *testing.T) { 16 | started := false 17 | stopped := false 18 | 19 | lc := New( 20 | "service1", 21 | WithStart(func() { 22 | started = true 23 | }), 24 | WithStop(func() { 25 | stopped = true 26 | }), 27 | ) 28 | require.NotNil(t, lc) 29 | 30 | require.Equal(t, StateNotStarted, lc.State()) 31 | 32 | lc.Start() 33 | require.True(t, started) 34 | require.Equal(t, StateStarted, lc.State()) 35 | 36 | require.NotPanics(t, lc.Start) 37 | 38 | lc.Stop() 39 | require.True(t, stopped) 40 | require.Equal(t, StateStopped, lc.State()) 41 | 42 | require.NotPanics(t, lc.Stop) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/observability/health/healthutil/json_result_writer_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package healthutil_test 8 | 9 | import ( 10 | "net/http" 11 | "net/http/httptest" 12 | "testing" 13 | "time" 14 | 15 | "github.com/alexliesenfeld/health" 16 | "github.com/stretchr/testify/require" 17 | 18 | "github.com/trustbloc/vcs/pkg/observability/health/healthutil" 19 | ) 20 | 21 | func TestResultWriter_Write(t *testing.T) { 22 | writer := healthutil.NewJSONResultWriter(map[string]healthutil.ResponseTimeState{ 23 | "up": { 24 | LastResponseTime: time.Millisecond, 25 | AverageResponseTime: time.Millisecond, 26 | }, 27 | }) 28 | 29 | rw := httptest.NewRecorder() 30 | now := time.Now() 31 | 32 | err := writer.Write(&health.CheckerResult{ 33 | Status: health.StatusUp, 34 | Details: map[string]health.CheckResult{ 35 | "up": { 36 | Status: health.StatusUp, 37 | Timestamp: now, 38 | }, 39 | "down": { 40 | Status: health.StatusDown, 41 | Timestamp: now, 42 | }, 43 | }, 44 | }, http.StatusOK, rw, nil) 45 | 46 | require.NoError(t, err) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/observability/health/healthutil/response_time_interceptor.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package healthutil 8 | 9 | import ( 10 | "context" 11 | "sync" 12 | "time" 13 | 14 | "github.com/alexliesenfeld/health" 15 | ) 16 | 17 | type ResponseTimeState struct { 18 | LastResponseTime time.Duration 19 | AverageResponseTime time.Duration 20 | } 21 | 22 | func ResponseTimeInterceptor(m map[string]ResponseTimeState) health.Interceptor { 23 | var mu sync.Mutex 24 | return func(next health.InterceptorFunc) health.InterceptorFunc { 25 | return func(ctx context.Context, name string, state health.CheckState) health.CheckState { 26 | now := time.Now() 27 | result := next(ctx, name, state) 28 | 29 | elapsed := time.Since(now) 30 | 31 | mu.Lock() 32 | defer mu.Unlock() 33 | 34 | if _, ok := m[name]; !ok { 35 | m[name] = ResponseTimeState{ 36 | LastResponseTime: elapsed, 37 | AverageResponseTime: elapsed, 38 | } 39 | } else { 40 | m[name] = ResponseTimeState{ 41 | LastResponseTime: elapsed, 42 | AverageResponseTime: (m[name].AverageResponseTime + elapsed) / 2, //nolint:mnd 43 | } 44 | } 45 | 46 | return result 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pkg/observability/health/healthutil/response_time_interceptor_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package healthutil_test 8 | 9 | import ( 10 | "context" 11 | "testing" 12 | 13 | "github.com/alexliesenfeld/health" 14 | "github.com/stretchr/testify/require" 15 | 16 | "github.com/trustbloc/vcs/pkg/observability/health/healthutil" 17 | ) 18 | 19 | func TestResponseTimeInterceptor(t *testing.T) { 20 | interceptor := healthutil.ResponseTimeInterceptor(map[string]healthutil.ResponseTimeState{ 21 | "test": { 22 | LastResponseTime: 0, 23 | AverageResponseTime: 0, 24 | }, 25 | }) 26 | 27 | next := &mockInterceptor{} 28 | 29 | interceptor(next.InterceptorFunc())(context.Background(), "test", health.CheckState{}) 30 | 31 | require.True(t, next.Called) 32 | } 33 | 34 | type mockInterceptor struct { 35 | Called bool 36 | } 37 | 38 | func (m *mockInterceptor) InterceptorFunc() health.InterceptorFunc { 39 | return func(_ context.Context, _ string, state health.CheckState) health.CheckState { 40 | m.Called = true 41 | return state 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pkg/observability/health/mongo/check.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongo 8 | 9 | import ( 10 | "context" 11 | "fmt" 12 | 13 | "go.mongodb.org/mongo-driver/mongo" 14 | "go.mongodb.org/mongo-driver/mongo/options" 15 | "go.mongodb.org/mongo-driver/mongo/readpref" 16 | ) 17 | 18 | func New(uri string) func(ctx context.Context) error { 19 | return func(ctx context.Context) error { 20 | client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) 21 | if err != nil { 22 | return err 23 | } 24 | 25 | if err = client.Ping(ctx, readpref.Primary()); err != nil { 26 | return fmt.Errorf("failed to ping mongodb: %w", err) 27 | } 28 | 29 | return client.Disconnect(ctx) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/observability/metrics/noop/provider.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package noop 8 | 9 | import ( 10 | "net/http" 11 | "time" 12 | 13 | "github.com/trustbloc/vcs/pkg/observability/metrics" 14 | ) 15 | 16 | // NoMetrics provides default no operation implementation for the NoMetrics interface. 17 | type NoMetrics struct{} 18 | 19 | // GetMetrics returns metrics implementation. 20 | func GetMetrics() metrics.Metrics { 21 | return &NoMetrics{} 22 | } 23 | 24 | func (n *NoMetrics) SignTime(_ time.Duration) {} 25 | func (n *NoMetrics) CheckAuthorizationResponseTime(_ time.Duration) {} 26 | func (n *NoMetrics) VerifyOIDCVerifiablePresentationTime(_ time.Duration) {} 27 | 28 | // InstrumentHTTPTransport simply returns the provided transport. 29 | func (n *NoMetrics) InstrumentHTTPTransport(_ metrics.ClientID, transport http.RoundTripper) http.RoundTripper { 30 | return transport 31 | } 32 | -------------------------------------------------------------------------------- /pkg/observability/metrics/noop/provider_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package noop 8 | 9 | import ( 10 | "net/http" 11 | "testing" 12 | "time" 13 | 14 | "github.com/stretchr/testify/require" 15 | 16 | "github.com/trustbloc/vcs/pkg/observability/metrics" 17 | ) 18 | 19 | func TestMetrics(t *testing.T) { 20 | m := GetMetrics() 21 | require.NotNil(t, m) 22 | 23 | t.Run("VCS Activity", func(t *testing.T) { 24 | require.NotPanics(t, func() { m.SignTime(time.Second) }) 25 | require.NotPanics(t, func() { m.CheckAuthorizationResponseTime(time.Second) }) 26 | require.NotPanics(t, func() { m.VerifyOIDCVerifiablePresentationTime(time.Second) }) 27 | }) 28 | } 29 | 30 | func TestMetrics_InstrumentHTTPTransport(t *testing.T) { 31 | m := GetMetrics() 32 | require.NotNil(t, m) 33 | 34 | t1 := http.DefaultTransport 35 | 36 | t2 := m.InstrumentHTTPTransport(metrics.ClientVerifierProfile, t1) 37 | require.NotNil(t, t2) 38 | require.True(t, t1 == t2) 39 | } 40 | -------------------------------------------------------------------------------- /pkg/observability/tracing/wrappers/credentialstatus/eventhandler/eventhandler_wrapper.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | //go:generate mockgen -destination gomocks_test.go -self_package mocks -package eventhandler -source=eventhandler_wrapper.go -mock_names service=MockEventHandler 8 | 9 | package eventhandler 10 | 11 | import ( 12 | "context" 13 | 14 | "go.opentelemetry.io/otel/attribute" 15 | "go.opentelemetry.io/otel/trace" 16 | 17 | "github.com/trustbloc/vcs/pkg/event/spi" 18 | ) 19 | 20 | var _ service = (*Wrapper)(nil) // make sure Wrapper implements service 21 | 22 | type service interface { 23 | HandleEvent(ctx context.Context, event *spi.Event) error 24 | } 25 | 26 | type Wrapper struct { 27 | svc service 28 | tracer trace.Tracer 29 | } 30 | 31 | func Wrap(svc service, tracer trace.Tracer) *Wrapper { 32 | return &Wrapper{svc: svc, tracer: tracer} 33 | } 34 | 35 | func (w *Wrapper) HandleEvent(ctx context.Context, event *spi.Event) error { 36 | spanCtx, span := w.tracer.Start(ctx, "credentialstatus.HandleEvent", trace.WithAttributes( 37 | attribute.KeyValue{Key: "event_id", Value: attribute.StringValue(event.ID)}, 38 | attribute.KeyValue{Key: "event_type", Value: attribute.StringValue(string(event.Type))}, 39 | )) 40 | defer span.End() 41 | 42 | err := w.svc.HandleEvent(spanCtx, event) 43 | if err != nil { 44 | span.RecordError(err) 45 | return err 46 | } 47 | 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /pkg/observability/tracing/wrappers/credentialstatus/eventhandler/eventhandler_wrapper_test.go: -------------------------------------------------------------------------------- 1 | /*CreateStatusListEntry 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package eventhandler 8 | 9 | import ( 10 | "context" 11 | "testing" 12 | 13 | "github.com/golang/mock/gomock" 14 | "github.com/stretchr/testify/require" 15 | "github.com/trustbloc/vcs/pkg/event/spi" 16 | nooptracer "go.opentelemetry.io/otel/trace/noop" 17 | ) 18 | 19 | func TestWrapper_HandleEvent(t *testing.T) { 20 | event := spi.NewEvent( 21 | "http://example.edu/credentials/1872", 22 | "test", 23 | spi.CredentialStatusStatusUpdated) 24 | 25 | ctrl := gomock.NewController(t) 26 | 27 | svc := NewMockEventHandler(ctrl) 28 | svc.EXPECT().HandleEvent(gomock.Any(), event).Times(1) 29 | 30 | w := Wrap(svc, nooptracer.NewTracerProvider().Tracer("")) 31 | 32 | err := w.HandleEvent(context.Background(), event) 33 | require.NoError(t, err) 34 | } 35 | -------------------------------------------------------------------------------- /pkg/observability/tracing/wrappers/issuecredential/issuecredential_wrapper_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | //nolint:lll 8 | package issuecredential 9 | 10 | import ( 11 | "context" 12 | "testing" 13 | 14 | "github.com/golang/mock/gomock" 15 | "github.com/stretchr/testify/require" 16 | "github.com/trustbloc/vc-go/verifiable" 17 | "github.com/trustbloc/vcs/pkg/profile" 18 | nooptracer "go.opentelemetry.io/otel/trace/noop" 19 | ) 20 | 21 | func TestWrapper_IssueCredential(t *testing.T) { 22 | ctrl := gomock.NewController(t) 23 | 24 | svc := NewMockService(ctrl) 25 | svc.EXPECT().IssueCredential(gomock.Any(), &verifiable.Credential{}, &profile.Issuer{}, nil).Times(1) 26 | 27 | w := Wrap(svc, nooptracer.NewTracerProvider().Tracer("")) 28 | 29 | _, err := w.IssueCredential(context.Background(), &verifiable.Credential{}, &profile.Issuer{}, nil) 30 | require.NoError(t, err) 31 | } 32 | -------------------------------------------------------------------------------- /pkg/observability/tracing/wrappers/verifypresentation/verifypresentation_wrapper_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | //nolint:lll 8 | package verifypresentation 9 | 10 | import ( 11 | "context" 12 | "testing" 13 | 14 | "github.com/golang/mock/gomock" 15 | "github.com/stretchr/testify/require" 16 | "github.com/trustbloc/vc-go/verifiable" 17 | profileapi "github.com/trustbloc/vcs/pkg/profile" 18 | "github.com/trustbloc/vcs/pkg/service/verifypresentation" 19 | nooptracer "go.opentelemetry.io/otel/trace/noop" 20 | ) 21 | 22 | func TestWrapper_VerifyPresentation(t *testing.T) { 23 | ctrl := gomock.NewController(t) 24 | 25 | svc := NewMockService(ctrl) 26 | svc.EXPECT().VerifyPresentation(gomock.Any(), &verifiable.Presentation{}, &verifypresentation.Options{}, &profileapi.Verifier{}).Times(1) 27 | 28 | w := Wrap(svc, nooptracer.NewTracerProvider().Tracer("")) 29 | 30 | _, _, err := w.VerifyPresentation(context.Background(), &verifiable.Presentation{}, &verifypresentation.Options{}, &profileapi.Verifier{}) 31 | require.NoError(t, err) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/restapi/common/common.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package common 8 | 9 | import "net/http" 10 | 11 | // HTTPRequestHandler is an HTTP handler. 12 | type HTTPRequestHandler func(http.ResponseWriter, *http.Request) 13 | 14 | // HTTPHandler is an HTTP handler descriptor containing the context path, method, and request handler. 15 | type HTTPHandler interface { 16 | Path() string 17 | Method() string 18 | Handler() HTTPRequestHandler 19 | } 20 | -------------------------------------------------------------------------------- /pkg/restapi/resterr/error.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package resterr 8 | 9 | import ( 10 | "errors" 11 | ) 12 | 13 | var ( 14 | ErrDataNotFound = errors.New("data not found") 15 | ErrProfileInactive = errors.New("profile not active") 16 | ErrProfileNotFound = errors.New("profile doesn't exist") 17 | ) 18 | -------------------------------------------------------------------------------- /pkg/restapi/resterr/event_error_codes.go: -------------------------------------------------------------------------------- 1 | package resterr 2 | 3 | type EventErrorCode = string 4 | 5 | //nolint:gosec 6 | const ( 7 | SystemError EventErrorCode = "system-error" 8 | InvalidValue EventErrorCode = "invalid-value" 9 | InvalidCredentialConfigurationID EventErrorCode = "invalid-credential-configuration-id" 10 | CredentialTypeNotSupported EventErrorCode = "credential-type-not-supported" 11 | CredentialFormatNotSupported EventErrorCode = "credential-format-not-supported" 12 | InvalidStateTransition EventErrorCode = "invalid-state-transition" 13 | ) 14 | -------------------------------------------------------------------------------- /pkg/restapi/resterr/oidc4ci/credential_status_endpoint.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | import ( 10 | "net/http" 11 | ) 12 | 13 | func NewForbiddenError(err error) *Error { 14 | return &Error{ 15 | ErrorCode: forbidden, 16 | Err: err, 17 | HTTPStatus: http.StatusForbidden, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pkg/restapi/resterr/oidc4ci/initiate_interaction.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | import ( 10 | "net/http" 11 | ) 12 | 13 | func NewUnauthorizedError(err error) *Error { 14 | return &Error{ 15 | ErrorCode: unauthorized, 16 | Err: err, 17 | HTTPStatus: http.StatusUnauthorized, 18 | } 19 | } 20 | 21 | func NewBadRequestError(err error) *Error { 22 | return &Error{ 23 | ErrorCode: badRequest, 24 | Err: err, 25 | HTTPStatus: http.StatusBadRequest, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pkg/restapi/resterr/oidc4ci/notification_endpoint.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | import ( 10 | "net/http" 11 | ) 12 | 13 | func NewInvalidNotificationIDError(err error) *Error { 14 | return &Error{ 15 | ErrorCode: invalidNotificationID, 16 | Err: err, 17 | HTTPStatus: http.StatusBadRequest, 18 | } 19 | } 20 | 21 | func NewExpiredAckIDError(err error) *Error { 22 | return &Error{ 23 | ErrorCode: expiredAckID, 24 | Err: err, 25 | HTTPStatus: http.StatusBadRequest, 26 | } 27 | } 28 | 29 | func NewInvalidNotificationRequestError(err error) *Error { 30 | return &Error{ 31 | ErrorCode: invalidNotificationRequest, 32 | Err: err, 33 | HTTPStatus: http.StatusBadRequest, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pkg/restapi/resterr/oidc4ci/request_object_endpoint.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | import ( 10 | "net/http" 11 | ) 12 | 13 | func NewNotFoundError(err error) *Error { 14 | return &Error{ 15 | ErrorCode: notFound, 16 | Err: err, 17 | HTTPStatus: http.StatusNotFound, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pkg/restapi/v1/common/openapi.cfg.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | package: common 8 | output: openapi.gen.go 9 | generate: 10 | models: true 11 | embedded-spec: true 12 | output-options: 13 | skip-prune: true -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/openapi.cfg.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | package: issuer 8 | output: openapi.gen.go 9 | generate: 10 | models: true 11 | echo-server: true 12 | client: true 13 | embedded-spec: false 14 | import-mapping: 15 | ./common.yaml: github.com/trustbloc/vcs/pkg/restapi/v1/common 16 | output-options: 17 | include-tags: 18 | - issuer 19 | -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/testdata/sample_invalid_vc_v2.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/ns/credentials/v2", 4 | "https://w3id.org/citizenship/v2" 5 | ], 6 | "validFrom": "2019-12-03T12:19:52Z", 7 | "validUntil": "2029-12-03T12:19:52Z", 8 | "credentialSubject": { 9 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 10 | "lprNumber": "999-999-999", 11 | "gender": "Male", 12 | "residentSince": "2015-01-01", 13 | "givenName": "JOHN", 14 | "familyName": "SMITH", 15 | "birthCountry": "Bahamas", 16 | "id": "did:example:b34ca6cd37bbf23", 17 | "invalidField": "C1", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "birthDate": "1958-07-17", 23 | "lprCategory": "C09" 24 | }, 25 | "name": "Permanent Resident Card", 26 | "description": "Permanent Resident Card", 27 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c#13250913-eb53-4418-9077-fb429f6b033f", 28 | "type": [ 29 | "VerifiableCredential", 30 | "PermanentResidentCard" 31 | ], 32 | "issuer": "did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN" 33 | } -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/testdata/sample_vc.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "credential": { 3 | "@context": [ 4 | "https://www.w3.org/ns/credentials/v2", 5 | "https://w3id.org/citizenship/v2" 6 | ], 7 | "validFrom": "2019-12-03T12:19:52Z", 8 | "validUntil": "2029-12-03T12:19:52Z", 9 | "credentialSubject": { 10 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 11 | "lprNumber": "999-999-999", 12 | "gender": "Male", 13 | "residentSince": "2015-01-01", 14 | "givenName": "JOHN", 15 | "familyName": "SMITH", 16 | "birthCountry": "Bahamas", 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "commuterClassification": "C1", 19 | "type": [ 20 | "PermanentResident", 21 | "Person" 22 | ], 23 | "birthDate": "1958-07-17", 24 | "lprCategory": "C09" 25 | }, 26 | "name": "Permanent Resident Card", 27 | "description": "Permanent Resident Card", 28 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c#13250913-eb53-4418-9077-fb429f6b033f", 29 | "type": [ 30 | "VerifiableCredential", 31 | "PermanentResidentCard" 32 | ], 33 | "issuer": "did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/testdata/sample_vc.jwt: -------------------------------------------------------------------------------- 1 | { 2 | "credential": "eyJhbGciOiJub25lIn0.eyJleHAiOjIxNDc0ODM2NDAsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L2Jicy92MSJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwidW5pdmVyc2l0eSI6Ik1JVCJ9LCJpZCI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsIm5hbWUiOiJKYXlkZW4gRG9lIiwic3BvdXNlIjoiZGlkOmV4YW1wbGU6YzI3NmUxMmVjMjFlYmZlYjFmNzEyZWJjNmYxIn0sImV4cGlyYXRpb25EYXRlIjoiMjAzOC0wMS0xOVQwMzoxNDowMFoiLCJpZCI6Imh0dHA6Ly9leGFtcGxlLmVkdS9jcmVkZW50aWFscy8xODcyIiwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQxOToyMzoyNFoiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6ZXhhbXBsZTo3NmUxMmVjNzEyZWJjNmYxYzIyMWViZmViMWYiLCJuYW1lIjoiRXhhbXBsZSBVbml2ZXJzaXR5In0sInJlZmVyZW5jZU51bWJlciI6OC4zMjk0ODQ3ZSswNywidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ." 3 | } 4 | -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/testdata/sample_vc_invalid_university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1", 5 | "https://w3id.org/security/bbs/v1" 6 | ], 7 | "credentialSchema": [], 8 | "credentialSubject": { 9 | "alumniOf": { 10 | "id": "did:example:c276e12ec21ebfeb1f712ebc6f1" 11 | }, 12 | "degree": { 13 | "type": "BachelorDegree", 14 | "name": "Bachelor of Science and Arts" 15 | } 16 | }, 17 | "expirationDate": "2038-01-19T03:14:00Z", 18 | "id": "http://example.edu/credentials/1872", 19 | "issuanceDate": "2010-01-01T19:23:24Z", 20 | "issuer": { 21 | "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", 22 | "name": "Example University" 23 | }, 24 | "referenceNumber": 83294847, 25 | "type": [ 26 | "VerifiableCredential", 27 | "UniversityDegreeCredential" 28 | ] 29 | } -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/testdata/sample_vc_university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1", 5 | "https://w3id.org/security/bbs/v1" 6 | ], 7 | "credentialSchema": [], 8 | "credentialSubject": { 9 | "alumniOf": { 10 | "id": "did:example:c276e12ec21ebfeb1f712ebc6f1", 11 | "name": [ 12 | { 13 | "value": "Example University", 14 | "lang": "en" 15 | }, 16 | { 17 | "value": "Exemple d'Université", 18 | "lang": "fr" 19 | } 20 | ] 21 | }, 22 | "degree": { 23 | "type": "BachelorDegree", 24 | "name": "Bachelor of Science and Arts" 25 | } 26 | }, 27 | "expirationDate": "2038-01-19T03:14:00Z", 28 | "id": "http://example.edu/credentials/1872", 29 | "issuanceDate": "2010-01-01T19:23:24Z", 30 | "issuer": { 31 | "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", 32 | "name": "Example University" 33 | }, 34 | "referenceNumber": 83294847, 35 | "type": [ 36 | "VerifiableCredential", 37 | "UniversityDegreeCredential" 38 | ] 39 | } -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/testdata/sample_vc_v2.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "credential": { 3 | "@context": [ 4 | "https://www.w3.org/ns/credentials/v2", 5 | "https://w3id.org/citizenship/v2" 6 | ], 7 | "validFrom": "2019-12-03T12:19:52Z", 8 | "validUntil": "2029-12-03T12:19:52Z", 9 | "credentialSubject": { 10 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 11 | "lprNumber": "999-999-999", 12 | "gender": "Male", 13 | "residentSince": "2015-01-01", 14 | "givenName": "JOHN", 15 | "familyName": "SMITH", 16 | "birthCountry": "Bahamas", 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "commuterClassification": "C1", 19 | "type": [ 20 | "PermanentResident", 21 | "Person" 22 | ], 23 | "birthDate": "1958-07-17", 24 | "lprCategory": "C09" 25 | }, 26 | "name": "Permanent Resident Card", 27 | "description": "Permanent Resident Card", 28 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c#13250913-eb53-4418-9077-fb429f6b033f", 29 | "type": [ 30 | "VerifiableCredential", 31 | "PermanentResidentCard" 32 | ], 33 | "issuer": "did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pkg/restapi/v1/issuer/testdata/universitydegree.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$id": "https://trustbloc.com/universitydegree.schema.json", 3 | "$schema": "https://json-schema.org/draft/2020-12/schema", 4 | "title": "UniversityDegreeCredential", 5 | "type": "object", 6 | "properties": { 7 | "alumniOf": { 8 | "type": "object", 9 | "description": "Describes the university.", 10 | "properties": { 11 | "id": { 12 | "type": "string" 13 | }, 14 | "name": { 15 | "type": "array", 16 | "description": "A list of language-specific names.", 17 | "items": { 18 | "type": "object", 19 | "properties": { 20 | "value": { 21 | "type": "string" 22 | }, 23 | "lang": { 24 | "type": "string" 25 | } 26 | }, 27 | "required": ["value", "lang"] 28 | }, 29 | "minItems": 1 30 | } 31 | }, 32 | "required": ["id", "name"] 33 | }, 34 | "degree": { 35 | "type": "object", 36 | "description": "Describes the degree.", 37 | "properties": { 38 | "type": { 39 | "type": "string" 40 | }, 41 | "name": { 42 | "type": "string" 43 | } 44 | }, 45 | "required": ["type","name"] 46 | } 47 | }, 48 | "required": ["alumniOf","degree"] 49 | } -------------------------------------------------------------------------------- /pkg/restapi/v1/logapi/controller.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package logapi 8 | 9 | import ( 10 | "fmt" 11 | "io" 12 | "net/http" 13 | 14 | "github.com/labstack/echo/v4" 15 | "github.com/trustbloc/logutil-go/pkg/log" 16 | ) 17 | 18 | //go:generate mockgen -destination controller_mocks_test.go -package logapi_test -source=controller.go 19 | 20 | var logger = log.New("logapi") 21 | 22 | type Controller struct { 23 | } 24 | 25 | type router interface { 26 | POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route 27 | } 28 | 29 | func NewController( 30 | router router, 31 | ) *Controller { 32 | c := &Controller{} 33 | 34 | router.POST("/loglevels", func(ctx echo.Context) error { 35 | return c.PostLogLevels(ctx) 36 | }) 37 | 38 | return c 39 | } 40 | 41 | // PostLogLevels updates log levels. 42 | // (POST /loglevels). 43 | func (c *Controller) PostLogLevels(ctx echo.Context) error { 44 | req := ctx.Request() 45 | 46 | logLevelBytes, err := io.ReadAll(req.Body) 47 | if err != nil { 48 | return fmt.Errorf("failed to read body: %w", err) 49 | } 50 | 51 | logLevels := string(logLevelBytes) 52 | 53 | if err := log.SetSpec(logLevels); err != nil { 54 | return fmt.Errorf("failed to set log spec: %w", err) 55 | } 56 | 57 | logger.Info(fmt.Sprintf("log levels modified to: %s", logLevels)) 58 | return ctx.NoContent(http.StatusOK) 59 | } 60 | -------------------------------------------------------------------------------- /pkg/restapi/v1/oidc4ci/ldp_proof.go: -------------------------------------------------------------------------------- 1 | package oidc4ci 2 | 3 | import "github.com/trustbloc/vc-go/verifiable" 4 | 5 | type DefaultLDPProofParser struct { 6 | } 7 | 8 | func NewDefaultLDPProofParser() *DefaultLDPProofParser { 9 | return &DefaultLDPProofParser{} 10 | } 11 | 12 | func (p *DefaultLDPProofParser) Parse( 13 | rawProof []byte, 14 | opt []verifiable.PresentationOpt, 15 | ) (*verifiable.Presentation, error) { 16 | return verifiable.ParsePresentation(rawProof, 17 | opt..., 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /pkg/restapi/v1/oidc4ci/models.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | // PushedAuthorizationRequest is a model with custom OIDC4CI-related fields for PAR. 10 | type PushedAuthorizationRequest struct { 11 | AuthorizationDetails string `form:"authorization_details"` 12 | OpState string `form:"op_state"` 13 | } 14 | 15 | type ProofClaims struct { 16 | Issuer string `json:"iss,omitempty" cbor:"1,keyasint"` 17 | Audience string `json:"aud,omitempty" cbor:"3,keyasint"` 18 | IssuedAt *int64 `json:"iat,omitempty" cbor:"6,keyasint"` 19 | Nonce string `json:"nonce,omitempty" cbor:"10,keyasint"` 20 | } 21 | -------------------------------------------------------------------------------- /pkg/restapi/v1/oidc4ci/openapi.cfg.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | package: oidc4ci 8 | output: openapi.gen.go 9 | generate: 10 | models: true 11 | echo-server: true 12 | embedded-spec: false 13 | import-mapping: 14 | ./common.yaml: github.com/trustbloc/vcs/pkg/restapi/v1/common 15 | output-options: 16 | include-tags: 17 | - oidc4ci 18 | -------------------------------------------------------------------------------- /pkg/restapi/v1/oidc4ci/types.go: -------------------------------------------------------------------------------- 1 | package oidc4ci 2 | 3 | type ProofHeaders struct { 4 | Type string 5 | KeyID string 6 | ProofType string 7 | } 8 | -------------------------------------------------------------------------------- /pkg/restapi/v1/oidc4vp/openapi.cfg.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | package: oidc4vp 8 | output: openapi.gen.go 9 | generate: 10 | models: true 11 | echo-server: true 12 | embedded-spec: false 13 | import-mapping: 14 | ./common.yaml: github.com/trustbloc/vcs/pkg/restapi/v1/common 15 | output-options: 16 | include-tags: 17 | - oidc4vp 18 | -------------------------------------------------------------------------------- /pkg/restapi/v1/refresh/openapi.cfg.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | package: refresh 8 | output: openapi.gen.go 9 | generate: 10 | models: true 11 | echo-server: true 12 | embedded-spec: false 13 | output-options: 14 | include-tags: 15 | - refresh 16 | -------------------------------------------------------------------------------- /pkg/restapi/v1/util/auth.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package util 8 | 9 | import ( 10 | "errors" 11 | 12 | "github.com/labstack/echo/v4" 13 | ) 14 | 15 | const ( 16 | tenantIDHeader = "X-Tenant-ID" 17 | ) 18 | 19 | func GetTenantIDFromRequest(e echo.Context) (string, error) { 20 | tenantID := e.Request().Header.Get(tenantIDHeader) 21 | if tenantID == "" { 22 | return "", errors.New("missing authorization") 23 | } 24 | 25 | return tenantID, nil 26 | } 27 | -------------------------------------------------------------------------------- /pkg/restapi/v1/util/bind.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package util 8 | 9 | import ( 10 | "encoding/json" 11 | "net/http" 12 | 13 | "github.com/labstack/echo/v4" 14 | ) 15 | 16 | func WriteOutput(ctx echo.Context) func(output interface{}, err error) error { 17 | return WriteOutputWithCode(http.StatusOK, ctx) 18 | } 19 | 20 | func WriteOutputWithCode(code int, ctx echo.Context) func(output interface{}, err error) error { 21 | return func(output interface{}, err error) error { 22 | if err != nil { 23 | return err 24 | } 25 | 26 | b, err := json.Marshal(output) 27 | if err != nil { 28 | return err 29 | } 30 | 31 | return ctx.JSONBlob(code, b) 32 | } 33 | } 34 | 35 | func WriteOutputWithContentType(ctx echo.Context) func(output interface{}, ct string, err error) error { 36 | return func(output interface{}, ct string, err error) error { 37 | if err != nil { 38 | return err 39 | } 40 | 41 | b, err := json.Marshal(output) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | return ctx.Blob(http.StatusOK, ct, b) 47 | } 48 | } 49 | 50 | func WriteRawOutputWithContentType(ctx echo.Context) func(output []byte, ct string, err error) error { 51 | return func(output []byte, ct string, err error) error { 52 | if err != nil { 53 | return err 54 | } 55 | 56 | return ctx.Blob(http.StatusOK, ct, output) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /pkg/restapi/v1/verifier/openapi.cfg.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | package: verifier 8 | output: openapi.gen.go 9 | generate: 10 | models: true 11 | echo-server: true 12 | embedded-spec: false 13 | import-mapping: 14 | ./common.yaml: github.com/trustbloc/vcs/pkg/restapi/v1/common 15 | output-options: 16 | include-tags: 17 | - verifier 18 | exclude-schemas: 19 | - PresentationDefinition 20 | -------------------------------------------------------------------------------- /pkg/restapi/v1/verifier/testdata/sample_vc_jsonld_request.json: -------------------------------------------------------------------------------- 1 | { 2 | "credential": { 3 | "@context": [ 4 | "https://www.w3.org/ns/credentials/v2", 5 | "https://w3id.org/citizenship/v2" 6 | ], 7 | "validFrom": "2019-12-03T12:19:52Z", 8 | "validUntil": "2029-12-03T12:19:52Z", 9 | "credentialSubject": { 10 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 11 | "lprNumber": "999-999-999", 12 | "gender": "Male", 13 | "residentSince": "2015-01-01", 14 | "givenName": "JOHN", 15 | "familyName": "SMITH", 16 | "birthCountry": "Bahamas", 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "commuterClassification": "C1", 19 | "type": [ 20 | "PermanentResident", 21 | "Person" 22 | ], 23 | "birthDate": "1958-07-17", 24 | "lprCategory": "C09" 25 | }, 26 | "name": "Permanent Resident Card", 27 | "description": "Permanent Resident Card", 28 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c#13250913-eb53-4418-9077-fb429f6b033f", 29 | "type": [ 30 | "VerifiableCredential", 31 | "PermanentResidentCard" 32 | ], 33 | "issuer": "did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN" 34 | }, 35 | "options": {} 36 | } 37 | -------------------------------------------------------------------------------- /pkg/restapi/v1/verifier/testdata/sample_vc_jwt_request.json: -------------------------------------------------------------------------------- 1 | { 2 | "credential": "eyJhbGciOiJub25lIn0.eyJleHAiOjIxNDc0ODM2NDAsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L2Jicy92MSJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiZXhwaXJhdGlvbkRhdGUiOiIyMDM4LTAxLTE5VDAzOjE0OjAwWiIsImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImlzc3VlciI6eyJpZCI6ImRpZDpleGFtcGxlOjc2ZTEyZWM3MTJlYmM2ZjFjMjIxZWJmZWIxZiIsIm5hbWUiOiJFeGFtcGxlIFVuaXZlcnNpdHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ.", 3 | "options": {} 4 | } 5 | -------------------------------------------------------------------------------- /pkg/restapi/v1/verifier/testdata/sample_vp.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1", 5 | "https://trustbloc.github.io/context/vc/examples-v1.jsonld", 6 | "https://w3id.org/vc/status-list/2021/v1", 7 | "https://w3id.org/security/suites/jws-2020/v1" 8 | ], 9 | "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", 10 | "type": "VerifiablePresentation", 11 | "verifiableCredential": [ 12 | { 13 | "@context": [ 14 | "https://www.w3.org/2018/credentials/v1", 15 | "https://www.w3.org/2018/credentials/examples/v1" 16 | ], 17 | "id": "http://example.edu/credentials/58473", 18 | "type": [ 19 | "VerifiableCredential", 20 | "UniversityDegreeCredential" 21 | ], 22 | "issuer": "https://example.edu/issuers/14", 23 | "issuanceDate": "2010-01-01T19:23:24Z", 24 | "credentialSubject": { 25 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 26 | "alumniOf": "Example University" 27 | } 28 | } 29 | ], 30 | "holder": "did:trustblock:abc" 31 | } -------------------------------------------------------------------------------- /pkg/restapi/v1/verifier/testdata/sample_vp.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIn0.eyJpc3MiOiJkaWQ6dHJ1c3RibG9jazphYmMiLCJqdGkiOiJ1cm46dXVpZDozOTc4MzQ0Zi04NTk2LTRjM2EtYTk3OC04ZmNhYmEzOTAzYzUiLCJ2cCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIiwiaHR0cHM6Ly90cnVzdGJsb2MuZ2l0aHViLmlvL2NvbnRleHQvdmMvZXhhbXBsZXMtdjEuanNvbmxkIiwiaHR0cHM6Ly93M2lkLm9yZy92Yy9zdGF0dXMtbGlzdC8yMDIxL3YxIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwiaG9sZGVyIjoiZGlkOnRydXN0YmxvY2s6YWJjIiwiaWQiOiJ1cm46dXVpZDozOTc4MzQ0Zi04NTk2LTRjM2EtYTk3OC04ZmNhYmEzOTAzYzUiLCJ0eXBlIjoiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiIsInZlcmlmaWFibGVDcmVkZW50aWFsIjpbeyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImFsdW1uaU9mIjoiRXhhbXBsZSBVbml2ZXJzaXR5IiwiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEifSwiaWQiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvNTg0NzMiLCJpc3N1YW5jZURhdGUiOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImlzc3VlciI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvaXNzdWVycy8xNCIsInByb29mIjp7InR5cGUiOiJSc2FTaWduYXR1cmUyMDE4In0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVbml2ZXJzaXR5RGVncmVlQ3JlZGVudGlhbCJdfV19fQ. -------------------------------------------------------------------------------- /pkg/restapi/v1/verifier/testdata/sample_vp_jsonld_request.json: -------------------------------------------------------------------------------- 1 | { 2 | "verifiablePresentation": { 3 | "@context": [ 4 | "https://www.w3.org/2018/credentials/v1", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://trustbloc.github.io/context/vc/examples-v1.jsonld", 7 | "https://w3id.org/vc/status-list/2021/v1", 8 | "https://w3id.org/security/suites/jws-2020/v1" 9 | ], 10 | "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", 11 | "type": "VerifiablePresentation", 12 | "verifiableCredential": [ 13 | { 14 | "@context": [ 15 | "https://www.w3.org/2018/credentials/v1", 16 | "https://www.w3.org/2018/credentials/examples/v1" 17 | ], 18 | "id": "http://example.edu/credentials/58473", 19 | "type": [ 20 | "VerifiableCredential", 21 | "UniversityDegreeCredential" 22 | ], 23 | "issuer": "https://example.edu/issuers/14", 24 | "issuanceDate": "2010-01-01T19:23:24Z", 25 | "credentialSubject": { 26 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 27 | "alumniOf": "Example University" 28 | }, 29 | "proof": { 30 | "type": "Ed25519Signature2018" 31 | } 32 | } 33 | ], 34 | "holder": "did:trustblock:abc" 35 | }, 36 | "options": {} 37 | } -------------------------------------------------------------------------------- /pkg/restapi/v1/version/controller.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package version 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/labstack/echo/v4" 12 | ) 13 | 14 | //go:generate mockgen -destination controller_mocks_test.go -package version_test -source=controller.go 15 | 16 | type router interface { 17 | GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route 18 | } 19 | 20 | type Config struct { 21 | Version string 22 | ServerVersion string 23 | } 24 | 25 | type Controller struct { 26 | version string 27 | serverVersion string 28 | } 29 | 30 | type versionResponse struct { 31 | Version string `json:"version"` 32 | } 33 | 34 | type serverVersionResponse struct { 35 | Version string `json:"version"` 36 | } 37 | 38 | func NewController(router router, cfg Config) *Controller { 39 | c := &Controller{ 40 | version: cfg.Version, 41 | serverVersion: cfg.ServerVersion, 42 | } 43 | 44 | router.GET("/version", c.Version) 45 | router.GET("/version/system", c.ServerVersion) 46 | 47 | return c 48 | } 49 | 50 | func (c *Controller) Version(ctx echo.Context) error { 51 | return ctx.JSON(http.StatusOK, versionResponse{Version: c.version}) 52 | } 53 | 54 | func (c *Controller) ServerVersion(ctx echo.Context) error { 55 | return ctx.JSON(http.StatusOK, serverVersionResponse{Version: c.serverVersion}) 56 | } 57 | -------------------------------------------------------------------------------- /pkg/service/clientidscheme/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package clientidscheme 8 | 9 | import "context" 10 | 11 | // ServiceInterface defines an interface for OAuth 2.0 Client ID Scheme service. 12 | type ServiceInterface interface { 13 | Register(ctx context.Context, clientURI, issuerState string) error 14 | } 15 | -------------------------------------------------------------------------------- /pkg/service/clientmanager/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package clientmanager 8 | 9 | import ( 10 | "context" 11 | "errors" 12 | 13 | "github.com/ory/fosite" 14 | 15 | "github.com/trustbloc/vcs/pkg/oauth2client" 16 | ) 17 | 18 | // ServiceInterface defines an interface for OAuth2 client manager. 19 | type ServiceInterface interface { 20 | Create(ctx context.Context, profileID, profileVersion string, data *ClientMetadata) (*oauth2client.Client, error) //nolint:lll // *rfc7591.Error 21 | Get(ctx context.Context, id string) (fosite.Client, error) 22 | } 23 | 24 | var ( 25 | ErrClientNotFound = errors.New("client not found") 26 | ) 27 | -------------------------------------------------------------------------------- /pkg/service/issuecredential/interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package issuecredential 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/trustbloc/vc-go/verifiable" 13 | 14 | profileapi "github.com/trustbloc/vcs/pkg/profile" 15 | ) 16 | 17 | //go:generate mockgen -destination interfaces_mocks_test.go -package issuecredential_test -source=interfaces.go 18 | 19 | type composer interface { 20 | Compose( 21 | ctx context.Context, 22 | cred *verifiable.Credential, 23 | req *PrepareCredentialsRequest, 24 | ) (*verifiable.Credential, error) 25 | } 26 | 27 | type ServiceInterface interface { 28 | IssueCredential( 29 | ctx context.Context, 30 | credential *verifiable.Credential, 31 | profile *profileapi.Issuer, 32 | opts ...Opts, 33 | ) (*verifiable.Credential, error) 34 | } 35 | -------------------------------------------------------------------------------- /pkg/service/issuecredential/testdata/university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://w3id.org/vc/status-list/2021/v1" 7 | ], 8 | "type": [ 9 | "VerifiableCredential", 10 | "UniversityDegreeCredential" 11 | ], 12 | "id": "http://example.gov/credentials/3732", 13 | "issuanceDate": "2020-03-16T22:37:26.544Z", 14 | "issuer": { 15 | "id": "did:trustblock:abc", 16 | "name": "University" 17 | }, 18 | "credentialStatus": { 19 | "id": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1#0", 20 | "type": "StatusList2021Entry", 21 | "statusListIndex": "1", 22 | "statusListCredential": "", 23 | "statusPurpose": "2" 24 | }, 25 | "credentialSubject": { 26 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 27 | "degree": { 28 | "type": "BachelorDegree", 29 | "degree": "MIT" 30 | }, 31 | "name": "Jayden Doe", 32 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 33 | } 34 | } -------------------------------------------------------------------------------- /pkg/service/issuecredential/types_test.go: -------------------------------------------------------------------------------- 1 | package issuecredential_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | 8 | "github.com/trustbloc/vcs/pkg/service/issuecredential" 9 | ) 10 | 11 | func TestToDTO(t *testing.T) { 12 | det := issuecredential.AuthorizationDetails{ 13 | CredentialDefinition: &issuecredential.CredentialDefinition{ 14 | Context: []string{"a", "b"}, 15 | Type: []string{"c", "d"}, 16 | }, 17 | } 18 | 19 | resp := det.ToDTO() 20 | 21 | assert.Equal(t, []string{"a", "b"}, *resp.CredentialDefinition.Context) 22 | assert.Equal(t, []string{"c", "d"}, resp.CredentialDefinition.Type) 23 | } 24 | -------------------------------------------------------------------------------- /pkg/service/oidc4ci/claims.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/trustbloc/vcs/internal/claims" 13 | "github.com/trustbloc/vcs/pkg/service/issuecredential" 14 | ) 15 | 16 | func (s *Service) EncryptClaims(ctx context.Context, data map[string]interface{}) (*issuecredential.ClaimData, error) { 17 | return claims.EncryptClaims(ctx, data, s.dataProtector) 18 | } 19 | 20 | func (s *Service) DecryptClaims(ctx context.Context, data *issuecredential.ClaimData) (map[string]interface{}, error) { 21 | return claims.DecryptClaims(ctx, data, s.dataProtector) 22 | } 23 | -------------------------------------------------------------------------------- /pkg/service/oidc4ci/interfaces.go: -------------------------------------------------------------------------------- 1 | package oidc4ci 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/trustbloc/vc-go/verifiable" 7 | 8 | profileapi "github.com/trustbloc/vcs/pkg/profile" 9 | "github.com/trustbloc/vcs/pkg/service/issuecredential" 10 | ) 11 | 12 | //go:generate mockgen -destination interfaces_mocks_test.go -package oidc4ci_test -source=interfaces.go 13 | 14 | type credentialIssuer interface { 15 | PrepareCredential( 16 | ctx context.Context, 17 | req *issuecredential.PrepareCredentialsRequest, 18 | ) (*verifiable.Credential, error) 19 | } 20 | 21 | type composer interface { // nolint:unused 22 | Compose( 23 | ctx context.Context, 24 | cred *verifiable.Credential, 25 | req *issuecredential.PrepareCredentialsRequest, 26 | ) (*verifiable.Credential, error) 27 | } 28 | 29 | type wellKnownProvider interface { 30 | AddDynamicConfiguration( 31 | ctx context.Context, 32 | profileID string, 33 | id string, 34 | credSupported *profileapi.CredentialsConfigurationSupported, 35 | ) error 36 | } 37 | -------------------------------------------------------------------------------- /pkg/service/oidc4ci/oidc4ci_service_state.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | import ( 10 | "fmt" 11 | 12 | "github.com/trustbloc/vcs/pkg/service/issuecredential" 13 | ) 14 | 15 | func (s *Service) validateStateTransition( 16 | oldState issuecredential.TransactionState, 17 | newState issuecredential.TransactionState, 18 | ) error { 19 | if oldState == issuecredential.TransactionStateIssuanceInitiated && 20 | newState == issuecredential.TransactionStatePreAuthCodeValidated { 21 | return nil // pre-auth 1 22 | } 23 | 24 | if oldState == issuecredential.TransactionStateIssuanceInitiated && 25 | newState == issuecredential.TransactionStateAwaitingIssuerOIDCAuthorization { 26 | return nil // auth 1 27 | } 28 | 29 | if oldState == issuecredential.TransactionStateAwaitingIssuerOIDCAuthorization && 30 | newState == issuecredential.TransactionStateIssuerOIDCAuthorizationDone { 31 | return nil 32 | } 33 | 34 | if oldState == issuecredential.TransactionStatePreAuthCodeValidated && 35 | newState == issuecredential.TransactionStateCredentialsIssued { 36 | return nil 37 | } 38 | 39 | if oldState == issuecredential.TransactionStateIssuerOIDCAuthorizationDone && 40 | newState == issuecredential.TransactionStateCredentialsIssued { 41 | return nil 42 | } 43 | 44 | return fmt.Errorf("unexpected transition from %v to %v", oldState, newState) 45 | } 46 | -------------------------------------------------------------------------------- /pkg/service/oidc4ci/regex.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ci 8 | 9 | import ( 10 | "strings" 11 | ) 12 | 13 | const ( 14 | WalletInitFlowClaimExpectedMatchCount = 2 15 | ) 16 | 17 | func ExtractIssuerURL(input string) string { 18 | if strings.HasPrefix(input, "http://") || strings.HasPrefix(input, "https://") { 19 | return input 20 | } 21 | 22 | return "" 23 | } 24 | -------------------------------------------------------------------------------- /pkg/service/oidc4vp/testdata/sample_vc_v2.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/ns/credentials/v2", 4 | "https://w3id.org/citizenship/v2" 5 | ], 6 | "validFrom": "2019-12-03T12:19:52Z", 7 | "validUntil": "2029-12-03T12:19:52Z", 8 | "credentialSubject": { 9 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 10 | "lprNumber": "999-999-999", 11 | "gender": "Male", 12 | "residentSince": "2015-01-01", 13 | "givenName": "JOHN", 14 | "familyName": "SMITH", 15 | "birthCountry": "Bahamas", 16 | "id": "did:example:b34ca6cd37bbf23", 17 | "commuterClassification": "C1", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "birthDate": "1958-07-17", 23 | "lprCategory": "C09" 24 | }, 25 | "name": "Permanent Resident Card", 26 | "description": "Permanent Resident Card", 27 | "id": "http://example.gov/credentials/ff98f978", 28 | "type": [ 29 | "VerifiableCredential", 30 | "PermanentResidentCard" 31 | ], 32 | "issuer": "did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN" 33 | } 34 | -------------------------------------------------------------------------------- /pkg/service/oidc4vp/testdata/university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://w3id.org/vc/status-list/2021/v1" 7 | ], 8 | "type": [ 9 | "VerifiableCredential", 10 | "UniversityDegreeCredential" 11 | ], 12 | "id": "http://example.gov/credentials/3732", 13 | "issuanceDate": "2020-03-16T22:37:26.544Z", 14 | "expirationDate": "2030-03-16T22:37:26.544Z", 15 | "issuer": { 16 | "id": "did:trustblock:abc", 17 | "name": "University" 18 | }, 19 | "credentialStatus": { 20 | "id": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1#0", 21 | "type": "StatusList2021Entry", 22 | "statusListIndex": "1", 23 | "statusListCredential": "", 24 | "statusPurpose": "2" 25 | }, 26 | "credentialSubject": { 27 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 28 | "degree": { 29 | "type": "BachelorDegree", 30 | "degree": "MIT" 31 | }, 32 | "name": "Jayden Doe", 33 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pkg/service/oidc4vp/testdata/university_degree.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1ODQzOTgyNDYsImlzcyI6ImRpZDp0cnVzdGJsb2NrOmFiYyIsImp0aSI6Imh0dHA6Ly9leGFtcGxlLmdvdi9jcmVkZW50aWFscy8zNzMyIiwibmJmIjoxNTg0Mzk4MjQ2LCJzdWIiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNjLWNjZy5naXRodWIuaW8vbGRzLWp3czIwMjAvY29udGV4dHMvbGRzLWp3czIwMjAtdjEuanNvbiIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIiwiaHR0cHM6Ly93M2lkLm9yZy92Yy9zdGF0dXMtbGlzdC8yMDIxL3YxIl0sIm5hbWUiOiJhYmNkIiwiZGVzY3JpcHRpb24iOiJzb21lLWRlc2NyaXB0aW9uIiwiY3JlZGVudGlhbFN0YXR1cyI6eyJpZCI6Imh0dHBzOi8vaXNzdWVyLXZjcy5zYW5kYm94LnRydXN0YmxvYy5kZXYvdmMtaXNzdWVyLXRlc3QtMi9zdGF0dXMvMSMwIiwic3RhdHVzTGlzdENyZWRlbnRpYWwiOiIiLCJzdGF0dXNMaXN0SW5kZXgiOiIxIiwic3RhdHVzUHVycG9zZSI6IjIiLCJ0eXBlIjoiU3RhdHVzTGlzdDIwMjFFbnRyeSJ9LCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsiZGVncmVlIjoiTUlUIiwidHlwZSI6IkJhY2hlbG9yRGVncmVlIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiaWQiOiJodHRwOi8vZXhhbXBsZS5nb3YvY3JlZGVudGlhbHMvMzczMiIsImlzc3VhbmNlRGF0ZSI6IjIwMjAtMDMtMTZUMjI6Mzc6MjYuNTQ0WiIsImlzc3VlciI6eyJpZCI6ImRpZDp0cnVzdGJsb2NrOmFiYyIsIm5hbWUiOiJVbml2ZXJzaXR5In0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVbml2ZXJzaXR5RGVncmVlQ3JlZGVudGlhbCJdfX0.bhCHeeHB840slD03CTLcNjv0Dan_eeMNjOrDtjm89T8 -------------------------------------------------------------------------------- /pkg/service/requestobject/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package requestobject 8 | 9 | import ( 10 | "errors" 11 | ) 12 | 13 | type RequestObject struct { 14 | ID string `json:"id"` 15 | Content string `json:"content"` 16 | } 17 | 18 | var ErrDataNotFound = errors.New("data not found") 19 | -------------------------------------------------------------------------------- /pkg/service/verifycredential/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package verifycredential 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/trustbloc/vc-go/verifiable" 13 | 14 | profileapi "github.com/trustbloc/vcs/pkg/profile" 15 | ) 16 | 17 | // CredentialsVerificationCheckResult resp containing failure check details. 18 | type CredentialsVerificationCheckResult struct { 19 | Check string 20 | Error string 21 | VerificationMethod string 22 | } 23 | 24 | // Options represents options for verify credential. 25 | type Options struct { 26 | // Challenge is added to the proof. 27 | Challenge string 28 | 29 | // Domain is added to the proof. 30 | Domain string 31 | } 32 | 33 | type ServiceInterface interface { 34 | VerifyCredential( 35 | ctx context.Context, 36 | credential *verifiable.Credential, 37 | opts *Options, 38 | profile *profileapi.Verifier, 39 | ) ([]CredentialsVerificationCheckResult, error) 40 | 41 | ValidateCredentialProof( 42 | ctx context.Context, 43 | credential *verifiable.Credential, 44 | proofChallenge, proofDomain string, 45 | vcInVPValidation bool, 46 | strictValidation bool, 47 | ) error 48 | 49 | ValidateVCStatus(ctx context.Context, vcStatus []*verifiable.TypedID, issuer *verifiable.Issuer) error 50 | 51 | ValidateLinkedDomain(ctx context.Context, signingDID string) error 52 | } 53 | -------------------------------------------------------------------------------- /pkg/service/verifycredential/testdata/revocation.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/vc/status-list/2021/v1" 5 | ], 6 | "id": "https://example.com/credentials/status/3", 7 | "type": ["VerifiableCredential", "RevocationList2020Credential"], 8 | "issuer": "did:trustblock:abc", 9 | "issuanceDate": "2020-04-05T14:27:40Z", 10 | "credentialSubject": { 11 | "id": "https://example.com/status/3#list", 12 | "type": "StatusList2021", 13 | "statusPurpose": "revocation", 14 | "encodedList": "H4sIAAAAAAAA_2IABAAA__-N7wLSAQAAAA" 15 | } 16 | } -------------------------------------------------------------------------------- /pkg/service/verifycredential/testdata/university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://w3id.org/vc/status-list/2021/v1" 7 | ], 8 | "type": [ 9 | "VerifiableCredential", 10 | "UniversityDegreeCredential" 11 | ], 12 | "id": "http://example.gov/credentials/3732", 13 | "issuanceDate": "2020-03-16T22:37:26.544Z", 14 | "issuer": { 15 | "id": "did:trustblock:abc", 16 | "name": "University" 17 | }, 18 | "credentialStatus": { 19 | "id": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1#0", 20 | "type": "StatusList2021Entry", 21 | "statusListIndex": "1", 22 | "statusListCredential": "", 23 | "statusPurpose": "2" 24 | }, 25 | "credentialSubject": { 26 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 27 | "degree": { 28 | "type": "BachelorDegree", 29 | "degree": "MIT" 30 | }, 31 | "name": "Jayden Doe", 32 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 33 | } 34 | } -------------------------------------------------------------------------------- /pkg/service/verifycredential/testdata/university_degree.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpYXQiOjE1ODQzOTgyNDYsImlzcyI6ImRpZDp0cnVzdGJsb2NrOmFiYyIsImp0aSI6Imh0dHA6Ly9leGFtcGxlLmdvdi9jcmVkZW50aWFscy8zNzMyIiwibmJmIjoxNTg0Mzk4MjQ2LCJzdWIiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNjLWNjZy5naXRodWIuaW8vbGRzLWp3czIwMjAvY29udGV4dHMvbGRzLWp3czIwMjAtdjEuanNvbiIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIiwiaHR0cHM6Ly93M2lkLm9yZy92Yy9zdGF0dXMtbGlzdC8yMDIxL3YxIl0sImNyZWRlbnRpYWxTdGF0dXMiOnsiaWQiOiJodHRwczovL2lzc3Vlci12Y3Muc2FuZGJveC50cnVzdGJsb2MuZGV2L3ZjLWlzc3Vlci10ZXN0LTIvc3RhdHVzLzEjMCIsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiIiwic3RhdHVzTGlzdEluZGV4IjoiMSIsInN0YXR1c1B1cnBvc2UiOiIyIiwidHlwZSI6IlN0YXR1c0xpc3QyMDIxRW50cnkifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiZGVncmVlIjp7ImRlZ3JlZSI6Ik1JVCIsInR5cGUiOiJCYWNoZWxvckRlZ3JlZSJ9LCJpZCI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsIm5hbWUiOiJKYXlkZW4gRG9lIiwic3BvdXNlIjoiZGlkOmV4YW1wbGU6YzI3NmUxMmVjMjFlYmZlYjFmNzEyZWJjNmYxIn0sImlkIjoiaHR0cDovL2V4YW1wbGUuZ292L2NyZWRlbnRpYWxzLzM3MzIiLCJpc3N1YW5jZURhdGUiOiIyMDIwLTAzLTE2VDIyOjM3OjI2LjU0NFoiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6dHJ1c3RibG9jazphYmMiLCJuYW1lIjoiVW5pdmVyc2l0eSJ9LCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXX19. -------------------------------------------------------------------------------- /pkg/service/verifypresentation/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package verifypresentation 8 | 9 | import ( 10 | "context" 11 | 12 | "github.com/samber/lo" 13 | "github.com/trustbloc/vc-go/verifiable" 14 | 15 | profileapi "github.com/trustbloc/vcs/pkg/profile" 16 | ) 17 | 18 | type Options struct { 19 | Domain string 20 | Challenge string 21 | } 22 | 23 | // PresentationVerificationResult resp containing failure check details. 24 | type PresentationVerificationResult struct { 25 | Checks []*Check 26 | } 27 | 28 | func (r *PresentationVerificationResult) HasErrors() bool { 29 | return len(r.Errors()) > 0 30 | } 31 | 32 | func (r *PresentationVerificationResult) Errors() []*Check { 33 | var checks []*Check 34 | 35 | for _, check := range r.Checks { 36 | if !lo.IsNil(check.Error) { 37 | checks = append(checks, check) 38 | } 39 | } 40 | 41 | return checks 42 | } 43 | 44 | type Check struct { 45 | Check string 46 | Error error 47 | } 48 | 49 | type ServiceInterface interface { 50 | VerifyPresentation( 51 | ctx context.Context, 52 | presentation *verifiable.Presentation, 53 | opts *Options, 54 | profile *profileapi.Verifier, 55 | ) (PresentationVerificationResult, map[string][]string, error) 56 | } 57 | -------------------------------------------------------------------------------- /pkg/service/wellknown/provider/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Gen Digital Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package provider 8 | 9 | type DynamicWellKnownStore dynamicWellKnownStore 10 | -------------------------------------------------------------------------------- /pkg/service/wellknown/provider/interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Gen Digital Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package provider 8 | 9 | import ( 10 | "context" 11 | 12 | profileapi "github.com/trustbloc/vcs/pkg/profile" 13 | ) 14 | 15 | //go:generate mockgen -destination interfaces_mocks_test.go -package provider -source=interfaces.go 16 | 17 | type dynamicWellKnownStore interface { 18 | Upsert( 19 | ctx context.Context, 20 | profileID string, 21 | item map[string]*profileapi.CredentialsConfigurationSupported, 22 | ) error 23 | Get(ctx context.Context, profileID string) (map[string]*profileapi.CredentialsConfigurationSupported, error) 24 | } 25 | -------------------------------------------------------------------------------- /pkg/storage/awsecret/arieskmsstore/interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package arieskmsstore 8 | 9 | //go:generate mockgen -destination interfaces_mocks_test.go -package arieskmsstore_test -source=interfaces.go 10 | 11 | import ( 12 | "context" 13 | 14 | "github.com/aws/aws-sdk-go-v2/service/secretsmanager" 15 | ) 16 | 17 | type Client interface { 18 | CreateSecret( 19 | ctx context.Context, 20 | params *secretsmanager.CreateSecretInput, 21 | optFns ...func(*secretsmanager.Options), 22 | ) (*secretsmanager.CreateSecretOutput, error) 23 | 24 | GetSecretValue( 25 | ctx context.Context, 26 | params *secretsmanager.GetSecretValueInput, 27 | optFns ...func(*secretsmanager.Options), 28 | ) (*secretsmanager.GetSecretValueOutput, error) 29 | 30 | DeleteSecret( 31 | ctx context.Context, 32 | params *secretsmanager.DeleteSecretInput, 33 | optFns ...func(*secretsmanager.Options), 34 | ) (*secretsmanager.DeleteSecretOutput, error) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/storage/mongodb/clientmanager/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Gen Digital Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package clientmanager 8 | 9 | import "errors" 10 | 11 | var ErrDataNotFound = errors.New("data not found") 12 | -------------------------------------------------------------------------------- /pkg/storage/mongodb/cslindexstore/testdata/university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://w3id.org/vc/status-list/2021/v1" 7 | ], 8 | "type": [ 9 | "VerifiableCredential", 10 | "UniversityDegreeCredential" 11 | ], 12 | "id": "http://example.gov/credentials/3732", 13 | "issuanceDate": "2020-03-16T22:37:26.544Z", 14 | "issuer": { 15 | "id": "did:trustblock:abc", 16 | "name": "University" 17 | }, 18 | "credentialStatus": { 19 | "id": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1#0", 20 | "type": "StatusList2021Entry", 21 | "statusListIndex": "1", 22 | "statusListCredential": "", 23 | "statusPurpose": "2" 24 | }, 25 | "credentialSubject": { 26 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 27 | "degree": { 28 | "type": "BachelorDegree", 29 | "degree": "MIT" 30 | }, 31 | "name": "Jayden Doe", 32 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 33 | } 34 | } -------------------------------------------------------------------------------- /pkg/storage/mongodb/cslindexstore/testdata/university_degree.jwt: -------------------------------------------------------------------------------- 1 | "eyJhbGciOiJub25lIn0.eyJpYXQiOjE1ODQzOTgyNDYsImlzcyI6ImRpZDp0cnVzdGJsb2NrOmFiYyIsImp0aSI6Imh0dHA6Ly9leGFtcGxlLmdvdi9jcmVkZW50aWFscy8zNzMyLzEiLCJuYmYiOjE1ODQzOTgyNDYsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93M2MtY2NnLmdpdGh1Yi5pby9sZHMtandzMjAyMC9jb250ZXh0cy9sZHMtandzMjAyMC12MS5qc29uIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiLCJodHRwczovL3czaWQub3JnL3ZjL3N0YXR1cy1saXN0LzIwMjEvdjEiXSwiY3JlZGVudGlhbFN0YXR1cyI6eyJpZCI6Imh0dHBzOi8vaXNzdWVyLXZjcy5zYW5kYm94LnRydXN0YmxvYy5kZXYvdmMtaXNzdWVyLXRlc3QtMi9zdGF0dXMvMSMwIiwic3RhdHVzTGlzdENyZWRlbnRpYWwiOiIiLCJzdGF0dXNMaXN0SW5kZXgiOiIxIiwic3RhdHVzUHVycG9zZSI6IjIiLCJ0eXBlIjoiU3RhdHVzTGlzdDIwMjFFbnRyeSJ9LCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsiZGVncmVlIjoiTUlUIiwidHlwZSI6IkJhY2hlbG9yRGVncmVlIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiaWQiOiJodHRwOi8vZXhhbXBsZS5nb3YvY3JlZGVudGlhbHMvMzczMi8xIiwiaXNzdWFuY2VEYXRlIjoiMjAyMC0wMy0xNlQyMjozNzoyNi41NDRaIiwiaXNzdWVyIjp7ImlkIjoiZGlkOnRydXN0YmxvY2s6YWJjIiwibmFtZSI6IlVuaXZlcnNpdHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ." -------------------------------------------------------------------------------- /pkg/storage/mongodb/cslvcstore/testdata/university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://w3id.org/vc/status-list/2021/v1" 7 | ], 8 | "type": [ 9 | "VerifiableCredential", 10 | "UniversityDegreeCredential" 11 | ], 12 | "id": "http://example.gov/credentials/3732", 13 | "issuanceDate": "2020-03-16T22:37:26.544Z", 14 | "issuer": { 15 | "id": "did:trustblock:abc", 16 | "name": "University" 17 | }, 18 | "credentialStatus": { 19 | "id": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1#0", 20 | "type": "StatusList2021Entry", 21 | "statusListIndex": "1", 22 | "statusListCredential": "", 23 | "statusPurpose": "2" 24 | }, 25 | "credentialSubject": { 26 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 27 | "degree": { 28 | "type": "BachelorDegree", 29 | "degree": "MIT" 30 | }, 31 | "name": "Jayden Doe", 32 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 33 | } 34 | } -------------------------------------------------------------------------------- /pkg/storage/mongodb/cslvcstore/testdata/university_degree.jwt: -------------------------------------------------------------------------------- 1 | "eyJhbGciOiJub25lIn0.eyJpYXQiOjE1ODQzOTgyNDYsImlzcyI6ImRpZDp0cnVzdGJsb2NrOmFiYyIsImp0aSI6Imh0dHA6Ly9leGFtcGxlLmdvdi9jcmVkZW50aWFscy8zNzMyLzEiLCJuYmYiOjE1ODQzOTgyNDYsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93M2MtY2NnLmdpdGh1Yi5pby9sZHMtandzMjAyMC9jb250ZXh0cy9sZHMtandzMjAyMC12MS5qc29uIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiLCJodHRwczovL3czaWQub3JnL3ZjL3N0YXR1cy1saXN0LzIwMjEvdjEiXSwiY3JlZGVudGlhbFN0YXR1cyI6eyJpZCI6Imh0dHBzOi8vaXNzdWVyLXZjcy5zYW5kYm94LnRydXN0YmxvYy5kZXYvdmMtaXNzdWVyLXRlc3QtMi9zdGF0dXMvMSMwIiwic3RhdHVzTGlzdENyZWRlbnRpYWwiOiIiLCJzdGF0dXNMaXN0SW5kZXgiOiIxIiwic3RhdHVzUHVycG9zZSI6IjIiLCJ0eXBlIjoiU3RhdHVzTGlzdDIwMjFFbnRyeSJ9LCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsiZGVncmVlIjoiTUlUIiwidHlwZSI6IkJhY2hlbG9yRGVncmVlIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiaWQiOiJodHRwOi8vZXhhbXBsZS5nb3YvY3JlZGVudGlhbHMvMzczMi8xIiwiaXNzdWFuY2VEYXRlIjoiMjAyMC0wMy0xNlQyMjozNzoyNi41NDRaIiwiaXNzdWVyIjp7ImlkIjoiZGlkOnRydXN0YmxvY2s6YWJjIiwibmFtZSI6IlVuaXZlcnNpdHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ." -------------------------------------------------------------------------------- /pkg/storage/mongodb/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package mongodb 8 | 9 | import ( 10 | "encoding/json" 11 | 12 | "github.com/trustbloc/vcs/internal/utils" 13 | ) 14 | 15 | func StructureToMap(obj interface{}) (map[string]interface{}, error) { 16 | return utils.StructureToMap(obj) 17 | } 18 | 19 | func MapToStructure(in map[string]interface{}, out interface{}) error { 20 | b, err := json.Marshal(in) 21 | if err != nil { 22 | return err 23 | } 24 | 25 | return json.Unmarshal(b, out) 26 | } 27 | -------------------------------------------------------------------------------- /pkg/storage/mongodb/vcstatusstore/testdata/university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://w3id.org/vc/status-list/2021/v1" 7 | ], 8 | "type": [ 9 | "VerifiableCredential", 10 | "UniversityDegreeCredential" 11 | ], 12 | "id": "http://example.gov/credentials/3732", 13 | "issuanceDate": "2020-03-16T22:37:26.544Z", 14 | "issuer": { 15 | "id": "did:trustblock:abc", 16 | "name": "University" 17 | }, 18 | "credentialStatus": { 19 | "id": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1#0", 20 | "type": "StatusList2021Entry", 21 | "statusListIndex": "1", 22 | "statusListCredential": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1", 23 | "statusPurpose": "revocation" 24 | }, 25 | "credentialSubject": { 26 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 27 | "degree": { 28 | "type": "BachelorDegree", 29 | "degree": "MIT" 30 | }, 31 | "name": "Jayden Doe", 32 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 33 | } 34 | } -------------------------------------------------------------------------------- /pkg/storage/redis/ackstore/interfaces.go: -------------------------------------------------------------------------------- 1 | package ackstore 2 | 3 | import redisapi "github.com/redis/go-redis/v9" 4 | 5 | //go:generate mockgen -destination interfaces_mocks_test.go -package ackstore_test -source=interfaces.go 6 | 7 | type redisClient interface { 8 | API() redisapi.UniversalClient 9 | } 10 | 11 | // nolint 12 | type redisApi interface { 13 | redisapi.UniversalClient 14 | } 15 | -------------------------------------------------------------------------------- /pkg/storage/redis/dynamicwellknown/interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Gen Digital Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package dynamicwellknown 8 | 9 | import redisapi "github.com/redis/go-redis/v9" 10 | 11 | //go:generate mockgen -destination interfaces_mocks_test.go -package dynamicwellknown_test -source=interfaces.go 12 | 13 | type redisClient interface { 14 | API() redisapi.UniversalClient 15 | } 16 | 17 | // nolint 18 | type redisApi interface { 19 | redisapi.UniversalClient 20 | } 21 | -------------------------------------------------------------------------------- /pkg/storage/redis/oidc4ciclaimdatastore/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4ciclaimdatastore 8 | 9 | import ( 10 | "encoding/json" 11 | "time" 12 | 13 | "github.com/trustbloc/vcs/pkg/service/issuecredential" 14 | ) 15 | 16 | type redisDocument struct { 17 | ClaimData issuecredential.ClaimData `json:"claimData"` 18 | ExpireAt time.Time `json:"expireAt,omitempty"` 19 | } 20 | 21 | func (d *redisDocument) MarshalBinary() ([]byte, error) { 22 | return json.Marshal(d) 23 | } 24 | 25 | func (d *redisDocument) UnmarshalBinary(data []byte) error { 26 | return json.Unmarshal(data, d) 27 | } 28 | -------------------------------------------------------------------------------- /pkg/storage/redis/oidc4cinoncestore/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4cinoncestore 8 | 9 | import ( 10 | "encoding/json" 11 | "time" 12 | 13 | "github.com/trustbloc/vcs/pkg/service/issuecredential" 14 | ) 15 | 16 | type redisDocument struct { 17 | ID string 18 | ExpireAt time.Time 19 | TransactionData *issuecredential.TransactionData 20 | } 21 | 22 | func (d *redisDocument) MarshalBinary() ([]byte, error) { 23 | return json.Marshal(d) 24 | } 25 | 26 | func (d *redisDocument) UnmarshalBinary(data []byte) error { 27 | return json.Unmarshal(data, d) 28 | } 29 | -------------------------------------------------------------------------------- /pkg/storage/redis/oidc4cistatestore/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4cistatestore 8 | 9 | import ( 10 | "encoding/json" 11 | "time" 12 | 13 | "github.com/trustbloc/vcs/pkg/service/oidc4ci" 14 | ) 15 | 16 | type redisDocument struct { 17 | ExpireAt time.Time `json:"expireAt"` 18 | State *oidc4ci.AuthorizeState `json:"state"` 19 | } 20 | 21 | func (d *redisDocument) MarshalBinary() ([]byte, error) { 22 | return json.Marshal(d) 23 | } 24 | 25 | func (d *redisDocument) UnmarshalBinary(data []byte) error { 26 | return json.Unmarshal(data, d) 27 | } 28 | -------------------------------------------------------------------------------- /pkg/storage/redis/oidc4vpclaimsstore/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4vpclaimsstore 8 | 9 | import ( 10 | "encoding/json" 11 | "time" 12 | 13 | "github.com/trustbloc/vcs/pkg/service/oidc4vp" 14 | ) 15 | 16 | type claimDataDocument struct { 17 | ExpireAt time.Time `json:"expireAt"` 18 | *oidc4vp.ClaimData 19 | } 20 | 21 | func (d *claimDataDocument) MarshalBinary() ([]byte, error) { 22 | return json.Marshal(d) 23 | } 24 | 25 | func (d *claimDataDocument) UnmarshalBinary(data []byte) error { 26 | return json.Unmarshal(data, d) 27 | } 28 | -------------------------------------------------------------------------------- /pkg/storage/redis/oidc4vpnoncestore/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4vpnoncestore 8 | 9 | import ( 10 | "encoding/json" 11 | "time" 12 | 13 | "github.com/trustbloc/vcs/pkg/service/oidc4vp" 14 | ) 15 | 16 | type nonceDocument struct { 17 | TxID oidc4vp.TxID `json:"txId"` 18 | ExpireAt time.Time `json:"expireAt"` 19 | } 20 | 21 | func (d *nonceDocument) MarshalBinary() ([]byte, error) { 22 | return json.Marshal(d) 23 | } 24 | 25 | func (d *nonceDocument) UnmarshalBinary(data []byte) error { 26 | return json.Unmarshal(data, d) 27 | } 28 | -------------------------------------------------------------------------------- /pkg/storage/redis/oidc4vptxstore/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package oidc4vptxstore 8 | 9 | import ( 10 | "encoding/json" 11 | "time" 12 | 13 | "github.com/trustbloc/vc-go/presexch" 14 | ) 15 | 16 | type txDocument struct { 17 | ProfileID string `json:"profileId"` 18 | ProfileVersion string `json:"profileVersion"` 19 | ReceivedClaimsID string `json:"receivedClaimsId,omitempty"` 20 | PresentationDefinition *presexch.PresentationDefinition `json:"presentationDefinition"` 21 | ExpireAt time.Time `json:"expireAt"` 22 | CustomScopes []string `json:"customScopes,omitempty"` 23 | } 24 | 25 | func (d *txDocument) MarshalBinary() ([]byte, error) { 26 | return json.Marshal(d) 27 | } 28 | 29 | func (d *txDocument) UnmarshalBinary(data []byte) error { 30 | return json.Unmarshal(data, d) 31 | } 32 | -------------------------------------------------------------------------------- /pkg/storage/s3/cslvcstore/testdata/university_degree.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", 5 | "https://www.w3.org/2018/credentials/examples/v1", 6 | "https://w3id.org/vc/status-list/2021/v1" 7 | ], 8 | "type": [ 9 | "VerifiableCredential", 10 | "UniversityDegreeCredential" 11 | ], 12 | "id": "http://example.gov/credentials/3732", 13 | "issuanceDate": "2020-03-16T22:37:26.544Z", 14 | "issuer": { 15 | "id": "did:trustblock:abc", 16 | "name": "University" 17 | }, 18 | "credentialStatus": { 19 | "id": "https://issuer-vcs.sandbox.trustbloc.dev/vc-issuer-test-2/status/1#0", 20 | "type": "StatusList2021Entry", 21 | "statusListIndex": "1", 22 | "statusListCredential": "", 23 | "statusPurpose": "2" 24 | }, 25 | "credentialSubject": { 26 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 27 | "degree": { 28 | "type": "BachelorDegree", 29 | "degree": "MIT" 30 | }, 31 | "name": "Jayden Doe", 32 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 33 | } 34 | } -------------------------------------------------------------------------------- /pkg/storage/s3/cslvcstore/testdata/university_degree.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIn0.eyJpYXQiOjE1ODQzOTgyNDYsImlzcyI6ImRpZDp0cnVzdGJsb2NrOmFiYyIsImp0aSI6Imh0dHA6Ly9leGFtcGxlLmdvdi9jcmVkZW50aWFscy8zNzMyIiwibmJmIjoxNTg0Mzk4MjQ2LCJzdWIiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNjLWNjZy5naXRodWIuaW8vbGRzLWp3czIwMjAvY29udGV4dHMvbGRzLWp3czIwMjAtdjEuanNvbiIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIiwiaHR0cHM6Ly93M2lkLm9yZy92Yy9zdGF0dXMtbGlzdC8yMDIxL3YxIl0sImNyZWRlbnRpYWxTdGF0dXMiOnsiaWQiOiJodHRwczovL2lzc3Vlci12Y3Muc2FuZGJveC50cnVzdGJsb2MuZGV2L3ZjLWlzc3Vlci10ZXN0LTIvc3RhdHVzLzEjMCIsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiIiwic3RhdHVzTGlzdEluZGV4IjoiMSIsInN0YXR1c1B1cnBvc2UiOiIyIiwidHlwZSI6IlN0YXR1c0xpc3QyMDIxRW50cnkifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiZGVncmVlIjp7ImRlZ3JlZSI6Ik1JVCIsInR5cGUiOiJCYWNoZWxvckRlZ3JlZSJ9LCJpZCI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsIm5hbWUiOiJKYXlkZW4gRG9lIiwic3BvdXNlIjoiZGlkOmV4YW1wbGU6YzI3NmUxMmVjMjFlYmZlYjFmNzEyZWJjNmYxIn0sImlkIjoiaHR0cDovL2V4YW1wbGUuZ292L2NyZWRlbnRpYWxzLzM3MzIiLCJpc3N1YW5jZURhdGUiOiIyMDIwLTAzLTE2VDIyOjM3OjI2LjU0NFoiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6dHJ1c3RibG9jazphYmMiLCJuYW1lIjoiVW5pdmVyc2l0eSJ9LCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXX19.123 -------------------------------------------------------------------------------- /scripts/build-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | set -e 9 | 10 | 11 | 12 | cd /opt/workspace/vcs 13 | 14 | echo "Building wallet cli binaries" 15 | 16 | cd component/wallet-cli/;CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o ../../.build/dist/bin/wallet-cli-linux-amd64 main.go 17 | cd /opt/workspace/vcs 18 | cd .build/dist/bin;tar cvzf wallet-cli-linux-amd64.tar.gz wallet-cli-linux-amd64;rm -rf wallet-cli-linux-amd64 19 | cd /opt/workspace/vcs 20 | 21 | cd component/wallet-cli/;CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -o ../../.build/dist/bin/wallet-cli-linux-arm64 main.go 22 | cd /opt/workspace/vcs 23 | cd .build/dist/bin;tar cvzf wallet-cli-linux-arm64.tar.gz wallet-cli-linux-arm64;rm -rf wallet-cli-linux-arm64 24 | cd /opt/workspace/vcs 25 | 26 | cd component/wallet-cli/;GOOS=darwin GOARCH=arm64 go build -o ../../.build/dist/bin/wallet-cli-darwin-arm64 main.go 27 | cd /opt/workspace/vcs 28 | cd .build/dist/bin;tar cvzf wallet-cli-darwin-arm64.tar.gz wallet-cli-darwin-arm64;rm -rf wallet-cli-darwin-arm64 29 | cd /opt/workspace/vcs 30 | 31 | cd component/wallet-cli/;CC=o64-clang CXX=o64-clang++ CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -o ../../.build/dist/bin/wallet-cli-darwin-amd64 main.go 32 | cd /opt/workspace/vcs 33 | cd .build/dist/bin;tar cvzf wallet-cli-darwin-amd64.tar.gz wallet-cli-darwin-amd64;rm -rf wallet-cli-darwin-amd64 34 | cd /opt/workspace/vcs 35 | -------------------------------------------------------------------------------- /scripts/check_integration.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | set -e 8 | 9 | 10 | TAGS=${TAGS:-all} 11 | 12 | PWD=`pwd` 13 | cd test/bdd 14 | 15 | echo "Running vcs integration tests with tag=$TAGS" 16 | 17 | #export DISABLE_COMPOSITION=true 18 | #export TAGS=@oidc4vc_rest_pre_auth_flow_credential_refresh 19 | go test -count=1 -v -cover . -p 1 -timeout=40m $TAGS 20 | cd $PWD -------------------------------------------------------------------------------- /scripts/check_lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | set -e 9 | 10 | echo "Running $0" 11 | 12 | DOCKER_CMD=${DOCKER_CMD:-docker} 13 | GOLANGCI_LINT_IMAGE="golangci/golangci-lint:v1.62.0" 14 | 15 | if [ ! $(command -v ${DOCKER_CMD}) ]; then 16 | exit 0 17 | fi 18 | 19 | lint_tasks=( 20 | "." 21 | "component/profile/reader/file" 22 | "component/event" 23 | "component/healthchecks" 24 | "component/credentialstatus" 25 | "component/oidc/fosite" 26 | ) 27 | 28 | run_lint() { 29 | local task_dir=$1 30 | ${DOCKER_CMD} run --rm -e GOPROXY=${GOPROXY} \ 31 | -v $(pwd):/opt/workspace \ 32 | -w /opt/workspace/$task_dir ${GOLANGCI_LINT_IMAGE} \ 33 | golangci-lint run --timeout 5m --exclude-files '.*_test\.go' 34 | } 35 | 36 | if [ "$LINT_CONCURRENTLY" = "true" ]; then 37 | for task in "${lint_tasks[@]}"; do 38 | run_lint "$task" & 39 | done 40 | wait 41 | else 42 | for task in "${lint_tasks[@]}"; do 43 | run_lint "$task" 44 | done 45 | fi 46 | -------------------------------------------------------------------------------- /test/bdd/attestation/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package main 8 | 9 | import ( 10 | "log" 11 | "net/http" 12 | "os" 13 | ) 14 | 15 | func main() { 16 | serveCertPath := os.Getenv("TLS_CERT_PATH") 17 | if serveCertPath == "" { 18 | log.Fatalf("TLS_CERT_PATH is required") 19 | 20 | return 21 | } 22 | 23 | serveKeyPath := os.Getenv("TLS_KEY_PATH") 24 | if serveKeyPath == "" { 25 | log.Fatalf("TLS_KEY_PATH is required") 26 | 27 | return 28 | } 29 | 30 | listenAddr := os.Getenv("LISTEN_ADDR") 31 | if listenAddr == "" { 32 | log.Fatalf("LISTEN_ADDR is required") 33 | 34 | return 35 | } 36 | 37 | log.Printf("Listening on %s", listenAddr) 38 | 39 | log.Fatal(http.ListenAndServeTLS( 40 | listenAddr, 41 | serveCertPath, serveKeyPath, 42 | newServer(), 43 | )) 44 | } 45 | -------------------------------------------------------------------------------- /test/bdd/attestation/models.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package main 8 | 9 | type AttestWalletInitRequest struct { 10 | Payload map[string]interface{} `json:"payload"` 11 | } 12 | 13 | type AttestWalletInitResponse struct { 14 | Challenge string `json:"challenge"` 15 | SessionID string `json:"session_id"` 16 | } 17 | 18 | type AttestWalletCompleteRequest struct { 19 | AssuranceLevel string `json:"assurance_level"` 20 | Proof Proof `json:"proof"` 21 | SessionID string `json:"session_id"` 22 | } 23 | 24 | type Proof struct { 25 | Jwt string `json:"jwt,omitempty"` 26 | ProofType string `json:"proof_type"` 27 | } 28 | 29 | type JwtProofClaims struct { 30 | Issuer string `json:"iss,omitempty"` 31 | Audience string `json:"aud,omitempty"` 32 | IssuedAt int64 `json:"iat,omitempty"` 33 | Nonce string `json:"nonce,omitempty"` 34 | Exp int64 `json:"exp,omitempty"` 35 | } 36 | 37 | type AttestWalletCompleteResponse struct { 38 | WalletAttestationVC string `json:"wallet_attestation_vc"` 39 | } 40 | 41 | type IssueCredentialData struct { 42 | Credential interface{} `json:"credential"` 43 | } 44 | -------------------------------------------------------------------------------- /test/bdd/cognito-auth/resolver.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package main 8 | 9 | import ( 10 | "context" 11 | "net/url" 12 | 13 | cip "github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider" 14 | transport "github.com/aws/smithy-go/endpoints" 15 | ) 16 | 17 | // EndpointResolver resolves the endpoint. 18 | type EndpointResolver struct { 19 | Endpoint string 20 | } 21 | 22 | // ResolveEndpoint resolves the endpoint. 23 | func (e *EndpointResolver) ResolveEndpoint( 24 | _ context.Context, 25 | _ cip.EndpointParameters, 26 | ) (transport.Endpoint, error) { 27 | targetURL, err := url.Parse(e.Endpoint) 28 | if err != nil { 29 | return transport.Endpoint{}, err 30 | } 31 | 32 | return transport.Endpoint{ 33 | URI: *targetURL, 34 | }, nil 35 | } 36 | -------------------------------------------------------------------------------- /test/bdd/features/vc_dev_api.feature: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | @all 8 | @vc_dev_api 9 | Feature: Request DID Config 10 | 11 | Scenario Outline: Request DID Config 12 | When I request did config for "" with ID "" and type "" 13 | Then I receive response with status code "200" for didconfig 14 | 15 | Examples: 16 | | profileType | profileId | credentialType | 17 | | issuer | i_myprofile_ud_P256k1/v1.0 | ldp | 18 | | issuer | i_myprofile_ud_es256_jwt/v1.0 | jwt | 19 | | verifier | v_myprofile_ldp/v1.0 | ldp | 20 | | verifier | v_myprofile_jwt/v1.0 | jwt | 21 | | verifier | v_myprofile_multivp_jwt/v1.0 | jwt | -------------------------------------------------------------------------------- /test/bdd/features/vc_echo_api.feature: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | @all 8 | @vc_rest_echo 9 | Feature: VC REST API using Echo web framework 10 | Scenario: VC server is up and running (health probe) 11 | When I make an HTTP GET to "http://localhost:48127/healthcheck" 12 | Then I receive response with status code "200" 13 | 14 | Scenario: VC server is up and running (ready probe) 15 | When I make an HTTP GET to "http://localhost:48127/ready" 16 | Then I receive response with status code "200" -------------------------------------------------------------------------------- /test/bdd/features/vc_log_api.feature: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | @all 8 | @log_api 9 | Feature: Change log levels 10 | Scenario: Modify log levels 11 | When an HTTP POST is sent to "http://localhost:8075/loglevels" with content "DEBUG" of type "text/plain" 12 | When an HTTP POST is sent to "http://localhost:8075/loglevels" with content "INVALID" of type "text/plain" and the returned status code is 500 13 | 14 | -------------------------------------------------------------------------------- /test/bdd/features/vc_stress.feature: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | @vc_stress 8 | Feature: VC stress test 9 | @vc_stress_test 10 | Scenario: Stress test method 11 | When Profile "i_myprofile_ud_P256k1/v1.0" issuer has been authorized with username "profile-user-issuer-1" and password "profile-user-issuer-1-pwd" 12 | And Profile "v_myprofile_ldp/v1.0" verifier has been authorized with username "profile-user-verifier-1" and password "profile-user-verifier-1-pwd" 13 | And "USER_NUMS" users request to create a vc and verify it "VC_URL" with profiles issuer "ISSUER_PROFILE_ID" verify "VERIFY_PROFILE_ID" using "CONCURRENT_REQ" concurrent requests 14 | -------------------------------------------------------------------------------- /test/bdd/features/vc_version_api.feature: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | @all 8 | @vc_status_api 9 | Feature: Version API 10 | 11 | Scenario: Request version 12 | When I request Version 13 | Then Version is set 14 | 15 | Scenario: Request SystemVersion 16 | When I request SystemVersion 17 | Then Version is set -------------------------------------------------------------------------------- /test/bdd/fixtures/.env: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | VC_REST_IMAGE=ghcr.io/trustbloc/vc-server 8 | 9 | # VC rest in issuer mode 10 | ISSUER_VC_HOST=0.0.0.0 11 | ISSUER_VC_PORT=8070 12 | 13 | # VC rest in verifier mode 14 | VERIFIER_VC_HOST=0.0.0.0 15 | VERIFIER_VC_PORT=8069 16 | 17 | # VC rest in holder mode 18 | HOLDER_VC_HOST=0.0.0.0 19 | HOLDER_VC_PORT=8067 20 | 21 | # VC rest in combined mode 22 | VC_REST_HOST=0.0.0.0 23 | VC_REST_PORT=8068 24 | 25 | # Remote JSON-LD context provider 26 | CONTEXT_PROVIDER_URL=https://file-server.trustbloc.local:10096/ld-contexts.json 27 | 28 | # Webhook configurations 29 | SAMPLE_WEBHOOK_IMAGE=vcs/sample-webhook 30 | SAMPLE_WEBHOOK_IMAGE_TAG=latest 31 | 32 | # Cognito auth configurations 33 | SAMPLE_COGNITO_AUTH_IMAGE=vcs/sample-cognito-auth 34 | SAMPLE_COGNITO_AUTH_IMAGE_TAG=latest 35 | 36 | 37 | # did-resolver 38 | DID_RESOLVER_IMAGE=ghcr.io/trustbloc-cicd/did-resolver 39 | DID_RESOLVER_IMAGE_TAG=v0.0.1-snapshot-58ab302 40 | DID_RESOLVER_HOST=0.0.0.0 41 | DID_RESOLVER_PORT=8072 42 | 43 | # kms 44 | KMS_IMAGE=ghcr.io/trustbloc/kms 45 | KMS_IMAGE_TAG=v0.1.8 46 | KMS_DATABASE_TYPE=mongodb 47 | 48 | # mongodb 49 | MONGODB_IMAGE=mongo 50 | MONGODB_IMAGE_TAG=4.0.0 51 | MONGODB_PORT=27017 52 | 53 | 54 | # API gateway and OAuth provider 55 | KRAKEND_IMAGE_TAG=2.1.3 56 | COGNITO_MOCK_IMAGE_TAG=0.2.2 57 | -------------------------------------------------------------------------------- /test/bdd/fixtures/aws-kms/seed.yaml: -------------------------------------------------------------------------------- 1 | Keys: 2 | Symmetric: 3 | Aes: 4 | - Metadata: 5 | KeyId: bc436485-5092-42b8-92a3-0aa8b93536dc 6 | BackingKeys: 7 | - 5cdaead27fe7da2de47945d73cd6d79e36494e73802f3cd3869f1d2cb0b5d7a9 8 | Asymmetric: 9 | Ecc: 10 | - Metadata: 11 | KeyId: 800d5768-3fd7-4edd-a4b8-4c81c3e4c147 12 | KeyUsage: SIGN_VERIFY 13 | Description: ECC key with curve secp256r1 14 | PrivateKeyPem: | 15 | -----BEGIN EC PRIVATE KEY----- 16 | MHcCAQEEIMnOrUrXr8rwne7d8f01cfwmpS/w+K7jcyWmmeLDgWKaoAoGCCqGSM49 17 | AwEHoUQDQgAEYNMBBZ3h1ipuph1iO5k+yLvTs94UN71quXN3f0P/tprs2Fp2FEas 18 | M7m7XZ2xlDK3wcEAs1QEIoQjjwnhcptQ6A== 19 | -----END EC PRIVATE KEY----- 20 | 21 | Aliases: 22 | - AliasName: alias/testing 23 | TargetKeyId: bc436485-5092-42b8-92a3-0aa8b93536dc -------------------------------------------------------------------------------- /test/bdd/fixtures/cognito-config/config.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/bdd/fixtures/cognito-config/db/clients.json: -------------------------------------------------------------------------------- 1 | { 2 | "Clients": { 3 | "f13d1va9lp403pb9lyj89vk55": { 4 | "ExplicitAuthFlows": [ 5 | "USER_PASSWORD_AUTH" 6 | ], 7 | "ClientId": "f13d1va9lp403pb9lyj89vk55", 8 | "ClientName": "Test Org", 9 | "ClientSecret": "ejqxi9jb1vew2jbdnogpjcgrz", 10 | "CreationDate": "2023-01-13T15:45:43.942Z", 11 | "LastModifiedDate": "2023-01-13T15:45:43.942Z", 12 | "TokenValidityUnits": { 13 | "AccessToken": "hours", 14 | "IdToken": "minutes", 15 | "RefreshToken": "days" 16 | }, 17 | "UserPoolId": "local_5a9GzRvB" 18 | }, 19 | "7d4u50e7w6nfq8tfayhzplgjf": { 20 | "AllowedOAuthFlows": [ 21 | "authorization_code" 22 | ], 23 | "AllowedOAuthScopes": [ 24 | "openid", 25 | "profile" 26 | ], 27 | "CallbackURLs": [ 28 | "https://api-gateway.trustbloc.local:5566/oidc/redirect" 29 | ], 30 | "ClientId": "7d4u50e7w6nfq8tfayhzplgjf", 31 | "ClientName": "Bank Issuer", 32 | "ClientSecret": "282ks4fkuqfosus5k0x30abnv", 33 | "CreationDate": "2023-01-17T13:02:14.380Z", 34 | "LastModifiedDate": "2023-01-17T13:02:14.380Z", 35 | "TokenValidityUnits": { 36 | "AccessToken": "hours", 37 | "IdToken": "minutes", 38 | "RefreshToken": "days" 39 | }, 40 | "UserPoolId": "local_5a9GzRvB" 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /test/bdd/fixtures/did-resolver/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "pattern": "^(did:factom:.+)$", 5 | "url": "https://uniresolver.io/1.0/identifiers/$1" 6 | }, 7 | { 8 | "pattern": "^(did:key:.+)$" 9 | }, 10 | { 11 | "pattern": "^(did:orb:.+)$" 12 | }, 13 | { 14 | "pattern": "^(did:web:.+)$" 15 | }, 16 | { 17 | "pattern": "^(did:ion:.+)$", 18 | "url": "https://uniresolver.io/1.0/identifiers/$1" 19 | }, 20 | { 21 | "pattern": "^(did:.+)$", 22 | "url": "http://uni-resolver-web:8080/1.0/identifiers/$1" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /test/bdd/fixtures/file-server/.well-known/oauth-client: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "https://file-server.trustbloc.local:10096", 3 | "client_name": "discoverable_client_id_scheme", 4 | "redirect_uris": [ 5 | "http://127.0.0.1/callback" 6 | ], 7 | "grant_types": [ 8 | "authorization_code" 9 | ], 10 | "response_types": [ 11 | "code" 12 | ], 13 | "scopes": [ 14 | "openid", 15 | "profile" 16 | ], 17 | "token_endpoint_auth_method": "none" 18 | } -------------------------------------------------------------------------------- /test/bdd/fixtures/krakend-config/generate-configs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function generate_krakend_config() { 4 | env=$1 5 | 6 | build_path="build/$env" 7 | 8 | mkdir -p "$build_path" 9 | 10 | docker run --rm -v "$PWD":/etc/krakend/ \ 11 | -e FC_ENABLE=1 \ 12 | -e FC_OUT="/etc/krakend/$build_path/krakend-raw.json" \ 13 | -e FC_PARTIALS="/etc/krakend/partials" \ 14 | -e FC_SETTINGS="/etc/krakend/settings" \ 15 | -e FC_TEMPLATES="/etc/krakend/templates" \ 16 | devopsfaith/krakend check -d -t -c krakend.tmpl 17 | 18 | if [ -x "$(command -v jq)" ] 19 | then 20 | jq '.' ./"$build_path"/krakend-raw.json > ./"$build_path"/krakend-formatted.json 21 | else 22 | echo "jq could not be found" 23 | fi 24 | } 25 | 26 | generate_krakend_config local 27 | -------------------------------------------------------------------------------- /test/bdd/fixtures/krakend-config/partials/x_api_key_header.tmpl: -------------------------------------------------------------------------------- 1 | "modifier/martian": { 2 | "header.Modifier": { 3 | "scope": [ 4 | "request" 5 | ], 6 | "name": "X-API-Key", 7 | "value": "rw_token" 8 | } 9 | } -------------------------------------------------------------------------------- /test/bdd/fixtures/krakend-config/settings/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 8080, 3 | "default_hosts": [ 4 | "http://vc-rest-echo.trustbloc.local:8075" 5 | ], 6 | "timeout": "3s", 7 | "cache_ttl": "300s", 8 | "tls": { 9 | "public_key": "/etc/tls/ec-pubCert.pem", 10 | "private_key": "/etc/tls/ec-key.pem" 11 | }, 12 | "plugin": { 13 | "pattern": ".so", 14 | "folder": "/etc/krakend/plugins/" 15 | } 16 | } -------------------------------------------------------------------------------- /test/bdd/fixtures/krakend-config/templates/auth_validator.tmpl: -------------------------------------------------------------------------------- 1 | "auth/validator": { 2 | "alg": "RS256", 3 | "scopes": [ 4 | "org_admin" 5 | ], 6 | "jwk_url": "http://cognito-mock.trustbloc.local:9229/local_5a9GzRvB/.well-known/jwks.json", 7 | "cache": true, 8 | "disable_jwk_security": true, 9 | "operation_debug": true, 10 | "propagate_claims": [ 11 | [ 12 | "custom:tenant_id", 13 | "x-tenant-id" 14 | ] 15 | {{ if .propagate_roles_header }} 16 | , 17 | [ 18 | "custom:roles", 19 | "x-client-roles" 20 | ] 21 | 22 | {{ end }} 23 | ] 24 | {{ if .roles_to_validate }} 25 | , 26 | "roles_key": "custom:roles", 27 | "roles": [ 28 | {{range $index, $role := .roles_to_validate }} {{if $index}},{{end}} "{{$role}}" {{ end }} 29 | ] 30 | {{ end }} 31 | } -------------------------------------------------------------------------------- /test/bdd/fixtures/mysql-config/mysql_config.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | \! echo "Configuring MySQL users..."; 8 | 9 | /* 10 | oidc provider (hydra) 11 | */ 12 | CREATE USER 'thirdpartyoidc'@'%' IDENTIFIED BY 'thirdpartyoidc-secret-pw'; 13 | CREATE DATABASE thirdpartyoidc; 14 | GRANT ALL PRIVILEGES ON thirdpartyoidc.* TO 'thirdpartyoidc'@'%'; 15 | -------------------------------------------------------------------------------- /test/bdd/fixtures/nginx-config/data/.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | * 7 | */ 8 | !.gitignore -------------------------------------------------------------------------------- /test/bdd/fixtures/nginx-config/nginx.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | events {} 8 | 9 | http { 10 | 11 | server { 12 | listen 8076; 13 | 14 | root /var/www/data; 15 | 16 | location / { 17 | } 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /test/bdd/fixtures/oauth-clients/clients.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "client_id": "oidc4vc_client", 4 | "redirect_uris": ["http://127.0.0.1/callback"], 5 | "grant_types": ["authorization_code"], 6 | "response_types": ["code"], 7 | "scopes": [ 8 | "openid", 9 | "profile", 10 | "VerifiedEmployeeCredential_001", 11 | "UniversityDegreeCredential_001", 12 | "CrudeProductCredential_001" 13 | ], 14 | "token_endpoint_auth_method": "none" 15 | } 16 | ] -------------------------------------------------------------------------------- /test/bdd/fixtures/prometheus-config/prometheus.yml: -------------------------------------------------------------------------------- 1 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | # Global config 7 | global: 8 | scrape_interval: 2s # Set the scrape interval to every 2 seconds. Default is every 1 minute. 9 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 10 | # scrape_timeout is set to the global default (10s). 11 | 12 | # Alertmanager configuration 13 | alerting: 14 | alertmanagers: 15 | - static_configs: 16 | - targets: 17 | # - alertmanager:9093 18 | 19 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 20 | rule_files: 21 | # - "first_rules.yml" 22 | # - "second_rules.yml" 23 | 24 | # A scrape configuration containing exactly one endpoint to scrape: 25 | # Here it's Prometheus itself. 26 | scrape_configs: 27 | # The job name is added as a label `job=` to any timeseries scraped from this config. 28 | - job_name: 'prometheus' 29 | 30 | # metrics_path defaults to '/metrics' 31 | # scheme defaults to 'http'. 32 | scheme: http 33 | 34 | static_configs: 35 | - targets: ['vc-rest-echo.trustbloc.local:48127'] 36 | -------------------------------------------------------------------------------- /test/bdd/fixtures/universal-resolver/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "drivers": [ 3 | { 4 | "pattern": "^(did:v1:test:nym:.+)$", 5 | "image": "veresone/uni-resolver-did-v1-driver", 6 | "imageProperties": "true", 7 | "tag": "latest" 8 | }, 9 | { 10 | "pattern": "^(did:web:.+)$", 11 | "image": "uport/uni-resolver-driver-did-uport", 12 | "imagePort": "8081", 13 | "tag": "latest" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /test/bdd/fixtures/universal-resolver/run-uni-resolver-web.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright SecureKey Technologies Inc. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | cd /opt/uni-resolver-java/uni-resolver-web/ 9 | mvn jetty:run 10 | -------------------------------------------------------------------------------- /test/bdd/krakend-plugins/http-client-no-redirect/go.mod: -------------------------------------------------------------------------------- 1 | // Copyright Avast Software. All Rights Reserved. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | module http-client-no-redirect 6 | 7 | go 1.22 8 | -------------------------------------------------------------------------------- /test/bdd/krakend-plugins/http-client-no-redirect/go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustbloc/vcs/e8fcdb8eddaafa8f40485d979b360dd359245d16/test/bdd/krakend-plugins/http-client-no-redirect/go.sum -------------------------------------------------------------------------------- /test/bdd/loginconsent/go.mod: -------------------------------------------------------------------------------- 1 | // Copyright Avast Software. All Rights Reserved. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | module github.com/trustbloc/vcs/test/bdd/loginconsent 6 | 7 | go 1.22 8 | 9 | require ( 10 | github.com/google/uuid v1.3.0 11 | github.com/gorilla/mux v1.8.0 12 | github.com/ory/hydra-client-go v1.11.8 13 | github.com/stretchr/testify v1.8.0 14 | gopkg.in/square/go-jose.v2 v2.6.0 15 | ) 16 | 17 | require ( 18 | github.com/davecgh/go-spew v1.1.1 // indirect 19 | github.com/golang/protobuf v1.5.2 // indirect 20 | github.com/pmezard/go-difflib v1.0.0 // indirect 21 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect 22 | golang.org/x/net v0.7.0 // indirect 23 | golang.org/x/oauth2 v0.1.0 // indirect 24 | google.golang.org/appengine v1.6.7 // indirect 25 | google.golang.org/protobuf v1.28.1 // indirect 26 | gopkg.in/yaml.v3 v3.0.1 // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /test/bdd/pkg/bddutil/contexts/examples-v2.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@vocab": "https://www.w3.org/ns/credentials/examples#" 4 | } 5 | } -------------------------------------------------------------------------------- /test/bdd/pkg/v1/vc/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vc 8 | 9 | type VerificationResult struct { 10 | Code string `json:"code"` 11 | Message string `json:"message"` 12 | IncorrectValue string `json:"incorrect_value"` 13 | } 14 | -------------------------------------------------------------------------------- /test/bdd/testdata/danubetech_vc1.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1" 5 | ], 6 | "type": [ 7 | "VerifiableCredential", 8 | "UniversityDegreeCredential" 9 | ], 10 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 11 | "issuanceDate": "2020-05-11T22:04:22Z", 12 | "issuer": "did:v1:test:nym:z6MkfqxbQu6ikzpZRM3GwaFiUzy5vDgbmt99MGLA38kZUnEB", 13 | "credentialSubject": { 14 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 15 | "degree": { 16 | "type": "BachelorDegree", 17 | "degree": "MIT" 18 | }, 19 | "name": "Jayden Doe", 20 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 21 | } 22 | } -------------------------------------------------------------------------------- /test/bdd/testdata/danubetech_vc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/citizenship/v1" 5 | ], 6 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 7 | "type": [ 8 | "VerifiableCredential", 9 | "PermanentResidentCard" 10 | ], 11 | "name": "Permanent Resident Card", 12 | "description": "Permanent Resident Card", 13 | "issuer": "did:v1:test:nym:z6MkfqxbQu6ikzpZRM3GwaFiUzy5vDgbmt99MGLA38kZUnEB", 14 | "issuanceDate": "2020-05-11T22:04:24Z", 15 | "expirationDate": "2029-12-03T12:19:52Z", 16 | "credentialSubject": { 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "givenName": "JOHN", 23 | "familyName": "SMITH", 24 | "gender": "Male", 25 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 26 | "residentSince": "2015-01-01", 27 | "lprCategory": "C09", 28 | "lprNumber": "999-999-999", 29 | "commuterClassification": "C1", 30 | "birthCountry": "Bahamas", 31 | "birthDate": "1958-07-17" 32 | }, 33 | "proof": { 34 | "type": "Ed25519Signature2018", 35 | "created": "2020-05-11T22:04:24Z", 36 | "proofPurpose": "assertionMethod", 37 | "verificationMethod": "did:v1:test:nym:z6MkfqxbQu6ikzpZRM3GwaFiUzy5vDgbmt99MGLA38kZUnEB#z6MkgmQGoevpPSeqb74jYSomuoWhXyJ9t5XtMAPq6NVFGssL", 38 | "jws": "eyJjcml0IjpbImI2NCJdLCJiNjQiOmZhbHNlLCJhbGciOiJFZERTQSJ9..qpy3ECZXjchOWxMnjJ6PaM_dr2La8-YTrDBZIR3xtdc7ZBwbsMPKByz_J9h0xo_ejiD1IwhLpfo5zGIRfGegAA" 39 | } 40 | } -------------------------------------------------------------------------------- /test/bdd/testdata/digitalbazaar_vc1.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/citizenship/v1" 5 | ], 6 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 7 | "type": [ 8 | "VerifiableCredential", 9 | "PermanentResidentCard" 10 | ], 11 | "name": "Permanent Resident Card", 12 | "description": "Permanent Resident Card", 13 | "issuer": "did:key:z6Mki2dzq2PLm7crMwq8aTz4Nx3RXNUCaLLmytKdAxL8KyXx", 14 | "issuanceDate": "2019-12-03T12:19:52Z", 15 | "expirationDate": "2029-12-03T12:19:52Z", 16 | "credentialSubject": { 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "givenName": "JOHN", 23 | "familyName": "SMITH", 24 | "gender": "Male", 25 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 26 | "residentSince": "2015-01-01", 27 | "lprCategory": "C09", 28 | "lprNumber": "999-999-999", 29 | "commuterClassification": "C1", 30 | "birthCountry": "Bahamas", 31 | "birthDate": "1958-07-17" 32 | }, 33 | "proof": { 34 | "type": "Ed25519Signature2018", 35 | "created": "2020-05-11T22:04:21Z", 36 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..5SFp4pG1xKhRjl_HbstFU3IC60bG4QHtAYJW9JE1ElYestw0-y2jLNkPYRWiW6WwSSK94S-ZSvbW04-MCdeiCQ", 37 | "proofPurpose": "assertionMethod", 38 | "verificationMethod": "did:key:z6Mki2dzq2PLm7crMwq8aTz4Nx3RXNUCaLLmytKdAxL8KyXx#z6Mki2dzq2PLm7crMwq8aTz4Nx3RXNUCaLLmytKdAxL8KyXx" 39 | } 40 | } -------------------------------------------------------------------------------- /test/bdd/testdata/factom_vc1.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1" 5 | ], 6 | "type": [ 7 | "VerifiableCredential", 8 | "UniversityDegreeCredential" 9 | ], 10 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 11 | "issuanceDate": "2020-03-16T22:37:26.544Z", 12 | "issuer": "did:factom:5d0dd58757119dd437c70d92b44fbf86627ee275f0f2146c3d99e441da342d9f", 13 | "credentialSubject": { 14 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 15 | "degree": { 16 | "type": "BachelorDegree", 17 | "degree": "MIT" 18 | }, 19 | "name": "Jayden Doe", 20 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 21 | }, 22 | "proof": { 23 | "type": "Ed25519Signature2018", 24 | "created": "2020-05-11T22:04:39Z", 25 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..y87895mDkpEwFWRcsZ89DuGW8YPvK7VysrHBq8liBMF5Pf2uVM75sBWQFbL80g8KaTxKJxNtPNLks5Pb4QQOCw", 26 | "proofPurpose": "assertionMethod", 27 | "verificationMethod": "did:factom:5d0dd58757119dd437c70d92b44fbf86627ee275f0f2146c3d99e441da342d9f#key-0" 28 | } 29 | } -------------------------------------------------------------------------------- /test/bdd/testdata/factom_vc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/citizenship/v1" 5 | ], 6 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 7 | "type": [ 8 | "VerifiableCredential", 9 | "PermanentResidentCard" 10 | ], 11 | "name": "Permanent Resident Card", 12 | "description": "Permanent Resident Card", 13 | "issuer": "did:factom:5d0dd58757119dd437c70d92b44fbf86627ee275f0f2146c3d99e441da342d9f", 14 | "issuanceDate": "2019-12-03T12:19:52Z", 15 | "expirationDate": "2029-12-03T12:19:52Z", 16 | "credentialSubject": { 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "givenName": "JOHN", 23 | "familyName": "SMITH", 24 | "gender": "Male", 25 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 26 | "residentSince": "2015-01-01", 27 | "lprCategory": "C09", 28 | "lprNumber": "999-999-999", 29 | "commuterClassification": "C1", 30 | "birthCountry": "Bahamas", 31 | "birthDate": "1958-07-17" 32 | }, 33 | "proof": { 34 | "type": "Ed25519Signature2018", 35 | "created": "2020-05-11T22:04:40Z", 36 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..V0Ld7A7HRIlVnubgpmGi1xjXzK3s7FIS9_bLuOE96jgzC9Mk-4c4FOAnQbLcEfPsgUO6pGBNTovQlRHyK-mqBA", 37 | "proofPurpose": "assertionMethod", 38 | "verificationMethod": "did:factom:5d0dd58757119dd437c70d92b44fbf86627ee275f0f2146c3d99e441da342d9f#key-0" 39 | } 40 | } -------------------------------------------------------------------------------- /test/bdd/testdata/mavennet_vc1.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1" 5 | ], 6 | "type": [ 7 | "VerifiableCredential", 8 | "UniversityDegreeCredential" 9 | ], 10 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 11 | "issuanceDate": "2020-03-16T22:37:26.544Z", 12 | "issuer": "did:v1:test:nym:z6MkfG5HTrBXzsAP8AbayNpG3ZaoyM4PCqNPrdWQRSpHDV6J", 13 | "credentialSubject": { 14 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 15 | "degree": { 16 | "type": "BachelorDegree", 17 | "degree": "MIT" 18 | }, 19 | "name": "Jayden Doe", 20 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 21 | }, 22 | "proof": { 23 | "type": "Ed25519Signature2018", 24 | "created": "2020-05-11T22:04:25Z", 25 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ox4nPlKPNgjYhaI0wUJtmoLbut7bXbO9-4BRGCaXDk_4RKSsPqoqrHjBUmnq9RnXGCZx2j5quL6gDHdLuPUYBQ", 26 | "proofPurpose": "assertionMethod", 27 | "verificationMethod": "did:v1:test:nym:z6MkfG5HTrBXzsAP8AbayNpG3ZaoyM4PCqNPrdWQRSpHDV6J#z6MkqfvdBsFw4QdGrZrnx7L1EKfY5zh9tT4gumUGsMMEZHY3" 28 | } 29 | } -------------------------------------------------------------------------------- /test/bdd/testdata/mavennet_vc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/citizenship/v1" 5 | ], 6 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 7 | "type": [ 8 | "VerifiableCredential", 9 | "PermanentResidentCard" 10 | ], 11 | "name": "Permanent Resident Card", 12 | "description": "Permanent Resident Card", 13 | "issuer": "did:v1:test:nym:z6MkfG5HTrBXzsAP8AbayNpG3ZaoyM4PCqNPrdWQRSpHDV6J", 14 | "issuanceDate": "2019-12-03T12:19:52Z", 15 | "expirationDate": "2029-12-03T12:19:52Z", 16 | "credentialSubject": { 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "givenName": "JOHN", 23 | "familyName": "SMITH", 24 | "gender": "Male", 25 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 26 | "residentSince": "2015-01-01", 27 | "lprCategory": "C09", 28 | "lprNumber": "999-999-999", 29 | "commuterClassification": "C1", 30 | "birthCountry": "Bahamas", 31 | "birthDate": "1958-07-17" 32 | }, 33 | "proof": { 34 | "type": "Ed25519Signature2018", 35 | "created": "2020-05-11T22:04:28Z", 36 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..1ClIc5Vyfz2zQ5SAT2pmX30dAlrltd3ezhxsls7Uu87VyW3PgiDif7Bv6MPt5lmDYtFKiPmAeuEUNY1clJv1Dw", 37 | "proofPurpose": "assertionMethod", 38 | "verificationMethod": "did:v1:test:nym:z6MkfG5HTrBXzsAP8AbayNpG3ZaoyM4PCqNPrdWQRSpHDV6J#z6MkqfvdBsFw4QdGrZrnx7L1EKfY5zh9tT4gumUGsMMEZHY3" 39 | } 40 | } -------------------------------------------------------------------------------- /test/bdd/testdata/permanent_resident_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/citizenship/v1" 5 | ], 6 | "id": "https://issuer.oidp.uscis.gov/credentials/83627465", 7 | "type": [ 8 | "VerifiableCredential", 9 | "PermanentResidentCard" 10 | ], 11 | "name": "Permanent Resident Card", 12 | "description": "Permanent Resident Card", 13 | "issuer": "did:example:28394728934792387", 14 | "issuanceDate": "2019-12-03T12:19:52Z", 15 | "expirationDate": "2029-12-03T12:19:52Z", 16 | "credentialSubject": { 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "givenName": "JOHN", 23 | "familyName": "SMITH", 24 | "gender": "Male", 25 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 26 | "residentSince": "2015-01-01", 27 | "lprCategory": "C09", 28 | "lprNumber": "999-999-999", 29 | "commuterClassification": "C1", 30 | "birthCountry": "Bahamas", 31 | "birthDate": "1958-07-17" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/bdd/testdata/profile_request_template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "uri": "https://example.com/credentials", 4 | "signatureType": "", 5 | "signatureRepresentation": 1 6 | } 7 | -------------------------------------------------------------------------------- /test/bdd/testdata/sicpa_vc1.json: -------------------------------------------------------------------------------- 1 | { 2 | "issuanceDate":"2020-03-16T22:37:26.544Z", 3 | "credentialSubject":{ 4 | "degree":{ 5 | "degree":"MIT", 6 | "type":"BachelorDegree" 7 | }, 8 | "name":"Jayden Doe", 9 | "id":"did:example:ebfeb1f712ebc6f1c276e12ec21", 10 | "spouse":"did:example:c276e12ec21ebfeb1f712ebc6f1" 11 | }, 12 | "id":"http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c#23132ee9-d55d-4f7e-a138-1a655e23a178", 13 | "type":[ 14 | "VerifiableCredential", 15 | "UniversityDegreeCredential" 16 | ], 17 | "@context":[ 18 | "https://www.w3.org/2018/credentials/v1", 19 | "https://www.w3.org/2018/credentials/examples/v1" 20 | ], 21 | "issuer":{ 22 | "name":"University", 23 | "id":"did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN" 24 | }, 25 | "proof":{ 26 | "created":"2020-05-13T21:02:52.665Z", 27 | "proofPurpose":"assertionMethod", 28 | "type":"Ed25519Signature2018", 29 | "verificationMethod":"did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN#z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN", 30 | "jws":"eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..UTbPZpmZSL4txaFGFni5i3SsrfCQzARE7-S04Ia-wjfoHx7jfCXBVOuxpocPod2QzAct7A4Z5abKY0iGdn3mBQ" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/bdd/testdata/sicpa_vc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "issuanceDate":"2019-12-03T12:19:52Z", 3 | "credentialSubject":{ 4 | "image":"data:image/png;base64,iVBORw0KGgo...kJggg==", 5 | "lprNumber":"999-999-999", 6 | "gender":"Male", 7 | "residentSince":"2015-01-01", 8 | "givenName":"JOHN", 9 | "familyName":"SMITH", 10 | "birthCountry":"Bahamas", 11 | "id":"did:example:b34ca6cd37bbf23", 12 | "commuterClassification":"C1", 13 | "type":[ 14 | "PermanentResident", 15 | "Person" 16 | ], 17 | "birthDate":"1958-07-17", 18 | "lprCategory":"C09" 19 | }, 20 | "name":"Permanent Resident Card", 21 | "description":"Permanent Resident Card", 22 | "id":"http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c#13250913-eb53-4418-9077-fb429f6b033f", 23 | "type":[ 24 | "VerifiableCredential", 25 | "PermanentResidentCard" 26 | ], 27 | "@context":[ 28 | "https://www.w3.org/2018/credentials/v1", 29 | "https://w3id.org/citizenship/v1" 30 | ], 31 | "issuer":"did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN", 32 | "expirationDate":"2029-12-03T12:19:52Z", 33 | "proof":{ 34 | "created":"2020-05-13T20:58:47.687Z", 35 | "proofPurpose":"assertionMethod", 36 | "type":"Ed25519Signature2018", 37 | "verificationMethod":"did:key:z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN#z6MkrqCMy45WhL3UEa1gGTHUtr17AvU4czfP5fH9KNDoYaYN", 38 | "jws":"eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..ZmIGBjpui632KMVRQyk_obaOllC0BrBsqmL_pIzugsTuyBJ5k6w1YoJjK80mfPMHGM2cxAPVmWRIscDelSpfBw" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/bdd/testdata/transmute_vc1.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1" 5 | ], 6 | "type": [ 7 | "VerifiableCredential", 8 | "UniversityDegreeCredential" 9 | ], 10 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 11 | "issuanceDate": "2020-03-16T22:37:26.544Z", 12 | "issuer": { 13 | "id": "did:web:vc.transmute.world", 14 | "name": "University" 15 | }, 16 | "credentialSubject": { 17 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 18 | "degree": { 19 | "type": "BachelorDegree", 20 | "degree": "MIT" 21 | }, 22 | "name": "Jayden Doe", 23 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 24 | }, 25 | "proof": { 26 | "type": "Ed25519Signature2018", 27 | "created": "2019-12-11T03:50:55Z", 28 | "verificationMethod": "did:web:vc.transmute.world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN", 29 | "proofPurpose": "assertionMethod", 30 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..hckTjvJ8umMsgAdsgPfAYGKYh-4IqqvuGOX_kbNMwpkwyslFj_XKl06wgJDDMLkmnvHHEk74FDBUL_F_0mdeAA" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/bdd/testdata/transmute_vc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://w3id.org/citizenship/v1" 5 | ], 6 | "id": "http://example.gov/credentials/ff98f978-588f-4eb0-b17b-60c18e1dac2c", 7 | "type": [ 8 | "VerifiableCredential", 9 | "PermanentResidentCard" 10 | ], 11 | "name": "Permanent Resident Card", 12 | "description": "Permanent Resident Card", 13 | "issuer": "did:web:vc.transmute.world", 14 | "issuanceDate": "2019-12-03T12:19:52Z", 15 | "expirationDate": "2029-12-03T12:19:52Z", 16 | "credentialSubject": { 17 | "id": "did:example:b34ca6cd37bbf23", 18 | "type": [ 19 | "PermanentResident", 20 | "Person" 21 | ], 22 | "givenName": "JOHN", 23 | "familyName": "SMITH", 24 | "gender": "Male", 25 | "image": "data:image/png;base64,iVBORw0KGgo...kJggg==", 26 | "residentSince": "2015-01-01", 27 | "lprCategory": "C09", 28 | "lprNumber": "999-999-999", 29 | "commuterClassification": "C1", 30 | "birthCountry": "Bahamas", 31 | "birthDate": "1958-07-17" 32 | }, 33 | "proof": { 34 | "type": "Ed25519Signature2018", 35 | "created": "2019-12-11T03:50:55Z", 36 | "verificationMethod": "did:web:vc.transmute.world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN", 37 | "proofPurpose": "assertionMethod", 38 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..SeUoIpwN_1Zrwc9zcl5NuvI88eJh6mWcxUMROHLrRg9Ubrz1YBhprPjcIZVE9JikK2DOO75pwC06fEwmu4GUAw" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/bdd/testdata/university_certificate.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context":["https://www.w3.org/2018/credentials/v1"], 3 | "id": "http://example.edu/credentials/1872", 4 | "type": "VerifiableCredential", 5 | "credentialSubject": { 6 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21" 7 | }, 8 | "issuer": { 9 | "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", 10 | "name": "Example University" 11 | }, 12 | "issuanceDate": "2010-01-01T19:23:24Z" 13 | } 14 | -------------------------------------------------------------------------------- /test/bdd/testdata/university_degree.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1" 5 | ], 6 | "type": [ 7 | "VerifiableCredential", 8 | "UniversityDegreeCredential" 9 | ], 10 | "id": "http://example.gov/credentials/3732", 11 | "issuanceDate": "2020-03-16T22:37:26.544Z", 12 | "issuer": { 13 | "id": "did:example:oakek12as93mas91220dapop092", 14 | "name": "University" 15 | }, 16 | "credentialSubject": { 17 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 18 | "degree": { 19 | "type": "BachelorDegree", 20 | "degree": "MIT" 21 | }, 22 | "name": "Jayden Doe", 23 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 24 | } 25 | } -------------------------------------------------------------------------------- /test/bdd/testdata/university_degree.jwt: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJleHAiOjE1Nzc5MDY2MDQsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L2Jicy92MSJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwidW5pdmVyc2l0eSI6Ik1JVCJ9LCJpZCI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsIm5hbWUiOiJKYXlkZW4gRG9lIiwic3BvdXNlIjoiZGlkOmV4YW1wbGU6YzI3NmUxMmVjMjFlYmZlYjFmNzEyZWJjNmYxIn0sImV4cGlyYXRpb25EYXRlIjoiMjAyMC0wMS0wMVQxOToyMzoyNFoiLCJpZCI6Imh0dHA6Ly9leGFtcGxlLmVkdS9jcmVkZW50aWFscy8xODcyIiwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQxOToyMzoyNFoiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6ZXhhbXBsZTo3NmUxMmVjNzEyZWJjNmYxYzIyMWViZmViMWYiLCJuYW1lIjoiRXhhbXBsZSBVbml2ZXJzaXR5In0sInJlZmVyZW5jZU51bWJlciI6OC4zMjk0ODQ3ZSswNywidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ. -------------------------------------------------------------------------------- /test/bdd/testdata/university_degree_invalid_claims.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://www.w3.org/2018/credentials/v1", 4 | "https://www.w3.org/2018/credentials/examples/v1" 5 | ], 6 | "type": [ 7 | "VerifiableCredential", 8 | "UniversityDegreeCredential" 9 | ], 10 | "id": "http://example.gov/credentials/3732", 11 | "issuanceDate": "2020-03-16T22:37:26.544Z", 12 | "issuer": { 13 | "id": "did:example:oakek12as93mas91220dapop092", 14 | "name": "University" 15 | }, 16 | "credentialSubject": { 17 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 18 | "degree": { 19 | "type": "BachelorDegree", 20 | "degree": "MIT" 21 | }, 22 | "name": "Jayden Doe", 23 | "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1", 24 | "totallyRandomField": "abcd" 25 | } 26 | } -------------------------------------------------------------------------------- /test/bdd/trustregistry/go.mod: -------------------------------------------------------------------------------- 1 | // Copyright Avast Software. All Rights Reserved. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | module github.com/trustbloc/vcs/test/bdd/trustregistry 6 | 7 | go 1.22 8 | 9 | require ( 10 | github.com/gorilla/mux v1.8.0 11 | github.com/samber/lo v1.39.0 12 | ) 13 | 14 | require golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect 15 | -------------------------------------------------------------------------------- /test/bdd/trustregistry/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 2 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 3 | github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= 4 | github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= 5 | golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= 6 | golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= 7 | -------------------------------------------------------------------------------- /test/bdd/trustregistry/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package main 8 | 9 | import ( 10 | "log" 11 | "net/http" 12 | "os" 13 | ) 14 | 15 | func main() { 16 | serveCertPath := os.Getenv("TLS_CERT_PATH") 17 | if serveCertPath == "" { 18 | log.Fatalf("TLS_CERT_PATH is required") 19 | 20 | return 21 | } 22 | 23 | serveKeyPath := os.Getenv("TLS_KEY_PATH") 24 | if serveKeyPath == "" { 25 | log.Fatalf("TLS_KEY_PATH is required") 26 | 27 | return 28 | } 29 | 30 | listenAddr := os.Getenv("LISTEN_ADDR") 31 | if listenAddr == "" { 32 | log.Fatalf("LISTEN_ADDR is required") 33 | 34 | return 35 | } 36 | 37 | log.Printf("Listening on %s", listenAddr) 38 | 39 | log.Fatal(http.ListenAndServeTLS( 40 | listenAddr, 41 | serveCertPath, serveKeyPath, 42 | newServer(), 43 | )) 44 | } 45 | -------------------------------------------------------------------------------- /test/stress/cmd/cluster.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright SecureKey Technologies Inc. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package main 8 | 9 | import ( 10 | "context" 11 | "fmt" 12 | "os" 13 | "strings" 14 | 15 | "github.com/redis/go-redis/v9" 16 | ) 17 | 18 | func getNodeName() string { 19 | hostName, _ := os.Hostname() 20 | if v := os.Getenv("CUSTOM_HOST"); v != "" { 21 | hostName = v 22 | } 23 | 24 | return strings.ReplaceAll(hostName, ".", "-") 25 | } 26 | 27 | func getClusterMembers(ctx context.Context, rdb redis.UniversalClient) (map[string]string, error) { 28 | resp := rdb.HGetAll(ctx, orchestratorKey) 29 | if resp.Err() != nil { 30 | return nil, resp.Err() 31 | } 32 | 33 | result, err := resp.Result() 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | return result, nil 39 | } 40 | 41 | func getClusterResultKey(id string) string { 42 | return fmt.Sprintf("stress:cluster:result:%v", id) 43 | } 44 | 45 | func getResultKey(id string) string { 46 | return fmt.Sprintf("stress:result:%v", id) 47 | } 48 | -------------------------------------------------------------------------------- /test/stress/pkg/stress/mitm.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Avast Software. All Rights Reserved. 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package stress 8 | 9 | import "net/http" 10 | 11 | type mitmTransport struct { 12 | root http.RoundTripper 13 | requestInterceptor func(request *http.Request, parent http.RoundTripper) (*http.Response, error) 14 | } 15 | 16 | func (m *mitmTransport) RoundTrip(request *http.Request) (*http.Response, error) { 17 | return m.requestInterceptor(request, m.root) 18 | } 19 | --------------------------------------------------------------------------------