def test_verify_third_party_caveats(self): m = Macaroon( location='http://mybank/', identifier='we used our other secret key', key='this is a different super-secret key; \ never use the same secret twice' ) m.add_first_party_caveat('account = 3735928559') caveat_key = '4; guaranteed random by a fair toss of the dice' identifier = 'this was how we remind auth of key/pred' m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier) discharge = Macaroon( location='http://auth.mybank/', key=caveat_key, identifier=identifier ) discharge.add_first_party_caveat('time < 2015-01-01T00:00') protected = m.prepare_for_request(discharge) v = Verifier() v.satisfy_exact('account = 3735928559') v.satisfy_exact('time < 2015-01-01T00:00') verified = v.verify( m, 'this is a different super-secret key; \ never use the same secret twice', discharge_macaroons=[protected] ) assert_true(verified)
def test_verify_third_party_caveats_multi_level(self): # See https://github.com/ecordell/pymacaroons/issues/37 root = Macaroon(location="", identifier="root-id", key="root-key") root.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great") # Create a discharge macaroon that requires a secondary discharge. discharge1 = Macaroon(location="bob", identifier="bob-is-great", key="bob-caveat-root-key") discharge1.add_third_party_caveat("barbara", "barbara-caveat-root-key", "barbara-is-great") # Create the secondary discharge macaroon. discharge2 = Macaroon(location="barbara", identifier="barbara-is-great", key="barbara-caveat-root-key") # Prepare the discharge macaroons for request. discharge1 = root.prepare_for_request(discharge1) discharge2 = root.prepare_for_request(discharge2) verified = Verifier( discharge_macaroons=[discharge1, discharge2]).verify( root, "root-key") assert_true(verified)
def generate_macaroon(self, nonce): m = Macaroon( location='http://mybank/', identifier='we used our other secret key', key='this is a different super-secret key; \ never use the same secret twice' ) m.add_first_party_caveat('account = 3735928559') caveat_key = '4; guaranteed random by a fair toss of the dice' identifier = 'this was how we remind auth of key/pred' m.add_third_party_caveat( 'http://auth.mybank/', caveat_key, identifier, nonce=nonce, ) discharge = Macaroon( location='http://auth.mybank/', key=caveat_key, identifier=identifier ) discharge.add_first_party_caveat('time < 2015-01-01T00:00') protected = m.prepare_for_request(discharge) return protected.signature
def test_prepare_for_request(self, rand_nonce): # use a fixed nonce to ensure the same signature rand_nonce.return_value = truncate_or_pad( b'\0', size=crypto_box_NONCEBYTES ) m = Macaroon( location='http://mybank/', identifier='we used our other secret key', key='this is a different super-secret key; \ never use the same secret twice' ) m.add_first_party_caveat('account = 3735928559') caveat_key = '4; guaranteed random by a fair toss of the dice' identifier = 'this was how we remind auth of key/pred' m.add_third_party_caveat( 'http://auth.mybank/', caveat_key, identifier ) discharge = Macaroon( location='http://auth.mybank/', key=caveat_key, identifier=identifier ) discharge.add_first_party_caveat('time < 2015-01-01T00:00') protected = m.prepare_for_request(discharge) assert_equal( protected.signature, '2eb01d0dd2b4475330739140188648cf25dda0425ea9f661f1574ca0a9eac54e' )
def test_verify_third_party_caveats(self): m = Macaroon( location='http://mybank/', identifier='we used our other secret key', key='this is a different super-secret key; \ never use the same secret twice' ) m.add_first_party_caveat('account = 3735928559') caveat_key = '4; guaranteed random by a fair toss of the dice' identifier = 'this was how we remind auth of key/pred' m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier) discharge = Macaroon( location='http://auth.mybank/', key=caveat_key, identifier=identifier ) discharge.add_first_party_caveat('time < 2015-01-01T00:00') protected = m.prepare_for_request(discharge) v = Verifier() v.satisfy_exact('account = 3735928559') v.satisfy_exact('time < 2015-01-01T00:00') verified = v.verify( m, 'this is a different super-secret key; \ never use the same secret twice', discharge_macaroons=[protected] ) assert_true(verified)
def test_prepare_for_request(self, rand_nonce): # use a fixed nonce to ensure the same signature rand_nonce.return_value = truncate_or_pad( b'\0', size=crypto_box_NONCEBYTES ) m = Macaroon( location='http://mybank/', identifier='we used our other secret key', key='this is a different super-secret key; \ never use the same secret twice' ) m.add_first_party_caveat('account = 3735928559') caveat_key = '4; guaranteed random by a fair toss of the dice' identifier = 'this was how we remind auth of key/pred' m.add_third_party_caveat( 'http://auth.mybank/', caveat_key, identifier ) discharge = Macaroon( location='http://auth.mybank/', key=caveat_key, identifier=identifier ) discharge.add_first_party_caveat('time < 2015-01-01T00:00') protected = m.prepare_for_request(discharge) assert_equal( protected.signature, '2eb01d0dd2b4475330739140188648cf25dda0425ea9f661f1574ca0a9eac54e' )
def test_mutual_discharge(self): m1 = Macaroon(location="", identifier="root-id", key="root-key") m1.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great") m2 = Macaroon(location="bob", identifier="bob-is-great", key="bob-caveat-root-key") m2.add_third_party_caveat("charlie", "bob-caveat-root-key", "bob-is-great") m2 = m1.prepare_for_request(m2) Verifier(discharge_macaroons=[m2]).verify(m1, "root-key")
def test_mutual_discharge(self): m1 = Macaroon(location="", identifier="root-id", key="root-key") m1.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great") m2 = Macaroon(location="bob", identifier="bob-is-great", key="bob-caveat-root-key") m2.add_third_party_caveat("charlie", "bob-caveat-root-key", "bob-is-great") m2 = m1.prepare_for_request(m2) Verifier(discharge_macaroons=[m2]).verify(m1, "root-key")
def create_macaroons(self): (key_id, key) = create_key_id_pair(prefix='{loc}::{user}::'.format( loc=current_app.config['TARGET_SERVICE_LOCATION'], user=self.username)) macaroon = Macaroon( location=current_app.config['TARGET_SERVICE_LOCATION'], key=key, identifier=key_id) discharge = self._add_user_caveat(macaroon) protected = macaroon.prepare_for_request(discharge) return macaroon, protected
def test_verify_third_party_caveats_multi_level(self): # See https://github.com/ecordell/pymacaroons/issues/37 root = Macaroon(location="", identifier="root-id", key="root-key") root.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great") # Create a discharge macaroon that requires a secondary discharge. discharge1 = Macaroon(location="bob", identifier="bob-is-great", key="bob-caveat-root-key") discharge1.add_third_party_caveat("barbara", "barbara-caveat-root-key", "barbara-is-great") # Create the secondary discharge macaroon. discharge2 = Macaroon(location="barbara", identifier="barbara-is-great", key="barbara-caveat-root-key") # Prepare the discharge macaroons for request. discharge1 = root.prepare_for_request(discharge1) discharge2 = root.prepare_for_request(discharge2) verified = Verifier(discharge_macaroons=[discharge1, discharge2]).verify(root, "root-key") assert_true(verified)
def test_macaroon_paper_fig6_fails_with_binding_on_tampered_sig(self): ''' Runs a similar test as test_macaroon_paper_fig6 with the discharge macaroon binding being done on a tampered signature. ''' locator = bakery.ThirdPartyStore() bs = common.new_bakery('bs-loc', locator) ts = common.new_bakery('ts-loc', locator) # ts creates a macaroon. ts_macaroon = ts.oven.macaroon(bakery.LATEST_VERSION, common.ages, None, [bakery.LOGIN_OP]) # ts somehow sends the macaroon to fs which adds a third party caveat # to be discharged by as. ts_macaroon.add_caveat(checkers.Caveat(condition='user==bob', location='bs-loc'), ts.oven.key, ts.oven.locator) # client asks for a discharge macaroon for each third party caveat def get_discharge(cav, payload): self.assertEqual(cav.location, 'bs-loc') return bakery.discharge( common.test_context, cav.caveat_id_bytes, payload, bs.oven.key, common.ThirdPartyStrcmpChecker('user==bob'), bs.oven.locator, ) d = bakery.discharge_all(ts_macaroon, get_discharge) # client has all the discharge macaroons. For each discharge macaroon # bind it to our ts_macaroon and add it to our request. tampered_macaroon = Macaroon() for i, dm in enumerate(d[1:]): d[i + 1] = tampered_macaroon.prepare_for_request(dm) # client makes request to ts. with self.assertRaises(bakery.VerificationError) as exc: ts.checker.auth([d]).allow(common.test_context, bakery.LOGIN_OP) self.assertEqual('verification failed: Signatures do not match', exc.exception.args[0])
def generate_macaroon(self, nonce): m = Macaroon(location='http://mybank/', identifier='we used our other secret key', key='this is a different super-secret key; \ never use the same secret twice') m.add_first_party_caveat('account = 3735928559') caveat_key = '4; guaranteed random by a fair toss of the dice' identifier = 'this was how we remind auth of key/pred' m.add_third_party_caveat( 'http://auth.mybank/', caveat_key, identifier, nonce=nonce, ) discharge = Macaroon(location='http://auth.mybank/', key=caveat_key, identifier=identifier) discharge.add_first_party_caveat('time < 2015-01-01T00:00') protected = m.prepare_for_request(discharge) return protected.signature