def test_teestream_full(): new_tee = io.BytesIO() test_tee = TeeStream(data(), new_tee) raw_read = test_tee.read() assert data().getvalue() == raw_read == new_tee.getvalue()
def deserialize_header(stream): # type: (IO) -> MessageHeader """Deserializes the header from a source stream :param stream: Source data stream :type stream: io.BytesIO :returns: Deserialized MessageHeader object :rtype: :class:`aws_encryption_sdk.structures.MessageHeader` and bytes :raises NotSupportedError: if unsupported data types are found :raises UnknownIdentityError: if unknown data types are found :raises SerializationError: if IV length does not match algorithm """ _LOGGER.debug("Starting header deserialization") tee = io.BytesIO() tee_stream = TeeStream(stream, tee) version_id, message_type_id = unpack_values(">BB", tee_stream) header = dict() header["version"] = _verified_version_from_id(version_id) header["type"] = _verified_message_type_from_id(message_type_id) algorithm_id, message_id, ser_encryption_context_length = unpack_values( ">H16sH", tee_stream) header["algorithm"] = _verified_algorithm_from_id(algorithm_id) header["message_id"] = message_id header["encryption_context"] = deserialize_encryption_context( tee_stream.read(ser_encryption_context_length)) header["encrypted_data_keys"] = _deserialize_encrypted_data_keys( tee_stream) (content_type_id, ) = unpack_values(">B", tee_stream) header["content_type"] = _verified_content_type_from_id(content_type_id) (content_aad_length, ) = unpack_values(">I", tee_stream) header["content_aad_length"] = _verified_content_aad_length( content_aad_length) (iv_length, ) = unpack_values(">B", tee_stream) header["header_iv_length"] = _verified_iv_length(iv_length, header["algorithm"]) (frame_length, ) = unpack_values(">I", tee_stream) header["frame_length"] = _verified_frame_length(frame_length, header["content_type"]) return MessageHeader(**header), tee.getvalue()
def deserialize_header(stream, max_encrypted_data_keys=None): # type: (IO, Union[int, None]) -> MessageHeader """Deserializes the header from a source stream :param stream: Source data stream :type stream: io.BytesIO :param max_encrypted_data_keys: Maximum number of encrypted keys to deserialize :type max_encrypted_data_keys: None or positive int :returns: Deserialized MessageHeader object :rtype: :class:`aws_encryption_sdk.structures.MessageHeader` and bytes :raises NotSupportedError: if unsupported data types are found :raises UnknownIdentityError: if unknown data types are found :raises SerializationError: if IV length does not match algorithm """ _LOGGER.debug("Starting header deserialization") tee = io.BytesIO() tee_stream = TeeStream(stream, tee) (version_id, ) = unpack_values(">B", tee_stream) version = _verified_version_from_id(version_id) header = {} header["version"] = version if version == SerializationVersion.V1: return _deserialize_header_v1(header, tee_stream, max_encrypted_data_keys), tee.getvalue() elif version == SerializationVersion.V2: return _deserialize_header_v2(header, tee_stream, max_encrypted_data_keys), tee.getvalue() else: raise NotSupportedError( "Unrecognized message format version: {}".format(version))
def deserialize_header(stream): """Deserializes the header from a source stream :param stream: Source data stream :type stream: io.BytesIO :returns: Deserialized MessageHeader object :rtype: :class:`aws_encryption_sdk.structures.MessageHeader` and bytes :raises NotSupportedError: if unsupported data types are found :raises UnknownIdentityError: if unknown data types are found :raises SerializationError: if IV length does not match algorithm """ _LOGGER.debug('Starting header deserialization') tee = io.BytesIO() tee_stream = TeeStream(stream, tee) version_id, message_type_id = unpack_values('>BB', tee_stream) try: message_type = ObjectType(message_type_id) except ValueError as error: raise NotSupportedError( 'Unsupported type {} discovered in data stream'.format( message_type_id), error) try: version = SerializationVersion(version_id) except ValueError as error: raise NotSupportedError('Unsupported version {}'.format(version_id), error) header = {'version': version, 'type': message_type} algorithm_id, message_id, ser_encryption_context_length = unpack_values( '>H16sH', tee_stream) try: alg = Algorithm.get_by_id(algorithm_id) except KeyError as error: raise UnknownIdentityError('Unknown algorithm {}'.format(algorithm_id), error) if not alg.allowed: raise NotSupportedError('Unsupported algorithm: {}'.format(alg)) header['algorithm'] = alg header['message_id'] = message_id header['encryption_context'] = deserialize_encryption_context( tee_stream.read(ser_encryption_context_length)) (encrypted_data_key_count, ) = unpack_values('>H', tee_stream) encrypted_data_keys = set([]) for _ in range(encrypted_data_key_count): (key_provider_length, ) = unpack_values('>H', tee_stream) (key_provider_identifier, ) = unpack_values( '>{}s'.format(key_provider_length), tee_stream) (key_provider_information_length, ) = unpack_values('>H', tee_stream) (key_provider_information, ) = unpack_values( '>{}s'.format(key_provider_information_length), tee_stream) (encrypted_data_key_length, ) = unpack_values('>H', tee_stream) encrypted_data_key = tee_stream.read(encrypted_data_key_length) encrypted_data_keys.add( EncryptedDataKey(key_provider=MasterKeyInfo( provider_id=to_str(key_provider_identifier), key_info=key_provider_information), encrypted_data_key=encrypted_data_key)) header['encrypted_data_keys'] = encrypted_data_keys (content_type_id, ) = unpack_values('>B', tee_stream) try: content_type = ContentType(content_type_id) except ValueError as error: raise UnknownIdentityError( 'Unknown content type {}'.format(content_type_id), error) header['content_type'] = content_type (content_aad_length, ) = unpack_values('>I', tee_stream) if content_aad_length != 0: raise SerializationError( 'Content AAD length field is currently unused, its value must be always 0' ) header['content_aad_length'] = 0 (iv_length, ) = unpack_values('>B', tee_stream) if iv_length != alg.iv_len: raise SerializationError( 'Specified IV length ({length}) does not match algorithm IV length ({alg})' .format(length=iv_length, alg=alg)) header['header_iv_length'] = iv_length (frame_length, ) = unpack_values('>I', tee_stream) if content_type == ContentType.FRAMED_DATA and frame_length > MAX_FRAME_SIZE: raise SerializationError( 'Specified frame length larger than allowed maximum: {found} > {max}' .format(found=frame_length, max=MAX_FRAME_SIZE)) elif content_type == ContentType.NO_FRAMING and frame_length != 0: raise SerializationError( 'Non-zero frame length found for non-framed message') header['frame_length'] = frame_length return MessageHeader(**header), tee.getvalue()