aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAJ Christensen <aj@junglistheavy.industries>2016-10-26 12:00:08 +1300
committerAJ Christensen <aj@junglistheavy.industries>2016-10-26 14:18:48 +1300
commitea1891668a36322802b2c8b34bbe85b25d989f74 (patch)
tree9254b37e8decf0abff62ee93c238e7413a539ef0
parentbc210282ea3e468b9bf79878092d1b6479343c62 (diff)
downloadeasypki-ea1891668a36322802b2c8b34bbe85b25d989f74.tar.xz
[easyca] handle CAs, Intermediates, and Client
* Split certificate type handling up, try to re-use operations where possible. * Set the EKUs for client/serverauth on clients, servers, and Intermediate CAs
-rw-r--r--pkg/easypki/easyca.go57
1 files changed, 34 insertions, 23 deletions
diff --git a/pkg/easypki/easyca.go b/pkg/easypki/easyca.go
index 17d0192..dbb6f0e 100644
--- a/pkg/easypki/easyca.go
+++ b/pkg/easypki/easyca.go
@@ -113,48 +113,47 @@ func GenerateCertificate(genReq *GenerationRequest) error {
genReq.Template.NotBefore = time.Now()
genReq.Template.SignatureAlgorithm = x509.SHA256WithRSA
- if genReq.Template.IsCA {
+ // Non-intermediate Certificate Authority
+ if genReq.Template.IsCA && !genReq.IsIntermediateCA {
+ // Random Serial
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return fmt.Errorf("failed to generate ca serial number: %s", err)
}
genReq.Template.SerialNumber = serialNumber
- genReq.Template.KeyUsage = x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign
- genReq.Template.BasicConstraintsValid = true
+
+ // Root certificate can self-sign
genReq.Template.Issuer = genReq.Template.Subject
genReq.Template.AuthorityKeyId = genReq.Template.SubjectKeyId
- // if the maximum path length was provided be sure to enforce it
- if genReq.MaxPathLen >= 0 {
- genReq.Template.MaxPathLen = genReq.MaxPathLen
- genReq.Template.MaxPathLenZero = true // doesn't force to zero
- }
+ // Use the generated certificate template and private key (self-signing)
+ caCrt = genReq.Template
+ caKey = privateKey
+ }
+ // Intermediate-only Certificate Authority
+ if genReq.Template.IsCA && genReq.IsIntermediateCA {
genReq.Template.ExtKeyUsage = []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageServerAuth,
}
-
- caCrt = genReq.Template
- caKey = privateKey
}
- // if this is not a CA certificate...
- // or if this is an intermediate certificate...
- // we want to sign it with our parent CA's key
- if !genReq.Template.IsCA || genReq.IsIntermediateCA {
- if !genReq.IsIntermediateCA {
- // set the usage for non-CA certificates
- genReq.Template.KeyUsage = x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
- genReq.Template.ExtKeyUsage = append(genReq.Template.ExtKeyUsage, x509.ExtKeyUsageClientAuth)
+ // Either type of Certificate Authority (intermediate, root, etc.)
+ if genReq.Template.IsCA || genReq.IsIntermediateCA {
+ genReq.Template.KeyUsage = x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign
+ genReq.Template.BasicConstraintsValid = true
- // set UsageServerAuth only if this isn't a client cert
- if !genReq.IsClientCertificate {
- genReq.Template.ExtKeyUsage = append(genReq.Template.ExtKeyUsage, x509.ExtKeyUsageServerAuth)
- }
+ // Enforce Maximum Path Length
+ if genReq.MaxPathLen >= 0 {
+ genReq.Template.MaxPathLen = genReq.MaxPathLen
+ genReq.Template.MaxPathLenZero = true // doesn't force to zero
}
+ }
+ // Any leaf: intermediate CAs, client/server certificates, signed by a root
+ if !genReq.Template.IsCA || genReq.IsIntermediateCA {
serialNumber, err := NextNumber(genReq.PKIRoot, "serial")
if err != nil {
return fmt.Errorf("get next serial: %v", err)
@@ -167,6 +166,18 @@ func GenerateCertificate(genReq *GenerationRequest) error {
}
}
+ // Should cover only client/server (All non-CA, i.e. doesn't include intermediates)
+ if !genReq.Template.IsCA {
+ if !genReq.IsClientCertificate {
+ genReq.Template.ExtKeyUsage = append(genReq.Template.ExtKeyUsage, x509.ExtKeyUsageServerAuth)
+ }
+ // Clients can only use ClientAuth
+ genReq.Template.ExtKeyUsage = append(genReq.Template.ExtKeyUsage, x509.ExtKeyUsageClientAuth)
+
+ // set the usage for non-CA certificates
+ genReq.Template.KeyUsage = x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
+ }
+
crt, err := x509.CreateCertificate(rand.Reader, genReq.Template, caCrt, privateKey.Public(), caKey)
if err != nil {
return fmt.Errorf("create certificate: %v", err)