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. // Needed by all subcommands.
var Output string var Name string
var OutDir string
// Needed by some subcommands.
var KeyFile string
func init() { func init() {
rootCmd.AddCommand(generateCmd) rootCmd.AddCommand(generateCmd)
// All "generate" commands output an artifact to a file, // Name for artifacts being written to file(s).
// be it a key or a cert, etc.
generateCmd.PersistentFlags().StringVarP( generateCmd.PersistentFlags().StringVarP(
&Output, &Name,
"output", "name",
"o", "n",
"", "",
"output filename", "name of the artifact being benerated",
) )
generateCmd.MarkPersistentFlagRequired("output") generateCmd.MarkPersistentFlagRequired("name")
generateCmd.MarkPersistentFlagFilename("output")
// 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{ var generateCmd = &cobra.Command{
Use: "generate", 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 package hmpki
import ( import (
"crypto/ecdsa"
"crypto/rand" "crypto/rand"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
@@ -9,7 +8,7 @@ import (
"errors" "errors"
"math" "math"
"math/big" "math/big"
"os" "path"
"time" "time"
"git.handmadecities.com/HMC/shhh/pkg/pki" "git.handmadecities.com/HMC/shhh/pkg/pki"
@@ -18,41 +17,19 @@ import (
func init() { func init() {
generateCmd.AddCommand(generateCACmd) 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{ var generateCACmd = &cobra.Command{
Use: "ca", Use: "ca",
Short: "Generate a Certificate Authority", Short: "Generate a Certificate Authority",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
// Read key from KeyFile. // Private key for the ca.
keyPemBytes, err := os.ReadFile(KeyFile) key := pki.GenerateKey()
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")
}
// Cryptographically random 64bit number as the serial. // Cryptographically random 64bit number as the serial.
sn, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)) sn, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
if err != nil { 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{ caTmpl := &x509.Certificate{
SerialNumber: sn, SerialNumber: sn,
@@ -87,17 +64,16 @@ var generateCACmd = &cobra.Command{
Bytes: caBytes, Bytes: caBytes,
}) })
caf, err := os.OpenFile( // Write ca to disk.
Output, cafn := path.Join(OutDir, Name+"_ca.crt")
// Write only, and fail if it alreay exists. err = createFileWith(cafn, caPEMBytes, pki.CertFilePerms)
os.O_WRONLY|os.O_CREATE|os.O_EXCL,
pki.CertFilePerms,
)
if err != nil { if err != nil {
return err return err
} }
defer caf.Close() // Write private key to disk.
if _, err = caf.Write(caPEMBytes); err != nil { keyfn := path.Join(OutDir, Name+"_ca.key")
err = createFileWith(keyfn, pki.MarshalKeyToPEM(key), pki.PrivateKeyFilePerms)
if err != nil {
return err return err
} }