a fTO@s ddlZddlZddlZddlZddlmZddlmZddlm Z m Z ddl m Z ddl mZmZddlmZmZddlmZmZmZdd lmZmZmZmZdd lmZdd lmZe e!d d dZ"e"Z#ddZ$ddZ%GdddeZ&GdddeZ'ddZ(dS)N)six)default_backend)Ciphermodes)Lock)serialize_headerdeserialize_header_from_stream)EncryptedDataHeader$EncryptedDataHeaderDataEncryptionKey)DEFAULT_MAX_GCM_ENCRYPTION_SIZEDEFAULT_ALGORITHM$DEFAULT_MAX_ENCRYPTION_SIZE_SENTINEL)convert_to_bytesconvert_to_strgenerate_random_iv$convert_encryption_context_to_string) Algorithm)CryptoResultStreamcCsfd}t|tkrVd}t|}|t}|||}t|dkr>qb||j|d7}|}qn |j|d}|S)Nr)data)len2MAX_ENCRYPTOR_DECRYPTOR_UPDATE_CHUNK_SIZE_IN_BYTES memoryviewupdate)Zcryptorrresult start_indexmemviewZ end_indexZ next_datar E/usr/lib/python3.9/site-packages/oci/encryption/internal/streaming.py_update_cryptor_with_data(s    r"c Cs&|dur dSt|tstdg}g}g}t|D]n\}}ttkrNt|tsZt|tjsf||n| drz||ttkrt|tst|tjs4||q4|s|rtd t|t||rt d t|zt |Wn8t y }zt d t|WYd}~n d}~00dS)Nz!encryption_context must be a dictzoci-zjencryption_context must be a dict with string keys and string values. Invalid keys: {}. Invalid values: {}zKencryption_context cannot contain keys with prefix 'oci-'. Invalid keys: {}z7encryption_context must be JSON serializable. Error: {}) isinstancedict TypeErrorrZ iteritemsstrbytesZ string_typesappend startswithformat ValueErrorjsondumps)encryption_contextZ invalid_keysZinvalid_valuesZinvalid_prefix_keyskeyvalueer r r!_validate_encryption_context<s@       r2c@s\eZdZedfddZddZddZdd Zd d Zd d Z ddZ ddZ dddZ dS)StreamEncryptorNcCst|_||_|jstd|j|j|_||_t|||_ t t ||_ t |jj|_t|j|jj|j|jtd}||_d|_|tur|jjjtjjkrt|_qtdt|jn |durt|tst d||_d|_!d|_"d|_#d|_$d|_%t&|_'d|_(dS) a Provides a stream that wraps 'stream_to_encrypt' and allows reading data from the underlying stream encrypted under the provided master key. :param int max_encryption_size: (optional) Max number of bytes able to be encrypted by this StreamEncryptor. The default value differs based on the algorithm used. For GCM (the default algorithm) the default value is 2147483647 bytes. This is provided mainly for use with authenticated encryption algorithms that require verification of an authentication tag upon decryption. Because decrypting using these algorithms will buffer the entire payload into memory before returning it, this max_encryption_size provides a sanity check against encrypting payloads too large to decrypt. This is possible because encryption does not require holding the entire payload in memory. The 2147483647 byte limit was chosen because that is the maximum number of bytes that can be encrypted or decrypted by the OCI Java SDK. This is to avoid users accidentally encrypting payloads in Python that cannot be decrypted in Java. Explicitly passing this value as None will disable the size check and allow encrypting payloads up to the maximum size supported by the algorithm. :param dict encryption_context: (optional) Optional additional data to be provided as input to authenticated encryption algorithms. This must be a dict with keys that are strings and values that are strings. Keys may NOT match the prefix oci-* as that namespace is reserved for OCI internal keys that may be added to the AAD. zNmaster_key_provider must contain a primary master key in order to encrypt data algorithmmodeZbackendNz#Unrecognized algorithm provided: {}z/argument max_encryption_size must be an integerrrF))r _algorithmZget_primary_master_key_primary_master_keyr+Zgenerate_data_encryption_key_data_encryption_key_stream_to_encryptr2_encryption_contextrr_encryption_context_bytesrZiv_lenivrr5Zplaintext_key_bytesr6r encryptor_max_encryption_sizer namerZGCMr r*r&r#intr%_header_content_buffer_bytes_written_total_bytes_written_excluding_header _finalizedr_lock_closed)selfmaster_key_providerZstream_to_encryptZmax_encryption_sizer.cipherr r r!__init__hsL     zStreamEncryptor.__init__cCsFt|j|jj|jj|jjdg}t||j|j j |j d}t |dS)N) master_key_idvault_idregionencrypted_data_key_bytes)encrypted_data_keysiv_bytes algorithm_id#additional_authenticated_data_bytes)encrypted_data_header) r r8Zget_identifierrNrOr9Zencrypted_key_bytesr r=r7idr<r)rIrQrUr r r!_build_header_contents z%StreamEncryptor._build_header_contentcCs>|jdtj}|jdtj|j}|j|||S)Nr)r:seekosSEEK_CURSEEK_ENDtell)rIZcur_poslengthr r r!=_get_bytes_remaining_in_stream_to_encrypt_using_seek_and_tells   zMStreamEncryptor._get_bytes_remaining_in_stream_to_encrypt_using_seek_and_tellcCsx|j|}|dkrNt|jdrNt|jdrNt|jdrN|jrN|j|}|jdurt||jkrttd||jdS)NrXr\seekablezqAttempted to encrypt > _max_encryption_size bytes. Total bytes requested to encrypt: {}. Max encryption size: {}.)rEhasattrr:r`r^r?r+r*)rIsize_of_next_readZ!_total_bytes_requested_to_encryptr r r!_enforce_max_encryption_sizes.  z,StreamEncryptor._enforce_max_encryption_sizecCs|SNr rIr r r! __enter__szStreamEncryptor.__enter__cCs |dSrdcloserItyper0 tracebackr r r!__exit__szStreamEncryptor.__exit__cCs6|jzd|_d|_W|jn |j0dSNTrrGacquirerHrCreleaserer r r!rhs  zStreamEncryptor.closecCs|jSrd)r;rer r r!get_encryption_contextsz&StreamEncryptor.get_encryption_contextr_c Cs|jz|jrtd|dkr4W|jdS|dk}|jsp||_|j|j7_|jrp|j |j|j |d|j s(|t |jks|r(|rd}n|t |j}d}|rt|j}nt|j|}t |}t|j |}||kp|}|r||j |j j7}d|_ |j|7_|rD|jdd}d|_n|jd|}|j|d|_|jt |7_|jt |jkr|jt |j|_nd|_|j dd|W|jS|j0dS)  Read up to size bytes from the object and return them. As a convenience, if size is unspecified or -1, all bytes until EOF are returned. If 0 bytes are returned, and size was not 0, this indicates end of file. :param int size: (optional) The number of bytes to attempt to read from the underlying stream. :rtype: bytes Cannot read from closed streamrrr_)rbFTN)rGrorHr+rprBrWrCr<r>authenticate_additional_datarcrFrrr:readr"finalizetagrDrE) rIsizeREAD_ALLZsize_to_read_into_bufferZ reached_endZbytes_to_encryptZtotal_bytes_to_encrypt_sizeZ ciphertextoutputr r r!rusn K        zStreamEncryptor.read)r_) __name__ __module__ __qualname__r rLrWr^rcrfrlrhrqrur r r r!r3gs R r3c@sNeZdZddZddZddZddZd d Zd d Zd dZ dddZ dS)StreamDecryptorcCsB||_||_d|_d|_d|_d|_d|_i|_t|_ d|_ dS)a Returns a StreamDecryptor which produces decrypted data based on the underlying stream supplied as 'stream_to_decrypt'. :param oci.encryption.MasterKeyProvider master_key_provider: (required) A MasterKeyProvider to use for decrypting the data. :param stream stream_to_encrypt: (required) The stream to be decrypted. NrF) _stream_to_decrypt_master_key_provider _decryptorr7rC_header_deserializedrFr;rrGrH)rIZstream_to_decryptrJr r r!rL`s zStreamDecryptor.__init__cCs|Srdr rer r r!rfyszStreamDecryptor.__enter__cCs |dSrdrgrir r r!rl|szStreamDecryptor.__exit__cCs6|jzd|_d|_W|jn |j0dSrmrnrer r r!rhs  zStreamDecryptor.closecsfddtD}|s(tdjn |d|_jd}|jj|j|j |j d}| |j }t |}t|j||jjtd}||_tjrttj|_|jjdS)Ncsg|]}j|jkr|qSr )rSrV).0Zalgoheaderr r! rzMStreamDecryptor._init_decryptor_and_header_related_fields..zGCould not decrypt payload encrypted using unrecognized algorithm ID: {}r)rMrNrOr4)rr+r*rSr7rQrZget_master_keyrMrNrOZdecryptrPbase64Z b64decoderr5r6rRrZ decryptorrrrTr,loadsrr;rt)rIrZmatching_algosZencrypted_data_keyZprimary_master_keyZdecrypted_dek_bytesZdek_plaintext_bytesrKr rr!)_init_decryptor_and_header_related_fieldss>       z9StreamDecryptor._init_decryptor_and_header_related_fieldscCs2|js.|jrtdd|_t|j}||dS)NrsT)rrHr+rrr)rIrr r r!_handle_headers  zStreamDecryptor._handle_headercCs6|jz||jW|jS|j0dSrd)rGrorr;rprer r r!rqs  z&StreamDecryptor.get_encryption_contextr_cCs |jz|jrtd|dkr2W|jdS||dk}|jsd|_tt|j }||j j d}|d|j j }t |j |}||j |7}|j|7_|r|jdd}d|_n&|jd|}t|j}||d|_|W|jS|j0dS)rrrsrrr_TN)rGrorHr+rprrFr_read_full_stream_contentrr7Ztag_lenr"rZfinalize_with_tagrCr)rIrxryZbytes_to_decryptrwZdecrypted_datarzrr r r!rus< (   zStreamDecryptor.readN)r_) r{r|r}rLrfrlrhrrrqrur r r r!r~_s ) r~cCs$t|drt|jSt|SdS)Nreadall)rarrru)streamr r r!rs  r))rYrZmathr,Z oci._vendorrZcryptography.hazmat.backendsrZ&cryptography.hazmat.primitives.ciphersrr threadingrZ%oci.encryption.internal.serializationrrZoci.encryption.internal.modelsr r Z oci.encryption.internal.defaultsr r r Zoci.encryption.internal.utilsrrrrZoci.encryption.algorithmsrZoci.encryption.modelsrrApowZMAX_32_BIT_SIGNED_INTEGERrr"r2r3r~rr r r r!s,     +y#