package main import ( "bytes" "crypto/rsa" "fmt" "io/ioutil" "os" "strings" "syscall" "forge.cadoles.com/Cadoles/go-http-peering/crypto" "github.com/pkg/errors" "golang.org/x/crypto/ssh/terminal" ) func getPassphrase() ([]byte, error) { passphrase, exists := os.LookupEnv("KEY_PASSPHRASE") if exists { return []byte(passphrase), nil } return askPassphrase() } func askPassphrase() ([]byte, error) { fmt.Print("Passphrase: ") passphrase, err := terminal.ReadPassword(syscall.Stdin) if err != nil { return nil, errors.WithStack(err) } fmt.Println() fmt.Print("Confirm passphrase: ") passphraseConfirmation, err := terminal.ReadPassword(syscall.Stdin) if err != nil { return nil, errors.WithStack(err) } fmt.Println() if !bytes.Equal(passphrase, passphraseConfirmation) { return nil, errors.New("passphrases does not match") } return passphrase, nil } func loadPrivateKey() (*rsa.PrivateKey, error) { if keyFile == "" { return nil, errors.New("you must specify a key file to load") } pem, err := ioutil.ReadFile(keyFile) if err != nil { return nil, errors.WithStack(err) } passphrase, err := getPassphrase() if err != nil { return nil, errors.WithStack(err) } privateKey, err := crypto.DecodePEMEncryptedPrivateKey(pem, passphrase) if err != nil { return nil, errors.WithStack(err) } return privateKey, nil } func loadToken() (string, error) { if tokenFile == "" { return "", errors.New("you must specify a token file to load") } token, err := os.ReadFile(tokenFile) if err != nil { return "", errors.WithStack(err) } return strings.TrimSpace(string(token)), nil } func handleError(err error) { if !debug { fmt.Printf("%+v\n", errors.WithStack(err)) } else { panic(fmt.Sprintf("%+v", errors.WithStack(err))) } os.Exit(1) }