Use new x509util in tls_test.go

This commit is contained in:
Mariano Cano 2020-08-10 18:14:32 -07:00
parent 0a59efd853
commit 3577d696c7

View file

@ -3,6 +3,8 @@ package authority
import (
"context"
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha1"
"crypto/x509"
@ -22,8 +24,8 @@ import (
"github.com/smallstep/certificates/errs"
"github.com/smallstep/cli/crypto/keys"
"github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/crypto/x509util"
"github.com/smallstep/cli/jose"
"go.step.sm/crypto/x509util"
"gopkg.in/square/go-jose.v2/jwt"
)
@ -51,10 +53,73 @@ func (m *certificateDurationEnforcer) Enforce(cert *x509.Certificate) error {
return nil
}
func withProvisionerOID(name, kid string) x509util.WithOption {
return func(p x509util.Profile) error {
crt := p.Subject()
func generateCertificate(t *testing.T, commonName string, sans []string, opts ...interface{}) *x509.Certificate {
t.Helper()
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.FatalError(t, err)
cr, err := x509util.CreateCertificateRequest(commonName, sans, priv)
assert.FatalError(t, err)
template, err := x509util.NewCertificate(cr)
assert.FatalError(t, err)
cert := template.GetCertificate()
for _, m := range opts {
switch m := m.(type) {
case provisioner.CertificateModifierFunc:
err = m.Modify(cert, provisioner.SignOptions{})
assert.FatalError(t, err)
case signerFunc:
cert, err = m(cert, priv.Public())
assert.FatalError(t, err)
default:
t.Fatalf("unknown type %T", m)
}
}
return cert
}
func generateRootCertificate(t *testing.T) (*x509.Certificate, crypto.Signer) {
t.Helper()
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.FatalError(t, err)
cr, err := x509util.CreateCertificateRequest("TestRootCA", nil, priv)
assert.FatalError(t, err)
data := x509util.CreateTemplateData("TestRootCA", nil)
template, err := x509util.NewCertificate(cr, x509util.WithTemplate(x509util.DefaultRootTemplate, data))
assert.FatalError(t, err)
cert := template.GetCertificate()
cert, err = x509util.CreateCertificate(cert, cert, priv.Public(), priv)
assert.FatalError(t, err)
return cert, priv
}
func generateIntermidiateCertificate(t *testing.T, issuer *x509.Certificate, signer crypto.Signer) (*x509.Certificate, crypto.Signer) {
t.Helper()
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.FatalError(t, err)
cr, err := x509util.CreateCertificateRequest("TestIntermediateCA", nil, priv)
assert.FatalError(t, err)
data := x509util.CreateTemplateData("TestIntermediateCA", nil)
template, err := x509util.NewCertificate(cr, x509util.WithTemplate(x509util.DefaultRootTemplate, data))
assert.FatalError(t, err)
cert := template.GetCertificate()
cert, err = x509util.CreateCertificate(cert, issuer, priv.Public(), signer)
assert.FatalError(t, err)
return cert, priv
}
func withProvisionerOID(name, kid string) provisioner.CertificateModifierFunc {
return func(crt *x509.Certificate, _ provisioner.SignOptions) error {
b, err := asn1.Marshal(stepProvisionerASN1{
Type: provisionerTypeJWK,
Name: []byte(name),
@ -68,11 +133,26 @@ func withProvisionerOID(name, kid string) x509util.WithOption {
Critical: false,
Value: b,
})
return nil
}
}
func withNotBeforeNotAfter(notBefore, notAfter time.Time) provisioner.CertificateModifierFunc {
return func(crt *x509.Certificate, _ provisioner.SignOptions) error {
crt.NotBefore = notBefore
crt.NotAfter = notAfter
return nil
}
}
type signerFunc func(crt *x509.Certificate, pub crypto.PublicKey) (*x509.Certificate, error)
func withSigner(issuer *x509.Certificate, signer crypto.Signer) signerFunc {
return func(crt *x509.Certificate, pub crypto.PublicKey) (*x509.Certificate, error) {
return x509util.CreateCertificate(crt, issuer, pub, signer)
}
}
func getCSR(t *testing.T, priv interface{}, opts ...func(*x509.CertificateRequest)) *x509.CertificateRequest {
_csr := &x509.CertificateRequest{
Subject: pkix.Name{CommonName: "smallstep test"},
@ -473,9 +553,6 @@ ZYtQ9Ot36qc=
}
func TestAuthority_Renew(t *testing.T) {
pub, _, err := keys.GenerateDefaultKeyPair()
assert.FatalError(t, err)
a := testAuthority(t)
a.config.AuthorityConfig.Template = &ASN1DN{
Country: "Tazmania",
@ -486,13 +563,6 @@ func TestAuthority_Renew(t *testing.T) {
CommonName: "renew",
}
certModToWithOptions := func(m provisioner.CertificateModifierFunc) x509util.WithOption {
return func(p x509util.Profile) error {
crt := p.Subject()
return m.Modify(crt, provisioner.SignOptions{})
}
}
now := time.Now().UTC()
nb1 := now.Add(-time.Minute * 7)
na1 := now
@ -501,28 +571,17 @@ func TestAuthority_Renew(t *testing.T) {
NotAfter: provisioner.NewTimeDuration(na1),
}
leaf, err := x509util.NewLeafProfile("renew", a.x509Issuer, a.x509Signer,
x509util.WithNotBeforeAfterDuration(so.NotBefore.Time(), so.NotAfter.Time(), 0),
certModToWithOptions(withDefaultASN1DN(a.config.AuthorityConfig.Template)),
x509util.WithPublicKey(pub), x509util.WithHosts("test.smallstep.com,test"),
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID))
assert.FatalError(t, err)
certBytes, err := leaf.CreateCertificate()
assert.FatalError(t, err)
cert, err := x509.ParseCertificate(certBytes)
assert.FatalError(t, err)
cert := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
withDefaultASN1DN(a.config.AuthorityConfig.Template),
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID),
withSigner(a.x509Issuer, a.x509Signer))
leafNoRenew, err := x509util.NewLeafProfile("norenew", a.x509Issuer, a.x509Signer,
x509util.WithNotBeforeAfterDuration(so.NotBefore.Time(), so.NotAfter.Time(), 0),
certModToWithOptions(withDefaultASN1DN(a.config.AuthorityConfig.Template)),
x509util.WithPublicKey(pub), x509util.WithHosts("test.smallstep.com,test"),
certNoRenew := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
withDefaultASN1DN(a.config.AuthorityConfig.Template),
withProvisionerOID("dev", a.config.AuthorityConfig.Provisioners[2].(*provisioner.JWK).Key.KeyID),
)
assert.FatalError(t, err)
certBytesNoRenew, err := leafNoRenew.CreateCertificate()
assert.FatalError(t, err)
certNoRenew, err := x509.ParseCertificate(certBytesNoRenew)
assert.FatalError(t, err)
withSigner(a.x509Issuer, a.x509Signer))
type renewTest struct {
auth *Authority
@ -555,24 +614,12 @@ func TestAuthority_Renew(t *testing.T) {
}, nil
},
"ok/success-new-intermediate": func() (*renewTest, error) {
newRootProfile, err := x509util.NewRootProfile("new-root")
assert.FatalError(t, err)
newRootBytes, err := newRootProfile.CreateCertificate()
assert.FatalError(t, err)
newRootCert, err := x509.ParseCertificate(newRootBytes)
assert.FatalError(t, err)
newIntermediateProfile, err := x509util.NewIntermediateProfile("new-intermediate",
newRootCert, newRootProfile.SubjectPrivateKey())
assert.FatalError(t, err)
newIntermediateBytes, err := newIntermediateProfile.CreateCertificate()
assert.FatalError(t, err)
newIntermediateCert, err := x509.ParseCertificate(newIntermediateBytes)
assert.FatalError(t, err)
rootCert, rootSigner := generateRootCertificate(t)
intCert, intSigner := generateIntermidiateCertificate(t, rootCert, rootSigner)
_a := testAuthority(t)
_a.x509Signer = newIntermediateProfile.SubjectPrivateKey().(crypto.Signer)
_a.x509Issuer = newIntermediateCert
_a.x509Signer = intSigner
_a.x509Issuer = intCert
return &renewTest{
auth: _a,
cert: cert,
@ -634,7 +681,7 @@ func TestAuthority_Renew(t *testing.T) {
[]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth})
assert.Equals(t, leaf.DNSNames, []string{"test.smallstep.com", "test"})
subjectKeyID, err := generateSubjectKeyID(pub)
subjectKeyID, err := generateSubjectKeyID(leaf.PublicKey)
assert.FatalError(t, err)
assert.Equals(t, leaf.SubjectKeyId, subjectKeyID)
@ -700,8 +747,6 @@ func TestAuthority_Renew(t *testing.T) {
func TestAuthority_Rekey(t *testing.T) {
pub, _, err := keys.GenerateDefaultKeyPair()
assert.FatalError(t, err)
pub1, _, err := keys.GenerateDefaultKeyPair()
assert.FatalError(t, err)
a := testAuthority(t)
a.config.AuthorityConfig.Template = &ASN1DN{
@ -713,13 +758,6 @@ func TestAuthority_Rekey(t *testing.T) {
CommonName: "renew",
}
certModToWithOptions := func(m provisioner.CertificateModifierFunc) x509util.WithOption {
return func(p x509util.Profile) error {
crt := p.Subject()
return m.Modify(crt, provisioner.SignOptions{})
}
}
now := time.Now().UTC()
nb1 := now.Add(-time.Minute * 7)
na1 := now
@ -728,28 +766,17 @@ func TestAuthority_Rekey(t *testing.T) {
NotAfter: provisioner.NewTimeDuration(na1),
}
leaf, err := x509util.NewLeafProfile("renew", a.x509Issuer, a.x509Signer,
x509util.WithNotBeforeAfterDuration(so.NotBefore.Time(), so.NotAfter.Time(), 0),
certModToWithOptions(withDefaultASN1DN(a.config.AuthorityConfig.Template)),
x509util.WithPublicKey(pub), x509util.WithHosts("test.smallstep.com,test"),
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID))
assert.FatalError(t, err)
certBytes, err := leaf.CreateCertificate()
assert.FatalError(t, err)
cert, err := x509.ParseCertificate(certBytes)
assert.FatalError(t, err)
cert := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
withDefaultASN1DN(a.config.AuthorityConfig.Template),
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID),
withSigner(a.x509Issuer, a.x509Signer))
leafNoRenew, err := x509util.NewLeafProfile("norenew", a.x509Issuer, a.x509Signer,
x509util.WithNotBeforeAfterDuration(so.NotBefore.Time(), so.NotAfter.Time(), 0),
certModToWithOptions(withDefaultASN1DN(a.config.AuthorityConfig.Template)),
x509util.WithPublicKey(pub), x509util.WithHosts("test.smallstep.com,test"),
certNoRenew := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
withDefaultASN1DN(a.config.AuthorityConfig.Template),
withProvisionerOID("dev", a.config.AuthorityConfig.Provisioners[2].(*provisioner.JWK).Key.KeyID),
)
assert.FatalError(t, err)
certBytesNoRenew, err := leafNoRenew.CreateCertificate()
assert.FatalError(t, err)
certNoRenew, err := x509.ParseCertificate(certBytesNoRenew)
assert.FatalError(t, err)
withSigner(a.x509Issuer, a.x509Signer))
type renewTest struct {
auth *Authority
@ -786,28 +813,16 @@ func TestAuthority_Rekey(t *testing.T) {
return &renewTest{
auth: a,
cert: cert,
pk: pub1,
pk: pub,
}, nil
},
"ok/renew/success-new-intermediate": func() (*renewTest, error) {
newRootProfile, err := x509util.NewRootProfile("new-root")
assert.FatalError(t, err)
newRootBytes, err := newRootProfile.CreateCertificate()
assert.FatalError(t, err)
newRootCert, err := x509.ParseCertificate(newRootBytes)
assert.FatalError(t, err)
newIntermediateProfile, err := x509util.NewIntermediateProfile("new-intermediate",
newRootCert, newRootProfile.SubjectPrivateKey())
assert.FatalError(t, err)
newIntermediateBytes, err := newIntermediateProfile.CreateCertificate()
assert.FatalError(t, err)
newIntermediateCert, err := x509.ParseCertificate(newIntermediateBytes)
assert.FatalError(t, err)
rootCert, rootSigner := generateRootCertificate(t)
intCert, intSigner := generateIntermidiateCertificate(t, rootCert, rootSigner)
_a := testAuthority(t)
_a.x509Signer = newIntermediateProfile.SubjectPrivateKey().(crypto.Signer)
_a.x509Issuer = newIntermediateCert
_a.x509Signer = intSigner
_a.x509Issuer = intCert
return &renewTest{
auth: _a,
cert: cert,