# Path: macaroonbakery/bakery/_keys.py
# class PublicKey(object):
#     ''' A public key used by the bakery to encrypt third party caveats.
# 
#     Every discharger is associated with a public key which is used to
#     encrypt third party caveat ids addressed to that discharger.
#     Internally, it is a 256 bit Ed25519 public key.
#     '''
#     def __init__(self, key):
#         self._key = key
# 
#     @property
#     def key(self):
#         ''' Internal nacl key representation.
#         '''
#         return self._key
# 
#     def serialize(self, raw=False):
#         '''Encode the private part of the key in a base64 format by default,
#         but when raw is True it will return hex encoded bytes.
#         @return: bytes
#         '''
#         if raw:
#             return self._key.encode()
#         return self._key.encode(nacl.encoding.Base64Encoder)
# 
#     def __str__(self):
#         '''Return the key as a base64-encoded string'''
#         return self.serialize().decode('utf-8')
# 
#     @classmethod
#     def deserialize(cls, serialized):
#         ''' Create a PublicKey from a base64 encoded bytes.
#         :return: a PublicKey
#         '''
#         return PublicKey(
#             nacl.public.PublicKey(serialized,
#                                   encoder=nacl.encoding.Base64Encoder))
# 
#     def __eq__(self, other):
#         return self.key == other.key


import base64
import json
import macaroonbakery.checkers as checkers
import nacl.public
import six
from ._versions import (VERSION_1, VERSION_2, VERSION_3)
from ._third_party import legacy_namespace, ThirdPartyCaveatInfo
from ._keys import PublicKey
from ._error import VerificationError
    raise VerificationError('unknown version for caveat')


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'))

# Path: macaroonbakery/bakery/_keys.py
# class PublicKey(object):
#     ''' A public key used by the bakery to encrypt third party caveats.
# 
#     Every discharger is associated with a public key which is used to
#     encrypt third party caveat ids addressed to that discharger.
#     Internally, it is a 256 bit Ed25519 public key.
#     '''
#     def __init__(self, key):
#         self._key = key
# 
#     @property
#     def key(self):
#         ''' Internal nacl key representation.
#         '''
#         return self._key
# 
#     def serialize(self, raw=False):
#         '''Encode the private part of the key in a base64 format by default,
#         but when raw is True it will return hex encoded bytes.
#         @return: bytes
#         '''
#         if raw:
#             return self._key.encode()
#         return self._key.encode(nacl.encoding.Base64Encoder)
# 
#     def __str__(self):
#         '''Return the key as a base64-encoded string'''
#         return self.serialize().decode('utf-8')
# 
#     @classmethod
#     def deserialize(cls, serialized):
#         ''' Create a PublicKey from a base64 encoded bytes.
#         :return: a PublicKey
#         '''
#         return PublicKey(
#             nacl.public.PublicKey(serialized,
#                                   encoder=nacl.encoding.Base64Encoder))
# 
#     def __eq__(self, other):
#         return self.key == other.key


# Path: macaroonbakery/bakery/_codec.py
import base64
import json
import macaroonbakery.checkers as checkers
import nacl.public
import six
from ._versions import (VERSION_1, VERSION_2, VERSION_3)
from ._third_party import legacy_namespace, ThirdPartyCaveatInfo
from ._keys import PublicKey
from ._error import VerificationError

    raise VerificationError('unknown version for caveat')


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(