@@ -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