Ejemplo n.º 1
0
    def _packetize(self, key, data):
        # The 2 covers the space and the newline
        packet_size = self.PACKET_PREFIX_LENGTH + 2 + len(key) + len(data)
        # Ignore the first two chars, 0x
        packet_size_hex = hex(packet_size)[2:]

        if packet_size > 65535:
            raise MacaroonSerializationException(
                'Packet too long for serialization. '
                'Max length is 0xFFFF (65535). '
                'Packet length: 0x{hex_length} ({length}) '
                'Key: {key}'.format(
                    key=key,
                    hex_length=packet_size_hex,
                    length=packet_size
                )
            )

        header = packet_size_hex.zfill(4).encode('ascii')
        packet_content = key + b' ' + convert_to_bytes(data) + b'\n'
        packet = struct.pack(
            convert_to_bytes("4s%ds" % len(packet_content)),
            header,
            packet_content
        )
        return packet
Ejemplo n.º 2
0
    def _serialize_v2(self, macaroon):
        from pymacaroons.macaroon import MACAROON_V2

        # https://github.com/rescrv/libmacaroons/blob/master/doc/format.txt
        data = bytearray()
        data.append(MACAROON_V2)
        if macaroon.location is not None:
            self._append_packet(data, self._LOCATION, convert_to_bytes(
                macaroon.location))
            self._append_packet(data, self._IDENTIFIER,
                                macaroon.identifier_bytes)
        self._append_packet(data, self._EOS)
        for c in macaroon.caveats:
            if c.location is not None:
                self._append_packet(data, self._LOCATION,
                                    convert_to_bytes(c.location))
            self._append_packet(data, self._IDENTIFIER, c.caveat_id_bytes)
            if c.verification_key_id is not None:
                self._append_packet(data, self._VID, convert_to_bytes(
                    c.verification_key_id))
            self._append_packet(data, self._EOS)
        self._append_packet(data, self._EOS)
        self._append_packet(data, self._SIGNATURE, binascii.unhexlify(
            macaroon.signature_bytes))
        return bytes(data)
Ejemplo n.º 3
0
 def add_first_party_caveat(self, macaroon, predicate, **kwargs):
     predicate = convert_to_bytes(predicate)
     caveat = Caveat(caveat_id=convert_to_bytes(predicate))
     macaroon.caveats.append(caveat)
     encode_key = binascii.unhexlify(macaroon.signature_bytes)
     macaroon.signature = sign_first_party_caveat(encode_key, predicate)
     return macaroon
Ejemplo n.º 4
0
 def verify(self, macaroon, key):
     key = generate_derived_key(convert_to_bytes(key))
     return self.verify_discharge(
         macaroon,
         macaroon,
         key,
     )
Ejemplo n.º 5
0
 def add_third_party_caveat(self,
                            macaroon,
                            location,
                            key,
                            key_id,
                            **kwargs):
     derived_key = truncate_or_pad(
         generate_derived_key(convert_to_bytes(key))
     )
     old_key = truncate_or_pad(binascii.unhexlify(macaroon.signature_bytes))
     box = SecretBox(key=old_key)
     verification_key_id = box.encrypt(
         derived_key, nonce=kwargs.get('nonce')
     )
     caveat = Caveat(
         caveat_id=key_id,
         location=location,
         verification_key_id=verification_key_id
     )
     macaroon.caveats.append(caveat)
     encode_key = binascii.unhexlify(macaroon.signature_bytes)
     macaroon.signature = sign_third_party_caveat(
         encode_key,
         caveat._verification_key_id,
         caveat._caveat_id
     )
     return macaroon
Ejemplo n.º 6
0
 def __init__(self,
              location=None,
              identifier=None,
              key=None,
              caveats=None,
              signature=None):
     self.caveats = caveats or []
     self.location = location or ''
     self.identifier = identifier or ''
     self.signature = signature or ''
     self.first_party_caveat_delegate = FirstPartyCaveatDelegate()
     self.third_party_caveat_delegate = ThirdPartyCaveatDelegate()
     if key:
         self.signature = create_initial_signature(
             convert_to_bytes(key), convert_to_bytes(identifier)
         )
Ejemplo n.º 7
0
def _read_json_binary_field(deserialized, field):
    ''' Read the value of a JSON field that may be string or base64-encoded.
    '''
    val = deserialized.get(field)
    if val is not None:
        return utils.convert_to_bytes(val)
    val = deserialized.get(field + '64')
    if val is None:
        return None
    return utils.raw_urlsafe_b64decode(val)
Ejemplo n.º 8
0
    def deserialize(self, serialized):
        from pymacaroons.macaroon import Macaroon
        from pymacaroons.caveat import Caveat
        from pymacaroons.exceptions import MacaroonDeserializationException

        macaroon = Macaroon()

        decoded = urlsafe_b64decode(convert_to_bytes(
            serialized + "=" * (-len(serialized) % 4)
        ))

        index = 0

        while index < len(decoded):
            packet_length = int(
                struct.unpack(
                    b"4s",
                    decoded[index:index + self.PACKET_PREFIX_LENGTH]
                )[0],
                16
            )
            packet = decoded[
                index + self.PACKET_PREFIX_LENGTH:index + packet_length
            ]

            key, value = self._depacketize(packet)

            if key == b'location':
                macaroon.location = value
            elif key == b'identifier':
                macaroon.identifier = value
            elif key == b'cid':
                macaroon.caveats.append(Caveat(caveat_id=value))
            elif key == b'vid':
                macaroon.caveats[-1].verification_key_id = value
            elif key == b'cl':
                macaroon.caveats[-1].location = value
            elif key == b'signature':
                macaroon.signature = binascii.hexlify(value)
            else:
                raise MacaroonDeserializationException(
                    'Key {key} not valid key for this format. '
                    'Value: {value}'.format(
                        key=key, value=value
                    )
                )

            index = index + packet_length

        return macaroon
Ejemplo n.º 9
0
 def __init__(self,
              location=None,
              identifier=None,
              key=None,
              caveats=None,
              signature=None,
              version=MACAROON_V1):
     if version > MACAROON_V2:
         version = MACAROON_V2
     self._version = version
     self.caveats = caveats or []
     self.location = location or ''
     self.identifier = identifier or ''
     self.signature = signature or ''
     self.first_party_caveat_delegate = FirstPartyCaveatDelegate()
     self.third_party_caveat_delegate = ThirdPartyCaveatDelegate()
     if key:
         self.signature = create_initial_signature(
             convert_to_bytes(key), self.identifier_bytes
         )
Ejemplo n.º 10
0
 def caveat_id(self, value):
     self._caveat_id = convert_to_bytes(value)
Ejemplo n.º 11
0
 def decrypt(self, signature, field_data):
     key = truncate_or_pad(signature)
     box = SecretBox(key=key)
     encoded = convert_to_bytes(field_data[len(self.signifier):])
     decrypted = box.decrypt(standard_b64decode(encoded))
     return convert_to_string(decrypted)
Ejemplo n.º 12
0
 def encrypt(self, signature, field_data):
     encrypt_key = truncate_or_pad(signature)
     box = SecretBox(key=encrypt_key)
     encrypted = box.encrypt(convert_to_bytes(field_data), nonce=self.nonce)
     return self._signifier + standard_b64encode(encrypted)
Ejemplo n.º 13
0
 def signifier(self, string_or_bytes):
     self._signifier = convert_to_bytes(string_or_bytes)
Ejemplo n.º 14
0
 def signifier(self):
     return convert_to_bytes(self._signifier)
Ejemplo n.º 15
0
 def location(self, string_or_bytes):
     self._location = convert_to_bytes(string_or_bytes)
Ejemplo n.º 16
0
 def identifier(self, string_or_bytes):
     self._identifier = convert_to_bytes(string_or_bytes)
Ejemplo n.º 17
0
 def location(self, value):
     self._location = convert_to_bytes(value)
Ejemplo n.º 18
0
 def _signatures_match(self, macaroon_signature, computed_signature):
     return constant_time_compare(
         convert_to_bytes(macaroon_signature),
         convert_to_bytes(computed_signature)
     )
Ejemplo n.º 19
0
 def location(self, value):
     self._location = convert_to_bytes(value)
Ejemplo n.º 20
0
 def verification_key_id(self, value):
     self._verification_key_id = convert_to_bytes(value)
Ejemplo n.º 21
0
 def caveat_id(self, value):
     self._caveat_id = convert_to_bytes(value)
Ejemplo n.º 22
0
 def verification_key_id(self, value):
     self._verification_key_id = convert_to_bytes(value)
Ejemplo n.º 23
0
 def location(self, string_or_bytes):
     self._location = convert_to_bytes(string_or_bytes)
from mock import *
from nose.tools import *
from hypothesis import assume, given, strategy
from hypothesis.specifiers import one_of, sampled_from

from six import text_type, binary_type
from pymacaroons import Macaroon, Verifier
from pymacaroons.utils import convert_to_bytes


ascii_text_strategy = strategy(
    [sampled_from(map(chr, range(0, 128)))]
).map(lambda c: ''.join(c))

ascii_bin_strategy = strategy(ascii_text_strategy).map(
    lambda s: convert_to_bytes(s)
)


class TestMacaroon(object):

    def setup(self):
        pass

    @given(
        key_id=one_of((ascii_text_strategy, ascii_bin_strategy)),
        loc=one_of((ascii_text_strategy, ascii_bin_strategy)),
        key=one_of((ascii_text_strategy, ascii_bin_strategy))
    )
    def test_serializing_deserializing_macaroon(self, key_id, loc, key):
        assume(key_id and loc and key)
Ejemplo n.º 25
0
 def signature(self, string_or_bytes):
     self._signature = convert_to_bytes(string_or_bytes)
Ejemplo n.º 26
0
 def _signatures_match(self, macaroon_signature, computed_signature):
     return constant_time_compare(
         convert_to_bytes(macaroon_signature),
         convert_to_bytes(computed_signature)
     )