예제 #1
0
    def add_caveat(self, cav, key=None, loc=None):
        '''Add a caveat to the macaroon.

        It encrypts it using the given key pair
        and by looking up the location using the given locator.
        As a special case, if the caveat's Location field has the prefix
        "local " the caveat is added as a client self-discharge caveat using
        the public key base64-encoded in the rest of the location. In this
        case, the Condition field must be empty. The resulting third-party
        caveat will encode the condition "true" encrypted with that public
        key.

        @param cav the checkers.Caveat to be added.
        @param key the public key to encrypt third party caveat.
        @param loc locator to find information on third parties when adding
        third party caveats. It is expected to have a third_party_info method
        that will be called with a location string and should return a
        ThirdPartyInfo instance holding the requested information.
        '''
        if cav.location is None:
            self._macaroon.add_first_party_caveat(
                self.namespace.resolve_caveat(cav).condition)
            return
        if key is None:
            raise ValueError('no private key to encrypt third party caveat')
        local_info = _parse_local_location(cav.location)
        if local_info is not None:
            info = local_info
            if cav.condition is not '':
                raise ValueError('cannot specify caveat condition in '
                                 'local third-party caveat')
            cav = checkers.Caveat(location='local', condition='true')
        else:
            if loc is None:
                raise ValueError('no locator when adding third party caveat')
            info = loc.third_party_info(cav.location)

        root_key = os.urandom(24)

        # Use the least supported version to encode the caveat.
        if self._version < info.version:
            info = bakery.ThirdPartyInfo(
                version=self._version,
                public_key=info.public_key,
            )

        caveat_info = bakery.encode_caveat(cav.condition, root_key, info, key,
                                           self._namespace)
        if info.version < bakery.VERSION_3:
            # We're encoding for an earlier client or third party which does
            # not understand bundled caveat info, so use the encoded
            # caveat information as the caveat id.
            id = caveat_info
        else:
            id = self._new_caveat_id(self._caveat_id_prefix)
            self._caveat_data[id] = caveat_info

        self._macaroon.add_third_party_caveat(cav.location, root_key, id)
예제 #2
0
 def test_v2_round_trip(self):
     tp_info = bakery.ThirdPartyInfo(version=bakery.VERSION_2,
                                     public_key=self.tp_key.public_key)
     cid = bakery.encode_caveat('is-authenticated-user', b'a random string',
                                tp_info, self.fp_key, None)
     res = bakery.decode_caveat(self.tp_key, cid)
     self.assertEquals(
         res,
         bakery.ThirdPartyCaveatInfo(
             first_party_public_key=self.fp_key.public_key,
             root_key=b'a random string',
             condition='is-authenticated-user',
             caveat=cid,
             third_party_key_pair=self.tp_key,
             version=bakery.VERSION_2,
             id=None,
             namespace=bakery.legacy_namespace()))
예제 #3
0
 def test_v3_round_trip(self):
     tp_info = bakery.ThirdPartyInfo(version=bakery.VERSION_3,
                                     public_key=self.tp_key.public_key)
     ns = checkers.Namespace()
     ns.register('testns', 'x')
     cid = bakery.encode_caveat('is-authenticated-user', b'a random string',
                                tp_info, self.fp_key, ns)
     res = bakery.decode_caveat(self.tp_key, cid)
     self.assertEquals(
         res,
         bakery.ThirdPartyCaveatInfo(
             first_party_public_key=self.fp_key.public_key,
             root_key=b'a random string',
             condition='is-authenticated-user',
             caveat=cid,
             third_party_key_pair=self.tp_key,
             version=bakery.VERSION_3,
             id=None,
             namespace=ns))
 def test_v2_round_trip(self):
     tp_info = bakery.ThirdPartyInfo(
         version=bakery.VERSION_2,
         public_key=self.tp_key.public_key)
     cid = bakery.encode_caveat(
         'is-authenticated-user',
         b'a random string',
         tp_info,
         self.fp_key,
         None)
     res = bakery.decode_caveat(self.tp_key, cid)
     self.assertEquals(res, bakery.ThirdPartyCaveatInfo(
         first_party_public_key=self.fp_key.public_key,
         root_key=b'a random string',
         condition='is-authenticated-user',
         caveat=cid,
         third_party_key_pair=self.tp_key,
         version=bakery.VERSION_2,
         id=None,
         namespace=bakery.legacy_namespace()
     ))
 def test_v3_round_trip(self):
     tp_info = bakery.ThirdPartyInfo(
         version=bakery.VERSION_3,
         public_key=self.tp_key.public_key)
     ns = checkers.Namespace()
     ns.register('testns', 'x')
     cid = bakery.encode_caveat(
         'is-authenticated-user',
         b'a random string',
         tp_info,
         self.fp_key,
         ns)
     res = bakery.decode_caveat(self.tp_key, cid)
     self.assertEquals(res, bakery.ThirdPartyCaveatInfo(
         first_party_public_key=self.fp_key.public_key,
         root_key=b'a random string',
         condition='is-authenticated-user',
         caveat=cid,
         third_party_key_pair=self.tp_key,
         version=bakery.VERSION_3,
         id=None,
         namespace=ns
     ))
예제 #6
0
    def add_caveat(self, cav, key=None, loc=None):
        '''Add a caveat to the macaroon.

        It encrypts it using the given key pair
        and by looking up the location using the given locator.
        As a special case, if the caveat's Location field has the prefix
        "local " the caveat is added as a client self-discharge caveat using
        the public key base64-encoded in the rest of the location. In this
        case, the Condition field must be empty. The resulting third-party
        caveat will encode the condition "true" encrypted with that public
        key.

        @param cav the checkers.Caveat to be added.
        @param key the public key to encrypt third party caveat.
        @param loc locator to find information on third parties when adding
        third party caveats. It is expected to have a third_party_info method
        that will be called with a location string and should return a
        ThirdPartyInfo instance holding the requested information.
        '''
        if cav.location is None:
            self._macaroon.add_first_party_caveat(
                self.namespace.resolve_caveat(cav).condition)
            return
        if key is None:
            raise ValueError(
                'no private key to encrypt third party caveat')
        local_info = _parse_local_location(cav.location)
        if local_info is not None:
            info = local_info
            if cav.condition is not '':
                raise ValueError(
                    'cannot specify caveat condition in '
                    'local third-party caveat')
            cav = checkers.Caveat(location='local', condition='true')
        else:
            if loc is None:
                raise ValueError(
                    'no locator when adding third party caveat')
            info = loc.third_party_info(cav.location)

        root_key = os.urandom(24)

        # Use the least supported version to encode the caveat.
        if self._version < info.version:
            info = bakery.ThirdPartyInfo(
                version=self._version,
                public_key=info.public_key,
            )

        caveat_info = bakery.encode_caveat(
            cav.condition, root_key, info, key, self._namespace)
        if info.version < bakery.VERSION_3:
            # We're encoding for an earlier client or third party which does
            # not understand bundled caveat info, so use the encoded
            # caveat information as the caveat id.
            id = caveat_info
        else:
            id = self._new_caveat_id(self._caveat_id_prefix)
            self._caveat_data[id] = caveat_info

        self._macaroon.add_third_party_caveat(cav.location, root_key, id)