
                             d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z
 ddlm	Z	 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ  G d de	j*                        Zy)z7Sign a user input file using an asymmetric-signing key.    )absolute_import)division)unicode_literals)
exceptions)base)crc32c)e2e_integrity)flags)
get_digest)log)filesc                   R    e Zd ZdZed        Zd Zd Zd Zd Z	d Z
d Zdd	Zd
 Zy)AsymmetricSigna  Sign a user input file using an asymmetric-signing key version.

  Creates a digital signature of the input file using the provided
  asymmetric-signing key version and saves the base64 encoded signature.

  The required flag `signature-file` indicates the path to store signature.

  By default, the command performs integrity verification on data sent to and
  received from Cloud KMS. Use `--skip-integrity-verification` to disable
  integrity verification.

  ## EXAMPLES
  The following command will read the file '/tmp/my/file.to.sign', digest it
  with the digest algorithm 'sha256' and sign it using the asymmetric CryptoKey
  `dont-panic` Version 3, and save the signature in base64 format to
  '/tmp/my/signature'.

    $ {command} \
    --location=us-central1 \
    --keyring=hitchhiker \
    --key=dont-panic \
    --version=3 \
    --digest-algorithm=sha256 \
    --input-file=/tmp/my/file.to.sign \
    --signature-file=/tmp/my/signature

  c                 
   t        j                  | d       t        j                  | d       t        j                  | d       t        j                  | d       t        j
                  | d       t        j                  |        y )Nzto use for signing.zto use for signingz"The algorithm to digest the input.zto signz	to output)r
   AddKeyResourceFlagsAddCryptoKeyVersionFlagAddDigestAlgorithmFlagAddInputFileFlagAddSignatureFileFlagAddSkipIntegrityVerification)parsers    "lib/surface/kms/asymmetric_sign.pyArgszAsymmetricSign.Args>   sc    	f&;<	!!&*>?	  )MN	69-	v{3	&&v.    c                     |j                    S N)skip_integrity_verificationselfargss     r   _PerformIntegrityVerificationz,AsymmetricSign._PerformIntegrityVerificationG   s    ////r   c                     |j                   d uS r   )digest_algorithmr   s     r   _SignOnDigestzAsymmetricSign._SignOnDigestJ   s      ,,r   c                     t        j                  |      }t        |      |kD  r%t        j                  dj                  ||            |S )Nz<The file [{0}] is larger than the maximum size of {1} bytes.)r   ReadBinaryFileContentslenr   BadFileExceptionformat)r   path	max_bytesdatas       r   _ReadBinaryFilezAsymmetricSign._ReadBinaryFileM   sK    ''-D
4y9''
H
O
OI    Kr   c                 @   	 t        j                  |j                  |j                        }t        j                         }|j                  t        j                  |      j                               }| j                  |      rCt        j                   t#        ||j                              }|j%                  ||      |_        |S |j%                  |      |_        |S # t        $ r4}t        j                  dj                  |j                  |            d }~ww xY w)N$Failed to read input file [{0}]: {1}name)digestdigestCrc32c)r2   )r   	GetDigestr#   
input_fileEnvironmentErrorr   r(   r)   cloudkms_baseGetMessagesModuleQCloudkmsProjectsLocationsKeyRingsCryptoKeysCryptoKeyVersionsAsymmetricSignRequestr
   ParseCryptoKeyVersionNameRelativeNamer!   r   Crc32cgetattrAsymmetricSignRequestasymmetricSignRequest)r   r    r2   emessagesreqdigest_crc32cs          r   $_CreateAsymmetricSignRequestOnDigestz3AsymmetricSign._CreateAsymmetricSignRequestOnDigestU   s   M##D$9$94??Kf
 ..0H

d
d,,T2??A e CC ))$/mmGFD4I4I$JKm"*"@"@m #A #5c
 J #+"@"@"@"OcJ!  M''
0
7
7
KM MMs   *C   	D)/DDc                    	 | j                  |j                  d      }t        j                         }|j                  t        j                  |      j                               }| j                  |      r/t        j                  |      }|j!                  ||      |_        |S |j!                  |      |_        |S # t        j                  $ r4}t	        j
                  dj                  |j                  |            d}~ww xY w)aZ  Returns an AsymmetricSignRequest for use with a data input.

    Populates an AsymmetricSignRequest with its data field populated by data
    read from args.input_file. dataCrc32c is populated if integrity verification
    is not skipped.

    Args:
      args: Input arguments.

    Returns:
      An AsymmetricSignRequest with data populated and dataCrc32c populated if
      integrity verification is not skipped.

    Raises:
      exceptions.BadFileException: An error occurred reading the input file.
      This can occur if the file can't be read or if the file is larger than
      64 KiB.
    i   )r+   r/   Nr0   )r,   
dataCrc32c)r,   )r-   r5   r   Errorr   r(   r)   r7   r8   r9   r
   r:   r;   r!   r   r<   r>   r?   )r   r    r,   r@   rA   rB   data_crc32cs          r   "_CreateAsymmetricSignRequestOnDataz1AsymmetricSign._CreateAsymmetricSignRequestOnDataj   s    &M!!$//U!Cd
 ..0H

d
d,,T2??A e CC ))$/MM$'k"*"@"@ #A #-c
 J #+"@"@d"@"KcJ ;; M''
0
7
7
KM MMs   B? ?D/DDc                 h    | j                  |      r| j                  |      S | j                  |      S r   )r$   rD   rI   r   s     r   _CreateAsymmetricSignRequestz+AsymmetricSign._CreateAsymmetricSignRequest   s2    $66t<<44T::r   c                 "   |j                   |j                   k7  r=t        j                  t        j                  |j                   |j                               |r3|j                  sZt        j
                  t        j                               |j                  s't        j
                  t        j                               t        j                  |j                  |j                        s't        j
                  t        j                               y)z4Verifies integrity fields in AsymmetricSignResponse.N)r1   r	   ResourceNameVerificationError#GetResourceNameMismatchErrorMessageverifiedDigestCrc32c$ClientSideIntegrityVerificationError'GetRequestToServerCorruptedErrorMessageverifiedDataCrc32cr   Crc32cMatches	signaturesignatureCrc32c*GetResponseFromServerCorruptedErrorMessage)r   rB   resp
use_digests       r   _VerifyResponseIntegrityFieldsz-AsymmetricSign._VerifyResponseIntegrityFields   s     xx49977

;
;hh		#$ $ &&@@AACE 	E $$@@AACE 	E 0D0DE>>

B
B
DF F Fr   c                    t        j                         }| j                  |      }	 |j                  j	                  |      }| j                  |      r#| j                  || j                  |             	 t        j                  |j                  j                  ddd       y # t
        j                  $ r}t        j                  |       Y d }~d }~ww xY w# t         j"                  $ r}t%        j&                  |      d }~ww xY w)N)rX   T)	overwritebinaryprivate)r7   GetClientInstancerK   8projects_locations_keyRings_cryptoKeys_cryptoKeyVersionsr   apitools_exceptionsHttpBadRequestErrorr	   ProcessHttpBadRequestErrorr!   rY   r$   r   WriteToFileOrStdoutsignature_filerT   r   rG   r   r(   )r   r    clientrB   rW   errorr@   s          r   RunzAsymmetricSign.Run   s    ,,.F

+
+D
1C6

I
I>#  ))$/
))
t 2 24 8 * :+	



.. 22 6..u556 ;; +''**+s/   B& 7.C &C9CCD.DDN)T)__name__
__module____qualname____doc__staticmethodr   r!   r$   r-   rD   rI   rK   rY   rg    r   r   r   r   !   sE    8 / /0-*%N;F2+r   r   N)rk   
__future__r   r   r   apitools.base.pyr   r`   googlecloudsdk.api_lib.cloudkmsr   r7   googlecloudsdk.calliopegooglecloudsdk.command_lib.kmsr   r	   r
   r   googlecloudsdk.corer   googlecloudsdk.core.utilr   Commandr   rm   r   r   <module>rv      sC    > &  ' > A ( . 1 8 0 5 # *g+T\\ g+r   