@@ -12,39 +12,63 @@ import (
1212
1313 "github.com/theupdateframework/go-tuf/data"
1414 "github.com/theupdateframework/go-tuf/encrypted"
15+ "github.com/theupdateframework/go-tuf/internal/sets"
1516 "github.com/theupdateframework/go-tuf/pkg/keys"
1617 "github.com/theupdateframework/go-tuf/util"
1718)
1819
19- func signers (privateKeys []* data.PrivateKey ) []keys.Signer {
20- res := make ([]keys.Signer , 0 , len (privateKeys ))
21- for _ , k := range privateKeys {
22- signer , err := keys .GetSigner (k )
23- if err != nil {
24- continue
25- }
26- res = append (res , signer )
27- }
28- return res
20+ type LocalStore interface {
21+ // GetMeta returns a map from metadata file names (e.g. root.json) to their raw JSON payload or an error.
22+ GetMeta () (map [string ]json.RawMessage , error )
23+
24+ // SetMeta is used to update a metadata file name with a JSON payload.
25+ SetMeta (name string , meta json.RawMessage ) error
26+
27+ // WalkStagedTargets calls targetsFn for each staged target file in paths.
28+ // If paths is empty, all staged target files will be walked.
29+ WalkStagedTargets (paths []string , targetsFn TargetsWalkFunc ) error
30+
31+ // Commit is used to publish staged files to the repository
32+ Commit (consistentSnapshot bool , versions map [string ]int , hashes map [string ]data.Hashes ) error
33+
34+ // GetSigners return a list of signers for a role.
35+ GetSigners (role string ) ([]keys.Signer , error )
36+
37+ // SaveSigner adds a signer to a role.
38+ SaveSigner (role string , signer keys.Signer ) error
39+
40+ // SignersForRole return a list of signing keys for a role.
41+ SignersForKeyIDs (keyIDs []string ) []keys.Signer
42+
43+ // Clean is used to remove all staged manifests.
44+ Clean () error
45+ }
46+
47+ type PassphraseChanger interface {
48+ // ChangePassphrase changes the passphrase for a role keys file.
49+ ChangePassphrase (string ) error
2950}
3051
3152func MemoryStore (meta map [string ]json.RawMessage , files map [string ][]byte ) LocalStore {
3253 if meta == nil {
3354 meta = make (map [string ]json.RawMessage )
3455 }
3556 return & memoryStore {
36- meta : meta ,
37- stagedMeta : make (map [string ]json.RawMessage ),
38- files : files ,
39- signers : make (map [string ][]keys.Signer ),
57+ meta : meta ,
58+ stagedMeta : make (map [string ]json.RawMessage ),
59+ files : files ,
60+ signerForKeyID : make (map [string ]keys.Signer ),
61+ keyIDsForRole : make (map [string ][]string ),
4062 }
4163}
4264
4365type memoryStore struct {
4466 meta map [string ]json.RawMessage
4567 stagedMeta map [string ]json.RawMessage
4668 files map [string ][]byte
47- signers map [string ][]keys.Signer
69+
70+ signerForKeyID map [string ]keys.Signer
71+ keyIDsForRole map [string ][]string
4872}
4973
5074func (m * memoryStore ) GetMeta () (map [string ]json.RawMessage , error ) {
@@ -96,14 +120,53 @@ func (m *memoryStore) Commit(consistentSnapshot bool, versions map[string]int, h
96120}
97121
98122func (m * memoryStore ) GetSigners (role string ) ([]keys.Signer , error ) {
99- return m .signers [role ], nil
123+ keyIDs , ok := m .keyIDsForRole [role ]
124+ if ok {
125+ return m .SignersForKeyIDs (keyIDs ), nil
126+ }
127+
128+ return nil , nil
100129}
101130
102131func (m * memoryStore ) SaveSigner (role string , signer keys.Signer ) error {
103- m .signers [role ] = append (m .signers [role ], signer )
132+ keyIDs := signer .PublicData ().IDs ()
133+
134+ for _ , keyID := range keyIDs {
135+ m .signerForKeyID [keyID ] = signer
136+ }
137+
138+ mergedKeyIDs := sets .DeduplicateStrings (append (m .keyIDsForRole [role ], keyIDs ... ))
139+ m .keyIDsForRole [role ] = mergedKeyIDs
104140 return nil
105141}
106142
143+ func (m * memoryStore ) SignersForKeyIDs (keyIDs []string ) []keys.Signer {
144+ signers := []keys.Signer {}
145+ keyIDsSeen := map [string ]struct {}{}
146+
147+ for _ , keyID := range keyIDs {
148+ signer , ok := m .signerForKeyID [keyID ]
149+ if ! ok {
150+ continue
151+ }
152+ addSigner := false
153+
154+ for _ , skid := range signer .PublicData ().IDs () {
155+ if _ , seen := keyIDsSeen [skid ]; ! seen {
156+ addSigner = true
157+ }
158+
159+ keyIDsSeen [skid ] = struct {}{}
160+ }
161+
162+ if addSigner {
163+ signers = append (signers , signer )
164+ }
165+ }
166+
167+ return signers
168+ }
169+
107170func (m * memoryStore ) Clean () error {
108171 return nil
109172}
@@ -117,16 +180,17 @@ func FileSystemStore(dir string, p util.PassphraseFunc) LocalStore {
117180 return & fileSystemStore {
118181 dir : dir ,
119182 passphraseFunc : p ,
120- signers : make (map [string ][]keys.Signer ),
183+ signerForKeyID : make (map [string ]keys.Signer ),
184+ keyIDsForRole : make (map [string ][]string ),
121185 }
122186}
123187
124188type fileSystemStore struct {
125189 dir string
126190 passphraseFunc util.PassphraseFunc
127191
128- // signers is a cache of persisted keys to avoid decrypting multiple times
129- signers map [string ][]keys. Signer
192+ signerForKeyID map [ string ] keys. Signer
193+ keyIDsForRole map [string ][]string
130194}
131195
132196func (f * fileSystemStore ) repoDir () string {
@@ -319,18 +383,63 @@ func (f *fileSystemStore) Commit(consistentSnapshot bool, versions map[string]in
319383}
320384
321385func (f * fileSystemStore ) GetSigners (role string ) ([]keys.Signer , error ) {
322- if keys , ok := f .signers [role ]; ok {
323- return keys , nil
386+ keyIDs , ok := f .keyIDsForRole [role ]
387+ if ok {
388+ return f .SignersForKeyIDs (keyIDs ), nil
324389 }
325- keys , _ , err := f .loadPrivateKeys (role )
390+
391+ privKeys , _ , err := f .loadPrivateKeys (role )
326392 if err != nil {
327393 if os .IsNotExist (err ) {
328394 return nil , nil
329395 }
330396 return nil , err
331397 }
332- f .signers [role ] = signers (keys )
333- return f .signers [role ], nil
398+
399+ signers := []keys.Signer {}
400+ for _ , key := range privKeys {
401+ signer , err := keys .GetSigner (key )
402+ if err != nil {
403+ return nil , err
404+ }
405+
406+ // Cache the signers.
407+ for _ , keyID := range signer .PublicData ().IDs () {
408+ f .keyIDsForRole [role ] = append (f .keyIDsForRole [role ], keyID )
409+ f .signerForKeyID [keyID ] = signer
410+ }
411+ signers = append (signers , signer )
412+ }
413+
414+ return signers , nil
415+ }
416+
417+ func (f * fileSystemStore ) SignersForKeyIDs (keyIDs []string ) []keys.Signer {
418+ signers := []keys.Signer {}
419+ keyIDsSeen := map [string ]struct {}{}
420+
421+ for _ , keyID := range keyIDs {
422+ signer , ok := f .signerForKeyID [keyID ]
423+ if ! ok {
424+ continue
425+ }
426+
427+ addSigner := false
428+
429+ for _ , skid := range signer .PublicData ().IDs () {
430+ if _ , seen := keyIDsSeen [skid ]; ! seen {
431+ addSigner = true
432+ }
433+
434+ keyIDsSeen [skid ] = struct {}{}
435+ }
436+
437+ if addSigner {
438+ signers = append (signers , signer )
439+ }
440+ }
441+
442+ return signers
334443}
335444
336445// ChangePassphrase changes the passphrase for a role keys file. Implements
@@ -377,15 +486,15 @@ func (f *fileSystemStore) SaveSigner(role string, signer keys.Signer) error {
377486 }
378487
379488 // add the key to the existing keys (if any)
380- keys , pass , err := f .loadPrivateKeys (role )
489+ privKeys , pass , err := f .loadPrivateKeys (role )
381490 if err != nil && ! os .IsNotExist (err ) {
382491 return err
383492 }
384493 key , err := signer .MarshalPrivateKey ()
385494 if err != nil {
386495 return err
387496 }
388- keys = append (keys , key )
497+ privKeys = append (privKeys , key )
389498
390499 // if loadPrivateKeys didn't return a passphrase (because no keys yet exist)
391500 // and passphraseFunc is set, get the passphrase so the keys file can
@@ -400,13 +509,13 @@ func (f *fileSystemStore) SaveSigner(role string, signer keys.Signer) error {
400509
401510 pk := & persistedKeys {}
402511 if pass != nil {
403- pk .Data , err = encrypted .Marshal (keys , pass )
512+ pk .Data , err = encrypted .Marshal (privKeys , pass )
404513 if err != nil {
405514 return err
406515 }
407516 pk .Encrypted = true
408517 } else {
409- pk .Data , err = json .MarshalIndent (keys , "" , "\t " )
518+ pk .Data , err = json .MarshalIndent (privKeys , "" , "\t " )
410519 if err != nil {
411520 return err
412521 }
@@ -418,7 +527,26 @@ func (f *fileSystemStore) SaveSigner(role string, signer keys.Signer) error {
418527 if err := util .AtomicallyWriteFile (f .keysPath (role ), append (data , '\n' ), 0600 ); err != nil {
419528 return err
420529 }
421- f .signers [role ] = append (f .signers [role ], signer )
530+
531+ innerKeyIdsForRole := f .keyIDsForRole [role ]
532+
533+ for _ , key := range privKeys {
534+ signer , err := keys .GetSigner (key )
535+ if err != nil {
536+ return err
537+ }
538+
539+ keyIDs := signer .PublicData ().IDs ()
540+
541+ for _ , keyID := range keyIDs {
542+ f .signerForKeyID [keyID ] = signer
543+ }
544+
545+ innerKeyIdsForRole = append (innerKeyIdsForRole , keyIDs ... )
546+ }
547+
548+ f .keyIDsForRole [role ] = sets .DeduplicateStrings (innerKeyIdsForRole )
549+
422550 return nil
423551}
424552
0 commit comments