public async Task IssueCredentialThrowsExceptionUnableToSendA2AMessage() { //Establish a connection between the two parties var(issuerConnection, holderConnection) = await Scenarios.EstablishConnectionAsync( _connectionService, _messages, _issuerWallet, _holderWallet); // Create an issuer DID/VK. Can also be created during provisioning var issuer = await Did.CreateAndStoreMyDidAsync(_issuerWallet.Wallet, new { seed = "000000000000000000000000Steward1" }.ToJson()); // Creata a schema and credential definition for this issuer (var definitionId, _) = await Scenarios.CreateDummySchemaAndNonRevokableCredDef(_issuerWallet, _schemaService, issuer.Did, new[] { "dummy_attr" }); var offerConfig = new OfferConfiguration() { IssuerDid = issuer.Did, CredentialDefinitionId = definitionId }; // Send an offer to the holder using the established connection channel await _credentialService.SendOfferAsync(_issuerWallet, issuerConnection.Id, offerConfig); // Holder retrives message from their cloud agent var credentialOffer = FindContentMessage <CredentialOfferMessage>(_messages); // Holder processes the credential offer by storing it var holderCredentialId = await _credentialService.ProcessOfferAsync(_holderWallet, credentialOffer, holderConnection); // Holder creates master secret. Will also be created during wallet agent provisioning await AnonCreds.ProverCreateMasterSecretAsync(_holderWallet.Wallet, MasterSecretId); // Holder accepts the credential offer and sends a credential request await _credentialService.AcceptOfferAsync(_holderWallet, holderCredentialId, new Dictionary <string, string> { { "dummy_attr", "dummyVal" } }); // Issuer retrieves credential request from cloud agent var credentialRequest = FindContentMessage <CredentialRequestMessage>(_messages); Assert.NotNull(credentialRequest); // Issuer processes the credential request by storing it var issuerCredentialId = await _credentialService.ProcessCredentialRequestAsync(_issuerWallet, credentialRequest, issuerConnection); //Try issue the credential with a credential service that has a bad routing service _routeMessage = false; var ex = await Assert.ThrowsAsync <AgentFrameworkException>(async() => await _credentialService.IssueCredentialAsync(_issuerWallet, issuer.Did, issuerCredentialId)); Assert.True(ex.ErrorCode == ErrorCode.A2AMessageTransmissionError); _routeMessage = true; }
/// <inheritdoc /> public virtual async Task ProvisionAgentAsync(Wallet wallet, ProvisioningConfiguration provisioningConfiguration) { if (provisioningConfiguration == null) { throw new ArgumentNullException(nameof(provisioningConfiguration)); } if (provisioningConfiguration.EndpointUri == null) { throw new ArgumentNullException(nameof(provisioningConfiguration.EndpointUri)); } var record = await GetProvisioningAsync(wallet); if (record != null) { throw new WalletAlreadyProvisionedException(); } var agent = await Did.CreateAndStoreMyDidAsync(wallet, provisioningConfiguration.AgentSeed != null ?new { seed = provisioningConfiguration.AgentSeed }.ToJson() : "{}"); var masterSecretId = await AnonCreds.ProverCreateMasterSecretAsync(wallet, null); record = new ProvisioningRecord { IssuerSeed = provisioningConfiguration.IssuerSeed, AgentSeed = provisioningConfiguration.AgentSeed, MasterSecretId = masterSecretId, Endpoint = { Uri = provisioningConfiguration.EndpointUri.ToString(), Did = agent.Did, Verkey = agent.VerKey }, Owner = { Name = provisioningConfiguration.OwnerName, ImageUrl = provisioningConfiguration.OwnerImageUrl }, TailsBaseUri = provisioningConfiguration.TailsBaseUri.ToString() }; if (provisioningConfiguration.CreateIssuer) { var issuer = await Did.CreateAndStoreMyDidAsync(wallet, provisioningConfiguration.IssuerSeed != null ?new { seed = provisioningConfiguration.IssuerSeed }.ToJson() : "{}"); record.IssuerDid = issuer.Did; record.IssuerVerkey = issuer.VerKey; } await RecordService.AddAsync(wallet, record); }
private async Task <string> BuildRevocationStatesAsync(IAgentContext agentContext, IEnumerable <CredentialInfo> credentialObjects, ProofRequest proofRequest, RequestedCredentials requestedCredentials) { var allCredentials = new List <RequestedAttribute>(); allCredentials.AddRange(requestedCredentials.RequestedAttributes.Values); allCredentials.AddRange(requestedCredentials.RequestedPredicates.Values); var result = new Dictionary <string, Dictionary <string, JObject> >(); foreach (var requestedCredential in allCredentials) { // ReSharper disable once PossibleMultipleEnumeration var credential = credentialObjects.First(x => x.Referent == requestedCredential.CredentialId); if (credential.RevocationRegistryId == null || (proofRequest.NonRevoked == null)) { continue; } var registryDefinition = await LedgerService.LookupRevocationRegistryDefinitionAsync( agentContext : agentContext, registryId : credential.RevocationRegistryId); var delta = await LedgerService.LookupRevocationRegistryDeltaAsync( agentContext : agentContext, revocationRegistryId : credential.RevocationRegistryId, from : proofRequest.NonRevoked.From, to : proofRequest.NonRevoked.To); var tailsfile = await TailsService.EnsureTailsExistsAsync(agentContext, credential.RevocationRegistryId); var tailsReader = await TailsService.OpenTailsAsync(tailsfile); var state = await AnonCreds.CreateRevocationStateAsync( blobStorageReader : tailsReader, revRegDef : registryDefinition.ObjectJson, revRegDelta : delta.ObjectJson, timestamp : (long)delta.Timestamp, credRevId : credential.CredentialRevocationId); if (!result.ContainsKey(credential.RevocationRegistryId)) { result.Add(credential.RevocationRegistryId, new Dictionary <string, JObject>()); } requestedCredential.Timestamp = (long)delta.Timestamp; if (!result[credential.RevocationRegistryId].ContainsKey($"{delta.Timestamp}")) { result[credential.RevocationRegistryId].Add($"{delta.Timestamp}", JObject.Parse(state)); } } return(result.ToJson()); }
private async Task <string> BuildRevocationStatesAsync(Pool pool, IEnumerable <CredentialInfo> credentialObjects, RequestedCredentials requestedCredentials) { var allCredentials = new List <RequestedAttribute>(); allCredentials.AddRange(requestedCredentials.RequestedAttributes.Values); allCredentials.AddRange(requestedCredentials.RequestedPredicates.Values); var result = new Dictionary <string, Dictionary <string, JObject> >(); foreach (var requestedCredential in allCredentials) { // ReSharper disable once PossibleMultipleEnumeration var credential = credentialObjects.First(x => x.Referent == requestedCredential.CredentialId); if (credential.RevocationRegistryId == null) { continue; } var timestamp = requestedCredential.Timestamp ?? throw new Exception( "Timestamp must be provided for credential that supports revocation"); if (result.ContainsKey(credential.RevocationRegistryId) && result[credential.RevocationRegistryId].ContainsKey($"{timestamp}")) { continue; } var registryDefinition = await LedgerService.LookupRevocationRegistryDefinitionAsync(pool, null, credential.RevocationRegistryId); var delta = await LedgerService.LookupRevocationRegistryDeltaAsync(pool, credential.RevocationRegistryId, -1, timestamp); var tailsfile = await TailsService.EnsureTailsExistsAsync(pool, credential.RevocationRegistryId); var tailsReader = await TailsService.OpenTailsAsync(tailsfile); var state = await AnonCreds.CreateRevocationStateAsync(tailsReader, registryDefinition.ObjectJson, delta.ObjectJson, (long)delta.Timestamp, credential.CredentialRevocationId); if (!result.ContainsKey(credential.RevocationRegistryId)) { result.Add(credential.RevocationRegistryId, new Dictionary <string, JObject>()); } result[credential.RevocationRegistryId].Add($"{timestamp}", JObject.Parse(state)); // TODO: Revocation state should provide the state between a certain period // that can be requested in the proof request in the 'non_revocation' field. } return(result.ToJson()); }
public async Task RejectCredentialRequestThrowsExceptionCredentialInvalidState() { //Establish a connection between the two parties var(issuerConnection, holderConnection) = await Scenarios.EstablishConnectionAsync( _connectionService, _messages, _issuerWallet, _holderWallet); // Create an issuer DID/VK. Can also be created during provisioning var issuer = await Did.CreateAndStoreMyDidAsync(_issuerWallet.Wallet, new { seed = TestConstants.StewartDid }.ToJson()); // Create a schema and credential definition for this issuer var(definitionId, _) = await Scenarios.CreateDummySchemaAndNonRevokableCredDef(_issuerWallet, _schemaService, issuer.Did, new[] { "dummy_attr" }); var offerConfig = new OfferConfiguration { IssuerDid = issuer.Did, CredentialDefinitionId = definitionId }; // Send an offer to the holder using the established connection channel var(offerMessage, _) = await _credentialService.CreateOfferAsync(_issuerWallet, offerConfig, issuerConnection.Id); _messages.Add(offerMessage); // Holder retrieves message from their cloud agent var credentialOffer = FindContentMessage <CredentialOfferMessage>(_messages); // Holder processes the credential offer by storing it var holderCredentialId = await _credentialService.ProcessOfferAsync(_holderWallet, credentialOffer, holderConnection); // Holder creates master secret. Will also be created during wallet agent provisioning await AnonCreds.ProverCreateMasterSecretAsync(_holderWallet.Wallet, TestConstants.DefaultMasterSecret); // Holder accepts the credential offer and sends a credential request (var request, var _) = await _credentialService.CreateRequestAsync(_holderWallet, holderCredentialId); _messages.Add(request); // Issuer retrieves credential request from cloud agent var credentialRequest = FindContentMessage <CredentialRequestMessage>(_messages); Assert.NotNull(credentialRequest); // Issuer processes the credential request by storing it var issuerCredentialId = await _credentialService.ProcessCredentialRequestAsync(_issuerWallet, credentialRequest, issuerConnection); await _credentialService.RejectCredentialRequestAsync(_issuerWallet, issuerCredentialId); //Try reject the credential request again var ex = await Assert.ThrowsAsync <AriesFrameworkException>(async() => await _credentialService.RejectCredentialRequestAsync(_issuerWallet, issuerCredentialId)); Assert.True(ex.ErrorCode == ErrorCode.RecordInInvalidState); }
/// <inheritdoc /> public virtual async Task <(ProofMessage, ProofRecord)> CreateProofAsync(IAgentContext agentContext, string proofRequestId, RequestedCredentials requestedCredentials) { var record = await GetAsync(agentContext, proofRequestId); if (record.State != ProofState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Proof state was invalid. Expected '{ProofState.Requested}', found '{record.State}'"); } var provisioningRecord = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet); var credentialObjects = new List <CredentialInfo>(); foreach (var credId in requestedCredentials.GetCredentialIdentifiers()) { credentialObjects.Add( JsonConvert.DeserializeObject <CredentialInfo>( await AnonCreds.ProverGetCredentialAsync(agentContext.Wallet, credId))); } var schemas = await BuildSchemasAsync(await agentContext.Pool, credentialObjects .Select(x => x.SchemaId) .Distinct()); var definitions = await BuildCredentialDefinitionsAsync(await agentContext.Pool, credentialObjects .Select(x => x.CredentialDefinitionId) .Distinct()); var revocationStates = await BuildRevocationStatesAsync(await agentContext.Pool, credentialObjects, requestedCredentials); var proofJson = await AnonCreds.ProverCreateProofAsync(agentContext.Wallet, record.RequestJson, requestedCredentials.ToJson(), provisioningRecord.MasterSecretId, schemas, definitions, revocationStates); record.ProofJson = proofJson; await record.TriggerAsync(ProofTrigger.Accept); await RecordService.UpdateAsync(agentContext.Wallet, record); var threadId = record.GetTag(TagConstants.LastThreadId); var proofMsg = new ProofMessage { ProofJson = proofJson }; proofMsg.ThreadFrom(threadId); return(proofMsg, record); }
public async Task RejectProofRequestCredentialInvalidState() { //Setup a connection and issue the credentials to the holder var(issuerConnection, holderConnection) = await Scenarios.EstablishConnectionAsync( _connectionService, _messages, _issuerWallet, _holderWallet); await Scenarios.IssueCredentialAsync( _schemaService, _credentialService, _messages, issuerConnection, holderConnection, _issuerWallet, _holderWallet, await _holderWallet.Pool, TestConstants.DefaultMasterSecret, true, new List <CredentialPreviewAttribute> { new CredentialPreviewAttribute("first_name", "Test"), new CredentialPreviewAttribute("last_name", "Holder") }); _messages.Clear(); //Requestor initialize a connection with the holder var(_, requestorConnection) = await Scenarios.EstablishConnectionAsync( _connectionService, _messages, _holderWallet, _requestorWallet); // Verifier sends a proof request to prover { var proofRequestObject = new ProofRequest { Name = "ProofReq", Version = "1.0", Nonce = await AnonCreds.GenerateNonceAsync(), RequestedAttributes = new Dictionary <string, ProofAttributeInfo> { { "first-name-requirement", new ProofAttributeInfo { Name = "first_name" } } } }; //Requestor sends a proof request var(message, _) = await _proofService.CreateRequestAsync(_requestorWallet, proofRequestObject, requestorConnection.Id); _messages.Add(message); } //Holder retrieves proof request message from their cloud agent var proofRequest = FindContentMessage <RequestPresentationMessage>(); Assert.NotNull(proofRequest); //Holder stores the proof request var holderProofRequestId = await _proofService.ProcessRequestAsync(_holderWallet, proofRequest, holderConnection); //Holder accepts the proof request and sends a proof await _proofService.RejectProofRequestAsync(_holderWallet, holderProofRequestId.Id); var ex = await Assert.ThrowsAsync <AriesFrameworkException>(async() => await _proofService.RejectProofRequestAsync(_holderWallet, holderProofRequestId.Id)); Assert.True(ex.ErrorCode == ErrorCode.RecordInInvalidState); }
public async Task TestProverCreateMasterSecretWorksForDuplicate() { await AnonCreds.ProverCreateMasterSecretAsync(_wallet, "master_secret_name_duplicate"); var ex = await Assert.ThrowsExceptionAsync <IndyException>(() => AnonCreds.ProverCreateMasterSecretAsync(_wallet, "master_secret_name_duplicate") ); Assert.AreEqual(ErrorCode.AnoncredsMasterSecretDuplicateNameError, ex.ErrorCode); }
public async Task TestIssuerCreateAndStoreClaimDefWorksForInvalidSchemaJson() { var schema = "{\"seqNo\":1, \"name\":\"name\",\"version\":\"1.0\", \"keys\":[\"name\"]}"; var ex = await Assert.ThrowsExceptionAsync <IndyException>(() => AnonCreds.IssuerCreateAndStoreClaimDefAsync(_wallet, _issuerDid, schema, null, false) ); Assert.AreEqual(ErrorCode.CommonInvalidStructure, ex.ErrorCode); }
public async Task TestsProverGetClaimOffersWorksForEmptyFilter() { await InitCommonWallet(); var claimOffers = await AnonCreds.ProverGetClaimOffersAsync(_commonWallet, "{}"); var claimOffersArray = JArray.Parse(claimOffers); Assert.AreEqual(3, claimOffersArray.Count); }
public async Task TestProverCreateAndStoreClaimReqWorksForInvalidClaimOffer() { await InitCommonWallet(); var claimOffer = string.Format("{{\"issuer_did\":\"{0}\"}}", issuerDid); var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.ProverCreateCredentialReqAsync(commonWallet, proverDid, claimOffer, claimDef, masterSecretName) ); }
public async Task TestProverCreateAndStoreClaimReqWorksForClaimDefDoesNotCorrespondToClaimOfferDifferentSchema() { await InitCommonWallet(); var claimOffer = string.Format(claimOfferTemplate, issuerDid, 2); var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.ProverCreateCredentialReqAsync(commonWallet, proverDid, claimOffer, claimDef, masterSecretName) ); }
public async Task TestProverGetCredentialsWorksForEmptyResult() { var filter = string.Format("{{\"issuer_id\":\"{0}a\"}}", issuerDid); var credentials = await AnonCreds.ProverGetCredentialsAsync(wallet, filter); var credentialsArray = JArray.Parse(credentials); Assert.AreEqual(0, credentialsArray.Count); }
public async Task TestProverGetCredentialsWorksForFilterByCredDefId() { var filter = string.Format("{{\"cred_def_id\":\"{0}\"}}", issuer1gvtCredDefId); var credentials = await AnonCreds.ProverGetCredentialsAsync(wallet, filter); var credentialsArray = JArray.Parse(credentials); Assert.AreEqual(1, credentialsArray.Count); }
public async Task TestProverGetCredentialsWorksForFilterBySchemaName() { var filter = "{\"schema_name\":\"gvt\"}"; var credentials = await AnonCreds.ProverGetCredentialsAsync(wallet, filter); var credentialsArray = JArray.Parse(credentials); Assert.AreEqual(2, credentialsArray.Count); }
public async Task TestProverGetCredentialsWorksForFilterBySchema() { var filter = string.Format("{{\"schema_id\":\"{0}\"}}", gvtSchemaId); var credentials = await AnonCreds.ProverGetCredentialsAsync(wallet, filter); var credentialsArray = JArray.Parse(credentials); Assert.AreEqual(2, credentialsArray.Count); }
public async Task TestProverCreateProofWorksForInvalidMasterSecret() { var schemasJson = new JObject(new JProperty(gvtSchemaId, JObject.Parse(gvtSchema))).ToString(); var credentialDefsJson = new JObject(new JProperty(issuer1gvtCredDefId, JObject.Parse(issuer1gvtCredDef))).ToString(); var revocStatesJson = "{}"; var ex = await Assert.ThrowsExceptionAsync <WalletItemNotFoundException>(() => AnonCreds.ProverCreateProofAsync(wallet, proofRequest, requestedCredentialsJson, "wrong_master_secret", schemasJson, credentialDefsJson, revocStatesJson) ); }
public async Task CreateProofRequestConnectionNotFound() { var ex = await Assert.ThrowsAsync <AriesFrameworkException>(async() => await _proofService.CreateRequestAsync(_issuerWallet, new ProofRequest { Name = "Test", Nonce = await AnonCreds.GenerateNonceAsync() }, "bad-connection-id")); Assert.True(ex.ErrorCode == ErrorCode.RecordNotFound); }
public async Task TestProverStoreClaimOfferWorksForInvalidIssuerDid() { var claimOffer = "{\"issuer_did\":\"invalid_base58_string\",\"schema_seq_no\":1}"; var ex = await Assert.ThrowsExceptionAsync <IndyException>(() => AnonCreds.ProverStoreClaimOfferAsync(_wallet, claimOffer) ); Assert.AreEqual(ErrorCode.CommonInvalidStructure, ex.ErrorCode); }
public async Task TestProverGetClaimsForProofRequestWorksForInvalidPredicateType() { await InitCommonWallet(); var filter = string.Format("{{\"schema_seq_no\":\"{0}\"}}", 1); var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.ProverGetCredentialsAsync(commonWallet, filter) ); }
public async Task TestProverStoreClaimOfferWorksForInvalidJson() { var claimOffer = "{\"issuer_did\":\"NcYxiDXkpYi6ov5FcYDi1e\"}"; var ex = await Assert.ThrowsExceptionAsync <IndyException>(() => AnonCreds.ProverStoreClaimOfferAsync(_wallet, claimOffer) ); Assert.AreEqual(ErrorCode.CommonInvalidStructure, ex.ErrorCode); }
public async Task TestProverGetClaimsWorksForEmptyFilter() { await InitCommonWallet(); var claims = await AnonCreds.ProverGetCredentialsAsync(commonWallet, "{}"); var claimsArray = JArray.Parse(claims); Assert.AreEqual(1, claimsArray.Count); }
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) ); }
/// <inheritdoc /> public virtual async Task <string> ProcessCredentialAsync(IAgentContext agentContext, CredentialIssueMessage credential, ConnectionRecord connection) { var credentialAttachment = credential.Credentials.FirstOrDefault(x => x.Id == "libindy-cred-0") ?? throw new ArgumentException("Credential attachment not found"); var credentialJson = credentialAttachment.Data.Base64.GetBytesFromBase64().GetUTF8String(); var credentialJobj = JObject.Parse(credentialJson); var definitionId = credentialJobj["cred_def_id"].ToObject <string>(); var revRegId = credentialJobj["rev_reg_id"]?.ToObject <string>(); var credentialRecord = await Policy.Handle <AriesFrameworkException>() .RetryAsync(3, async(ex, retry) => { await Task.Delay((int)Math.Pow(retry, 2) * 100); }) .ExecuteAsync(() => this.GetByThreadIdAsync(agentContext, credential.GetThreadId())); if (credentialRecord.State != CredentialState.Requested) { throw new AriesFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Requested}', found '{credentialRecord.State}'"); } var credentialDefinition = await LedgerService.LookupDefinitionAsync(agentContext, definitionId); string revocationRegistryDefinitionJson = null; if (!string.IsNullOrEmpty(revRegId)) { // If credential supports revocation, lookup registry definition var revocationRegistry = await LedgerService.LookupRevocationRegistryDefinitionAsync(agentContext, revRegId); revocationRegistryDefinitionJson = revocationRegistry.ObjectJson; credentialRecord.RevocationRegistryId = revRegId; } var credentialId = await AnonCreds.ProverStoreCredentialAsync( wallet : agentContext.Wallet, credId : credentialRecord.Id, credReqMetadataJson : credentialRecord.CredentialRequestMetadataJson, credJson : credentialJson, credDefJson : credentialDefinition.ObjectJson, revRegDefJson : revocationRegistryDefinitionJson); credentialRecord.CredentialId = credentialId; await credentialRecord.TriggerAsync(CredentialTrigger.Issue); await RecordService.UpdateAsync(agentContext.Wallet, credentialRecord); EventAggregator.Publish(new ServiceMessageProcessingEvent { RecordId = credentialRecord.Id, MessageType = credential.Type, ThreadId = credential.GetThreadId() }); return(credentialRecord.Id); }
/// <inheritdoc /> public async Task <bool> IsRevokedAsync(IAgentContext context, CredentialRecord record) { if (record.RevocationRegistryId == null) { return(false); } if (record.State == CredentialState.Offered || record.State == CredentialState.Requested) { return(false); } if (record.State == CredentialState.Revoked || record.State == CredentialState.Rejected) { return(true); } var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var proofRequest = new ProofRequest { Name = "revocation check", Version = "1.0", Nonce = await AnonCreds.GenerateNonceAsync(), RequestedAttributes = new Dictionary <string, ProofAttributeInfo> { { "referent1", new ProofAttributeInfo { Name = record.CredentialAttributesValues.First().Name } } }, NonRevoked = new RevocationInterval { From = (uint)now, To = (uint)now } }; var proof = await CreateProofAsync(context, proofRequest, new RequestedCredentials { RequestedAttributes = new Dictionary <string, RequestedAttribute> { { "referent1", new RequestedAttribute { CredentialId = record.CredentialId, Timestamp = now, Revealed = true } } } }); var isValid = await VerifyProofAsync(context, proofRequest.ToJson(), proof); if (!isValid) { await record.TriggerAsync(CredentialTrigger.Revoke); record.SetTag("LastRevocationCheck", now.ToString()); await RecordService.UpdateAsync(context.Wallet, record); } return(!isValid); }
/// <inheritdoc /> public virtual async Task <CredentialOfferMessage> CreateOfferAsync(Wallet wallet, DefaultCreateOfferConfiguration config) { Logger.LogInformation(LoggingEvents.CreateCredentialOffer, "DefinitionId {0}, ConnectionId {1}, IssuerDid {2}", config.CredentialDefinitionId, config.ConnectionId, config.IssuerDid); var connection = await ConnectionService.GetAsync(wallet, config.ConnectionId); var offerJson = await AnonCreds.IssuerCreateCredentialOfferAsync(wallet, config.CredentialDefinitionId); var nonce = JObject.Parse(offerJson)["nonce"].ToObject <string>(); // Write offer record to local wallet var credentialRecord = new CredentialRecord { Id = Guid.NewGuid().ToString(), CredentialDefinitionId = config.CredentialDefinitionId, OfferJson = offerJson, ValuesJson = CredentialUtils.FormatCredentialValues(config.CredentialAttributeValues), State = CredentialState.Offered, ConnectionId = connection.GetId(), }; credentialRecord.Tags.Add(TagConstants.Nonce, nonce); credentialRecord.Tags.Add(TagConstants.Role, TagConstants.Issuer); credentialRecord.Tags.Add(TagConstants.ConnectionId, connection.GetId()); if (!string.IsNullOrEmpty(config.IssuerDid)) { credentialRecord.Tags.Add(TagConstants.IssuerDid, config.IssuerDid); } if (config.Tags != null) { foreach (var tag in config.Tags) { if (!credentialRecord.Tags.Keys.Contains(tag.Key)) { credentialRecord.Tags.Add(tag.Key, tag.Value); } } } await RecordService.AddAsync(wallet, credentialRecord); var credentialOffer = await MessageSerializer.PackSealedAsync <CredentialOfferMessage>( new CredentialOfferDetails { OfferJson = offerJson }, wallet, connection.MyVk, connection.TheirVk); credentialOffer.Type = MessageUtils.FormatDidMessageType(connection.TheirDid, MessageTypes.CredentialOffer); return(credentialOffer); }
/// <inheritdoc /> public virtual async Task <List <Credential> > ListCredentialsForProofRequestAsync(IAgentContext agentContext, ProofRequest proofRequest, string attributeReferent) { using (var search = await AnonCreds.ProverSearchCredentialsForProofRequestAsync(agentContext.Wallet, proofRequest.ToJson())) { var searchResult = await search.NextAsync(attributeReferent, 100); return(JsonConvert.DeserializeObject <List <Credential> >(searchResult)); } }
public async Task TestProverGetClaimOffersWorksForInvalidFilterJson() { await InitCommonWallet(); var filter = string.Format("{{\"schema_seq_no\":\"{0}\"}}", 1); var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.ProverGetClaimOffersAsync(commonWallet, filter) ); }
public async Task <ClaimDefinition> CreateClaimDefinitionAsync(string userId, Guid credentialSchemaId) { var schema = await _dbContext.CredentialSchemas.Include(p => p.User).FirstOrDefaultAsync(p => p.Id == credentialSchemaId); var schemaCreatorWalletData = await GetDefaultWalletDataAsync(schema.UserId); var walletData = await GetDefaultWalletDataAsync(userId); var wallet = await Wallet.OpenWalletAsync(walletData.Name, null, null); try { using (var pool = await PoolUtils.CreateAndOpenPoolLedgerAsync()) { var schemaData = JsonConvert.SerializeObject(new { name = schema.Name, version = schema.Version }); var getSchemaRequest = await Ledger.BuildGetSchemaRequestAsync(walletData.Did, schemaCreatorWalletData.Did, schemaData); var getSchemaResponse = await Ledger.SubmitRequestAsync(pool, getSchemaRequest); var schemaValue = JObject.Parse(getSchemaResponse).GetValue("result"); var claimDefJson = await AnonCreds.IssuerCreateAndStoreClaimDefAsync(wallet, walletData.Did, schemaValue.ToString(), "CL", false); var claimDef = JObject.Parse(claimDefJson); var claimDefRequest = await Ledger.BuildClaimDefTxnAsync(walletData.Did, claimDef.Value <int>("ref"), claimDef.Value <string>("signature_type"), claimDef.GetValue("data").ToString()); var result = await Ledger.SignAndSubmitRequestAsync(pool, wallet, walletData.Did, claimDefRequest); var claimDefinition = new ClaimDefinition { Id = Guid.NewGuid(), CredentialSchemaId = credentialSchemaId, UserId = userId }; _dbContext.ClaimDefinitions.Add(claimDefinition); await _dbContext.SaveChangesAsync(); return(claimDefinition); } } catch (Exception ex) { throw; } finally { await wallet.CloseAsync(); } }
public async Task TestProverCreateProofWorksForInvalidSchemas() { var schemasJson = "{}"; var credentialDefsJson = new JObject(new JProperty(issuer1gvtCredDefId, issuer1gvtCredDef)).ToString(); var revocStatesJson = "{}"; var ex = await Assert.ThrowsExceptionAsync <InvalidStructureException>(() => AnonCreds.ProverCreateProofAsync(wallet, proofRequest, requestedCredentialsJson, masterSecretId, schemasJson, credentialDefsJson, revocStatesJson) ); }