@@ -3,7 +3,9 @@ const fetch = require('npm-registry-fetch')
3
3
const localeCompare = require ( '@isaacs/string-locale-compare' ) ( 'en' )
4
4
const npa = require ( 'npm-package-arg' )
5
5
const pacote = require ( 'pacote' )
6
+ const path = require ( 'path' )
6
7
const pMap = require ( 'p-map' )
8
+ const { sigstore } = require ( 'sigstore' )
7
9
8
10
const ArboristWorkspaceCmd = require ( '../arborist-cmd.js' )
9
11
const auditError = require ( '../utils/audit-error.js' )
@@ -188,19 +190,42 @@ class VerifySignatures {
188
190
}
189
191
190
192
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
+
204
229
if ( keys ) {
205
230
this . keys . set ( registry , keys )
206
231
}
0 commit comments