Skip to content

Commit

Permalink
Merge pull request #29 from square/cs/intermediate-ca
Browse files Browse the repository at this point in the history
Add ability to create intermediate CA cert
  • Loading branch information
csstaub committed May 25, 2016
2 parents d9a1fc8 + 308aeab commit 2147421
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
14 changes: 11 additions & 3 deletions cmd/sign.go
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func NewSignCommand() cli.Command {
cli.IntFlag{"years", 2, "How long until the certificate expires", ""},
cli.StringFlag{"CA", "", "CA to sign cert", ""},
cli.BoolFlag{"stdout", "Print certificate to stdout in addition to saving file", ""},
cli.BoolFlag{"intermediate", "Generated certificate should be a intermediate", ""},
},
Action: newSignAction,
}
Expand Down Expand Up @@ -89,7 +90,14 @@ func newSignAction(c *cli.Context) {
}
}

crtHost, err := pkix.CreateCertificateHost(crt, key, csr, c.Int("years"))
var crtOut *pkix.Certificate
if c.Bool("intermediate") {
fmt.Fprintf(os.Stderr, "Building intermediate")
crtOut, err = pkix.CreateIntermediateCertificateAuthority(crt, key, csr, c.Int("years"))
} else {
crtOut, err = pkix.CreateCertificateHost(crt, key, csr, c.Int("years"))
}

if err != nil {
fmt.Fprintln(os.Stderr, "Create certificate error:", err)
os.Exit(1)
Expand All @@ -98,7 +106,7 @@ func newSignAction(c *cli.Context) {
}

if c.Bool("stdout") {
crtBytes, err := crtHost.Export()
crtBytes, err := crtOut.Export()
if err != nil {
fmt.Fprintln(os.Stderr, "Print certificate error:", err)
os.Exit(1)
Expand All @@ -107,7 +115,7 @@ func newSignAction(c *cli.Context) {
}
}

if err = depot.PutCertificate(d, formattedReqName, crtHost); err != nil {
if err = depot.PutCertificate(d, formattedReqName, crtOut); err != nil {
fmt.Fprintln(os.Stderr, "Save certificate error:", err)
}
}
48 changes: 48 additions & 0 deletions pkix/cert_auth.go
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,51 @@ func CreateCertificateAuthority(key *Key, organizationalUnit string, years int,

return NewCertificateFromDER(crtBytes), nil
}

// CreateIntermediateCertificateAuthority creates an intermediate
// CA certificate signed by the given authority.
func CreateIntermediateCertificateAuthority(crtAuth *Certificate, keyAuth *Key, csr *CertificateSigningRequest, years int) (*Certificate, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, err
}
authTemplate.SerialNumber.Set(serialNumber)
authTemplate.MaxPathLenZero = false

rawCsr, err := csr.GetRawCertificateSigningRequest()
if err != nil {
return nil, err
}

authTemplate.RawSubject = rawCsr.RawSubject

caExpiry := time.Now().Add(crtAuth.GetExpirationDuration())
proposedExpiry := time.Now().AddDate(years, 0, 0).UTC()
// ensure cert doesn't expire after issuer
if caExpiry.Before(proposedExpiry) {
authTemplate.NotAfter = caExpiry
} else {
authTemplate.NotAfter = proposedExpiry
}

authTemplate.SubjectKeyId, err = GenerateSubjectKeyID(rawCsr.PublicKey)
if err != nil {
return nil, err
}

authTemplate.IPAddresses = rawCsr.IPAddresses
authTemplate.DNSNames = rawCsr.DNSNames

rawCrtAuth, err := crtAuth.GetRawCertificate()
if err != nil {
return nil, err
}

crtOutBytes, err := x509.CreateCertificate(rand.Reader, &authTemplate, rawCrtAuth, rawCsr.PublicKey, keyAuth.Private)
if err != nil {
return nil, err
}

return NewCertificateFromDER(crtOutBytes), nil
}
Empty file modified pkix/cert_host.go
100755 → 100644
Empty file.

0 comments on commit 2147421

Please sign in to comment.