aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Heckman <t@heckman.io>2016-10-25 18:20:05 -0700
committerTim Heckman <t@heckman.io>2016-10-25 18:24:24 -0700
commit9269e3056eb5a66b128df22cec2296f0ccb9547d (patch)
tree9254b37e8decf0abff62ee93c238e7413a539ef0
parentbc210282ea3e468b9bf79878092d1b6479343c62 (diff)
parentea1891668a36322802b2c8b34bbe85b25d989f74 (diff)
downloadeasypki-9269e3056eb5a66b128df22cec2296f0ccb9547d.tar.xz
Merge pull request #2 from fujin/supereasypki
[easyca] handle CAs, Intermediates, and Client
-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)