ó 9(Zc@s2dZddlZddlZddlZddlZddlmZmZmZm Z ddl m Z m Z ddl ZddlmZddlmZejeƒZd„Zd„Zd „Zd „Zd efd „ƒYZd „Zy eZWnek rej ZnXd„Z!d„Z"d„Z#dS(s0Helper utility functions for AWS Encryption SDK.iÿÿÿÿN(tActionNotAllowedErrortInvalidDataKeyErrortSerializationErrortUnknownIdentityError(tContentAADStringt ContentType(tto_bytes(tEncryptedDataKeycCs|dkrtjStjSdS(sëReturns the appropriate content type based on the frame length. :param int frame_length: Message frame length :returns: Appropriate content type based on frame length :rtype: aws_encryption_sdk.identifiers.ContentType iN(Rt NO_FRAMINGt FRAMED_DATA(t frame_length((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pyt content_type s cCs†|dks"||jjdkrCtdjd|jjƒƒ‚n|tjjjkr‚tdjd|dtjjjƒƒ‚ndS(sÖValidates that frame length is within the defined limits and is compatible with the selected algorithm. :param int frame_length: Frame size in bytes :param algorithm: Algorithm to use for encryption :type algorithm: aws_encryption_sdk.identifiers.Algorithm :raises SerializationError: if frame size is negative or not a multiple of the algorithm block size :raises SerializationError: if frame size is larger than the maximum allowed frame size isbFrame size must be a non-negative multiple of the block size of the crypto algorithm: {block_size}t block_sizes%Frame size too large: {frame} > {max}tframetmaxN(tencryption_algorithmR Rtformattaws_encryption_sdktinternaltdefaultstMAX_FRAME_SIZE(R t algorithm((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pytvalidate_frame_length-s "  cCstjtjjjƒS(sLGenerates a new message ID. :returns: Message ID :rtype: bytes (tosturandomRRRtMESSAGE_ID_LENGTH(((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pyt message_idCscCsX|tjkrtj}n9|tjkrH|r<tj}qTtj}n tdƒ‚|S(s¬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 sUnhandled content type(RRRtNON_FRAMED_STRING_IDR tFINAL_FRAME_STRING_IDtFRAME_STRING_IDR(R tis_final_frametaad_content_string((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pytget_aad_content_stringLs     tROStreamcBs)eZdZd„Zd„Zd„ZRS(s¶Provides a read-only interface on top of a stream object. Used to provide MasterKeyProviders with read-only access to plaintext. :param source_stream: File-like object cCs||_|jƒdS(sPrepares the passthroughs.N(t_source_streamt_duplicate_api(tselft source_stream((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pyt__init__js cCsƒtgt|jƒD]}|jdƒs|^qƒ}tt|ƒƒ}x3|j|ƒD]"}t||t|j|ƒƒqYWdS(s,Maps the source stream API onto this object.t_N(tsettdirR"t startswitht differencetsetattrtgetattr(R$tmethodtsource_attributestself_attributest attribute((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pyR#os cCstdƒ‚dS(sSBlocks calls to write. :raises ActionNotAllowedError: when called s%Write not allowed on ROStream objectsN(R(R$tb((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pytwriteys(t__name__t __module__t__doc__R&R#R3(((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pyR!bs  c CsÇtƒ}d}|j||ƒ}tjd|jƒx†|D]~}||kr{td|jd|jƒ}|j|ƒq;n|j d|d|d|ƒ}|j|ƒtjd|jƒq;W||fS( s*Prepares a DataKey to be used for encrypting message and list of EncryptedDataKey objects to be serialized into header. :param primary_master_key: Master key with which to generate the encryption data key :type primary_master_key: aws_encryption_sdk.key_providers.base.MasterKey :param master_keys: All master keys with which to encrypt data keys :type master_keys: list of :class:`aws_encryption_sdk.key_providers.base.MasterKey` :param algorithm: Algorithm to use for encryption :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to use when generating data key :rtype: tuple containing :class:`aws_encryption_sdk.structures.DataKey` and set of :class:`aws_encryption_sdk.structures.EncryptedDataKey` s-encryption data generated with master key: %st key_providertencrypted_data_keytdata_keyRtencryption_contexts,encryption key encrypted with master key: %sN( R(tNonetgenerate_data_keyt_LOGGERtdebugR7RR8taddtencrypt_data_key( tprimary_master_keyt master_keysRR:tencrypted_data_keystencrypted_data_encryption_keytdata_encryption_keyt master_keyt encrypted_key((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pytprepare_data_keyss$         cCs5t|ttjtjfƒr"|Stjt|ƒƒS(sÿTakes an input str, bytes, io.IOBase, or file object and returns an appropriate stream for _EncryptionStream objects. :param data: Input data :type data: str, bytes, io.IOBase, or file :returns: Prepared stream :rtype: io.BytesIO (t isinstancet _FILE_TYPEtiotIOBasetsixtStringIOtBytesIOR(tdata((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pytprep_stream_data¬s cCsIt|jƒ|jkrEtdjdt|jƒd|jƒƒ‚ndS(snValidates that the supplied source_data_key's data_key is the correct length for the supplied algorithm's kdf_input_len value. :param source_data_key: Source data key object received from MasterKey decrypt or generate data_key methods :type source_data_key: :class:`aws_encryption_sdk.structures.RawDataKey` or :class:`aws_encryption_sdk.structures.DataKey` :param algorithm: Algorithm object which directs how this data key will be used :type algorithm: aws_encryption_sdk.identifiers.Algorithm :raises InvalidDataKeyError: if data key length does not match required kdf input length sJInvalid Source Data Key length {actual} for algorithm required: {required}tactualtrequiredN(tlenR9t kdf_input_lenRR(tsource_data_keyR((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pytsource_data_key_length_checkºs  cCs-|dkrd}n |d7}||7}|S(sèAdds a suffix to the provided user agent. :param str user_agent: Existing user agent (None == not yet defined) :param str suffix: Desired suffix to add to user agent :returns: User agent with suffix :rtype: str tt N(R;(t user_agenttsuffix((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pytextend_user_agent_suffixÌs     ($R6RKtloggingRRMtaws_encryption_sdk.exceptionsRRRRtaws_encryption_sdk.identifiersRRt$aws_encryption_sdk.internal.defaultsRt#aws_encryption_sdk.internal.str_opsRtaws_encryption_sdk.structuresRt getLoggerR4R=R RRR tobjectR!RHtfileRJt NameErrorRLRQRWR\(((sM/tmp/pip-build-wDUJoH/aws-encryption-sdk/aws_encryption_sdk/internal/utils.pyt s.    "    %