public void VerificationFailsWithInvalidSignature() { // Arrange Macaroon mValid = new Macaroon(Location, Secret, Identifier); mValid.AddFirstPartyCaveat("account = 3735928559"); mValid.AddFirstPartyCaveat("time < 2115-01-01T00:00"); mValid.AddFirstPartyCaveat("email = [email protected]"); // This is a Macaroon from the tutorial (https://github.com/rescrv/libmacaroons) containing an invalid signature string serialized = "MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaWVyIHdlIHVzZWQgb3VyIHNlY3JldCBrZXkKMDAxZGNpZCBhY2NvdW50ID0gMzczNTkyODU1OQowMDIwY2lkIHRpbWUgPCAyMDE1LTAxLTAxVDAwOjAwCjAwMjJjaWQgZW1haWwgPSBhbGljZUBleGFtcGxlLm9yZwowMDJmc2lnbmF0dXJlID8f19FL+bkC9p/aoMmIecC7GxdOcLVyUnrv6lJMM7NSCg=="; Macaroon mInvalid = Macaroon.Deserialize(serialized); Verifier v = new Verifier(); v.SatisfyExact("account = 3735928559"); v.SatisfyExact("time < 2115-01-01T00:00"); v.SatisfyExact("email = [email protected]"); // Act VerificationResult verifiedOk = mValid.Verify(v, Secret); VerificationResult verifiedFails = mInvalid.Verify(v, Secret); // Assert Assert.AreEqual(mValid.Location, mInvalid.Location); Assert.AreEqual(mValid.Identifier, mInvalid.Identifier); Assert.AreEqual(mValid.Caveats.Count, mInvalid.Caveats.Count); Assert.AreNotEqual(mValid.Signature, mInvalid.Signature); Assert.IsTrue(verifiedOk.Success); Assert.IsFalse(verifiedFails.Success); Assert.AreEqual(2, verifiedFails.Messages.Count); StringAssert.Contains("Caveat 'time < 2015-01-01T00:00' failed", verifiedFails.Messages[0]); StringAssert.Contains("Signature mismatch", verifiedFails.Messages[1]); }
public void CanVerifyWithDischargeMacaroon() { // Arrange Macaroon m = new Macaroon(Location2, Secret2, Identifier2); m.AddFirstPartyCaveat("account = 3735928559"); string caveat_key = "4; guaranteed random by a fair toss of the dice"; string identifier = "this was how we remind auth of key/pred"; m.AddThirdPartyCaveat("http://auth.mybank/", caveat_key, identifier); Macaroon d = new Macaroon("http://auth.mybank/", caveat_key, identifier); d.AddFirstPartyCaveat("time < 2115-01-01T00:00"); Macaroon dp = m.PrepareForRequest(d); Verifier v = new Verifier(); v.SatisfyExact("account = 3735928559"); v.SatisfyGeneral(TimeVerifier); // Act VerificationResult result = m.Verify(v, Secret2, new List <Macaroon> { dp }); // Assert Assert.True(result.Success); }
static void TestSerialization() { Macaroon m = new Macaroon(LocationBytes, SecretBytes, IdentifierBytes); m.AddFirstPartyCaveat("account = 3735928559"); string caveat_key = "4; guaranteed random by a fair toss of the dice"; string identifier = "this was how we remind auth of key/pred"; m.AddThirdPartyCaveat("http://auth.mybank/", caveat_key, identifier); Stopwatch w1 = new Stopwatch(); w1.Start(); for (int i = 0; i < 10000; ++i) { string s = m.Serialize(); Macaroon n = Macaroon.Deserialize(s); } w1.Stop(); Console.WriteLine("Total: " + w1.Elapsed); }
public void CanVerifyFirstPartyGeneralCaveat() { // Arrange Macaroon mSuccess = new Macaroon(Location, Secret, Identifier); mSuccess.AddFirstPartyCaveat("time < 2115-01-01T00:00"); Macaroon mFailure = new Macaroon(Location, Secret, Identifier); mFailure.AddFirstPartyCaveat("time < 2000-01-01T00:00"); Verifier v = new Verifier(); v.SatisfyGeneral(TimeVerifier); // Act VerificationResult verified1 = mSuccess.Verify(v, Secret); VerificationResult verified2 = mFailure.Verify(v, Secret); // Assert Assert.IsTrue(verified1.Success); Assert.IsFalse(verified2.Success); Assert.AreEqual(1, verified2.Messages.Count); StringAssert.Contains("Caveat", verified2.Messages[0]); StringAssert.Contains("time < 2000-01-01T00:00", verified2.Messages[0]); StringAssert.Contains("failed", verified2.Messages[0]); }
public void CanPrintMacaroon() { var m = new Macaroon(Location, Secret, Identifier); var s = m.ToString(); Assert.Equal(Location, s); }
public void CanSerializeAndDeserializeThirdPartyCaveats() { // Arrange Macaroon m1 = new Macaroon(Location, Secret, Identifier); m1.AddFirstPartyCaveat("account = 3735928559"); string caveat_key = "4; guaranteed random by a fair toss of the dice"; string identifier = "this was how we remind auth of key/pred"; m1.AddThirdPartyCaveat("http://auth.mybank/", caveat_key, identifier); // Act string s = m1.Serialize(); Macaroon m2 = Macaroon.Deserialize(s); // Assert Assert.AreEqual(m1.Location, m2.Location); Assert.AreEqual(m1.Identifier, m2.Identifier); Assert.AreEqual(m1.Signature, m2.Signature); Assert.AreEqual(m1.Caveats.Count, m2.Caveats.Count); Assert.AreEqual(m1.Caveats[0].Cl, m2.Caveats[0].Cl); Assert.AreEqual(m1.Caveats[0].CId, m2.Caveats[0].CId); Assert.AreEqual(m1.Caveats[0].VId, m2.Caveats[0].VId); Assert.AreEqual(m1.Caveats[1].Cl, m2.Caveats[1].Cl); Assert.AreEqual(m1.Caveats[1].CId, m2.Caveats[1].CId); Assert.AreEqual(m1.Caveats[1].VId, m2.Caveats[1].VId); }
public void CanAddMultipleFirstPartyCaveats() { // Arrange Macaroon m = new Macaroon(Location, Secret, Identifier); // Act m.AddFirstPartyCaveat("account = 3735928559"); m.AddFirstPartyCaveat("time < 2015-01-01T00:00"); m.AddFirstPartyCaveat("email = [email protected]"); // Assert Assert.AreEqual(3, m.Caveats.Count); Assert.AreEqual("CId = account = 3735928559", m.Caveats[0].Inspect()); Assert.AreEqual("CId = time < 2015-01-01T00:00", m.Caveats[1].Inspect()); Assert.AreEqual("CId = email = [email protected]", m.Caveats[2].Inspect()); Assert.AreEqual("882E6D59496ED5245EDB7AB5B8839ECD63E5D504E54839804F164070D8EED952", m.Signature.ToString()); string expectedStringRepresentation = @"Location = http://mybank/ Identifier = we used our secret key CId = account = 3735928559 CId = time < 2015-01-01T00:00 CId = email = [email protected] Signature = 882E6D59496ED5245EDB7AB5B8839ECD63E5D504E54839804F164070D8EED952 "; Assert.AreEqual(expectedStringRepresentation, m.Inspect()); }
public void CanSerializeEmptyMacaroon() { var m = new Macaroon(Location, Secret, Identifier); var s = m.Serialize(); Assert.Equal( "MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaWVyIHdlIHVzZWQgb3VyIHNlY3JldCBrZXkKMDAyZnNpZ25hdHVyZSDj2eApCFJsTAA5rhURQRXZf91ovyujebNCqvD2F9BVLwo", s); }
public void CanVerifyEmptyMacaroon() { var m = new Macaroon(Location, Secret, Identifier); var v = new Verifier(); var r = m.Verify(v, Secret); Assert.True(r.Success); }
public void WhenDeserializingBadPacketItThrowsInvalidDataException() { // Arrange // - This data would make the deserializer run around in circles in earlier versions. string s = "MDAyNWxvY2F0aW9uIGNTZWFyY2g6ZG9jdW1lbnQ6MTQ5MzY0CjAwMjJpZGVudGlmaWVyIGRvY3VtZW50SWQ6IDE0OTM2NAowMDFiY2lkIGRvY3VtZW50SWQ6IDE0OTM2NAowMDIzY2lkIHRpbWUgPCAyMDE2LTAxLTA0VDEyOjQzOjU2CjAwMmZzaWduyXR1cmUgQbpcMXKEUSc4AE1xANE2V4b1BbKAGSbrEO2oAOqZYhkK"; Assert.Throws <InvalidDataException>(() => Macaroon.Deserialize(s)); }
public void CanCreateEmptyMacaroonWithSignature() { // Act Macaroon m = new Macaroon(Location, Secret, Identifier); // Assert Assert.AreEqual(Identifier, m.Identifier.ToString()); Assert.AreEqual(Location, m.Location.ToString()); Assert.AreEqual("E3D9E02908526C4C0039AE15114115D97FDD68BF2BA379B342AAF0F617D0552F", m.Signature.ToString()); Assert.AreEqual(0, m.Caveats.Count); }
public void CanPrintMacaroon() { // Arrange Macaroon m = new Macaroon(Location, Secret, Identifier); // Act string s = m.ToString(); // Assert Assert.AreEqual(Location, s); }
static void TestCreateAndDecrypt() { //Macaroon.Crypto = new NoEncryption(); Stopwatch w1 = new Stopwatch(); Stopwatch w2 = new Stopwatch(); Stopwatch w3 = new Stopwatch(); Stopwatch w4 = new Stopwatch(); w1.Start(); for (int i = 0; i < 2000; ++i) { w2.Start(); //Macaroon m = new Macaroon(Location2, Secret2, Identifier2); Macaroon m = new Macaroon(LocationBytes, SecretBytes, IdentifierBytes); m.AddFirstPartyCaveat("account = 3735928559"); string caveat_key = "4; guaranteed random by a fair toss of the dice"; string identifier = "this was how we remind auth of key/pred"; m.AddThirdPartyCaveat("http://auth.mybank/", caveat_key, identifier); //m.AddFirstPartyCaveat("account = 3735928559"); w2.Stop(); Macaroon d = new Macaroon("http://auth.mybank/", caveat_key, identifier); //d.AddFirstPartyCaveat("time < 2015-01-01T00:00"); w3.Start(); Macaroon dp = m.PrepareForRequest(d); w3.Stop(); w4.Start(); Verifier v = new Verifier(); v.SatisfyExact("account = 3735928559"); //v.SatisfyGeneral(TimeVerifier); VerificationResult result = m.Verify(v, Secret2, new List <Macaroon> { dp }); w4.Stop(); if (!result.Success) { throw new InvalidOperationException(); } } //Console.WriteLine(result.Success); w1.Stop(); Console.WriteLine("Total: " + w1.Elapsed); Console.WriteLine("Create: " + w2.Elapsed); Console.WriteLine("Prepare: " + w3.Elapsed); Console.WriteLine("Verify: " + w4.Elapsed); }
public void CanVerifyEmptyMacaroon() { // Arrange - create macaroon without any caveats Macaroon m = new Macaroon(Location, Secret, Identifier); Verifier v = new Verifier(); // Act VerificationResult verified = m.Verify(v, Secret); // Assert Assert.IsTrue(verified.Success); }
public void CanAddOneFirstPartyCaveat() { // Arrange Macaroon m = new Macaroon(Location, Secret, Identifier); // Act m.AddFirstPartyCaveat("account = 3735928559"); // Assert Assert.AreEqual(1, m.Caveats.Count); Assert.AreEqual("CId = account = 3735928559", m.Caveats[0].Inspect()); Assert.AreEqual("1EFE4763F290DBCE0C1D08477367E11F4EEE456A64933CF662D79772DBB82128", m.Signature.ToString()); }
public void CanDeserializeEmptyMacaroon() { // Arrange (this is a Macaroon from the tutorial (https://github.com/rescrv/libmacaroons) containing an invalid signature - but that should not be checked here) string serialized = "MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaWVyIHdlIHVzZWQgb3VyIHNlY3JldCBrZXkKMDAyZnNpZ25hdHVyZSDj2eApCFJsTAA5rhURQRXZf91ovyujebNCqvD2F9BVLwo"; // Act Macaroon m = Macaroon.Deserialize(serialized); // Assert Assert.AreEqual(Location, m.Location.ToString()); Assert.AreEqual(Identifier, m.Identifier.ToString()); Assert.AreEqual(0, m.Caveats.Count); Assert.IsTrue(m.Verify(new Verifier(), Secret).Success); }
public void VerificationFailsWhenDischargeMacaroonIsMissing() { // Arrange // - Create primary macaroon Macaroon m = new Macaroon(Location, Secret, Identifier); m.AddFirstPartyCaveat("account = 3735928559"); // - Add third party caveat (1) string caveat_key1 = "4; guaranteed random by a fair toss of the dice"; string identifier1 = "this was how we remind auth of key/pred"; m.AddThirdPartyCaveat("http://auth.mybank/", caveat_key1, identifier1); // - Add third party caveat (2) string caveat_key2 = "random key 2"; string identifier2 = "identifier 2"; m.AddThirdPartyCaveat("http://auth.government/", caveat_key2, identifier2); // - Create discharge macaroon (1) Macaroon d1 = new Macaroon("http://auth.mybank/", caveat_key1, identifier1); d1.AddFirstPartyCaveat("time < 2115-01-01T00:00"); Macaroon dp1 = m.PrepareForRequest(d1); // - Create discharge macaroon (2) Macaroon d2 = new Macaroon("http://auth.mybank/", caveat_key2, identifier2); Macaroon dp2 = m.PrepareForRequest(d2); // Create verifier with suitable predicates Verifier v = new Verifier(); v.SatisfyExact("account = 3735928559"); v.SatisfyGeneral(TimeVerifier); // Act VerificationResult result1 = m.Verify(v, Secret, new List <Macaroon> { dp1 }); VerificationResult result2 = m.Verify(v, Secret, new List <Macaroon> { dp2 }); // Assert Assert.IsFalse(result1.Success); Assert.IsFalse(result2.Success); }
public void CanSerializeMultipleFirstPartyCaveats() { // Arrange Macaroon m = new Macaroon(Location, Secret, Identifier); m.AddFirstPartyCaveat("account = 3735928559"); m.AddFirstPartyCaveat("time < 2015-01-01T00:00"); m.AddFirstPartyCaveat("email = [email protected]"); // Act string s = m.Serialize(); // Assert (the expected value here is just calculated - I havent seen any correct value on the web) Assert.AreEqual("MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaWVyIHdlIHVzZWQgb3VyIHNlY3JldCBrZXkKMDAxZGNpZCBhY2NvdW50ID0gMzczNTkyODU1OQowMDIwY2lkIHRpbWUgPCAyMDE1LTAxLTAxVDAwOjAwCjAwMjJjaWQgZW1haWwgPSBhbGljZUBleGFtcGxlLm9yZwowMDJmc2lnbmF0dXJlIIgubVlJbtUkXtt6tbiDns1j5dUE5Ug5gE8WQHDY7tlSCg", s); }
public void CanDeserializeMultipleFirstPartyCaveats() { // Arrange string serialized = "MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaWVyIHdlIHVzZWQgb3VyIHNlY3JldCBrZXkKMDAxZGNpZCBhY2NvdW50ID0gMzczNTkyODU1OQowMDIwY2lkIHRpbWUgPCAyMDE1LTAxLTAxVDAwOjAwCjAwMjJjaWQgZW1haWwgPSBhbGljZUBleGFtcGxlLm9yZwowMDJmc2lnbmF0dXJlID8f19FL+bkC9p/aoMmIecC7GxdOcLVyUnrv6lJMM7NSCg=="; // Act Macaroon m = Macaroon.Deserialize(serialized); // Assert Assert.AreEqual(Location, m.Location.ToString()); Assert.AreEqual(Identifier, m.Identifier.ToString()); Assert.AreEqual(3, m.Caveats.Count); Assert.AreEqual("account = 3735928559", m.Caveats[0].CId.ToString()); Assert.AreEqual("time < 2015-01-01T00:00", m.Caveats[1].CId.ToString()); Assert.AreEqual("email = [email protected]", m.Caveats[2].CId.ToString()); }
public void CanVerifyFirstPartyCaveat() { // Arrange Macaroon m = new Macaroon(Location, Secret, Identifier); m.AddFirstPartyCaveat("account = 3735928559"); Verifier v = new Verifier(); v.SatisfyExact("account = 3735928559"); // Act VerificationResult verified = m.Verify(v, Secret); // Assert Assert.IsTrue(verified.Success); }
public void CanCopyMacaroon() { var m1 = new Macaroon(Location, Secret, Identifier); m1.AddFirstPartyCaveat("account = 3735928559"); var m2 = new Macaroon(m1); Assert.Equal(m1.Location, m2.Location); Assert.Equal(m1.Identifier, m2.Identifier); Assert.Equal(m1.Signature, m2.Signature); // - Change m2 and check that m1 stays the same m2.AddFirstPartyCaveat("a = 10"); Assert.Equal(2, m2.Caveats.Count); Assert.Equal("account = 3735928559", m2.Caveats[0].CId.ToString()); Assert.Equal(1, m1.Caveats.Count); }
public void VerificationFailsWithInvalidSecret() { // Arrange Macaroon m = new Macaroon(Location, "Another secret", Identifier); m.AddFirstPartyCaveat("account = 3735928559"); Verifier v = new Verifier(); v.SatisfyExact("account = 3735928559"); // Act VerificationResult verified = m.Verify(v, Secret); // Assert Assert.IsFalse(verified.Success); Assert.AreEqual(1, verified.Messages.Count); StringAssert.Contains("Signature mismatch", verified.Messages[0]); }
public void StandardExpiresVerifierDoesNotAddReasonWhenNoExpiresCaveatArePresent() { // Arrange Macaroon mFailure = new Macaroon(Location, Secret, Identifier); mFailure.AddFirstPartyCaveat("other: 1234"); Verifier v = new Verifier(); v.SatisfyGeneral(StandardCaveatVerifiers.ExpiresVerifier); // Act VerificationResult verified2 = mFailure.Verify(v, Secret); // Assert Assert.IsFalse(verified2.Success); Assert.AreEqual(1, verified2.Messages.Count); Assert.AreEqual("Caveat 'other: 1234' failed", verified2.Messages[0]); }
public void StandardExpiresVerifierOnlyAcceptsISOTimeStamp() { // Arrange Macaroon mFailure = new Macaroon(Location, Secret, Identifier); mFailure.AddFirstPartyCaveat("expires: 23-12-2000"); Verifier v = new Verifier(); v.SatisfyGeneral(StandardCaveatVerifiers.ExpiresVerifier); // Act VerificationResult verified2 = mFailure.Verify(v, Secret); // Assert Assert.IsFalse(verified2.Success); Assert.AreEqual(1, verified2.Messages.Count); Assert.AreEqual("Invalid timestamp in 'expires: 23-12-2000'", verified2.Messages[0]); }
public void FailedVerificationAddsVerifierReason() { // Arrange Macaroon mFailure = new Macaroon(Location, Secret, Identifier); mFailure.AddFirstPartyCaveat("expires: 2000-01-01T00:00:00Z"); Verifier v = new Verifier(); v.SatisfyGeneral(StandardCaveatVerifiers.ExpiresVerifier); // Act VerificationResult verified2 = mFailure.Verify(v, Secret); // Assert Assert.IsFalse(verified2.Success); Assert.AreEqual(1, verified2.Messages.Count); Assert.AreEqual("Timestamp '2000-01-01T00:00:00Z' has expired", verified2.Messages[0]); }
public void VerificationFailsWhenHavingCircularMacaroonReferences() { // Arrange // - Create primary macaroon Macaroon m = new Macaroon(Location, Secret, Identifier); // - Add third party caveat (1) string caveat_key1 = "4; guaranteed random by a fair toss of the dice"; string identifier1 = "this was how we remind auth of key/pred"; m.AddThirdPartyCaveat("http://auth.mybank/", caveat_key1, identifier1); // - Add third party caveat (2) string caveat_key2 = "random key 2"; string identifier2 = "identifier 2"; m.AddThirdPartyCaveat("http://auth.government/", caveat_key2, identifier2); // - Create discharge macaroon (1) with reference to (2) Macaroon d1 = new Macaroon("http://auth.mybank/", caveat_key1, identifier1); d1.AddThirdPartyCaveat("http://auth.government/", caveat_key2, identifier2); Macaroon dp1 = m.PrepareForRequest(d1); // - Create discharge macaroon (2) with reference to (1) Macaroon d2 = new Macaroon("http://auth.mybank/", caveat_key2, identifier2); d2.AddThirdPartyCaveat("http://auth.government/", caveat_key1, identifier1); Macaroon dp2 = m.PrepareForRequest(d2); Verifier v = new Verifier(); // Act VerificationResult result = m.Verify(v, Secret, new List <Macaroon> { dp1, dp2 }); // Assert Assert.IsFalse(result.Success); Assert.AreEqual(2, result.Messages.Count); StringAssert.Contains("circular", result.Messages[0]); }
public void VerificationFailsWithUnknownCaveat() { // Arrange Macaroon m = new Macaroon(Location, Secret, Identifier); m.AddFirstPartyCaveat("account = 3735928559"); Verifier v = new Verifier(); v.SatisfyExact("account = 88778"); // Act VerificationResult verified = m.Verify(v, Secret); // Assert Assert.IsFalse(verified.Success); Assert.AreEqual(1, verified.Messages.Count); StringAssert.Contains("Caveat", verified.Messages[0]); StringAssert.Contains("failed", verified.Messages[0]); }
public void CanAddThirdPartyCaveat() { // Arrange Macaroon m = new Macaroon(Location2, Secret2, Identifier2); m.AddFirstPartyCaveat("account = 3735928559"); // - just checking (this should although be covered in other tests) ... Assert.AreEqual("1434E674AD84FDFDC9BC1AA00785325C8B6D57341FC7CE200BA4680C80786DDA", m.Signature.ToString()); // Act string caveat_key = "4; guaranteed random by a fair toss of the dice"; // string predicate = "user = Alice"; // # send_to_auth(caveat_key, predicate) // # identifier = recv_from_auth() string identifier = "this was how we remind auth of key/pred"; m.AddThirdPartyCaveat("http://auth.mybank/", caveat_key, identifier); // Assert Assert.AreEqual("D27DB2FD1F22760E4C3DAE8137E2D8FC1DF6C0741C18AED4B97256BF78D1F55C", m.Signature.ToString()); string expectedStringRepresentation = string.Join(Environment.NewLine, new[] { "Location = http://mybank/", "Identifier = we used our other secret key", "CId = account = 3735928559", "CId = this was how we remind auth of key/pred", " VId = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA027FAuBYhtHwJ58FX6UlVNFtFsGxQHS7uD_w_dedwv4Jjw7UorCREw5rXbRqIKhr", " Cl = http://auth.mybank/", "Signature = D27DB2FD1F22760E4C3DAE8137E2D8FC1DF6C0741C18AED4B97256BF78D1F55C", "" }); Assert.AreEqual(expectedStringRepresentation, m.Inspect()); List <Caveat> thirdPartyCaveats = m.ThirdPartyCaveats.ToList(); Assert.AreEqual(1, thirdPartyCaveats.Count); Assert.AreEqual("http://auth.mybank/", thirdPartyCaveats[0].Cl.ToString()); Assert.AreEqual("this was how we remind auth of key/pred", thirdPartyCaveats[0].CId.ToString()); }
public void CanVerifyMultipleFirstPartyCaveats() { // Arrange Macaroon m = new Macaroon(Location, Secret, Identifier); m.AddFirstPartyCaveat("account = 3735928559"); m.AddFirstPartyCaveat("time < 2115-01-01T00:00"); m.AddFirstPartyCaveat("email = [email protected]"); Verifier v = new Verifier(); v.SatisfyExact("account = 3735928559"); v.SatisfyExact("time < 2115-01-01T00:00"); v.SatisfyExact("email = [email protected]"); // Act VerificationResult verified = m.Verify(v, Secret); // Assert Assert.IsTrue(verified.Success); }
public void CanAddThirdPartyCaveat() { // Arrange Macaroon m = new Macaroon(Location2, Secret2, Identifier2); m.AddFirstPartyCaveat("account = 3735928559"); // - just checking (this should although be covered in other Tests) ... Assert.Equal("1434E674AD84FDFDC9BC1AA00785325C8B6D57341FC7CE200BA4680C80786DDA", m.Signature.ToString().ToUpperInvariant()); // Act string caveat_key = "4; guaranteed random by a fair toss of the dice"; // string predicate = "user = Alice"; // # send_to_auth(caveat_key, predicate) // # identifier = recv_from_auth() string identifier = "this was how we remind auth of key/pred"; m.AddThirdPartyCaveat("http://auth.mybank/", caveat_key, identifier); // Assert Assert.Equal("D27DB2FD1F22760E4C3DAE8137E2D8FC1DF6C0741C18AED4B97256BF78D1F55C", m.Signature.ToString().ToUpperInvariant()); string expectedStringRepresentation = @"Location = http://mybank/ Identifier = we used our other secret key CId = account = 3735928559 CId = this was how we remind auth of key/pred VId = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA027FAuBYhtHwJ58FX6UlVNFtFsGxQHS7uD_w_dedwv4Jjw7UorCREw5rXbRqIKhr Cl = http://auth.mybank/ Signature = d27db2fd1f22760e4c3dae8137e2d8fc1df6c0741c18aed4b97256bf78d1f55c "; Assert.Equal(expectedStringRepresentation, m.Inspect()); List <Caveat> thirdPartyCaveats = m.ThirdPartyCaveats.ToList(); Assert.Single(thirdPartyCaveats); Assert.Equal("http://auth.mybank/", thirdPartyCaveats[0].Cl.ToString()); Assert.Equal("this was how we remind auth of key/pred", thirdPartyCaveats[0].CId.ToString()); }