/// <summary> /// Verify macaroon with respect to the verifier's set of valid predicates and a set of discharge macaroons. /// </summary> public VerificationResult Verify(Macaroon m, Packet key, List <Macaroon> ms = null) { Condition.Requires(m, "m").IsNotNull(); Condition.Requires(key, "key").IsNotNull(); return(m.Verify(this, key, ms)); }
protected VerificationResult VerifyInner3rd(Macaroon TM, Caveat c, Verifier v, List <Macaroon> ms, Packet csig, Stack <Macaroon> treePath) { var discharge = ms.FirstOrDefault(m => m.Identifier == c.CId); if (discharge is null) { return(new VerificationResult(String.Format($"No discharge macaroon found for caveat '{c}'"))); } if (treePath.Contains(discharge)) { return(new VerificationResult($"A circular discharge macaroon reference was found for caveat {c}")); } try { byte[] keyData = Crypto.Decrypt(csig.Data, c.VId.Data); Packet key = new Packet(keyData, DataEncoding.Hex); treePath.Push(discharge); var result = discharge.VerifyInner(TM, v, key, ms, treePath); treePath.Pop(); return(result); } catch (CryptographicException ex) { return(new VerificationResult(ex.Message)); } }
/// <summary> /// Prepare this macaroon for request by binding it to the authorizing macaroon. /// </summary> /// <param name="d">Authorizing macaroon</param> /// <returns>A new bound discharge macaroon ready for sending along with the authorizing macaroon.</returns> public Macaroon PrepareForRequest(Macaroon d) { Packet boundSignature = Bind(Signature, d.Signature); Macaroon bound = new Macaroon(d) { Signature = boundSignature }; return(bound); }
public VerificationResult Verify(Macaroon m, Packet key, List <Macaroon> ms = null) { if (m == null) { throw new ArgumentNullException(nameof(m)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } return(m.Verify(this, key, ms)); }
public Macaroon(Macaroon src) { if (src.Location != null) { Location = new Packet(src.Location); } Identifier = new Packet(src.Identifier); Signature = new Packet(src.Signature); CaveatsList = new List <Caveat>(src.CaveatsList.Count); foreach (Caveat c in src.CaveatsList) { CaveatsList.Add(new Caveat(c)); } }
/// <summary> /// Recursive verification of both 1st and 3rd party caveats in this macaroon. /// </summary> /// <param name="TM"></param> /// <param name="v"></param> /// <param name="key"></param> /// <param name="ms"></param> /// <param name="treePath"></param> /// <returns></returns> protected VerificationResult VerifyInner(Macaroon TM, Verifier v, Packet key, List <Macaroon> ms, Stack <Macaroon> treePath) { VerificationResult result = new VerificationResult(); Packet csig = CalculateHash1(key, Identifier); foreach (var c in Caveats) { if (c.IsFirstPartyCaveat) { string reason; if (!VerifyInner1st(c, v, out reason)) { if (reason == null) { result.AddFailure(string.Format($"Caveat '{c}' failed")); } else { result.AddFailure(reason); } } csig = CalculateHash1(csig, c.CId); } else { VerificationResult res = VerifyInner3rd(TM, c, v, ms, csig, treePath); result.MergeFailures(res); csig = CalculateHash2(csig, c.VId, c.CId); } } // If this a discharge macaroon? The bind signature to primary authorizing macaroon. if (treePath.Count > 0) { csig = Bind(TM.Signature, csig); } bool isValidSignature = (Signature == csig); if (!isValidSignature) { result.AddFailure($"Signature mismatch for '{Identifier}'"); } return(result); }
/// <summary> /// Initializes a macaroon with a copy of another macaroon. /// </summary> /// <param name="src"></param> public Macaroon(Macaroon src) { Condition.Requires(src, "src").IsNotNull(); if (src.Location != null) { Location = new Packet(src.Location); } Identifier = new Packet(src.Identifier); Signature = new Packet(src.Signature); CaveatsList = new List <Caveat>(src.CaveatsList.Count); foreach (Caveat c in src.CaveatsList) { CaveatsList.Add(new Caveat(c)); } }
protected VerificationResult VerifyInner3rd(Macaroon TM, Caveat c, Verifier v, List <Macaroon> ms, Packet csig, Stack <Macaroon> treePath) { // Find discharge macaroon Macaroon discharge = ms.Where(m => m.Identifier == c.CId).FirstOrDefault(); // No discharge found? Thats an error. if (discharge == null) { return(new VerificationResult(string.Format("No discharge macaroon found for caveat '{0}'", c))); } // Have we used this before? That would mean a circular reference was found if (treePath.Contains(discharge)) { return(new VerificationResult(string.Format("A circular discharge macaroon reference was found for caveat '{0}'", c))); } try { // Decrypt root key for discharge macaroon byte[] keyData = Crypto.Decrypt(csig.Data, c.VId.Data); Packet key = new Packet(keyData, DataEncoding.Hex); // Keep track of visited discharge macaroons treePath.Push(discharge); // Use the root key to verify discharge macaroon recursively VerificationResult result = discharge.VerifyInner(TM, v, key, ms, treePath); treePath.Pop(); return(result); } catch (CryptographicException ex) { return(new VerificationResult(ex.Message)); } }