From 2421a4ab31547682d159f14e4e2865fde6cda224 Mon Sep 17 00:00:00 2001 From: jlanger Date: Tue, 21 Nov 2017 17:07:40 +0100 Subject: [PATCH] Added option to provide db config to ocsp serve command --- cli/ocspserve/ocspserve.go | 30 ++++++++++++++++++++---------- ocsp/responder.go | 27 ++++++++++++++++++++++----- ocsp/responder_test.go | 12 ++++++++++++ ocsp/testdata/db-config.json | 1 + 4 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 ocsp/testdata/db-config.json diff --git a/cli/ocspserve/ocspserve.go b/cli/ocspserve/ocspserve.go index 9f8519fc9..06ff43258 100644 --- a/cli/ocspserve/ocspserve.go +++ b/cli/ocspserve/ocspserve.go @@ -12,32 +12,42 @@ import ( ) // Usage text of 'cfssl serve' -var ocspServerUsageText = `cfssl ocspserve -- set up an HTTP server that handles OCSP requests from a file (see RFC 5019) +var ocspServerUsageText = `cfssl ocspserve -- set up an HTTP server that handles OCSP requests from either a file or directly from a database (see RFC 5019) Usage of ocspserve: - cfssl ocspserve [-address address] [-port port] [-responses file] + cfssl ocspserve [-address address] [-port port] [-responses file] [-db-config db-config] Flags: ` // Flags used by 'cfssl serve' -var ocspServerFlags = []string{"address", "port", "responses"} +var ocspServerFlags = []string{"address", "port", "responses", "db-config"} // ocspServerMain is the command line entry point to the OCSP responder. // It sets up a new HTTP server that responds to OCSP requests. func ocspServerMain(args []string, c cli.Config) error { + var src ocsp.Source // serve doesn't support arguments. if len(args) > 0 { return errors.New("argument is provided but not defined; please refer to the usage by flag -h") } - if c.Responses == "" { - return errors.New("no response file provided, please set the -responses flag") - } - - src, err := ocsp.NewSourceFromFile(c.Responses) - if err != nil { - return errors.New("unable to read response file") + if c.Responses != "" { + s, err := ocsp.NewSourceFromFile(c.Responses) + if err != nil { + return errors.New("unable to read response file") + } + src = s + } else if c.DBConfigFile != "" { + s, err := ocsp.NewSourceFromDB(c.DBConfigFile) + if err != nil { + return errors.New("unable to read configuration file") + } + src = s + } else { + return errors.New( + "no response file or db-config provided, please set the one of these using either -responses or -db-config flags", + ) } log.Info("Registering OCSP responder handler") diff --git a/ocsp/responder.go b/ocsp/responder.go index b1ae2f7f7..26c19d8c1 100644 --- a/ocsp/responder.go +++ b/ocsp/responder.go @@ -13,16 +13,17 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/cloudflare/cfssl/certdb" + "github.com/cloudflare/cfssl/certdb/dbconf" + "github.com/cloudflare/cfssl/certdb/sql" + "github.com/cloudflare/cfssl/log" + "github.com/jmhodges/clock" + "golang.org/x/crypto/ocsp" "io/ioutil" "net/http" "net/url" "regexp" "time" - - "github.com/cloudflare/cfssl/certdb" - "github.com/cloudflare/cfssl/log" - "github.com/jmhodges/clock" - "golang.org/x/crypto/ocsp" ) var ( @@ -158,6 +159,22 @@ func NewSourceFromFile(responseFile string) (Source, error) { return src, nil } +// NewSourceFromDB reads the given database configuration file +// and creates a database data source for use with the OCSP responder +func NewSourceFromDB(DBConfigFile string) (Source, error) { + // Load DB from cofiguration file + db, err := dbconf.DBFromConfig(DBConfigFile) + + if err != nil { + return nil, err + } + // Create accesor + accessor := sql.NewAccessor(db) + src := NewDBSource(accessor) + + return src, nil +} + // A Responder object provides the HTTP logic to expose a // Source of OCSP responses. type Responder struct { diff --git a/ocsp/responder_test.go b/ocsp/responder_test.go index 5c33aac34..09990c23d 100644 --- a/ocsp/responder_test.go +++ b/ocsp/responder_test.go @@ -348,4 +348,16 @@ func TestSqliteRealResponse(t *testing.T) { if err != nil { t.Errorf("Error parsing response: %v", err) } + + // Manually run the query "SELECT max(version_id) FROM goose_db_version;" + // on testdata/sqlite_test.db after running this test to verify that the + // DB was properly connected to. + +} +func TestNewSqliteSource(t *testing.T) { + dbpath := "testdata/db-config.json" + _, err := NewSourceFromDB(dbpath) + if err != nil { + t.Errorf("Error connecting to Sqlite DB: %v", err) + } } diff --git a/ocsp/testdata/db-config.json b/ocsp/testdata/db-config.json new file mode 100644 index 000000000..f93728c82 --- /dev/null +++ b/ocsp/testdata/db-config.json @@ -0,0 +1 @@ +{"driver":"sqlite3","data_source":"sqlite_test.db"}