package hmpki import ( "crypto/rand" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "path" "time" "git.handmadecities.com/HMC/shhh/pkg/pki" "github.com/spf13/cobra" ) func init() { generateCmd.AddCommand(generateClientCertCmd) generateClientCertCmd.Flags().StringVar( &CAFile, "ca", "", "File for the CA that will sign the leaf", ) generateClientCertCmd.MarkFlagRequired("ca") generateClientCertCmd.MarkFlagFilename("ca") generateClientCertCmd.Flags().StringVar( &CAKeyFile, "ca-key", "", "File for the CA private key that will sign the leaf", ) generateClientCertCmd.MarkFlagRequired("ca-key") generateClientCertCmd.MarkFlagFilename("ca-key") generateClientCertCmd.Flags().StringVar( &CommonName, "common-name", "", "Common Name for the CA", ) generateClientCertCmd.MarkFlagRequired("common-name") } var generateClientCertCmd = &cobra.Command{ Use: "client-cert", Short: "Generate a leaf client certificate and private key", RunE: func(cmd *cobra.Command, args []string) error { ca, err := pki.ParseCertFromFile(CAFile) if err != nil { return err } caKey, err := pki.ParseKeyFromFile(CAKeyFile) if err != nil { return err } crtKey := pki.NewKey() clientCrtTmpl := &x509.Certificate{ SerialNumber: pki.NewCertSerialNumber(), Subject: pkix.Name{ CommonName: CommonName, }, // Leaf certs valid for 1 year. NotBefore: time.Now(), NotAfter: time.Now().AddDate(1, 0, 0), // This cert is a leaf, and not a CA. IsCA: false, // Disambiguate `IsCA` BasicConstraintsValid: true, KeyUsage: x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, } clientCrtBytes, err := x509.CreateCertificate( rand.Reader, clientCrtTmpl, // CA is the parent. ca, // The cert embeds its own public key. &crtKey.PublicKey, // The CA's private key is the one signing the leaf cert. caKey, ) clientCrtPEMBytes := pem.EncodeToMemory(&pem.Block{ Type: pki.PEMTypeCertificate, Bytes: clientCrtBytes, }) // Write cert to disk. crtfn := path.Join(OutDir, Name+".crt") err = createFileWith(crtfn, clientCrtPEMBytes, pki.CertFilePerms) if err != nil { return err } // Write cert private key to disk. keyfn := path.Join(OutDir, Name+".key") err = createFileWith(keyfn, pki.MarshalKeyToPEM(crtKey), pki.PrivateKeyFilePerms) if err != nil { return err } return nil }, }