refactor: generate ca now generates and writes its own private key.
This commit is contained in:
1 parent
16474e57b9
commit
657208a7c2
2 files changed
+30
-48
No files matched your search
@@ -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)",
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user