コード例 #1
0
 def test_decode_caveat_v3_from_go(self):
     tp_key = bakery.PrivateKey(
         nacl.public.PrivateKey(base64.b64decode(
             'TSpvLpQkRj+T3JXnsW2n43n5zP/0X4zn0RvDiWC3IJ0=')))
     fp_key = bakery.PrivateKey(nacl.public.PrivateKey(
         base64.b64decode(
             'KXpsoJ9ujZYi/O2Cca6kaWh65MSawzy79LWkrjOfzcs=')))
     root_key = base64.b64decode(b'oqOXI3/Mz/pKjCuFOt2eYxb7ndLq66GY')
     # This caveat has been generated from the go code
     # to check the compatibilty
     encrypted_cav = bakery.b64decode(
         'A_D-xlUf2MdGMgtu7OKRQnCP1OQJk6PKeFWRK26WIBA6DNwKGNLeFSkD2M-8A'
         'EYvmgVH95GWu7T7caKxKhhOQFcEKgnXKJvYXxz1zin4cZc4Q6C7gVqA-J4_j3'
         '1LX4VKxymqG62UGPo78wOv0_fKjr3OI6PPJOYOQgBMclemlRF2',
     )
     cav = bakery.decode_caveat(tp_key, encrypted_cav)
     self.assertEquals(cav, bakery.ThirdPartyCaveatInfo(
         condition='third party condition',
         first_party_public_key=fp_key.public_key,
         third_party_key_pair=tp_key,
         root_key=root_key,
         caveat=encrypted_cav,
         version=bakery.VERSION_3,
         id=None,
         namespace=bakery.legacy_namespace()
     ))
コード例 #2
0
 def test_decode_caveat_v2_from_go(self):
     tp_key = bakery.PrivateKey(nacl.public.PrivateKey(
         base64.b64decode(
             'TSpvLpQkRj+T3JXnsW2n43n5zP/0X4zn0RvDiWC3IJ0=')))
     fp_key = bakery.PrivateKey(
         nacl.public.PrivateKey(base64.b64decode(
             'KXpsoJ9ujZYi/O2Cca6kaWh65MSawzy79LWkrjOfzcs=')))
     root_key = base64.b64decode('wh0HSM65wWHOIxoGjgJJOFvQKn2jJFhC')
     # This caveat has been generated from the go code
     # to check the compatibilty
     encrypted_cav = bakery.b64decode(
         'AvD-xlUf2MdGMgtu7OKRQnCP1OQJk6PKeFWRK26WIBA6DNwKGIHq9xGcHS9IZ'
         'Lh0cL6D9qpeKI0mXmCPfnwRQDuVYC8y5gVWd-oCGZaj5TGtk3byp2Vnw6ojmt'
         'sULDhY59YA_J_Y0ATkERO5T9ajoRWBxU2OXBoX6bImXA',
     )
     cav = bakery.decode_caveat(tp_key, encrypted_cav)
     self.assertEqual(cav, bakery.ThirdPartyCaveatInfo(
         condition='third party condition',
         first_party_public_key=fp_key.public_key,
         third_party_key_pair=tp_key,
         root_key=root_key,
         caveat=encrypted_cav,
         version=bakery.VERSION_2,
         id=None,
         namespace=bakery.legacy_namespace()
     ))
コード例 #3
0
    def _test_json_with_version(self, version):
        locator = bakery.ThirdPartyStore()
        bs = common.new_bakery('bs-loc', locator)

        ns = checkers.Namespace({
            'testns': 'x',
        })

        m = bakery.Macaroon(root_key=b'root key',
                            id=b'id',
                            location='location',
                            version=version,
                            namespace=ns)
        m.add_caveat(checkers.Caveat(location='bs-loc', condition='something'),
                     bs.oven.key, locator)

        # Sanity check that no external caveat data has been added.
        self.assertEqual(len(m._caveat_data), 0)

        data = json.dumps(m, cls=bakery.MacaroonJSONEncoder)
        m1 = json.loads(data, cls=bakery.MacaroonJSONDecoder)

        # Just check the signature and version - we're not interested in fully
        # checking the macaroon marshaling here.
        self.assertEqual(m1.macaroon.signature, m.macaroon.signature)
        self.assertEqual(m1.macaroon.version, bakery.macaroon_version(version))
        self.assertEqual(len(m1.macaroon.caveats), 1)

        # Namespace information has been thrown away.
        self.assertEqual(m1.namespace, bakery.legacy_namespace())

        self.assertEqual(len(m1._caveat_data), 0)
コード例 #4
0
    def _test_json_with_version(self, version):
        locator = bakery.ThirdPartyStore()
        bs = common.new_bakery('bs-loc', locator)

        ns = checkers.Namespace({
            'testns': 'x',
        })

        m = bakery.Macaroon(
            root_key=b'root key', id=b'id',
            location='location', version=version,
            namespace=ns)
        m.add_caveat(checkers.Caveat(location='bs-loc', condition='something'),
                     bs.oven.key, locator)

        # Sanity check that no external caveat data has been added.
        self.assertEqual(len(m._caveat_data), 0)

        data = json.dumps(m, cls=bakery.MacaroonJSONEncoder)
        m1 = json.loads(data, cls=bakery.MacaroonJSONDecoder)

        # Just check the signature and version - we're not interested in fully
        # checking the macaroon marshaling here.
        self.assertEqual(m1.macaroon.signature, m.macaroon.signature)
        self.assertEqual(m1.macaroon.version,
                         bakery.macaroon_version(version))
        self.assertEqual(len(m1.macaroon.caveats), 1)

        # Namespace information has been thrown away.
        self.assertEqual(m1.namespace, bakery.legacy_namespace())

        self.assertEqual(len(m1._caveat_data), 0)
コード例 #5
0
    def test_decode_caveat_v1_from_go(self):
        tp_key = macaroonbakery.PrivateKey(
            nacl.public.PrivateKey(
                base64.b64decode(
                    'TSpvLpQkRj+T3JXnsW2n43n5zP/0X4zn0RvDiWC3IJ0=')))
        fp_key = macaroonbakery.PrivateKey(
            nacl.public.PrivateKey(
                base64.b64decode(
                    'KXpsoJ9ujZYi/O2Cca6kaWh65MSawzy79LWkrjOfzcs=')))
        root_key = base64.b64decode('vDxEmWZEkgiNEFlJ+8ruXe3qDSLf1H+o')
        # This caveat has been generated from the go code
        # to check the compatibilty

        encrypted_cav = six.b(
            'eyJUaGlyZFBhcnR5UHVibGljS2V5IjoiOFA3R1ZZc3BlWlN4c'
            '3hFdmJsSVFFSTFqdTBTSWl0WlIrRFdhWE40cmxocz0iLCJGaX'
            'JzdFBhcnR5UHVibGljS2V5IjoiSDlqSFJqSUxidXppa1VKd2o'
            '5VGtDWk9qeW5oVmtTdHVsaUFRT2d6Y0NoZz0iLCJOb25jZSI6'
            'Ii9lWTRTTWR6TGFxbDlsRFc3bHUyZTZuSzJnVG9veVl0IiwiS'
            'WQiOiJra0ZuOGJEaEt4RUxtUjd0NkJxTU0vdHhMMFVqaEZjR1'
            'BORldUUExGdjVla1dWUjA4Uk1sbGJhc3c4VGdFbkhzM0laeVo'
            '0V2lEOHhRUWdjU3ljOHY4eUt4dEhxejVEczJOYmh1ZDJhUFdt'
            'UTVMcVlNWitmZ2FNaTAxdE9DIn0=')
        cav = macaroonbakery.decode_caveat(tp_key, encrypted_cav)
        self.assertEquals(
            cav,
            macaroonbakery.ThirdPartyCaveatInfo(
                condition='caveat condition',
                first_party_public_key=fp_key.public_key,
                third_party_key_pair=tp_key,
                root_key=root_key,
                caveat=encrypted_cav,
                version=macaroonbakery.BAKERY_V1,
                namespace=macaroonbakery.legacy_namespace()))
コード例 #6
0
 def test_decode_caveat_v2_from_go(self):
     tp_key = macaroonbakery.PrivateKey(
         nacl.public.PrivateKey(
             base64.b64decode(
                 'TSpvLpQkRj+T3JXnsW2n43n5zP/0X4zn0RvDiWC3IJ0=')))
     fp_key = macaroonbakery.PrivateKey(
         nacl.public.PrivateKey(
             base64.b64decode(
                 'KXpsoJ9ujZYi/O2Cca6kaWh65MSawzy79LWkrjOfzcs=')))
     root_key = base64.b64decode('wh0HSM65wWHOIxoGjgJJOFvQKn2jJFhC')
     # This caveat has been generated from the go code
     # to check the compatibilty
     encrypted_cav = base64.urlsafe_b64decode(
         utils.add_base64_padding(
             six.
             b('AvD-xlUf2MdGMgtu7OKRQnCP1OQJk6PKeFWRK26WIBA6DNwKGIHq9xGcHS9IZ'
               'Lh0cL6D9qpeKI0mXmCPfnwRQDuVYC8y5gVWd-oCGZaj5TGtk3byp2Vnw6ojmt'
               'sULDhY59YA_J_Y0ATkERO5T9ajoRWBxU2OXBoX6bImXA')))
     cav = macaroonbakery.decode_caveat(tp_key, encrypted_cav)
     self.assertEqual(
         cav,
         macaroonbakery.ThirdPartyCaveatInfo(
             condition='third party condition',
             first_party_public_key=fp_key.public_key,
             third_party_key_pair=tp_key,
             root_key=root_key,
             caveat=encrypted_cav,
             version=macaroonbakery.BAKERY_V2,
             namespace=macaroonbakery.legacy_namespace()))
コード例 #7
0
 def test_decode_caveat_v3_from_go(self):
     tp_key = macaroonbakery.PrivateKey(
         nacl.public.PrivateKey(
             base64.b64decode(
                 'TSpvLpQkRj+T3JXnsW2n43n5zP/0X4zn0RvDiWC3IJ0=')))
     fp_key = macaroonbakery.PrivateKey(
         nacl.public.PrivateKey(
             base64.b64decode(
                 'KXpsoJ9ujZYi/O2Cca6kaWh65MSawzy79LWkrjOfzcs=')))
     root_key = base64.b64decode(b'oqOXI3/Mz/pKjCuFOt2eYxb7ndLq66GY')
     # This caveat has been generated from the go code
     # to check the compatibilty
     encrypted_cav = base64.urlsafe_b64decode(
         utils.add_base64_padding(
             six.
             b('A_D-xlUf2MdGMgtu7OKRQnCP1OQJk6PKeFWRK26WIBA6DNwKGNLeFSkD2M-8A'
               'EYvmgVH95GWu7T7caKxKhhOQFcEKgnXKJvYXxz1zin4cZc4Q6C7gVqA-J4_j3'
               '1LX4VKxymqG62UGPo78wOv0_fKjr3OI6PPJOYOQgBMclemlRF2')))
     cav = macaroonbakery.decode_caveat(tp_key, encrypted_cav)
     self.assertEquals(
         cav,
         macaroonbakery.ThirdPartyCaveatInfo(
             condition='third party condition',
             first_party_public_key=fp_key.public_key,
             third_party_key_pair=tp_key,
             root_key=root_key,
             caveat=encrypted_cav,
             version=macaroonbakery.BAKERY_V3,
             namespace=macaroonbakery.legacy_namespace()))
コード例 #8
0
    def test_decode_caveat_v1_from_go(self):
        tp_key = bakery.PrivateKey(
            nacl.public.PrivateKey(base64.b64decode(
                'TSpvLpQkRj+T3JXnsW2n43n5zP/0X4zn0RvDiWC3IJ0=')))
        fp_key = bakery.PrivateKey(
            nacl.public.PrivateKey(base64.b64decode(
                'KXpsoJ9ujZYi/O2Cca6kaWh65MSawzy79LWkrjOfzcs=')))
        root_key = base64.b64decode('vDxEmWZEkgiNEFlJ+8ruXe3qDSLf1H+o')
        # This caveat has been generated from the go code
        # to check the compatibilty

        encrypted_cav = six.b(
            'eyJUaGlyZFBhcnR5UHVibGljS2V5IjoiOFA3R1ZZc3BlWlN4c'
            '3hFdmJsSVFFSTFqdTBTSWl0WlIrRFdhWE40cmxocz0iLCJGaX'
            'JzdFBhcnR5UHVibGljS2V5IjoiSDlqSFJqSUxidXppa1VKd2o'
            '5VGtDWk9qeW5oVmtTdHVsaUFRT2d6Y0NoZz0iLCJOb25jZSI6'
            'Ii9lWTRTTWR6TGFxbDlsRFc3bHUyZTZuSzJnVG9veVl0IiwiS'
            'WQiOiJra0ZuOGJEaEt4RUxtUjd0NkJxTU0vdHhMMFVqaEZjR1'
            'BORldUUExGdjVla1dWUjA4Uk1sbGJhc3c4VGdFbkhzM0laeVo'
            '0V2lEOHhRUWdjU3ljOHY4eUt4dEhxejVEczJOYmh1ZDJhUFdt'
            'UTVMcVlNWitmZ2FNaTAxdE9DIn0=')
        cav = bakery.decode_caveat(tp_key, encrypted_cav)
        self.assertEquals(cav, bakery.ThirdPartyCaveatInfo(
            condition='caveat condition',
            first_party_public_key=fp_key.public_key,
            third_party_key_pair=tp_key,
            root_key=root_key,
            caveat=encrypted_cav,
            version=bakery.VERSION_1,
            id=None,
            namespace=bakery.legacy_namespace()
        ))
コード例 #9
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()))
コード例 #10
0
    def from_dict(cls, json_dict):
        '''Return a macaroon obtained from the given dictionary as
        deserialized from JSON.
        @param json_dict The deserialized JSON object.
        '''
        json_macaroon = json_dict.get('m')
        if json_macaroon is None:
            # Try the v1 format if we don't have a macaroon field.
            m = pymacaroons.Macaroon.deserialize(
                json.dumps(json_dict), json_serializer.JsonSerializer())
            macaroon = Macaroon(root_key=None,
                                id=None,
                                namespace=bakery.legacy_namespace(),
                                version=_bakery_version(m.version))
            macaroon._macaroon = m
            return macaroon

        version = json_dict.get('v', None)
        if version is None:
            raise ValueError('no version specified')
        if (version < bakery.VERSION_3 or version > bakery.LATEST_VERSION):
            raise ValueError('unknown bakery version {}'.format(version))
        m = pymacaroons.Macaroon.deserialize(json.dumps(json_macaroon),
                                             json_serializer.JsonSerializer())
        if m.version != macaroon_version(version):
            raise ValueError('underlying macaroon has inconsistent version; '
                             'got {} want {}'.format(
                                 m.version, macaroon_version(version)))
        namespace = checkers.deserialize_namespace(json_dict.get('ns'))
        cdata = json_dict.get('cdata', {})
        caveat_data = {}
        for id64 in cdata:
            id = utils.b64decode(id64)
            data = utils.b64decode(cdata[id64])
            caveat_data[id] = data
        macaroon = Macaroon(root_key=None,
                            id=None,
                            namespace=namespace,
                            version=version)
        macaroon._caveat_data = caveat_data
        macaroon._macaroon = m
        return macaroon
コード例 #11
0
    def from_dict(cls, json_dict):
        '''Return a macaroon obtained from the given dictionary as
        deserialized from JSON.
        @param json_dict The deserialized JSON object.
        '''
        json_macaroon = json_dict.get('m')
        if json_macaroon is None:
            # Try the v1 format if we don't have a macaroon field.
            m = pymacaroons.Macaroon.deserialize(
                json.dumps(json_dict), json_serializer.JsonSerializer())
            macaroon = Macaroon(root_key=None, id=None,
                                namespace=bakery.legacy_namespace(),
                                version=_bakery_version(m.version))
            macaroon._macaroon = m
            return macaroon

        version = json_dict.get('v', None)
        if version is None:
            raise ValueError('no version specified')
        if (version < bakery.VERSION_3 or
                version > bakery.LATEST_VERSION):
            raise ValueError('unknown bakery version {}'.format(version))
        m = pymacaroons.Macaroon.deserialize(json.dumps(json_macaroon),
                                             json_serializer.JsonSerializer())
        if m.version != macaroon_version(version):
            raise ValueError(
                'underlying macaroon has inconsistent version; '
                'got {} want {}'.format(m.version, macaroon_version(version)))
        namespace = checkers.deserialize_namespace(json_dict.get('ns'))
        cdata = json_dict.get('cdata', {})
        caveat_data = {}
        for id64 in cdata:
            id = utils.b64decode(id64)
            data = utils.b64decode(cdata[id64])
            caveat_data[id] = data
        macaroon = Macaroon(root_key=None, id=None,
                            namespace=namespace,
                            version=version)
        macaroon._caveat_data = caveat_data
        macaroon._macaroon = m
        return macaroon
コード例 #12
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()
     ))
コード例 #13
0
    def deserialize_json(cls, serialized_json):
        serialized = json.loads(serialized_json)
        json_macaroon = serialized.get('m')
        if json_macaroon is None:
            # Try the v1 format if we don't have a macaroon filed
            m = pymacaroons.Macaroon.deserialize(
                serialized_json, json_serializer.JsonSerializer())
            macaroon = Macaroon(root_key=None,
                                id=None,
                                namespace=macaroonbakery.legacy_namespace(),
                                version=_bakery_version(m.version))
            macaroon._macaroon = m
            return macaroon

        version = serialized.get('v', None)
        if version is None:
            raise ValueError('no version specified')
        if (version < macaroonbakery.BAKERY_V3
                or version > macaroonbakery.LATEST_BAKERY_VERSION):
            raise ValueError('unknow bakery version {}'.format(version))
        m = pymacaroons.Macaroon.deserialize(json.dumps(json_macaroon),
                                             json_serializer.JsonSerializer())
        if m.version != macaroon_version(version):
            raise ValueError('underlying macaroon has inconsistent version; '
                             'got {} want {}'.format(
                                 m.version, macaroon_version(version)))
        namespace = checkers.deserialize_namespace(serialized.get('ns'))
        cdata = serialized.get('cdata', {})
        caveat_data = {}
        for id64 in cdata:
            id = utils.raw_b64decode(id64)
            data = utils.raw_b64decode(cdata[id64])
            caveat_data[id] = data
        macaroon = Macaroon(root_key=None,
                            id=None,
                            namespace=namespace,
                            version=version)
        macaroon._caveat_data = caveat_data
        macaroon._macaroon = m
        return macaroon
コード例 #14
0
def _decode_secret_part_v2_v3(version, data):
    if len(data) < 1:
        raise bakery.VerificationError('secret part too short')
    got_version = six.byte2int(data[:1])
    data = data[1:]
    if version != got_version:
        raise bakery.VerificationError(
            'unexpected secret part version, got {} want {}'.format(
                got_version, version))
    root_key_length, read = decode_uvarint(data)
    data = data[read:]
    root_key = data[:root_key_length]
    data = data[root_key_length:]
    if version >= bakery.VERSION_3:
        namespace_length, read = decode_uvarint(data)
        data = data[read:]
        ns_data = data[:namespace_length]
        data = data[namespace_length:]
        ns = checkers.deserialize_namespace(ns_data)
    else:
        ns = bakery.legacy_namespace()
    return root_key, data, ns
コード例 #15
0
def _decode_secret_part_v2_v3(version, data):
    if len(data) < 1:
        raise macaroonbakery.VerificationError('secret part too short')
    got_version = six.byte2int(data[:1])
    data = data[1:]
    if version != got_version:
        raise macaroonbakery.VerificationError(
            'unexpected secret part version, got {} want {}'.format(
                got_version, version))
    root_key_length, read = decode_uvarint(data)
    data = data[read:]
    root_key = data[:root_key_length]
    data = data[root_key_length:]
    if version >= macaroonbakery.BAKERY_V3:
        namespace_length, read = decode_uvarint(data)
        data = data[read:]
        ns_data = data[:namespace_length]
        data = data[namespace_length:]
        ns = checkers.deserialize_namespace(ns_data)
    else:
        ns = macaroonbakery.legacy_namespace()
    return root_key, data, ns
コード例 #16
0
def _decode_caveat_v1(key, caveat):
    '''Decode a base64 encoded JSON id.

    @param key the nacl private key to decode.
    @param caveat a base64 encoded JSON string.
    '''

    data = base64.b64decode(caveat).decode('utf-8')
    wrapper = json.loads(data)
    tp_public_key = nacl.public.PublicKey(
        base64.b64decode(wrapper['ThirdPartyPublicKey']))
    if key.public_key.key != tp_public_key:
        raise Exception('public key mismatch')  # TODO

    if wrapper.get('FirstPartyPublicKey', None) is None:
        raise Exception('target service public key not specified')

    # The encrypted string is base64 encoded in the JSON representation.
    secret = base64.b64decode(wrapper.get('Id'))
    nonce = base64.b64decode(wrapper.get('Nonce'))

    fp_public_key = nacl.public.PublicKey(base64.b64decode(
        wrapper.get('FirstPartyPublicKey')))

    box = nacl.public.Box(key.key, fp_public_key)
    c = box.decrypt(secret, nonce)
    record = json.loads(c.decode('utf-8'))
    fp_key = nacl.public.PublicKey(
        base64.b64decode(wrapper.get('FirstPartyPublicKey')))
    return bakery.ThirdPartyCaveatInfo(
        condition=record.get('Condition'),
        first_party_public_key=bakery.PublicKey(fp_key),
        third_party_key_pair=key,
        root_key=base64.b64decode(record.get('RootKey')),
        caveat=caveat,
        id=None,
        version=bakery.VERSION_1,
        namespace=bakery.legacy_namespace()
    )
コード例 #17
0
ファイル: codec.py プロジェクト: azzar1/py-macaroon-bakery
def _decode_caveat_v1(key, caveat):
    '''Decode a base64 encoded JSON id.

    @param key the nacl private key to decode.
    @param caveat a base64 encoded JSON string.
    '''

    data = base64.b64decode(caveat).decode('utf-8')
    wrapper = json.loads(data)
    tp_public_key = nacl.public.PublicKey(
        base64.b64decode(wrapper['ThirdPartyPublicKey']))
    if key.public_key.key != tp_public_key:
        raise Exception('public key mismatch')  # TODO

    if wrapper.get('FirstPartyPublicKey', None) is None:
        raise Exception('target service public key not specified')

    # The encrypted string is base64 encoded in the JSON representation.
    secret = base64.b64decode(wrapper.get('Id'))
    nonce = base64.b64decode(wrapper.get('Nonce'))

    fp_public_key = nacl.public.PublicKey(
        base64.b64decode(wrapper.get('FirstPartyPublicKey')))

    box = nacl.public.Box(key.key, fp_public_key)
    c = box.decrypt(secret, nonce)
    record = json.loads(c.decode('utf-8'))
    fp_key = nacl.public.PublicKey(
        base64.b64decode(wrapper.get('FirstPartyPublicKey')))
    return bakery.ThirdPartyCaveatInfo(
        condition=record.get('Condition'),
        first_party_public_key=bakery.PublicKey(fp_key),
        third_party_key_pair=key,
        root_key=base64.b64decode(record.get('RootKey')),
        caveat=caveat,
        id=None,
        version=bakery.VERSION_1,
        namespace=bakery.legacy_namespace())