diff --git a/create_certs/create_certs_linux b/create_certs/create_certs_linux index e809faa..7e57e04 100755 Binary files a/create_certs/create_certs_linux and b/create_certs/create_certs_linux differ diff --git a/create_certs/create_certs_osx b/create_certs/create_certs_osx index c985f63..308e263 100755 Binary files a/create_certs/create_certs_osx and b/create_certs/create_certs_osx differ diff --git a/create_certs/create_certs_rpi b/create_certs/create_certs_rpi index c678ef0..0b561aa 100755 Binary files a/create_certs/create_certs_rpi and b/create_certs/create_certs_rpi differ diff --git a/create_certs/create_certs_windows.exe b/create_certs/create_certs_windows.exe index 18bfa69..2c84b99 100755 Binary files a/create_certs/create_certs_windows.exe and b/create_certs/create_certs_windows.exe differ diff --git a/create_certs/src/create_certs.go b/create_certs/src/create_certs.go index 5eaa1a8..ce61b37 100644 --- a/create_certs/src/create_certs.go +++ b/create_certs/src/create_certs.go @@ -9,21 +9,82 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "flag" + "fmt" "log" "math/big" "net" "os" + "path/filepath" "time" ) +var InBumperSan string +var OutCertDirectory string + +func setFlags() { + + exePath, _ := os.Executable() + currentDir, _ := os.Getwd() + + //certPath will be current working directory by defaultß + certPath, err := filepath.Abs(currentDir) + if err != nil { + log.Printf("Error: %v", err) + } + + //sanPath will be exe path /Bumper_SAN.txt by default + sanPath, err := filepath.Abs(filepath.Join(exePath, "..", "/Bumper_SAN.txt")) + if err != nil { + log.Printf("Error: %v", err) + } + + flag.StringVar(&InBumperSan, "inSAN", sanPath, "Input file containing a list of Subject Alternate Names (line separated)") + flag.StringVar(&OutCertDirectory, "out", certPath, "Directory to output certificates to") + + flag.Parse() + +} func main() { - make_CA() + setFlags() - signCert() + fmt.Printf("-------- Create_Certs --------\n") + + //get absolute path + outCertDirectory, _ := filepath.Abs(OutCertDirectory) + dexists, isdfile := pathExistsType(outCertDirectory) + if !dexists { + log.Fatalf("Certs directory doesn't exist: %v", outCertDirectory) + } + if isdfile { + log.Fatalf("Certs directory is a file, not a directory: %v", outCertDirectory) + } + + //get absolute path + inBumperSan, _ := filepath.Abs(InBumperSan) + bexists, isbfile := pathExistsType(inBumperSan) + if !bexists { + log.Printf("Bumper SAN doesn't exist, certificate won't contain Subject Alternate Names: %v\n", inBumperSan) + inBumperSan = "" + } + if bexists && !isbfile { + log.Printf("Bumper SAN is a directory instead of file, certificate won't contain Subject Alternate Names: %v\n", inBumperSan) + inBumperSan = "" + } + + fmt.Printf("-------- Starting Certificate Creation --------\n") + fmt.Printf("Options: \n Output Directory: %v\n Input SAN List: %v\n", outCertDirectory, inBumperSan) + + make_CA(outCertDirectory) + signCert(outCertDirectory, inBumperSan) + + fmt.Printf("-------- Certificate Creation Complete --------\n") } -func make_CA() { +func make_CA(outCertDirectory string) { + + fmt.Printf("-------- Creating CA Cert --------\n") priv, _ := rsa.GenerateKey(rand.Reader, 2048) pub := &priv.PublicKey @@ -46,40 +107,40 @@ func make_CA() { ca_b, err := x509.CreateCertificate(rand.Reader, ca, ca, pub, priv) if err != nil { - log.Println("create ca failed", err) - return + log.Fatalf("Create ca failed: %v", err) } // Public key - certOut, err := os.Create("ca.crt") + certOut, err := os.Create(filepath.Join(outCertDirectory, "ca.crt")) if err != nil { - log.Fatal("create ca.crt failed", err) + log.Fatalf("Create ca.crt failed: %v", err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: ca_b}) certOut.Close() - log.Print("ca.crt created\n") + log.Printf("ca.crt created at %v\n", filepath.Join(outCertDirectory, "ca.crt")) // Private key - keyOut, err := os.OpenFile("ca.key", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + keyOut, err := os.OpenFile(filepath.Join(outCertDirectory, "ca.key"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { - log.Fatal("create ca.key failed", err) + log.Fatalf("Create ca.key failed: %v", err) } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() - log.Print("ca.key created\n") + log.Printf("ca.key created at %v\n", filepath.Join(outCertDirectory, "ca.key")) } -func signCert() { +func signCert(outCertDirectory string, inBumperSan string) { + fmt.Printf("-------- Creating Server Cert --------\n") // Load CA - catls, err := tls.LoadX509KeyPair("ca.crt", "ca.key") + catls, err := tls.LoadX509KeyPair(filepath.Join(outCertDirectory, "ca.crt"), filepath.Join(outCertDirectory, "ca.key")) if err != nil { - log.Fatal("error loading ca cert", err) + log.Fatalf("Error loading ca cert: %v", err) } ca, err := x509.ParseCertificate(catls.Certificate[0]) if err != nil { - log.Fatal("error parsing ca cert", err) + log.Fatalf("Error parsing ca cert: %v", err) } hostname, _ := os.Hostname() @@ -109,10 +170,19 @@ func signCert() { //DNS/SAN names for cert dnsNames := []string{hostname, "localhost"} //Read SANs from file - if fileExists("Bumper_SAN.txt") { - sans, err := readLines("Bumper_SAN.txt") + //get absolute path + + bexists, isbfile := pathExistsType(inBumperSan) + if !bexists { + log.Print("Bumper SAN doesn't exist, certificate won't contain Subject Alternate Names") + } + if bexists && !isbfile { + log.Print("Bumper SAN is a directory instead of file, certificate won't contain Subject Alternate Names") + } + if bexists && isbfile { + sans, err := readLines(inBumperSan) if err != nil { - log.Fatalf("readLines: %s", err) + log.Printf("Error reading %v certificates will be created without Subject Alternate Names: %v", inBumperSan, err) } dnsNames = append(dnsNames, sans...) } @@ -138,25 +208,25 @@ func signCert() { } // Sign the certificate - cert_b, err := x509.CreateCertificate(rand.Reader, &template, ca, pubKey, catls.PrivateKey) + cert_b, err := x509.CreateCertificate(rand.Reader, &template, ca, pubKey, catls.PrivateKey) // Public key - certOut, err := os.Create("bumper.crt") + certOut, err := os.Create(filepath.Join(outCertDirectory, "bumper.crt")) if err != nil { - log.Fatal("create bumper.crt failed", err) + log.Fatalf("Create bumper.crt failed: %v", err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: cert_b}) certOut.Close() - log.Print("bumper.crt created\n") + log.Printf("bumper.crt created at %v\n", filepath.Join(outCertDirectory, "bumper.crt")) // Private key - keyOut, err := os.OpenFile("bumper.key", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + keyOut, err := os.OpenFile(filepath.Join(outCertDirectory, "bumper.key"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { - log.Fatal("create bumper.key failed", err) + log.Fatalf("create bumper.key failed: %v", err) } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}) keyOut.Close() - log.Print("bumper.key created\n") + log.Printf("bumper.key created at %v\n", filepath.Join(outCertDirectory, "bumper.key")) } func bigIntHash(n *big.Int) []byte { @@ -182,12 +252,11 @@ func readLines(path string) ([]string, error) { return lines, scanner.Err() } -// fileExists checks if a file exists and is not a directory before we -// try using it to prevent further errors. -func fileExists(filename string) bool { +// pathexistsType checks if a path exists and is a file or directory +func pathExistsType(filename string) (exists bool, isfile bool) { info, err := os.Stat(filename) if os.IsNotExist(err) { - return false + return false, false } - return !info.IsDir() + return true, !info.IsDir() } diff --git a/create_certs/src/create_certs_test.go b/create_certs/src/create_certs_test.go new file mode 100644 index 0000000..e645dc6 --- /dev/null +++ b/create_certs/src/create_certs_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "flag" + "os" + "testing" +) + +func TestArgs(t *testing.T) { + + orArgs := os.Args + + flag.CommandLine = flag.NewFlagSet(orArgs[0], flag.ContinueOnError) + os.Args = []string{"cmd", "-inSAN", "123"} + setFlags() + + if InBumperSan != "123" { + t.Error("InBumperSan not set by arg") + } + + flag.CommandLine = flag.NewFlagSet(orArgs[0], flag.ContinueOnError) + os.Args = []string{"cmd", "-out", "456"} + setFlags() + + if OutCertDirectory != "456" { + t.Error("Out path not set by arg") + } + + flag.CommandLine = flag.NewFlagSet(orArgs[0], flag.ContinueOnError) + os.Args = []string{"cmd", "-inSAN", "san1", "-out", "out2"} + setFlags() + + if InBumperSan != "san1" { + t.Error("InBumperSan not set by arg") + } + if OutCertDirectory != "out2" { + t.Error("Out path not set by arg") + } + + os.Args = orArgs +}