forked from TrueCloudLab/certificates
first steps
This commit is contained in:
parent
2f60f20b0b
commit
af3cf7dae9
15 changed files with 251 additions and 205 deletions
|
@ -31,7 +31,7 @@ import (
|
||||||
// Authority implements the Certificate Authority internal interface.
|
// Authority implements the Certificate Authority internal interface.
|
||||||
type Authority struct {
|
type Authority struct {
|
||||||
config *config.Config
|
config *config.Config
|
||||||
mgmtDB *mgmt.DB
|
mgmtDB mgmt.DB
|
||||||
keyManager kms.KeyManager
|
keyManager kms.KeyManager
|
||||||
provisioners *provisioner.Collection
|
provisioners *provisioner.Collection
|
||||||
db db.AuthDB
|
db db.AuthDB
|
||||||
|
@ -146,20 +146,26 @@ func (a *Authority) init() error {
|
||||||
|
|
||||||
// Pull AuthConfig from DB.
|
// Pull AuthConfig from DB.
|
||||||
if true {
|
if true {
|
||||||
if len(a.config.AuthConfig.AuthorityID)_== 0 {
|
// Check if AuthConfig already exists
|
||||||
mgmtDB, err := authMgmtNosql.New(a.db.(nosql.DB), mgmt.DefaultAuthorityID)
|
a.mgmtDB, err = authMgmtNosql.New(a.db.(nosql.DB), mgmt.DefaultAuthorityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mgmtAuthConfig, err := mgmt.CreateAuthority(context.Background, mgmtDB, WithDefaultAuthorityID)
|
mgmtAuthConfig, err := a.mgmtDB.GetAuthConfig(context.Background(), mgmt.DefaultAuthorityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
if k, ok := err.(*mgmt.Error); ok && k.IsType(mgmt.ErrorNotFoundType) {
|
||||||
}
|
mgmtAuthConfig, err = mgmt.CreateAuthority(context.Background(), a.mgmtDB, mgmt.WithDefaultAuthorityID)
|
||||||
a.config.AuthConfig, err := mgmtAuthConfig.ToCertificates()
|
if err != nil {
|
||||||
if err != nil {
|
return mgmt.WrapErrorISE(err, "error creating authConfig")
|
||||||
return err
|
}
|
||||||
|
} else {
|
||||||
|
return mgmt.WrapErrorISE(err, "error getting authConfig from db")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
a.config.AuthorityConfig, err = mgmtAuthConfig.ToCertificates()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize key manager if it has not been set in the options.
|
// Initialize key manager if it has not been set in the options.
|
||||||
|
@ -394,6 +400,11 @@ func (a *Authority) GetDatabase() db.AuthDB {
|
||||||
return a.db
|
return a.db
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMgmtDatabase returns the mgmt database, if one exists.
|
||||||
|
func (a *Authority) GetMgmtDatabase() mgmt.DB {
|
||||||
|
return a.mgmtDB
|
||||||
|
}
|
||||||
|
|
||||||
// Shutdown safely shuts down any clients, databases, etc. held by the Authority.
|
// Shutdown safely shuts down any clients, databases, etc. held by the Authority.
|
||||||
func (a *Authority) Shutdown() error {
|
func (a *Authority) Shutdown() error {
|
||||||
if err := a.keyManager.Close(); err != nil {
|
if err := a.keyManager.Close(); err != nil {
|
||||||
|
|
|
@ -32,9 +32,14 @@ var (
|
||||||
MaxVersion: 1.2,
|
MaxVersion: 1.2,
|
||||||
Renegotiation: false,
|
Renegotiation: false,
|
||||||
}
|
}
|
||||||
DefaultBackdate = time.Minute
|
// DefaultBackdate length of time to backdate certificates to avoid
|
||||||
|
// clock skew validation issues.
|
||||||
|
DefaultBackdate = time.Minute
|
||||||
|
// DefaultDisableRenewal disables renewals per provisioner.
|
||||||
DefaultDisableRenewal = false
|
DefaultDisableRenewal = false
|
||||||
DefaultEnableSSHCA = false
|
// DefaultEnableSSHCA enable SSH CA features per provisioner or globally
|
||||||
|
// for all provisioners.
|
||||||
|
DefaultEnableSSHCA = false
|
||||||
// GlobalProvisionerClaims default claims for the Authority. Can be overriden
|
// GlobalProvisionerClaims default claims for the Authority. Can be overriden
|
||||||
// by provisioner specific claims.
|
// by provisioner specific claims.
|
||||||
GlobalProvisionerClaims = provisioner.Claims{
|
GlobalProvisionerClaims = provisioner.Claims{
|
||||||
|
@ -153,7 +158,7 @@ func LoadConfiguration(filename string) (*Config, error) {
|
||||||
return nil, errors.Wrapf(err, "error parsing %s", filename)
|
return nil, errors.Wrapf(err, "error parsing %s", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.init()
|
c.Init()
|
||||||
|
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,55 +58,59 @@ func (h *Handler) GetAdmins(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// CreateAdmin creates a new admin.
|
// CreateAdmin creates a new admin.
|
||||||
func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
/*
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
var body CreateAdminRequest
|
var body CreateAdminRequest
|
||||||
if err := ReadJSON(r.Body, &body); err != nil {
|
if err := ReadJSON(r.Body, &body); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := body.Validate(); err != nil {
|
if err := body.Validate(); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
adm := &config.Admin{
|
adm := &config.Admin{
|
||||||
Name: body.Name,
|
Name: body.Name,
|
||||||
Provisioner: body.Provisioner,
|
Provisioner: body.Provisioner,
|
||||||
IsSuperAdmin: body.IsSuperAdmin,
|
IsSuperAdmin: body.IsSuperAdmin,
|
||||||
}
|
}
|
||||||
if err := h.db.CreateAdmin(ctx, adm); err != nil {
|
if err := h.db.CreateAdmin(ctx, adm); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
api.JSONStatus(w, adm, http.StatusCreated)
|
api.JSONStatus(w, adm, http.StatusCreated)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAdmin updates an existing admin.
|
// UpdateAdmin updates an existing admin.
|
||||||
func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
/*
|
||||||
id := chi.URLParam(r, "id")
|
ctx := r.Context()
|
||||||
|
id := chi.URLParam(r, "id")
|
||||||
|
|
||||||
var body UpdateAdminRequest
|
var body UpdateAdminRequest
|
||||||
if err := ReadJSON(r.Body, &body); err != nil {
|
if err := ReadJSON(r.Body, &body); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := body.Validate(); err != nil {
|
if err := body.Validate(); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if adm, err := h.db.GetAdmin(ctx, id); err != nil {
|
if adm, err := h.db.GetAdmin(ctx, id); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
adm.Name = body.Name
|
adm.Name = body.Name
|
||||||
adm.Provisioner = body.Provisioner
|
adm.Provisioner = body.Provisioner
|
||||||
adm.IsSuperAdmin = body.IsSuperAdmin
|
adm.IsSuperAdmin = body.IsSuperAdmin
|
||||||
|
|
||||||
if err := h.db.UpdateAdmin(ctx, adm); err != nil {
|
if err := h.db.UpdateAdmin(ctx, adm); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
api.JSON(w, adm)
|
api.JSON(w, adm)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,15 @@ import (
|
||||||
|
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/smallstep/certificates/api"
|
"github.com/smallstep/certificates/api"
|
||||||
"github.com/smallstep/certificates/authority"
|
|
||||||
"github.com/smallstep/certificates/authority/config"
|
"github.com/smallstep/certificates/authority/config"
|
||||||
|
"github.com/smallstep/certificates/authority/mgmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateAuthConfigRequest represents the body for a CreateAuthConfig request.
|
// CreateAuthConfigRequest represents the body for a CreateAuthConfig request.
|
||||||
type CreateAuthConfigRequest struct {
|
type CreateAuthConfigRequest struct {
|
||||||
ASN1DN *authority.ASN1DN `json:"asn1dn,omitempty"`
|
ASN1DN *config.ASN1DN `json:"asn1dn,omitempty"`
|
||||||
Claims *config.Claims `json:"claims,omitempty"`
|
Claims *mgmt.Claims `json:"claims,omitempty"`
|
||||||
DisableIssuedAtCheck bool `json:"disableIssuedAtCheck,omitempty"`
|
Backdate string `json:"backdate,omitempty"`
|
||||||
Backdate string `json:"backdate,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates a CreateAuthConfig request body.
|
// Validate validates a CreateAuthConfig request body.
|
||||||
|
@ -24,10 +23,9 @@ func (car *CreateAuthConfigRequest) Validate() error {
|
||||||
|
|
||||||
// UpdateAuthConfigRequest represents the body for a UpdateAuthConfig request.
|
// UpdateAuthConfigRequest represents the body for a UpdateAuthConfig request.
|
||||||
type UpdateAuthConfigRequest struct {
|
type UpdateAuthConfigRequest struct {
|
||||||
ASN1DN *authority.ASN1DN `json:"asn1dn"`
|
ASN1DN *config.ASN1DN `json:"asn1dn"`
|
||||||
Claims *config.Claims `json:"claims"`
|
Claims *mgmt.Claims `json:"claims"`
|
||||||
DisableIssuedAtCheck bool `json:"disableIssuedAtCheck,omitempty"`
|
Backdate string `json:"backdate,omitempty"`
|
||||||
Backdate string `json:"backdate,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates a new-admin request body.
|
// Validate validates a new-admin request body.
|
||||||
|
@ -53,7 +51,7 @@ func (h *Handler) CreateAuthConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
var body CreateAuthConfigRequest
|
var body CreateAuthConfigRequest
|
||||||
if err := ReadJSON(r.Body, &body); err != nil {
|
if err := api.ReadJSON(r.Body, &body); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -61,10 +59,9 @@ func (h *Handler) CreateAuthConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ac := config.AuthConfig{
|
ac := &mgmt.AuthConfig{
|
||||||
Status: config.StatusActive,
|
Status: mgmt.StatusActive,
|
||||||
DisableIssuedAtCheck: body.DisableIssuedAtCheck,
|
Backdate: "1m",
|
||||||
Backdate: "1m",
|
|
||||||
}
|
}
|
||||||
if body.ASN1DN != nil {
|
if body.ASN1DN != nil {
|
||||||
ac.ASN1DN = body.ASN1DN
|
ac.ASN1DN = body.ASN1DN
|
||||||
|
@ -84,38 +81,40 @@ func (h *Handler) CreateAuthConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// UpdateAuthConfig updates an existing AuthConfig.
|
// UpdateAuthConfig updates an existing AuthConfig.
|
||||||
func (h *Handler) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
/*
|
||||||
id := chi.URLParam(r, "id")
|
ctx := r.Context()
|
||||||
|
id := chi.URLParam(r, "id")
|
||||||
|
|
||||||
var body UpdateAuthConfigRequest
|
var body UpdateAuthConfigRequest
|
||||||
if err := ReadJSON(r.Body, &body); err != nil {
|
if err := api.ReadJSON(r.Body, &body); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := body.Validate(); err != nil {
|
if err := body.Validate(); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ac, err := h.db.GetAuthConfig(ctx, id); err != nil {
|
ac, err := h.db.GetAuthConfig(ctx, id)
|
||||||
api.WriteError(w, err)
|
if err != nil {
|
||||||
return
|
api.WriteError(w, err)
|
||||||
}
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ac.DisableIssuedAtCheck = body.DisableIssuedAtCheck
|
ac.Status = body.Status
|
||||||
ac.Status = body.Status
|
if body.ASN1DN != nil {
|
||||||
if body.ASN1DN != nil {
|
ac.ASN1DN = body.ASN1DN
|
||||||
ac.ASN1DN = body.ASN1DN
|
}
|
||||||
}
|
if body.Claims != nil {
|
||||||
if body.Claims != nil {
|
ac.Claims = body.Claims
|
||||||
ac.Claims = body.Claims
|
}
|
||||||
}
|
if body.Backdate != "" {
|
||||||
if body.Backdate != "" {
|
ac.Backdate = body.Backdate
|
||||||
ac.Backdate = body.Backdate
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if err := h.db.UpdateAuthConfig(ctx, ac); err != nil {
|
if err := h.db.UpdateAuthConfig(ctx, ac); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
api.JSON(w, ac)
|
api.JSON(w, ac)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/smallstep/certificates/api"
|
"github.com/smallstep/certificates/api"
|
||||||
"github.com/smallstep/certificates/authority/config"
|
"github.com/smallstep/certificates/authority/mgmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Clock that returns time in UTC rounded to seconds.
|
// Clock that returns time in UTC rounded to seconds.
|
||||||
|
@ -19,14 +19,12 @@ var clock Clock
|
||||||
|
|
||||||
// Handler is the ACME API request handler.
|
// Handler is the ACME API request handler.
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
db config.DB
|
db mgmt.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHandler returns a new Authority Config Handler.
|
// NewHandler returns a new Authority Config Handler.
|
||||||
func NewHandler(db config.DB) api.RouterHandler {
|
func NewHandler(db mgmt.DB) api.RouterHandler {
|
||||||
return &Handler{
|
return &Handler{db}
|
||||||
db: ops.DB,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route traffic and implement the Router interface.
|
// Route traffic and implement the Router interface.
|
||||||
|
|
|
@ -5,17 +5,17 @@ import (
|
||||||
|
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/smallstep/certificates/api"
|
"github.com/smallstep/certificates/api"
|
||||||
"github.com/smallstep/certificates/authority/config"
|
"github.com/smallstep/certificates/authority/mgmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateProvisionerRequest represents the body for a CreateProvisioner request.
|
// CreateProvisionerRequest represents the body for a CreateProvisioner request.
|
||||||
type CreateProvisionerRequest struct {
|
type CreateProvisionerRequest struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Claims *config.Claims `json:"claims"`
|
Claims *mgmt.Claims `json:"claims"`
|
||||||
Details interface{} `json:"details"`
|
Details interface{} `json:"details"`
|
||||||
X509Template string `json:"x509Template"`
|
X509Template string `json:"x509Template"`
|
||||||
SSHTemplate string `json:"sshTemplate"`
|
SSHTemplate string `json:"sshTemplate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates a new-provisioner request body.
|
// Validate validates a new-provisioner request body.
|
||||||
|
@ -25,10 +25,10 @@ func (car *CreateProvisionerRequest) Validate() error {
|
||||||
|
|
||||||
// UpdateProvisionerRequest represents the body for a UpdateProvisioner request.
|
// UpdateProvisionerRequest represents the body for a UpdateProvisioner request.
|
||||||
type UpdateProvisionerRequest struct {
|
type UpdateProvisionerRequest struct {
|
||||||
Claims *config.Claims `json:"claims"`
|
Claims *mgmt.Claims `json:"claims"`
|
||||||
Details interface{} `json:"details"`
|
Details interface{} `json:"details"`
|
||||||
X509Template string `json:"x509Template"`
|
X509Template string `json:"x509Template"`
|
||||||
SSHTemplate string `json:"sshTemplate"`
|
SSHTemplate string `json:"sshTemplate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates a new-provisioner request body.
|
// Validate validates a new-provisioner request body.
|
||||||
|
@ -66,7 +66,7 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
var body CreateProvisionerRequest
|
var body CreateProvisionerRequest
|
||||||
if err := ReadJSON(r.Body, &body); err != nil {
|
if err := api.ReadJSON(r.Body, &body); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prov := &config.Provisioner{
|
prov := &mgmt.Provisioner{
|
||||||
Type: body.Type,
|
Type: body.Type,
|
||||||
Name: body.Name,
|
Name: body.Name,
|
||||||
Claims: body.Claims,
|
Claims: body.Claims,
|
||||||
|
@ -91,32 +91,34 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// UpdateProvisioner updates an existing prov.
|
// UpdateProvisioner updates an existing prov.
|
||||||
func (h *Handler) UpdateProvisioner(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) UpdateProvisioner(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
/*
|
||||||
id := chi.URLParam(r, "id")
|
ctx := r.Context()
|
||||||
|
id := chi.URLParam(r, "id")
|
||||||
|
|
||||||
var body UpdateProvisionerRequest
|
var body UpdateProvisionerRequest
|
||||||
if err := ReadJSON(r.Body, &body); err != nil {
|
if err := ReadJSON(r.Body, &body); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := body.Validate(); err != nil {
|
if err := body.Validate(); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if prov, err := h.db.GetProvisioner(ctx, id); err != nil {
|
if prov, err := h.db.GetProvisioner(ctx, id); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
prov.Claims = body.Claims
|
prov.Claims = body.Claims
|
||||||
prov.Details = body.Provisioner
|
prov.Details = body.Provisioner
|
||||||
prov.X509Template = body.X509Template
|
prov.X509Template = body.X509Template
|
||||||
prov.SSHTemplate = body.SSHTemplate
|
prov.SSHTemplate = body.SSHTemplate
|
||||||
prov.Status = body.Status
|
prov.Status = body.Status
|
||||||
|
|
||||||
if err := h.db.UpdateProvisioner(ctx, prov); err != nil {
|
if err := h.db.UpdateProvisioner(ctx, prov); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
api.JSON(w, prov)
|
api.JSON(w, prov)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,28 +19,8 @@ type AuthConfig struct {
|
||||||
|
|
||||||
func NewDefaultAuthConfig() *AuthConfig {
|
func NewDefaultAuthConfig() *AuthConfig {
|
||||||
return &AuthConfig{
|
return &AuthConfig{
|
||||||
Claims: &Claims{
|
Claims: NewDefaultClaims(),
|
||||||
X509: &X509Claims{
|
ASN1DN: &config.ASN1DN{},
|
||||||
Durations: &Durations{
|
|
||||||
Min: config.GlobalProvisionerClaims.MinTLSDur.String(),
|
|
||||||
Max: config.GlobalProvisionerClaims.MaxTLSDur.String(),
|
|
||||||
Default: config.GlobalProvisionerClaims.DefaultTLSDur.String(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SSH: &SSHClaims{
|
|
||||||
UserDurations: &Durations{
|
|
||||||
Min: config.GlobalProvisionerClaims.MinUserSSHDur.String(),
|
|
||||||
Max: config.GlobalProvisionerClaims.MaxUserSSHDur.String(),
|
|
||||||
Default: config.GlobalProvisionerClaims.DefaultUserSSHDur.String(),
|
|
||||||
},
|
|
||||||
HostDurations: &Durations{
|
|
||||||
Min: config.GlobalProvisionerClaims.MinHostSSHDur.String(),
|
|
||||||
Max: config.GlobalProvisionerClaims.MaxHostSSHDur.String(),
|
|
||||||
Default: config.GlobalProvisionerClaims.DefaultHostSSHDur.String(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DisableRenewal: config.DefaultDisableRenewal,
|
|
||||||
},
|
|
||||||
Backdate: config.DefaultBackdate.String(),
|
Backdate: config.DefaultBackdate.String(),
|
||||||
Status: StatusActive,
|
Status: StatusActive,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/certificates/authority/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -50,6 +51,31 @@ type Durations struct {
|
||||||
Default string `json:"default"`
|
Default string `json:"default"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDefaultClaims() *Claims {
|
||||||
|
return &Claims{
|
||||||
|
X509: &X509Claims{
|
||||||
|
Durations: &Durations{
|
||||||
|
Min: config.GlobalProvisionerClaims.MinTLSDur.String(),
|
||||||
|
Max: config.GlobalProvisionerClaims.MaxTLSDur.String(),
|
||||||
|
Default: config.GlobalProvisionerClaims.DefaultTLSDur.String(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SSH: &SSHClaims{
|
||||||
|
UserDurations: &Durations{
|
||||||
|
Min: config.GlobalProvisionerClaims.MinUserSSHDur.String(),
|
||||||
|
Max: config.GlobalProvisionerClaims.MaxUserSSHDur.String(),
|
||||||
|
Default: config.GlobalProvisionerClaims.DefaultUserSSHDur.String(),
|
||||||
|
},
|
||||||
|
HostDurations: &Durations{
|
||||||
|
Min: config.GlobalProvisionerClaims.MinHostSSHDur.String(),
|
||||||
|
Max: config.GlobalProvisionerClaims.MaxHostSSHDur.String(),
|
||||||
|
Default: config.GlobalProvisionerClaims.DefaultHostSSHDur.String(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DisableRenewal: config.DefaultDisableRenewal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type AuthorityOption func(*AuthConfig) error
|
type AuthorityOption func(*AuthConfig) error
|
||||||
|
|
||||||
func WithDefaultAuthorityID(ac *AuthConfig) error {
|
func WithDefaultAuthorityID(ac *AuthConfig) error {
|
||||||
|
|
|
@ -18,7 +18,7 @@ type DB interface {
|
||||||
UpdateProvisioner(ctx context.Context, prov *Provisioner) error
|
UpdateProvisioner(ctx context.Context, prov *Provisioner) error
|
||||||
|
|
||||||
CreateAdmin(ctx context.Context, admin *Admin) error
|
CreateAdmin(ctx context.Context, admin *Admin) error
|
||||||
GetAdmin(ctx context.Context, id string) error
|
GetAdmin(ctx context.Context, id string) (*Admin, error)
|
||||||
GetAdmins(ctx context.Context) ([]*Admin, error)
|
GetAdmins(ctx context.Context) ([]*Admin, error)
|
||||||
UpdateAdmin(ctx context.Context, admin *Admin) error
|
UpdateAdmin(ctx context.Context, admin *Admin) error
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ func (m *MockDB) GetAdmins(ctx context.Context) ([]*Admin, error) {
|
||||||
|
|
||||||
// UpdateAdmin mock
|
// UpdateAdmin mock
|
||||||
func (m *MockDB) UpdateAdmin(ctx context.Context, adm *Admin) error {
|
func (m *MockDB) UpdateAdmin(ctx context.Context, adm *Admin) error {
|
||||||
if m.UpdateAdmin != nil {
|
if m.MockUpdateAdmin != nil {
|
||||||
return m.MockUpdateAdmin(ctx, adm)
|
return m.MockUpdateAdmin(ctx, adm)
|
||||||
}
|
}
|
||||||
return m.MockError
|
return m.MockError
|
||||||
|
@ -142,7 +142,7 @@ func (m *MockDB) GetAuthConfig(ctx context.Context, id string) (*AuthConfig, err
|
||||||
|
|
||||||
// UpdateAuthConfig mock
|
// UpdateAuthConfig mock
|
||||||
func (m *MockDB) UpdateAuthConfig(ctx context.Context, adm *AuthConfig) error {
|
func (m *MockDB) UpdateAuthConfig(ctx context.Context, adm *AuthConfig) error {
|
||||||
if m.UpdateAuthConfig != nil {
|
if m.MockUpdateAuthConfig != nil {
|
||||||
return m.MockUpdateAuthConfig(ctx, adm)
|
return m.MockUpdateAuthConfig(ctx, adm)
|
||||||
}
|
}
|
||||||
return m.MockError
|
return m.MockError
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/acme"
|
|
||||||
"github.com/smallstep/certificates/authority/mgmt"
|
"github.com/smallstep/certificates/authority/mgmt"
|
||||||
"github.com/smallstep/nosql"
|
"github.com/smallstep/nosql"
|
||||||
)
|
)
|
||||||
|
@ -109,7 +108,7 @@ func unmarshalAdmin(data []byte, id string) (*mgmt.Admin, error) {
|
||||||
// GetAdmins retrieves and unmarshals all active (not deleted) admins
|
// GetAdmins retrieves and unmarshals all active (not deleted) admins
|
||||||
// from the database.
|
// from the database.
|
||||||
// TODO should we be paginating?
|
// TODO should we be paginating?
|
||||||
func (db *DB) GetAdmins(ctx context.Context, az *acme.Authorization) ([]*mgmt.Admin, error) {
|
func (db *DB) GetAdmins(ctx context.Context) ([]*mgmt.Admin, error) {
|
||||||
dbEntries, err := db.db.List(authorityAdminsTable)
|
dbEntries, err := db.db.List(authorityAdminsTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error loading admins")
|
return nil, errors.Wrap(err, "error loading admins")
|
||||||
|
|
|
@ -12,13 +12,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type dbAuthConfig struct {
|
type dbAuthConfig struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
ASN1DN *config.ASN1DN `json:"asn1dn"`
|
ASN1DN *config.ASN1DN `json:"asn1dn"`
|
||||||
Claims *mgmt.Claims `json:"claims"`
|
Claims *mgmt.Claims `json:"claims"`
|
||||||
DisableIssuedAtCheck bool `json:"disableIssuedAtCheck,omitempty"`
|
Backdate string `json:"backdate,omitempty"`
|
||||||
Backdate string `json:"backdate,omitempty"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
DeletedAt time.Time `json:"deletedAt"`
|
||||||
DeletedAt time.Time `json:"deletedAt"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *dbAuthConfig) clone() *dbAuthConfig {
|
func (dbp *dbAuthConfig) clone() *dbAuthConfig {
|
||||||
|
@ -63,30 +62,30 @@ func (db *DB) GetAuthConfig(ctx context.Context, id string) (*mgmt.AuthConfig, e
|
||||||
}
|
}
|
||||||
|
|
||||||
return &mgmt.AuthConfig{
|
return &mgmt.AuthConfig{
|
||||||
ID: dba.ID,
|
ID: dba.ID,
|
||||||
Provisioners: provs,
|
Provisioners: provs,
|
||||||
ASN1DN: dba.ASN1DN,
|
ASN1DN: dba.ASN1DN,
|
||||||
Backdate: dba.Backdate,
|
Backdate: dba.Backdate,
|
||||||
Claims: dba.Claims,
|
Claims: dba.Claims,
|
||||||
DisableIssuedAtCheck: dba.DisableIssuedAtCheck,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAuthConfig stores a new provisioner to the database.
|
// CreateAuthConfig stores a new provisioner to the database.
|
||||||
func (db *DB) CreateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
|
func (db *DB) CreateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
|
||||||
var err error
|
var err error
|
||||||
ac.ID, err = randID()
|
if ac.ID == "" {
|
||||||
if err != nil {
|
ac.ID, err = randID()
|
||||||
return errors.Wrap(err, "error generating random id for provisioner")
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error generating random id for provisioner")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dba := &dbAuthConfig{
|
dba := &dbAuthConfig{
|
||||||
ID: ac.ID,
|
ID: ac.ID,
|
||||||
ASN1DN: ac.ASN1DN,
|
ASN1DN: ac.ASN1DN,
|
||||||
Claims: ac.Claims,
|
Claims: ac.Claims,
|
||||||
DisableIssuedAtCheck: ac.DisableIssuedAtCheck,
|
Backdate: ac.Backdate,
|
||||||
Backdate: ac.Backdate,
|
CreatedAt: clock.Now(),
|
||||||
CreatedAt: clock.Now(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.save(ctx, dba.ID, dba, nil, "authConfig", authorityConfigsTable)
|
return db.save(ctx, dba.ID, dba, nil, "authConfig", authorityConfigsTable)
|
||||||
|
@ -106,7 +105,6 @@ func (db *DB) UpdateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
|
||||||
nu.DeletedAt = clock.Now()
|
nu.DeletedAt = clock.Now()
|
||||||
}
|
}
|
||||||
nu.Claims = ac.Claims
|
nu.Claims = ac.Claims
|
||||||
nu.DisableIssuedAtCheck = ac.DisableIssuedAtCheck
|
|
||||||
nu.Backdate = ac.Backdate
|
nu.Backdate = ac.Backdate
|
||||||
|
|
||||||
return db.save(ctx, old.ID, nu, old, "authConfig", authorityProvisionersTable)
|
return db.save(ctx, old.ID, nu, old, "authConfig", authorityProvisionersTable)
|
||||||
|
|
|
@ -87,6 +87,11 @@ type Error struct {
|
||||||
Status int `json:"-"`
|
Status int `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsType returns true if the error type matches the input type.
|
||||||
|
func (e *Error) IsType(pt ProblemType) bool {
|
||||||
|
return pt.String() == e.Type
|
||||||
|
}
|
||||||
|
|
||||||
// NewError creates a new Error type.
|
// NewError creates a new Error type.
|
||||||
func NewError(pt ProblemType, msg string, args ...interface{}) *Error {
|
func NewError(pt ProblemType, msg string, args ...interface{}) *Error {
|
||||||
return newError(pt, errors.Errorf(msg, args...))
|
return newError(pt, errors.Errorf(msg, args...))
|
||||||
|
|
|
@ -20,6 +20,16 @@ type ProvisionerCtx struct {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewProvisionerCtx(opts ...ProvisionerOption) *ProvisionerCtx {
|
||||||
|
pc := &ProvisionerCtx{
|
||||||
|
Claims: NewDefaultClaims(),
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(pc)
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
func WithJWK(jwk *jose.JSONWebKey, jwe *jose.JSONWebEncryption) func(*ProvisionerCtx) {
|
func WithJWK(jwk *jose.JSONWebKey, jwe *jose.JSONWebEncryption) func(*ProvisionerCtx) {
|
||||||
return func(ctx *ProvisionerCtx) {
|
return func(ctx *ProvisionerCtx) {
|
||||||
ctx.JWK = jwk
|
ctx.JWK = jwk
|
||||||
|
@ -62,10 +72,7 @@ func (p *Provisioner) GetOptions() *provisioner.Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateProvisioner(ctx context.Context, db DB, typ, name string, opts ...ProvisionerOption) (*Provisioner, error) {
|
func CreateProvisioner(ctx context.Context, db DB, typ, name string, opts ...ProvisionerOption) (*Provisioner, error) {
|
||||||
pc := new(ProvisionerCtx)
|
pc := NewProvisionerCtx(opts...)
|
||||||
for _, o := range opts {
|
|
||||||
o(pc)
|
|
||||||
}
|
|
||||||
|
|
||||||
details, err := createJWKDetails(pc)
|
details, err := createJWKDetails(pc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
12
ca/ca.go
12
ca/ca.go
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/smallstep/certificates/authority"
|
"github.com/smallstep/certificates/authority"
|
||||||
"github.com/smallstep/certificates/authority/config"
|
"github.com/smallstep/certificates/authority/config"
|
||||||
"github.com/smallstep/certificates/authority/mgmt"
|
"github.com/smallstep/certificates/authority/mgmt"
|
||||||
|
mgmtAPI "github.com/smallstep/certificates/authority/mgmt/api"
|
||||||
"github.com/smallstep/certificates/db"
|
"github.com/smallstep/certificates/db"
|
||||||
"github.com/smallstep/certificates/logging"
|
"github.com/smallstep/certificates/logging"
|
||||||
"github.com/smallstep/certificates/monitoring"
|
"github.com/smallstep/certificates/monitoring"
|
||||||
|
@ -143,6 +144,7 @@ func (ca *CA) Init(config *config.Config) (*CA, error) {
|
||||||
dns = fmt.Sprintf("%s:%s", dns, port)
|
dns = fmt.Sprintf("%s:%s", dns, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ACME Router
|
||||||
prefix := "acme"
|
prefix := "acme"
|
||||||
var acmeDB acme.DB
|
var acmeDB acme.DB
|
||||||
if config.DB == nil {
|
if config.DB == nil {
|
||||||
|
@ -169,6 +171,16 @@ func (ca *CA) Init(config *config.Config) (*CA, error) {
|
||||||
acmeHandler.Route(r)
|
acmeHandler.Route(r)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// MGMT Router
|
||||||
|
|
||||||
|
mgmtDB := auth.GetMgmtDatabase()
|
||||||
|
if mgmtDB != nil {
|
||||||
|
mgmtHandler := mgmtAPI.NewHandler(mgmtDB)
|
||||||
|
mux.Route("/mgmt", func(r chi.Router) {
|
||||||
|
mgmtHandler.Route(r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// helpful routine for logging all routes //
|
// helpful routine for logging all routes //
|
||||||
/*
|
/*
|
||||||
walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
|
walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
|
||||||
|
|
|
@ -60,10 +60,10 @@ func (c *MgmtClient) retryOnError(r *http.Response) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAdmin performs the GET /config/admin/{id} request to the CA.
|
// GetAdmin performs the GET /mgmt/admin/{id} request to the CA.
|
||||||
func (c *MgmtClient) GetAdmin(id string) (*mgmt.Admin, error) {
|
func (c *MgmtClient) GetAdmin(id string) (*mgmt.Admin, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/config/admin", id)})
|
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/mgmt/admin", id)})
|
||||||
retry:
|
retry:
|
||||||
resp, err := c.client.Get(u.String())
|
resp, err := c.client.Get(u.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -83,10 +83,10 @@ retry:
|
||||||
return adm, nil
|
return adm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAdmins performs the GET /config/admins request to the CA.
|
// GetAdmins performs the GET /mgmt/admins request to the CA.
|
||||||
func (c *MgmtClient) GetAdmins() ([]*mgmt.Admin, error) {
|
func (c *MgmtClient) GetAdmins() ([]*mgmt.Admin, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
u := c.endpoint.ResolveReference(&url.URL{Path: "/config/admins"})
|
u := c.endpoint.ResolveReference(&url.URL{Path: "/mgmt/admins"})
|
||||||
retry:
|
retry:
|
||||||
resp, err := c.client.Get(u.String())
|
resp, err := c.client.Get(u.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue