make key algorithm configurable for local development with in memory ed25519 crypto service

Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
David Lawrence
2015-07-29 12:03:20 -07:00
parent 3746a86509
commit f7ca3ef62e
8 changed files with 62 additions and 25 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,6 @@
/cmd/notary-server/notary-server
/cmd/notary-server/local.config.json
/cmd/notary-signer/local.config.json
cover
bin
cross

View File

@@ -456,6 +456,12 @@ func testPublish(t *testing.T, rootType data.KeyAlgorithm) {
// Set up server
ctx := context.WithValue(context.Background(), "metaStore", storage.NewMemStorage())
// Do not pass one of the const KeyAlgorithms here as the value! Passing a
// string is in itself good test that we are handling it correctly as we will
// be receiving a string from the configuration.
ctx = context.WithValue(ctx, "keyAlgorithm", "ecdsa")
hand := utils.RootHandlerFactory(nil, ctx,
cryptoservice.NewCryptoService("", trustmanager.NewKeyMemoryStore(passphraseRetriever)))

View File

@@ -6,12 +6,19 @@
"type": "remote",
"hostname": "notarysigner",
"port": "7899",
"tls_ca_file": "./fixtures/root-ca.crt" },
"tls_ca_file": "./fixtures/root-ca.crt",
"key_algorithm": "ecdsa"
},
"logging": {
"level": "debug"
},
"storage": {
"backend": "mysql",
"db_url": "dockercondemo:dockercondemo@tcp(notarymysql:3306)/dockercondemo"
},
"reporting": {
"bugsnag": "enable",
"bugsnag_api_key": "",
"bugsnag_release_stage": "development"
}
}

View File

@@ -7,7 +7,8 @@
"trust_service": {
"type": "local",
"hostname": "",
"port": ""
"port": "",
"key_algorithm": "ed25519"
},
"logging": {
"level": "debug"

View File

@@ -8,18 +8,18 @@ import (
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/bugsnag/bugsnag-go"
_ "github.com/docker/distribution/registry/auth/htpasswd"
_ "github.com/docker/distribution/registry/auth/token"
"github.com/endophage/gotuf/signed"
_ "github.com/go-sql-driver/mysql"
"golang.org/x/net/context"
bugsnag_hook "github.com/Sirupsen/logrus/hooks/bugsnag"
"github.com/docker/notary/server"
"github.com/docker/notary/server/storage"
"github.com/docker/notary/signer"
@@ -71,11 +71,28 @@ func main() {
}
logrus.SetLevel(lvl)
sigHup := make(chan os.Signal)
sigTerm := make(chan os.Signal)
signal.Notify(sigHup, syscall.SIGHUP)
signal.Notify(sigTerm, syscall.SIGTERM)
// set up bugsnag and attach to logrus
bugs := viper.GetString("reporting.bugsnag")
if bugs != "" {
apiKey := viper.GetString("reporting.bugsnag_api_key")
releaseStage := viper.GetString("reporting.bugsnag_release_stage")
bugsnag.Configure(bugsnag.Configuration{
APIKey: apiKey,
ReleaseStage: releaseStage,
})
hook, err := bugsnag_hook.NewBugsnagHook()
if err != nil {
logrus.Error("Could not attach bugsnag to logrus: ", err.Error())
} else {
logrus.AddHook(hook)
}
}
keyAlgo := viper.GetString("trust_service.key_algorithm")
if keyAlgo == "" {
logrus.Fatal("no key algorithm configured.")
os.Exit(1)
}
ctx = context.WithValue(ctx, "keyAlgorithm", keyAlgo)
var trust signed.CryptoService
if viper.GetString("trust_service.type") == "remote" {

View File

@@ -10,70 +10,69 @@ import (
// with the registry API
const errGroup = "notary.api.v1"
// These errors should be returned from contextHandlers only. They are
// serialized and returned to a user as part of the generic error handling
// done by the rootHandler
var (
// ErrNoStorage lint comment
ErrNoStorage = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NO_STORAGE",
Message: "The server is misconfigured and has no storage.",
Description: "No storage backend has been configured for the server.",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrNoFilename lint comment
ErrNoFilename = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NO_FILENAME",
Message: "No file/role name provided.",
Description: "No file/role name is provided to associate an update with.",
HTTPStatusCode: http.StatusBadRequest,
})
// ErrInvalidRole lint comment
ErrInvalidRole = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "INVALID_ROLE",
Message: "The role you are attempting to operate on is invalid.",
Description: "The user attempted to operate on a role that is not deemed valid.",
HTTPStatusCode: http.StatusBadRequest,
})
// ErrMalformedJSON lint comment
ErrMalformedJSON = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MALFORMED_JSON",
Message: "JSON sent by the client could not be parsed by the server",
Description: "The client sent malformed JSON.",
HTTPStatusCode: http.StatusBadRequest,
})
// ErrUpdating lint comment
ErrUpdating = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "UPDATING",
Message: "An error has occurred while updating the TUF repository.",
Description: "An error occurred when attempting to apply an update at the storage layer.",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrMetadataNotFound lint comment
ErrMetadataNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "METADATA_NOT_FOUND",
Message: "You have requested metadata that does not exist.",
Description: "The user requested metadata that is not known to the server.",
HTTPStatusCode: http.StatusNotFound,
})
// ErrMalformedUpload lint comment
ErrMalformedUpload = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "MALFORMED_UPLOAD",
Message: "The body of your request is malformed.",
Description: "The user uploaded new TUF data and the server was unable to parse it as multipart/form-data.",
HTTPStatusCode: http.StatusBadRequest,
})
// ErrGenericNotFound lint comment
ErrGenericNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "GENERIC_NOT_FOUND",
Message: "You have requested a resource that does not exist.",
Description: "The user requested a non-specific resource that is not known to the server.",
HTTPStatusCode: http.StatusNotFound,
})
// ErrNoCryptoService lint comment
ErrNoCryptoService = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NO_CRYPTOSERVICE",
Message: "The server does not have a signing service configured.",
Description: "No signing service has been configured for the server and it has been asked to perform an operation that requires either signing, or key generation.",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrUnknown is the generic internal server error
ErrNoKeyAlgorithm = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "NO_KEYALGORITHM",
Message: "The server does not have a key algorithm configured.",
Description: "No key algorihtm has been configured for the server and it has been asked to perform an operation that requires generation.",
HTTPStatusCode: http.StatusInternalServerError,
})
ErrUnknown = errcode.ErrorCodeUnknown
)

View File

@@ -161,20 +161,27 @@ func GetTimestampKeyHandler(ctx context.Context, w http.ResponseWriter, r *http.
s := ctx.Value("metaStore")
store, ok := s.(storage.MetaStore)
if !ok {
logrus.Debugf("[Notary Server] 500 GET storage not configured")
logrus.Debug("[Notary Server] 500 GET storage not configured")
return errors.ErrNoStorage.WithDetail(nil)
}
c := ctx.Value("cryptoService")
crypto, ok := c.(signed.CryptoService)
if !ok {
logrus.Debugf("[Notary Server] 500 GET crypto service not configured")
logrus.Debug("[Notary Server] 500 GET crypto service not configured")
return errors.ErrNoCryptoService.WithDetail(nil)
}
algo := ctx.Value("keyAlgorithm")
keyAlgo, ok := algo.(string)
if !ok {
logrus.Debug("[Notary Server] 500 GET key algorithm not configured")
return errors.ErrNoKeyAlgorithm.WithDetail(nil)
}
keyAlgorithm := data.KeyAlgorithm(keyAlgo)
vars := mux.Vars(r)
gun := vars["imageName"]
key, err := timestamp.GetOrCreateTimestampKey(gun, store, crypto, data.ECDSAKey)
key, err := timestamp.GetOrCreateTimestampKey(gun, store, crypto, keyAlgorithm)
if err != nil {
logrus.Debugf("[Notary Server] 500 GET timestamp key for %s: %v", gun, err)
return errors.ErrUnknown.WithDetail(err)

View File

@@ -70,9 +70,7 @@ func Run(ctx context.Context, addr, tlsCertFile, tlsKeyFile string, trust signed
}
var ac auth.AccessController
if authMethod == "" {
ac = nil
} else {
if authMethod == "token" {
authOptions, ok := authOpts.(map[string]interface{})
if !ok {
return fmt.Errorf("auth.options must be a map[string]interface{}")