diff options
Diffstat (limited to 'enc/enc.go')
| -rw-r--r-- | enc/enc.go | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/enc/enc.go b/enc/enc.go new file mode 100644 index 0000000..180927b --- /dev/null +++ b/enc/enc.go @@ -0,0 +1,78 @@ +package main + +import ( + "crypto/rand" + "encoding/binary" + "flag" + "fmt" + "os" + "strings" + + "golang.org/x/term" + "roseh.moe/cmd/sym/internal/sym" + "roseh.moe/pkg/wordlist" +) + +var ( + generatePassword = flag.Bool("g", false, "generate a secure password automatically (password will be printed to stderr)") + passwordFlag = flag.String("p", "", "use the specified password; if not provided, enc will prompt for a password") + asciiOutput = flag.Bool("a", false, "Output in base64, default is binary output") +) + +func enc() error { + if *generatePassword && *passwordFlag != "" { + return fmt.Errorf("-g and -p cannot be used together") + } + args := flag.Args() + if len(args) == 0 && !*generatePassword && *passwordFlag == "" { + return fmt.Errorf("must use -g or -p when reading from stdin") + } + var password string + if *passwordFlag != "" { + password = *passwordFlag + } else if *generatePassword { + const nWords = 10 + buf := make([]byte, 2*nWords) + rand.Read(buf) + words := make([]string, nWords) + for i := range words { + words[i] = wordlist.Words[binary.NativeEndian.Uint16(buf[2*i:])&0x1fff] + } + password = strings.Join(words, " ") + fmt.Fprintf(os.Stderr, "Your password: %s\n", password) + } else { + fmt.Fprint(os.Stderr, "Enter password: ") + pw, err := term.ReadPassword(int(os.Stdin.Fd())) + fmt.Fprintln(os.Stderr) + if err != nil { + return err + } + password = string(pw) + } + salt := make([]byte, sym.SaltSize) + rand.Read(salt) + key, err := sym.HashPassword(password, salt) + if err != nil { + return err + } + if len(args) == 0 { + if *asciiOutput { + return sym.EncryptBase64(os.Stdout, os.Stdin, key, salt, 0) + } + return sym.Encrypt(os.Stdout, os.Stdin, key, salt, 0) + } + for i, fileName := range args { + if err := sym.EncryptFile(fileName, key, salt, i, *asciiOutput); err != nil { + return err + } + } + return nil +} + +func main() { + flag.Parse() + if err := enc(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} |
