From b691f0957c9d3401d242fdd4e68f5bbee08fe98a Mon Sep 17 00:00:00 2001
From: Paul Vaughan <paulieboo@gmail.com>
Date: Fri, 10 Sep 2021 19:13:21 +0100
Subject: [PATCH] Implemented a helper flag in both commands to spit out a
 handful of keys in hex and base64 with a variety of lengths.

---
 cmd/collector/main.go |  7 +++++++
 cmd/receiver/main.go  |  7 +++++++
 internal/vcms.go      | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/cmd/collector/main.go b/cmd/collector/main.go
index 57e1224..030f536 100644
--- a/cmd/collector/main.go
+++ b/cmd/collector/main.go
@@ -33,6 +33,7 @@ func main() {
 
 	var (
 		version     = false
+		keyGen      = false
 		debug       = false
 		testing     = false
 		receiverURL = "http://127.0.0.1:8080"
@@ -40,6 +41,7 @@ func main() {
 	)
 
 	flag.BoolVar(&debug, "d", debug, "Shows debugging info")
+	flag.BoolVar(&keyGen, "k", false, "Quickly generate a few random keys")
 	flag.BoolVar(&testing, "t", testing, "Creates a random hostname, username and IP address")
 	flag.StringVar(&receiverURL, "r", receiverURL, "URL of the 'Receiver' application")
 	flag.BoolVar(&version, "v", version, "Show version info and quit")
@@ -50,6 +52,11 @@ func main() {
 		os.Exit(0)
 	}
 
+	if keyGen {
+		vcms.ShowRandomKeys()
+		os.Exit(0)
+	}
+
 	// Opens a logfile for writing and also outputs to stdout.
 	vcms.CheckLogFolder(vcms.LogFolder)
 	lf, err := os.OpenFile(logName, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0755)
diff --git a/cmd/receiver/main.go b/cmd/receiver/main.go
index 50f3a2d..13dc309 100644
--- a/cmd/receiver/main.go
+++ b/cmd/receiver/main.go
@@ -76,12 +76,14 @@ func main() {
 
 	var (
 		version     = false
+		keyGen      = false
 		receiverURL = "127.0.0.1:8080" // Don't put e.g. http:// at the start. Add this to docs.
 		logName     = vcms.CreateLogName(vcms.LogFolder, cmdCodename)
 	)
 
 	flag.BoolVar(&debug, "d", debug, "Shows debugging info")
 	flag.BoolVar(&version, "v", false, "Show version info and quit")
+	flag.BoolVar(&keyGen, "k", false, "Quickly generate a few random keys")
 	flag.StringVar(&receiverURL, "r", receiverURL, "URL to run this application's web server on")
 	flag.Parse()
 
@@ -90,6 +92,11 @@ func main() {
 		os.Exit(0)
 	}
 
+	if keyGen {
+		vcms.ShowRandomKeys()
+		os.Exit(0)
+	}
+
 	// Opens a logfile for writing and also outputs to stdout.
 	vcms.CheckLogFolder(vcms.LogFolder)
 	lf, err := os.OpenFile(logName, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0755)
diff --git a/internal/vcms.go b/internal/vcms.go
index 2ef8421..5dd1d61 100644
--- a/internal/vcms.go
+++ b/internal/vcms.go
@@ -2,10 +2,14 @@
 package vcms
 
 import (
+	"encoding/base64"
+	"encoding/hex"
 	"fmt"
 	"log"
+	"math/rand"
 	"os"
 	"runtime"
+	"strings"
 	"time"
 )
 
@@ -132,3 +136,39 @@ func CreateLogName(logFolder string, cmdName string) string {
 
 	return fmt.Sprintf("%s/%s_%s.log", logFolder, cmdName, time)
 }
+
+// Creates a random string of length n, in either hex or base64.
+func createRandomString(n int, keyType string) string {
+	b := make([]byte, (n+1)/2)
+
+	src := rand.New(rand.NewSource(time.Now().UnixNano()))
+	if _, err := src.Read(b); err != nil {
+		panic(err)
+	}
+
+	switch keyType {
+	case "hex":
+		return hex.EncodeToString(b)
+	case "base64":
+		return base64.URLEncoding.EncodeToString(b)
+	default:
+		return ""
+	}
+}
+
+// ShowRandomKeys prints a bunch of strings of varying lengths, generated from random data and converted to hex or base64.
+func ShowRandomKeys() {
+	fmt.Println("Randonly generated bytes, converted to hex and base64 strings, suitable for being used as a pre-shared key.")
+	fmt.Println("Re-run for more random keys.")
+	fmt.Println("\nHex:")
+	for _, n := range []int{16, 32, 48, 64, 96, 128} {
+		key := createRandomString(n, "hex")
+		fmt.Printf("%3d chars: %s / %s\n", len(key), key, strings.ToUpper(key))
+	}
+
+	fmt.Println("\nBase64:")
+	for _, n := range []int{24, 48, 72, 96, 144, 192} {
+		key := createRandomString(n, "base64")
+		fmt.Printf("%3d chars: %s\n", len(key), key)
+	}
+}