Ejemplo n.º 1
0
    def Decrypt(self, input_bytes):
        """
    Decrypts the given ciphertext.

    @param input_bytes: raw byte string formatted as Header|IV|Ciph|Sig where
      Sig is the signature over the entire payload (Header|IV|Ciph).
    @type input_bytes: string

    @return: plaintext message
    @rtype: string

    @raise ShortCiphertextError: if the ciphertext is too short to have IV & Sig
    @raise InvalidSignatureError: if the signature doesn't correspond to payload
    """
        data_bytes = input_bytes[keyczar.HEADER_SIZE:]  # remove header
        if len(data_bytes) < self.block_size + util.HLEN:  # IV + sig
            raise errors.ShortCiphertextError(len(data_bytes))

        iv_bytes = data_bytes[:self.
                              block_size]  # first block of bytes is the IV
        ciph_bytes = data_bytes[self.block_size:-util.HLEN]
        sig_bytes = data_bytes[-util.HLEN:]  # last 20 bytes are sig
        if not self.hmac_key.Verify(input_bytes[:-util.HLEN], sig_bytes):
            raise errors.InvalidSignatureError()

        plain = AES.new(self.key_bytes, AES.MODE_CBC,
                        iv_bytes).decrypt(ciph_bytes)
        return self._UnPad(plain)
Ejemplo n.º 2
0
def handle_request(ip, request):
    if request.get('version') != '1':
        raise errors.UnsupportedVersionError()

    if request.get('api_key') not in settings.API_KEYS:
        raise errors.InvalidAPIKeyError()

    if not is_nonce_ok(request):
        raise errors.InvalidNonceError()

    if not is_signature_ok(request):
        raise errors.InvalidSignatureError()

    if not is_timestamp_ok(request):
        raise errors.InvalidTimestampError()

    if request.get('request') not in REQUEST_TABLE:
        raise errors.InvalidRequestError()

    if not is_request_authorized(request):
        raise errors.UnauthorizedRequestError()

    if not is_ip_authorized(ip, request):
        raise errors.UnauthorizedIPAddressError(ip)

    return dispatch_request(ip, request)
Ejemplo n.º 3
0
    def read(self, chars=-1):
        """ 
    Decrypts data from the source stream and returns the resulting plaintext.
    NOTE: the signature validation is performed on the final read if sufficient
    data is available. Streaming => it isn't possible to validate up front as
    done by Decrypt().

    @param chars: indicates the number of characters to read from the stream.
    read() will never return more than chars characters, but it might return
    less, if there are not enough characters available.
    @type chars: integer

    @raise ShortCiphertextError: if the ciphertext is too short to have IV & Sig
    @raise InvalidSignatureError: if the signature doesn't correspond to payload
    @raise KeyNotFoundError: if key specified in header doesn't exist
    @raise ValueError: if stream closed
    """
        self.__CheckOpen('read')
        is_data_avail = True
        if not self.__key:
            is_data_avail = self.__CreateKey()

        if is_data_avail and self.__key and not self.__cipher:
            is_data_avail = self.__CreateCipher()

        if is_data_avail and self.__key and self.__cipher:
            data_to_decrypt = ''
            need_more_data = True
            while need_more_data:
                read_bytes, is_data_avail = self.__ReadBytes(
                    self.__key.block_size, block=False)
                if read_bytes:
                    self.__encrypted_buffer += read_bytes

                reserved_data_len = util.HLEN
                if is_data_avail:
                    reserved_data_len += self.__key.block_size

                available_data = self.__encrypted_buffer[:-reserved_data_len]

                if is_data_avail:
                    no_decrypt_len = len(
                        available_data) % self.__key.block_size
                else:
                    no_decrypt_len = 0
                # slicing with [:-0] does not work!
                if no_decrypt_len:
                    data_to_decrypt = available_data[:-no_decrypt_len]
                else:
                    data_to_decrypt = available_data

                need_more_data = (is_data_avail and not data_to_decrypt)

            if data_to_decrypt:
                self.__hmac_stream.Update(data_to_decrypt)
                self.__encrypted_buffer = self.__encrypted_buffer[
                    len(data_to_decrypt):]
                decrypted_data = self.__cipher.decrypt(data_to_decrypt)
                if not is_data_avail:
                    decrypted_data = self.__key._UnPad(decrypted_data)

                self.__decrypted_buffer += decrypted_data

                if not is_data_avail:
                    if len(self.__encrypted_buffer) != util.HLEN:
                        raise errors.ShortCiphertextError(
                            len(self.__encrypted_buffer))
                    current_sig_bytes = self.__hmac_stream.Sign()
                    msg_sig_bytes = self.__encrypted_buffer
                    self.__encrypted_buffer = ''
                    if not self.__key.hmac_key.VerifySignedData(
                            current_sig_bytes, msg_sig_bytes):
                        raise errors.InvalidSignatureError()

        if chars < 0:
            result = self.__decrypted_buffer
            self.__decrypted_buffer = ''
        else:
            result = self.__decrypted_buffer[:chars]
            self.__decrypted_buffer = self.__decrypted_buffer[chars:]

        if not result and is_data_avail:
            result = None

        return result