public override async Task <ValidationResult> ValidateAsync(JToken proof, ProofOptions options)
        {
            var result = await base.ValidateAsync(proof, options);

            var verificationMethodId = Options.VerificationMethod["id"].ToString();
            var controllerId         = Controller ?? GetVerificationMethod() ??
                                       throw new ProofValidationException("Controller or VerificationMethod not found");

            var framed = JsonLdProcessor.Frame(
                controllerId,
                new JObject
            {
                { "@context", Constants.SECURITY_CONTEXT_V2_URL },
                { "id", controllerId },
                { Term, new JObject
                  {
                      { "@embed", "@never" },
                      { "id", verificationMethodId }
                  } }
            },
                options.GetProcessorOptions());

            if (framed[Term] is JArray keys && keys.Any(x => x.ToString() == verificationMethodId))
            {
                result.Controller = framed["id"].ToString();
                return(result);
            }

            throw new ProofValidationException($"Verification method '{verificationMethodId}' not authorized " +
                                               $"by controller for proof purpose '{Term}'.");
        }
 public virtual Task <ValidationResult> ValidateAsync(JToken proof, ProofOptions options)
 {
     if (proof["proofPurpose"]?.ToString() == Term)
     {
         return(Task.FromResult(new ValidationResult()));
     }
     throw new ProofValidationException($"Invalid proof purpose. Expected '{Term}', found '{proof["proofPurpose"]}'");
 }
        public override async Task <ProofResult> CreateProofAsync(ProofOptions options)
        {
            VerificationMethod = options.AdditonalData["originalDocument"]["proof"]["verificationMethod"].ToString();

            var result = await base.CreateProofAsync(options);

            result.UpdatedDocument = options.AdditonalData["revealDocument"] as JObject;
            return(result);
        }
        protected override IVerifyData CreateVerifyData(JObject proof, ProofOptions options)
        {
            var processorOptions = options.GetProcessorOptions();

            var c14nProofOptions = Helpers.CanonizeProofStatements(proof, processorOptions);
            var c14nDocument     = Helpers.CanonizeStatements(options.Input, processorOptions);

            return((StringArray)c14nProofOptions.Concat(c14nDocument).ToArray());
        }
示例#5
0
        public override async Task <JObject> UpdateAsync(JObject proof, ProofOptions options)
        {
            proof = await base.UpdateAsync(proof, options);

            proof["challenge"] = Challenge ?? throw new Exception("'challenge' must be specified.");

            if (Domain != null)
            {
                proof["domain"] = Domain;
            }
            return(proof);
        }
示例#6
0
        protected override IVerifyData CreateVerifyData(JObject proof, ProofOptions options)
        {
            var documentCopy = options.Input.DeepClone();
            var proofCopy    = proof.DeepClone();

            proofCopy.Remove("signatureValue");
            documentCopy["proof"] = proofCopy;

            var canonicalizer = new JsonCanonicalizer(documentCopy.ToString())
                                .GetEncodedUTF8();
            var hashed = SHA256.Create().ComputeHash(canonicalizer);

            return((ByteArray)hashed);
        }
        public override async Task <JObject> UpdateAsync(JObject proof, ProofOptions options)
        {
            if (Options?.Capability == null)
            {
                throw new Exception("'capability' is required.");
            }

            proof = await base.UpdateAsync(proof, options);

            proof["capability"] = Options.Capability;
            if (Options.CapabilityAction != null)
            {
                proof["capabilityAction"] = Options.CapabilityAction;
            }
            return(proof);
        }
示例#8
0
        public override Task <ValidationResult> ValidateAsync(JToken proof, ProofOptions options)
        {
            if (proof["challenge"]?.ToString() != Challenge)
            {
                throw new Exception("The challenge is not as expected;" +
                                    $"challenge = '{proof["challenge"]}', expected = '{Challenge}'");
            }

            if (Domain != null && proof["domain"]?.ToString() != Domain)
            {
                throw new Exception("The domain is not as expected;" +
                                    $"domain = '{proof["domain"]}', expected = '{Domain}'");
            }

            return(base.ValidateAsync(proof, options));
        }
        /// <inheritdoc />
        protected override IVerifyData CreateVerifyData(JObject proof, ProofOptions options)
        {
            var originalProof = options.AdditonalData["originalDocument"]["proof"].DeepClone() as JObject;

            originalProof["type"] = "BbsBlsSignature2020";

            var processorOptions = options.GetProcessorOptions();

            var proofStatements    = Helpers.CanonizeProofStatements(originalProof, processorOptions, Constants.SECURITY_CONTEXT_V3_URL);
            var documentStatements = Helpers.CanonizeStatements(options.Input, processorOptions);

            var numberOfProofStatements = proofStatements.Count();

            // if RevealDocument is present, this is a proof derivation
            // apply transformation of blank node to urn:bnid format
            if (RevealDocument != null)
            {
                var transformedInputDocumentStatements = documentStatements.Select(TransformBlankNodeToId).ToArray();
                var compactInputDocument = Helpers.FromRdf(transformedInputDocumentStatements);

                var revealDocument           = JsonLdProcessor.Frame(compactInputDocument, RevealDocument, processorOptions);
                var revealDocumentStatements = Helpers.CanonizeStatements(revealDocument, processorOptions);

                options.AdditonalData["revealDocument"] = revealDocument;

                var documentRevealIndicies = revealDocumentStatements.Select(x => Array.IndexOf(transformedInputDocumentStatements, x) + numberOfProofStatements).ToArray();

                if (documentRevealIndicies.Count() != revealDocumentStatements.Count())
                {
                    throw new Exception("Some statements in the reveal document not found in original proof");
                }

                var proofRevealIndicies = new int[numberOfProofStatements].Select((_, x) => x).ToArray();
                var revealIndicies      = proofRevealIndicies.Concat(documentRevealIndicies);

                options.AdditonalData["revealIndicies"] = new JArray(revealIndicies.ToArray());
            }
            else
            {
                // it's proof verification, apply transform id to blank node
                documentStatements = documentStatements.Select(TransformIdToBlankNode);
            }

            var allInputStatements = proofStatements.Concat(documentStatements);

            return((StringArray)allInputStatements.ToArray());
        }
示例#10
0
        public override async Task <JObject> UpdateAsync(JObject proof, ProofOptions options)
        {
            proof = await base.UpdateAsync(proof, options);

            // no capability chain given, attempt to compute from parent
            if (CapabilityChain == null)
            {
                var processorOptions = new JsonLdProcessorOptions
                {
                    CompactToRelative = false,
                    DocumentLoader    = options.DocumentLoader.Load
                };

                var capability = await Utils.FetchInSecurityContextAsync(
                    options.Input, false, processorOptions);

                CapabilityChain = await Utils.ComputeCapabilityChainAsync(
                    capability, processorOptions);
            }

            proof["capabilityChain"] = new JArray(CapabilityChain);
            return(proof);
        }
        /// <inheritdoc />
        protected override Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options)
        {
            var stringArray = verifyData as StringArray ?? throw new Exception("Unsupported verify data type");

            var proofData = Helpers.FromBase64String(proof["proofValue"]?.ToString() ?? throw new Exception("Proof value not found"));
            var nonce     = Helpers.FromBase64String(proof["nonce"]?.ToString() ?? throw new Exception("Nonce not found"));
            var keyPair   = new Bls12381G2Key2020(GetVerificationMethod(proof as JObject, options));

            var messageCount = Service.GetTotalMessageCount(proofData);

            var verifyResult = Service.VerifyProof(new VerifyProofRequest(
                                                       publicKey: keyPair.ToBlsKeyPair().GetBbsKey((uint)messageCount),
                                                       proof: proofData,
                                                       messages: stringArray.Data,
                                                       nonce: nonce));

            if (!verifyResult)
            {
                throw new Exception("Invalid signature proof");
            }
            return(Task.CompletedTask);
        }
示例#12
0
 protected override Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options)
 {
     throw new NotImplementedException();
 }
示例#13
0
 protected override Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options)
 {
     proof["proofValue"] = Convert.ToBase64String((verifyData as ByteArray).Data);
     return(Task.FromResult(proof));
 }
示例#14
0
 public override Task <ValidationResult> VerifyProofAsync(JToken proof, ProofOptions options)
 {
     throw new NotImplementedException();
 }
        public override async Task <LinkedDataProofs.Purposes.ValidationResult> ValidateAsync(JToken proof, ProofOptions options)
        {
            if (proof["capability"] is null)
            {
                throw new Exception("'capability' was not found in the capability invocation proof.");
            }

            if (Options?.ExpectedTarget == null)
            {
                throw new ArgumentNullException("ExpectedTarget is required.");
            }

            // 1. get the capability in the security v2 context
            var result = await Utils.FetchInSecurityContextAsync(proof["capability"], false, new JsonLdProcessorOptions
            {
                CompactToRelative = false,
                DocumentLoader    = options.DocumentLoader.Load
            });

            var capability = new CapabilityDelegation(result as JObject);

            // 2. verify the capability delegation chain
            await Utils.VerifyCapabilityChain(capability, Options);

            // 3. verify the invoker...
            // authorized invoker must match the verification method itself OR
            // the controller of the verification method
            if (!capability.HasInvoker(new VerificationMethod(Options.VerificationMethod)))
            {
                throw new Exception("The authorized invoker does not match the " +
                                    "verification method or its controller.");
            }

            var validateResult = await base.ValidateAsync(proof, options);

            validateResult.Invoker    = validateResult.Controller;
            validateResult.Controller = null;

            return(validateResult);
        }
        protected override Task VerifyAsync(IVerifyData payload, JToken proof, JToken verificationMethod, ProofOptions options)
        {
            var verifyData = payload as StringArray ?? throw new ArgumentException("Invalid data type");

            var blsVerificationMethod = new Bls12381G2Key2020(verificationMethod as JObject);

            var key       = new BlsKeyPair(Multibase.Base58.Decode(blsVerificationMethod.PublicKeyBase58));
            var signature = Helpers.FromBase64String(proof["proofValue"]?.ToString() ?? throw new Exception("Proof value not found"));

            var valid = SignatureService.Verify(new VerifyRequest(key, signature, verifyData.Data));

            if (!valid)
            {
                throw new Exception("Invalid signature");
            }
            return(Task.CompletedTask);
        }
        protected override Task <JObject> SignAsync(IVerifyData payload, JObject proof, ProofOptions options)
        {
            var verifyData = payload as StringArray ?? throw new ArgumentException("Invalid data type");

            if (KeyPair?.SecretKey == null)
            {
                throw new Exception("Private key not found.");
            }

            var proofValue = SignatureService.Sign(new SignRequest(KeyPair, verifyData.Data));

            proof["proofValue"] = Convert.ToBase64String(proofValue);
            proof["type"]       = "BbsBlsSignature2020";

            return(Task.FromResult(proof));
        }
        /// <inheritdoc />
        protected override Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options)
        {
            var verifyDataArray = verifyData as StringArray ?? throw new Exception("Unsupported verify data type");

            var derivedProof = new JObject {
                { "@context", Constants.SECURITY_CONTEXT_V3_URL }
            };
            var originalProof = options.AdditonalData["originalDocument"]["proof"];
            var signature     = Convert.FromBase64String(originalProof["proofValue"].ToString());

            var keyPair = new Bls12381G2Key2020(GetVerificationMethod(originalProof as JObject, options));
            var bbsKey  = keyPair.ToBlsKeyPair().GetBbsKey((uint)verifyDataArray.Data.Length);
            var nonce   = Nonce ?? Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());

            var proofMessages = GetProofMessages(
                allInputStatements: verifyDataArray.Data,
                revealIndicies: options.AdditonalData["revealIndicies"].ToObject <int[]>());

            var outputProof = Service.CreateProof(new CreateProofRequest(
                                                      publicKey: bbsKey,
                                                      messages: proofMessages.ToArray(),
                                                      signature: signature,
                                                      blindingFactor: null,
                                                      nonce: nonce));

            // Set the proof value on the derived proof
            derivedProof["proofValue"]         = Convert.ToBase64String(outputProof);
            derivedProof["nonce"]              = Convert.ToBase64String(nonce);
            derivedProof["created"]            = originalProof["created"];
            derivedProof["proofPurpose"]       = originalProof["proofPurpose"];
            derivedProof["verificationMethod"] = originalProof["verificationMethod"];
            derivedProof["type"] = "BbsBlsSignatureProof2020";

            return(Task.FromResult(derivedProof));
        }
示例#19
0
        protected override Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options)
        {
            var data = verifyData as ByteArray ?? throw new Exception("Invalid verify data type");

            var signature = Signer.Sign(data);

            proof["signatureValue"] = Multibase.Base58.Encode(signature);

            return(Task.FromResult(proof));
        }
示例#20
0
 public virtual Task <JObject> UpdateAsync(JObject proof, ProofOptions options)
 {
     proof["proofPurpose"] = Term;
     return(Task.FromResult(proof));
 }
示例#21
0
        protected override Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options)
        {
            var data = verifyData as ByteArray ?? throw new Exception("Invalid verify data type");

            var signature = Multibase.Base58.Decode(proof["signatureValue"].ToString());
            var valid     = Signer.Verify(signature, data);

            if (!valid)
            {
                throw new Exception("Invalid signature");
            }
            return(Task.CompletedTask);
        }