
                            d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddl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$ 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/m0Z0 ddl!Z!ddl1Z1ddl2m3Z3 dZ4dZ5dZ6dZ7dZ8dZ9dZ:d Z;d!Z<d"Z=d#Z>d$Z?d%Z@d&ZAd'ZBd(ZCd)ZDd*ZEd+ZFd,ZGd-ZHd.ZId/ ZJd0 ZKd1 ZLd2 ZMd3 ZNd4 ZOd5 ZPd6 ZQd7 ZRd8 ZSd9 ZTd: ZUd; ZVd< ZWd= ZXd> ZYdNd?ZZd@ Z[dA Z\dB Z]dC Z^dD Z_dE Z`dF ZadG Zb G dH dIec      Zd G dJ dKec      Ze G dL dMec      Zfy)Oz Utility for handling SBOM files.    )absolute_import)division)unicode_literalsN)encoding)
exceptions)docker_creds)docker_name)docker_http)docker_image)docker_image_list)base)util)filter_util)requests)storage_api)storage_util)docker_util)log)	resources)
transports)files)urllibspdx	cyclonedxzRThe file is not in a supported SBOM format. Only spdx and cyclonedx are supported.zapplication/vnd.in-toto+jsonz!https://in-toto.io/Statement/v0.1z+https://bcid.corp.google.com/reference/v0.1zapplication/spdx+jsonzapplication/jsonzapplication/vnd.cyclonedx+jsonz>https://containeranalysis.googleapis.com/ArtifactAnalysis@v0.1z	spdx.jsonjsonzbom.json$abcdefghijklmnopqrstuvwxyz0123456789   zregistry.hub.docker.comlibraryhttphttpsartifactregistrygcrotherc                    | d   }d}t        |t        j                        r)t        j                  d|      }||j                  d      }|s$t        j                  dj                  |            t        t        |      S )  Retrieves version from the given SBOM dict.

  Args:
    data: Parsed json content of an SBOM file.

  Raises:
    ar_exceptions.InvalidInputValueError: If the sbom format is not supported.

  Returns:
    A SbomFile object with metadata of the given sbom.
  spdxVersionNz^SPDX-([0-9]+[.][0-9]+)$   zUnable to read spdxVersion {0}.sbom_formatversion)
isinstancesixstring_typesrematchgroupar_exceptionsInvalidInputValueErrorformatSbomFile_SBOM_FORMAT_SPDX)dataspdx_versionr*   rs       5lib/googlecloudsdk/command_lib/artifacts/sbom_util.py
_ParseSpdxr:   Y   sz     m$,'c../
,l;A}
g	

.
.)00>  
/	AA    c                 X   d| vrt        j                  d      d}t        | d   t        j                        r+t        j                  d| d         }||j                         }|s5t        j                  dj                  | d   j                                     t        t        |      S )r%   specVersionz1Unable to find specVersion in the CycloneDX file.Nz^[0-9]+[.][0-9]+$zUnable to read specVersion {0}.r(   )r1   r2   r+   r,   r-   r.   r/   r0   r3   __str__r4   _SBOM_FORMAT_CYCLONEDX)r6   r*   r8   s      r9   _ParseCycloneDxr@   s   s     $

.
.;  ']#S%5%56
%tM':;A}	g	

.
.)00m1D1L1L1NO  
4g	FFr;   c                    	 t        j                  |       }t        j                  |      }d|v rt        |      }n9|j                  d      dk(  rt        |      }nt        j                  t              t        j                  t        j                  |            j!                         }||j"                  d<   |S # t        $ r}t        j                  d|      d}~wt         j                  $ r}t        j                  d|      d}~ww xY w)a#  Retrieves information about a docker image based on the fully-qualified name.

  Args:
    file_path: str, The sbom file location.

  Raises:
    ar_exceptions.InvalidInputValueError: If the sbom format is not supported.

  Returns:
    An SbomFile object with metadata of the given sbom.
  z!The file is not a valid JSON fileNzFailed to read the sbom filer&   	bomFormat	CycloneDXsha256)r   ReadFileContentsr   loads
ValueErrorr1   r2   Errorr:   getr@   _UNSUPPORTED_SBOM_FORMAT_ERRORhashlibrD   r,   ensure_binary	hexdigestdigests)	file_pathcontentr6   eressha256_digests         r9   ParseJsonSbomrT      s    
$$Y/G::gD d
T
Cxx+
$
C

.
./M
NN..!2!27!;<FFH-'#++h	*# 
 

.
.+Q  
 

.
.& s#   *B< <	DCD1DDc                     t        j                  |       \  }}|j                  }d|j                  j	                  dd      i}t        |j                         |j                  |j                  |t        t              S )zRetrieves metadata from the given AR docker image.

  Args:
    uri: Uri of the AR docker image.

  Raises:
    ar_exceptions.InvalidInputValueError: If the uri is invalid.

  Returns:
    An Artifact object with metadata of the given artifact.
  rD   sha256: resource_uriprojectlocationrN   artifact_typescheme)r   DockerUrlToVersiondocker_repodigestreplaceArtifactGetDockerStringrZ   r[   ARTIFACT_TYPE_AR_IMAGE_REGISTRY_SCHEME_HTTPS)uriimagedocker_versionreporN   s        r9   _GetARDockerImagerj      sq     &88=%			$~,,44YCD'	!113ll}}*#
 r;   c           
         ddddd}	 t        j                  |       }d}d}t        j                  t        j                  |       }|r%||j                  d         }|j                  d      }t        j                  t        j                  |       }|r6||j                  d         }|j                  d      j                  d	d
d      }|r|st        j                  d      t        |j                         ||d|j                  j                  dd      it         t"              S # t         j                  $ r)}t        j                  dj                  |            d}~ww xY w)zRetrieves information about the given GCR image.

  Args:
    uri: str, The artifact uri.

  Raises:
    ar_exceptions.InvalidInputValueError: If the uri is invalid.

  Returns:
    An Artifact object with metadata of the given artifact.
  useuropeasia)z	us.gcr.iozgcr.ioz	eu.gcr.iozasia.gcr.ioz-Failed to resolve digest of the GCR image: {}Nri   rZ   /:r'   z8Failed to parse project and location from the GCR image.rD   rV   rW   rX   )gcr_utilGetDigestFromNameInvalidImageNameErrorr1   r2   r3   r.   r/   r   GCR_DOCKER_REPO_REGEXr0   #GCR_DOCKER_DOMAIN_SCOPED_REPO_REGEXra   rb   r>   r`   ARTIFACT_TYPE_GCR_IMAGEre   )rf   location_mapdocker_digestrQ   rZ   r[   matchess          r9   _GetGCRImagerz      sQ    	,..s3M
 '(HH[66<'GMM&12HmmI&GHH[DDcJ'GMM&12HmmI&..sC;G	

.
.B  
 ((*--55iDE+#
 % 
	'	' 

.
.7>>qA s   D% %E!8$EE!c                    t        j                  t        j                         | t	        j
                               5 }|j                         r|j                         cddd       S 	 ddd       t        j                  t        j                         | t	        j
                         t        j                        5 }|j                         r|j                         cddd       S 	 ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)a  Returns Digest of the given Docker image.

  Lookup registry to get the manifest's digest. If it returns a list of
  manifests, will return the first one.

  Args:
    image: docker_name.Tag or docker_name.Digest, Docker image.

  Returns:
    An str for the digest.
  )basic_credsname	transportN)r|   r}   r~   accepted_mimes)v2_2_image_listFromRegistryr   	Anonymousr   GetApitoolsTransportexistsr`   
v2_2_imagev2_2_docker_httpSUPPORTED_MANIFEST_MIMES)rg   manifest_listv2_2_imgs      r9   _ResolveDockerImageDigestr      s     ##((*//1 !!# 
  ((*//1%>>	
 __     s    C/; C;%C;/C8;Dc           	         	 t        j                  |       }t        |t         j                        r1t	        | d|j
                  j                  dd      it        ddd      S 	 | }d| vr| dz   }t        j                  |	      }t        j                  |j                         }	 t#        |      }|s$t        j                  d
j                  |             dj                  |j                   |j.                  |      }t	        |d|j                  dd      it        dd|      S # t         j                  f$ r3}t        j                  dj                  | t        |                  d}~ww xY w# t        j$                  t&        j(                  j*                  t        j,                  f$ r3}t        j                  dj                  | t        |                  d}~ww xY w)a:  Retrieves information about the given docker image.

  Args:
    uri: str, The artifact uri.

  Raises:
    ar_exceptions.InvalidInputValueError: If the artifact is with tag, and it
    can not be resolved by querying the docker http APIs.

  Returns:
    An Artifact object with metadata of the given artifact.
  rD   rV   rW   NrY   rN   r\   rZ   r[   r]   zFailed to resolve {0}: {1}rp   z:latestr}   zFailed to resolve {0}.z{registry}/{repo}@{digest})registryri   r`   )r	   from_stringr+   Digestrb   r`   ra   ARTIFACT_TYPE_OTHERBadNameExceptionr1   r2   r3   strTagr   Schemer   r   V2DiagnosticExceptionr   r   
InvalidURLBadStateException
repository)rf   image_digestrQ   	image_uri	image_tagr]   r`   rY   s           r9   _GetDockerImager     s   **3/L, 2 23\0088BGH+  4 )^iIoo9-)""9#5#56&	&y1F 


.
. '',  .44!!	(<(<V 5 , 
	267'
 7 
&
&	( 

.
.$++CQ8  ,,$$((
 
 
.
.$++CQ8 s0   AD$ $E. $E+8.E&&E+.<G*.GGc           	      L   t        j                  |       rt        |       S t        j                  |       rt	        |       S 	 t        |       S # t        j                  $ rC}t        j                  dj                  |             t        | i t        ddd      cY d}~S d}~ww xY w)zRetrieves information about the given artifact.

  Args:
    uri: str, The artifact uri.

  Raises:
    ar_exceptions.InvalidInputValueError: If the artifact type is unsupported.

  Returns:
    An Artifact object with metadata of the given artifact.
  z"Failed to resolve the artifact: {}Nr   )r   IsARDockerImagerj   
IsGCRImagerz   r   r1   r2   r   debugr3   rb   r   )rf   rQ   s     r9   ProcessArtifactr   \  s       %S!!c"S!!// 		ii4;;A>?+ 	s   
A B# 8BB#B#c                 D    | j                  |      r| t        |      d  S | S N)
startswithlenvalueprefixs     r9   _RemovePrefixr   }  s&    
fV	,r;   c                 2    | j                  |      s|| z   } | S r   )r   r   s     r9   _EnsurePrefixr     s    			&	!UNE	,r;   c                 |   | j                   }| j                  }| j                  }|r|s|s|r|rt        j                  d      t        j                         j                  dg      }t        j                  |       }|rt        j                         j                  dg      j                  dj                  |            }t        t        j                  ||j                         d            }|sg S t!        d |D              }|j#                  |       |rt%        |d      }	dj                  |	      |	g}
	 t'        |	      }|	|j(                  k7  r*|
dj                  |j(                        |j(                  gz   }
|j*                  r*t        j,                  |j*                  | j.                        }|j#                  |
       |r.t%        |d      }|j;                  dj                  |      |g       |r%t        j<                  ||j?                               }n/t        j                  ||j                         | j@                        }|rtC        |      S |D cg c]  }tE        |i        c}S # t        j                  t0        j2                  f$ r# t4        j6                  j9                  d	       Y w xY wc c}w )
z~Lists SBOM references in a given project.

  Args:
    args: User input arguments.

  Returns:
    List of SBOM references.
  zYCannot specify more than one of the flags --dependency, --resource and --resource-prefix.SBOM_REFERENCEPACKAGEz<noteProjectId="goog-analysis" AND dependencyPackageName="{}"Nc              3   H   K   | ]  }t        |j                  d         yw)https://N)r   resourceUri).0os     r9   	<genexpr>z%ListSbomReferences.<locals>.<genexpr>  s     P<aq}}j9<s    "r   
https://{}z;Failed to resolve the artifact. Filter on the URI directly.)#resourceresource_prefix
dependencyr1   r2   r   ContainerAnalysisFilter	WithKindsr   
GetProjectWithCustomFilterr3   listca_requestsListOccurrences	GetFiltersetWithResourcesr   r   rY   rZ   	GetParentr[   r	   r   r   statusPrintWithResourcePrefixesListOccurrencesWithFiltersGetChunkifiedFilters	page_size_VerifyGCSObjectsSbomReference)argsr   r   r   filtersrZ   dependency_filterspackage_occsimagesrY   resource_urisartifactpath_prefixoccsoccs                  r9   ListSbomReferencesr     s    ]](&*Fjv*

.
.	- 
 //1;;=M<NO'OOD!'++-	I;			JVJ

  ##'113T	
L
 i
 P<PPF&! :6L 	L)M .h	..	.% 5 56!!)
 

 
		..!1!14==A -(
3K  K(" 
 11--/D &&""$dnnD T"",0	1DS-R
 D	11= 00+2N2NO 	jj
G < 
2s   8A:I0 J90AJ65J6c                 >    | D cg c]  }t        |       c}S c c}w r   )_VerifyGCSObject)r   r   s     r9   r   r     s     +/	04C
3
4	00	0s   c                    t        j                         }t        j                  j	                  | j
                  j                  j                  j                        }i }	 |j                  |       d|d<   t%        | |      S # t        j                  $ r d|d<   Y &t        j                  $ r4}t        j                  |j                        }|d   d   |d<   Y d}~gd}~wt         $ r}t#        |      |d<   Y d}~d}~ww xY w)zVerify the existence and the content of a GCS SBOM file object.

  Args:
    occ: SBOM reference occurrence.

  Returns:
    An SbomReference object with the input occurrence and SBOM file information.
  Tr   Ferrormessageerr_msgN)r   StorageClientr   ObjectReferenceFromUrlsbomReferencepayload	predicater[   	GetObjectapitools_exceptionsHttpNotFoundError	HttpErrorr   rF   rP   	Exceptionr   r   )r   
gcs_clientobj_ref	file_inforQ   msgs         r9   r   r     s     ((**((00	))22' )! Ih 
sI	&& 
	.	.  Ih		&	& 3
**QYY
Cw<	2Ii	 " q6Ii"s*   B D D -*CD (C;;D c                 &    dj                  ||       S )Nzartifactanalysis-{0}-{1})r3   )project_numr[   s     r9   _DefaultGCSBucketNamer     s    	#	*	*8[	AAr;   c           	      
   t         j                  j                  d|i      dd  }|j                  j	                  dd      } dj
                  d
i | j	                  dd      j                  d      |||j                         d	S )Nrf      .-z;gs://{storage_path}/{uri_encoded}/sbom/user-{version}.{ext}zgs://rW   ro   )storage_pathuri_encodedr*   ext )r   parse	urlencoder*   ra   r3   rstripGetExtension)r   rY   sbomr   r*   s        r9   _GetSbomGCSPathr     s    &&|'<=abA+LL  c*'	O
G	O	O 
&..w;BB3G$""$		
 r;   c           	      <   t        j                         }|j                  |      }|D ](  }t        j                  dj                  |j                               |j                  j                  |       sN|j                  j                         dk(  r/t        j                  dj                  |j                               |j                  j                         |j                         k7  rXt        j                  dj                  |j                  |j                  j                         |j                                      |j                  c S  | dz   }t        t              D ]  }|t        j                  t              z   }  |j!                  |||dd       	 |j#                  |	      }|j$                  rt'        j(                  |j$                        ni }d
|d<   t'        j*                  ||j,                  j.                  j0                        |_        |j,                  j3                  ||      }	|j4                  j6                  j9                  |	       |S # t:        $ r0}
t        j<                  dj                  ||
             Y d}
~
|S d}
~
ww xY w)a  Find an appropriate default bucket to store the SBOM file.

  Find a bucket with the same prefix same as the default bucket in the project.
  If no bucket could be found, will start to create a new bucket by
  concatenating the default bucket name and a random suffix.

  Args:
    default_bucket: str, targeting default bucket name for the resource.
    project_id: str, project we will use to store the SBOM.
    location: str, location we will use to store the SBOM.

  Returns:
    bucket_name: str, name of the prepared bucket.
  rZ   zVerifying bucket {}zdual-regionzSkipping dual region bucket {}z4The bucket {0} has location {1} is not matching {2}.r   T)bucketrZ   r[   check_ownershipenable_uniform_level_accessr   artifact-analysisgoog-managed-byr   bucketResource%Failed to add labels to bucket {}: {}N)r   r   ListBucketsr   r   r3   r}   r   locationTypelowerr[   range_BUCKET_SUFFIX_LENGTHrandomchoice_BUCKET_NAME_CHARSCreateBucketIfNotExists	GetBucketlabelsr   MessageToDictDictToMessagemessagesBucketLabelsValueStorageBucketsPatchRequestclientbucketsPatchr   warning)default_bucket
project_idr[   r   r  r   bucket_name_labels_dictrequestrQ   s              r9   _FindAvailableGCSBucketr$  #  s3    ((**"":"6'fII#**6;;78;;!!.1  "m3	ii077DE(.."22	ii
@
G
Gkk6??002HNN4D
 ;; " $+&'a.@ AAK ($$"& % P!!!5F;A==(((7bK%8K!"**Z((//;;FM !!<< = G ##G, 
 
 PKK7>>{ANOO	Ps   !B?I" "	J+%JJc                    t        j                         }|rt        ||j                  |      }nnt	        j
                  |j                        }|j                  }|j                  }|dk(  rd}t        ||      }	|	}
d}	 |j                  |
||d       	 |j                  |
      }|j                  rt        j                  |j                        ni }d|d<   t        j                  ||j                  j                   j"                        |_        |j                  j%                  |
|	      }|j&                  j(                  j+                  |       |rt=        |	||      }
t/        j6                  dj3                  |
             t        |
|j                  |      }t>        j@                  jC                  |      }|jE                  | |       |S # t,        $ r/}t/        j0                  d
j3                  |
|             Y d}~d}~ww xY w# t         j4                  $ r t/        j6                  d       d}Y t8        j:                  $ r t/        j6                  d       d}Y w xY w)a  Upload an SBOM file onto the GCS bucket in the given project and location.

  Args:
    source: str, the SBOM file location.
    artifact: Artifact, the artifact metadata SBOM file generated from.
    sbom: SbomFile, metadata of the SBOM file.
    gcs_path: str, the GCS location for the SBOm file. If not provided, will use
      the default bucket path of the artifact.

  Returns:
    dest: str, the GCS storage path the file is copied to.
  rm   euFT)r   rZ   r[   r  r  r  r  r  r  Nz)The default bucket is in a wrong project.z&The default bucket cannot be accessed.zUsing bucket: {})#r   r   r   rY   project_utilGetProjectNumberrZ   r[   r   r  r  r  r   r  r  r  r  r  r  r  r  r  r   r   r  r3   BucketInWrongProjectErrorr   r   HttpForbiddenErrorr$  r   r   r   CopyFileToGCS)sourcer   r   gcs_pathr   destr   bucket_projectbucket_locationr  r   use_backup_bucketr   r"  r#  rQ   
target_refs                    r9   UploadSbomToGCSr3  a  s:    ((**8X%:%:DAD//0@0@AK%%N''O("o*;HN K%(( "	 ) 
%%[%95;]]H""6==1 	 *=%& ..,,33??
 %%@@! A 
 	!!''0" +
./k II ''45;(=(=tDD++33D9*6:.	+5  
3::;J	
 	

 00  
ii;<11  
ii89s=   ?H B?G 	H	%H?H H		H *I%8)I%$I%c                 B   t        j                         }t        j                         }t        |j                  |j
                        }t        j                  j                  d| |      j                         }	 |j                  |      }|j                  j                  |      }t        j                   d
j#                  |             |S # t        j                  $ r t        j                   dj#                  |             |j%                  |j                  |j
                        }|j'                  |j&                  j(                  j*                  |      }	|j-                  dj#                  |       ||		      }
|j                  j                  |
      }Y w xY w)zCreate the SBOM reference note if not exists.

  Args:
    project_id: str, the project we will use to create the note.
    sbom: SbomFile, metadata of the SBOM file.

  Returns:
    A Note object for the targeting SBOM reference note.
  z containeranalysis.projects.notes)
collection
projectsIdnotesIdr   z"Note not found. Creating note {0}.)r3   r*   )kindr   projects/{project}r   )parentnoteIdnotezget note results: {0})r   	GetClientGetMessages_GetReferenceNoteIDr)   r*   r   REGISTRYCreateRelativeName(ContaineranalysisProjectsNotesGetRequestprojects_notesGetr   r   r   r   r3   SBOMReferenceNoteNoteKindValueValuesEnumr   +ContaineranalysisProjectsNotesCreateRequest)r  r   r  r  note_idr}   get_requestr<  sbom_referencenew_notecreate_requests              r9   _CreateSbomRefNoteIfNotExistsrO    sx      "&$$&( 0 0$,,?'				"	"3 
# 
 LN	 8CCCNK  $$[1D" ))#**401	+# 
	.	. 8II299$?@// 0 N }}]]..==$  H II#**:*> J N
   ''7D8s   :-C CFFc                    t        j                         }|j                  j                         }|j                  j                         D ]E  \  }}|j                  j                  |j                  j                  j                  ||             G |j                  |||j                         t              }|j                  t        t        |      }	|j                  j                         }
| j                  j                         D ]E  \  }}|
j                  j                  |j                  j                  j                  ||             G |j                  |
| j                        }|	j                   j                  |       |j#                  |	t$              }|j'                  ||j(                  | j+                               }|S )ah  Create the SBOM reference note if not exists.

  Args:
    artifact: Artifact, the artifact metadata SBOM file generated from.
    sbom: SbomFile, metadata of the SBOM file.
    note: Note, the Note object we will use to attach occurrence.
    storage: str, the path that SBOM is stored remotely.

  Returns:
    An Occurrence object for the SBOM reference.
  )keyr   )r`   r[   mimeType
referrerId)predicateType_typer   )r`   r}   )r   payloadType)r   noteNamer   )r   r>  SbomReferenceIntotoPredicateDigestValuerN   itemsadditionalPropertiesappendAdditionalPropertyGetMimeType_SBOM_REFERENCE_REFERRERIDSbomReferenceIntotoPayload_SBOM_REFERENCE_PREDICATE_TYPE_SBOM_REFERENCE_TARGET_TYPESubjectrY   subjectSBOMReferenceOccurrence_SBOM_REFERENCE_PAYLOAD_TYPE
Occurrencer}   GetOccurrenceResourceUri)r   r   r<  storager  sbom_digsetskvr   r   artifact_digestssbom_subjectref_occr   s                 r9   _GenerateSbomRefOccurrencerp    s    $$&(66BBD,ll  "da%%,,--99LL 	M 	
 # 33!+	 4 ) //2' 0 '
 %%113$$&da))00$$77 	8 	
 ' !!H$9$9 " , 
//&,,. - '
 	yy335 	 	# 
*r;   c                 J    |j                  dd      }dj                  | |      S )Nr   r   zsbom-{0}-{1})ra   r3   )r)   sbom_versionsbom_version_encodeds      r9   r?  r?    s)    %--c37			{,@	AAr;   c                    t        j                         }|j                  | j                         g       |j	                  dg       t        |j                  |j                        }t        |j                  d            dkD  r|j                  d      d   }|j                  dj                  ||             |j                         S )Nr   ro   r'   r   z$noteId="{0}" AND noteProjectId="{1}")r   r   r   rh  r   r?  r)   r*   r   splitr   r3   r   )r   r   r  frJ  s        r9   $_GenerateSbomRefOccurrenceListFilterrw    s    ))+!//844678++ ! 0 0$,,?'		#	!#!!#&q)J,33GZH 
r;   c                 V    dt        |       | j                  d      t        |      |fz  S )a  Creates DSSEv1 Pre-Authentication encoding for given type and payload.

  Args:
    payload_type: str, the SBOM reference payload type.
    payload: bytes, the serialized SBOM reference payload.

  Returns:
    A bytes of DSSEv1 Pre-Authentication encoding.
  s   DSSEv1 %d %b %d %bzutf-8)r   encode)payload_typer   s     r9   _PAEr{  ,  s6     
	,'"	'l	" 
 r;   c                    t        j                  t        j                  | j                  j
                              }t        | j                  j                  |      }t        j                         }t        j                         }|j                  ||j                  |            }|j                  j                  |      }t        j                          }|j#                  ||j$                        }	|j'                  || j                  j                  |	g      | _        | j                  j*                  j-                  |	       | S )a   Add signatures in reference occurrence by using the given kms key.

  Args:
    occ: Occurrence, the SBOM reference occurrence object we want to sign.
    kms_key_version: str, a kms key used to sign the reference occurrence.

  Returns:
    An Occurrence object with signatures added.
  )r6   )r}   asymmetricSignRequest)keyidsig)r   rV  
signatures)r,   rL   r   MessageToJsonr   r   r{  rV  cloudkms_baseGetClientInstanceGetMessagesModuleQCloudkmsProjectsLocationsKeyRingsCryptoKeysCryptoKeyVersionsAsymmetricSignRequestAsymmetricSignRequest8projects_locations_keyRings_cryptoKeys_cryptoKeyVersionsAsymmetricSignr   r>  EnvelopeSignature	signatureEnvelopeenveloper  r\  )
r   kms_key_versionpayload_bytesr6   
kms_clientkms_messagesreqrespr  evelope_signatures
             r9   _SignSbomRefOccurrencePayloadr  ?  s+    ##S..667- 
c++]	;$..0*002,ff(>>D>I 	g 	# 
	L	L	[	[	
$ $$&(00 1  ""##//#$ # #,
 %%&78	*r;   c                 B   t        ||      }t        | |||      }|rt        ||      }t        | ||      }t	        j
                  dj                  |             t        j                         }t        j                         }	t        j                  ||d      }
t	        j
                  dj                  |
             d}|
D ]  }|} n |rht	        j
                  dj                  |j                               |	j                  |j                  |d      }|j                  j                  |      }n>|	j                  |dj                  |      	      }|j                  j!                  |      }t	        j
                  d
j                  |             |j                  S )a  Write the reference occurrence to link the artifact and the SBOM.

  Args:
    artifact: Artifact, the artifact metadata SBOM file generated from.
    project_id: str, the project_id where we will use to store the Occurrence.
    storage: str, the path that SBOM is stored remotely.
    sbom: SbomFile, metadata of the SBOM file.
    kms_key_version: str, the kms key to sign the reference occurrence payload.

  Returns:
    A str for occurrence ID.
  z#listing occurrence with filter {0}.Nzlist successfully: {}zupdating occurrence {0}.zsbom_reference,envelope)r}   
occurrence
updateMaskr9  r   )r  r:  zUsed occurrence: {0}.)rO  rp  r  rw  r   r   r3   r   r=  r>  r   r}   0ContaineranalysisProjectsOccurrencesPatchRequestprojects_occurrencesr  1ContaineranalysisProjectsOccurrencesCreateRequestrA  )r   r  ri  r   r  r<  r   rv  r  r  r   old_occr   r#  s                 r9   WriteReferenceOccurrencer  g  sw     
'z4	8$ 	#8T4A#
'_
=C +8T:F!))188;<  "&$$&(		$	$ZD	9$))#**401'aG	 
 II(//=>GG\\, H G
 
%
%
+
+G
4CHH#**:*> I G 
%
%
,
,W
5C))#**3/0	/r;   c                    | j                   st        j                  d      t        | j                   d      }t	        j
                  |      rt        |      }nt	        j                  |      rt        |      }t        j                         }t        j                  |j                        }|j                  |j                  j                  j                   k7  r9t        j                  d      t        j                  dj#                  |            t%        j&                  |       }|j                  r|j                  }t%        j(                  || j*                        }t-        j.                  |dj#                  |j0                              }t2        j4                  j7                  dj#                  |j0                  |j8                               y)zSExport SBOM files for a given AR image.

  Args:
    args: User input arguments.
  z--uri is required.r   zyThis command only supports Artifact Registry. You can enable redirection to use gcr.io repositories in Artifact Registry.z%{} is not an Artifact Registry image.r   zDExporting the SBOM file for resource {}. Discovery occurrence ID: {}N)rf   r1   r2   r   r   r   rj   r   rz   ar_requestsr>  GetProjectSettingsrZ   legacyRedirectionStateProjectSettings%LegacyRedirectionStateValueValuesEnumREDIRECTION_FROM_GCR_IO_ENABLEDr3   r   r   r   r[   r   ExportSbomV1beta1rY   r   r   r   discoveryOccurrenceId)r   rf   r   r  settingsrZ   r:  r  s           r9   
ExportSbomr    sz    


.
.  	dhh
+#  % %Hc"C H&&(H--h.>.>?H''##IIii	j 00J 
 
.
./66s;  OOD!'G>>'4==1&		&	&l!!("7"78
$ **Lv




$
$r;   c                   6    e Zd ZdZd Zed        Zed        Zy)r   zHolder for SBOM reference.

  Properties:
    occ: SBOM reference occurrence.
    file_info: Information of GCS object SBOM file.
  c                      || _         || _        y r   )_occ
_file_info)selfr   r   s      r9   __init__zSbomReference.__init__  s    DIDOr;   c                     | j                   S r   )r  r  s    r9   r   zSbomReference.occ  s    99r;   c                     | j                   S r   )r  r  s    r9   r   zSbomReference.file_info  s    ??r;   N)__name__
__module____qualname____doc__r  propertyr   r   r   r;   r9   r   r     s4         r;   r   c                   R    e Zd ZdZd Zd Zd Zed        Zed        Z	ed        Z
y)	r4   zHolder for SBOM file's metadata.

  Properties:
    sbom_format: Data format of the SBOM file.
    version: Version of the SBOM format.
    digests: A dictionary of digests, where key is the algorithm.
  c                 >    || _         || _        t               | _        y r   )_sbom_format_versiondict_digests)r  r)   r*   s      r9   r  zSbomFile.__init__  s    #DDMFDMr;   c                 r    | j                   t        k(  rt        S | j                   t        k(  rt        S t
        S r   )r  r5   _SBOM_REFERENCE_SPDX_MIME_TYPEr?   #_SBOM_REFERENCE_CYCLONEDX_MIME_TYPE!_SBOM_REFERENCE_DEFAULT_MIME_TYPEr  s    r9   r^  zSbomFile.GetMimeType  2    --++2200,,r;   c                 r    | j                   t        k(  rt        S | j                   t        k(  rt        S t
        S r   )r  r5   _SBOM_REFERENCE_SPDX_EXTENSIONr?   #_SBOM_REFERENCE_CYCLONEDX_EXTENSION!_SBOM_REFERENCE_DEFAULT_EXTENSIONr  s    r9   r   zSbomFile.GetExtension  r  r;   c                     | j                   S r   r  r  s    r9   rN   zSbomFile.digests      ==r;   c                     | j                   S r   )r  r  s    r9   r)   zSbomFile.sbom_format  s    r;   c                     | j                   S r   )r  r  s    r9   r*   zSbomFile.version  r  r;   N)r  r  r  r  r  r^  r   r  rN   r)   r*   r   r;   r9   r4   r4     sR    
--      r;   r4   c                   l    e Zd ZdZd Zed        Zed        Zed        Zed        Z	ed        Z
d Zy	)
rb   a{  Holder for Artifact's metadata.

  Properties:
    resource_uri: str, Uri will be used when storing as a reference occurrence.
    project: str, Project of the artifact.
    location: str, Location of the artifact.
    digests: A dictionary of digests, where key is the algorithm.
    artifact_type: str, Type of the provided artifact.
    scheme: str, Scheme of the registry.
  c                 X    || _         || _        || _        || _        || _        || _        y r   )_resource_uri_project	_locationr  _artifact_type_scheme)r  rY   rZ   r[   rN   r\   r]   s          r9   r  zArtifact.__init__  s0     &DDMDNDM'DDLr;   c                     | j                   S r   )r  r  s    r9   rY   zArtifact.resource_uri   s    r;   c                     | j                   S r   )r  r  s    r9   rZ   zArtifact.project$  r  r;   c                     | j                   S r   )r  r  s    r9   r[   zArtifact.location(  s    >>r;   c                     | j                   S r   r  r  s    r9   rN   zArtifact.digests,  r  r;   c                     | j                   S r   )r  r  s    r9   r\   zArtifact.artifact_type0  s    r;   c                     | j                   | j                  S dj                  | j                   | j                        S )Nz{scheme}://{uri})r]   rf   )r  rY   r3   r  s    r9   rh  z!Artifact.GetOccurrenceResourceUri4  s8    ||$$DLLd>O>O$PPr;   N)r  r  r  r  r  r  rY   rZ   r[   rN   r\   rh  r   r;   r9   rb   rb   
  sv    	          Qr;   rb   r   )gr  
__future__r   r   r   rK   r   r  r.   apitools.base.pyr   r   r   containerregistry.clientr   r	   containerregistry.client.v2_2r
   r   r   r   r   r    googlecloudsdk.api_lib.artifactsr1   googlecloudsdk.api_lib.cloudkmsr   r  'googlecloudsdk.api_lib.container.imagesr   rq   (googlecloudsdk.api_lib.containeranalysisr   r   r   googlecloudsdk.api_lib.storager   r   $googlecloudsdk.command_lib.artifactsr   r  #googlecloudsdk.command_lib.projectsr'  googlecloudsdk.corer   r   r   googlecloudsdk.core.utilr   r,   	six.movesr   r5   r?   rJ   rf  rb  ra  r  r  r  r_  r  r  r  r  r  _DEFAULT_DOCKER_REGISTRY_DEFAULT_DOCKER_REPOSITORY_REGISTRY_SCHEME_HTTPre   rd   rv   r   r:   r@   rT   rj   rz   r   r   r   r   r   r   r   r   r   r   r$  r3  rO  rp  r?  rw  r{  r  r  r  objectr   r4   rb   r   r;   r9   <module>r     s   ' &  '    	 % > 1 0 I D N H A D @ L 6 7 < H 5 D # ) * *  
  $ / 
  > A 6  "9 $6 !&F #D  "- $* !&0 #;  4 &    +   B4G<!H4.b>:zB`2F1'DB
;|M`(V:zB

&%P5p*ZF *&v &R-Qv -Qr;   