U
    %Y01                     @   s   d dl mZ d dlZd dlmZ d dlZd dlZd dlZd dlm	Z	 d dl
mZmZmZ d dlmZ d dlmZ edd	d
gZG dd deZdd Zejjdkrdd Zndd Zdd ZdS )    )unicode_literalsN)
namedtuple)urlsafe_b64encode)convert_to_bytesconvert_to_stringraw_b64decode)BaseSerializer)MacaroonSerializationExceptionPacketV2
field_typedatac                   @   s   e Zd ZdZdZdZdZdZdZdd Z	dd	 Z
d
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd!ddZdd Zdd  ZdS )"BinarySerializer            r   c                 C   s   t | |ddS )Nascii=)r   serialize_rawdecoderstrip)selfmacaroon r   K/usr/lib/python3/dist-packages/pymacaroons/serializers/binary_serializer.py	serialize   s    zBinarySerializer.serializec                 C   s*   ddl m} |j|kr | |S | |S )Nr   )MACAROON_V1)pymacaroons.macaroonr   version_serialize_v1_serialize_v2)r   r   r   r   r   r   r   #   s    

zBinarySerializer.serialize_rawc                 C   s   |  d|j}||  d|j7 }|jD ]F}||  d|j7 }|jr&|jr&||  d|j7 }||  d|j7 }q&||  dt|j	7 }|S )N   location
   identifier   cid   vid   cl	   signature)

_packetizelocation
identifiercaveatsZ
_caveat_idZ_verification_key_idZ	_locationbinascii	unhexlifysignature_bytes)r   r   ZcombinedZcaveatr   r   r   r   )   s    
 
zBinarySerializer._serialize_v1c                 C   s   ddl m} t }|| |jd k	rN| || jt|j | || j|j	 | || j
 |jD ]d}|jd k	r| || jt|j | || j|j |jd k	r| || jt|j | || j
 qb| || j
 | || jt|j t|S )Nr   MACAROON_V2)r   r/   	bytearrayappendr(   _append_packet	_LOCATIONr   _IDENTIFIERZidentifier_bytes_EOSr*   Zcaveat_id_bytesverification_key_id_VID
_SIGNATUREr+   r,   r-   bytes)r   r   r/   r   cr   r   r   r    ;   s6    






zBinarySerializer._serialize_v2c                 C   s.   t |dkrtdt|}t|}| |S )Nr   zempty macaroon)len
ValueErrorr   r   deserialize_raw)r   
serializeddecodedr   r   r   deserializeU   s
    zBinarySerializer.deserializec                 C   sZ   ddl m} ddlm} t|d d }||kr<| |S t|rN| |S |dd S )Nr   r.    MacaroonDeserializationExceptionr   z7cannot determine data format of binary-encoded macaroon)	r   r/   pymacaroons.exceptionsrB   sixZbyte2int_deserialize_v2_is_ascii_hex_deserialize_v1)r   r>   r/   rB   firstr   r   r   r=   \   s    

z BinarySerializer.deserialize_rawc                 C   s.  ddl m}m} ddlm} ddlm} ||d}d}|t|k r*tt	
d|||| j  d d}||| j ||  }	| |	\}
}|
dkr||_n|
d	kr||_nt|
d
kr|j|||d nV|
dkr||jd _n@|
dkr||jd _n*|
dkrt||_n|dj|
|d|| }q6|S )Nr   )Macaroonr   CaveatrA   r   s   4s   r!   r"   r#   )	caveat_idr   r$   r%   r&   z7Key {key} not valid key for this format. Value: {value})keyvalue)r   rI   r   pymacaroons.caveatrK   rC   rB   r;   intstructZunpackPACKET_PREFIX_LENGTH_depacketizer(   r)   r*   r1   r6   r+   hexlify	signatureformat)r   r?   rI   r   rK   rB   r   indexZpacket_lengthpacketrP   rQ   r   r   r   rG   h   sT    
 


 
z BinarySerializer._deserialize_v1c                 C   s  ddl m}m} ddlm} ddlm} |dd  }| |\}}d}t|dkr~|d j	| j
kr~|d jd}|dd  }t|dks|d j	| jkr|d||d j||d	}| |\}	}|	}t|dkrؐq||d
}
t|dkr |d j	| j
kr |d jd|
_|dd  }t|dks@|d j	| jkrH|d|d j|
_|dd  }t|dkr|
jd k	r|d|j|
 qt|dkr|d|d j	| jkr|d|d j|
_|j|
 q| |\}}|j	| jkr|dt|j|_|S )Nr   )rI   r/   rJ   rA   r    zutf-8zinvalid macaroon header)r)   r(   r   rL   zno identifier in caveatz*location not allowed in first party caveatzextra fields found in caveatzinvalid field found in caveatz+unexpected field found instead of signature)r   rI   r/   rR   rK   rC   rB   _parse_section_v2r;   r   r3   r   r   r4   r(   rN   r*   r1   r7   r6   _parse_packet_v2r8   r+   rW   rX   )r   r>   rI   r/   rK   rB   ZsectionZlocr   restZcavr[   r   r   r   rE      sl    
  z BinarySerializer._deserialize_v2c                 C   s   | j d t| t| }t|dd  }|dkrFtdj|||d|dd}|d t| d }t	td	t| ||}|S )
Nr   i  ztPacket too long for serialization. Max length is 0xFFFF (65535). Packet length: 0x{hex_length} ({length}) Key: {key})rP   Z
hex_lengthZlengthr   r          
z4s%ds)
rU   r;   hexr	   rY   zfillencoder   rT   Zpack)r   rP   r   Zpacket_sizeZpacket_size_hexheaderZpacket_contentr[   r   r   r   r'      s$    zBinarySerializer._packetizec                 C   s*   | dd }|t|d d }||fS )Nr`   r   r   rO   )splitr;   )r   r[   rP   rQ   r   r   r   rV      s    zBinarySerializer._depacketizeNc                 C   s0   t || || jkr,t |t| || d S )N)_encode_uvarintr5   r;   extend)r   r   r   Zpacket_datar   r   r   r2      s    

zBinarySerializer._append_packetc                 C   sv   ddl m} d}g }t|dkr(|d| |\}}|j| jkrJ||fS |j|kr\|d|| |j}|}qdS )z Parses a sequence of packets in data.

        The sequence is terminated by a packet with a field type of EOS
        :param data bytes to be deserialized.
        :return: the rest of data and an array of packet V2
        r   rA   rO   z"section extends past end of bufferzfields out of orderN)rC   rB   r;   r^   r   r5   r1   )r   r   rB   Zprev_field_typeZpacketsr_   r[   r   r   r   r]      s    

z"BinarySerializer._parse_section_v2c                 C   s   ddl m} t|\}}||d }|| jkr<|t|dfS t|\}}||d }|t|krh|d||d t||d| fS )aQ   Parses a V2 data packet at the start of the given data.

        The format of a packet is as follows:

        field_type(varint) payload_len(varint) data[payload_len bytes]

        apart from EOS which has no payload_en or data (it's a single zero
        byte).

        :param data:
        :return: rest of data, PacketV2
        r   rA   Nz%field data extends past end of buffer)rC   rB   _decode_uvarintr5   r
   r;   )r   r   rB   ZftnZpayload_lenr   r   r   r^     s    
z!BinarySerializer._parse_packet_v2)N)__name__
__module____qualname__rU   r3   r4   r7   r8   r5   r   r   r   r    r@   r=   rG   rE   r'   rV   r2   r]   r^   r   r   r   r   r      s&   0;
r   c                 C   sH   |dk rt d|d@ }|dL }|dkr4| | qD| |dB  qdS )z7 Encodes integer into variable-length format into data.r   zonly support positive integer         N)r<   r1   )r   rj   Z	this_byter   r   r   rg   -  s    
rg   r   c                 C   sf   d}d}d}| D ]H}t |}|d7 }|dk r@|||> B |f  S ||d@ |> O }|d7 }qtddS z Decode a variable -length integer.

        Reads a sequence of unsigned integer byte and decodes them into an
        integer in variable-length format and returns it and the length read.
        r   r   rp   rn   ro   zcannot read uvarint from bufferN)ord	Exceptionr   rj   shiftibr   r   r   ri   ;  s    
ri   c                 C   s^   d}d}d}| D ]@}|d7 }|dk r8|||> B |f  S ||d@ |> O }|d7 }qt ddS rq   )rs   rt   r   r   r   ri   M  s    
c                 C   sL   t d|   krt dkr$n ndS t d|   kr@t dkrHn ndS dS )N09TafF)rr   )rw   r   r   r   rF   _  s
      rF   )Z
__future__r   r+   collectionsr   rD   rT   sysbase64r   Zpymacaroons.utilsr   r   r   Z'pymacaroons.serializers.base_serializerr   rC   r	   r
   r   rg   version_infomajorri   rF   r   r   r   r   <module>   s$     
