...
1 package signer
2
3 import (
4 "crypto"
5 "crypto/rand"
6 "crypto/x509"
7 "fmt"
8 "time"
9 )
10
11
12
13 type CertificateAuthority struct {
14
15 RawCert []byte
16
17 RawKey []byte
18
19 Certificate *x509.Certificate
20 PrivateKey crypto.Signer
21 Backdate time.Duration
22 Now func() time.Time
23 }
24
25
26
27 func (ca *CertificateAuthority) Sign(certTemplate *x509.Certificate, policy SigningPolicy) ([]byte, error) {
28 now := time.Now()
29 if ca.Now != nil {
30 now = ca.Now()
31 }
32
33 nbf := now.Add(-ca.Backdate)
34 if !nbf.Before(ca.Certificate.NotAfter) {
35 return nil, fmt.Errorf("the signer has expired: NotAfter=%v", ca.Certificate.NotAfter)
36 }
37
38 if err := policy.apply(certTemplate); err != nil {
39 return nil, err
40 }
41
42 if !certTemplate.NotAfter.Before(ca.Certificate.NotAfter) {
43 certTemplate.NotAfter = ca.Certificate.NotAfter
44 }
45 if !now.Before(ca.Certificate.NotAfter) {
46 return nil, fmt.Errorf("refusing to sign a certificate that expired in the past")
47 }
48
49 der, err := x509.CreateCertificate(rand.Reader, certTemplate, ca.Certificate, certTemplate.PublicKey, ca.PrivateKey)
50 if err != nil {
51 return nil, fmt.Errorf("failed to sign certificate: %v", err)
52 }
53
54 return der, nil
55 }
56
View as plain text