Compare commits
No commits in common. "c9cb1bb2d885241b1677869beccb7892ca49b9f5" and "c3c506e206f4d1bd1327b0e5e650ebe186ea78da" have entirely different histories.
c9cb1bb2d8
...
c3c506e206
@ -11,5 +11,4 @@ Exact amount of required characters can be calculated by formula: $\lceil 256 /
|
||||
|
||||
## TODO
|
||||
[X] piped/terminal output as raw/verbose
|
||||
[X] handle broken pipe signal since program will so much depend on pipes
|
||||
[ ] option to read hex number that will be used instead of hash of password (usefull if user already has sha 256 hash of smth or want to use something else as input instead)
|
||||
[ ] handle broken pipe signal since program will so much depend on pipes
|
||||
|
||||
@ -7,10 +7,8 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"slices"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
@ -46,76 +44,7 @@ Each word or number is mapped following this list:
|
||||
- stupid - no limit
|
||||
`
|
||||
|
||||
type Flags struct {
|
||||
RawOutput bool
|
||||
OutputFile string
|
||||
EntropyLevel int
|
||||
}
|
||||
|
||||
func main() {
|
||||
setSystemSignalHandlers()
|
||||
flags, err := parseFlags()
|
||||
if err != nil {
|
||||
errorf("error while parsing arguments: %s\n", err)
|
||||
}
|
||||
|
||||
passbytes, err := getPasswordBytes()
|
||||
if err != nil {
|
||||
errorf("Failed to get password, error: %s\n", err)
|
||||
}
|
||||
valid := isEntropyValid(passbytes, flags.EntropyLevel)
|
||||
if !valid {
|
||||
errorf("You should choose stroger password!!! (or change entropy level, read more with --help)\n")
|
||||
}
|
||||
|
||||
sum := sha256.Sum256(passbytes)
|
||||
|
||||
k, err := newX25519IdentityFromScalar(sum[:])
|
||||
if err != nil {
|
||||
errorf("internal error: %v", err)
|
||||
}
|
||||
|
||||
// if user is not seeing private keyfile, which also contains public key,
|
||||
// also duplicate public key it to stderr,
|
||||
// but if user sees public key via stdout, no need for duplication
|
||||
if flags.OutputFile != "" {
|
||||
if !flags.RawOutput {
|
||||
fmt.Printf("Public key: %s\n", k.Recipient())
|
||||
} else {
|
||||
fmt.Printf("%s", k.Recipient())
|
||||
}
|
||||
}
|
||||
|
||||
output := os.Stdout
|
||||
if flags.OutputFile != "" {
|
||||
output, err = os.Create(flags.OutputFile)
|
||||
if err != nil {
|
||||
errorf("failed to create output file, error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = writeSecretKey(output, k, !flags.RawOutput)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to write secret key to file, error: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func setSystemSignalHandlers() {
|
||||
go handleSigpipe()
|
||||
}
|
||||
|
||||
func handleSigpipe() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGPIPE)
|
||||
|
||||
<-c
|
||||
|
||||
errorf("Recieved SIGPIPE. Check if your programs that give input or recieve input do not stops before this one")
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func parseFlags() (*Flags, error) {
|
||||
log.SetFlags(0)
|
||||
flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s", usage) }
|
||||
|
||||
@ -133,14 +62,48 @@ func parseFlags() (*Flags, error) {
|
||||
|
||||
eLevel, err := parseEntropyLevel(entropyLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
errorf("error while parsing --entropy-level argument: %s\n", err)
|
||||
}
|
||||
|
||||
return &Flags{
|
||||
RawOutput: rawOutput,
|
||||
OutputFile: outputFile,
|
||||
EntropyLevel: eLevel,
|
||||
}, nil
|
||||
passbytes, err := getPasswordBytes()
|
||||
if err != nil {
|
||||
errorf("Failed to get password, error: %s\n", err)
|
||||
}
|
||||
valid := isEntropyValid(passbytes, eLevel)
|
||||
if !valid {
|
||||
errorf("You should choose stroger password!!! (or change entropy level, read more with --help)\n")
|
||||
}
|
||||
|
||||
sum := sha256.Sum256(passbytes)
|
||||
|
||||
k, err := newX25519IdentityFromScalar(sum[:])
|
||||
if err != nil {
|
||||
errorf("internal error: %v", err)
|
||||
}
|
||||
|
||||
// if user is not seeing private keyfile, which also contains public key,
|
||||
// also duplicate public key it to stderr,
|
||||
// but if user sees public key via stdout, no need for duplication
|
||||
if outputFile != "" {
|
||||
if !rawOutput {
|
||||
fmt.Printf("Public key: %s\n", k.Recipient())
|
||||
} else {
|
||||
fmt.Printf("%s", k.Recipient())
|
||||
}
|
||||
}
|
||||
|
||||
output := os.Stdout
|
||||
if outputFile != "" {
|
||||
output, err = os.Create(outputFile)
|
||||
if err != nil {
|
||||
errorf("failed to create output file, error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = writeSecretKey(output, k, !rawOutput)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to write secret key to file, error: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func parseEntropyLevel(entropyLevel string) (int, error) {
|
||||
@ -171,17 +134,10 @@ func isEntropyValid(passbytes []byte, entropyLevel int) bool {
|
||||
|
||||
func getPasswordBytes() ([]byte, error) {
|
||||
if term.IsTerminal(int(os.Stdin.Fd())) {
|
||||
oldState, err := term.MakeRaw(0)
|
||||
defer term.Restore(0, oldState)
|
||||
|
||||
screen := struct {
|
||||
io.Reader
|
||||
io.Writer
|
||||
}{os.Stdin, os.Stdout}
|
||||
t := term.NewTerminal(screen, "")
|
||||
pass, err := t.ReadPassword("Enter pass: ")
|
||||
|
||||
return []byte(pass), err
|
||||
fmt.Fprintf(os.Stderr, "Enter password: ")
|
||||
passbytes, err := term.ReadPassword(int(os.Stdin.Fd()))
|
||||
fmt.Println()
|
||||
return passbytes, err
|
||||
} else {
|
||||
return io.ReadAll(os.Stdin)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user