Merge pull request #312 from mtrmac/cert-expiration

Cert expiration
This commit is contained in:
David Lawrence 2015-12-10 08:40:24 -08:00
commit 26d30953c8
10 changed files with 48 additions and 51 deletions

View File

@ -242,7 +242,7 @@ func filestoreWithTwoCerts(t *testing.T, gun, keyAlg string) (
key, _, err := fileKeyStore.GetKey(pubKey.ID())
assert.NoError(t, err)
cert, err := cryptoservice.GenerateCertificate(key, gun)
cert, err := cryptoservice.GenerateTestingCertificate(key.CryptoSigner(), gun)
assert.NoError(t, err)
certificates[i] = cert

View File

@ -9,6 +9,7 @@ import (
"net/http"
"os"
"path/filepath"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/notary/certs"
@ -142,7 +143,9 @@ func (r *NotaryRepository) Initialize(rootKeyID string) error {
return err
}
rootCert, err := cryptoservice.GenerateCertificate(privKey, r.gun)
// Hard-coded policy: the generated certificate expires in 10 years.
startTime := time.Now()
rootCert, err := cryptoservice.GenerateCertificate(privKey, r.gun, startTime, startTime.AddDate(10, 0, 0))
if err != nil {
return err

View File

@ -2,8 +2,6 @@ package main
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/hex"
@ -16,6 +14,7 @@ import (
"time"
"github.com/docker/notary/client"
"github.com/docker/notary/cryptoservice"
"github.com/docker/notary/passphrase"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/tuf/data"
@ -201,19 +200,12 @@ func TestPrettyPrintSortedTargets(t *testing.T) {
// --- tests for pretty printing certs ---
func generateCertificate(t *testing.T, gun string, expireInHours int64) *x509.Certificate {
template, err := trustmanager.NewCertificate(gun)
assert.NoError(t, err)
template.NotAfter = template.NotBefore.Add(
time.Hour * time.Duration(expireInHours))
ecdsaPrivKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
ecdsaPrivKey, err := trustmanager.GenerateECDSAKey(rand.Reader)
assert.NoError(t, err)
certBytes, err := x509.CreateCertificate(rand.Reader, template, template,
ecdsaPrivKey.Public(), ecdsaPrivKey)
assert.NoError(t, err)
cert, err := x509.ParseCertificate(certBytes)
startTime := time.Now()
endTime := startTime.Add(time.Hour * time.Duration(expireInHours))
cert, err := cryptoservice.GenerateCertificate(ecdsaPrivKey, gun, startTime, endTime)
assert.NoError(t, err)
return cert
}

View File

@ -1,22 +1,35 @@
package cryptoservice
import (
"crypto"
"crypto/rand"
"crypto/x509"
"fmt"
"time"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/tuf/data"
)
// GenerateCertificate generates an X509 Certificate from a template, given a GUN
func GenerateCertificate(rootKey data.PrivateKey, gun string) (*x509.Certificate, error) {
// GenerateCertificate generates an X509 Certificate from a template, given a GUN and validity interval
func GenerateCertificate(rootKey data.PrivateKey, gun string, startTime, endTime time.Time) (*x509.Certificate, error) {
signer := rootKey.CryptoSigner()
if signer == nil {
return nil, fmt.Errorf("key type not supported for Certificate generation: %s\n", rootKey.Algorithm())
}
template, err := trustmanager.NewCertificate(gun)
return generateCertificate(signer, gun, startTime, endTime)
}
// GenerateTestingCertificate generates a non-expired X509 Certificate from a template, given a GUN.
// Good enough for tests where expiration does not really matter; do not use if you care about the policy.
func GenerateTestingCertificate(signer crypto.Signer, gun string) (*x509.Certificate, error) {
startTime := time.Now()
return generateCertificate(signer, gun, startTime, startTime.AddDate(10, 0, 0))
}
func generateCertificate(signer crypto.Signer, gun string, startTime, endTime time.Time) (*x509.Certificate, error) {
template, err := trustmanager.NewCertificate(gun, startTime, endTime)
if err != nil {
return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err)
}
@ -26,7 +39,6 @@ func GenerateCertificate(rootKey data.PrivateKey, gun string) (*x509.Certificate
return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err)
}
// Encode the new certificate into PEM
cert, err := x509.ParseCertificate(derBytes)
if err != nil {
return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err)

View File

@ -4,6 +4,7 @@ import (
"crypto/rand"
"crypto/x509"
"testing"
"time"
"github.com/docker/notary/trustmanager"
"github.com/stretchr/testify/assert"
@ -20,7 +21,8 @@ func TestGenerateCertificate(t *testing.T) {
// Check GenerateCertificate method
gun := "docker.com/notary"
cert, err := GenerateCertificate(privKey, gun)
startTime := time.Now()
cert, err := GenerateCertificate(privKey, gun, startTime, startTime.AddDate(10, 0, 0))
assert.NoError(t, err, "could not generate certificate")
// Check public key

View File

@ -471,12 +471,8 @@ func CertsToKeys(certs []*x509.Certificate) map[string]data.PublicKey {
return keys
}
// NewCertificate returns an X509 Certificate following a template, given a GUN.
func NewCertificate(gun string) (*x509.Certificate, error) {
notBefore := time.Now()
// Certificates will expire in 10 years
notAfter := notBefore.Add(time.Hour * 24 * 365 * 10)
// NewCertificate returns an X509 Certificate following a template, given a GUN and validity interval.
func NewCertificate(gun string, startTime, endTime time.Time) (*x509.Certificate, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
@ -489,8 +485,8 @@ func NewCertificate(gun string) (*x509.Certificate, error) {
Subject: pkix.Name{
CommonName: gun,
},
NotBefore: notBefore,
NotAfter: notAfter,
NotBefore: startTime,
NotAfter: endTime,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},

View File

@ -47,11 +47,13 @@ func TestCertsToKeys(t *testing.T) {
}
func TestNewCertificate(t *testing.T) {
cert, err := NewCertificate("docker.com/alpine")
startTime := time.Now()
endTime := startTime.AddDate(10, 0, 0)
cert, err := NewCertificate("docker.com/alpine", startTime, endTime)
assert.NoError(t, err)
assert.Equal(t, cert.Subject.CommonName, "docker.com/alpine")
assert.True(t, time.Now().Before(cert.NotAfter))
assert.True(t, time.Now().AddDate(10, 0, 1).After(cert.NotAfter))
assert.Equal(t, cert.NotBefore, startTime)
assert.Equal(t, cert.NotAfter, endTime)
}
func TestKeyOperations(t *testing.T) {
@ -177,7 +179,8 @@ func TestRSAX509PublickeyID(t *testing.T) {
// X509PublickeyID returns the public key ID of an ECDSA X509 key rather than
// the cert ID
func TestECDSAX509PublickeyID(t *testing.T) {
template, err := NewCertificate("something")
startTime := time.Now()
template, err := NewCertificate("something", startTime, startTime.AddDate(10, 0, 0))
assert.NoError(t, err)
template.SignatureAlgorithm = x509.ECDSAWithSHA256
template.PublicKeyAlgorithm = x509.ECDSA

View File

@ -14,6 +14,7 @@ import (
"io"
"math/big"
"os"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/notary/passphrase"
@ -217,7 +218,9 @@ func addECDSAKey(
ecdsaPrivKeyD := ensurePrivateKeySize(ecdsaPrivKey.D.Bytes())
template, err := trustmanager.NewCertificate(role)
// Hard-coded policy: the generated certificate expires in 10 years.
startTime := time.Now()
template, err := trustmanager.NewCertificate(role, startTime, startTime.AddDate(10, 0, 0))
if err != nil {
return fmt.Errorf("failed to create the certificate template: %v", err)
}

View File

@ -2,11 +2,11 @@ package signed
import (
"crypto/rand"
"crypto/x509"
"encoding/pem"
"io"
"testing"
"github.com/docker/notary/cryptoservice"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/tuf/data"
"github.com/stretchr/testify/assert"
@ -254,15 +254,7 @@ func TestSignWithX509(t *testing.T) {
assert.NoError(t, err)
// make a RSA x509 key
template, err := trustmanager.NewCertificate("test")
assert.NoError(t, err)
signer := privKey.CryptoSigner()
derBytes, err := x509.CreateCertificate(
rand.Reader, template, template, signer.Public(), signer)
assert.NoError(t, err)
cert, err := x509.ParseCertificate(derBytes)
cert, err := cryptoservice.GenerateTestingCertificate(privKey.CryptoSigner(), "test")
assert.NoError(t, err)
tufRSAx509Key := trustmanager.CertToKey(cert)

View File

@ -7,11 +7,11 @@ import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"io/ioutil"
"os"
"testing"
"github.com/docker/notary/cryptoservice"
"github.com/docker/notary/trustmanager"
"github.com/stretchr/testify/assert"
)
@ -33,15 +33,9 @@ func generateMultiCert(t *testing.T) string {
assert.NoError(t, err)
ecKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.NoError(t, err)
template, err := trustmanager.NewCertificate("gun")
assert.NoError(t, err)
for _, key := range []crypto.Signer{rsaKey, ecKey} {
derBytes, err := x509.CreateCertificate(
rand.Reader, template, template, key.Public(), key)
assert.NoError(t, err)
cert, err := x509.ParseCertificate(derBytes)
cert, err := cryptoservice.GenerateTestingCertificate(key, "gun")
assert.NoError(t, err)
pemBytes := trustmanager.CertToPEM(cert)