Esempio n. 1
0
        public async Task SignAndVerifyDocument()
        {
            var aliceKey = new Ed25519VerificationKey2018(Mock.Alice_Keys.VerificationMethod.First() as JObject);

            var signedDocument = await LdSignatures.SignAsync(
                Mock.ExampleDoc,
                new ProofOptions
            {
                Suite = new JcsEd25519Signature2020
                {
                    Signer             = aliceKey,
                    VerificationMethod = aliceKey.Id
                },
                Purpose        = new AssertionMethodPurpose(),
                DocumentLoader = Mock.DocumentLoader
            });

            var verified = await LdSignatures.VerifyAsync(
                document: signedDocument,
                options: new ProofOptions
            {
                Suite = new JcsEd25519Signature2020
                {
                    Signer             = aliceKey,
                    VerificationMethod = aliceKey.Id
                },
                Purpose        = new AssertionMethodPurpose(),
                DocumentLoader = Mock.DocumentLoader
            });

            Assert.NotNull(verified);
        }
        public async Task SignCreateProofAndVerifyVaccination()
        {
            var unsignedDocument   = Utilities.LoadJson("Data/vaccination-certificate-unsigned.jsonld");
            var verificationMethod = new Bls12381G2Key2020(Utilities.LoadJson("Data/did_example_489398593_test.json"));

            var signedDocument = await LdSignatures.SignAsync(unsignedDocument, new ProofOptions
            {
                Suite = new BbsBlsSignature2020
                {
                    KeyPair            = verificationMethod.ToBlsKeyPair(),
                    VerificationMethod = "did:example:489398593#test"
                },
                Purpose = new AssertionMethodPurpose()
            });

            var revealDocument = Utilities.LoadJson("Data/vaccination-certificate-frame.jsonld");

            var derivedDocument = await LdSignatures.SignAsync(signedDocument, new ProofOptions
            {
                Suite = new BbsBlsSignatureProof2020
                {
                    RevealDocument = revealDocument
                },
                Purpose = new AssertionMethodPurpose()
            });

            var result = await LdSignatures.VerifyAsync(derivedDocument, new ProofOptions
            {
                Suite   = new BbsBlsSignatureProof2020(),
                Purpose = new AssertionMethodPurpose()
            });

            Assert.NotNull(result);
            Assert.Equal("did:example:489398593", result.Controller);
        }
Esempio n. 3
0
        public async Task SignSampleDocument()
        {
            // an example document to sign
            var document = JObject.Parse(@"{
                'id': 'Alice'
            }");

            // signer key
            var key = Ed25519VerificationKey2018.Generate();

            // create proof
            var signedDocument = await LdSignatures.SignAsync(
                document,
                new ProofOptions
            {
                Suite = new Ed25519Signature2018
                {
                    Signer             = key,
                    VerificationMethod = key.Id
                },
                Purpose = new AssertionMethodPurpose()
            });

            Console.WriteLine(signedDocument.ToString(Formatting.Indented));
        }
Esempio n. 4
0
        public async Task VerifySignedVerifiableCredential()
        {
            var document = Utilities.LoadJson("Data/test_signed_vc.json");

            var result = await LdSignatures.VerifyAsync(document, new ProofOptions
            {
                Suite   = new BbsBlsSignature2020(),
                Purpose = new AssertionMethodPurpose()
            });

            result.Should().NotBeNull();
        }
Esempio n. 5
0
        public async Task ShouldNotVerifyBadDocument()
        {
            var document = Utilities.LoadJson("Data/test_bad_signed_document.json");

            var actual = LdSignatures.VerifyAsync(document, new ProofOptions
            {
                Suite   = new BbsBlsSignature2020(),
                Purpose = new AssertionMethodPurpose()
            });

            await Assert.ThrowsAsync <BbsException>(() => actual);
        }
        public async Task VerifyPartialDerivedProofFromVc()
        {
            var document = Utilities.LoadJson("Data/test_partial_proof_vc_document.json");

            var result = await LdSignatures.VerifyAsync(document, new ProofOptions
            {
                Suite   = new BbsBlsSignatureProof2020(),
                Purpose = new AssertionMethodPurpose()
            });

            Assert.NotNull(result);
            Assert.Equal("did:example:489398593", result.Controller);
        }
Esempio n. 7
0
        public async Task VerifySignedDocumentIncorrectPurposeThrows()
        {
            var cap = Mock.ExampleDocAlphaInvocation;

            await Assert.ThrowsAsync <ProofValidationException>(() => LdSignatures.VerifyAsync(
                                                                    document: cap,
                                                                    options: new ProofOptions
            {
                Suite          = new Ed25519Signature2018(),
                Purpose        = new AssertionMethodPurpose(),
                DocumentLoader = Mock.DocumentLoader
            }));
        }
Esempio n. 8
0
        public async Task ShouldNotVerifyModifiedSignedDocument()
        {
            var document = Utilities.LoadJson("Data/test_signed_document.json");

            document["email"] = "*****@*****.**";

            var actual = LdSignatures.VerifyAsync(document, new ProofOptions
            {
                Suite   = new BbsBlsSignature2020(),
                Purpose = new AssertionMethodPurpose()
            });

            await Assert.ThrowsAsync <Exception>(() => actual);
        }
Esempio n. 9
0
        public async Task ShouldNotVerifyAdditionalUnsignedStatement()
        {
            var document = Utilities.LoadJson("Data/test_signed_document.json");

            document["unsignedClaim"] = "oops";

            var actual = LdSignatures.VerifyAsync(document, new ProofOptions
            {
                Suite   = new BbsBlsSignature2020(),
                Purpose = new AssertionMethodPurpose()
            });

            await Assert.ThrowsAsync <Exception>(() => actual);
        }
Esempio n. 10
0
        public async Task SignMockSuite()
        {
            var doc = Utilities.LoadJson("TestData/example-doc.json");

            var data = await LdSignatures.SignAsync(doc, new ProofOptions
            {
                Suite = new MockSuite
                {
                    VerificationMethod = "did:example:alice"
                },
                Purpose = new AssertionMethodPurpose()
            });

            Assert.NotNull(data);
            Assert.NotNull(data["proof"]);
        }
Esempio n. 11
0
        public async Task VerifySignedInvocationCap()
        {
            var cap = Mock.ExampleDocAlphaInvocation;

            var result = await LdSignatures.VerifyAsync(
                document: cap,
                options: new ProofOptions
            {
                Suite   = new Ed25519Signature2018(),
                Purpose = new CapabilityInvocation(new PurposeOptions
                {
                    ExpectedTarget = Mock.RootCapAlpha.Id
                }),
                DocumentLoader = Mock.DocumentLoader
            });

            Assert.NotNull(result);
        }
Esempio n. 12
0
        public async Task SignVerifiableCredential()
        {
            var keyPair  = BlsKeyPair.GenerateG2();
            var document = Utilities.LoadJson("Data/test_vc.json");

            var signedDocument = await LdSignatures.SignAsync(document, new ProofOptions
            {
                Suite = new BbsBlsSignature2020
                {
                    KeyPair            = keyPair,
                    VerificationMethod = "did:example:alice#key-1"
                },
                Purpose = new AssertionMethodPurpose()
            });

            signedDocument.Should().NotBeNull();
            signedDocument["proof"].Should().NotBeNull();
            signedDocument["proof"]["proofValue"].Should().NotBeNull();
        }
Esempio n. 13
0
        public async Task Test1()
        {
            var doc = Utilities.LoadJson("TestData/example-doc.json");

            var signedDoc = await LdSignatures.SignAsync(doc, new ProofOptions
            {
                Suite = new MockSuite
                {
                    VerificationMethod = "did:example:bob"
                },
                Purpose = new CapabilityInvocation()
                {
                    Controller = "did:example:bob",
                    Options    = new PurposeOptions
                    {
                        Capability = "http://example/mock"
                    }
                }
            });
        }
        public async Task SignDocumentRevealAll()
        {
            var revealDocument = Utilities.LoadJson("Data/test_reveal_all_document.json");
            var signedDocument = Utilities.LoadJson("Data/test_signed_document.json");

            var verificationMethod = new Bls12381G2Key2020(Utilities.LoadJson("Data/did_example_489398593_test.json"));

            var derivedDocument = await LdSignatures.SignAsync(signedDocument, new ProofOptions
            {
                Suite = new BbsBlsSignatureProof2020
                {
                    RevealDocument     = revealDocument,
                    VerificationMethod = verificationMethod.Id
                },
                Purpose = new AssertionMethodPurpose()
            });

            derivedDocument.Should().NotBeNull();
            derivedDocument["proof"].Should().NotBeNull();
            derivedDocument["proof"]["proofValue"].Should().NotBeNull();
        }
        public async Task SignDocumentRevealSome()
        {
            var revealDocument   = Utilities.LoadJson("Data/test_vc_reveal_document.json");
            var unsignedDocument = Utilities.LoadJson("Data/test_vc.json");

            var verificationMethod = new Bls12381G2Key2020(Utilities.LoadJson("Data/did_example_489398593_test.json"));

            var signedDocument = await LdSignatures.SignAsync(unsignedDocument, new ProofOptions
            {
                Suite = new BbsBlsSignature2020
                {
                    KeyPair            = verificationMethod.ToBlsKeyPair(),
                    VerificationMethod = "did:example:489398593#test"
                },
                Purpose = new AssertionMethodPurpose()
            });

            var derivedDocument = await LdSignatures.SignAsync(signedDocument, new ProofOptions
            {
                Suite = new BbsBlsSignatureProof2020
                {
                    RevealDocument = revealDocument
                },
                Purpose = new AssertionMethodPurpose()
            });

            derivedDocument.Should().NotBeNull();
            derivedDocument["proof"].Should().NotBeNull();
            derivedDocument["proof"]["proofValue"].Should().NotBeNull();

            var verifyDerived = await LdSignatures.VerifyAsync(derivedDocument, new ProofOptions
            {
                Suite   = new BbsBlsSignatureProof2020(),
                Purpose = new AssertionMethodPurpose()
            });

            Assert.NotNull(verifyDerived);
            Assert.Equal(verifyDerived.Controller, verificationMethod.Controller);
        }
Esempio n. 16
0
        public async Task SignDocument()
        {
            var aliceKey = new Ed25519VerificationKey2018(Mock.Alice_Keys.VerificationMethod.First() as JObject);

            var signedDocument = await LdSignatures.SignAsync(
                Mock.ExampleDoc,
                new ProofOptions
            {
                Suite = new JcsEd25519Signature2020
                {
                    Signer             = aliceKey,
                    VerificationMethod = aliceKey.Id
                },
                Purpose        = new AssertionMethodPurpose(),
                DocumentLoader = Mock.DocumentLoader
            });

            Assert.NotNull(signedDocument);
            Assert.NotNull(signedDocument["proof"]);
            Assert.Equal("assertionMethod", signedDocument["proof"]?["proofPurpose"]);
            Assert.NotNull(signedDocument["proof"]?["signatureValue"]);
            Assert.Equal(aliceKey.Id, signedDocument["proof"]?["verificationMethod"]);
        }
Esempio n. 17
0
        public async Task VerifyProofRandomKey()
        {
            var signer = new Ed25519VerificationKey2018(Mock.Diana_Keys.VerificationMethod.First() as JObject);

            var document = new DidDocument {
                Id = signer.Controller
            };

            var signedDocument = await LdSignatures.SignAsync(
                document,
                new ProofOptions
            {
                Suite = new Ed25519Signature2018
                {
                    Signer             = signer,
                    VerificationMethod = signer.Id
                },
                Purpose        = new AssertionMethodPurpose(),
                DocumentLoader = Mock.DocumentLoader
            });

            signedDocument["@context"] = new JArray(new[]
            {
                Constants.DID_V1_URL,
                Constants.SECURITY_CONTEXT_V2_URL
            });

            var result = await LdSignatures.VerifyAsync(signedDocument, new ProofOptions
            {
                Suite          = new Ed25519Signature2018(),
                Purpose        = new AssertionMethodPurpose(),
                DocumentLoader = Mock.DocumentLoader
            });

            Assert.NotNull(result);
        }
Esempio n. 18
0
        /// <summary>
        /// Verifies the capability chain, if any, attached to the given capability.
        /// </summary>
        /// <param name="capability"></param>
        /// <returns></returns>
        public static async Task <JToken> VerifyCapabilityChain(JToken capability, PurposeOptions purposeOptions, JsonLdProcessorOptions options = null)
        {
            /* Verification process is:
             *  1. Fetch capability if only its ID was passed.
             *  1.1. Ensure `capabilityAction` is allowed.
             *  2. Get the capability delegation chain for the capability.
             *  3. Validate the capability delegation chain.
             *  4. Verify the root capability:
             *      4.1. Check the expected target, if one was specified.
             *      4.2. Ensure that the caveats are met on the root capability.
             *      4.3. Ensure root capability is expected and has no invocation target.
             *  5. If `excludeGivenCapability` is not true, then we need to verify the
             *      capability delegation proof on `capability`, so add it to the chain to
             *      get processed below.
             *  6. For each capability `cap` in the chain, verify the capability delegation
             *      proof on `cap`. This will validate everything else for `cap` including
             *      that caveats are met.
             *
             *  Note: We start verifying a capability from its root of trust (the
             *  beginning or head of the capability chain) as this approach limits an
             *  attacker's ability to waste our time and effort traversing from the tail
             *  to the head.
             */

            // 1. Fetch capability if only its ID was passed.
            capability = await FetchInSecurityContextAsync(capability, false, options);

            //capability = new CapabilityDelegation(cap as JObject);

            // TODO: Add allowed action validation

            // 2. Get the capability delegation chain for the capability.
            var capabilityChain = GetCapabilityChain(capability);

            // 3. Validate the capability delegation chain.
            ValidateCapabilityChain(capability, capabilityChain);

            // 4. Verify root capability (note: it must *always* be dereferenced since
            // it does not need to have a delegation proof to vouch for its authenticity
            // ... dereferencing it prevents adversaries from submitting an invalid
            // root capability that is accepted):
            var isRoot         = !capabilityChain.Any();
            var rootCapability = isRoot ? capability : capabilityChain.First();

            capabilityChain = capabilityChain.Skip(1).ToArray();

            rootCapability = await Utils.FetchInSecurityContextAsync(rootCapability, isRoot, null);

            // 4.1. Check the expected target, if one was specified.
            if (purposeOptions.ExpectedTarget != null)
            {
                var target = GetTarget(rootCapability);
                if (target != purposeOptions.ExpectedTarget)
                {
                    throw new Exception($"Expected target ({purposeOptions.ExpectedTarget}) does not match " +
                                        $"root capability target({target}).");
                }
            }

            // 4.2. Ensure that the caveats are met on the root capability.
            // TODO: Add caveats

            // 4.3. Ensure root capability is expected and has no invocation target.

            // run root capability checks (note that these will only be run once
            // because the `verifiedParentCapability` parameter stops recursion
            // from happening below)

            // ensure that the invocation target matches the root capability or,
            // if `expectedRootCapability` is present, that it matches that
            if (purposeOptions.ExpectedRootCapability != null)
            {
                if (purposeOptions.ExpectedRootCapability != rootCapability["id"].Value <string>())
                {
                    throw new Exception($"Expected root capability ({purposeOptions.ExpectedRootCapability}) does not " +
                                        $"match actual root capability({rootCapability["id"]}).");
                }
            }
            else if (GetTarget(rootCapability) != rootCapability["id"].Value <string>())
            {
                throw new Exception("The root capability must not specify a different " +
                                    "invocation target.");
            }

            // root capability now verified
            var verifiedParentCapability = rootCapability;

            // if verifying a delegation proof and we're at the root, exit early
            if (isRoot)
            {
                return(verifiedParentCapability);
            }

            // create a document loader that will use properly embedded capabilities
            var documentLoader = new CachingDocumentLoader(Array.Empty <IDocumentResolver>());
            var next           = capabilityChain;

            while (next.Any())
            {
                // the only capability that may be embedded (if the zcap is valid) is
                // the last one in the chain, if it is embedded, add it to `dlMap` and
                // recurse into its chain and loop to collect all embedded zcaps
                var cap = next.Last();

                if (!(cap is JObject))
                {
                    break;
                }

                if (cap["@context"] == null)
                {
                    // the capabilities in the chain are already in the security context
                    // if no context has been specified
                    cap["@context"] = Constants.SECURITY_CONTEXT_V2_URL;
                }

                // Transforms the `capability` into the security context (the native
                // context this code uses) so we can process it cleanly and then
                // verifies the capability delegation proof on `capability`. This allows
                // capabilities to be expressed using custom contexts.
                cap = await FetchInSecurityContextAsync(cap, false, options);

                documentLoader.AddCached(cap["id"].Value <string>(), cap as JObject);

                next = GetCapabilityChain(cap);
            }
            options.DocumentLoader = documentLoader.Load;

            // 5. If `excludeGivenCapability` is not true, then we need to verify the
            //  capability delegation proof on `capability`, so add it to the chain to
            //  get processed below. If an `inspectCapabilityChain` handler has been
            //  provided, the verify results are required on all capabilities.
            // TODO: Add support for `excludeGivenCapability`

            // 6. For each capability `cap` in the chain, verify the capability
            //   delegation proof on `cap`. This will validate everything else for
            //   `cap` including that caveats are met.

            // note that `verifiedParentCapability` will prevent repetitive checking
            // of the same segments of the chain (once a parent is verified, its chain
            // is not checked again when checking its children)

            for (int i = 0; i < capabilityChain.Count(); i++)
            {
                var cap = capabilityChain.ElementAt(i);
                cap = await FetchInSecurityContextAsync(cap, false, options);

                var verifyResult = LdSignatures.VerifyAsync(cap, new ProofOptions
                {
                    Suite   = purposeOptions.Suite,
                    Purpose = new CapabilityDelegationProofPurpose
                    {
                        Options = new PurposeOptions
                        {
                            ExpectedTarget         = purposeOptions.ExpectedTarget,
                            ExpectedRootCapability = purposeOptions.ExpectedRootCapability
                        },
                        VerifiedParentCapability = verifiedParentCapability
                    },
                    DocumentLoader = documentLoader,
                    CompactProof   = false
                });
            }

            return(null);
        }