
    M                     x   S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJr  SSKJ	r	  SSK
Jr  SSK
Jr  SSKJr  \R                  " S	5      rS
r " S S\R$                  5      r\R(                  " S/ SQ5      r " S S5      r\" 5       rS rS r\R4                  " SS9S 5       rS rS rSS jrSS jrSS jr g)z1Utilities that support customer encryption flows.    N)errors)	hash_util)user_request_args_factory)
properties)yaml)function_result_cachezqprojects/([^/]+)/locations/([a-zA-Z0-9_-]{1,63})/keyRings/([a-zA-Z0-9_-]{1,63})/cryptoKeys/([a-zA-Z0-9_-]{1,63})$AES256c                       \ rS rSrSrSrSrg)KeyType'   CMEKCSEK N)__name__
__module____qualname____firstlineno__r   r   __static_attributes__r       9lib/googlecloudsdk/command_lib/storage/encryption_util.pyr   r   '   s    	$	$r   r   EncryptionKey)keytypesha256c                   .    \ rS rSrSr   SS jrS rSrg)	_KeyStore5   au  Holds encryption key information.

Attributes:
  encryption_key (Optional[EncryptionKey]): The key for encryption.
  decryption_key_index (Dict[EncryptionKey.sha256, EncryptionKey]): Indexes
    keys that can be used for decryption.
  initialized (bool): True if encryption_key and decryption_key_index
    reflect the values they should based on flag and key file values.
Nc                 <    Xl         U=(       d    0 U l        X0l        g N)encryption_keydecryption_key_indexinitialized)selfr    r!   r"   s       r   __init___KeyStore.__init__@   s     ) 4 :D"r   c                     [        XR                  5      (       d  [        $ U R                  UR                  :H  =(       a9    U R                  UR                  :H  =(       a    U R
                  UR
                  :H  $ r   )
isinstance	__class__NotImplementedr    r!   r"   )r#   others     r   __eq___KeyStore.__eq__H   sb    e^^,,u333 	.!!U%?%??	.E---r   )r!   r    r"   )NNF)r   r   r   r   __doc__r$   r+   r   r   r   r   r   r   5   s     #$( #r   r   c                    U (       d  [         R                  " S5      eU R                  S5      (       a  [         R                  " SU -   5      e[        R	                  U 5      (       d%  [         R                  " SR                  U 5      5      eg )NzKey is empty./z1KMS key should not start with leading slash (/): zInvalid KMS key name: {}.
KMS keys should follow the format "projects/<project-id>/locations/<location>/keyRings/<keyring>/cryptoKeys/<key-name>")r   Error
startswith_CMEK_REGEXmatchformat)raw_keys    r   validate_cmekr6   U   sx    	
,,
''
,,J     
		7	#	#
,,	!!'2 2 
$r   c                 d   U R                  S5      n [        U 5        [        R                  nSn[        XUS9$ ! [        R
                   aa    [        U 5      S:w  a  e [        R                  n[        R                  " [        R                  " [        R                  " U5      5      5      n N~f = f)zAReturns an EncryptionKey populated with information from raw_key.asciiN,   )r   r   r   )encoder6   r   r   r   r0   lenr   r   get_base64_hash_digest_stringhashlibr   base64	b64decoder   )r5   raw_key_byteskey_typer   s       r   	parse_keyrB   d   s    ..)-	9'||HF 
7	AA 
 9
7|r||H44v''679F	9s   : A2B/.B/   )maxsizec                     U =(       d2    [         R                  R                  R                  R	                  5       nU(       d  0 $ [
        R                  " U5      $ )zReads the key store file, if it exists.

Args:
  key_path: str | None, only provided for unit tests.

Returns:
  The contents of the key store file, or an empty dict if the file does not
  exist.
)r   VALUESstoragekey_store_pathGetr   	load_path)key_pathrH   s     r   _read_key_store_filerL   t   s@     Mz0088GGKKM.	I		''r   c                 X    [        XS5      nUb  U$ [        U5      R                  U5      $ )a  Searches for key values in flags, falling back to a file if necessary.

Args:
  args: An object containing flag values from the command surface.
  key_field_name (str): Corresponds to a flag name or field name in the key
      file.
  key_store_path (str | None): The path to the key store file. Only provided
    if testing.

Returns:
  The flag value associated with key_field_name, or the value contained in the
  key file.
N)getattrrL   get)argskey_field_namerH   flag_keys       r   _get_raw_keyrS      s1     T40(O	n	-	1	1.	AAr   c                     0 nU (       aK  U  HE  nU(       d  M  [        U5      nUR                  [        R                  :X  d  M7  X1UR                  '   MG     U$ )zParses and indexes raw keys.

Args:
  raw_keys (list[str]): The keys to index.

Returns:
  A dict mapping key hashes to keys in raw_keys. Falsy elements of raw_keys
  and non-CSEKs are skipped.
)rB   r   r   r   r   )raw_keysindexr5   r   s       r   _index_decryption_keysrW      sI     %gc	W\\	!cjj  
,r   c                 L   [         R                  (       a  g[        U SU5      n[        U SS5      (       a  [        R
                  [         l        OU(       a  [        U5      [         l        U/n[        U SU5      nU(       a  X4-  n[        U5      [         l	        S[         l        g)a  Loads appropriate encryption and decryption keys into memory.

Prefers values from flags over those from the user's key file. If _key_store
  is not already initialized, creates a _KeyStore instance and stores it in a
  global variable.

Args:
  args: An object containing flag values from the command surface.
  key_store_path (str | None): The path to the key store file. Only provided
    if testing.
Nr    clear_encryption_keydecryption_keysT)

_key_storer"   rS   rN   r   CLEARr    rB   rW   r!   )rP   rH   raw_encryption_keyrU   raw_decryption_keyss        r   initialize_key_storer_      s     
#D*:NKT)400 9 ? ?J )*< =J !($T+<nM#H$:8$D*!*r   c                     [         R                  (       a   [         R                  R                  U 5      nOSnU(       d,  U(       a%  [        R
                  " SR                  X5      5      eU$ )zCReturns a key that matches sha256_hash, or None if no key is found.NzPMissing decryption key with SHA256 hash {}. No decryption key matches object {}.)r[   r"   r!   rO   r   r0   r4   )sha256_hashurl_for_missing_key_errordecryption_keys      r   get_decryption_keyrd      sV    4488ENN	5
,,	#VKKM M 
r   c                 r    [         R                  (       a"  U (       a  [        X5      $ [         R                  $ g)a  Returns an EncryptionKey, None, or a CLEAR string constant.

Args:
  sha256_hash (str): Attempts to return a CSEK key that matches this hash.
    Used for encrypting with a non-default key.
  url_for_missing_key_error (StorageUrl): If a key matching sha256_hash can
    not be found, raise an error adding this object URL to the error text.

Returns:
  EncryptionKey: Custom or default key depending on presence of sha256_hash.
  None: Matching key to sha256_hash could not be found and
    url_for_missing_key_error was None. Or, no sha256_hash and no default key.
  user_request_args_factory.CLEAR (str): Value indicating that the
    user requested to clear an existing encryption.
N)r[   r"   rd   r    )ra   rb   s     r   get_encryption_keyrf      s,      GG$$$ r   r   )NN)!r-   r>   collectionsenumr=   re"googlecloudsdk.command_lib.storager   r   r   googlecloudsdk.corer   r   googlecloudsdk.core.cacher   compiler2   ENCRYPTION_ALGORITHMEnumr   
namedtupler   r   r[   r6   rB   lrurL   rS   rW   r_   rd   rf   r   r   r   <module>rr      s    8     	 5 8 H * $ ; jj = >   dii 
 && : [
2B  1%( &( B(* <
%r   