/// <summary> /// Cryptographically signs the provided document by adding a `proof` section, /// based on the provided suite and proof purpose. /// </summary> /// <param name="document"></param> /// <param name="options"></param> /// <returns></returns> public static async Task <JToken> SignAsync(JToken document, ProofOptions options) { if (options.Purpose is null) { throw new Exception("Proof purpose is required."); } if (options.Suite is null) { throw new Exception("Suite is required."); } options.AdditonalData["originalDocument"] = document; var documentCopy = document.DeepClone(); documentCopy = options.CompactProof ? JsonLdProcessor.Compact(documentCopy, Constants.SECURITY_CONTEXT_V2_URL, options.GetProcessorOptions()) : document.DeepClone(); documentCopy.Remove("proof"); // create the new proof (suites MUST output a proof using the security-v2 // `@context`) options.Input = documentCopy; var proof = await options.Suite.CreateProofAsync(options); // TODO: Check compaction again proof.Proof.Remove("@context"); var result = proof.UpdatedDocument ?? document.DeepClone(); result["proof"] = proof.Proof; return(result); }
public bool VerifyProof(VerifyProofOptions proofOptions) { var suite = suiteFactory.GetSuite(proofOptions.LdSuiteType) ?? throw new Exception($"Suite not found for type '{proofOptions.LdSuiteType}'"); var processorOptions = new JsonLdProcessorOptions { CompactToRelative = false, DocumentLoader = documentLoader.GetDocumentLoader() }; if (proofOptions.CompactProof) { proofOptions.Document = JsonLdProcessor.Compact( input: proofOptions.Document, context: Constants.SECURITY_CONTEXT_V2_URL, options: processorOptions); } var proof = (JObject)proofOptions.Document["proof"].DeepClone(); proof["@context"] = Constants.SECURITY_CONTEXT_V2_URL; proofOptions.Document.Remove("proof"); proofOptions.Proof = proof; return(suite.VerifyProof(proofOptions, processorOptions)); }
public static void Run() { var doc = JObject.Parse(_docJson); var remoteContext = JObject.Parse("{'@context':'http://example.org/context.jsonld'}"); var opts = new JsonLdOptions { documentLoader = new CustomDocumentLoader() }; var compacted = JsonLdProcessor.Compact(doc, remoteContext, opts); Console.WriteLine(compacted); /* * * Output: * { * "@id": "http://example.org/ld-experts", * "member": { * "@type": "Person", * "image": "http://manu.sporny.org/images/manu.png", * "name": "Manu Sporny", * "homepage": "http://manu.sporny.org/" * }, * "name": "LD Experts" * } * */ }
public static JObject Run() { var doc = JObject.Parse(_docJson); var context = JObject.Parse(_contextJson); var opts = new JsonLdOptions(); var compacted = JsonLdProcessor.Compact(doc, context, opts); Console.WriteLine(compacted); /* * * Output: * { * "@id": "ld-experts", * "member": { * "image": "http://manu.sporny.org/images/manu.png", * "name": "Manu Sporny", * "homepage": "http://manu.sporny.org/", * }, * "name": "LD Experts", * "@context": . . . * } * */ return(compacted); }
/// <inheritdoc /> public void Save(IGraph graph, TextWriter output) { JToken data = (_context != null ? JsonLdProcessor.Compact(MakeExpandedForm(graph), _context, new JsonLdOptions()) : MakeExpandedForm(graph)); output.Write(data.ToString()); output.Flush(); }
public JToken CreateProof(CreateProofOptions options) { if (options.VerificationMethod is null) { throw new Exception("Verification method is required."); } if (options.ProofPurpose is null) { throw new Exception("Proof purpose is required."); } if (options.LdSuiteType is null) { throw new Exception("Suite type is required."); } var suite = suiteFactory.GetSuite(options.LdSuiteType) ?? throw new Exception($"Suite not found for type '{options.LdSuiteType}'"); var processorOptions = new JsonLdProcessorOptions { CompactToRelative = false, DocumentLoader = documentLoader.GetDocumentLoader() }; if (options.CompactProof) { options.Document = JsonLdProcessor.Compact( input: options.Document, context: Constants.SECURITY_CONTEXT_V2_URL, options: processorOptions); } return(suite.CreateProof(options, processorOptions)); }
public JToken CreateProof(CreateProofOptions options, JsonLdProcessorOptions processorOptions) { if (!(options.VerificationMethod is Bls12381VerificationKey2020 verificationMethod)) { throw new Exception( $"Invalid verification method. " + $"Expected '{nameof(Bls12381VerificationKey2020)}'. " + $"Found '{options.VerificationMethod?.GetType().Name}'."); } // Prepare proof var compactedProof = JsonLdProcessor.Compact( input: new BbsBlsSignature2020 { Context = Constants.SECURITY_CONTEXT_V2_URL, TypeName = "https://w3c-ccg.github.io/ldp-bbs2020/context/v1#BbsBlsSignature2020" }, context: Constants.SECURITY_CONTEXT_V2_URL, options: processorOptions); var proof = new BbsBlsSignature2020(compactedProof) { Context = Constants.SECURITY_CONTEXT_V2_URL, VerificationMethod = options.VerificationMethod switch { VerificationMethodReference reference => (string)reference, VerificationMethod method => method.Id, _ => throw new Exception("Unknown VerificationMethod type") },
public JToken CreateProof(CreateProofOptions options, JsonLdProcessorOptions processorOptions) { var(document, proofs) = options.Document.GetProofs(processorOptions); var proof = new BbsBlsSignature2020(proofs.FirstOrDefault() ?? throw new Exception("Proof not found")); proof.Context = Constants.SECURITY_CONTEXT_V2_URL; var signature = Convert.FromBase64String(proof.ProofValue); var derivedProof = JsonLdProcessor.Compact(new BbsBlsSignatureProof2020(), Constants.SECURITY_CONTEXT_V2_URL, processorOptions); var documentStatements = BbsBlsSignature2020Suite.CreateVerifyDocumentData(document, processorOptions); var proofStatements = BbsBlsSignature2020Suite.CreateVerifyProofData(proof, processorOptions); var transformedInputDocumentStatements = documentStatements.Select(TransformBlankNodeToId).ToArray(); var compactInputDocument = Helpers.FromRdf(transformedInputDocumentStatements); var revealDocument = JsonLdProcessor.Frame(compactInputDocument, options.ProofRequest, processorOptions); var revealDocumentStatements = BbsBlsSignature2020Suite.CreateVerifyDocumentData(revealDocument, processorOptions); var numberOfProofStatements = proofStatements.Count(); var proofRevealIndicies = EnumerableFromInt(numberOfProofStatements).ToArray(); 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 revealIndicies = proofRevealIndicies.Concat(documentRevealIndicies); derivedProof["nonce"] = options.Nonce ?? Guid.NewGuid().ToString(); //Combine all the input statements that //were originally signed to generate the proof var allInputStatements = proofStatements.Concat(documentStatements); var verificationMethod = BbsBlsSignature2020Suite.GetVerificationMethod(proofs.First(), processorOptions); var outputProof = BbsProvider.CreateProof(new CreateProofRequest( publicKey: verificationMethod.ToBlsKeyPair().GeyBbsKeyPair((uint)allInputStatements.Count()), messages: GetProofMessages(allInputStatements.ToArray(), revealIndicies).ToArray(), signature: signature, blindingFactor: null, nonce: derivedProof["nonce"].ToString())); // Set the proof value on the derived proof derivedProof["proofValue"] = Convert.ToBase64String(outputProof); // Set the relevant proof elements on the derived proof from the input proof derivedProof["verificationMethod"] = proof["verificationMethod"]; derivedProof["proofPurpose"] = proof["proofPurpose"]; derivedProof["created"] = proof["created"]; revealDocument["proof"] = derivedProof; return(revealDocument); }
/// <summary> /// Deserializes the JSON-LD object into a typed model. /// </summary> /// <typeparam name="T">destination entity model</typeparam> /// <param name="jsonLd">a JSON-LD object</param> public T Deserialize <T>(JObject jsonLd) { var jsonLdContext = _contextProvider.GetContext(typeof(T)); if (jsonLdContext == null) { return(jsonLd.ToObject <T>(_jsonSerializer)); } return(JsonLdProcessor.Compact(jsonLd, jsonLdContext, new JsonLdOptions()).ToObject <T>(_jsonSerializer)); }
/// <summary> /// Deserializes the NQuads into a typed model /// </summary> /// <typeparam name="T">destination entity model type</typeparam> /// <param name="nQuads">RDF data in NQuads.</param> public T Deserialize <T>(string nQuads) { var jsonLdObject = JsonLdProcessor.FromRDF(nQuads); var jsonLdContext = _contextProvider.GetContext(typeof(T)); if (jsonLdContext == null) { throw new ContextNotFoundException(typeof(T)); } return(JsonLdProcessor.Compact(jsonLdObject, jsonLdContext, new JsonLdOptions()).ToObject <T>(_jsonSerializer)); }
/// <summary> /// Fetches a JSON-LD document from a URL and, if necessary, compacts it to /// the security v2 context. /// </summary> /// <param name="document"></param> /// <param name="isRoot"></param> /// <param name="options"></param> /// <returns></returns> public static async Task <JObject> FetchInSecurityContextAsync(JToken document, bool isRoot = false, JsonLdProcessorOptions options = null) { await Task.Yield(); if (document.Type == JTokenType.Object && document["@context"]?.Value <string>() == Constants.SECURITY_CONTEXT_V2_URL && !isRoot) { return(document as JObject); } return(JsonLdProcessor.Compact(document, Constants.SECURITY_CONTEXT_V2_URL, options)); }
public void Should_serialize_URI_values_as_strings() { // given var serialized = this.serializer.Serialize(new UriPropertyMappedToAbsoluteUri { Property = new Uri(UriValue) }); // when // to remove @context, an empty JObject can be passed var noContext = JsonLdProcessor.Compact(serialized, new JObject(), new JsonLdOptions()); // then Assert.That(noContext[PropertyUri].ToString(), Is.EqualTo(UriValue)); }
public void Should_serialize_URI_values_as_expanded_object() { // given var serialized = this.serializer.Serialize(new UriPropertyForcedToExpand { Property = new IriRef(UriValue) }); // when // to remove @context, an empty JObject can be passed var noContext = JsonLdProcessor.Compact(serialized, new JObject(), new JsonLdOptions()); // then Assert.That(noContext[PropertyUri]["@id"].ToString(), Is.EqualTo(UriValue)); }
public void Should_serialize_URI_values_as_strings_with_context() { // given var serialized = this.serializer.Serialize(new UriPropertyWithContext { Property = new Uri(UriValue) }); // when // to remove @context, an empty JObject can be passed var noContext = JsonLdProcessor.Compact(serialized, new JObject(), new JsonLdOptions()); // then Assert.Equal(UriValue, noContext[PropertyUri]["@id"].ToString()); }
public void Save(IGraph g, TextWriter output) { JToken flattened = MakeExpandedForm(g); if (Frame == null) { output.Write(flattened); } else { JObject framed = JsonLdProcessor.Frame(flattened, Frame, new JsonLdOptions()); JObject compacted = JsonLdProcessor.Compact(framed, framed["@context"], new JsonLdOptions()); output.Write(compacted); } }
public static (JToken, IEnumerable <JObject>) GetProofs(this JToken document, JsonLdProcessorOptions options, bool compactProof = true, string proofPropertyName = "proof") { if (compactProof) { document = JsonLdProcessor.Compact(document, Constants.SECURITY_CONTEXT_V2_URL, options); } var proofs = document[proofPropertyName]; (document as JObject).Remove(proofPropertyName); return(document, proofs switch { JObject _ => new[] { proofs as JObject }, JArray _ => proofs.Select(x => x as JObject), _ => throw new Exception("Unexpected proof type") });
private T Deserialize <T>(JToken jsonLd, JToken context, JObject frame) { if (context == null) { return(jsonLd.ToObject <T>(this.jsonSerializer)); } if (frame == null) { return(JsonLdProcessor.Compact(jsonLd, context, new JsonLdOptions()).ToObject <T>(this.jsonSerializer)); } frame["@context"] = context; var framed = JsonLdProcessor.Frame(jsonLd, frame, new JsonLdOptions()); return(framed["@graph"].Single().ToObject <T>(this.jsonSerializer)); }
/// <summary> /// Serializes the specified entity as JSON-LD. /// </summary> /// <returns> /// A compacted JSON-LD object /// </returns> public JObject Serialize(object entity, [AllowNull] SerializationOptions options = null) { options = options ?? new SerializationOptions(); var jsonLd = JObject.FromObject(entity, this.jsonSerializer); var context = this.contextResolver.GetContext(entity); if (context != null && IsNotEmpty(context)) { jsonLd.AddFirst(new JProperty("@context", context)); if (options.SerializeCompacted || entity.GetType().IsMarkedForCompaction()) { jsonLd = JsonLdProcessor.Compact(jsonLd, context, new JsonLdOptions()); } } return(jsonLd); }
public JObject GetMoviesJObject(List <MovieResponse> movies) { var docJson = @" { '@id': 'http://example.org/movies', 'http://schema.org/name': 'Movies', '@type': 'http://schema.org/ItemList', 'http://schema.org/itemListElement': ["; docJson = AddMovieArray(movies, docJson); docJson += "]}"; var doc = JObject.Parse(docJson.UnEscapeString()); var context = JObject.Parse(_moviesContextJson); var opts = new JsonLdOptions(); var compacted = JsonLdProcessor.Compact(doc, context, opts); return(compacted); }
public static JObject JsonFromGraph(IGraph graph, string rootType, JToken context) { System.IO.StringWriter stringWriter = new System.IO.StringWriter(); IRdfWriter rdfWriter = new JsonLdWriter(); rdfWriter.Save(graph, stringWriter); stringWriter.Flush(); JObject frame = new JObject(); frame.Add("@context", context); frame.Add("@type", rootType); //frame.Add("@embed", false); JToken flattened = JToken.Parse(stringWriter.ToString()); JObject framed = JsonLdProcessor.Frame(flattened, frame, new JsonLdOptions()); JObject compacted = JsonLdProcessor.Compact(framed, context, new JsonLdOptions()); return(compacted); }
public static string CreateJson(IGraph graph, JToken frame = null) { System.IO.StringWriter writer = new System.IO.StringWriter(); IRdfWriter rdfWriter = new JsonLdWriter(); rdfWriter.Save(graph, writer); writer.Flush(); if (frame == null) { return(writer.ToString()); } else { JToken flattened = JToken.Parse(writer.ToString()); JObject framed = JsonLdProcessor.Frame(flattened, frame, new JsonLdOptions()); JObject compacted = JsonLdProcessor.Compact(framed, frame["@context"], new JsonLdOptions()); return(compacted.ToString()); } }
/// <summary> /// Get a proof from a signed document /// </summary> /// <param name="document"></param> /// <param name="options"></param> /// <returns></returns> public static (JToken proof, JToken document) GetProof(JToken document, ProofOptions options) { var documentCopy = options.CompactProof ? JsonLdProcessor.Compact( input: document, context: Constants.SECURITY_CONTEXT_V2_URL, options: options.GetProcessorOptions()) : document.DeepClone(); var proof = documentCopy["proof"].DeepClone(); document.Remove("proof"); if (proof == null) { throw new Exception("No matching proofs found in the given document."); } proof["@context"] = Constants.SECURITY_CONTEXT_V2_URL; return(proof, document); }
public JObject GetMovieDetailObject(MovieDetailResponse movie) { var rating = GetRating(movie); var docJson = @" { '@id': 'http://example.org/movies', 'http://schema.org/name': '" + movie.Title.EscapeString() + @"', '@type': 'http://schema.org/Movie', 'http://schema.org/image': {'@id': '" + movie.Poster + @"'}, 'http://schema.org/dateCreated' : '" + movie.Year.ValidateYear() + @"', 'http://schema.org/director': '" + movie.Director.EscapeString() + @"', 'http://schema.org/review': { '@type': 'http://schema.org/Review', 'http://schema.org/reviewRating': { '@type': 'http://schema.org/Rating', 'http://schema.org/ratingValue': '" + rating.Value + @"' }, 'http://schema.org/author': { '@type': 'http://schema.org/Person', 'http://schema.org/name': '" + rating.Source + @"' }, 'http://schema.org/reviewBody': '" + rating.Source + @"' }, 'http://schema.org/actor': ["; docJson = AddActorsArray(movie, docJson); docJson += "]}"; var doc = JObject.Parse(docJson.UnEscapeString()); var context = JObject.Parse(_movieContextJson); var opts = new JsonLdOptions(); var compacted = JsonLdProcessor.Compact(doc, context, opts); return(compacted); }
/// <summary> /// Create proof /// </summary> /// <param name="options"></param> /// <returns></returns> public override async Task <ProofResult> CreateProofAsync(ProofOptions options) { if (VerificationMethod == null) { throw new ArgumentNullException(nameof(VerificationMethod), "VerificationMethod must be specified."); } if (TypeName == null) { throw new ArgumentNullException(nameof(TypeName), "TypeName must be specified."); } var proof = InitialProof != null ? JsonLdProcessor.Compact(InitialProof, Constants.SECURITY_CONTEXT_V2_URL, options.GetProcessorOptions()) : new JObject { { "@context", Constants.SECURITY_CONTEXT_V2_URL } }; proof["type"] = TypeName; proof["created"] = Date.HasValue ? Date.Value.ToString("s") : DateTime.Now.ToString("s"); proof["verificationMethod"] = VerificationMethod; // allow purpose to update the proof; the `proof` is in the // SECURITY_CONTEXT_URL `@context` -- therefore the `purpose` must // ensure any added fields are also represented in that same `@context` proof = await options.Purpose.UpdateAsync(proof, options); // create data to sign var verifyData = CreateVerifyData(proof, options); // sign data proof = await SignAsync(verifyData, proof, options); return(new ProofResult { Proof = proof }); }
public IEnumerator <object[]> GetEnumerator() { foreach (string manifest in manifests) { JToken manifestJson; manifestJson = GetJson(manifest); foreach (JObject testcase in manifestJson["sequence"]) { Func <JToken> run; ConformanceCase newCase = new ConformanceCase(); newCase.input = GetJson(testcase["input"]); newCase.context = GetJson(testcase["context"]); newCase.frame = GetJson(testcase["frame"]); var options = new JsonLdOptions("http://json-ld.org/test-suite/tests/" + (string)testcase["input"]); var testType = (JArray)testcase["@type"]; if (testType.Any((s) => (string)s == "jld:NegativeEvaluationTest")) { newCase.error = testcase["expect"]; } else if (testType.Any((s) => (string)s == "jld:PositiveEvaluationTest")) { if (testType.Any((s) => new List <string> { "jld:ToRDFTest", "jld:NormalizeTest" }.Contains((string)s))) { newCase.output = File.ReadAllText(Path.Combine("W3C", (string)testcase["expect"])); } else if (testType.Any((s) => (string)s == "jld:FromRDFTest")) { newCase.input = File.ReadAllText(Path.Combine("W3C", (string)testcase["input"])); newCase.output = GetJson(testcase["expect"]); } else { newCase.output = GetJson(testcase["expect"]); } } else { throw new Exception("Expecting either positive or negative evaluation test."); } JToken optionToken; JToken value; if (testcase.TryGetValue("option", out optionToken)) { JObject optionDescription = (JObject)optionToken; if (optionDescription.TryGetValue("compactArrays", out value)) { options.SetCompactArrays((bool)value); } if (optionDescription.TryGetValue("base", out value)) { options.SetBase((string)value); } if (optionDescription.TryGetValue("expandContext", out value)) { newCase.context = GetJson(testcase["option"]["expandContext"]); options.SetExpandContext((JObject)newCase.context); } if (optionDescription.TryGetValue("produceGeneralizedRdf", out value)) { options.SetProduceGeneralizedRdf((bool)value); } if (optionDescription.TryGetValue("useNativeTypes", out value)) { options.SetUseNativeTypes((bool)value); } if (optionDescription.TryGetValue("useRdfType", out value)) { options.SetUseRdfType((bool)value); } } if (testType.Any((s) => (string)s == "jld:CompactTest")) { run = () => JsonLdProcessor.Compact(newCase.input, newCase.context, options); } else if (testType.Any((s) => (string)s == "jld:ExpandTest")) { run = () => JsonLdProcessor.Expand(newCase.input, options); } else if (testType.Any((s) => (string)s == "jld:FlattenTest")) { run = () => JsonLdProcessor.Flatten(newCase.input, newCase.context, options); } else if (testType.Any((s) => (string)s == "jld:FrameTest")) { run = () => JsonLdProcessor.Frame(newCase.input, newCase.frame, options); } else if (testType.Any((s) => (string)s == "jld:NormalizeTest")) { run = () => new JValue( RDFDatasetUtils.ToNQuads((RDFDataset)JsonLdProcessor.Normalize(newCase.input, options)).Replace("\n", "\r\n") ); } else if (testType.Any((s) => (string)s == "jld:ToRDFTest")) { options.format = "application/nquads"; run = () => new JValue( ((string)JsonLdProcessor.ToRDF(newCase.input, options)).Replace("\n", "\r\n") ); } else if (testType.Any((s) => (string)s == "jld:FromRDFTest")) { options.format = "application/nquads"; run = () => JsonLdProcessor.FromRDF(newCase.input, options); } else { run = () => { throw new Exception("Couldn't find a test type, apparently."); }; } if ((string)manifestJson["name"] == "Remote document") { Func <JToken> innerRun = run; run = () => { var remoteDoc = options.documentLoader.LoadDocument("https://json-ld.org/test-suite/tests/" + (string)testcase["input"]); newCase.input = remoteDoc.Document; options.SetBase(remoteDoc.DocumentUrl); options.SetExpandContext((JObject)remoteDoc.Context); return(innerRun()); }; } if (testType.Any((s) => (string)s == "jld:NegativeEvaluationTest")) { Func <JToken> innerRun = run; run = () => { try { return(innerRun()); } catch (JsonLdError err) { JObject result = new JObject(); result["error"] = err.Message; return(result); } }; } newCase.run = run; yield return(new object[] { manifest + (string)testcase["@id"], (string)testcase["name"], newCase }); } } }
public static JObject Compact(JToken swidTag) { // first, compact it to the canonical context return(JsonLdProcessor.Compact(swidTag, IdentityIndex.Context, _options)); }
protected JObject Serialize(object obj) { var jObject = _serializer.Serialize(obj); return(JsonLdProcessor.Compact(jObject, new JObject(), new JsonLdOptions())); }