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, // Ledger will not return correct revocation state if the 'from' field // is other than 0 from : 0, //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, 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()); }
/// <inheritdoc /> public async Task <ProofRecord> CreatePresentationAsync(IAgentContext agentContext, RequestPresentationMessage requestPresentation, RequestedCredentials requestedCredentials) { var service = requestPresentation.GetDecorator <ServiceDecorator>(DecoratorNames.ServiceDecorator); var record = await ProcessRequestAsync(agentContext, requestPresentation, null); var(presentationMessage, proofRecord) = await CreatePresentationAsync(agentContext, record.Id, requestedCredentials); await MessageService.SendAsync( wallet : agentContext.Wallet, message : presentationMessage, recipientKey : service.RecipientKeys.First(), endpointUri : service.ServiceEndpoint, routingKeys : service.RoutingKeys?.ToArray()); return(proofRecord); }
/// <inheritdoc /> public virtual async Task <string> CreateProofAsync(IAgentContext agentContext, ProofRequest proofRequest, RequestedCredentials requestedCredentials) { 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, proofRequest.ToJson(), requestedCredentials.ToJson(), provisioningRecord.MasterSecretId, schemas, definitions, revocationStates); return(proofJson); }