diff options
Diffstat (limited to 'key')
| -rw-r--r-- | key/boxgen.go | 78 | ||||
| -rw-r--r-- | key/generate.go | 126 | ||||
| -rw-r--r-- | key/siggen.go | 47 |
3 files changed, 126 insertions, 125 deletions
diff --git a/key/boxgen.go b/key/boxgen.go deleted file mode 100644 index 06ff360..0000000 --- a/key/boxgen.go +++ /dev/null @@ -1,78 +0,0 @@ -package key - -import ( - crypto_rand "crypto/rand" - "encoding/hex" - "fmt" - "golang.org/x/crypto/nacl/box" - "os" - - "git.samanthony.xyz/hose/util" -) - -// generateBoxKeypair generates a new public/private keypair for NaCl box -// (encryption/decryption) operations. It stores the private key in the private box -// key file and the public box key in the public key file. If either of the key files -// already exist, they will not be overwritten; instead an error will be returned. -func generateBoxKeypair() error { - util.Logf("generating new encryption/decryption keypair...") - - // Create public key file. - pubFile, err := createFileIfNotExist(boxPubKeyFile, pubFileMode) - if err != nil { - return err - } - defer pubFile.Close() - - // Create private key file. - privFile, err := createFileIfNotExist(boxPrivKeyFile, privFileMode) - if err != nil { - pubFile.Close() - _ = os.Remove(boxPubKeyFile) - return err - } - defer privFile.Close() - - // Generate keypair. - pubkey, privkey, err := box.GenerateKey(crypto_rand.Reader) - if err != nil { - return err - } - - // Write keypair to files. - buf := make([]byte, hex.EncodedLen(len(*pubkey))) - hex.Encode(buf, (*pubkey)[:]) - if _, err := pubFile.Write(buf); err != nil { - return err - } - buf = make([]byte, hex.EncodedLen(len(*privkey))) - hex.Encode(buf, (*privkey)[:]) - if _, err := privFile.Write(buf); err != nil { - return err - } - - return nil -} - -// generateBoxKeypairIfNotExist generates a NaCal box keypair if it doesn't already exist. -func generateBoxKeypairIfNotExist() error { - pubExists, err := fileExists(boxPubKeyFile) - if err != nil { - return err - } - privExists, err := fileExists(boxPrivKeyFile) - if err != nil { - return err - } - - if pubExists && privExists { - // Keypair already exists. - return nil - } else if pubExists && !privExists { - return fmt.Errorf("found public key file but not private key file") - } else if privExists && !pubExists { - return fmt.Errorf("found private key file but not public key file") - } - // Neither public nor private key file exists; generate new keypair. - return generateBoxKeypair() -} diff --git a/key/generate.go b/key/generate.go new file mode 100644 index 0000000..d7480c9 --- /dev/null +++ b/key/generate.go @@ -0,0 +1,126 @@ +package key + +import ( + crypto_rand "crypto/rand" + "encoding/hex" + "fmt" + "golang.org/x/crypto/nacl/box" + "golang.org/x/crypto/nacl/sign" + "io" + + "git.samanthony.xyz/hose/util" +) + +// A keyGenerator generates a new keypair from a random bitstream. +type keyGenerator func(rand io.Reader) (publicKey, privateKey []byte, err error) + +// generateKeypair uses a key generator function to create a new public/private keypair. +// The public key is saved to the public file, and the private key is saved to the private file. +// If either of the files already exist, an error is returned. +func generateKeypair(generate keyGenerator, pubFileName, privFileName string) error { + // Create public key file. + pubFile, err := createFileIfNotExist(pubFileName, pubFileMode) + if err != nil { + return err + } + defer pubFile.Close() + + // Create private key file. + privFile, err := createFileIfNotExist(privFileName, privFileMode) + if err != nil { + return err + } + defer privFile.Close() + + // Generate keypair. + pubkey, privkey, err := generate(crypto_rand.Reader) + if err != nil { + return err + } + + // Write keypair to files. + buf := make([]byte, hex.EncodedLen(len(pubkey))) + hex.Encode(buf, pubkey) + if _, err := pubFile.Write(buf); err != nil { + return err + } + buf = make([]byte, hex.EncodedLen(len(privkey))) + hex.Encode(buf, privkey) + if _, err := privFile.Write(buf); err != nil { + return err + } + + return nil +} + +// If neither the public file nor private file exist, generateKeypair uses the key generator +// function to create a new keypair. The public key is saved to the public key file, +// and the private key is saved to the private key file. +func generateKeypairIfNotExist(generate keyGenerator, pubFile, privFile string) error { + pubExists, err := fileExists(pubFile) + if err != nil { + return err + } + privExists, err := fileExists(privFile) + if err != nil { + return err + } + + if pubExists && privExists { + // Keypair already exists. + return nil + } else if pubExists && !privExists { + return fmt.Errorf("found public key file but not private key file") + } else if privExists && !pubExists { + return fmt.Errorf("found private key file but not public key file") + } + // Neither public nor private key file exists; generate new keypair. + return generateKeypair(generate, pubFile, privFile) +} + +// generateBoxKeypair generates a new public/private keypair for NaCl box +// (encryption/decryption) operations. It stores the private key in the private box +// key file and the public box key in the public key file. If either of the key files +// already exist, they will not be overwritten; instead an error will be returned. +func generateBoxKeypair() error { + return generateKeypair(boxKeyGenerator, boxPubKeyFile, boxPrivKeyFile) +} + +// generateBoxKeypairIfNotExist generates a NaCal box keypair if it doesn't already exist. +func generateBoxKeypairIfNotExist() error { + return generateKeypairIfNotExist(boxKeyGenerator, boxPubKeyFile, boxPrivKeyFile) +} + +// NaCl box (encrypt/decrypt) keypair generator for use with generateKeypair(). +func boxKeyGenerator(rand io.Reader) (publicKey, privateKey []byte, err error) { + util.Logf("generating new encryption/decryption keypair...") + pub, priv, err := box.GenerateKey(rand) + if err != nil { + return []byte{}, []byte{}, err + } + return (*pub)[:], (*priv)[:], nil +} + +// generateSigKeypair generates a new NaCl sign/verify keypair. +// It stores the private signing key in the private signing key file +// and the public verification key in the public verification key file. +// If either of the key files already exist, they will not be overwritten; +// instead an error will be returned. +func generateSigKeypair() error { + util.Logf("generating new sign/verify keypair...") + return generateKeypair(sigKeyGenerator, sigPubKeyFile, sigPrivKeyFile) +} + +// generateSigKeypairIfNotExist generates a NaCl sign/verify keypair if it doesn't already exist. +func generateSigKeypairIfNotExist() error { + return generateKeypairIfNotExist(sigKeyGenerator, sigPubKeyFile, sigPrivKeyFile) +} + +// NaCl sign/verify keypair generator for use with generateKeypair(). +func sigKeyGenerator(rand io.Reader) (publicKey, privateKey []byte, err error) { + pub, priv, err := sign.GenerateKey(rand) + if err != nil { + return []byte{}, []byte{}, err + } + return (*pub)[:], (*priv)[:], nil +} diff --git a/key/siggen.go b/key/siggen.go deleted file mode 100644 index 84d26fb..0000000 --- a/key/siggen.go +++ /dev/null @@ -1,47 +0,0 @@ -package key - -import ( - crypto_rand "crypto/rand" - "encoding/hex" - "golang.org/x/crypto/nacl/sign" - - "git.samanthony.xyz/hose/util" -) - -func generateSigKeypair() error { - util.Logf("generating new sign/verify keypair...") - - // Create public key file. - pubFile, err := createFileIfNotExist(sigPubKeyFile, pubFileMode) - if err != nil { - return err - } - defer pubFile.Close() - - // Create private key file. - privFile, err := createFileIfNotExist(sigPrivKeyFile, privFileMode) - if err != nil { - return err - } - defer privFile.Close() - - // Generate keypair. - pubkey, privkey, err := sign.GenerateKey(crypto_rand.Reader) - if err != nil { - return err - } - - // Write keypair to files. - buf := make([]byte, hex.EncodedLen(len(*pubkey))) - hex.Encode(buf, (*pubkey)[:]) - if _, err := pubFile.Write(buf); err != nil { - return err - } - buf = make([]byte, hex.EncodedLen(len(*privkey))) - hex.Encode(buf, (*privkey)[:]) - if _, err := privFile.Write(buf); err != nil { - return err - } - - return nil -} |