Use new x509util on pki package.

This commit is contained in:
Mariano Cano 2020-08-10 19:05:27 -07:00
parent 3577d696c7
commit 8c2d5425e7

View file

@ -14,6 +14,7 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/authority" "github.com/smallstep/certificates/authority"
@ -23,11 +24,11 @@ import (
"github.com/smallstep/cli/config" "github.com/smallstep/cli/config"
"github.com/smallstep/cli/crypto/keys" "github.com/smallstep/cli/crypto/keys"
"github.com/smallstep/cli/crypto/pemutil" "github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/crypto/x509util"
"github.com/smallstep/cli/errs" "github.com/smallstep/cli/errs"
"github.com/smallstep/cli/jose" "github.com/smallstep/cli/jose"
"github.com/smallstep/cli/ui" "github.com/smallstep/cli/ui"
"github.com/smallstep/cli/utils" "github.com/smallstep/cli/utils"
"go.step.sm/crypto/x509util"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
@ -113,6 +114,18 @@ func GetProvisioners(caURL, rootFile string) (provisioner.List, error) {
} }
} }
func generateDefaultKey() (crypto.Signer, error) {
priv, err := keys.GenerateDefaultKey()
if err != nil {
return nil, err
}
signer, ok := priv.(crypto.Signer)
if !ok {
return nil, errors.Errorf("type %T is not a cyrpto.Signer", priv)
}
return signer, nil
}
// GetProvisionerKey returns the encrypted provisioner key with the for the // GetProvisionerKey returns the encrypted provisioner key with the for the
// given kid. // given kid.
func GetProvisionerKey(caURL, rootFile, kid string) (string, error) { func GetProvisionerKey(caURL, rootFile, kid string) (string, error) {
@ -254,25 +267,35 @@ func (p *PKI) GenerateKeyPairs(pass []byte) error {
// GenerateRootCertificate generates a root certificate with the given name. // GenerateRootCertificate generates a root certificate with the given name.
func (p *PKI) GenerateRootCertificate(name string, pass []byte) (*x509.Certificate, interface{}, error) { func (p *PKI) GenerateRootCertificate(name string, pass []byte) (*x509.Certificate, interface{}, error) {
rootProfile, err := x509util.NewRootProfile(name) signer, err := generateDefaultKey()
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
rootBytes, err := rootProfile.CreateWriteCertificate(p.root, p.rootKey, string(pass)) cr, err := x509util.CreateCertificateRequest(name, []string{}, signer)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
rootCrt, err := x509.ParseCertificate(rootBytes) data := x509util.CreateTemplateData(name, []string{})
cert, err := x509util.NewCertificate(cr, x509util.WithTemplate(x509util.DefaultRootTemplate, data))
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "error parsing root certificate") return nil, nil, err
} }
sum := sha256.Sum256(rootCrt.Raw) template := cert.GetCertificate()
p.rootFingerprint = strings.ToLower(hex.EncodeToString(sum[:])) template.NotBefore = time.Now()
template.NotAfter = template.NotBefore.AddDate(10, 0, 0)
rootCrt, err := x509util.CreateCertificate(template, template, signer.Public(), signer)
if err != nil {
return nil, nil, err
}
return rootCrt, rootProfile.SubjectPrivateKey(), nil if err := p.WriteRootCertificate(rootCrt, signer, pass); err != nil {
return nil, nil, err
}
return rootCrt, signer, nil
} }
// WriteRootCertificate writes to disk the given certificate and key. // WriteRootCertificate writes to disk the given certificate and key.
@ -284,7 +307,7 @@ func (p *PKI) WriteRootCertificate(rootCrt *x509.Certificate, rootKey interface{
return err return err
} }
_, err := pemutil.Serialize(rootKey, pemutil.WithPassword([]byte(pass)), pemutil.ToFile(p.rootKey, 0600)) _, err := pemutil.Serialize(rootKey, pemutil.WithPassword(pass), pemutil.ToFile(p.rootKey, 0600))
if err != nil { if err != nil {
return err return err
} }
@ -298,12 +321,46 @@ func (p *PKI) WriteRootCertificate(rootCrt *x509.Certificate, rootKey interface{
// GenerateIntermediateCertificate generates an intermediate certificate with // GenerateIntermediateCertificate generates an intermediate certificate with
// the given name. // the given name.
func (p *PKI) GenerateIntermediateCertificate(name string, rootCrt *x509.Certificate, rootKey interface{}, pass []byte) error { func (p *PKI) GenerateIntermediateCertificate(name string, rootCrt *x509.Certificate, rootKey interface{}, pass []byte) error {
interProfile, err := x509util.NewIntermediateProfile(name, rootCrt, rootKey) key, err := generateDefaultKey()
if err != nil { if err != nil {
return err return err
} }
_, err = interProfile.CreateWriteCertificate(p.intermediate, p.intermediateKey, string(pass))
return err cr, err := x509util.CreateCertificateRequest(name, []string{}, key)
if err != nil {
return err
}
data := x509util.CreateTemplateData(name, []string{})
cert, err := x509util.NewCertificate(cr, x509util.WithTemplate(x509util.DefaultIntermediateTemplate, data))
if err != nil {
return err
}
template := cert.GetCertificate()
template.NotBefore = rootCrt.NotBefore
template.NotAfter = rootCrt.NotAfter
intermediateCrt, err := x509util.CreateCertificate(template, rootCrt, key.Public(), rootKey.(crypto.Signer))
if err != nil {
return err
}
return p.WriteIntermediateCertificate(intermediateCrt, key, pass)
}
// WriteIntermediateCertificate writes to disk the given certificate and key.
func (p *PKI) WriteIntermediateCertificate(crt *x509.Certificate, key interface{}, pass []byte) error {
if err := utils.WriteFile(p.intermediate, pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: crt.Raw,
}), 0600); err != nil {
return err
}
_, err := pemutil.Serialize(key, pemutil.WithPassword(pass), pemutil.ToFile(p.intermediateKey, 0600))
if err != nil {
return err
}
return nil
} }
// GenerateSSHSigningKeys generates and encrypts a private key used for signing // GenerateSSHSigningKeys generates and encrypts a private key used for signing