Fix extensions copy on renew

Fixes #36
This commit is contained in:
Mariano Cano 2019-02-14 16:44:36 -08:00
parent 7893f84677
commit d78febec7a
2 changed files with 29 additions and 5 deletions

View file

@ -30,8 +30,9 @@ type SignOptions struct {
} }
var ( var (
stepOIDRoot = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 37476, 9000, 64} stepOIDRoot = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 37476, 9000, 64}
stepOIDProvisioner = append(asn1.ObjectIdentifier(nil), append(stepOIDRoot, 1)...) stepOIDProvisioner = append(asn1.ObjectIdentifier(nil), append(stepOIDRoot, 1)...)
oidAuthorityKeyIdentifier = asn1.ObjectIdentifier{2, 5, 29, 35}
) )
type stepProvisionerASN1 struct { type stepProvisionerASN1 struct {
@ -190,8 +191,6 @@ func (a *Authority) Renew(ocx *x509.Certificate) (*x509.Certificate, *x509.Certi
NotBefore: now, NotBefore: now,
NotAfter: now.Add(duration), NotAfter: now.Add(duration),
KeyUsage: oldCert.KeyUsage, KeyUsage: oldCert.KeyUsage,
Extensions: oldCert.Extensions,
ExtraExtensions: oldCert.ExtraExtensions,
UnhandledCriticalExtensions: oldCert.UnhandledCriticalExtensions, UnhandledCriticalExtensions: oldCert.UnhandledCriticalExtensions,
ExtKeyUsage: oldCert.ExtKeyUsage, ExtKeyUsage: oldCert.ExtKeyUsage,
UnknownExtKeyUsage: oldCert.UnknownExtKeyUsage, UnknownExtKeyUsage: oldCert.UnknownExtKeyUsage,
@ -218,6 +217,15 @@ func (a *Authority) Renew(ocx *x509.Certificate) (*x509.Certificate, *x509.Certi
PolicyIdentifiers: oldCert.PolicyIdentifiers, PolicyIdentifiers: oldCert.PolicyIdentifiers,
} }
// Copy all extensions except for Authority Key Identifier. This one might
// be different if we rotate the intermediate certificate and it will cause
// a TLS bad certificate error.
for _, ext := range oldCert.Extensions {
if !ext.Id.Equal(oidAuthorityKeyIdentifier) {
newCert.ExtraExtensions = append(newCert.ExtraExtensions, ext)
}
}
leaf, err := x509util.NewLeafProfileWithTemplate(newCert, leaf, err := x509util.NewLeafProfileWithTemplate(newCert,
issIdentity.Crt, issIdentity.Key) issIdentity.Crt, issIdentity.Key)
if err != nil { if err != nil {

View file

@ -9,6 +9,7 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"reflect"
"testing" "testing"
"time" "time"
@ -269,7 +270,8 @@ func TestRenew(t *testing.T) {
a.intermediateIdentity.Key, a.intermediateIdentity.Key,
x509util.WithNotBeforeAfterDuration(so.NotBefore, so.NotAfter, 0), x509util.WithNotBeforeAfterDuration(so.NotBefore, so.NotAfter, 0),
withDefaultASN1DN(a.config.AuthorityConfig.Template), withDefaultASN1DN(a.config.AuthorityConfig.Template),
x509util.WithPublicKey(pub), x509util.WithHosts("test.smallstep.com,test")) x509util.WithPublicKey(pub), x509util.WithHosts("test.smallstep.com,test"),
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].Key.KeyID))
assert.FatalError(t, err) assert.FatalError(t, err)
crtBytes, err := leaf.CreateCertificate() crtBytes, err := leaf.CreateCertificate()
assert.FatalError(t, err) assert.FatalError(t, err)
@ -390,6 +392,20 @@ func TestRenew(t *testing.T) {
realIntermediate, err := x509.ParseCertificate(a.intermediateIdentity.Crt.Raw) realIntermediate, err := x509.ParseCertificate(a.intermediateIdentity.Crt.Raw)
assert.FatalError(t, err) assert.FatalError(t, err)
assert.Equals(t, intermediate, realIntermediate) assert.Equals(t, intermediate, realIntermediate)
// Compare extensions: they can be in a different order
for _, ext1 := range crt.Extensions {
found := false
for _, ext2 := range leaf.Extensions {
if reflect.DeepEqual(ext1, ext2) {
found = true
break
}
}
if !found {
t.Errorf("x509 extension %s not found in renewed certificate", ext1.Id.String())
}
}
} }
} }
}) })