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(generateCACmd) generateCACmd.Flags().StringVar( &CommonName, "common-name", "", "Common Name for the CA", ) generateCACmd.MarkFlagRequired("common-name") } var generateCACmd = &cobra.Command{ Use: "ca", Short: "Generate a Certificate Authority", RunE: func(cmd *cobra.Command, args []string) error { // Private key for the ca. key := pki.NewKey() caTmpl := &x509.Certificate{ SerialNumber: pki.NewCertSerialNumber(), Subject: pkix.Name{ CommonName: CommonName, }, // Valid starting now and for 10 years. NotBefore: time.Now(), NotAfter: time.Now().AddDate(10, 0, 0), // This cert is a CA. IsCA: true, // No intermeddiate CAs, just one root that can issue leaf certs. MaxPathLen: 0, MaxPathLenZero: true, // Disambiguate `IsCA` and path len settings from their zero value. BasicConstraintsValid: true, // Only allow to sign new certs, and cert revokation lists. // Can't be used as a server or client cert itself. KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, } caBytes, err := x509.CreateCertificate( rand.Reader, // Same template and parent, i.e. self-signed. caTmpl, caTmpl, &key.PublicKey, key, ) caPEMBytes := pem.EncodeToMemory(&pem.Block{ Type: pki.PEMTypeCertificate, Bytes: caBytes, }) // Write ca to disk. cafn := path.Join(OutDir, Name+"_ca.crt") err = createFileWith(cafn, caPEMBytes, pki.CertFilePerms) if err != nil { return err } // 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 } return nil }, }