@@ -3,7 +3,9 @@ const fetch = require('npm-registry-fetch')
33const  localeCompare  =  require ( '@isaacs/string-locale-compare' ) ( 'en' ) 
44const  npa  =  require ( 'npm-package-arg' ) 
55const  pacote  =  require ( 'pacote' ) 
6+ const  path  =  require ( 'path' ) 
67const  pMap  =  require ( 'p-map' ) 
8+ const  {  sigstore }  =  require ( 'sigstore' ) 
79
810const  ArboristWorkspaceCmd  =  require ( '../arborist-cmd.js' ) 
911const  auditError  =  require ( '../utils/audit-error.js' ) 
@@ -188,19 +190,42 @@ class VerifySignatures {
188190 } 
189191
190192 async  setKeys  ( {  registry } )  { 
191-  const  keys  =  await  fetch . json ( '/-/npm/v1/keys' ,  { 
192-  ...this . npm . flatOptions , 
193-  registry, 
194-  } ) . then ( ( {  keys : ks  } )  =>  ks . map ( ( key )  =>  ( { 
195-  ...key , 
196-  pemkey : `-----BEGIN PUBLIC KEY-----\n${ key . key }  \n-----END PUBLIC KEY-----` , 
197-  } ) ) ) . catch ( err  =>  { 
198-  if  ( err . code  ===  'E404'  ||  err . code  ===  'E400' )  { 
199-  return  null 
200-  }  else  { 
201-  throw  err 
202-  } 
203-  } ) 
193+  const  {  host,  pathname }  =  new  URL ( registry ) 
194+  // Strip any trailing slashes from pathname 
195+  const  regKey  =  `${ host } ${ pathname . replace ( / \/ $ / ,  '' ) }  /keys.json` 
196+  const  tufCachePath  =  path . join ( this . npm . cache ,  '_tuf' ) 
197+  let  keys  =  await  sigstore . tuf . getTarget ( regKey ,  {  tufCachePath } ) 
198+  . then ( ( target )  =>  JSON . parse ( target ) ) 
199+  . then ( ( {  keys : ks  } )  =>  ks . map ( ( key )  =>  ( { 
200+  ...key , 
201+  keyid : key . keyId , 
202+  pemkey : `-----BEGIN PUBLIC KEY-----\n${ key . publicKey . rawBytes }  \n-----END PUBLIC KEY-----` , 
203+  expires : key . publicKey . validFor . end  ||  null , 
204+  } ) ) ) . catch ( err  =>  { 
205+  if  ( err . code  ===  'TUF_FIND_TARGET_ERROR' )  { 
206+  return  null 
207+  }  else  { 
208+  throw  err 
209+  } 
210+  } ) 
211+ 
212+  // If keys not found in Sigstore TUF repo, fallback to registry keys API 
213+  if  ( ! keys )  { 
214+  keys  =  await  fetch . json ( '/-/npm/v1/keys' ,  { 
215+  ...this . npm . flatOptions , 
216+  registry, 
217+  } ) . then ( ( {  keys : ks  } )  =>  ks . map ( ( key )  =>  ( { 
218+  ...key , 
219+  pemkey : `-----BEGIN PUBLIC KEY-----\n${ key . key }  \n-----END PUBLIC KEY-----` , 
220+  } ) ) ) . catch ( err  =>  { 
221+  if  ( err . code  ===  'E404'  ||  err . code  ===  'E400' )  { 
222+  return  null 
223+  }  else  { 
224+  throw  err 
225+  } 
226+  } ) 
227+  } 
228+ 
204229 if  ( keys )  { 
205230 this . keys . set ( registry ,  keys ) 
206231 } 
0 commit comments