Exemplo n.º 1
0
        /// <summary>
        /// Constructs my DID doc in a pairwise relationship from a connection record and the agents provisioning record.
        /// </summary>
        /// <param name="connection">Connection record.</param>
        /// <param name="provisioningRecord">Provisioning record.</param>
        /// <returns>DID Doc</returns>
        public static DidDoc MyDidDoc(this ConnectionRecord connection, ProvisioningRecord provisioningRecord)
        {
            var doc = new DidDoc
            {
                Keys = new List <DidDocKey>
                {
                    new DidDocKey
                    {
                        Id              = $"{connection.MyDid}#keys-1",
                        Type            = DefaultKeyType,
                        Controller      = connection.MyDid,
                        PublicKeyBase58 = connection.MyVk
                    }
                }
            };

            if (!string.IsNullOrEmpty(provisioningRecord.Endpoint.Uri))
            {
                doc.Services = new List <IDidDocServiceEndpoint>
                {
                    new IndyAgentDidDocService
                    {
                        Id = $"{connection.MyDid};indy",
                        ServiceEndpoint = provisioningRecord.Endpoint.Uri,
                        RecipientKeys   = connection.MyVk != null ? new[] { connection.MyVk } : new string[0],
                        RoutingKeys     = provisioningRecord.Endpoint?.Verkey != null ? new[] { provisioningRecord.Endpoint.Verkey } : new string[0]
                    }
                };
            }

            return(doc);
        }
        /// <inheritdoc/>
        public async Task <ConnectionRecord> ProcessResponseAsync(IAgentContext agentContext, DidExchangeResponseMessage responseMessage, ConnectionRecord connectionRecord)
        {
            await connectionRecord.TriggerAsync(ConnectionTrigger.Response);

            DidDoc didDoc = null;

            if (responseMessage.DidDoc.Data.Base64 is { } data)
            {
                var isValidSignature = await responseMessage.DidDoc.Data.VerifyJsonWebSignature();

                if (isValidSignature == false)
                {
                    throw new AriesFrameworkException(ErrorCode.InvalidSignatureEncoding,
                                                      "The given JSON web signature is invalid");
                }

                var json = data.FromBase64Url();
                didDoc = json.ToObject <DidDoc>();
            }

            if (didDoc == null)
            {
                throw new NotImplementedException("Response message must provide an attached did document");
            }

            if (didDoc.Keys.All(key => key.Type == DidDocExtensions.DefaultKeyType) == false)
            {
                throw new NotImplementedException($"Only {DidDocExtensions.DefaultKeyType} is supported");
            }

            var indyService = (IndyAgentDidDocService)didDoc.Services.First(service => service is IndyAgentDidDocService);

            var agentEndpoint = new AgentEndpoint(indyService.ServiceEndpoint, null, indyService.RoutingKeys.ToArray());

            connectionRecord.TheirDid = responseMessage.Did;
            connectionRecord.TheirVk  =
                didDoc.Keys.FirstOrDefault(key => key.Controller == responseMessage.Did)?.PublicKeyBase58
                ?? throw new NullReferenceException("Missing public key for controller");
            connectionRecord.Endpoint = agentEndpoint;

            await _recordService.UpdateAsync(agentContext.Wallet, connectionRecord);

            _eventAggregator.Publish(new ServiceMessageProcessingEvent()
            {
                MessageType = responseMessage.Type,
                RecordId    = connectionRecord.Id,
                ThreadId    = responseMessage.GetThreadId()
            });

            return(connectionRecord);
        }
        /// <inheritdoc/>
        public async Task <ConnectionRecord> ProcessRequestAsync(IAgentContext agentContext, DidExchangeRequestMessage requestMessage)
        {
            var myDid = await Did.CreateAndStoreMyDidAsync(agentContext.Wallet, "{}");

            DidDoc didDoc = null;

            if (requestMessage.DidDoc.Data.Base64 is { } data)
            {
                var isValidSignature = await requestMessage.DidDoc.Data.VerifyJsonWebSignature();

                if (isValidSignature == false)
                {
                    throw new AriesFrameworkException(ErrorCode.InvalidSignatureEncoding,
                                                      "The given JSON web signature is invalid");
                }

                var json = data.FromBase64Url();
                didDoc = json.ToObject <DidDoc>();
            }

            // Todo: Handle resolvable Dids
            if (didDoc == null)
            {
                throw new NotImplementedException("Request message must provide an attached did document");
            }

            if (didDoc.Keys.All(key => key.Type == DidDocExtensions.DefaultKeyType) == false)
            {
                throw new NotImplementedException($"Only {DidDocExtensions.DefaultKeyType} is supported");
            }

            var indyService = (IndyAgentDidDocService)didDoc.Services.First(service => service is IndyAgentDidDocService);

            var agentEndpoint = new AgentEndpoint(indyService.ServiceEndpoint, null, indyService.RoutingKeys.ToArray());

            var connectionRecord = new ConnectionRecord
            {
                Id    = Guid.NewGuid().ToString(),
                Alias = new ConnectionAlias {
                    Name = requestMessage.Label
                },
                MyDid    = DidUtils.ConvertVerkeyToDidKey(myDid.VerKey),
                MyVk     = myDid.VerKey,
                TheirDid = requestMessage.Did,
                TheirVk  = didDoc.Keys.FirstOrDefault(key => key.Controller == requestMessage.Did)?.PublicKeyBase58
                           ?? throw new NullReferenceException("Missing public for controller"),
                                 Endpoint = agentEndpoint,
                                 State    = ConnectionState.Negotiating
            };
            await _recordService.AddAsync(agentContext.Wallet, connectionRecord);

            _eventAggregator.Publish(
                new ServiceMessageProcessingEvent
            {
                MessageType = requestMessage.Type,
                RecordId    = connectionRecord.Id,
                ThreadId    = requestMessage.GetThreadId()
            });

            return(connectionRecord);
        }