diff --git a/cmd/userenckey/main.go b/cmd/userenckey/main.go index c24a2c69ab0bbfd37fea0fd57ad441bb4d3008fc..7a44070731d841c6590cf1b6c69b604042e4e9d1 100644 --- a/cmd/userenckey/main.go +++ b/cmd/userenckey/main.go @@ -1,6 +1,13 @@ package main +// Encrypt/decrypt user storage encryption keys. +// +// Keys are always in the composite format used in our LDAP backend +// (<id>:<key>), base64-encoded for convenience (and for compatibility +// with LDIF binary field encoding). + import ( + "bytes" "encoding/base64" "flag" "fmt" @@ -13,6 +20,7 @@ var ( doGenKeys = flag.Bool("gen-keys", false, "generate user encryption keys with the specified curve") doDecrypt = flag.Bool("decrypt", false, "decrypt the private key given on the command line") password = flag.String("password", "", "password") + keyID = flag.String("id", "", "key ID") ) func genKeys() ([]byte, []byte, error) { @@ -29,25 +37,37 @@ func genKeys() ([]byte, []byte, error) { return enc, pub, err } +func encodeWithID(key []byte) []byte { + return bytes.Join([][]byte{[]byte(*keyID), key}, []byte(":")) +} + +func decodeWithoutID(enc []byte) []byte { + if n := bytes.IndexByte(enc, ':'); n > 0 { + enc = enc[n+1:] + } + return enc +} + +func printLDAPField(key string, value []byte) { + fmt.Printf("%s:: %s\n", key, base64.StdEncoding.EncodeToString(value)) +} + func main() { log.SetFlags(0) flag.Parse() switch { case *doGenKeys: - if *password == "" { - log.Fatal("must specify --password") + if *password == "" || *keyID == "" { + log.Fatal("must specify --password and --id") } priv, pub, err := genKeys() if err != nil { log.Fatal(err) } - fmt.Printf( - "public key:\n%s\nprivate key (encrypted,base64): %s\n", - pub, - base64.StdEncoding.EncodeToString(priv), - ) + printLDAPField("storagePublicKey", pub) + printLDAPField("storageEncryptedSecretKey", encodeWithID(priv)) case *doDecrypt: if *password == "" { @@ -63,7 +83,7 @@ func main() { if err != nil { log.Fatalf("bad base64-encoded argument: %v", err) } - encKeys = append(encKeys, encKey) + encKeys = append(encKeys, decodeWithoutID(encKey)) } dec, err := userenckey.Decrypt(encKeys, []byte(*password))