@@ -34,6 +34,13 @@ import {DownloadVersion} from '../types/cosign/cosign';
3434import { GitHubRelease } from '../types/github' ;
3535import { dockerfileContent } from './dockerfile' ;
3636
37+ export interface DownloadOpts {
38+ version : string ;
39+ ghaNoCache ?: boolean ;
40+ skipState ?: boolean ;
41+ verifySignature ?: boolean ;
42+ }
43+
3744export interface InstallOpts {
3845 githubToken ?: string ;
3946 buildx ?: Buildx ;
@@ -48,8 +55,8 @@ export class Install {
4855 this . buildx = opts ?. buildx || new Buildx ( ) ;
4956 }
5057
51- public async download ( v : string , ghaNoCache ?: boolean , skipState ?: boolean ) : Promise < string > {
52- const version : DownloadVersion = await Install . getDownloadVersion ( v ) ;
58+ public async download ( opts : DownloadOpts ) : Promise < string > {
59+ const version : DownloadVersion = await Install . getDownloadVersion ( opts . version ) ;
5360 core . debug ( `Install.download version: ${ version . version } ` ) ;
5461
5562 const release : GitHubRelease = await Install . getRelease ( version , this . githubToken ) ;
@@ -68,7 +75,7 @@ export class Install {
6875 htcVersion : vspec ,
6976 baseCacheDir : path . join ( os . homedir ( ) , '.bin' ) ,
7077 cacheFile : os . platform ( ) == 'win32' ? 'cosign.exe' : 'cosign' ,
71- ghaNoCache : ghaNoCache
78+ ghaNoCache : opts . ghaNoCache
7279 } ) ;
7380
7481 const cacheFoundPath = await installCache . find ( ) ;
@@ -83,7 +90,11 @@ export class Install {
8390 const htcDownloadPath = await tc . downloadTool ( downloadURL , undefined , this . githubToken ) ;
8491 core . debug ( `Install.download htcDownloadPath: ${ htcDownloadPath } ` ) ;
8592
86- const cacheSavePath = await installCache . save ( htcDownloadPath , skipState ) ;
93+ if ( opts . verifySignature && semver . satisfies ( vspec , '>=3.0.1' ) ) {
94+ await this . verifySignature ( htcDownloadPath , downloadURL ) ;
95+ }
96+
97+ const cacheSavePath = await installCache . save ( htcDownloadPath , opts . skipState ) ;
8798 core . info ( `Cached to ${ cacheSavePath } ` ) ;
8899 return cacheSavePath ;
89100 }
@@ -176,6 +187,27 @@ export class Install {
176187 return await new Buildx ( { standalone : buildStandalone } ) . getCommand ( args ) ;
177188 }
178189
190+ private async verifySignature ( cosignBinPath : string , downloadURL : string ) : Promise < void > {
191+ const cosignBootstrapPath = path . join ( Context . tmpDir ( ) , `cosign-bootstrap${ os . platform ( ) == 'win32' ? '.exe' : '' } ` ) ;
192+ fs . copyFileSync ( cosignBinPath , cosignBootstrapPath ) ;
193+ fs . chmodSync ( cosignBootstrapPath , '0755' ) ;
194+
195+ const bundleURL = `${ downloadURL } .sigstore.json` ;
196+ core . info ( `Downloading keyless verification bundle at ${ bundleURL } ` ) ;
197+ const bundlePath = await tc . downloadTool ( bundleURL , undefined , this . githubToken ) ;
198+ core . debug ( `Install.verifySignature bundlePath: ${ bundlePath } ` ) ;
199+
200+ core . info ( `Verifying cosign binary signature with keyless verification bundle` ) ;
201+ // prettier-ignore
202+ await Exec . exec ( cosignBootstrapPath , [
203+ 'verify-blob' ,
204+ '--certificate-identity' , 'keyless@projectsigstore.iam.gserviceaccount.com' ,
205+ '--certificate-oidc-issuer' , 'https://accounts.google.com' ,
206+ '--bundle' , bundlePath ,
207+ cosignBinPath
208+ ] ) ;
209+ }
210+
179211 private filename ( ) : string {
180212 let arch : string ;
181213 switch ( os . arch ( ) ) {
0 commit comments