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