Add support for the flag --issuer-password-file

The new flag allows to pass a file with the password used to decrypt
the key used in RA mode.
This commit is contained in:
Mariano Cano 2021-03-24 14:53:19 -07:00
parent 71f59de396
commit bdeb0ccd7c
3 changed files with 42 additions and 8 deletions

View File

@ -23,9 +23,10 @@ import (
) )
type options struct { type options struct {
configFile string configFile string
password []byte password []byte
database db.AuthDB issuerPassword []byte
database db.AuthDB
} }
func (o *options) apply(opts []Option) { func (o *options) apply(opts []Option) {
@ -53,6 +54,14 @@ func WithPassword(password []byte) Option {
} }
} }
// WithIssuer sets the given password as the configured certificate issuer
// password in the CA options.
func WithIssuerPassword(password []byte) Option {
return func(o *options) {
o.issuerPassword = password
}
}
// WithDatabase sets the given authority database to the CA options. // WithDatabase sets the given authority database to the CA options.
func WithDatabase(db db.AuthDB) Option { func WithDatabase(db db.AuthDB) Option {
return func(o *options) { return func(o *options) {
@ -82,10 +91,18 @@ func New(config *authority.Config, opts ...Option) (*CA, error) {
// Init initializes the CA with the given configuration. // Init initializes the CA with the given configuration.
func (ca *CA) Init(config *authority.Config) (*CA, error) { func (ca *CA) Init(config *authority.Config) (*CA, error) {
if l := len(ca.opts.password); l > 0 { // Intermediate Password.
if len(ca.opts.password) > 0 {
ca.config.Password = string(ca.opts.password) ca.config.Password = string(ca.opts.password)
} }
// Certificate issuer password for RA mode.
if len(ca.opts.issuerPassword) > 0 {
if ca.config.AuthorityConfig != nil && ca.config.AuthorityConfig.CertificateIssuer != nil {
ca.config.AuthorityConfig.CertificateIssuer.Password = string(ca.opts.issuerPassword)
}
}
var opts []authority.Option var opts []authority.Option
if ca.opts.database != nil { if ca.opts.database != nil {
opts = append(opts, authority.WithDatabase(ca.opts.database)) opts = append(opts, authority.WithDatabase(ca.opts.database))
@ -213,6 +230,7 @@ func (ca *CA) Reload() error {
newCA, err := New(config, newCA, err := New(config,
WithPassword(ca.opts.password), WithPassword(ca.opts.password),
WithIssuerPassword(ca.opts.issuerPassword),
WithConfigFile(ca.opts.configFile), WithConfigFile(ca.opts.configFile),
WithDatabase(ca.auth.GetDatabase()), WithDatabase(ca.auth.GetDatabase()),
) )

View File

@ -106,7 +106,7 @@ func main() {
app.HelpName = "step-ca" app.HelpName = "step-ca"
app.Version = config.Version() app.Version = config.Version()
app.Usage = "an online certificate authority for secure automated certificate management" app.Usage = "an online certificate authority for secure automated certificate management"
app.UsageText = `**step-ca** <config> [**--password-file**=<file>] [**--resolver**=<addr>] [**--help**] [**--version**]` app.UsageText = `**step-ca** <config> [**--password-file**=<file>] [**--issuer-password-file**=<file>] [**--resolver**=<addr>] [**--help**] [**--version**]`
app.Description = `**step-ca** runs the Step Online Certificate Authority app.Description = `**step-ca** runs the Step Online Certificate Authority
(Step CA) using the given configuration. (Step CA) using the given configuration.
See the README.md for more detailed configuration documentation. See the README.md for more detailed configuration documentation.

View File

@ -22,13 +22,17 @@ var AppCommand = cli.Command{
Name: "start", Name: "start",
Action: appAction, Action: appAction,
UsageText: `**step-ca** <config> UsageText: `**step-ca** <config>
[**--password-file**=<file>] [**--password-file**=<file>] [**--issuer-password-file**=<file>] [**--resolver**=<addr>]`,
[**--resolver**=<addr>]`,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "password-file", Name: "password-file",
Usage: `path to the <file> containing the password to decrypt the Usage: `path to the <file> containing the password to decrypt the
intermediate private key.`, intermediate private key.`,
},
cli.StringFlag{
Name: "issuer-password-file",
Usage: `path to the <file> containing the password to decrypt the
certificate issuer private key used in the RA mode.`,
}, },
cli.StringFlag{ cli.StringFlag{
Name: "resolver", Name: "resolver",
@ -40,6 +44,7 @@ intermediate private key.`,
// AppAction is the action used when the top command runs. // AppAction is the action used when the top command runs.
func appAction(ctx *cli.Context) error { func appAction(ctx *cli.Context) error {
passFile := ctx.String("password-file") passFile := ctx.String("password-file")
issuerPassFile := ctx.String("issuer-password-file")
resolver := ctx.String("resolver") resolver := ctx.String("resolver")
// If zero cmd line args show help, if >1 cmd line args show error. // If zero cmd line args show help, if >1 cmd line args show error.
@ -64,6 +69,14 @@ func appAction(ctx *cli.Context) error {
password = bytes.TrimRightFunc(password, unicode.IsSpace) password = bytes.TrimRightFunc(password, unicode.IsSpace)
} }
var issuerPassword []byte
if issuerPassFile != "" {
if issuerPassword, err = ioutil.ReadFile(issuerPassFile); err != nil {
fatal(errors.Wrapf(err, "error reading %s", issuerPassFile))
}
issuerPassword = bytes.TrimRightFunc(issuerPassword, unicode.IsSpace)
}
// replace resolver if requested // replace resolver if requested
if resolver != "" { if resolver != "" {
net.DefaultResolver.PreferGo = true net.DefaultResolver.PreferGo = true
@ -72,7 +85,10 @@ func appAction(ctx *cli.Context) error {
} }
} }
srv, err := ca.New(config, ca.WithConfigFile(configFile), ca.WithPassword(password)) srv, err := ca.New(config,
ca.WithConfigFile(configFile),
ca.WithPassword(password),
ca.WithIssuerPassword(issuerPassword))
if err != nil { if err != nil {
fatal(err) fatal(err)
} }