From baf3c40fef7f102e40d224891f9744f2b65d3b77 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Mon, 21 Mar 2022 16:55:09 -0700 Subject: [PATCH 01/15] Print some basic configuration info on startup --- authority/authority.go | 10 ++++++++-- ca/ca.go | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/authority/authority.go b/authority/authority.go index cc26635e..516c8130 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -294,8 +294,6 @@ func (a *Authority) init() error { return err } a.rootX509Certs = append(a.rootX509Certs, resp.RootCertificate) - sum := sha256.Sum256(resp.RootCertificate.Raw) - log.Printf("Using root fingerprint '%s'", hex.EncodeToString(sum[:])) } } @@ -313,6 +311,7 @@ func (a *Authority) init() error { for _, crt := range a.rootX509Certs { sum := sha256.Sum256(crt.Raw) a.certificates.Store(hex.EncodeToString(sum[:]), crt) + log.Printf("X.509 Root Fingerprint: %s", hex.EncodeToString(sum[:])) } a.rootX509CertPool = x509.NewCertPool() @@ -541,6 +540,13 @@ func (a *Authority) init() error { a.templates.Data["Step"] = tmplVars } + if tmplVars.SSH.HostKey != nil { + log.Printf("SSH Host CA Key: %s\n", ssh.MarshalAuthorizedKey(tmplVars.SSH.HostKey)) + } + if tmplVars.SSH.HostKey != nil { + log.Printf("SSH User CA Key: %s\n", ssh.MarshalAuthorizedKey(tmplVars.SSH.UserKey)) + } + // JWT numeric dates are seconds. a.startTime = time.Now().Truncate(time.Second) // Set flag indicating that initialization has been completed, and should diff --git a/ca/ca.go b/ca/ca.go index c95ba22f..3be03e34 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -288,6 +288,9 @@ func (ca *CA) Run() error { var wg sync.WaitGroup errs := make(chan error, 1) + log.Printf("Documentation: https://u.step.sm/docs/ca") + log.Printf("Config File: %s", ca.opts.configFile) + if ca.insecureSrv != nil { wg.Add(1) go func() { From 91a25b52bdc3a3ee06c0fdae717641766b73aa94 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Mon, 21 Mar 2022 16:59:28 -0700 Subject: [PATCH 02/15] Print discord --- ca/ca.go | 1 + 1 file changed, 1 insertion(+) diff --git a/ca/ca.go b/ca/ca.go index 3be03e34..2751d050 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -289,6 +289,7 @@ func (ca *CA) Run() error { errs := make(chan error, 1) log.Printf("Documentation: https://u.step.sm/docs/ca") + log.Printf("Community Discord: https://u.step.sm/discord") log.Printf("Config File: %s", ca.opts.configFile) if ca.insecureSrv != nil { From 91be50cf70ef7ca1a2a8f92bf5f6f4e655bdafe1 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Mon, 21 Mar 2022 19:55:21 -0700 Subject: [PATCH 03/15] Add --quiet flag --- ca/ca.go | 18 +++++++++++++++--- commands/app.go | 8 +++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ca/ca.go b/ca/ca.go index 2751d050..9c852a19 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -31,6 +31,7 @@ import ( type options struct { configFile string linkedCAToken string + quiet bool password []byte issuerPassword []byte sshHostPassword []byte @@ -101,6 +102,14 @@ func WithLinkedCAToken(token string) Option { } } +// WithQuiet sets the quiet flag. +func WithQuiet(quiet bool) Option { + return func(o *options) { + o.quiet = quiet + } +} + + // CA is the type used to build the complete certificate authority. It builds // the HTTP server, set ups the middlewares and the HTTP handlers. type CA struct { @@ -288,9 +297,11 @@ func (ca *CA) Run() error { var wg sync.WaitGroup errs := make(chan error, 1) - log.Printf("Documentation: https://u.step.sm/docs/ca") - log.Printf("Community Discord: https://u.step.sm/discord") - log.Printf("Config File: %s", ca.opts.configFile) + if !ca.opts.quiet { + log.Printf("Documentation: https://u.step.sm/docs/ca") + log.Printf("Community Discord: https://u.step.sm/discord") + log.Printf("Config File: %s", ca.opts.configFile) + } if ca.insecureSrv != nil { wg.Add(1) @@ -359,6 +370,7 @@ func (ca *CA) Reload() error { WithSSHUserPassword(ca.opts.sshUserPassword), WithIssuerPassword(ca.opts.issuerPassword), WithLinkedCAToken(ca.opts.linkedCAToken), + WithQuiet(ca.opts.quiet), WithConfigFile(ca.opts.configFile), WithDatabase(ca.auth.GetDatabase()), ) diff --git a/commands/app.go b/commands/app.go index 8c40de0e..47fb1444 100644 --- a/commands/app.go +++ b/commands/app.go @@ -57,6 +57,10 @@ certificate issuer private key used in the RA mode.`, Usage: "token used to enable the linked ca.", EnvVar: "STEP_CA_TOKEN", }, + cli.BoolFlag{ + Name: "quiet", + Usage: "disable startup information", + }, }, } @@ -68,6 +72,7 @@ func appAction(ctx *cli.Context) error { issuerPassFile := ctx.String("issuer-password-file") resolver := ctx.String("resolver") token := ctx.String("token") + quiet := ctx.Bool("quiet") // If zero cmd line args show help, if >1 cmd line args show error. if ctx.NArg() == 0 { @@ -141,7 +146,8 @@ To get a linked authority token: ca.WithSSHHostPassword(sshHostPassword), ca.WithSSHUserPassword(sshUserPassword), ca.WithIssuerPassword(issuerPassword), - ca.WithLinkedCAToken(token)) + ca.WithLinkedCAToken(token), + ca.WithQuiet(quiet)) if err != nil { fatal(err) } From 25cc9a172835207680d2fee3c13690a5688169f4 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Tue, 22 Mar 2022 07:38:09 -0700 Subject: [PATCH 04/15] Update authority/authority.go Co-authored-by: Herman Slatman --- authority/authority.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/authority/authority.go b/authority/authority.go index 516c8130..50025cce 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -543,7 +543,7 @@ func (a *Authority) init() error { if tmplVars.SSH.HostKey != nil { log.Printf("SSH Host CA Key: %s\n", ssh.MarshalAuthorizedKey(tmplVars.SSH.HostKey)) } - if tmplVars.SSH.HostKey != nil { + if tmplVars.SSH.UserKey != nil { log.Printf("SSH User CA Key: %s\n", ssh.MarshalAuthorizedKey(tmplVars.SSH.UserKey)) } From f20784be56943dbb430f588fec761af61530ccd3 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Tue, 22 Mar 2022 10:41:16 -0700 Subject: [PATCH 05/15] format --- ca/ca.go | 1 - commands/app.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ca/ca.go b/ca/ca.go index 9c852a19..41f48483 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -109,7 +109,6 @@ func WithQuiet(quiet bool) Option { } } - // CA is the type used to build the complete certificate authority. It builds // the HTTP server, set ups the middlewares and the HTTP handlers. type CA struct { diff --git a/commands/app.go b/commands/app.go index 47fb1444..984ce067 100644 --- a/commands/app.go +++ b/commands/app.go @@ -58,7 +58,7 @@ certificate issuer private key used in the RA mode.`, EnvVar: "STEP_CA_TOKEN", }, cli.BoolFlag{ - Name: "quiet", + Name: "quiet", Usage: "disable startup information", }, }, From 055e75f3941f423acf87b95d60cb2a8252fade35 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Wed, 30 Mar 2022 15:48:42 -0700 Subject: [PATCH 06/15] Progress? --- authority/authority.go | 26 ++++++++++++++++++-------- ca/ca.go | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/authority/authority.go b/authority/authority.go index 50025cce..b6829861 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -80,6 +80,14 @@ type Authority struct { adminMutex sync.RWMutex } +type AuthorityInfo struct { + StartTime time.Time + RootX509Certs []*x509.Certificate + SSHCAUserCerts []ssh.PublicKey + SSHCAHostCerts []ssh.PublicKey +} + + // New creates and initiates a new Authority type. func New(cfg *config.Config, opts ...Option) (*Authority, error) { err := cfg.Validate() @@ -311,7 +319,6 @@ func (a *Authority) init() error { for _, crt := range a.rootX509Certs { sum := sha256.Sum256(crt.Raw) a.certificates.Store(hex.EncodeToString(sum[:]), crt) - log.Printf("X.509 Root Fingerprint: %s", hex.EncodeToString(sum[:])) } a.rootX509CertPool = x509.NewCertPool() @@ -540,13 +547,6 @@ func (a *Authority) init() error { a.templates.Data["Step"] = tmplVars } - if tmplVars.SSH.HostKey != nil { - log.Printf("SSH Host CA Key: %s\n", ssh.MarshalAuthorizedKey(tmplVars.SSH.HostKey)) - } - if tmplVars.SSH.UserKey != nil { - log.Printf("SSH User CA Key: %s\n", ssh.MarshalAuthorizedKey(tmplVars.SSH.UserKey)) - } - // JWT numeric dates are seconds. a.startTime = time.Now().Truncate(time.Second) // Set flag indicating that initialization has been completed, and should @@ -567,6 +567,16 @@ func (a *Authority) GetAdminDatabase() admin.DB { return a.adminDB } +func (a *Authority) GetAuthorityInfo() *AuthorityInfo { + return &AuthorityInfo{ + StartTime: a.startTime, + RootX509Certs: a.rootX509Certs, + SSHCAUserCerts: a.sshCAUserCerts, + SSHCAHostCerts: a.sshCAHostCerts, + } + +} + // IsAdminAPIEnabled returns a boolean indicating whether the Admin API has // been enabled. func (a *Authority) IsAdminAPIEnabled() bool { diff --git a/ca/ca.go b/ca/ca.go index 41f48483..223d2470 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -3,6 +3,8 @@ package ca import ( "crypto/tls" "crypto/x509" + "crypto/sha256" + "encoding/hex" "fmt" "log" "net/http" @@ -297,6 +299,18 @@ func (ca *CA) Run() error { errs := make(chan error, 1) if !ca.opts.quiet { + authorityInfo := ca.auth.GetAuthorityInfo() + log.Printf("Address: %s", ca.config.Address) + for _, crt := range authorityInfo.RootX509Certs { + sum := sha256.Sum256(crt.Raw) + log.Printf("X.509 Root Fingerprint: %s", hex.EncodeToString(sum[:])) + } + if ca.config.SSH != nil { + log.Printf("SSH Host CA Key: %s\n", ca.config.SSH.HostKey) + } + if ca.config.SSH != nil { + log.Printf("SSH User CA Key: %s\n", ca.config.SSH.UserKey) + } log.Printf("Documentation: https://u.step.sm/docs/ca") log.Printf("Community Discord: https://u.step.sm/discord") log.Printf("Config File: %s", ca.opts.configFile) From 90cb6315b187a751cc32dcd6c36f1476302e8ddf Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Wed, 30 Mar 2022 16:05:26 -0700 Subject: [PATCH 07/15] Progress. --- authority/authority.go | 16 ++++++++++------ ca/ca.go | 8 ++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/authority/authority.go b/authority/authority.go index b6829861..f2b8b983 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -83,8 +83,8 @@ type Authority struct { type AuthorityInfo struct { StartTime time.Time RootX509Certs []*x509.Certificate - SSHCAUserCerts []ssh.PublicKey - SSHCAHostCerts []ssh.PublicKey + SSHCAUserPublicKey []byte + SSHCAHostPublicKey []byte } @@ -568,13 +568,17 @@ func (a *Authority) GetAdminDatabase() admin.DB { } func (a *Authority) GetAuthorityInfo() *AuthorityInfo { - return &AuthorityInfo{ + ai := &AuthorityInfo{ StartTime: a.startTime, RootX509Certs: a.rootX509Certs, - SSHCAUserCerts: a.sshCAUserCerts, - SSHCAHostCerts: a.sshCAHostCerts, } - + if a.sshCAUserCertSignKey != nil { + ai.SSHCAUserPublicKey = ssh.MarshalAuthorizedKey(a.sshCAUserCertSignKey.PublicKey()) + } + if a.sshCAHostCertSignKey != nil { + ai.SSHCAHostPublicKey = ssh.MarshalAuthorizedKey(a.sshCAHostCertSignKey.PublicKey()) + } + return ai } // IsAdminAPIEnabled returns a boolean indicating whether the Admin API has diff --git a/ca/ca.go b/ca/ca.go index 223d2470..0e7f3dbb 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -305,11 +305,11 @@ func (ca *CA) Run() error { sum := sha256.Sum256(crt.Raw) log.Printf("X.509 Root Fingerprint: %s", hex.EncodeToString(sum[:])) } - if ca.config.SSH != nil { - log.Printf("SSH Host CA Key: %s\n", ca.config.SSH.HostKey) + if authorityInfo.SSHCAHostPublicKey != nil { + log.Printf("SSH Host CA Key: %s\n", authorityInfo.SSHCAHostPublicKey) } - if ca.config.SSH != nil { - log.Printf("SSH User CA Key: %s\n", ca.config.SSH.UserKey) + if authorityInfo.SSHCAUserPublicKey != nil { + log.Printf("SSH User CA Key: %s\n", authorityInfo.SSHCAUserPublicKey) } log.Printf("Documentation: https://u.step.sm/docs/ca") log.Printf("Community Discord: https://u.step.sm/discord") From a13e58e3407dc169739e42e0b7aa60d01f071175 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Wed, 30 Mar 2022 16:07:16 -0700 Subject: [PATCH 08/15] Update GetAuthorityInfo -> GetInfo --- authority/authority.go | 4 ++-- ca/ca.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/authority/authority.go b/authority/authority.go index f2b8b983..3b26dbc5 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -567,8 +567,8 @@ func (a *Authority) GetAdminDatabase() admin.DB { return a.adminDB } -func (a *Authority) GetAuthorityInfo() *AuthorityInfo { - ai := &AuthorityInfo{ +func (a *Authority) GetInfo() AuthorityInfo { + ai := AuthorityInfo{ StartTime: a.startTime, RootX509Certs: a.rootX509Certs, } diff --git a/ca/ca.go b/ca/ca.go index 0e7f3dbb..bf967aed 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -299,7 +299,7 @@ func (ca *CA) Run() error { errs := make(chan error, 1) if !ca.opts.quiet { - authorityInfo := ca.auth.GetAuthorityInfo() + authorityInfo := ca.auth.GetInfo() log.Printf("Address: %s", ca.config.Address) for _, crt := range authorityInfo.RootX509Certs { sum := sha256.Sum256(crt.Raw) From 1ba1584c7a2abb32b073d1e13a978868a0e91b2a Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Wed, 30 Mar 2022 16:08:10 -0700 Subject: [PATCH 09/15] Formatted. --- authority/authority.go | 11 +++++------ ca/ca.go | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/authority/authority.go b/authority/authority.go index 3b26dbc5..c5f8c3a6 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -81,13 +81,12 @@ type Authority struct { } type AuthorityInfo struct { - StartTime time.Time - RootX509Certs []*x509.Certificate - SSHCAUserPublicKey []byte - SSHCAHostPublicKey []byte + StartTime time.Time + RootX509Certs []*x509.Certificate + SSHCAUserPublicKey []byte + SSHCAHostPublicKey []byte } - // New creates and initiates a new Authority type. func New(cfg *config.Config, opts ...Option) (*Authority, error) { err := cfg.Validate() @@ -569,7 +568,7 @@ func (a *Authority) GetAdminDatabase() admin.DB { func (a *Authority) GetInfo() AuthorityInfo { ai := AuthorityInfo{ - StartTime: a.startTime, + StartTime: a.startTime, RootX509Certs: a.rootX509Certs, } if a.sshCAUserCertSignKey != nil { diff --git a/ca/ca.go b/ca/ca.go index bf967aed..21b64ee7 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -1,9 +1,9 @@ package ca import ( + "crypto/sha256" "crypto/tls" "crypto/x509" - "crypto/sha256" "encoding/hex" "fmt" "log" @@ -302,8 +302,8 @@ func (ca *CA) Run() error { authorityInfo := ca.auth.GetInfo() log.Printf("Address: %s", ca.config.Address) for _, crt := range authorityInfo.RootX509Certs { - sum := sha256.Sum256(crt.Raw) - log.Printf("X.509 Root Fingerprint: %s", hex.EncodeToString(sum[:])) + sum := sha256.Sum256(crt.Raw) + log.Printf("X.509 Root Fingerprint: %s", hex.EncodeToString(sum[:])) } if authorityInfo.SSHCAHostPublicKey != nil { log.Printf("SSH Host CA Key: %s\n", authorityInfo.SSHCAHostPublicKey) From 7ebb2e4c74f4f0510198baf1a0a1301b7e105e84 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Mon, 4 Apr 2022 11:14:04 -0700 Subject: [PATCH 10/15] Update ca/ca.go Co-authored-by: Herman Slatman --- ca/ca.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ca/ca.go b/ca/ca.go index 21b64ee7..185fb72e 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -302,8 +302,7 @@ func (ca *CA) Run() error { authorityInfo := ca.auth.GetInfo() log.Printf("Address: %s", ca.config.Address) for _, crt := range authorityInfo.RootX509Certs { - sum := sha256.Sum256(crt.Raw) - log.Printf("X.509 Root Fingerprint: %s", hex.EncodeToString(sum[:])) + log.Printf("X.509 Root Fingerprint: %s", x509util.Fingerprint(crt)) } if authorityInfo.SSHCAHostPublicKey != nil { log.Printf("SSH Host CA Key: %s\n", authorityInfo.SSHCAHostPublicKey) From 43f2c655b909b02e30b5c4aaff898cfe45525a60 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Mon, 4 Apr 2022 12:16:37 -0700 Subject: [PATCH 11/15] More info on startup --- authority/authority.go | 2 ++ ca/ca.go | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/authority/authority.go b/authority/authority.go index c5f8c3a6..8c5eb9c4 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -85,6 +85,7 @@ type AuthorityInfo struct { RootX509Certs []*x509.Certificate SSHCAUserPublicKey []byte SSHCAHostPublicKey []byte + DNSNames []string } // New creates and initiates a new Authority type. @@ -570,6 +571,7 @@ func (a *Authority) GetInfo() AuthorityInfo { ai := AuthorityInfo{ StartTime: a.startTime, RootX509Certs: a.rootX509Certs, + DNSNames: a.config.DNSNames, } if a.sshCAUserCertSignKey != nil { ai.SSHCAUserPublicKey = ssh.MarshalAuthorizedKey(a.sshCAUserCertSignKey.PublicKey()) diff --git a/ca/ca.go b/ca/ca.go index 185fb72e..89813d64 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -1,15 +1,14 @@ package ca import ( - "crypto/sha256" "crypto/tls" "crypto/x509" - "encoding/hex" "fmt" "log" "net/http" "net/url" "reflect" + "strings" "sync" "github.com/go-chi/chi" @@ -28,6 +27,7 @@ import ( scepAPI "github.com/smallstep/certificates/scep/api" "github.com/smallstep/certificates/server" "github.com/smallstep/nosql" + "go.step.sm/crypto/x509util" ) type options struct { @@ -300,12 +300,19 @@ func (ca *CA) Run() error { if !ca.opts.quiet { authorityInfo := ca.auth.GetInfo() - log.Printf("Address: %s", ca.config.Address) + log.Printf("Welcome to step-ca.") + log.Printf("The primary server URL is https://%s%s", + authorityInfo.DNSNames[0], + ca.config.Address[strings.LastIndex(ca.config.Address, ":"):]) + if len(authorityInfo.DNSNames) > 1 { + log.Printf("Additional configured hostnames: %s", + strings.Join(authorityInfo.DNSNames[1:], ", ")) + } for _, crt := range authorityInfo.RootX509Certs { log.Printf("X.509 Root Fingerprint: %s", x509util.Fingerprint(crt)) } if authorityInfo.SSHCAHostPublicKey != nil { - log.Printf("SSH Host CA Key: %s\n", authorityInfo.SSHCAHostPublicKey) + log.Printf("SSH Host CA Key is %s\n", authorityInfo.SSHCAHostPublicKey) } if authorityInfo.SSHCAUserPublicKey != nil { log.Printf("SSH User CA Key: %s\n", authorityInfo.SSHCAUserPublicKey) From acc75bc679f3f13f6424343133559f88ba8fa868 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Mon, 4 Apr 2022 12:29:27 -0700 Subject: [PATCH 12/15] Add context name to startup info --- ca/ca.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ca/ca.go b/ca/ca.go index e509f74d..fce80e00 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -27,6 +27,7 @@ import ( scepAPI "github.com/smallstep/certificates/scep/api" "github.com/smallstep/certificates/server" "github.com/smallstep/nosql" + "go.step.sm/cli-utils/step" "go.step.sm/crypto/x509util" ) @@ -301,6 +302,10 @@ func (ca *CA) Run() error { if !ca.opts.quiet { authorityInfo := ca.auth.GetInfo() log.Printf("Welcome to step-ca.") + log.Printf("Documentation: https://u.step.sm/docs/ca") + log.Printf("Community Discord: https://u.step.sm/discord") + log.Printf("Current context: %s", step.Contexts().GetCurrent().Name) + log.Printf("Config file: %s", ca.opts.configFile) log.Printf("The primary server URL is https://%s%s", authorityInfo.DNSNames[0], ca.config.Address[strings.LastIndex(ca.config.Address, ":"):]) @@ -317,9 +322,6 @@ func (ca *CA) Run() error { if authorityInfo.SSHCAUserPublicKey != nil { log.Printf("SSH User CA Key: %s\n", authorityInfo.SSHCAUserPublicKey) } - log.Printf("Documentation: https://u.step.sm/docs/ca") - log.Printf("Community Discord: https://u.step.sm/discord") - log.Printf("Config File: %s", ca.opts.configFile) } if ca.insecureSrv != nil { From 150eee70df9a6381bef1713fc0d38d42d46e074f Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Tue, 5 Apr 2022 10:59:25 -0700 Subject: [PATCH 13/15] Updates based on Herman's feedback --- authority/authority.go | 6 +++--- ca/ca.go | 10 +++++++--- commands/app.go | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/authority/authority.go b/authority/authority.go index 8c5eb9c4..b6071060 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -80,7 +80,7 @@ type Authority struct { adminMutex sync.RWMutex } -type AuthorityInfo struct { +type Info struct { StartTime time.Time RootX509Certs []*x509.Certificate SSHCAUserPublicKey []byte @@ -567,8 +567,8 @@ func (a *Authority) GetAdminDatabase() admin.DB { return a.adminDB } -func (a *Authority) GetInfo() AuthorityInfo { - ai := AuthorityInfo{ +func (a *Authority) GetInfo() Info { + ai := Info{ StartTime: a.startTime, RootX509Certs: a.rootX509Certs, DNSNames: a.config.DNSNames, diff --git a/ca/ca.go b/ca/ca.go index fce80e00..0d4f1578 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -301,14 +301,18 @@ func (ca *CA) Run() error { if !ca.opts.quiet { authorityInfo := ca.auth.GetInfo() - log.Printf("Welcome to step-ca.") + log.Printf("Starting %s", step.Version()) log.Printf("Documentation: https://u.step.sm/docs/ca") log.Printf("Community Discord: https://u.step.sm/discord") - log.Printf("Current context: %s", step.Contexts().GetCurrent().Name) + if step.Contexts().GetCurrent() != nil { + log.Printf("Current context: %s", step.Contexts().GetCurrent().Name) + } log.Printf("Config file: %s", ca.opts.configFile) - log.Printf("The primary server URL is https://%s%s", + baseURL := fmt.Sprintf("https://%s%s", authorityInfo.DNSNames[0], ca.config.Address[strings.LastIndex(ca.config.Address, ":"):]) + log.Printf("The primary server URL is %s", baseURL) + log.Printf("Root certificates are available at %s/roots.pem", baseURL) if len(authorityInfo.DNSNames) > 1 { log.Printf("Additional configured hostnames: %s", strings.Join(authorityInfo.DNSNames[1:], ", ")) diff --git a/commands/app.go b/commands/app.go index 6297581f..c3eacd02 100644 --- a/commands/app.go +++ b/commands/app.go @@ -61,6 +61,7 @@ certificate issuer private key used in the RA mode.`, cli.BoolFlag{ Name: "quiet", Usage: "disable startup information", + EnvVar: "STEP_CA_QUIET", }, cli.StringFlag{ Name: "context", From 2e61e01f41a646ae89a1f660ab6643f59f4ed3d9 Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Tue, 5 Apr 2022 10:59:35 -0700 Subject: [PATCH 14/15] Linted. --- commands/app.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/app.go b/commands/app.go index c3eacd02..265610f2 100644 --- a/commands/app.go +++ b/commands/app.go @@ -59,8 +59,8 @@ certificate issuer private key used in the RA mode.`, EnvVar: "STEP_CA_TOKEN", }, cli.BoolFlag{ - Name: "quiet", - Usage: "disable startup information", + Name: "quiet", + Usage: "disable startup information", EnvVar: "STEP_CA_QUIET", }, cli.StringFlag{ From 479c6d2bf563fcc0073779e5f736823d135a3fe2 Mon Sep 17 00:00:00 2001 From: Herman Slatman Date: Thu, 7 Apr 2022 12:37:34 +0200 Subject: [PATCH 15/15] Fix ACME IPv6 HTTP-01 challenges Fixes #890 --- acme/challenge.go | 13 ++++++++++++- acme/challenge_test.go | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/acme/challenge.go b/acme/challenge.go index 0e1994e4..9f08bae5 100644 --- a/acme/challenge.go +++ b/acme/challenge.go @@ -79,7 +79,7 @@ func (ch *Challenge) Validate(ctx context.Context, db DB, jwk *jose.JSONWebKey, } func http01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebKey, vo *ValidateChallengeOptions) error { - u := &url.URL{Scheme: "http", Host: ch.Value, Path: fmt.Sprintf("/.well-known/acme-challenge/%s", ch.Token)} + u := &url.URL{Scheme: "http", Host: http01ChallengeHost(ch.Value), Path: fmt.Sprintf("/.well-known/acme-challenge/%s", ch.Token)} resp, err := vo.HTTPGet(u.String()) if err != nil { @@ -119,6 +119,17 @@ func http01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWeb return nil } +// http01ChallengeHost checks if a Challenge value is an IPv6 address +// and adds square brackets if that's the case, so that it can be used +// as a hostname. Returns the original Challenge value as the host to +// use in other cases. +func http01ChallengeHost(value string) string { + if ip := net.ParseIP(value); ip != nil && ip.To4() == nil { + value = "[" + value + "]" + } + return value +} + func tlsAlert(err error) uint8 { var opErr *net.OpError if errors.As(err, &opErr) { diff --git a/acme/challenge_test.go b/acme/challenge_test.go index d8ce4d76..c05b25e7 100644 --- a/acme/challenge_test.go +++ b/acme/challenge_test.go @@ -13,6 +13,7 @@ import ( "encoding/asn1" "encoding/base64" "encoding/hex" + "errors" "fmt" "io" "math/big" @@ -23,9 +24,9 @@ import ( "testing" "time" - "github.com/pkg/errors" - "github.com/smallstep/assert" "go.step.sm/crypto/jose" + + "github.com/smallstep/assert" ) func Test_storeError(t *testing.T) { @@ -2350,3 +2351,34 @@ func Test_serverName(t *testing.T) { }) } } + +func Test_http01ChallengeHost(t *testing.T) { + tests := []struct { + name string + value string + want string + }{ + { + name: "dns", + value: "www.example.com", + want: "www.example.com", + }, + { + name: "ipv4", + value: "127.0.0.1", + want: "127.0.0.1", + }, + { + name: "ipv6", + value: "::1", + want: "[::1]", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := http01ChallengeHost(tt.value); got != tt.want { + t.Errorf("http01ChallengeHost() = %v, want %v", got, tt.want) + } + }) + } +}