diff --git a/cmd/keygen/main.go b/cmd/keygen/main.go index a74a4912..8539de50 100644 --- a/cmd/keygen/main.go +++ b/cmd/keygen/main.go @@ -1,7 +1,9 @@ package main import ( + "encoding/base64" "fmt" + "io/ioutil" "log" "os" "path/filepath" @@ -13,41 +15,52 @@ import ( ) const ( - // Names used for created files. - privKeyName = "priv.bin" - pubKeyName = "pub.bin" - identityName = "identity" + privKeyName = "priv.bin" + pubKeyName = "pub.bin" + pubKeyTxtName = "pub.txt" + identityName = "identity" + peerIDFileName = "peerid.txt" // New constant for the peer ID file ) const ( - // Permissions used for created files. privKeyPermissions = 0600 pubKeyPermissions = 0644 ) func main() { - - var ( - flagOutputDir string - ) + var flagOutputDir string pflag.StringVarP(&flagOutputDir, "output", "o", ".", "directory where keys should be stored") - pflag.Parse() - // Create output directory, if it doesn't exist. err := os.MkdirAll(flagOutputDir, os.ModePerm) if err != nil { log.Fatalf("could not create output directory: %s", err) } - // Generate key pair. - priv, pub, err := crypto.GenerateKeyPair(crypto.Ed25519, 0) - if err != nil { - log.Fatalf("could not generate key pair: %s", err) + privKeyFile := filepath.Join(flagOutputDir, privKeyName) + + var priv crypto.PrivKey + var pub crypto.PubKey + + if _, err := os.Stat(privKeyFile); os.IsNotExist(err) { + priv, pub, err = crypto.GenerateKeyPair(crypto.Ed25519, 0) + if err != nil { + log.Fatalf("could not generate key pair: %s", err) + } + } else { + privBytes, err := ioutil.ReadFile(privKeyFile) + if err != nil { + log.Fatalf("could not read existing private key: %s", err) + } + + priv, err = crypto.UnmarshalPrivateKey(privBytes) + if err != nil { + log.Fatalf("could not unmarshal private key: %s", err) + } + pub = priv.GetPublic() } - // Encode keys and extract peer ID from key. privPayload, err := crypto.MarshalPrivateKey(priv) if err != nil { log.Fatalf("could not marshal private key: %s", err) @@ -63,27 +76,40 @@ func main() { log.Fatalf("failed to get peer identity from public key: %s", err) } - // Write keys and identity to files. - pubKeyFile := filepath.Join(flagOutputDir, pubKeyName) err = os.WriteFile(pubKeyFile, pubPayload, pubKeyPermissions) if err != nil { - log.Fatalf("could not write private key to file: %s", err) + log.Fatalf("could not write public key to file: %s", err) + } + + pubKeyBase64 := base64.StdEncoding.EncodeToString(pubPayload) + pubKeyTxtFile := filepath.Join(flagOutputDir, pubKeyTxtName) + err = os.WriteFile(pubKeyTxtFile, []byte(pubKeyBase64), pubKeyPermissions) + if err != nil { + log.Fatalf("could not write public key string to file: %s", err) } idFile := filepath.Join(flagOutputDir, identityName) err = os.WriteFile(idFile, []byte(identity), pubKeyPermissions) if err != nil { - log.Fatalf("could not write private key to file: %s", err) + log.Fatalf("could not write identity to file: %s", err) + } + + // Write the Peer ID to a file + peerIDFile := filepath.Join(flagOutputDir, peerIDFileName) + err = os.WriteFile(peerIDFile, []byte(identity.Pretty()), pubKeyPermissions) + if err != nil { + log.Fatalf("could not write peer ID to file: %s", err) } - privKeyFile := filepath.Join(flagOutputDir, privKeyName) err = os.WriteFile(privKeyFile, privPayload, privKeyPermissions) if err != nil { log.Fatalf("could not write private key to file: %s", err) } - fmt.Printf("generated private key: %s\n", privKeyFile) - fmt.Printf("generated public key: %s\n", pubKeyFile) - fmt.Printf("generated identity file: %s\n", idFile) + fmt.Printf("private key file: %s\n", privKeyFile) + fmt.Printf("public key file: %s\n", pubKeyFile) + fmt.Printf("public key text: %s\n", pubKeyTxtFile) + fmt.Printf("identity file: %s\n", idFile) + fmt.Printf("peer ID file: %s\n", peerIDFile) // Output the Peer ID file path }