
    =                         d Z ddlZddlZddlZddlZddlZddlmZmZ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ZdZdZd Zd Zd Zd Z 	 ddZ! G d dejD                        Z#y)zLTool and utils for creating Sigstore attestations stored as a Docker images.    N)ListOptionalText)docker_creds)docker_name)docker_digest)docker_http)docker_image)docker_session)metadata)util)Errorz%application/vnd.dsse.envelope.v1+jsonzChttps://binaryauthorization.googleapis.com/policy_verification/v0.1c                 D    | j                  |      r| t        |      d  S | S N)
startswithlen)textprefixs     Clib/googlecloudsdk/command_lib/container/binauthz/sigstore_image.py_RemovePrefixr   +   s$    	__VF	+    c                 ,    | dd t        |        dz   z   S )Nz===   )r   encodeds    r   AddMissingBase64Paddingr   1   s     	5,CL=1,-	--r   c                     	 t        j                  |       S # t        j                  $ r! t        j                  t        |             cY S w xY wr   )base64	b64decodebinasciir   urlsafe_b64decoder   r   s    r   StandardOrUrlsafeBase64Decoder"   5   sE    FG$$	 F##$;G$DEEFs    1A
Ac                     t        j                  t        |             }t        j                  t        |d               }dj                  |d   d   d   |d   d   d   d         S )a  Extract the image url from a DSSE of predicate type https://binaryauthorization.googleapis.com/policy_verification/*.

  This is a helper function for mapping attestations back to their respective
  images. Do not use this for signature verification.

  Args:
    attestation: The attestation in base64 encoded string form.

  Returns:
    The image url referenced in the attestation.
  payloadz{}@sha256:{}subjectr   namedigestsha256)jsonloadsr"   format)attestation	deser_attdeser_payloads      r   AttestationToImageUrlr/   =   sq     jj6{CD)**#Ii$89- 
		Iq!&)Iq!(+H5
 r   c           
         t        j                         }t        j                  t	        j
                  | d            }t        j                  dj                  |j                  |j                  t        |j                  d                  }d}|rQt        j                  }|r|j                  |       |j                  t        j                   |j                              }|t#        |t        j$                        rt'        j(                         }t+        j,                  |||t.        j0                        5 }	|	j3                         r=t5        |g|	      }
t7        j8                  |||      j;                  |
       	 ddd       y	 ddd       t5        |g      }
t7        j8                  |||      j;                  |
       y# 1 sw Y   <xY w)at  Uploads a DSSE attestation to the registry.

  Args:
    image_url: The image url of the target image.
    attestation: The attestation referencing the target image in JSON DSSE form.
    use_docker_creds: Whether to use the Docker configuration file for
      authenticating to the registry.
    docker_config_dir: Directory where Docker saves authentication settings.
   )schemez{}/{}:sha256-{}.attsha256:N)accepted_mimes)httplib2Httpr   Digestbinauthz_utilReplaceImageUrlSchemeTagr+   registry
repositoryr   r'   r   DefaultKeychainsetCustomConfigDirResolveRegistry
isinstance	Anonymousr   CredentialProviderr
   FromRegistryr	   SUPPORTED_MANIFEST_MIMESexistsSigstoreAttestationImager   Pushupload)	image_urlr,   use_docker_credsdocker_config_dirhttp_objtarget_imageattestation_tagcredskeychain
v2_2_image	new_images              r   UploadAttestationToRegistryrT   U   s    ]]_( ##)))B?,  OO""




!
!
++Y
7/ %++H!!"34[11,2G2GHIE
]j(>(>?##%E
    99	
 *K=*Ei /5(;BB9M   '}5)ouh7>>yI s   9AGGc                       e Zd ZdZ	 ddee   deej                     fdZ	deddfdZ
defd	Zdefd
ZdedefdZd Zd Zy)rG   zCreates a new image or appends a layers on top of an existing image.

  Adheres to the Sigstore Attestation spec:
  https://github.com/sigstore/cosign/blob/main/specs/ATTESTATION_SPEC.md.
  Nadditional_blobsbasec                    t        j                  d |D              | _        |l|| _        t	        j
                  | j                  j                               | _        t	        j
                  | j                  j                               | _	        yd| _        t        j                  ddt        j                  ddg d| _        t               | _	        y)zCreates a new Sigstore style image or extends a base image.

    Args:
      additional_blobs: additional attestations to be appended to the image.
      base: optional base DockerImage.
    c              3   J   K   | ]  }t        j                  |      |f  y wr   )r   SHA256).0blobs     r   	<genexpr>z4SigstoreAttestationImage.__init__.<locals>.<genexpr>   s%      57Gt		d	#T*7Gs   !#N   r1   r   )r'   	mediaTypesize)r_   schemaVersionconfiglayers)collectionsOrderedDict_additional_blobs_baser)   r*   manifest_base_manifestconfig_file_base_config_filer	   OCI_MANIFEST_MIMECONFIG_JSON_MIMEdict)selfrV   rW   s      r   __init__z!SigstoreAttestationImage.__init__   s     )44 57G5 D dj JJtzz':':'<=d#zz$***@*@*BCddj"44&77
 	d  $vdr   r\   returnc                 H    || j                   t        j                  |      <   y r   )rf   r   rZ   )ro   r\   s     r   	add_layerz"SigstoreAttestationImage.add_layer   s    9=D=//56r   c                 r   | j                   }t        j                         }|j                  t        j
                        }| j                  j                         D cg c]  }t        |d       }}|j                  |      }t        j                  ||dd      }t        j                  |d      S c c}w )	Override.)
created_byr3   )rc   r1   )optionsarchitectureoperating_systemT	sort_keys)rk   r   	OverridesOverrider   
USER_AGENTrf   keysr   r)   dumps)ro   rj   	overridesblob_sumrc   s        r   rj   z$SigstoreAttestationImage.config_file   s    ((K""$I""k.D.D"EI ..3355H 	h	*5  
 "" # I
 ##	K ::kT22#s   B4c           	         t        j                  | j                        }| j                  j	                         D ]2  \  }}|d   j                  |t        t        |      dt        dd       4 | j                         }|j                  d      }t        j                  |      |d   d<   t        |      |d   d<   t        j                  |d	
      S )ru   rc   r1   )z"dev.cosignproject.cosign/signaturepredicateType)r'   r_   r`   annotationsutf8rb   r'   r`   Trz   )copydeepcopyri   rf   itemsappendDSSE_PAYLOAD_TYPEr   BINAUTHZ_CUSTOM_PREDICATErj   encoder   rZ   r)   r   )ro   rh   r   r\   rj   utf8_encoded_configs         r   rh   z!SigstoreAttestationImage.manifest   s    }}T001H00668$x(d)468	! 	 9 ""$K%,,V4#0#7#78K#LHXx !$%8!9HXv::h$//r   r'   c                     || j                   v r| j                   |   S | j                  r| j                  j                  |      S t        dj	                  |            )z$Override. Returns uncompressed blob.zDigest not found: {})rf   rg   r\   r   r+   )ro   r'   s     r   r\   zSigstoreAttestationImage.blob   sR    '''##F++zzZZ__V$$
&--f5
66r   c                     | S )ru    )ro   s    r   	__enter__z"SigstoreAttestationImage.__enter__   s    Kr   c                      y)ru   Nr   )ro   unused_typeunused_valueunused_tracebacks       r   __exit__z!SigstoreAttestationImage.__exit__   s    
r   r   )__name__
__module____qualname____doc__r   bytesr   r
   DockerImagerp   rs   r   rj   rh   r\   r   r   r   r   r   rG   rG      s{     26&U& \--.&@>E >d >34 320 0(7 7% 7r   rG   )NN)$r   r   r    rd   r   r)   typingr   r   r   containerregistry.clientr   r   containerregistry.client.v2_2r   r	   r
   r    containerregistry.transform.v2_2r   'googlecloudsdk.api_lib.container.imagesr   -googlecloudsdk.command_lib.container.binauthzr8   googlecloudsdk.core.exceptionsr   r5   r   r   r   r   r"   r/   rT   r   rG   r   r   r   <module>r      s    S      ' ' 1 0 7 5 6 8 5 8 O 0  < I 
.F2 FJ6Jrf|77 fr   