Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.

Commit 2952229

Browse files
committed
Unify certificate validation
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
1 parent 3baf0e4 commit 2952229

File tree

8 files changed

+198
-47
lines changed

8 files changed

+198
-47
lines changed

trustpinning/ca.crt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
-----BEGIN CERTIFICATE-----
2+
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
35+
lKmXlK4dTg==
36+
-----END CERTIFICATE-----
37+

trustpinning/certs.go

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"errors"
66
"fmt"
77
"strings"
8-
"time"
98

109
"github.com/Sirupsen/logrus"
1110
"github.com/docker/notary/tuf/data"
@@ -157,7 +156,7 @@ func ValidateRoot(prevRoot *data.SignedRoot, root *data.Signed, gun string, trus
157156
// Note that certsFromRoot is guaranteed to be unchanged only if we had prior cert data for this GUN or enabled TOFUS
158157
// If we attempted to pin a certain certificate or CA, certsFromRoot could have been pruned accordingly
159158
err = signed.VerifySignatures(root, data.BaseRole{
160-
Keys: trustmanager.CertsToKeys(certsFromRoot, validIntCerts), Threshold: rootRole.Threshold})
159+
Keys: utils.CertsToKeys(certsFromRoot, validIntCerts), Threshold: rootRole.Threshold})
161160
if err != nil {
162161
logrus.Debugf("failed to verify TUF data for: %s, %v", gun, err)
163162
return nil, &ErrValidationFail{Reason: "failed to validate integrity of roots"}
@@ -183,12 +182,7 @@ func validRootLeafCerts(allLeafCerts map[string]*x509.Certificate, gun string, c
183182
}
184183
// Make sure the certificate is not expired if checkExpiry is true
185184
// and warn if it hasn't expired yet but is within 6 months of expiry
186-
if checkExpiry {
187-
if err := checkCertExpiry(cert); err != nil {
188-
continue
189-
}
190-
}
191-
if err := checkCertSigAlgorithm(cert); err != nil {
185+
if err := utils.ValidateCertificate(cert, checkExpiry); err != nil {
192186
continue
193187
}
194188

@@ -213,10 +207,7 @@ func validRootIntCerts(allIntCerts map[string][]*x509.Certificate) map[string][]
213207
// Go through every leaf cert ID, and build its valid intermediate certificate list
214208
for leafID, intCertList := range allIntCerts {
215209
for _, intCert := range intCertList {
216-
if err := checkCertExpiry(intCert); err != nil {
217-
continue
218-
}
219-
if err := checkCertSigAlgorithm(intCert); err != nil {
210+
if err := utils.ValidateCertificate(intCert, true); err != nil {
220211
continue
221212
}
222213
validIntCerts[leafID] = append(validIntCerts[leafID], intCert)
@@ -288,24 +279,3 @@ func parseAllCerts(signedRoot *data.SignedRoot) (map[string]*x509.Certificate, m
288279

289280
return leafCerts, intCerts
290281
}
291-
292-
func checkCertExpiry(cert *x509.Certificate) error {
293-
if time.Now().After(cert.NotAfter) {
294-
logrus.Debugf("certificate with CN %s is expired", cert.Subject.CommonName)
295-
return fmt.Errorf("certificate expired: %s", cert.Subject.CommonName)
296-
} else if cert.NotAfter.Before(time.Now().AddDate(0, 6, 0)) {
297-
logrus.Warnf("certificate with CN %s is near expiry", cert.Subject.CommonName)
298-
}
299-
return nil
300-
}
301-
302-
func checkCertSigAlgorithm(cert *x509.Certificate) error {
303-
// We don't allow root certificates that use SHA1
304-
if cert.SignatureAlgorithm == x509.SHA1WithRSA ||
305-
cert.SignatureAlgorithm == x509.DSAWithSHA1 ||
306-
cert.SignatureAlgorithm == x509.ECDSAWithSHA1 {
307-
logrus.Debugf("error certificate uses deprecated hashing algorithm (SHA1)")
308-
return fmt.Errorf("invalid signature algorithm for certificate with CN %s", cert.Subject.CommonName)
309-
}
310-
return nil
311-
}

trustpinning/certs_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ func TestCheckingCertExpiry(t *testing.T) {
817817

818818
almostExpiredCert, err := generateTestingCertificate(testPrivKey, gun, notary.Day*30)
819819
require.NoError(t, err)
820-
almostExpiredPubKey, err := trustmanager.ParsePEMPublicKey(trustmanager.CertToPEM(almostExpiredCert))
820+
almostExpiredPubKey, err := utils.ParsePEMPublicKey(utils.CertToPEM(almostExpiredCert))
821821
require.NoError(t, err)
822822

823823
// set up a logrus logger to capture warning output
@@ -854,7 +854,7 @@ func TestCheckingCertExpiry(t *testing.T) {
854854

855855
expiredCert, err := generateExpiredTestingCertificate(testPrivKey, gun)
856856
require.NoError(t, err)
857-
expiredPubKey := trustmanager.CertToKey(expiredCert)
857+
expiredPubKey := utils.CertToKey(expiredCert)
858858

859859
rootRole, err = data.NewRole(data.CanonicalRootRole, 1, []string{expiredPubKey.ID()}, nil)
860860
require.NoError(t, err)

trustpinning/test.crt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIFKzCCAxWgAwIBAgIQRyp9QqcJfd3ayqdjiz8xIDALBgkqhkiG9w0BAQswODEa
3+
MBgGA1UEChMRZG9ja2VyLmNvbS9ub3RhcnkxGjAYBgNVBAMTEWRvY2tlci5jb20v
4+
bm90YXJ5MB4XDTE1MDcxNzA2MzQyM1oXDTE3MDcxNjA2MzQyM1owODEaMBgGA1UE
5+
ChMRZG9ja2VyLmNvbS9ub3RhcnkxGjAYBgNVBAMTEWRvY2tlci5jb20vbm90YXJ5
6+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoQffrzsYnsH8vGf4Jh55
7+
Cj5wrjUGzD/sHkaFHptjJ6ToJGJv5yMAPxzyInu5sIoGLJapnYVBoAU0YgI9qlAc
8+
YA6SxaSwgm6rpvmnl8Qn0qc6ger3inpGaUJylWHuPwWkvcimQAqHZx2dQtL7g6kp
9+
rmKeTWpWoWLw3JoAUZUVhZMd6a22ZL/DvAw+Hrogbz4XeyahFb9IH402zPxN6vga
10+
JEFTF0Ji1jtNg0Mo4pb9SHsMsiw+LZK7SffHVKPxvd21m/biNmwsgExA3U8OOG8p
11+
uygfacys5c8+ZrX+ZFG/cvwKz0k6/QfJU40s6MhXw5C2WttdVmsG9/7rGFYjHoIJ
12+
weDyxgWk7vxKzRJI/un7cagDIaQsKrJQcCHIGFRlpIR5TwX7vl3R7cRncrDRMVvc
13+
VSEG2esxbw7jtzIp/ypnVRxcOny7IypyjKqVeqZ6HgxZtTBVrF1O/aHo2kvlwyRS
14+
Aus4kvh6z3+jzTm9EzfXiPQzY9BEk5gOLxhW9rc6UhlS+pe5lkaN/Hyqy/lPuq89
15+
fMr2rr7lf5WFdFnze6WNYMAaW7dNA4NE0dyD53428ZLXxNVPL4WU66Gac6lynQ8l
16+
r5tPsYIFXzh6FVaRKGQUtW1hz9ecO6Y27Rh2JsyiIxgUqk2ooxE69uN42t+dtqKC
17+
1s8G/7VtY8GDALFLYTnzLvsCAwEAAaM1MDMwDgYDVR0PAQH/BAQDAgCgMBMGA1Ud
18+
JQQMMAoGCCsGAQUFBwMDMAwGA1UdEwEB/wQCMAAwCwYJKoZIhvcNAQELA4ICAQBM
19+
Oll3G/XBz8idiNdNJDWUh+5w3ojmwanrTBdCdqEk1WenaR6DtcflJx6Z3f/mwV4o
20+
b1skOAX1yX5RCahJHUMxMicz/Q38pOVelGPrWnc3TJB+VKjGyHXlQDVkZFb+4+ef
21+
wtj7HngXhHFFDSgjm3EdMndvgDQ7SQb4skOnCNS9iyX7eXxhFBCZmZL+HALKBj2B
22+
yhV4IcBDqmp504t14rx9/Jvty0dG7fY7I51gEQpm4S02JML5xvTm1xfboWIhZODI
23+
swEAO+ekBoFHbS1Q9KMPjIAw3TrCHH8x8XZq5zsYtAC1yZHdCKa26aWdy56A9eHj
24+
O1VxzwmbNyXRenVuBYP+0wr3HVKFG4JJ4ZZpNZzQW/pqEPghCTJIvIueK652ByUc
25+
//sv+nXd5f19LeES9pf0l253NDaFZPb6aegKfquWh8qlQBmUQ2GzaTLbtmNd28M6
26+
W7iL7tkKZe1ZnBz9RKgtPrDjjWGZInjjcOU8EtT4SLq7kCVDmPs5MD8vaAm96JsE
27+
jmLC3Uu/4k7HiDYX0i0mOWkFjZQMdVatcIF5FPSppwsSbW8QidnXt54UtwtFDEPz
28+
lpjs7ybeQE71JXcMZnVIK4bjRXsEFPI98RpIlEdedbSUdYAncLNJRT7HZBMPGSwZ
29+
0PNJuglnlr3srVzdW1dz2xQjdvLwxy6mNUF6rbQBWA==
30+
-----END CERTIFICATE-----
31+

trustpinning/trustpin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func NewTrustPinChecker(trustPinConfig TrustPinConfig, gun string) (CertChecker,
4848
// Now only consider certificates that are direct children from this CA cert chain
4949
caRootPool := x509.NewCertPool()
5050
for _, caCert := range caCerts {
51-
if err = utils.ValidateCertificate(caCert); err != nil {
51+
if err = utils.ValidateCertificate(caCert, true); err != nil {
5252
logrus.Debugf("ignoring root CA certificate with CN %s in bundle: %s", caCert.Subject.CommonName, err)
5353
continue
5454
}

tuf/tuf.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,17 @@ func (tr *Repo) GetDelegationRole(name string) (data.DelegationRole, error) {
245245
if err != nil {
246246
return err
247247
}
248+
// Check all public key certificates in the role for expiry
249+
// Currently we do not reject expired delegation keys but warn if they might expire soon or have already
250+
for keyID, pubKey := range delgRole.Keys {
251+
certFromKey, err := utils.LoadCertFromPEM(pubKey.Public())
252+
if err != nil {
253+
continue
254+
}
255+
if err := utils.ValidateCertificate(certFromKey, true); err != nil {
256+
logrus.Warnf("error with delegation %s key ID %d: %s", delgRole.Name, keyID, err)
257+
}
258+
}
248259
foundRole = &delgRole
249260
return StopWalk{}
250261
}

tuf/utils/x509.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func ParsePEMPublicKey(pubKeyBytes []byte) (data.PublicKey, error) {
247247
if err != nil {
248248
return nil, fmt.Errorf("could not parse provided certificate: %v", err)
249249
}
250-
err = ValidateCertificate(cert)
250+
err = ValidateCertificate(cert, true)
251251
if err != nil {
252252
return nil, fmt.Errorf("invalid certificate: %v", err)
253253
}
@@ -258,20 +258,27 @@ func ParsePEMPublicKey(pubKeyBytes []byte) (data.PublicKey, error) {
258258
}
259259

260260
// ValidateCertificate returns an error if the certificate is not valid for notary
261-
// Currently this is only a time expiry check, and ensuring the public key has a large enough modulus if RSA
262-
func ValidateCertificate(c *x509.Certificate) error {
261+
// Currently this is only ensuring the public key has a large enough modulus if RSA,
262+
// using a non SHA1 signature algorithm, and an optional time expiry check
263+
func ValidateCertificate(c *x509.Certificate, checkExpiry bool) error {
263264
if (c.NotBefore).After(c.NotAfter) {
264265
return fmt.Errorf("certificate validity window is invalid")
265266
}
266-
now := time.Now()
267-
tomorrow := now.AddDate(0, 0, 1)
268-
// Give one day leeway on creation "before" time, check "after" against today
269-
if (tomorrow).Before(c.NotBefore) || now.After(c.NotAfter) {
270-
return fmt.Errorf("certificate with CN %s is expired", c.Subject.CommonName)
267+
if checkExpiry {
268+
now := time.Now()
269+
tomorrow := now.AddDate(0, 0, 1)
270+
// Give one day leeway on creation "before" time, check "after" against today
271+
if (tomorrow).Before(c.NotBefore) || now.After(c.NotAfter) {
272+
return fmt.Errorf("certificate with CN %s is expired", c.Subject.CommonName)
273+
}
274+
// If this certificate is expiring within 6 months, put out a warning
275+
if (c.NotAfter).Before(time.Now().AddDate(0, 6, 0)) {
276+
logrus.Warnf("certificate with CN %s is near expiry", c.Subject.CommonName)
277+
}
271278
}
272-
// If this certificate is expiring within 6 months, put out a warning
273-
if (c.NotAfter).Before(time.Now().AddDate(0, 6, 0)) {
274-
logrus.Warn("certificate with CN %s is near expiry", c.Subject.CommonName)
279+
// Can't have SHA1 sig algorithm
280+
if c.SignatureAlgorithm == x509.SHA1WithRSA || c.SignatureAlgorithm == x509.DSAWithSHA1 || c.SignatureAlgorithm == x509.ECDSAWithSHA1 {
281+
return fmt.Errorf("certificate with CN %s uses invalid SHA1 signature algorithm", c.Subject.CommonName)
275282
}
276283
// If we have an RSA key, make sure it's long enough
277284
if c.PublicKeyAlgorithm == x509.RSA {

tuf/utils/x509_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/ecdsa"
55
"crypto/elliptic"
66
"crypto/rand"
7+
"crypto/rsa"
78
"crypto/x509"
89
"io/ioutil"
910
"strings"
@@ -220,3 +221,97 @@ func TestECDSAX509PublickeyID(t *testing.T) {
220221

221222
require.Equal(t, tufPrivKey.ID(), tufID)
222223
}
224+
225+
func TestValidateCertificateWithSHA1(t *testing.T) {
226+
// Test against SHA1 signature algorithm cert first
227+
startTime := time.Now()
228+
template, err := NewCertificate("something", startTime, startTime.AddDate(10, 0, 0))
229+
require.NoError(t, err)
230+
// SHA1 signature algorithm is invalid
231+
template.SignatureAlgorithm = x509.ECDSAWithSHA1
232+
template.PublicKeyAlgorithm = x509.ECDSA
233+
234+
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
235+
require.NoError(t, err)
236+
237+
derBytes, err := x509.CreateCertificate(
238+
rand.Reader, template, template, &privKey.PublicKey, privKey)
239+
require.NoError(t, err)
240+
241+
sha1Cert, err := x509.ParseCertificate(derBytes)
242+
require.NoError(t, err)
243+
244+
// Regardless of expiry check, this certificate should fail to validate
245+
require.Error(t, ValidateCertificate(sha1Cert, false))
246+
require.Error(t, ValidateCertificate(sha1Cert, true))
247+
}
248+
249+
func TestValidateCertificateWithExpiredCert(t *testing.T) {
250+
// Test against an expired cert for 10 years ago, only valid for a day
251+
startTime := time.Now().AddDate(-10, 0, 0)
252+
template, err := NewCertificate("something", startTime, startTime.AddDate(0, 0, 1))
253+
require.NoError(t, err)
254+
template.SignatureAlgorithm = x509.ECDSAWithSHA256
255+
template.PublicKeyAlgorithm = x509.ECDSA
256+
257+
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
258+
require.NoError(t, err)
259+
260+
derBytes, err := x509.CreateCertificate(
261+
rand.Reader, template, template, &privKey.PublicKey, privKey)
262+
require.NoError(t, err)
263+
264+
expiredCert, err := x509.ParseCertificate(derBytes)
265+
require.NoError(t, err)
266+
267+
// If we don't check expiry, this cert is perfectly valid
268+
require.NoError(t, ValidateCertificate(expiredCert, false))
269+
// We should get an error when we check expiry
270+
require.Error(t, ValidateCertificate(expiredCert, true))
271+
}
272+
273+
func TestValidateCertificateWithInvalidExpiry(t *testing.T) {
274+
// Test against a cert with an invalid expiry window: from 10 years in the future to 10 years ago
275+
startTime := time.Now().AddDate(10, 0, 0)
276+
template, err := NewCertificate("something", startTime, startTime.AddDate(-10, 0, 0))
277+
require.NoError(t, err)
278+
template.SignatureAlgorithm = x509.ECDSAWithSHA256
279+
template.PublicKeyAlgorithm = x509.ECDSA
280+
281+
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
282+
require.NoError(t, err)
283+
284+
derBytes, err := x509.CreateCertificate(
285+
rand.Reader, template, template, &privKey.PublicKey, privKey)
286+
require.NoError(t, err)
287+
288+
invalidCert, err := x509.ParseCertificate(derBytes)
289+
require.NoError(t, err)
290+
291+
// Regardless of expiry check, this certificate should fail to validate
292+
require.Error(t, ValidateCertificate(invalidCert, false))
293+
require.Error(t, ValidateCertificate(invalidCert, true))
294+
}
295+
296+
func TestValidateCertificateWithShortKey(t *testing.T) {
297+
startTime := time.Now()
298+
template, err := NewCertificate("something", startTime, startTime.AddDate(10, 0, 0))
299+
require.NoError(t, err)
300+
template.SignatureAlgorithm = x509.SHA256WithRSA
301+
template.PublicKeyAlgorithm = x509.RSA
302+
303+
// Use only 1024 bit modulus, this will fail
304+
weakPrivKey, err := rsa.GenerateKey(rand.Reader, 1024)
305+
require.NoError(t, err)
306+
307+
derBytes, err := x509.CreateCertificate(
308+
rand.Reader, template, template, &weakPrivKey.PublicKey, weakPrivKey)
309+
require.NoError(t, err)
310+
311+
weakKeyCert, err := x509.ParseCertificate(derBytes)
312+
require.NoError(t, err)
313+
314+
// Regardless of expiry check, this certificate should fail to validate
315+
require.Error(t, ValidateCertificate(weakKeyCert, false))
316+
require.Error(t, ValidateCertificate(weakKeyCert, true))
317+
}

0 commit comments

Comments
 (0)