From df86078ee04abbcffeab93d96b0415aa244b1fdf Mon Sep 17 00:00:00 2001 From: raul Date: Thu, 23 May 2024 08:50:38 +0200 Subject: [PATCH] Separate CA and client certificate generation --- cmd/generate-ca.go | 38 ++++++++++++++++++++ cmd/generate.go | 2 +- cmd/generateFunc.go | 84 ++++++++++++++++++++++++++++++++------------- 3 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 cmd/generate-ca.go diff --git a/cmd/generate-ca.go b/cmd/generate-ca.go new file mode 100644 index 0000000..aa235a4 --- /dev/null +++ b/cmd/generate-ca.go @@ -0,0 +1,38 @@ +/* +Copyright © 2024 raul +*/ + +package cmd + +import ( + "github.com/spf13/cobra" +) + +// generateCmd represents the generate command +var generatecaCmd = &cobra.Command{ + Use: "generate-ca", + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + Run: func(cmd *cobra.Command, args []string) { + generateCA() + }, +} + +func init() { + rootCmd.AddCommand(generatecaCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // generateCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // generateCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/cmd/generate.go b/cmd/generate.go index 980ee0a..c64f406 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -19,7 +19,7 @@ Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.`, Run: func(cmd *cobra.Command, args []string) { - generateCA() + generateCert() }, } diff --git a/cmd/generateFunc.go b/cmd/generateFunc.go index 535a642..492feef 100644 --- a/cmd/generateFunc.go +++ b/cmd/generateFunc.go @@ -12,7 +12,6 @@ import ( "crypto/x509/pkix" "encoding/pem" "fmt" - "io" "log" "math/big" "os" @@ -134,7 +133,8 @@ func generateCA() { func generateCert() { home, err := os.UserHomeDir() if err != nil { - log.Fatalf("Error happened looking up user home directory: %v\n", err) + log.Printf("Error happened looking up user home directory: %v\n", err) + return } cert := &x509.Certificate{ SerialNumber: big.NewInt(1658), @@ -156,40 +156,57 @@ func generateCert() { certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096) if err != nil { - log.Print(err) + log.Printf("Error happened generating client privkey: %v\n", err) + return } ////////////////////// Fetching CA data ////////////////////// - caPath, err := os.Open(home + "/.config/cert400/ca.crt") - if err != nil { - log.Print(err) - } - defer caPath.Close() - caPrivPath, err := os.Open(home + "/.config/cert400/ca.key") - if err != nil { - log.Print(err) - } - defer caPrivPath.Close() + // caPath, err := os.Open(home + "/.config/cert400/ca.crt") + // if err != nil { + // log.Printf("Error happened opening CA certificate: %v\n", err) + // return + // } + // defer caPath.Close() + // caPrivPath, err := os.Open(home + "/.config/cert400/ca.key") + // if err != nil { + // log.Printf("Error happened opening CA privkey: %v\n", err) + // return + // } + // defer caPrivPath.Close() ////////////////////////////////////////////////////////////// - caFile, err := io.ReadAll(caPath) + // Parse private CA certificate ///////////////////////////// + caFile, err := os.ReadFile(home + "/.config/cert400/ca.crt") if err != nil { - log.Print(err) + log.Printf("Error happened reading from CA certificate: %v\n", err) + return } - caCert, err := x509.ParseCertificate(caFile) + caPubBlock, _ := pem.Decode(caFile) + caCert, err := x509.ParseCertificate(caPubBlock.Bytes) if err != nil { - log.Print(err) + log.Printf("Error happened parsing CA certificate: %v\n", err) + return + } + ///////////////////////////////////////////////////////////// + + // Parse public CA certificate ///////////////////////////// + caPrivFile, err := os.ReadFile(home + "/.config/cert400/ca.key") + if err != nil { + log.Printf("Error happened reading from CA privkey: %v\n", err) + return + } + caPrivBlock, _ := pem.Decode(caPrivFile) + caPrivKey, err := x509.ParsePKCS1PrivateKey(caPrivBlock.Bytes) + if err != nil { + log.Printf("Error happened parsing CA privkey: %v\n", err) + return } - caPrivFile, err := io.ReadAll(caPrivPath) - if err != nil { - log.Print(err) - } - caPrivKey, err := x509.ParseCertificate(caPrivFile) - + // Generate signed client certificate certBytes, err := x509.CreateCertificate(rand.Reader, cert, caCert, &certPrivKey.PublicKey, caPrivKey) if err != nil { - log.Print(err) + log.Printf("Error happened signing certificate: %v\n", err) + return } certPEM := new(bytes.Buffer) @@ -203,4 +220,23 @@ func generateCert() { Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey), }) + fmt.Printf("Generating %v/.config/cert400/client.key...\n", home) + clientkey, err := os.OpenFile(home+"/.config/cert400/client.key", os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + log.Printf("Error happened opening file: %v\n", err) + return + } + defer clientkey.Close() + + fmt.Printf("Generating %v/.config/cert400/client.cert...\n", home) + clientcert, err := os.OpenFile(home+"/.config/cert400/client.crt", os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + log.Printf("Error happened opening file: %v\n", err) + return + } + defer clientcert.Close() + + clientkey.WriteString(string(certPrivKeyPEM.Bytes())) + clientcert.WriteString(string(certPEM.Bytes())) + }