public async Task <bool> DomainHasCapability(string domain, KzPaymail.Capability capability) { var id = KzPaymail.ToBrfcId(capability); var ba = await GetApiDescriptionFor(domain); if (ba == null || !ba.capabilities.ContainsKey(id)) { return(false); } var v = ba.capabilities[id].Value; return(!v.Equals(false)); }
/// <summary> /// Verifies that the message was signed by the private key corresponding the paymail's public key. /// </summary> /// <param name="message">A copy of the message which was originally signed.</param> /// <param name="signature">The signature received for validation.</param> /// <param name="paymail">The paymail claiming to have signed the message.</param> /// <param name="pubkey">If known, the public key corresponding to the private key used by the paymail to sign messages.</param> /// <returns>(ok, pubkey) where ok is true only if both the public key and signature were confirmed as valid. /// If ok is true, the returned public key is valid and can be saved for future validations. /// </returns> public async Task <(bool ok, KzPubKey pubkey)> IsValidSignature(string message, string signature, string paymail, KzPubKey pubkey = null) { var(ok, alias, domain) = KzPaymail.Parse(paymail); if (!ok) { goto fail; } if (pubkey != null) { // If a pubkey is provided and the domain is capable, verify that it is correct // If it is not correct, forget the input value and attempt to obtain the valid key. if (await DomainHasCapability(domain, KzPaymail.Capability.verifyPublicKeyOwner)) { if (!await VerifyPubKey(paymail, pubkey)) { pubkey = null; } } } if (pubkey == null) { // Attempt to determine the correct pubkey for the paymail. if (await DomainHasCapability(domain, KzPaymail.Capability.pki)) { pubkey = await GetPubKey(paymail); } } if (pubkey == null) { goto fail; } ok = pubkey.VerifyMessage(message, signature); return(ok, pubkey); fail: return(false, pubkey); }