/// <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);
        }
Esempio n. 2
0
        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());
        }
        /// <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 Task <(RequestPresentationMessage, ProofRecord)> CreateRequestAsync(
     IAgentContext agentContext,
     ProofRequest proofRequest,
     string connectionId) =>
        /// <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));
            }
        }
        /// <inheritdoc />
        public async Task <(RequestPresentationMessage, ProofRecord)> CreateRequestFromProposalAsync(IAgentContext agentContext, ProofRequestParameters requestParams,
                                                                                                     string proofRecordId, string connectionId)
        {
            Logger.LogInformation(LoggingEvents.CreateProofRequest, "ConnectionId {0}", connectionId);

            if (proofRecordId == null)
            {
                throw new ArgumentNullException(nameof(proofRecordId), "You must provide proof record Id");
            }
            if (connectionId != null)
            {
                var connection = await ConnectionService.GetAsync(agentContext, connectionId);

                if (connection.State != ConnectionState.Connected)
                {
                    throw new AriesFrameworkException(ErrorCode.RecordInInvalidState,
                                                      $"Connection state was invalid. Expected '{ConnectionState.Connected}', found '{connection.State}'");
                }
            }

            var proofRecord = await RecordService.GetAsync <ProofRecord>(agentContext.Wallet, proofRecordId);

            var proofProposal = proofRecord.ProposalJson.ToObject <ProofProposal>();


            // Build Proof Request from Proposal info
            var proofRequest = new ProofRequest
            {
                Name                = requestParams.Name,
                Version             = requestParams.Version,
                Nonce               = await AnonCreds.GenerateNonceAsync(),
                RequestedAttributes = new Dictionary <string, ProofAttributeInfo>(),
                NonRevoked          = requestParams.NonRevoked
            };

            var attributesByReferent = new Dictionary <string, List <ProposedAttribute> >();

            foreach (var proposedAttribute in proofProposal.ProposedAttributes)
            {
                if (proposedAttribute.Referent == null)
                {
                    proposedAttribute.Referent = Guid.NewGuid().ToString();
                }

                if (attributesByReferent.TryGetValue(proposedAttribute.Referent, out var referentAttributes))
                {
                    referentAttributes.Add(proposedAttribute);
                }
                else
                {
                    attributesByReferent.Add(proposedAttribute.Referent, new List <ProposedAttribute> {
                        proposedAttribute
                    });
                }
            }

            foreach (var referent in attributesByReferent.AsEnumerable())
            {
                var proposedAttributes = referent.Value;
                var attributeName      = proposedAttributes.Count() == 1 ? proposedAttributes.Single().Name : null;
                var attributeNames     = proposedAttributes.Count() > 1 ? proposedAttributes.ConvertAll <string>(r => r.Name).ToArray() : null;


                var requestedAttribute = new ProofAttributeInfo()
                {
                    Name         = attributeName,
                    Names        = attributeNames,
                    Restrictions = new List <AttributeFilter>
                    {
                        new AttributeFilter {
                            CredentialDefinitionId = proposedAttributes.First().CredentialDefinitionId,
                            SchemaId  = proposedAttributes.First().SchemaId,
                            IssuerDid = proposedAttributes.First().IssuerDid
                        }
                    }
                };
                proofRequest.RequestedAttributes.Add(referent.Key, requestedAttribute);
                Console.WriteLine($"Added Attribute to Proof Request \n {proofRequest.ToString()}");
            }

            foreach (var pred in proofProposal.ProposedPredicates)
            {
                if (pred.Referent == null)
                {
                    pred.Referent = Guid.NewGuid().ToString();
                }
                var predicate = new ProofPredicateInfo()
                {
                    Name           = pred.Name,
                    PredicateType  = pred.Predicate,
                    PredicateValue = pred.Threshold,
                    Restrictions   = new List <AttributeFilter>
                    {
                        new AttributeFilter {
                            CredentialDefinitionId = pred.CredentialDefinitionId,
                            SchemaId  = pred.SchemaId,
                            IssuerDid = pred.IssuerDid
                        }
                    }
                };
                proofRequest.RequestedPredicates.Add(pred.Referent, predicate);
            }

            proofRecord.RequestJson = proofRequest.ToJson();
            await proofRecord.TriggerAsync(ProofTrigger.Request);

            await RecordService.UpdateAsync(agentContext.Wallet, proofRecord);

            var message = new RequestPresentationMessage
            {
                Id       = proofRecord.Id,
                Requests = new[]
                {
                    new Attachment
                    {
                        Id       = "libindy-request-presentation-0",
                        MimeType = CredentialMimeTypes.ApplicationJsonMimeType,
                        Data     = new AttachmentContent
                        {
                            Base64 = proofRequest
                                     .ToJson()
                                     .GetUTF8Bytes()
                                     .ToBase64String()
                        }
                    }
                }
            };

            message.ThreadFrom(proofRecord.GetTag(TagConstants.LastThreadId));
            return(message, proofRecord);
        }
        /// <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);

                var result = JsonConvert.DeserializeObject <List <Credential> >(searchResult);

                if (proofRequest.NonRevoked != null)
                {
                    return(result.Where(x => x.CredentialInfo.RevocationRegistryId != null).ToList());
                }
                return(result);
            }
        }