private async Task <(IssuerCreateCredentialResult, RevocationRegistryRecord)> IssueCredentialSafeAsync( IAgentContext agentContext, DefinitionRecord definitionRecord, CredentialRecord credentialRecord) { BlobStorageReader tailsReader = null; RevocationRegistryRecord revocationRecord = null; if (definitionRecord.SupportsRevocation) { revocationRecord = await RecordService.GetAsync <RevocationRegistryRecord>(agentContext.Wallet, definitionRecord.CurrentRevocationRegistryId); tailsReader = await TailsService.OpenTailsAsync(revocationRecord.TailsFile); } try { return(await AnonCreds.IssuerCreateCredentialAsync( agentContext.Wallet, credentialRecord.OfferJson, credentialRecord.RequestJson, CredentialUtils.FormatCredentialValues(credentialRecord.CredentialAttributesValues), definitionRecord.CurrentRevocationRegistryId, tailsReader), revocationRecord); } catch (RevocationRegistryFullException) { if (!definitionRecord.RevocationAutoScale) { throw; } } var registryIndex = definitionRecord.CurrentRevocationRegistryId.Split(':').LastOrDefault()?.Split('-').FirstOrDefault(); string registryTag; if (int.TryParse(registryIndex, out var currentIndex)) { registryTag = $"{currentIndex + 1}-{definitionRecord.MaxCredentialCount}"; } else { registryTag = $"1-{definitionRecord.MaxCredentialCount}"; } var(_, nextRevocationRecord) = await SchemaService.CreateRevocationRegistryAsync(agentContext, registryTag, definitionRecord); definitionRecord.CurrentRevocationRegistryId = nextRevocationRecord.Id; await RecordService.UpdateAsync(agentContext.Wallet, definitionRecord); tailsReader = await TailsService.OpenTailsAsync(nextRevocationRecord.TailsFile); return(await AnonCreds.IssuerCreateCredentialAsync( agentContext.Wallet, credentialRecord.OfferJson, credentialRecord.RequestJson, CredentialUtils.FormatCredentialValues(credentialRecord.CredentialAttributesValues), nextRevocationRecord.Id, tailsReader), nextRevocationRecord); }
public async Task TestProverStoreClaimWorks() { await InitCommonWallet(); var proverWalletName = "proverWallet"; await Wallet.CreateWalletAsync("default", proverWalletName, "default", null, null); var proverWallet = await Wallet.OpenWalletAsync(proverWalletName, null, null); await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, masterSecretName); var claimOffer = string.Format(claimOfferTemplate, issuerDid, 1); var claimRequest = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, claimOffer, claimDef, masterSecretName); var claim = "{\"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + " \"height\":[\"175\",\"175\"],\n" + " \"age\":[\"28\",\"28\"]\n" + " }"; var createClaimResult = await AnonCreds.IssuerCreateCredentialAsync(commonWallet, claimRequest, claim, -1); var claimJson = createClaimResult.ClaimJson; await AnonCreds.ProverStoreClaimAsync(proverWallet, claimJson, createClaimResult.RevocRegUpdateJson); await proverWallet.CloseAsync(); await Wallet.DeleteWalletAsync(proverWalletName, null); }
public async Task TestIssuerCreateAndStoreClaimWorks() { await InitCommonWallet(); var claimRequest = string.Format(claimRequestTemplate, issuerDid, 1); var claim = "{\"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + " \"height\":[\"175\",\"175\"],\n" + " \"age\":[\"28\",\"28\"]\n" + " }"; var createClaimResult = await AnonCreds.IssuerCreateCredentialAsync(commonWallet, claimRequest, claim, -1); Assert.IsNotNull(createClaimResult); var claimJson = createClaimResult.ClaimJson; var claimObj = JObject.Parse(claimJson); var primaryClaim = claimObj["signature"]["primary_claim"]; Assert.IsTrue(primaryClaim.Value <string>("a").Length > 0); Assert.IsTrue(primaryClaim.Value <string>("m2").Length > 0); Assert.IsTrue(primaryClaim.Value <string>("e").Length > 0); Assert.IsTrue(primaryClaim.Value <string>("v").Length > 0); }
public async Task TestIssuerCreateAndStoreCredentialReqWorksForInvalidCredentialValues() { var credentialValues = "{\"sex\":\"male\",\n" + " \"age\":\"28\"" + " }"; var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.IssuerCreateCredentialAsync(wallet, issuer1GvtCredOffer, issuer1GvtCredReq, credentialValues, null, null) ); }
public async Task TestIssuerCreateAndStoreClaimWorksForClaimDoesNotCorrespondToClaimRequest() { await InitCommonWallet(); var claimRequest = string.Format(claimRequestTemplate, issuerDid, 1); var claim = "{\"status\":[\"partial\",\"51792877103171595686471452153480627530895\"],\n" + " \"period\":[\"8\",\"8\"]\n" + " }"; var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.IssuerCreateCredentialAsync(commonWallet, claimRequest, claim, -1) ); }
public async Task TestIssuerCreateAndStoreClaimReqWorksForInvalidClaim() { await InitCommonWallet(); String claimRequest = string.Format(claimRequestTemplate, issuerDid, 1); String claim = "{\"sex\":\"male\",\n" + " \"name\":\"Alex\",\n" + " \"height\":\"175\",\n" + " \"age\":\"28\"" + " }"; var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.IssuerCreateCredentialAsync(commonWallet, claimRequest, claim, -1) ); }
public async Task Before() { StorageUtils.CleanupStorage(); //1. Create Issuer wallet, get wallet handle await Wallet.CreateWalletAsync("default", _walletName, "default", null, null); _issuerWallet = await Wallet.OpenWalletAsync(_walletName, null, null); //2. Issuer create claim definition _claimDefJson = await AnonCreds.IssuerCreateAndStoreClaimDefAsync(_issuerWallet, issuerDid, schema, null, true); //3. Issuer create revocation registry await AnonCreds.IssuerCreateAndStoreRevocRegAsync(_issuerWallet, issuerDid, 1, 5); //4. Prover create Master Secret await AnonCreds.ProverCreateMasterSecretAsync(_issuerWallet, masterSecretName); //5. Prover store Claim Offer received from Issuer var claimOfferJson = string.Format(claimOfferTemplate, issuerDid, 1); await AnonCreds.ProverStoreCredentialOfferAsync(_issuerWallet, claimOfferJson); //6. Prover create Claim Request var proverDid = "BzfFCYk"; var claimReq = await AnonCreds.ProverCreateCredentialReqAsync( _issuerWallet, proverDid, claimOfferJson, _claimDefJson, masterSecretName); //7. Issuer create Claim var claimJson = "{" + "\"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"]," + "\"name\":[\"Alex\",\"1139481716457488690172217916278103335\"]," + "\"height\":[\"175\",\"175\"]," + "\"age\":[\"28\",\"28\"]" + "}"; _claimResult = await AnonCreds.IssuerCreateCredentialAsync(_issuerWallet, claimReq, claimJson, _userRevocIndex); //8. Prover store received Claim await AnonCreds.ProverStoreClaimAsync(_issuerWallet, _claimResult.CredentialJson, _claimResult.RevocRegDeltaJson); }
public async Task <string> createCredential(string credOfferJson, string credReqJson, string credValueJson, string revRegId = null, BlobStorageReader blob = null) { try { var cred = await AnonCreds.IssuerCreateCredentialAsync( d_openWallet, credOfferJson, credReqJson, credValueJson, revRegId, blob); // cred: {CredentailJson, RevocId, RevocRegDeltaJson} return(cred.CredentialJson); } catch (Exception e) { return($"Error: {e.Message}"); } }
protected async Task InitCommonWallet() { if (_walletOpened) { return; } StorageUtils.CleanupStorage(); var walletName = "anoncredsCommonWallet"; await Wallet.CreateWalletAsync("default", walletName, "default", null, null); commonWallet = await Wallet.OpenWalletAsync(walletName, null, null); claimDef = await AnonCreds.IssuerCreateAndStoreClaimDefAsync(commonWallet, issuerDid, schema, null, false); await AnonCreds.ProverStoreCredentialOfferAsync(commonWallet, string.Format(claimOfferTemplate, issuerDid, 1)); await AnonCreds.ProverStoreCredentialOfferAsync(commonWallet, string.Format(claimOfferTemplate, issuerDid, 2)); await AnonCreds.ProverStoreCredentialOfferAsync(commonWallet, string.Format(claimOfferTemplate, issuerDid2, 2)); await AnonCreds.ProverCreateMasterSecretAsync(commonWallet, masterSecretName); var claimOffer = string.Format("{{\"issuer_did\":\"{0}\",\"schema_seq_no\":{1}}}", issuerDid, 1); var claimRequest = await AnonCreds.ProverCreateCredentialReqAsync(commonWallet, "CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW", claimOffer, claimDef, masterSecretName); var claim = "{\"sex\":[\"male\",\"5944657099558967239210949258394887428692050081607692519917050011144233115103\"],\n" + " \"name\":[\"Alex\",\"1139481716457488690172217916278103335\"],\n" + " \"height\":[\"175\",\"175\"],\n" + " \"age\":[\"28\",\"28\"]\n" + " }"; var createClaimResult = await AnonCreds.IssuerCreateCredentialAsync(commonWallet, claimRequest, claim, -1); var claimJson = createClaimResult.ClaimJson; await AnonCreds.ProverStoreClaimAsync(commonWallet, claimJson, createClaimResult.RevocRegUpdateJson); _walletOpened = true; }
public async Task TestVerifyProofWorksForProofDoesNotCorrespondToProofRequest() { // Issuer create Schema var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, GVT_SCHEMA_NAME, SCHEMA_VERSION, GVT_SCHEMA_ATTRIBUTES); var gvtSchemaId = createSchemaResult.SchemaId; var gvtSchema = createSchemaResult.SchemaJson; // Issuer create CredentialDef var createCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(issuerWallet, issuerDid, gvtSchema, TAG, null, DEFAULT_CRED_DEF_CONFIG); var credDefId = createCredDefResult.CredDefId; var credDef = createCredDefResult.CredDefJson; // Prover create Master Secret await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, masterSecretId); // Issuer create Credential Offer var credOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(issuerWallet, credDefId); // Prover create CredentialReq var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, credOffer, credDef, masterSecretId); var credReq = createCredReqResult.CredentialRequestJson; var credReqMetadata = createCredReqResult.CredentialRequestMetadataJson; // Issuer create Credential var createCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(issuerWallet, credOffer, credReq, gvtCredentialValues, null, null); var credential = createCredentialResult.CredentialJson; // Prover store Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, credentialId1, credReqMetadata, credential, credDef, null); // Prover gets Credentials for Proof Request var proofRequestJson = JsonConvert.SerializeObject( new { nonce = "123432421212", name = "proof_req_1", version = "0.1", requested_attributes = new { attr1_referent = new { name = "name", restrictions = new[] { new { schema_id = gvtSchemaId } } }, attr2_referent = new { name = "phone" } }, requested_predicates = new {} } ); var credentialsForProofJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(proverWallet, proofRequestJson); Assert.IsNotNull(credentialsForProofJson); var credentialsForProof = JObject.Parse(credentialsForProofJson); var credentialsForAttribute1 = (JArray)credentialsForProof["attrs"]["attr1_referent"]; Assert.AreEqual(1, credentialsForAttribute1.Count); var credentialUuid = credentialsForAttribute1[0]["cred_info"]["referent"]; // Prover create Proof var selfAttestedValue = "8-800-300"; var requestedCredentialsJson = JsonConvert.SerializeObject( new { self_attested_attributes = new { attr3_referent = selfAttestedValue }, requested_attributes = new { attr1_referent = new { cred_id = credentialUuid, revealed = true }, }, requested_predicates = new { } } ); var schemas = new JObject(new JProperty(gvtSchemaId, JObject.Parse(gvtSchema))).ToString(); var credentialDefs = new JObject(new JProperty(credDefId, JObject.Parse(credDef))).ToString(); var revocInfos = "{}"; var proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequestJson, requestedCredentialsJson, masterSecretId, schemas, credentialDefs, revocInfos); var proof = JObject.Parse(proofJson); // Verifier verify Proof var revealedAttr1 = proof["requested_proof"]["revealed_attrs"]["attr1_referent"]; Assert.AreEqual("Alex", revealedAttr1["raw"]); Assert.AreEqual(selfAttestedValue, proof["requested_proof"]["self_attested_attrs"]["attr3_referent"]); var revocRegDefs = "{}"; var revocRegs = "{}"; proofRequestJson = JsonConvert.SerializeObject( new { nonce = "123432421212", name = "proof_req_1", version = "0.1", requested_attributes = new { attr1_referent = new { name = "name", restrictions = new[] { new { schema_id = gvtSchemaId } } }, attr2_referent = new { name = "phone" } }, requested_predicates = new { predicate1_referent = new { name = "age", p_type = ">=", p_value = 18 } } } ); var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.VerifierVerifyProofAsync(proofRequestJson, proofJson, schemas, credentialDefs, revocRegDefs, revocRegs) ); }
protected async Task InitCommonWallet() { if (_walletOpened) { return; } var walletConfig = JsonConvert.SerializeObject(new { id = Guid.NewGuid() }); await Wallet.CreateWalletAsync(walletConfig, CREDENTIALS); wallet = await Wallet.OpenWalletAsync(walletConfig, CREDENTIALS); var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, gvtSchemaName, schemaVersion, gvtSchemaAttributes); gvtSchemaId = createSchemaResult.SchemaId; gvtSchema = createSchemaResult.SchemaJson; var xyzSchemaAttributes = "[\"status\", \"period\"]"; var xyzSchemaName = "xyz"; createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, xyzSchemaName, schemaVersion, xyzSchemaAttributes); xyzSchemaId = createSchemaResult.SchemaId; xyzSchema = createSchemaResult.SchemaJson; //Issue GVT issuer1GvtCredential by Issuer1 var issuer1CreateGvtCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(wallet, issuerDid, gvtSchema, tag, null, defaultCredentialDefinitionConfig); issuer1gvtCredDefId = issuer1CreateGvtCredDefResult.CredDefId; issuer1gvtCredDef = issuer1CreateGvtCredDefResult.CredDefJson; //Issue XYZ issuer1GvtCredential by Issuer1 var issuer1CreateXyzCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(wallet, issuerDid, xyzSchema, tag, null, defaultCredentialDefinitionConfig); var issuer1xyzCredDefId = issuer1CreateXyzCredDefResult.CredDefId; issuer1xyzCredDef = issuer1CreateXyzCredDefResult.CredDefJson; //Issue GVT issuer1GvtCredential by Issuer2 var issuerDid2 = "VsKV7grR1BUE29mG2Fm2kX"; var issuer2CreateGvtCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(wallet, issuerDid2, gvtSchema, tag, null, defaultCredentialDefinitionConfig); var issuer2gvtCredDefId = issuer2CreateGvtCredDefResult.CredDefId; var issuer2gvtCredDef = issuer2CreateGvtCredDefResult.CredDefJson; issuer1GvtCredOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(wallet, issuer1gvtCredDefId); var issuer1XyzCredOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(wallet, issuer1xyzCredDefId); issuer2GvtCredOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(wallet, issuer2gvtCredDefId); await AnonCreds.ProverCreateMasterSecretAsync(wallet, masterSecretId); var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(wallet, proverDid, issuer1GvtCredOffer, issuer1gvtCredDef, masterSecretId); issuer1GvtCredReq = createCredReqResult.CredentialRequestJson; issuer1GvtCredReqMetadata = createCredReqResult.CredentialRequestMetadataJson; var createCredResult = await AnonCreds.IssuerCreateCredentialAsync(wallet, issuer1GvtCredOffer, issuer1GvtCredReq, gvtCredentialValuesJson, null, null); var issuer1GvtCredential = createCredResult.CredentialJson; await AnonCreds.ProverStoreCredentialAsync(wallet, credentialId1, issuer1GvtCredReqMetadata, issuer1GvtCredential, issuer1gvtCredDef, null); createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(wallet, proverDid, issuer1XyzCredOffer, issuer1xyzCredDef, masterSecretId); var issuer1XyzCredReq = createCredReqResult.CredentialRequestJson; var issuer1XyzCredReqMetadata = createCredReqResult.CredentialRequestMetadataJson; createCredResult = await AnonCreds.IssuerCreateCredentialAsync(wallet, issuer1XyzCredOffer, issuer1XyzCredReq, xyzCredentialValuesJson, null, null); var issuer1XyzCredential = createCredResult.CredentialJson; await AnonCreds.ProverStoreCredentialAsync(wallet, credentialId2, issuer1XyzCredReqMetadata, issuer1XyzCredential, issuer1xyzCredDef, null); createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(wallet, proverDid, issuer2GvtCredOffer, issuer2gvtCredDef, masterSecretId); var issuer2GvtCredReq = createCredReqResult.CredentialRequestJson; var issuer2GvtCredReqMetadata = createCredReqResult.CredentialRequestMetadataJson; var gvt2CredValues = "{" + " \"sex\":{\"raw\":\"male\",\"encoded\":\"2142657394558967239210949258394838228692050081607692519917028371144233115103\"},\n" + " \"name\":{\"raw\":\"Alexander\",\"encoded\":\"21332817548165488690172217217278169335\"},\n" + " \"height\":{\"raw\":\"170\",\"encoded\":\"170\"},\n" + " \"age\":{\"raw\":\"28\",\"encoded\":\"28\"}\n" + " }"; createCredResult = await AnonCreds.IssuerCreateCredentialAsync(wallet, issuer2GvtCredOffer, issuer2GvtCredReq, gvt2CredValues, null, null); var issuer2GvtCredential = createCredResult.CredentialJson; var credentialId3 = "id3"; await AnonCreds.ProverStoreCredentialAsync(wallet, credentialId3, issuer2GvtCredReqMetadata, issuer2GvtCredential, issuer2gvtCredDef, null); _walletOpened = true; }
public async Task TestIssuerCreateAndStoreCredentialWorksForCredentialValuesDoNotCorrespondToCredentialRequest() { var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.IssuerCreateCredentialAsync(wallet, issuer1GvtCredOffer, issuer1GvtCredReq, xyzCredentialValuesJson, null, null) ); }
/// <inheritdoc /> public virtual async Task IssueCredentialAsync(IAgentContext agentContext, string issuerDid, string credentialId, Dictionary <string, string> values) { var credential = await GetAsync(agentContext, credentialId); if (credential.State != CredentialState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Requested}', found '{credential.State}'"); } var credentialCopy = credential.DeepCopy(); if (values != null && values.Count > 0) { credential.ValuesJson = CredentialUtils.FormatCredentialValues(values); } var definitionRecord = await SchemaService.GetCredentialDefinitionAsync(agentContext.Wallet, credential.CredentialDefinitionId); var connection = await ConnectionService.GetAsync(agentContext, credential.ConnectionId); if (connection.State != ConnectionState.Connected) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Connection state was invalid. Expected '{ConnectionState.Connected}', found '{connection.State}'"); } string revocationRegistryId = null; BlobStorageReader tailsReader = null; if (definitionRecord.SupportsRevocation) { var revocationRecordSearch = await RecordService.SearchAsync <RevocationRegistryRecord>( agentContext.Wallet, SearchQuery.Equal(nameof(RevocationRegistryRecord.CredentialDefinitionId), definitionRecord.Id), null, 5); var revocationRecord = revocationRecordSearch.Single(); // TODO: Credential definition can have multiple revocation registries revocationRegistryId = revocationRecord.Id; tailsReader = await TailsService.OpenTailsAsync(revocationRecord.TailsFile); } var issuedCredential = await AnonCreds.IssuerCreateCredentialAsync(agentContext.Wallet, credential.OfferJson, credential.RequestJson, credential.ValuesJson, revocationRegistryId, tailsReader); if (definitionRecord.SupportsRevocation) { await LedgerService.SendRevocationRegistryEntryAsync(agentContext.Wallet, agentContext.Pool, issuerDid, revocationRegistryId, "CL_ACCUM", issuedCredential.RevocRegDeltaJson); credential.CredentialRevocationId = issuedCredential.RevocId; } var msg = new CredentialMessage { CredentialJson = issuedCredential.CredentialJson, RevocationRegistryId = revocationRegistryId }; await credential.TriggerAsync(CredentialTrigger.Issue); await RecordService.UpdateAsync(agentContext.Wallet, credential); try { await MessageService.SendAsync(agentContext.Wallet, msg, connection); } catch (Exception e) { await RecordService.UpdateAsync(agentContext.Wallet, credentialCopy); throw new AgentFrameworkException(ErrorCode.A2AMessageTransmissionError, "Failed to send credential request message", e); } }
public async Task TestIssuerRevokeProofWorks() { // Create wallet, get wallet handle var walletConfig = JsonConvert.SerializeObject(new { id = "revocationWallet" }); await Wallet.CreateWalletAsync(walletConfig, CREDENTIALS); var wallet = await Wallet.OpenWalletAsync(walletConfig, CREDENTIALS); // Issuer create Schema var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, gvtSchemaName, schemaVersion, gvtSchemaAttributes); var schemaId = createSchemaResult.SchemaId; var schemaJson = createSchemaResult.SchemaJson; // Issuer create issuer1GvtCredential definition var revocationCredentialDefConfig = "{\"support_revocation\":true}"; var createCredentialDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(wallet, issuerDid, schemaJson, tag, null, revocationCredentialDefConfig); var credDefId = createCredentialDefResult.CredDefId; var credDefJson = createCredentialDefResult.CredDefJson; // Issuer create revocation registry var tailsWriter = await BlobStorage.OpenWriterAsync("default", tailsWriterConfig); var revRegConfig = "{\"issuance_type\":null,\"max_cred_num\":5}"; var createRevRegResult = await AnonCreds.IssuerCreateAndStoreRevocRegAsync(wallet, issuerDid, null, tag, credDefId, revRegConfig, tailsWriter); var revRegId = createRevRegResult.RevRegId; var revRegDef = createRevRegResult.RevRegDefJson; // Prover create Master Secret await AnonCreds.ProverCreateMasterSecretAsync(wallet, masterSecretId); // Issuer create Credential Offer var credOfferJson = await AnonCreds.IssuerCreateCredentialOfferAsync(wallet, credDefId); // Prover create Credential Request var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(wallet, proverDid, credOfferJson, credDefJson, masterSecretId); var credentialReqJson = createCredReqResult.CredentialRequestJson; var credentialReqMetadataJson = createCredReqResult.CredentialRequestMetadataJson; // Issuer open TailsReader var blobReader = await BlobStorage.OpenReaderAsync("default", tailsWriterConfig); //9. Issuer create Credential var createCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(wallet, credOfferJson, credentialReqJson, gvtCredentialValuesJson, revRegId, blobReader); var credJson = createCredentialResult.CredentialJson; var credRevocId = createCredentialResult.RevocId; var revRegDelta = createCredentialResult.RevocRegDeltaJson; // Prover create RevocationState var timestamp = 100; var revStateJson = await AnonCreds.CreateRevocationStateAsync(blobReader, revRegDef, revRegDelta, timestamp, credRevocId); // Prover store received Credential await AnonCreds.ProverStoreCredentialAsync(wallet, credentialId1, credentialReqMetadataJson, credJson, credDefJson, revRegDef); // Prover gets Credentials for Proof Request var credentialsJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(wallet, proofRequest); var credentials = JObject.Parse(credentialsJson); var credentialsForAttr1 = credentials["attrs"]["attr1_referent"]; var credentialUuid = credentialsForAttr1[0]["cred_info"]["referent"]; // Prover create Proof var requestedCredentialsJson = string.Format("{{" + "\"self_attested_attributes\":{{}}," + "\"requested_attributes\":{{\"attr1_referent\":{{\"cred_id\":\"{0}\", \"revealed\":true, \"timestamp\":{1} }}}}," + "\"requested_predicates\":{{\"predicate1_referent\":{{\"cred_id\":\"{2}\", \"timestamp\":{3}}}}}" + "}}", credentialUuid, timestamp, credentialUuid, timestamp); var schemasJson = JObject.Parse(string.Format("{{\"{0}\":{1}}}", schemaId, schemaJson)).ToString(); var credentialDefsJson = JObject.Parse(string.Format("{{\"{0}\":{1}}}", credDefId, credDefJson)).ToString(); var revStatesJson = JObject.Parse(string.Format("{{\"{0}\":{{\"{1}\":{2}}}}}", revRegId, timestamp, revStateJson)).ToString(); var proofJson = await AnonCreds.ProverCreateProofAsync(wallet, proofRequest, requestedCredentialsJson, masterSecretId, schemasJson, credentialDefsJson, revStatesJson); var proof = JObject.Parse(proofJson); // Issuer revoke Credential revRegDelta = await AnonCreds.IssuerRevokeCredentialAsync(wallet, blobReader, revRegId, credRevocId); // Verifier verify proof var revealedAttr1 = proof["requested_proof"]["revealed_attrs"]["attr1_referent"]; Assert.AreEqual("Alex", revealedAttr1["raw"]); var revRegDefsJson = JObject.Parse(string.Format("{{\"{0}\":{1}}}", revRegId, revRegDef)).ToString(); var revRegs = JObject.Parse(string.Format("{{\"{0}\":{{\"{1}\":{2}}}}}", revRegId, timestamp, revRegDelta)).ToString(); var valid = await AnonCreds.VerifierVerifyProofAsync(proofRequest, proofJson, schemasJson, credentialDefsJson, revRegDefsJson, revRegs); Assert.IsFalse(valid); //// Close and Delete Wallet await wallet.CloseAsync(); await Wallet.DeleteWalletAsync(walletConfig, CREDENTIALS); }
/// <inheritdoc /> public virtual async Task <(CredentialMessage, CredentialRecord)> CreateCredentialAsync(IAgentContext agentContext, string issuerDid, string credentialId, IEnumerable <CredentialPreviewAttribute> values) { var credential = await GetAsync(agentContext, credentialId); if (credential.State != CredentialState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Requested}', found '{credential.State}'"); } if (values != null && values.Any()) { credential.CredentialAttributesValues = values; } var definitionRecord = await SchemaService.GetCredentialDefinitionAsync(agentContext.Wallet, credential.CredentialDefinitionId); var connection = await ConnectionService.GetAsync(agentContext, credential.ConnectionId); if (connection.State != ConnectionState.Connected) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Connection state was invalid. Expected '{ConnectionState.Connected}', found '{connection.State}'"); } string revocationRegistryId = null; BlobStorageReader tailsReader = null; if (definitionRecord.SupportsRevocation) { var revocationRecordSearch = await RecordService.SearchAsync <RevocationRegistryRecord>( agentContext.Wallet, SearchQuery.Equal(nameof(RevocationRegistryRecord.CredentialDefinitionId), definitionRecord.Id), null, 5); var revocationRecord = revocationRecordSearch.Single(); // TODO: Credential definition can have multiple revocation registries revocationRegistryId = revocationRecord.Id; tailsReader = await TailsService.OpenTailsAsync(revocationRecord.TailsFile); } var issuedCredential = await AnonCreds.IssuerCreateCredentialAsync(agentContext.Wallet, credential.OfferJson, credential.RequestJson, CredentialUtils.FormatCredentialValues(credential.CredentialAttributesValues), revocationRegistryId, tailsReader); if (definitionRecord.SupportsRevocation) { await LedgerService.SendRevocationRegistryEntryAsync(agentContext.Wallet, await agentContext.Pool, issuerDid, revocationRegistryId, "CL_ACCUM", issuedCredential.RevocRegDeltaJson); credential.CredentialRevocationId = issuedCredential.RevocId; } await credential.TriggerAsync(CredentialTrigger.Issue); await RecordService.UpdateAsync(agentContext.Wallet, credential); var threadId = credential.GetTag(TagConstants.LastThreadId); var credentialMsg = new CredentialMessage { CredentialJson = issuedCredential.CredentialJson, RevocationRegistryId = revocationRegistryId }; credentialMsg.ThreadFrom(threadId); return(credentialMsg, credential); }
public async Task TestAnonCredsWorksForRevocationProof() { // Issuer create Schema var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, GVT_SCHEMA_NAME, SCHEMA_VERSION, GVT_SCHEMA_ATTRIBUTES); var gvtSchemaId = createSchemaResult.SchemaId; var schemaJson = createSchemaResult.SchemaJson; // Issuer create credential definition var revocationCredentialDefConfig = JsonConvert.SerializeObject(new { support_revocation = true }); var createCredentialDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(issuerWallet, issuerDid, schemaJson, TAG, null, revocationCredentialDefConfig); var credDefId = createCredentialDefResult.CredDefId; var credDef = createCredentialDefResult.CredDefJson; // Issuer create revocation registry var revRegConfig = JsonConvert.SerializeObject(new { issuance_type = (object)null, max_cred_num = 5 }); var tailsWriterConfig = JsonConvert.SerializeObject( new { base_dir = EnvironmentUtils.GetIndyHomePath("tails"), uri_pattern = string.Empty } ); var tailsWriter = await BlobStorage.OpenWriterAsync("default", tailsWriterConfig); var createRevRegResult = await AnonCreds.IssuerCreateAndStoreRevocRegAsync(issuerWallet, issuerDid, null, TAG, credDefId, revRegConfig, tailsWriter); var revRegId = createRevRegResult.RevRegId; var revRegDef = createRevRegResult.RevRegDefJson; // Prover create Master Secret await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, masterSecretId); // Issuer create Credential Offer var credOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(issuerWallet, credDefId); // Prover create Credential Request var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, credOffer, credDef, masterSecretId); var credReq = createCredReqResult.CredentialRequestJson; var credReqMetadata = createCredReqResult.CredentialRequestMetadataJson; // Issuer open TailsReader var blobStorageReader = await BlobStorage.OpenReaderAsync("default", tailsWriterConfig); // Issuer create Credential var createCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(issuerWallet, credOffer, credReq, gvtCredentialValues, revRegId, blobStorageReader); var credential = createCredentialResult.CredentialJson; var revRegDelta = createCredentialResult.RevocRegDeltaJson; var credRevId = createCredentialResult.RevocId; // Prover store received Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, credentialId1, credReqMetadata, credential, credDef, revRegDef); // Prover gets Credentials for Proof Request var proofRequestJson = JsonConvert.SerializeObject( new { nonce = "123432421212", name = "proof_req_1", version = "0.1", requested_attributes = new { attr1_referent = new { name = "name" }, }, requested_predicates = new { predicate1_referent = new { name = "age", p_type = ">=", p_value = 18 }, } } ); var credentialsJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(proverWallet, proofRequestJson); var credentials = JObject.Parse(credentialsJson); var credentialsForAttr1 = (JArray)credentials["attrs"]["attr1_referent"]; var credentialUuid = credentialsForAttr1[0]["cred_info"]["referent"]; // Prover create RevocationState int timestamp = 100; var revStateJson = await AnonCreds.CreateRevocationStateAsync(blobStorageReader, revRegDef, revRegDelta, timestamp, credRevId); // Prover create Proof var requestedCredentialsJson = JsonConvert.SerializeObject( new { self_attested_attributes = new { }, requested_attributes = new { attr1_referent = new { cred_id = credentialUuid, revealed = true, timestamp = timestamp }, }, requested_predicates = new { predicate1_referent = new { cred_id = credentialUuid, timestamp = timestamp }, } } ); var schemas = new JObject(new JProperty(gvtSchemaId, JObject.Parse(schemaJson))).ToString(); var credentialDefs = new JObject(new JProperty(credDefId, JObject.Parse(credDef))).ToString(); var revStates = new JObject(new JProperty(revRegId, new JObject(new JProperty(timestamp.ToString(), JObject.Parse(revStateJson))))).ToString(); var proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequestJson, requestedCredentialsJson, masterSecretId, schemas, credentialDefs, revStates); var proof = JObject.Parse(proofJson); // Verifier verify proof var revealedAttr1 = proof["requested_proof"]["revealed_attrs"]["attr1_referent"]; Assert.AreEqual("Alex", revealedAttr1["raw"]); var revRegDefs = new JObject(new JProperty(revRegId, JObject.Parse(revRegDef))).ToString(); var revRegs = new JObject(new JProperty(revRegId, new JObject(new JProperty(timestamp.ToString(), JObject.Parse(revRegDelta))))).ToString(); var valid = await AnonCreds.VerifierVerifyProofAsync(proofRequestJson, proofJson, schemas, credentialDefs, revRegDefs, revRegs); Assert.IsTrue(valid); }
public async Task TestAnonCredsDemo() { var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, GVT_SCHEMA_NAME, SCHEMA_VERSION, GVT_SCHEMA_ATTRIBUTES); var gvtSchemaId = createSchemaResult.SchemaId; var gvtSchema = createSchemaResult.SchemaJson; // Issuer create CredentialDef var createCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(issuerWallet, issuerDid, gvtSchema, TAG, null, DEFAULT_CRED_DEF_CONFIG); var credDefId = createCredDefResult.CredDefId; var credDef = createCredDefResult.CredDefJson; // Prover create Master Secret await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, masterSecretId); // Issuer create Credential Offer var credOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(issuerWallet, credDefId); // Prover create CredentialReq var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, credOffer, credDef, masterSecretId); var credReq = createCredReqResult.CredentialRequestJson; var credReqMetadata = createCredReqResult.CredentialRequestMetadataJson; // Issuer create Credential var createCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(issuerWallet, credOffer, credReq, gvtCredentialValues, null, null); var credential = createCredentialResult.CredentialJson; // Prover store Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, credentialId1, credReqMetadata, credential, credDef, null); // Prover gets Credentials for Proof Request var proofRequestJson = "{" + " \"nonce\":\"123432421212\",\n" + " \"name\":\"proof_req_1\",\n" + " \"version\":\"0.1\", " + " \"requested_attributes\": {" + " \"attr1_referent\":{\"name\":\"name\"}," + " \"attr2_referent\":{\"name\":\"sex\"}," + " \"attr3_referent\":{\"name\":\"phone\"}" + " }," + " \"requested_predicates\":{" + " \"predicate1_referent\":{\"name\":\"age\",\"p_type\":\">=\",\"p_value\":18}" + " }" + " }"; var credentialsForProofJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(proverWallet, proofRequestJson); var credentialsForProof = JObject.Parse(credentialsForProofJson); var credentialsForAttribute1 = (JArray)credentialsForProof["attrs"]["attr1_referent"]; var credentialsForAttribute2 = (JArray)credentialsForProof["attrs"]["attr2_referent"]; var credentialsForAttribute3 = (JArray)credentialsForProof["attrs"]["attr3_referent"]; var credentialsForPredicate = (JArray)credentialsForProof["predicates"]["predicate1_referent"]; Assert.AreEqual(1, credentialsForAttribute1.Count); Assert.AreEqual(1, credentialsForAttribute2.Count); Assert.AreEqual(0, credentialsForAttribute3.Count); Assert.AreEqual(1, credentialsForPredicate.Count); var credentialUuid = credentialsForAttribute1[0]["cred_info"]["referent"]; // Prover create Proof var selfAttestedValue = "8-800-300"; var requestedCredentialsJson = JsonConvert.SerializeObject( new { self_attested_attributes = new { attr3_referent = selfAttestedValue }, requested_attributes = new { attr1_referent = new { cred_id = credentialUuid, revealed = true }, attr2_referent = new { cred_id = credentialUuid, revealed = false } }, requested_predicates = new { predicate1_referent = new { cred_id = credentialUuid } } } ); var schemas = new JObject(new JProperty(gvtSchemaId, JObject.Parse(gvtSchema))).ToString(); var credentialDefs = new JObject(new JProperty(credDefId, JObject.Parse(credDef))).ToString(); var revocStates = "{}"; var proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequestJson, requestedCredentialsJson, masterSecretId, schemas, credentialDefs, revocStates); var proof = JObject.Parse(proofJson); // Verifier verify Proof var revealedAttr1 = proof["requested_proof"]["revealed_attrs"]["attr1_referent"]; Assert.AreEqual("Alex", revealedAttr1["raw"]); Assert.IsNotNull(proof["requested_proof"]["unrevealed_attrs"]["attr2_referent"]["sub_proof_index"]); Assert.AreEqual(selfAttestedValue, proof["requested_proof"]["self_attested_attrs"]["attr3_referent"]); var revocRegDefs = "{}"; var revocRegs = "{}"; var valid = await AnonCreds.VerifierVerifyProofAsync(proofRequestJson, proofJson, schemas, credentialDefs, revocRegDefs, revocRegs); Assert.IsTrue(valid); }
public static async Task Execute() { Console.WriteLine("Anoncreds sample -> started"); var issuerWalletName = "issuerWallet"; var proverWalletName = "proverWallet"; var issuerWalletCredentials = "{\"key\":\"issuer_wallet_key\"}"; var proverWalletCredentials = "{\"key\":\"prover_wallet_key\"}"; var issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; var proverDid = "VsKV7grR1BUE29mG2Fm2kX"; try { //1. Create and Open Pool await PoolUtils.CreatePoolLedgerConfig(); //2. Issuer Create and Open Wallet await WalletUtils.CreateWalletAsync(PoolUtils.DEFAULT_POOL_NAME, issuerWalletName, "default", null, issuerWalletCredentials); //3. Prover Create and Open Wallet await WalletUtils.CreateWalletAsync(PoolUtils.DEFAULT_POOL_NAME, proverWalletName, "default", null, proverWalletCredentials); // Open pool and wallets in using statements to ensure they are closed when finished. using (var pool = await Pool.OpenPoolLedgerAsync(PoolUtils.DEFAULT_POOL_NAME, "{}")) using (var issuerWallet = await Wallet.OpenWalletAsync(issuerWalletName, null, issuerWalletCredentials)) using (var proverWallet = await Wallet.OpenWalletAsync(proverWalletName, null, proverWalletCredentials)) { //4. Issuer Creates Credential Schema var schemaName = "gvt"; var schemaVersion = "1.0"; var schemaAttributes = "[\"name\", \"age\", \"sex\", \"height\"]"; var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, schemaName, schemaVersion, schemaAttributes); var schemaId = createSchemaResult.SchemaId; var schemaJson = createSchemaResult.SchemaJson; //5. Issuer create Credential Definition var credDefTag = "Tag1"; var credDefConfigJson = "{\"support_revocation\":false}"; var createCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(issuerWallet, issuerDid, schemaJson, credDefTag, null, credDefConfigJson); var credDefId = createCredDefResult.CredDefId; var credDefJson = createCredDefResult.CredDefJson; //6. Prover create Master Secret var masterSecretId = await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, null); //7. Issuer Creates Credential Offer var credOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(issuerWallet, credDefId); //8. Prover Creates Credential Request var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, credOffer, credDefJson, masterSecretId); var credReqJson = createCredReqResult.CredentialRequestJson; var credReqMetadataJson = createCredReqResult.CredentialRequestMetadataJson; //9. Issuer create Credential var credValuesJson = "{\n" + " \"sex\": {\"raw\": \"male\", \"encoded\": \"594465709955896723921094925839488742869205008160769251991705001\"},\n" + " \"name\": {\"raw\": \"Alex\", \"encoded\": \"1139481716457488690172217916278103335\"},\n" + " \"height\": {\"raw\": \"175\", \"encoded\": \"175\"},\n" + " \"age\": {\"raw\": \"28\", \"encoded\": \"28\"}\n" + " }"; var createCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(issuerWallet, credOffer, credReqJson, credValuesJson, null, null); var credential = createCredentialResult.CredentialJson; //10. Prover Stores Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, null, credReqJson, credReqMetadataJson, credential, credDefJson, null); //11. Prover Gets Credentials for Proof Request var proofRequestJson = "{" + " \"nonce\":\"123432421212\",\n" + " \"name\":\"proof_req_1\",\n" + " \"version\":\"0.1\", " + " \"requested_attributes\": {" + " \"attr1_referent\":{\"name\":\"name\"}," + " \"attr2_referent\":{\"name\":\"sex\"}," + " \"attr3_referent\":{\"name\":\"phone\"}" + " }," + " \"requested_predicates\":{" + " \"predicate1_referent\":{\"name\":\"age\",\"p_type\":\">=\",\"p_value\":18}" + " }" + " }"; var credentialsForProofJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(proverWallet, proofRequestJson); var credentialsForProof = JObject.Parse(credentialsForProofJson); var credentialsForAttribute1 = (JArray)credentialsForProof["attrs"]["attr1_referent"]; var credentialsForAttribute2 = (JArray)credentialsForProof["attrs"]["attr2_referent"]; var credentialsForAttribute3 = (JArray)credentialsForProof["attrs"]["attr3_referent"]; var credentialsForPredicate = (JArray)credentialsForProof["predicates"]["predicate1_referent"]; Debug.Assert(credentialsForAttribute1.Count == 1); Debug.Assert(credentialsForAttribute2.Count == 1); Debug.Assert(credentialsForAttribute3.Count == 0); Debug.Assert(credentialsForPredicate.Count == 1); var credentialId = credentialsForAttribute1[0]["cred_info"]["referent"].ToObject <string>(); //12. Prover Creates Proof var selfAttestedValue = "8-800-300"; var requestedCredentialsJson = string.Format( "{{\n" + " \"self_attested_attributes\":{{\"attr3_referent\":\"{0}\"}},\n" + " \"requested_attributes\":{{\"attr1_referent\":{{\"cred_id\":\"{1}\", \"revealed\":true}},\n" + " \"attr2_referent\":{{\"cred_id\":\"{2}\", \"revealed\":false}}}},\n" + " \"requested_predicates\":{{\"predicate1_referent\":{{\"cred_id\":\"{3}\"}}}}\n" + " }}", selfAttestedValue, credentialId, credentialId, credentialId); var schemas = string.Format("{{\"{0}\":{1}}}", schemaId, schemaJson); var credentialDefs = string.Format("{{\"{0}\":{1}}}", credDefId, credDefJson); var revocStates = "{}"; var proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequestJson, requestedCredentialsJson, masterSecretId, schemas, credentialDefs, revocStates); var proof = JObject.Parse(proofJson); //13. Verifier verify Proof var revealedAttr1 = proof["requested_proof"]["revealed_attrs"]["attr1_referent"]; Debug.Assert("Alex" == revealedAttr1["raw"].ToObject <string>()); Debug.Assert(null != proof["requested_proof"]["unrevealed_attrs"]["attr2_referent"]["sub_proof_index"]); Debug.Assert(selfAttestedValue == proof["requested_proof"]["self_attested_attrs"]["attr3_referent"].ToObject <string>()); var revocRegDefs = "{}"; var revocRegs = "{}"; var valid = await AnonCreds.VerifierVerifyProofAsync(proofRequestJson, proofJson, schemas, credentialDefs, revocRegDefs, revocRegs); Debug.Assert(valid); //14. Close wallets and pool await issuerWallet.CloseAsync(); await proverWallet.CloseAsync(); await pool.CloseAsync(); } } finally { //15. Delete wallets and Pool ledger config await WalletUtils.DeleteWalletAsync(issuerWalletName, issuerWalletCredentials); await WalletUtils.DeleteWalletAsync(proverWalletName, proverWalletCredentials); await PoolUtils.DeletePoolLedgerConfigAsync(PoolUtils.DEFAULT_POOL_NAME); } Console.WriteLine("Anoncreds sample -> completed"); }
/// <inheritdoc /> public virtual async Task IssueCredentialAsync(Pool pool, Wallet wallet, string issuerDid, string credentialId, Dictionary <string, string> values) { var credentialRecord = await RecordService.GetAsync <CredentialRecord>(wallet, credentialId); if (values != null && values.Count > 0) { credentialRecord.ValuesJson = CredentialUtils.FormatCredentialValues(values); } var definitionRecord = await SchemaService.GetCredentialDefinitionAsync(wallet, credentialRecord.CredentialDefinitionId); var connection = await ConnectionService.GetAsync(wallet, credentialRecord.ConnectionId); if (credentialRecord.State != CredentialState.Requested) { throw new Exception( $"Credential sate was invalid. Expected '{CredentialState.Requested}', found '{credentialRecord.State}'"); } string revocationRegistryId = null; BlobStorageReader tailsReader = null; if (definitionRecord.SupportsRevocation) { var revocationRecordSearch = await RecordService.SearchAsync <RevocationRegistryRecord>( wallet, new SearchRecordQuery { { TagConstants.CredentialDefinitionId, definitionRecord.DefinitionId } }, null, 1); var revocationRecord = revocationRecordSearch.First(); revocationRegistryId = revocationRecord.RevocationRegistryId; tailsReader = await TailsService.OpenTailsAsync(revocationRecord.TailsFile); } var issuedCredential = await AnonCreds.IssuerCreateCredentialAsync(wallet, credentialRecord.OfferJson, credentialRecord.RequestJson, credentialRecord.ValuesJson, revocationRegistryId, tailsReader); if (definitionRecord.SupportsRevocation) { await LedgerService.SendRevocationRegistryEntryAsync(wallet, pool, issuerDid, revocationRegistryId, "CL_ACCUM", issuedCredential.RevocRegDeltaJson); credentialRecord.CredentialRevocationId = issuedCredential.RevocId; } var credentialDetails = new CredentialDetails { CredentialJson = issuedCredential.CredentialJson, RevocationRegistryId = revocationRegistryId }; await credentialRecord.TriggerAsync(CredentialTrigger.Issue); await RecordService.UpdateAsync(wallet, credentialRecord); var credential = await MessageSerializer.PackSealedAsync <CredentialMessage>(credentialDetails, wallet, connection.MyVk, connection.TheirVk); credential.Type = MessageUtils.FormatDidMessageType(connection.TheirDid, MessageTypes.Credential); await RouterService.ForwardAsync(new ForwardEnvelopeMessage { Content = credential.ToJson(), Type = MessageUtils.FormatDidMessageType(connection.TheirDid, MessageTypes.Forward) }, connection.Endpoint); }
public async Task <(CredentialIssueMessage, CredentialRecord)> CreateCredentialAsync(IAgentContext agentContext, string credentialId, IEnumerable <CredentialPreviewAttribute> values) { var credential = await GetAsync(agentContext, credentialId); if (credential.State != CredentialState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Requested}', found '{credential.State}'"); } if (values != null && values.Any()) { credential.CredentialAttributesValues = values; } var definitionRecord = await SchemaService.GetCredentialDefinitionAsync(agentContext.Wallet, credential.CredentialDefinitionId); var connection = await ConnectionService.GetAsync(agentContext, credential.ConnectionId); var provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet); if (connection.State != ConnectionState.Connected) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Connection state was invalid. Expected '{ConnectionState.Connected}', found '{connection.State}'"); } string revocationRegistryId = null; BlobStorageReader tailsReader = null; if (definitionRecord.SupportsRevocation) { var revocationRecordSearch = await RecordService.SearchAsync <RevocationRegistryRecord>( agentContext.Wallet, SearchQuery.Equal(nameof(RevocationRegistryRecord.CredentialDefinitionId), definitionRecord.Id), null, 5); var revocationRecord = revocationRecordSearch.Single(); // TODO: Credential definition can have multiple revocation registries revocationRegistryId = revocationRecord.Id; tailsReader = await TailsService.OpenTailsAsync(revocationRecord.TailsFile); } var issuedCredential = await AnonCreds.IssuerCreateCredentialAsync(agentContext.Wallet, credential.OfferJson, credential.RequestJson, CredentialUtils.FormatCredentialValues(credential.CredentialAttributesValues), revocationRegistryId, tailsReader); if (definitionRecord.SupportsRevocation) { var paymentInfo = await PaymentService.GetTransactionCostAsync(agentContext, TransactionTypes.REVOC_REG_ENTRY); await LedgerService.SendRevocationRegistryEntryAsync( wallet : agentContext.Wallet, pool : await agentContext.Pool, issuerDid : provisioning.IssuerDid, revocationRegistryDefinitionId : revocationRegistryId, revocationDefinitionType : "CL_ACCUM", value : issuedCredential.RevocRegDeltaJson, paymentInfo : paymentInfo); credential.CredentialRevocationId = issuedCredential.RevocId; if (paymentInfo != null) { await RecordService.UpdateAsync(agentContext.Wallet, paymentInfo.PaymentAddress); } } await credential.TriggerAsync(CredentialTrigger.Issue); await RecordService.UpdateAsync(agentContext.Wallet, credential); var threadId = credential.GetTag(TagConstants.LastThreadId); var credentialMsg = new CredentialIssueMessage { Credentials = new [] { new Attachment { Id = "libindy-cred-0", MimeType = CredentialMimeTypes.ApplicationJsonMimeType, Data = new AttachmentContent { Base64 = issuedCredential.CredentialJson .GetUTF8Bytes() .ToBase64String() } } } }; credentialMsg.ThreadFrom(threadId); return(credentialMsg, credential); }
public async Task testAnoncredsRevocationInteractionIssuanceByDefault() { // Issuer create DID var trusteeDidInfo = await Did.CreateAndStoreMyDidAsync(this.wallet, JsonConvert.SerializeObject(new { seed = TRUSTEE_SEED })); var issuerDidInfo = await Did.CreateAndStoreMyDidAsync(this.wallet, "{}"); var nymRequest = await Ledger.BuildNymRequestAsync(trusteeDidInfo.Did, issuerDidInfo.Did, issuerDidInfo.VerKey, null, "TRUSTEE"); await Ledger.SignAndSubmitRequestAsync(pool, wallet, trusteeDidInfo.Did, nymRequest); var issuerDid = issuerDidInfo.Did; // Prover create DID var proverDidInfo = await Did.CreateAndStoreMyDidAsync(proverWallet, "{}"); var proverDid = proverDidInfo.Did; var proverVerkey = proverDidInfo.VerKey; // Issuer publish Prover DID nymRequest = await Ledger.BuildNymRequestAsync(issuerDid, proverDid, proverVerkey, null, null); await Ledger.SignAndSubmitRequestAsync(pool, wallet, issuerDid, nymRequest); // ISSUER post to Ledger Schema, CredentialDefinition, RevocationRegistry // Issuer creates Schema var schemaInfo = await AnonCreds.IssuerCreateSchemaAsync(issuerDidInfo.Did, GVT_SCHEMA_NAME, SCHEMA_VERSION, GVT_SCHEMA_ATTRIBUTES); var schemaJson = schemaInfo.SchemaJson; // Issuer posts Schema to Ledger var schemaRequest = await Ledger.BuildSchemaRequestAsync(issuerDid, schemaJson); await Ledger.SignAndSubmitRequestAsync(pool, wallet, issuerDid, schemaRequest); // Issuer get Schema from Ledger var getSchemaRequest = await Ledger.BuildGetSchemaRequestAsync(issuerDid, schemaInfo.SchemaId); var getSchemaResponse = await PoolUtils.EnsurePreviousRequestAppliedAsync(pool, getSchemaRequest, response => { var getSchemaResponseObject = JObject.Parse(response); return(getSchemaResponseObject["result"]["seqNo"] != null); }); // !!IMPORTANT!! // It is important to get Schema from Ledger and parse it to get the correct schema JSON and correspondent id in Ledger // After that we can create CredentialDefinition for received Schema(not for result of indy_issuer_create_schema) ParseResponseResult schemaInfo1 = await Ledger.ParseGetSchemaResponseAsync(getSchemaResponse); schemaJson = schemaInfo1.ObjectJson; // Issuer creates CredentialDefinition var credDefInfo = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(wallet, issuerDid, schemaJson, TAG, null, JsonConvert.SerializeObject(new { support_revocation = true })); var credDefId = credDefInfo.CredDefId; var credDefJson = credDefInfo.CredDefJson; // Issuer post CredentialDefinition to Ledger var credDefRequest = await Ledger.BuildCredDefRequestAsync(issuerDid, credDefJson); await Ledger.SignAndSubmitRequestAsync(pool, wallet, issuerDid, credDefRequest); // Issuer creates RevocationRegistry /* FIXME: getIndyHomePath hard coded forward slash "/". It will not work for Windows. */ var tailsWriterConfig = JsonConvert.SerializeObject( new { base_dir = EnvironmentUtils.GetIndyHomePath("tails"), uri_pattern = string.Empty } ); var tailsWriterHandle = await BlobStorage.OpenWriterAsync("default", tailsWriterConfig); var revRegInfo = await AnonCreds.IssuerCreateAndStoreRevocRegAsync(wallet, issuerDid, null, TAG, credDefId, JsonConvert.SerializeObject(new { max_cred_num = 5, issuance_type = "ISSUANCE_BY_DEFAULT" }), tailsWriterHandle); var revRegId = revRegInfo.RevRegId; var revRegDefJson = revRegInfo.RevRegDefJson; var revRegEntryJson = revRegInfo.RevRegEntryJson; // Issuer posts RevocationRegistryDefinition to Ledger var revRegDefRequest = await Ledger.BuildRevocRegDefRequestAsync(issuerDid, revRegDefJson); await Ledger.SignAndSubmitRequestAsync(pool, wallet, issuerDid, revRegDefRequest); // Issuer posts RevocationRegistryEntry to Ledger var revRegEntryRequest = await Ledger.BuildRevocRegEntryRequestAsync(issuerDid, revRegId, REVOC_REG_TYPE, revRegEntryJson); await Ledger.SignAndSubmitRequestAsync(pool, wallet, issuerDid, revRegEntryRequest); // Issuance Credential for Prover // Prover creates Master Secret await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, COMMON_MASTER_SECRET); // Issuer creates Credential Offer var credOfferJson = await AnonCreds.IssuerCreateCredentialOfferAsync(wallet, credDefId); // Prover gets CredentialDefinition from Ledger var getCredDefRequest = await Ledger.BuildGetCredDefRequestAsync(proverDid, credDefInfo.CredDefId); var getCredDefResponse = await Ledger.SubmitRequestAsync(pool, getCredDefRequest); ParseResponseResult credDefIdInfo = await Ledger.ParseGetCredDefResponseAsync(getCredDefResponse); credDefId = credDefIdInfo.Id; credDefJson = credDefIdInfo.ObjectJson; // Prover creates Credential Request var credReqInfo = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, credOfferJson, credDefJson, COMMON_MASTER_SECRET); var credReqJson = credReqInfo.CredentialRequestJson; var credReqMetadataJson = credReqInfo.CredentialRequestMetadataJson; // Issuer creates TailsReader BlobStorageReader blobStorageReader = await BlobStorage.OpenReaderAsync(TYPE, tailsWriterConfig); // Issuer creates Credential // Issuer must not post rev_reg_delta to ledger for ISSUANCE_BY_DEFAULT strategy var credRegInfo = await AnonCreds.IssuerCreateCredentialAsync(wallet, credOfferJson, credReqJson, GVT_CRED_VALUES, revRegId, blobStorageReader); var credJson = credRegInfo.CredentialJson; var credRevId = credRegInfo.RevocId; // Prover gets RevocationRegistryDefinition var getRevRegDefRequest = await Ledger.BuildGetRevocRegDefRequestAsync(proverDid, revRegId); var getRevRegDefResponse = await Ledger.SubmitRequestAsync(pool, getRevRegDefRequest); ParseResponseResult revRegInfo1 = await Ledger.ParseGetRevocRegDefResponseAsync(getRevRegDefResponse); revRegId = revRegInfo1.Id; var revocRegDefJson = revRegInfo1.ObjectJson; // Prover store received Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, "credential1_id", credReqMetadataJson, credJson, credDefJson, revocRegDefJson); // Verifying Prover Credential Thread.Sleep(3000); long to = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds / 1000; var proofRequest = JsonConvert.SerializeObject( new { nonce = "123432421212", name = "proof_req_1", version = "0.1", requested_attributes = new { attr1_referent = new { name = "name" } }, requested_predicates = new { predicate1_referent = new { name = "age", p_type = ">=", p_value = 18 } }, non_revoked = new { to = to } } ); // Prover gets Claims for Proof Request var credentialsJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(proverWallet, proofRequest); var credentials = JObject.Parse(credentialsJson); var credsForReferent = (JArray)credentials["attrs"]["attr1_referent"]; var credential = credsForReferent[0]["cred_info"]; // Prover gets RevocationRegistryDelta from Ledger /* FIXME */ var getRevRegDeltaRequest = await Ledger.BuildGetRevocRegDeltaRequestAsync(proverDid, revRegId, -1, (int)to); var getRevRegDeltaResponse = await Ledger.SubmitRequestAsync(pool, getRevRegDeltaRequest); var revRegInfo2 = await Ledger.ParseGetRevocRegDeltaResponseAsync(getRevRegDeltaResponse); revRegId = revRegInfo2.Id; var revocRegDeltaJson = revRegInfo2.ObjectJson; // Prover creates RevocationState var timestamp = to; var revStateJson = await AnonCreds.CreateRevocationStateAsync(blobStorageReader, revocRegDefJson, revocRegDeltaJson, (int)timestamp, credRevId); // Prover gets Schema from Ledger getSchemaRequest = await Ledger.BuildGetSchemaRequestAsync(proverDid, schemaInfo1.Id); getSchemaResponse = await Ledger.SubmitRequestAsync(pool, getSchemaRequest); ParseResponseResult schemaInfo2 = await Ledger.ParseGetSchemaResponseAsync(getSchemaResponse); var schemaId = schemaInfo2.Id; schemaJson = schemaInfo2.ObjectJson; // Prover creates Proof var requestedCredentialsJson = JsonConvert.SerializeObject( new { self_attested_attributes = new { }, requested_attributes = new { attr1_referent = new { cred_id = credential["referent"], timestamp = timestamp, revealed = true } }, requested_predicates = new { predicate1_referent = new { cred_id = credential["referent"], timestamp = timestamp } } } ); var schemasJson = new JObject(new JProperty(schemaId, JObject.Parse(schemaJson))).ToString(); var credDefsJson = new JObject(new JProperty(credDefId, JObject.Parse(credDefJson))).ToString(); var revStatesJson = new JObject(new JProperty(revRegId, new JObject(new JProperty(timestamp.ToString(), JObject.Parse(revStateJson))))).ToString(); var proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequest, requestedCredentialsJson, COMMON_MASTER_SECRET, schemasJson, credDefsJson, revStatesJson); var proof = JObject.Parse(proofJson); // Verifier gets RevocationRegistry from Ledger var getRevRegReq = await Ledger.BuildGetRevocRegRequestAsync(DID_MY1, revRegId, (int)timestamp); var getRevRegResp = await Ledger.SubmitRequestAsync(pool, getRevRegReq); var revRegInfo3 = await Ledger.ParseGetRevocRegResponseAsync(getRevRegResp); revRegId = revRegInfo3.Id; var revRegJson = revRegInfo3.ObjectJson; // Verifier verifies proof Assert.AreNotEqual("Alex", proof["requested_proof"]["revealed_attrs"]["attr1_referent"].ToString()); var revRegDefsJson = new JObject(new JProperty(revRegId, JObject.Parse(revRegDefJson))).ToString(); var revRegsJson = new JObject(new JProperty(revRegId, new JObject(new JProperty(timestamp.ToString(), JObject.Parse(revRegJson))))).ToString(); var valid = await AnonCreds.VerifierVerifyProofAsync(proofRequest, proofJson, schemasJson, credDefsJson, revRegDefsJson, revRegsJson); Assert.IsTrue(valid); // Issuer revokes credential var revRegDeltaJson = await AnonCreds.IssuerRevokeCredentialAsync(wallet, blobStorageReader, revRegId, credRevId); // Issuer post RevocationRegistryDelta to Ledger revRegEntryRequest = await Ledger.BuildRevocRegEntryRequestAsync(issuerDid, revRegId, REVOC_REG_TYPE, revRegDeltaJson); await Ledger.SignAndSubmitRequestAsync(pool, wallet, issuerDid, revRegEntryRequest); // Verifying Prover Credential after Revocation Thread.Sleep(3000); long from = to; to = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds / 1000; // Prover gets RevocationRegistryDelta from Ledger getRevRegDeltaRequest = await Ledger.BuildGetRevocRegDeltaRequestAsync(proverDid, revRegId, (int)from, (int)to); getRevRegDeltaResponse = await Ledger.SubmitRequestAsync(pool, getRevRegDeltaRequest); var revRegInfo4 = await Ledger.ParseGetRevocRegDeltaResponseAsync(getRevRegDeltaResponse); revRegId = revRegInfo4.Id; revocRegDeltaJson = revRegInfo4.ObjectJson; timestamp = (long)revRegInfo4.Timestamp; // Prover creates RevocationState revStateJson = await AnonCreds.CreateRevocationStateAsync(blobStorageReader, revocRegDefJson, revocRegDeltaJson, (int)timestamp, credRevId); requestedCredentialsJson = JsonConvert.SerializeObject( new { self_attested_attributes = new { }, requested_attributes = new { attr1_referent = new { cred_id = credential["referent"], timestamp = timestamp, revealed = true } }, requested_predicates = new { predicate1_referent = new { cred_id = credential["referent"], timestamp = timestamp } } } ); revStatesJson = new JObject(new JProperty(revRegId, new JObject(new JProperty(timestamp.ToString(), JObject.Parse(revStateJson))))).ToString(); proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequest, requestedCredentialsJson, COMMON_MASTER_SECRET, schemasJson, credDefsJson, revStatesJson); // Verifier gets RevocationRegistry from Ledger getRevRegReq = await Ledger.BuildGetRevocRegRequestAsync(DID_MY1, revRegId, (int)timestamp); getRevRegResp = await Ledger.SubmitRequestAsync(pool, getRevRegReq); var revRegInfo5 = await Ledger.ParseGetRevocRegResponseAsync(getRevRegResp); revRegId = revRegInfo5.Id; revRegJson = revRegInfo5.ObjectJson; timestamp = (long)revRegInfo5.Timestamp; revRegsJson = new JObject(new JProperty(revRegId, new JObject(new JProperty(timestamp.ToString(), JObject.Parse(revRegJson))))).ToString(); valid = await AnonCreds.VerifierVerifyProofAsync(proofRequest, proofJson, schemasJson, credDefsJson, revRegDefsJson, revRegsJson); Assert.IsFalse(valid); }
public static async Task Execute() { Console.WriteLine("Anoncreds Revocation sample -> started"); var issuerWalletName = "issuerWallet"; var proverWalletName = "proverWallet"; var issuerWalletCredentials = "{\"key\":\"issuer_wallet_key\"}"; var proverWalletCredentials = "{\"key\":\"prover_wallet_key\"}"; var issuerDid = "NcYxiDXkpYi6ov5FcYDi1e"; var proverDid = "VsKV7grR1BUE29mG2Fm2kX"; try { //1. Create and Open Pool await PoolUtils.CreatePoolLedgerConfig(); //2. Issuer Create and Open Wallet await WalletUtils.CreateWalletAsync(PoolUtils.DEFAULT_POOL_NAME, issuerWalletName, "default", null, issuerWalletCredentials); //3. Prover Create and Open Wallet await WalletUtils.CreateWalletAsync(PoolUtils.DEFAULT_POOL_NAME, proverWalletName, "default", null, proverWalletCredentials); // Open pool and wallets in using statements to ensure they are closed when finished. using (var pool = await Pool.OpenPoolLedgerAsync(PoolUtils.DEFAULT_POOL_NAME, "{}")) using (var issuerWallet = await Wallet.OpenWalletAsync(issuerWalletName, null, issuerWalletCredentials)) using (var proverWallet = await Wallet.OpenWalletAsync(proverWalletName, null, proverWalletCredentials)) { //4. Issuer Creates Credential Schema var schemaName = "gvt"; var schemaVersion = "1.0"; var schemaAttributes = "[\"name\", \"age\", \"sex\", \"height\"]"; var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, schemaName, schemaVersion, schemaAttributes); var schemaId = createSchemaResult.SchemaId; var schemaJson = createSchemaResult.SchemaJson; //5. Issuer create Credential Definition var credDefTag = "Tag1"; var credDefConfigJson = "{\"support_revocation\":true}"; var createCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(issuerWallet, issuerDid, schemaJson, credDefTag, null, credDefConfigJson); var credDefId = createCredDefResult.CredDefId; var credDefJson = createCredDefResult.CredDefJson; //6. Issuer create Revocation Registry var revRegDefConfig = "{\"issuance_type\":\"ISSUANCE_ON_DEMAND\",\"max_cred_num\":5}"; var tailsWriterConfig = string.Format("{{\"base_dir\":\"{0}\", \"uri_pattern\":\"\"}}", EnvironmentUtils.GetIndyHomePath("tails")).Replace('\\', '/'); var tailsWriter = await BlobStorage.OpenWriterAsync("default", tailsWriterConfig); var revRegDefTag = "Tag2"; var createRevRegResult = await AnonCreds.IssuerCreateAndStoreRevocRegAsync(issuerWallet, issuerDid, null, revRegDefTag, credDefId, revRegDefConfig, tailsWriter); var revRegId = createRevRegResult.RevRegId; var revRegDefJson = createRevRegResult.RevRegDefJson; //7. Prover create Master Secret var masterSecretId = await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, null); //8. Issuer Creates Credential Offer var credOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(issuerWallet, credDefId); //9. Prover Creates Credential Request var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, credOffer, credDefJson, masterSecretId); var credReqJson = createCredReqResult.CredentialRequestJson; var credReqMetadataJson = createCredReqResult.CredentialRequestMetadataJson; //10. Issuer open Tails Reader var blobStorageReaderCfg = await BlobStorage.OpenReaderAsync("default", tailsWriterConfig); //11. Issuer create Credential var credValuesJson = "{\n" + " \"sex\": {\"raw\": \"male\", \"encoded\": \"594465709955896723921094925839488742869205008160769251991705001\"},\n" + " \"name\": {\"raw\": \"Alex\", \"encoded\": \"1139481716457488690172217916278103335\"},\n" + " \"height\": {\"raw\": \"175\", \"encoded\": \"175\"},\n" + " \"age\": {\"raw\": \"28\", \"encoded\": \"28\"}\n" + " }"; var createCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(issuerWallet, credOffer, credReqJson, credValuesJson, revRegId, blobStorageReaderCfg); var credential = createCredentialResult.CredentialJson; var revRegDeltaJson = createCredentialResult.RevocRegDeltaJson; var credRevId = createCredentialResult.RevocId; //12. Prover Stores Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, null, credReqMetadataJson, credential, credDefJson, revRegDefJson); //13. Prover Gets Credentials for Proof Request var proofRequestJson = "{\n" + " \"nonce\":\"123432421212\",\n" + " \"name\":\"proof_req_1\",\n" + " \"version\":\"0.1\", " + " \"requested_attributes\":{" + " \"attr1_referent\":{\"name\":\"name\"}" + " },\n" + " \"requested_predicates\":{" + " \"predicate1_referent\":{\"name\":\"age\",\"p_type\":\">=\",\"p_value\":18}" + " }" + " }"; var credentialsForProofJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(proverWallet, proofRequestJson); var credentials = JObject.Parse(credentialsForProofJson); var credentialsForAttr1 = (JArray)credentials["attrs"]["attr1_referent"]; var credentialsForPredicate1 = (JArray)credentials["predicates"]["predicate1_referent"]; var credIdForAttr1 = credentialsForAttr1[0]["cred_info"]["referent"].ToObject <string>(); var credIdForPred1 = credentialsForPredicate1[0]["cred_info"]["referent"].ToObject <string>(); //14. Prover create RevocationState long timestamp = 100; var revStateJson = await AnonCreds.CreateRevocationStateAsync(blobStorageReaderCfg, revRegDefJson, revRegDeltaJson, timestamp, credRevId); //15. Prover Creates Proof var requestedCredentialsJson = string.Format("{{" + "\"self_attested_attributes\":{{}}," + "\"requested_attributes\":{{\"attr1_referent\":{{\"cred_id\":\"{0}\", \"revealed\":true, \"timestamp\":{1} }}}}," + "\"requested_predicates\":{{\"predicate1_referent\":{{\"cred_id\":\"{2}\", \"timestamp\":{3}}}}}" + "}}", credIdForAttr1, timestamp, credIdForPred1, timestamp); var schemas = string.Format("{{\"{0}\":{1}}}", schemaId, schemaJson); var credentialDefs = string.Format("{{\"{0}\":{1}}}", credDefId, credDefJson); var revStates = string.Format("{{\"{0}\": {{ \"{1}\":{2} }}}}", revRegId, timestamp, revStateJson); var proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequestJson, requestedCredentialsJson, masterSecretId, schemas, credentialDefs, revStates); var proof = JObject.Parse(proofJson); //16. Verifier verify Proof var revealedAttr1 = proof["requested_proof"]["revealed_attrs"]["attr1_referent"]; Debug.Assert("Alex" == revealedAttr1["raw"].ToObject <string>()); var revRegDefs = string.Format("{{\"{0}\":{1}}}", revRegId, revRegDefJson); var revRegs = string.Format("{{\"{0}\": {{ \"{1}\":{2} }}}}", revRegId, timestamp, revRegDeltaJson); var valid = await AnonCreds.VerifierVerifyProofAsync(proofRequestJson, proofJson, schemas, credentialDefs, revRegDefs, revRegs); Debug.Assert(valid); await issuerWallet.CloseAsync(); await proverWallet.CloseAsync(); await pool.CloseAsync(); } } finally { //17. Delete wallets and Pool ledger config await WalletUtils.DeleteWalletAsync(issuerWalletName, issuerWalletCredentials); await WalletUtils.DeleteWalletAsync(proverWalletName, proverWalletCredentials); await PoolUtils.DeletePoolLedgerConfigAsync(PoolUtils.DEFAULT_POOL_NAME); } Console.WriteLine("Anoncreds Revocation sample -> completed"); }
public async Task TestAnonCredsWorksForSingleIssuerSingleProverMultipleCredentials() { // Issuer create GVT Schema var createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, GVT_SCHEMA_NAME, SCHEMA_VERSION, GVT_SCHEMA_ATTRIBUTES); var gvtSchemaId = createSchemaResult.SchemaId; var gvtSchema = createSchemaResult.SchemaJson; // Issuer create CredentialDef var createCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(issuerWallet, issuerDid, gvtSchema, TAG, null, DEFAULT_CRED_DEF_CONFIG); var gvtCredDefId = createCredDefResult.CredDefId; var gvtCredDef = createCredDefResult.CredDefJson; // Issuer create XYZ Schema createSchemaResult = await AnonCreds.IssuerCreateSchemaAsync(issuerDid, XYZ_SCHEMA_NAME, SCHEMA_VERSION, XYZ_SCHEMA_ATTRIBUTES); var xyzSchemaId = createSchemaResult.SchemaId; var xyzSchema = createSchemaResult.SchemaJson; // Issuer create CredentialDef createCredDefResult = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(issuerWallet, issuerDid, xyzSchema, TAG, null, DEFAULT_CRED_DEF_CONFIG); var xyzCredDefId = createCredDefResult.CredDefId; var xyzCredDef = createCredDefResult.CredDefJson; // Prover create Master Secret await AnonCreds.ProverCreateMasterSecretAsync(proverWallet, masterSecretId); // Issuer create GVT Credential Offer var gvtCredOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(issuerWallet, gvtCredDefId); // Issuer create XYZ Credential Offer var xyzCredOffer = await AnonCreds.IssuerCreateCredentialOfferAsync(issuerWallet, xyzCredDefId); // Prover create CredentialReq for GVT Credential Offer var createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, gvtCredOffer, gvtCredDef, masterSecretId); var gvtCredReq = createCredReqResult.CredentialRequestJson; var gvtCredReqMetadata = createCredReqResult.CredentialRequestMetadataJson; // Issuer create GVT Credential var gvtCreateCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(issuerWallet, gvtCredOffer, gvtCredReq, gvtCredentialValues, null, null); var gvtCredential = gvtCreateCredentialResult.CredentialJson; // Prover store GVT Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, credentialId1, gvtCredReqMetadata, gvtCredential, gvtCredDef, null); // Prover create CredentialReq for XYZ Credential Offer createCredReqResult = await AnonCreds.ProverCreateCredentialReqAsync(proverWallet, proverDid, xyzCredOffer, xyzCredDef, masterSecretId); var xyzCredReq = createCredReqResult.CredentialRequestJson; var xyzCredReqMetadata = createCredReqResult.CredentialRequestMetadataJson; // Issuer create XYZ Credential var xyzCreateCredentialResult = await AnonCreds.IssuerCreateCredentialAsync(issuerWallet, xyzCredOffer, xyzCredReq, xyzCredentialValues, null, null); var xyzCredential = xyzCreateCredentialResult.CredentialJson; // Prover store XYZ Credential await AnonCreds.ProverStoreCredentialAsync(proverWallet, credentialId2, xyzCredReqMetadata, xyzCredential, xyzCredDef, null); // Prover gets Credentials for Proof Request var proofRequestJson = JsonConvert.SerializeObject( new { nonce = "123432421212", name = "proof_req_1", version = "0.1", requested_attributes = new { attr1_referent = new { name = "name" }, attr2_referent = new { name = "status" } }, requested_predicates = new { predicate1_referent = new { name = "age", p_type = ">=", p_value = 18 }, predicate2_referent = new { name = "period", p_type = ">=", p_value = 5 }, } } ); var credentialsForProofJson = await AnonCreds.ProverGetCredentialsForProofReqAsync(proverWallet, proofRequestJson); Assert.IsNotNull(credentialsForProofJson); var credentialsForProof = JObject.Parse(credentialsForProofJson); var credentialsForAttribute1 = (JArray)credentialsForProof["attrs"]["attr1_referent"]; var credentialsForAttribute2 = (JArray)credentialsForProof["attrs"]["attr2_referent"]; var credentialsForPredicate1 = (JArray)credentialsForProof["predicates"]["predicate1_referent"]; var credentialsForPredicate2 = (JArray)credentialsForProof["predicates"]["predicate2_referent"]; Assert.AreEqual(1, credentialsForAttribute1.Count); Assert.AreEqual(1, credentialsForAttribute2.Count); Assert.AreEqual(1, credentialsForPredicate1.Count); Assert.AreEqual(1, credentialsForPredicate2.Count); var credentialUuidForAttr1 = credentialsForAttribute1[0]["cred_info"]["referent"]; var credentialUuidForAttr2 = credentialsForAttribute2[0]["cred_info"]["referent"]; var credentialUuidForPredicate1 = credentialsForPredicate1[0]["cred_info"]["referent"]; var credentialUuidForPredicate2 = credentialsForPredicate2[0]["cred_info"]["referent"]; // Prover create Proof var requestedCredentialsJson = JsonConvert.SerializeObject( new { self_attested_attributes = new { }, requested_attributes = new { attr1_referent = new { cred_id = credentialUuidForAttr1, revealed = true }, attr2_referent = new { cred_id = credentialUuidForAttr2, revealed = true } }, requested_predicates = new { predicate1_referent = new { cred_id = credentialUuidForPredicate1 }, predicate2_referent = new { cred_id = credentialUuidForPredicate2 } } } ); var schemas = new JObject(new JProperty(gvtSchemaId, JObject.Parse(gvtSchema)), new JProperty(xyzSchemaId, JObject.Parse(xyzSchema))).ToString(); var credentialDefs = new JObject(new JProperty(gvtCredDefId, JObject.Parse(gvtCredDef)), new JProperty(xyzCredDefId, JObject.Parse(xyzCredDef))).ToString(); var revocStates = "{}"; var proofJson = await AnonCreds.ProverCreateProofAsync(proverWallet, proofRequestJson, requestedCredentialsJson, masterSecretId, schemas, credentialDefs, revocStates); var proof = JObject.Parse(proofJson); // Verifier verify Proof var revealedAttr1 = proof["requested_proof"]["revealed_attrs"]["attr1_referent"]; Assert.AreEqual("Alex", revealedAttr1["raw"]); var revealedAttr2 = proof["requested_proof"]["revealed_attrs"]["attr2_referent"]; Assert.AreEqual("partial", revealedAttr2["raw"]); var revocRegDefs = "{}"; var revocRegs = "{}"; Boolean valid = await AnonCreds.VerifierVerifyProofAsync(proofRequestJson, proofJson, schemas, credentialDefs, revocRegDefs, revocRegs); Assert.IsTrue(valid); }