mirror of https://github.com/docker/docs.git
Fixing lint
Signed-off-by: Diogo Monica <diogo@docker.com>
This commit is contained in:
parent
d7999b6cdc
commit
682e7ea00b
|
@ -1,7 +1,7 @@
|
|||
package changelist
|
||||
|
||||
// tufChange represents a change to a TUF repo
|
||||
type tufChange struct {
|
||||
// TufChange represents a change to a TUF repo
|
||||
type TufChange struct {
|
||||
// Abbreviated because Go doesn't permit a field and method of the same name
|
||||
Actn int `json:"action"`
|
||||
Role string `json:"role"`
|
||||
|
@ -11,8 +11,8 @@ type tufChange struct {
|
|||
}
|
||||
|
||||
// NewTufChange initializes a tufChange object
|
||||
func NewTufChange(action int, role, changeType, changePath string, content []byte) *tufChange {
|
||||
return &tufChange{
|
||||
func NewTufChange(action int, role, changeType, changePath string, content []byte) *TufChange {
|
||||
return &TufChange{
|
||||
Actn: action,
|
||||
Role: role,
|
||||
ChangeType: changeType,
|
||||
|
@ -22,25 +22,26 @@ func NewTufChange(action int, role, changeType, changePath string, content []byt
|
|||
}
|
||||
|
||||
// Action return c.Actn
|
||||
func (c tufChange) Action() int {
|
||||
func (c TufChange) Action() int {
|
||||
return c.Actn
|
||||
}
|
||||
|
||||
// Scope returns c.Role
|
||||
func (c tufChange) Scope() string {
|
||||
func (c TufChange) Scope() string {
|
||||
return c.Role
|
||||
}
|
||||
|
||||
// Type returns c.ChangeType
|
||||
func (c tufChange) Type() string {
|
||||
func (c TufChange) Type() string {
|
||||
return c.ChangeType
|
||||
}
|
||||
|
||||
// Path return c.ChangePath
|
||||
func (c tufChange) Path() string {
|
||||
func (c TufChange) Path() string {
|
||||
return c.ChangePath
|
||||
}
|
||||
|
||||
func (c tufChange) Content() []byte {
|
||||
// Content returns c.Data
|
||||
func (c TufChange) Content() []byte {
|
||||
return c.Data
|
||||
}
|
||||
|
|
|
@ -7,30 +7,34 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
type appendChangelist struct {
|
||||
// AppendChangelist represents a list of TUF changes
|
||||
type AppendChangelist struct {
|
||||
path string
|
||||
file *os.File
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewAppendChangelist(path string) (*appendChangelist, error) {
|
||||
// NewAppendChangelist is a convinience method that returns an append only TUF
|
||||
// change list
|
||||
func NewAppendChangelist(path string) (*AppendChangelist, error) {
|
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &appendChangelist{
|
||||
return &AppendChangelist{
|
||||
path: path,
|
||||
file: file,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cl *appendChangelist) List() []Change {
|
||||
// List returns a list of Changes
|
||||
func (cl *AppendChangelist) List() []Change {
|
||||
cl.file.Seek(0, 0) // seek to start of file
|
||||
changes := make([]Change, 0)
|
||||
var changes []Change
|
||||
scnr := bufio.NewScanner(cl.file)
|
||||
for scnr.Scan() {
|
||||
line := scnr.Bytes()
|
||||
c := &tufChange{}
|
||||
c := &TufChange{}
|
||||
err := json.Unmarshal(line, c)
|
||||
if err != nil {
|
||||
// TODO(david): How should we handle this?
|
||||
|
@ -42,7 +46,8 @@ func (cl *appendChangelist) List() []Change {
|
|||
return changes
|
||||
}
|
||||
|
||||
func (cl *appendChangelist) Add(c Change) error {
|
||||
// Add adds a change to the append only changelist
|
||||
func (cl *AppendChangelist) Add(c Change) error {
|
||||
cl.file.Seek(0, 2) // seek to end of file
|
||||
entry, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
|
@ -64,14 +69,15 @@ func (cl *appendChangelist) Add(c Change) error {
|
|||
|
||||
// Clear empties the changelist file. It does not currently
|
||||
// support archiving
|
||||
func (cl *appendChangelist) Clear(archive string) error {
|
||||
func (cl *AppendChangelist) Clear(archive string) error {
|
||||
cl.file.Seek(0, 0) // seek to start
|
||||
cl.file.Truncate(0) // truncate
|
||||
cl.file.Sync()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cl *appendChangelist) Close() error {
|
||||
// Close marks the change list as closed
|
||||
func (cl *AppendChangelist) Close() error {
|
||||
cl.file.Sync()
|
||||
cl.closed = true
|
||||
return cl.file.Close()
|
||||
|
@ -82,21 +88,25 @@ type memChangelist struct {
|
|||
changes []Change
|
||||
}
|
||||
|
||||
// List returns a list of Changes
|
||||
func (cl memChangelist) List() []Change {
|
||||
return cl.changes
|
||||
}
|
||||
|
||||
// Add adds a change to the in-memory change list
|
||||
func (cl *memChangelist) Add(c Change) error {
|
||||
cl.changes = append(cl.changes, c)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clear empties the changelist file.
|
||||
func (cl *memChangelist) Clear(archive string) error {
|
||||
// appending to a nil list initializes it.
|
||||
cl.changes = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close is a no-op in this in-memory change-list
|
||||
func (cl *memChangelist) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,21 +13,24 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type fileChangelist struct {
|
||||
// FileChangelist stores all the changes as files
|
||||
type FileChangelist struct {
|
||||
dir string
|
||||
}
|
||||
|
||||
func NewFileChangelist(dir string) (*fileChangelist, error) {
|
||||
// NewFileChangelist is a convenience method for returning FileChangeLists
|
||||
func NewFileChangelist(dir string) (*FileChangelist, error) {
|
||||
logrus.Debug("Making dir path: ", dir)
|
||||
err := os.MkdirAll(dir, 0700)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &fileChangelist{dir: dir}, nil
|
||||
return &FileChangelist{dir: dir}, nil
|
||||
}
|
||||
|
||||
func (cl fileChangelist) List() []Change {
|
||||
changes := make([]Change, 0)
|
||||
// List returns a list of sorted changes
|
||||
func (cl FileChangelist) List() []Change {
|
||||
var changes []Change
|
||||
dir, err := os.Open(cl.dir)
|
||||
if err != nil {
|
||||
return changes
|
||||
|
@ -48,7 +51,7 @@ func (cl fileChangelist) List() []Change {
|
|||
fmt.Println(err.Error())
|
||||
continue
|
||||
}
|
||||
c := &tufChange{}
|
||||
c := &TufChange{}
|
||||
err = json.Unmarshal(raw, c)
|
||||
if err != nil {
|
||||
// TODO(david): How should we handle this?
|
||||
|
@ -60,16 +63,18 @@ func (cl fileChangelist) List() []Change {
|
|||
return changes
|
||||
}
|
||||
|
||||
func (cl fileChangelist) Add(c Change) error {
|
||||
cJson, err := json.Marshal(c)
|
||||
// Add adds a change to the file change list
|
||||
func (cl FileChangelist) Add(c Change) error {
|
||||
cJSON, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filename := fmt.Sprintf("%020d_%s.change", time.Now().UnixNano(), uuid.New())
|
||||
return ioutil.WriteFile(path.Join(cl.dir, filename), cJson, 0644)
|
||||
return ioutil.WriteFile(path.Join(cl.dir, filename), cJSON, 0644)
|
||||
}
|
||||
|
||||
func (cl fileChangelist) Clear(archive string) error {
|
||||
// Clear clears the change list
|
||||
func (cl FileChangelist) Clear(archive string) error {
|
||||
dir, err := os.Open(cl.dir)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -85,21 +90,25 @@ func (cl fileChangelist) Clear(archive string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cl fileChangelist) Close() error {
|
||||
// Close is a no-op
|
||||
func (cl FileChangelist) Close() error {
|
||||
// Nothing to do here
|
||||
return nil
|
||||
}
|
||||
|
||||
type fileChanges []os.FileInfo
|
||||
|
||||
// Len returns the length of a file change list
|
||||
func (cs fileChanges) Len() int {
|
||||
return len(cs)
|
||||
}
|
||||
|
||||
// Less compares the names of two different file changes
|
||||
func (cs fileChanges) Less(i, j int) bool {
|
||||
return cs[i].Name() < cs[j].Name()
|
||||
}
|
||||
|
||||
// Swap swaps the position of two file changes
|
||||
func (cs fileChanges) Swap(i, j int) {
|
||||
tmp := cs[i]
|
||||
cs[i] = cs[j]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package changelist
|
||||
|
||||
// Changelist is the interface for all TUF change lists
|
||||
type Changelist interface {
|
||||
// List returns the ordered list of changes
|
||||
// currently stored
|
||||
|
@ -20,11 +21,15 @@ type Changelist interface {
|
|||
}
|
||||
|
||||
const (
|
||||
// ActionCreate represents a Create action
|
||||
ActionCreate = iota
|
||||
// ActionUpdate represents an Update action
|
||||
ActionUpdate
|
||||
// ActionDelete represents a Delete action
|
||||
ActionDelete
|
||||
)
|
||||
|
||||
// Change is the interface for a TUF Change
|
||||
type Change interface {
|
||||
// "create","update", or "delete"
|
||||
Action() int
|
||||
|
|
|
@ -14,11 +14,15 @@ import (
|
|||
"github.com/endophage/gotuf/data"
|
||||
)
|
||||
|
||||
// CryptoService implements Sign and Create, holding a specific GUN and keystore to
|
||||
// operate on
|
||||
type CryptoService struct {
|
||||
gun string
|
||||
keyStore *trustmanager.KeyFileStore
|
||||
}
|
||||
|
||||
// RootCryptoService implements Sign and Create and operates on a rootKeyStore,
|
||||
// taking in a passphrase and calling decrypt when signing.
|
||||
type RootCryptoService struct {
|
||||
// TODO(diogo): support multiple passphrases per key
|
||||
passphrase string
|
||||
|
@ -87,7 +91,7 @@ func (rcs *RootCryptoService) Create(role string) (*data.PublicKey, error) {
|
|||
// Sign returns the signatures for data with the given root Key ID, falling back
|
||||
// if not rootKeyID is found
|
||||
// TODO(diogo): This code has 1 line change from the Sign from Crypto service. DRY it up.
|
||||
func (ccs *RootCryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signature, error) {
|
||||
func (rcs *RootCryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signature, error) {
|
||||
// Create hasher and hash data
|
||||
hash := crypto.SHA256
|
||||
hashed := sha256.Sum256(payload)
|
||||
|
@ -95,7 +99,7 @@ func (ccs *RootCryptoService) Sign(keyIDs []string, payload []byte) ([]data.Sign
|
|||
signatures := make([]data.Signature, 0, len(keyIDs))
|
||||
for _, fingerprint := range keyIDs {
|
||||
// Read PrivateKey from file
|
||||
privKey, err := ccs.rootKeyStore.GetDecryptedKey(fingerprint, ccs.passphrase)
|
||||
privKey, err := rcs.rootKeyStore.GetDecryptedKey(fingerprint, rcs.passphrase)
|
||||
if err != nil {
|
||||
// TODO(diogo): This error should be returned to the user in someway
|
||||
continue
|
||||
|
|
|
@ -24,32 +24,41 @@ import (
|
|||
"github.com/endophage/gotuf/store"
|
||||
)
|
||||
|
||||
// ErrRepoNotInitialized is returned when trying to can publish on an uninitialized
|
||||
// notary repository
|
||||
type ErrRepoNotInitialized struct{}
|
||||
|
||||
type passwordRetriever func() (string, error)
|
||||
|
||||
// ErrRepoNotInitialized is returned when trying to can publish on an uninitialized
|
||||
// notary repository
|
||||
func (err *ErrRepoNotInitialized) Error() string {
|
||||
return "Repository has not been initialized"
|
||||
}
|
||||
|
||||
// Default paths should end with a '/' so directory creation works correctly
|
||||
const (
|
||||
trustDir string = "/trusted_certificates/"
|
||||
privDir string = "/private/"
|
||||
tufDir string = "/tuf/"
|
||||
rootKeysDir string = privDir + "/root_keys/"
|
||||
trustDir string = "/trusted_certificates/"
|
||||
privDir string = "/private/"
|
||||
tufDir string = "/tuf/"
|
||||
rootKeysDir string = privDir + "/root_keys/"
|
||||
rsaKeySize int = 2048 // Used for snapshots and targets keys
|
||||
rsaRootKeySize int = 4096 // Used for new root keys
|
||||
)
|
||||
const rsaKeySize int = 2048
|
||||
|
||||
// ErrRepositoryNotExist gets returned when trying to make an action over a repository
|
||||
/// that doesn't exist
|
||||
/// that doesn't exist.
|
||||
var ErrRepositoryNotExist = errors.New("repository does not exist")
|
||||
|
||||
// UnlockedSigner encapsulates a private key and a signer that uses that private key,
|
||||
// providing convinience methods for generation of certificates.
|
||||
type UnlockedSigner struct {
|
||||
privKey *data.PrivateKey
|
||||
signer *signed.Signer
|
||||
}
|
||||
|
||||
// NotaryRepository stores all the information needed to operate on a notary
|
||||
// repository.
|
||||
type NotaryRepository struct {
|
||||
baseDir string
|
||||
Gun string
|
||||
|
@ -65,7 +74,8 @@ type NotaryRepository struct {
|
|||
rootSigner *UnlockedSigner
|
||||
}
|
||||
|
||||
// Target represents a simplified version of the data TUF operates on.
|
||||
// Target represents a simplified version of the data TUF operates on, so external
|
||||
// applications don't have to depend on tuf data types.
|
||||
type Target struct {
|
||||
Name string
|
||||
Hashes data.Hashes
|
||||
|
@ -87,9 +97,9 @@ func NewTarget(targetName string, targetPath string) (*Target, error) {
|
|||
return &Target{Name: targetName, Hashes: meta.Hashes, Length: meta.Length}, nil
|
||||
}
|
||||
|
||||
// NewClient is a helper method that returns a new notary Client, given a config
|
||||
// file. It makes the assumption that the base directory for the config file will
|
||||
// be the place where trust information is being cached locally.
|
||||
// NewNotaryRepository is a helper method that returns a new notary repository.
|
||||
// It takes the base directory under where all the trust files will be stored
|
||||
// (usually ~/.docker/trust/).
|
||||
func NewNotaryRepository(baseDir, gun, baseURL string) (*NotaryRepository, error) {
|
||||
trustDir := filepath.Join(baseDir, trustDir)
|
||||
rootKeysDir := filepath.Join(baseDir, rootKeysDir)
|
||||
|
@ -251,7 +261,7 @@ func (r *NotaryRepository) ListTargets() ([]*Target, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
targetList := make([]*Target, 0)
|
||||
var targetList []*Target
|
||||
for name, meta := range r.tufRepo.Targets["targets"].Signed.Targets {
|
||||
target := &Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}
|
||||
targetList = append(targetList, target)
|
||||
|
@ -467,7 +477,7 @@ func (r *NotaryRepository) saveMetadata(rootSigner *signed.Signer) error {
|
|||
func (r *NotaryRepository) snapshot() error {
|
||||
fmt.Println("Saving changes to Trusted Collection.")
|
||||
|
||||
for t, _ := range r.tufRepo.Targets {
|
||||
for t := range r.tufRepo.Targets {
|
||||
signedTargets, err := r.tufRepo.SignTargets(t, data.DefaultExpires("targets"), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -598,41 +608,41 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
|
|||
), nil
|
||||
}
|
||||
|
||||
// ListPrivateKeys lists all available root keys. Does not include private key
|
||||
// material
|
||||
func (c *NotaryRepository) ListRootKeys() []string {
|
||||
return c.rootKeyStore.ListKeys()
|
||||
// ListRootKeys returns the IDs for all of the root keys. It ignores symlinks
|
||||
// if any exist.
|
||||
func (r *NotaryRepository) ListRootKeys() []string {
|
||||
return r.rootKeyStore.ListKeys()
|
||||
}
|
||||
|
||||
// GenRootKey generates a new root key protected by a given passphrase
|
||||
func (c *NotaryRepository) GenRootKey(passphrase string) (string, error) {
|
||||
privKey, err := trustmanager.GenerateRSAKey(rand.Reader, rsaKeySize)
|
||||
func (r *NotaryRepository) GenRootKey(passphrase string) (string, error) {
|
||||
privKey, err := trustmanager.GenerateRSAKey(rand.Reader, rsaRootKeySize)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to convert private key: ", err)
|
||||
}
|
||||
|
||||
c.rootKeyStore.AddEncryptedKey(privKey.ID(), privKey, passphrase)
|
||||
r.rootKeyStore.AddEncryptedKey(privKey.ID(), privKey, passphrase)
|
||||
|
||||
return privKey.ID(), nil
|
||||
}
|
||||
|
||||
// GetRootSigner retreives a root key that includes the ID and a signer
|
||||
func (c *NotaryRepository) GetRootSigner(rootKeyID, passphrase string) (*UnlockedSigner, error) {
|
||||
privKey, err := c.rootKeyStore.GetDecryptedKey(rootKeyID, passphrase)
|
||||
func (r *NotaryRepository) GetRootSigner(rootKeyID, passphrase string) (*UnlockedSigner, error) {
|
||||
privKey, err := r.rootKeyStore.GetDecryptedKey(rootKeyID, passphrase)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get decrypted root key: %v", err)
|
||||
}
|
||||
|
||||
// This signer will be used for all of the normal TUF operations, except for
|
||||
// when a root key is needed.
|
||||
signer := signed.NewSigner(NewRootCryptoService(c.rootKeyStore, passphrase))
|
||||
signer := signed.NewSigner(NewRootCryptoService(r.rootKeyStore, passphrase))
|
||||
|
||||
return &UnlockedSigner{
|
||||
privKey: privKey,
|
||||
signer: signer}, nil
|
||||
}
|
||||
|
||||
func (c *NotaryRepository) loadKeys(trustDir, rootKeysDir string) error {
|
||||
func (r *NotaryRepository) loadKeys(trustDir, rootKeysDir string) error {
|
||||
// Load all CAs that aren't expired and don't use SHA1
|
||||
caStore, err := trustmanager.NewX509FilteredFileStore(trustDir, func(cert *x509.Certificate) bool {
|
||||
return cert.IsCA && cert.BasicConstraintsValid && cert.SubjectKeyId != nil &&
|
||||
|
@ -663,9 +673,9 @@ func (c *NotaryRepository) loadKeys(trustDir, rootKeysDir string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
c.caStore = caStore
|
||||
c.certificateStore = certificateStore
|
||||
c.rootKeyStore = rootKeyStore
|
||||
r.caStore = caStore
|
||||
r.certificateStore = certificateStore
|
||||
r.rootKeyStore = rootKeyStore
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func MainHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) *e
|
|||
return nil
|
||||
}
|
||||
|
||||
// AddHandler adds the provided json data for the role and GUN specified in the URL
|
||||
// UpdateHandler adds the provided json data for the role and GUN specified in the URL
|
||||
func UpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) *errors.HTTPError {
|
||||
defer r.Body.Close()
|
||||
s := ctx.Value("metaStore")
|
||||
|
@ -154,6 +154,7 @@ func DeleteHandler(ctx context.Context, w http.ResponseWriter, r *http.Request)
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetTimestampHandler returns a timestamp.json given a GUN
|
||||
func GetTimestampHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) *errors.HTTPError {
|
||||
s := ctx.Value("metaStore")
|
||||
store, ok := s.(storage.MetaStore)
|
||||
|
@ -198,6 +199,8 @@ func GetTimestampHandler(ctx context.Context, w http.ResponseWriter, r *http.Req
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetTimestampKeyHandler returns a timestamp public key, creating a new key-pair
|
||||
// it if it doesn't yet exist
|
||||
func GetTimestampKeyHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) *errors.HTTPError {
|
||||
s := ctx.Value("metaStore")
|
||||
store, ok := s.(storage.MetaStore)
|
||||
|
|
|
@ -58,7 +58,7 @@ func Run(ctx context.Context, addr, tlsCertFile, tlsKeyFile string, trust signed
|
|||
lsnr = tls.NewListener(lsnr, tlsConfig)
|
||||
}
|
||||
|
||||
var ac auth.AccessController = nil
|
||||
var ac auth.AccessController
|
||||
hand := utils.RootHandlerFactory(ac, ctx, trust)
|
||||
|
||||
r := mux.NewRouter()
|
||||
|
|
|
@ -27,13 +27,14 @@ type MySQLStorage struct {
|
|||
sql.DB
|
||||
}
|
||||
|
||||
// NewMySQLStorage is a convenience method to create a MySQLStorage
|
||||
func NewMySQLStorage(db *sql.DB) *MySQLStorage {
|
||||
return &MySQLStorage{
|
||||
DB: *db,
|
||||
}
|
||||
}
|
||||
|
||||
// Update multiple TUF records in a single transaction.
|
||||
// UpdateCurrent updates multiple TUF records in a single transaction.
|
||||
// Always insert a new row. The unique constraint will ensure there is only ever
|
||||
func (db *MySQLStorage) UpdateCurrent(gun, role string, version int, data []byte) error {
|
||||
checkStmt := "SELECT count(*) FROM `tuf_files` WHERE `gun`=? AND `role`=? AND `version`>=?;"
|
||||
|
@ -62,7 +63,7 @@ func (db *MySQLStorage) UpdateCurrent(gun, role string, version int, data []byte
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get a specific TUF record
|
||||
// GetCurrent gets a specific TUF record
|
||||
func (db *MySQLStorage) GetCurrent(gun, tufRole string) (data []byte, err error) {
|
||||
stmt := "SELECT `data` FROM `tuf_files` WHERE `gun`=? AND `role`=? ORDER BY `version` DESC LIMIT 1;"
|
||||
rows, err := db.Query(stmt, gun, tufRole) // this should be a QueryRow()
|
||||
|
@ -82,11 +83,14 @@ func (db *MySQLStorage) GetCurrent(gun, tufRole string) (data []byte, err error)
|
|||
return data, nil
|
||||
}
|
||||
|
||||
// Delete deletes all the records for a specific GUN
|
||||
func (db *MySQLStorage) Delete(gun string) error {
|
||||
stmt := "DELETE FROM `tuf_files` WHERE `gun`=?;"
|
||||
_, err := db.Exec(stmt, gun)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetTimestampKey returns the timestamps Public Key data
|
||||
func (db *MySQLStorage) GetTimestampKey(gun string) (cipher string, public []byte, err error) {
|
||||
stmt := "SELECT `cipher`, `public` FROM `timestamp_keys` WHERE `gun`=?;"
|
||||
row := db.QueryRow(stmt, gun)
|
||||
|
@ -100,6 +104,8 @@ func (db *MySQLStorage) GetTimestampKey(gun string) (cipher string, public []byt
|
|||
|
||||
return cipher, public, err
|
||||
}
|
||||
|
||||
// SetTimestampKey attempts to write a TimeStamp key and returns an error if it already exists
|
||||
func (db *MySQLStorage) SetTimestampKey(gun, cipher string, public []byte) error {
|
||||
stmt := "INSERT INTO `timestamp_keys` (`gun`, `cipher`, `public`) VALUES (?,?,?);"
|
||||
_, err := db.Exec(stmt, gun, cipher, public)
|
||||
|
|
|
@ -4,30 +4,38 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// ErrOldVersion is returned when a newer version of TUF metadada is already available
|
||||
type ErrOldVersion struct{}
|
||||
|
||||
// ErrOldVersion is returned when a newer version of TUF metadada is already available
|
||||
func (err ErrOldVersion) Error() string {
|
||||
return fmt.Sprintf("Error updating metadata. A newer version is already available")
|
||||
}
|
||||
|
||||
// ErrNotFound is returned when TUF metadata isn't found for a specific record
|
||||
type ErrNotFound struct{}
|
||||
|
||||
// Error implements error
|
||||
func (err ErrNotFound) Error() string {
|
||||
return fmt.Sprintf("No record found")
|
||||
}
|
||||
|
||||
// ErrTimestampKeyExists is returned when a timestamp key already exists
|
||||
type ErrTimestampKeyExists struct {
|
||||
gun string
|
||||
}
|
||||
|
||||
// ErrTimestampKeyExists is returned when a timestamp key already exists
|
||||
func (err ErrTimestampKeyExists) Error() string {
|
||||
return fmt.Sprintf("Error, timestamp key already exists for %s", err.gun)
|
||||
}
|
||||
|
||||
// ErrNoKey is returned when no timestamp key is found
|
||||
type ErrNoKey struct {
|
||||
gun string
|
||||
}
|
||||
|
||||
// ErrNoKey is returned when no timestamp key is found
|
||||
func (err ErrNoKey) Error() string {
|
||||
return fmt.Sprintf("Error, no timestamp key found for %s", err.gun)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package storage
|
||||
|
||||
// MetaStore holds the methods that are used for a Metadata Store
|
||||
type MetaStore interface {
|
||||
UpdateCurrent(gun, role string, version int, data []byte) error
|
||||
GetCurrent(gun, tufRole string) (data []byte, err error)
|
||||
|
|
|
@ -16,23 +16,24 @@ type ver struct {
|
|||
data []byte
|
||||
}
|
||||
|
||||
// memStorage is really just designed for dev and testing. It is very
|
||||
// MemStorage is really just designed for dev and testing. It is very
|
||||
// inefficient in many scenarios
|
||||
type memStorage struct {
|
||||
type MemStorage struct {
|
||||
lock sync.Mutex
|
||||
tufMeta map[string][]*ver
|
||||
tsKeys map[string]*key
|
||||
}
|
||||
|
||||
// NewMemStorage instantiates a memStorage instance
|
||||
func NewMemStorage() *memStorage {
|
||||
return &memStorage{
|
||||
func NewMemStorage() *MemStorage {
|
||||
return &MemStorage{
|
||||
tufMeta: make(map[string][]*ver),
|
||||
tsKeys: make(map[string]*key),
|
||||
}
|
||||
}
|
||||
|
||||
func (st *memStorage) UpdateCurrent(gun, role string, version int, data []byte) error {
|
||||
// UpdateCurrent updates the meta data for a specific role
|
||||
func (st *MemStorage) UpdateCurrent(gun, role string, version int, data []byte) error {
|
||||
id := entryKey(gun, role)
|
||||
st.lock.Lock()
|
||||
defer st.lock.Unlock()
|
||||
|
@ -47,7 +48,8 @@ func (st *memStorage) UpdateCurrent(gun, role string, version int, data []byte)
|
|||
return nil
|
||||
}
|
||||
|
||||
func (st *memStorage) GetCurrent(gun, role string) (data []byte, err error) {
|
||||
// GetCurrent returns the metadada for a given role, under a GUN
|
||||
func (st *MemStorage) GetCurrent(gun, role string) (data []byte, err error) {
|
||||
id := entryKey(gun, role)
|
||||
st.lock.Lock()
|
||||
defer st.lock.Unlock()
|
||||
|
@ -58,10 +60,11 @@ func (st *memStorage) GetCurrent(gun, role string) (data []byte, err error) {
|
|||
return space[len(st.tufMeta[id])-1].data, nil
|
||||
}
|
||||
|
||||
func (st *memStorage) Delete(gun string) error {
|
||||
// Delete delets all the metadata for a given GUN
|
||||
func (st *MemStorage) Delete(gun string) error {
|
||||
st.lock.Lock()
|
||||
defer st.lock.Unlock()
|
||||
for k, _ := range st.tufMeta {
|
||||
for k := range st.tufMeta {
|
||||
if strings.HasPrefix(k, gun) {
|
||||
delete(st.tufMeta, k)
|
||||
}
|
||||
|
@ -69,17 +72,20 @@ func (st *memStorage) Delete(gun string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (st *memStorage) GetTimestampKey(gun string) (cipher string, public []byte, err error) {
|
||||
// GetTimestampKey returns the public key material of the timestamp key of a given gun
|
||||
func (st *MemStorage) GetTimestampKey(gun string) (cipher string, public []byte, err error) {
|
||||
// no need for lock. It's ok to return nil if an update
|
||||
// wasn't observed
|
||||
if k, ok := st.tsKeys[gun]; !ok {
|
||||
k, ok := st.tsKeys[gun]
|
||||
if !ok {
|
||||
return "", nil, &ErrNoKey{gun: gun}
|
||||
} else {
|
||||
return k.cipher, k.public, nil
|
||||
}
|
||||
|
||||
return k.cipher, k.public, nil
|
||||
}
|
||||
|
||||
func (st *memStorage) SetTimestampKey(gun, cipher string, public []byte) error {
|
||||
// SetTimestampKey sets a Timestamp key under a gun
|
||||
func (st *MemStorage) SetTimestampKey(gun, cipher string, public []byte) error {
|
||||
k := &key{cipher: cipher, public: public}
|
||||
st.lock.Lock()
|
||||
defer st.lock.Unlock()
|
||||
|
|
|
@ -17,6 +17,7 @@ type RufusSigner struct {
|
|||
sClient pb.SignerClient
|
||||
}
|
||||
|
||||
// NewRufusSigner is a convinience method that returns RufusSigner
|
||||
func NewRufusSigner(hostname string, port string, tlscafile string) *RufusSigner {
|
||||
var opts []grpc.DialOption
|
||||
netAddr := net.JoinHostPort(hostname, port)
|
||||
|
|
|
@ -29,7 +29,7 @@ type SimpleFileStore struct {
|
|||
perms os.FileMode
|
||||
}
|
||||
|
||||
// NewFileStore creates a directory with 755 permissions
|
||||
// NewSimpleFileStore creates a directory with 755 permissions
|
||||
func NewSimpleFileStore(baseDir string, fileExt string) (FileStore, error) {
|
||||
if err := CreateDirectory(baseDir); err != nil {
|
||||
return nil, err
|
||||
|
@ -42,7 +42,7 @@ func NewSimpleFileStore(baseDir string, fileExt string) (FileStore, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// NewPrivateFileStore creates a directory with 700 permissions
|
||||
// NewPrivateSimpleFileStore creates a directory with 700 permissions
|
||||
func NewPrivateSimpleFileStore(baseDir string, fileExt string) (FileStore, error) {
|
||||
if err := CreatePrivateDirectory(baseDir); err != nil {
|
||||
return nil, err
|
||||
|
@ -103,12 +103,12 @@ func (f *SimpleFileStore) GetPath(name string) string {
|
|||
return f.genFilePath(name)
|
||||
}
|
||||
|
||||
// List lists all the files inside of a store
|
||||
// ListFiles lists all the files inside of a store
|
||||
func (f *SimpleFileStore) ListFiles(symlinks bool) []string {
|
||||
return f.list(f.baseDir, symlinks)
|
||||
}
|
||||
|
||||
// List lists all the files inside of a directory identified by a name
|
||||
// ListDir lists all the files inside of a directory identified by a name
|
||||
func (f *SimpleFileStore) ListDir(name string, symlinks bool) []string {
|
||||
fullPath := filepath.Join(f.baseDir, name)
|
||||
return f.list(fullPath, symlinks)
|
||||
|
|
|
@ -48,7 +48,7 @@ func (s *KeyFileStore) GetKey(name string) (*data.PrivateKey, error) {
|
|||
return privKey, nil
|
||||
}
|
||||
|
||||
// AddEncrypted stores the contents of a PEM-encoded private key as an encrypted PEM block
|
||||
// AddEncryptedKey stores the contents of a PEM-encoded private key as an encrypted PEM block
|
||||
func (s *KeyFileStore) AddEncryptedKey(name string, privKey *data.PrivateKey, passphrase string) error {
|
||||
encryptedPrivKey, err := EncryptPrivateKey(privKey, passphrase)
|
||||
if err != nil {
|
||||
|
@ -58,7 +58,7 @@ func (s *KeyFileStore) AddEncryptedKey(name string, privKey *data.PrivateKey, pa
|
|||
return s.Add(name, encryptedPrivKey)
|
||||
}
|
||||
|
||||
// GetDecrypted decrypts and returns the PEM Encoded private key given a flename
|
||||
// GetDecryptedKey decrypts and returns the PEM Encoded private key given a flename
|
||||
// and a passphrase
|
||||
func (s *KeyFileStore) GetDecryptedKey(name string, passphrase string) (*data.PrivateKey, error) {
|
||||
keyBytes, err := s.Get(name)
|
||||
|
|
|
@ -92,7 +92,7 @@ func EncryptPrivateKey(key *data.PrivateKey, passphrase string) ([]byte, error)
|
|||
return pem.EncodeToMemory(encryptedPEMBlock), nil
|
||||
}
|
||||
|
||||
// loadCertFromPEM returns the first certificate found in a bunch of bytes or error
|
||||
// LoadCertFromPEM returns the first certificate found in a bunch of bytes or error
|
||||
// if nothing is found. Taken from https://golang.org/src/crypto/x509/cert_pool.go#L85.
|
||||
func LoadCertFromPEM(pemBytes []byte) (*x509.Certificate, error) {
|
||||
for len(pemBytes) > 0 {
|
||||
|
|
Loading…
Reference in New Issue