def _verified_content_type_from_id(content_type_id): # type: (int) -> ContentType """Load a message :class:`ContentType` for the specified content type ID. :param int content_type_id: Content type ID :return: Message content type :rtype: ContentType :raises UnknownIdentityError: if unknown content type ID is received """ try: return ContentType(content_type_id) except ValueError as error: raise UnknownIdentityError("Unknown content type {}".format(content_type_id), error)
def _verified_algorithm_from_id(algorithm_id): # type: (int) -> AlgorithmSuite """Load a message :class:`AlgorithmSuite` for the specified algorithm suite ID. :param int algorithm_id: Algorithm suite ID :return: Algorithm suite :rtype: AlgorithmSuite :raises UnknownIdentityError: if unknown algorithm ID is received :raises NotSupportedError: if unsupported algorithm ID is received """ try: algorithm_suite = AlgorithmSuite.get_by_id(algorithm_id) except KeyError as error: raise UnknownIdentityError("Unknown algorithm {}".format(algorithm_id), error) if not algorithm_suite.allowed: raise NotSupportedError("Unsupported algorithm: {}".format(algorithm_suite)) return algorithm_suite
def get_aad_content_string(content_type, is_final_frame): """Prepares the appropriate Body AAD Value for a message body. :param content_type: Defines the type of content for which to prepare AAD String :type content_type: aws_encryption_sdk.identifiers.ContentType :param bool is_final_frame: Boolean stating whether this is the final frame in a body :returns: Appropriate AAD Content String :rtype: bytes :raises UnknownIdentityError: if unknown content type """ if content_type == ContentType.NO_FRAMING: aad_content_string = ContentAADString.NON_FRAMED_STRING_ID elif content_type == ContentType.FRAMED_DATA: if is_final_frame: aad_content_string = ContentAADString.FINAL_FRAME_STRING_ID else: aad_content_string = ContentAADString.FRAME_STRING_ID else: raise UnknownIdentityError('Unhandled content type') return aad_content_string
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()