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()); }
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); }
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); }
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()); }
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); }
protected override Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options) { throw new NotImplementedException(); }
protected override Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options) { proof["proofValue"] = Convert.ToBase64String((verifyData as ByteArray).Data); return(Task.FromResult(proof)); }
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)); }
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)); }
public virtual Task <JObject> UpdateAsync(JObject proof, ProofOptions options) { proof["proofPurpose"] = Term; return(Task.FromResult(proof)); }
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); }