diff --git a/client/client.go b/client/client.go index 8e226905..17ddc980 100644 --- a/client/client.go +++ b/client/client.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "encoding/json" "io" - "log" "github.com/theupdateframework/go-tuf/data" "github.com/theupdateframework/go-tuf/util" @@ -89,10 +88,6 @@ type Client struct { // consistent snapshots (as specified in root.json) consistentSnapshot bool - // this is an optional log writer. - // if nil, uses io.Discard - logger *log.Logger - // MaxDelegations limits by default the number of delegations visited for any // target MaxDelegations int @@ -101,26 +96,13 @@ type Client struct { MaxRootRotations int } -type ClientOpts func(c *Client) - -func WithLogger(logger *log.Logger) ClientOpts { - return func(c *Client) { - c.logger = logger - } -} - -func NewClient(local LocalStore, remote RemoteStore, opts ...ClientOpts) *Client { - client := &Client{ +func NewClient(local LocalStore, remote RemoteStore) *Client { + return &Client{ local: local, remote: remote, MaxDelegations: defaultMaxDelegations, MaxRootRotations: defaultMaxRootRotations, - logger: log.New(io.Discard, "", 0), - } - for _, opt := range opts { - opt(client) } - return client } // Init initializes a local repository from root metadata. @@ -470,8 +452,7 @@ func (c *Client) loadAndVerifyRootMeta(rootJSON []byte, ignoreExpiredCheck bool) if err := json.Unmarshal(s.Signed, root); err != nil { return err } - - ndb := verify.NewDB(verify.WithLogger(c.logger)) + ndb := verify.NewDB() for id, k := range root.Keys { if err := ndb.AddKey(id, k); err != nil { return err @@ -519,7 +500,7 @@ func (c *Client) verifyRoot(aJSON []byte, bJSON []byte) (*data.Root, error) { return nil, err } - ndb := verify.NewDB(verify.WithLogger(c.logger)) + ndb := verify.NewDB() for id, k := range aRoot.Keys { if err := ndb.AddKey(id, k); err != nil { return nil, err diff --git a/client/delegations.go b/client/delegations.go index 773226c7..de3e6647 100644 --- a/client/delegations.go +++ b/client/delegations.go @@ -43,8 +43,7 @@ func (c *Client) getTargetFileMeta(target string) (data.TargetFileMeta, error) { } if targets.Delegations != nil { - delegationsDB, err := verify.NewDBFromDelegations(targets.Delegations, - verify.WithLogger(c.logger)) + delegationsDB, err := verify.NewDBFromDelegations(targets.Delegations) if err != nil { return data.TargetFileMeta{}, err } diff --git a/internal/fsutil/perm_test.go b/internal/fsutil/perm_test.go index 6061d291..f80ef94a 100644 --- a/internal/fsutil/perm_test.go +++ b/internal/fsutil/perm_test.go @@ -4,7 +4,6 @@ package fsutil import ( - "fmt" "os" "path/filepath" "testing" @@ -59,7 +58,6 @@ func TestEnsureMaxPermissions(t *testing.T) { assert.NoError(t, err) err = EnsureMaxPermissions(fi, os.FileMode(0222)) assert.Error(t, err) - fmt.Println(err) // Check matching due to more restrictive perms on file err = os.Chmod(p, 0444) diff --git a/local_store.go b/local_store.go index 1b4a7f60..fee03f31 100644 --- a/local_store.go +++ b/local_store.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "io/fs" + "log" "os" "path/filepath" "strings" @@ -197,18 +198,44 @@ type persistedKeys struct { Data json.RawMessage `json:"data"` } +type StoreOpts struct { + Logger *log.Logger + PassFunc util.PassphraseFunc +} + func FileSystemStore(dir string, p util.PassphraseFunc) LocalStore { return &fileSystemStore{ dir: dir, passphraseFunc: p, + logger: log.New(io.Discard, "", 0), signerForKeyID: make(map[string]keys.Signer), keyIDsForRole: make(map[string][]string), } } +func FileSystemStoreWithOpts(dir string, opts ...StoreOpts) LocalStore { + store := &fileSystemStore{ + dir: dir, + passphraseFunc: nil, + logger: log.New(io.Discard, "", 0), + signerForKeyID: make(map[string]keys.Signer), + keyIDsForRole: make(map[string][]string), + } + for _, opt := range opts { + if opt.Logger != nil { + store.logger = opt.Logger + } + if opt.PassFunc != nil { + store.passphraseFunc = opt.PassFunc + } + } + return store +} + type fileSystemStore struct { dir string passphraseFunc util.PassphraseFunc + logger *log.Logger signerForKeyID map[string]keys.Signer keyIDsForRole map[string][]string @@ -526,7 +553,7 @@ func (f *fileSystemStore) ChangePassphrase(role string) error { keys, _, err := f.loadPrivateKeys(role) if err != nil { if os.IsNotExist(err) { - fmt.Printf("Failed to change passphrase. Missing keys file for %s role. \n", role) + f.logger.Printf("Failed to change passphrase. Missing keys file for %s role. \n", role) } return err } @@ -548,7 +575,7 @@ func (f *fileSystemStore) ChangePassphrase(role string) error { if err := util.AtomicallyWriteFile(f.keysPath(role), append(data, '\n'), 0600); err != nil { return err } - fmt.Printf("Successfully changed passphrase for %s keys file\n", role) + f.logger.Printf("Successfully changed passphrase for %s keys file\n", role) return nil } diff --git a/pkg/deprecated/deprecated_repo_test.go b/pkg/deprecated/deprecated_repo_test.go index 9500219f..6d194ab5 100644 --- a/pkg/deprecated/deprecated_repo_test.go +++ b/pkg/deprecated/deprecated_repo_test.go @@ -1,14 +1,11 @@ package deprecated import ( - "bytes" "crypto" "crypto/elliptic" "crypto/rand" "crypto/sha256" "encoding/json" - "log" - "strings" "testing" "github.com/secure-systems-lab/go-securesystemslib/cjson" @@ -37,10 +34,7 @@ func genKey(c *C, r *repo.Repo, role string) []string { func (rs *RepoSuite) TestDeprecatedHexEncodedKeysSucceed(c *C) { files := map[string][]byte{"foo.txt": []byte("foo")} local := repo.MemoryStore(make(map[string]json.RawMessage), files) - var logBytes bytes.Buffer - opts := repo.WithLogger(log.New(&logBytes, "", 0)) - - r, err := repo.NewRepoWithOpts(local, opts) + r, err := repo.NewRepo(local) c.Assert(err, IsNil) r.Init(false) @@ -85,7 +79,4 @@ func (rs *RepoSuite) TestDeprecatedHexEncodedKeysSucceed(c *C) { c.Assert(r.Snapshot(), IsNil) c.Assert(r.Timestamp(), IsNil) c.Assert(r.Commit(), IsNil) - - // Check logs. - c.Assert(strings.Contains(logBytes.String(), keys.WarnDeprecatedEcdsaKey), Equals, true) } diff --git a/pkg/keys/deprecated_ecdsa.go b/pkg/keys/deprecated_ecdsa.go index d12a22bf..6d48c9d6 100644 --- a/pkg/keys/deprecated_ecdsa.go +++ b/pkg/keys/deprecated_ecdsa.go @@ -9,25 +9,12 @@ import ( "errors" "fmt" "io" - "log" "github.com/theupdateframework/go-tuf/data" ) -var ( - WarnDeprecatedEcdsaKey = "tuf: warning using deprecated ecdsa hex-encoded keys" -) - -func NewDeprecatedEcdsaVerifier(opts ...VerifierOpts) Verifier { - verifier := &ecdsaVerifierWithDeprecatedSupport{ - logger: log.New(io.Discard, "", log.LstdFlags), - } - for _, opt := range opts { - if opt.Logger != nil { - verifier.logger = opt.Logger - } - } - return verifier +func NewDeprecatedEcdsaVerifier() Verifier { + return &ecdsaVerifierWithDeprecatedSupport{} } type ecdsaVerifierWithDeprecatedSupport struct { @@ -35,8 +22,6 @@ type ecdsaVerifierWithDeprecatedSupport struct { // This will switch based on whether this is a PEM-encoded key // or a deprecated hex-encoded key. Verifier - // This is used to write the deprecated warning to. - logger *log.Logger } func (p *ecdsaVerifierWithDeprecatedSupport) UnmarshalPublicKey(key *data.PublicKey) error { @@ -44,9 +29,7 @@ func (p *ecdsaVerifierWithDeprecatedSupport) UnmarshalPublicKey(key *data.Public pemVerifier := &EcdsaVerifier{} if err := pemVerifier.UnmarshalPublicKey(key); err != nil { // Try the deprecated hex-encoded verifier - hexVerifier := &deprecatedP256Verifier{ - logger: p.logger, - } + hexVerifier := &deprecatedP256Verifier{} if err := hexVerifier.UnmarshalPublicKey(key); err != nil { return err } @@ -67,8 +50,6 @@ func (p *ecdsaVerifierWithDeprecatedSupport) UnmarshalPublicKey(key *data.Public type deprecatedP256Verifier struct { PublicKey data.HexBytes `json:"public"` key *data.PublicKey - // This is used to write the deprecated warning to. - logger *log.Logger } func (p *deprecatedP256Verifier) Public() string { @@ -116,6 +97,5 @@ func (p *deprecatedP256Verifier) UnmarshalPublicKey(key *data.PublicKey) error { } p.key = key - p.logger.Print(WarnDeprecatedEcdsaKey) return nil } diff --git a/pkg/keys/deprecated_ecdsa_test.go b/pkg/keys/deprecated_ecdsa_test.go index 57563b29..ddfaa84d 100644 --- a/pkg/keys/deprecated_ecdsa_test.go +++ b/pkg/keys/deprecated_ecdsa_test.go @@ -1,7 +1,6 @@ package keys import ( - "bytes" "crypto" "crypto/ecdsa" "crypto/elliptic" @@ -9,8 +8,6 @@ import ( "crypto/sha256" "encoding/json" "errors" - "log" - "strings" "github.com/theupdateframework/go-tuf/data" . "gopkg.in/check.v1" @@ -130,21 +127,3 @@ func (DeprecatedECDSASuite) TestMarshalUnmarshalPublicKey(c *C) { c.Assert(deprecatedEcdsa.MarshalPublicKey(), DeepEquals, pub) } - -func (DeprecatedECDSASuite) TestLogMessageWriter(c *C) { - signer, err := generatedDeprecatedSigner() - c.Assert(err, IsNil) - - pub := signer.PublicData() - - var logBytes bytes.Buffer - opts := WithLogger(log.New(&logBytes, "", 0)) - - deprecatedEcdsa := NewDeprecatedEcdsaVerifier(opts) - err = deprecatedEcdsa.UnmarshalPublicKey(pub) - c.Assert(err, IsNil) - c.Assert(strings.TrimSuffix(logBytes.String(), "\n"), Equals, - WarnDeprecatedEcdsaKey) - - c.Assert(deprecatedEcdsa.MarshalPublicKey(), DeepEquals, pub) -} diff --git a/pkg/keys/ecdsa.go b/pkg/keys/ecdsa.go index c7083e8a..ee93e330 100644 --- a/pkg/keys/ecdsa.go +++ b/pkg/keys/ecdsa.go @@ -24,7 +24,7 @@ func init() { SignerMap.Store(data.KeyTypeECDSA_SHA2_P256, newEcdsaSigner) } -func NewEcdsaVerifier(_ ...VerifierOpts) Verifier { +func NewEcdsaVerifier() Verifier { return &EcdsaVerifier{} } diff --git a/pkg/keys/ed25519.go b/pkg/keys/ed25519.go index f7309b1b..1e4c66cc 100644 --- a/pkg/keys/ed25519.go +++ b/pkg/keys/ed25519.go @@ -23,7 +23,7 @@ func NewEd25519Signer() Signer { return &ed25519Signer{} } -func NewEd25519Verifier(_ ...VerifierOpts) Verifier { +func NewEd25519Verifier() Verifier { return &ed25519Verifier{} } diff --git a/pkg/keys/keys.go b/pkg/keys/keys.go index 7ac9c13e..dc5f3ea2 100644 --- a/pkg/keys/keys.go +++ b/pkg/keys/keys.go @@ -3,7 +3,6 @@ package keys import ( "errors" "fmt" - "log" "sync" "github.com/theupdateframework/go-tuf/data" @@ -58,20 +57,12 @@ type Signer interface { SignMessage(message []byte) ([]byte, error) } -type VerifierOpts struct { - Logger *log.Logger -} - -func WithLogger(logger *log.Logger) VerifierOpts { - return VerifierOpts{logger} -} - -func GetVerifier(key *data.PublicKey, opts ...VerifierOpts) (Verifier, error) { +func GetVerifier(key *data.PublicKey) (Verifier, error) { st, ok := VerifierMap.Load(key.Type) if !ok { return nil, ErrInvalidKey } - s := st.(func(opts ...VerifierOpts) Verifier)(opts...) + s := st.(func() Verifier)() if err := s.UnmarshalPublicKey(key); err != nil { return nil, fmt.Errorf("tuf: error unmarshalling key: %w", err) } diff --git a/pkg/keys/rsa.go b/pkg/keys/rsa.go index 3fc82cde..618f104e 100644 --- a/pkg/keys/rsa.go +++ b/pkg/keys/rsa.go @@ -21,7 +21,7 @@ func init() { SignerMap.Store(data.KeyTypeRSASSA_PSS_SHA256, newRsaSigner) } -func newRsaVerifier(_ ...VerifierOpts) Verifier { +func newRsaVerifier() Verifier { return &rsaVerifier{} } diff --git a/repo.go b/repo.go index cb4fb976..cce0020f 100644 --- a/repo.go +++ b/repo.go @@ -137,7 +137,7 @@ func (r *Repo) Init(consistentSnapshot bool) error { } func (r *Repo) topLevelKeysDB() (*verify.DB, error) { - db := verify.NewDB(verify.WithLogger(r.logger)) + db := verify.NewDB() root, err := r.root() if err != nil { return nil, err @@ -975,7 +975,7 @@ func (r *Repo) delegatorDBs(delegateeRole string) ([]*verify.DB, error) { continue } - db, err := verify.NewDBFromDelegations(t.Delegations, verify.WithLogger(r.logger)) + db, err := verify.NewDBFromDelegations(t.Delegations) if err != nil { return nil, err } @@ -1024,8 +1024,7 @@ func (r *Repo) targetDelegationForPath(path string, preferredRole string) (*data } if targetsMeta.Delegations != nil && len(targetsMeta.Delegations.Roles) > 0 { - db, err := verify.NewDBFromDelegations(targetsMeta.Delegations, - verify.WithLogger(r.logger)) + db, err := verify.NewDBFromDelegations(targetsMeta.Delegations) if err != nil { return nil, nil, err } diff --git a/repo_test.go b/repo_test.go index 2f3aebb4..d841bb59 100644 --- a/repo_test.go +++ b/repo_test.go @@ -9,6 +9,7 @@ import ( "encoding/json" "errors" "fmt" + "log" "os" "path" "path/filepath" @@ -1422,7 +1423,12 @@ func (rs *RepoSuite) TestKeyPersistence(c *C) { // Test changing the passphrase // 1. Create a secure store with a passphrase (create new object and temp folder so we discard any previous state) tmp = newTmpDir(c) - store = FileSystemStore(tmp.path, testPassphraseFunc) + var logBytes bytes.Buffer + storeOpts := StoreOpts{ + Logger: log.New(&logBytes, "", 0), + PassFunc: testPassphraseFunc, + } + store = FileSystemStoreWithOpts(tmp.path, storeOpts) // 1.5. Changing passphrase works for top-level and delegated roles. r, err := NewRepo(store) @@ -1433,6 +1439,7 @@ func (rs *RepoSuite) TestKeyPersistence(c *C) { // 2. Test changing the passphrase when the keys file does not exist - should FAIL c.Assert(store.(PassphraseChanger).ChangePassphrase("root"), NotNil) + c.Assert(strings.Contains(logBytes.String(), "Missing keys file"), Equals, true) // 3. Generate a new key signer, err = keys.GenerateEd25519Key() diff --git a/verify/db.go b/verify/db.go index acaf7b6e..04f5bf1c 100644 --- a/verify/db.go +++ b/verify/db.go @@ -1,9 +1,6 @@ package verify import ( - "io" - "log" - "github.com/theupdateframework/go-tuf/data" "github.com/theupdateframework/go-tuf/internal/roles" "github.com/theupdateframework/go-tuf/pkg/keys" @@ -22,33 +19,22 @@ func (r *Role) ValidKey(id string) bool { type DB struct { roles map[string]*Role verifiers map[string]keys.Verifier - logger *log.Logger -} - -type DBOpts func(db *DB) - -func WithLogger(logger *log.Logger) DBOpts { - return func(db *DB) { - db.logger = logger - } } -func NewDB(opts ...DBOpts) *DB { - db := &DB{ +func NewDB() *DB { + return &DB{ roles: make(map[string]*Role), verifiers: make(map[string]keys.Verifier), - logger: log.New(io.Discard, "", 0), - } - for _, opt := range opts { - opt(db) } - return db } // NewDBFromDelegations returns a DB that verifies delegations // of a given Targets. -func NewDBFromDelegations(d *data.Delegations, opts ...DBOpts) (*DB, error) { - db := NewDB(opts...) +func NewDBFromDelegations(d *data.Delegations) (*DB, error) { + db := &DB{ + roles: make(map[string]*Role, len(d.Roles)), + verifiers: make(map[string]keys.Verifier, len(d.Keys)), + } for _, r := range d.Roles { if _, ok := roles.TopLevelRoles[r.Name]; ok { return nil, ErrInvalidDelegatedRole @@ -67,11 +53,7 @@ func NewDBFromDelegations(d *data.Delegations, opts ...DBOpts) (*DB, error) { } func (db *DB) AddKey(id string, k *data.PublicKey) error { - opts := make([]keys.VerifierOpts, 0) - if db.logger != nil { - opts = append(opts, keys.WithLogger(db.logger)) - } - verifier, err := keys.GetVerifier(k, opts...) + verifier, err := keys.GetVerifier(k) if err != nil { return err // ErrInvalidKey }