refactor: generate ca now generates and writes its own private key.

This commit is contained in:
jmug committed 2026-10-22 16:30:01 -07:00
1 parent 16474e57b9
commit 657208a7c2
2 files changed
+30 -48

No files matched your search

+19 -13
View File
@@ -5,28 +5,34 @@ import (
)
// Needed by all subcommands.
var Output string
// Needed by some subcommands.
var KeyFile string
var Name string
var OutDir string
func init() {
rootCmd.AddCommand(generateCmd)
// All "generate" commands output an artifact to a file,
// be it a key or a cert, etc.
// Name for artifacts being written to file(s).
generateCmd.PersistentFlags().StringVarP(
&Output,
"output",
"o",
&Name,
"name",
"n",
"",
"output filename",
"name of the artifact being benerated",
)
generateCmd.MarkPersistentFlagRequired("output")
generateCmd.MarkPersistentFlagFilename("output")
generateCmd.MarkPersistentFlagRequired("name")
// Output direcotry.
generateCmd.PersistentFlags().StringVar(
&OutDir,
"output-dir",
".",
"output directory for artifacts produced by this command, defaults to the current directory",
)
generateCmd.MarkPersistentFlagRequired("output-dir")
generateCmd.MarkPersistentFlagDirname("output-dir")
}
var generateCmd = &cobra.Command{
Use: "generate",
Short: "Generate pki resources (keys/certs)",
Short: "Generate pki resources (cas/keys/certs)",
}
+11 -35
View File
@@ -1,7 +1,6 @@
package hmpki
import (
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
@@ -9,7 +8,7 @@ import (
"errors"
"math"
"math/big"
"os"
"path"
"time"
"git.handmadecities.com/HMC/shhh/pkg/pki"
@@ -18,41 +17,19 @@ import (
func init() {
generateCmd.AddCommand(generateCACmd)
generateCACmd.Flags().StringVar(
&KeyFile,
"key-file",
"",
"File that contains the private key that will be associated to the CA",
)
generateCACmd.MarkFlagRequired("key-file")
generateCACmd.MarkFlagFilename("key-file")
}
var generateCACmd = &cobra.Command{
Use: "ca",
Short: "Generate a Certificate Authority",
RunE: func(cmd *cobra.Command, args []string) error {
// Read key from KeyFile.
keyPemBytes, err := os.ReadFile(KeyFile)
if err != nil {
return err
}
privBlock, _ := pem.Decode(keyPemBytes)
if privBlock == nil || privBlock.Type != pki.PEMTypePrivateKey {
return errors.New("Invalid pem key file, or first block is not a private key")
}
rawKey, err := x509.ParsePKCS8PrivateKey(privBlock.Bytes)
key, ok := rawKey.(*ecdsa.PrivateKey)
if !ok {
return errors.New("key file did not contain an ecdsa private key")
}
// Private key for the ca.
key := pki.GenerateKey()
// Cryptographically random 64bit number as the serial.
sn, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
errors.New("Could not generate a ca serial number")
return errors.New("Could not generate a ca serial number")
}
caTmpl := &x509.Certificate{
SerialNumber: sn,
@@ -87,17 +64,16 @@ var generateCACmd = &cobra.Command{
Bytes: caBytes,
})
caf, err := os.OpenFile(
Output,
// Write only, and fail if it alreay exists.
os.O_WRONLY|os.O_CREATE|os.O_EXCL,
pki.CertFilePerms,
)
// Write ca to disk.
cafn := path.Join(OutDir, Name+"_ca.crt")
err = createFileWith(cafn, caPEMBytes, pki.CertFilePerms)
if err != nil {
return err
}
defer caf.Close()
if _, err = caf.Write(caPEMBytes); err != nil {
// Write private key to disk.
keyfn := path.Join(OutDir, Name+"_ca.key")
err = createFileWith(keyfn, pki.MarshalKeyToPEM(key), pki.PrivateKeyFilePerms)
if err != nil {
return err
}