Skip to content

Commit

Permalink
feature to support text input from stdin and fixing docker build
Browse files Browse the repository at this point in the history
  • Loading branch information
shibme committed Jul 10, 2024
1 parent 738fcd5 commit 28896a1
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 67 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM scratch
ARG TARGETARCH
COPY ./dist/xipher_linux_${TARGETARCH}*/ /
COPY ./dist/xipher-cli_linux_${TARGETARCH}*/ /
WORKDIR /data
ENTRYPOINT ["/xipher"]
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
Xipher is a curated collection of cryptographic primitives put together to perform key/password based asymmetric encryption.

## What does it do?

- Allows sharing of data securely between two parties over an insecure channel using asymmetric encryption.
- The sender encrypts the data using a public key (received from a receiver) derived from a password and shares the encrypted data with the receiver.
- The receiver decrypts the data using the same password.
Expand All @@ -22,7 +21,6 @@ Xipher is a curated collection of cryptographic primitives put together to perfo
Download the latest binary from the [releases](https://github.com/shibme/xipher/releases/latest) page and add it to your path.

### Demo

![Demo](https://dev.shib.me/xipher/demo.gif)

### Homebrew
Expand Down Expand Up @@ -60,7 +58,6 @@ docker run --rm -v $PWD:/data -it shibme/xipher help
```

## Web Interface

A web interface interoperable with the CLI, implemented using [web assembly](#web-assembly) is available [here](https://dev.shib.me/xipher).

## Using as a Go package
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ require (
github.com/cloudflare/circl v1.3.9
github.com/fatih/color v1.17.0
github.com/spf13/cobra v1.8.1
golang.org/x/crypto v0.24.0
golang.org/x/term v0.21.0
golang.org/x/crypto v0.25.0
golang.org/x/term v0.22.0
)

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/sys v0.22.0 // indirect
)
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
125 changes: 86 additions & 39 deletions internal/cli/commands/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,74 +46,121 @@ type flagDef struct {
usage string
}

type strFlag struct {
flagDef
value string
}

func (f *strFlag) flagFields() (string, string, string, string) {
return f.name, f.shorthand, f.value, f.usage
}

type boolFlag struct {
flagDef
value bool
}

func (f *boolFlag) flagFields() (string, string, bool, string) {
return f.name, f.shorthand, f.value, f.usage
}

var (

// Version Flag
versionFlag = flagDef{
name: "version",
shorthand: "v",
usage: "Shows version info",
versionFlag = boolFlag{
flagDef: flagDef{
name: "version",
shorthand: "v",
usage: "Shows version info",
},
}

// Public Key File Flag
publicKeyFileFlag = flagDef{
name: "public-key-file",
shorthand: "p",
usage: "Specify path to the public key file",
publicKeyFileFlag = strFlag{
flagDef: flagDef{
name: "public-key-file",
shorthand: "p",
usage: "Specify path to the public key file",
},
}

// Quantum-safe encryption
quantumSafeFlag = flagDef{
name: "quantum-safe",
shorthand: "q",
usage: "Uses quantum-safe cryptography",
quantumSafeFlag = boolFlag{
flagDef: flagDef{
name: "quantum-safe",
shorthand: "q",
usage: "Uses quantum-safe cryptography",
},
}

// Ignore Password Policy Check Flag
ignorePasswordCheckFlag = flagDef{
name: "ignore-password-policy",
usage: "Ignores the password policy check",
ignorePasswordCheckFlag = boolFlag{
flagDef: flagDef{
name: "ignore-password-policy",
usage: "Ignores the password policy check",
},
}

// Auto generate secret key Flag
autoGenerateSecretKey = flagDef{
name: "auto",
shorthand: "a",
usage: "Auto generate a secret key",
autoGenerateSecretKey = boolFlag{
flagDef: flagDef{
name: "auto",
shorthand: "a",
usage: "Auto generate a secret key",
},
}

// Key or Pwd Flag
keyOrPwdFlag = flagDef{
name: "key",
shorthand: "k",
usage: "Specify public key, secret key or a password",
keyOrPwdFlag = strFlag{
flagDef: flagDef{
name: "key",
shorthand: "k",
usage: "Specify public key, secret key or a password",
},
}

// Text Flag
textFlag = strFlag{
flagDef: flagDef{
name: "text",
shorthand: "t",
usage: "Specify the text to encrypt (use '-' to read from stdin)",
},
}

// Ciphertext Flag
ciphertextFlag = flagDef{
name: "ciphertext",
shorthand: "c",
usage: "Specify the ciphertext",
ciphertextFlag = strFlag{
flagDef: flagDef{
name: "ciphertext",
shorthand: "c",
usage: "Specify the ciphertext",
},
}

// File Flag
fileFlag = flagDef{
name: "file",
shorthand: "f",
usage: "Specify file path",
fileFlag = strFlag{
flagDef: flagDef{
name: "file",
shorthand: "f",
usage: "Specify file path",
},
}

// Out Flag
outFlag = flagDef{
name: "out",
shorthand: "o",
usage: "Specify an output file path",
outFlag = strFlag{
flagDef: flagDef{
name: "out",
shorthand: "o",
usage: "Specify an output file path",
},
}

// Compress Flag
compressFlag = flagDef{
name: "compress",
shorthand: "c",
usage: "Enable compression as the data is encrypted",
compressFlag = boolFlag{
flagDef: flagDef{
name: "compress",
shorthand: "c",
usage: "Enable compression as the data is encrypted",
},
}
)
6 changes: 3 additions & 3 deletions internal/cli/commands/decrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func decryptTextCommand() *cobra.Command {
safeExit()
},
}
decryptTxtCmd.Flags().StringP(ciphertextFlag.name, ciphertextFlag.shorthand, "", ciphertextFlag.usage)
decryptTxtCmd.Flags().StringP(ciphertextFlag.flagFields())
decryptTxtCmd.MarkFlagRequired(ciphertextFlag.name)
return decryptTxtCmd
}
Expand Down Expand Up @@ -116,8 +116,8 @@ func decryptFileCommand() *cobra.Command {
safeExit()
},
}
decryptFileCmd.Flags().StringP(fileFlag.name, fileFlag.shorthand, "", fileFlag.usage)
decryptFileCmd.Flags().StringP(outFlag.name, outFlag.shorthand, "", outFlag.usage)
decryptFileCmd.Flags().StringP(fileFlag.flagFields())
decryptFileCmd.Flags().StringP(outFlag.flagFields())
decryptFileCmd.MarkFlagRequired(fileFlag.name)
return decryptFileCmd
}
21 changes: 15 additions & 6 deletions internal/cli/commands/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func encryptCommand() *cobra.Command {
cmd.Help()
},
}
encryptCmd.PersistentFlags().StringP(keyOrPwdFlag.name, keyOrPwdFlag.shorthand, "", keyOrPwdFlag.usage)
encryptCmd.PersistentFlags().BoolP(ignorePasswordCheckFlag.name, ignorePasswordCheckFlag.shorthand, false, ignorePasswordCheckFlag.usage)
encryptCmd.PersistentFlags().StringP(keyOrPwdFlag.flagFields())
encryptCmd.PersistentFlags().BoolP(ignorePasswordCheckFlag.flagFields())
encryptCmd.AddCommand(encryptTextCommand())
encryptCmd.AddCommand(encryptFileCommand())
return encryptCmd
Expand Down Expand Up @@ -68,7 +68,15 @@ func encryptTextCommand() *cobra.Command {
if err != nil {
exitOnError(err)
}
input, err := getHiddenInputFromUser("Enter text to encrypt: ")
text, _ := cmd.Flags().GetString(textFlag.name)
var input []byte
if text == "" {
input, err = getHiddenInputFromUser("Enter text to encrypt: ")
} else if text == "-" {
input, err = readBufferFromStdin("")
} else {
input = []byte(text)
}
if err != nil {
exitOnError(err)
}
Expand All @@ -81,6 +89,7 @@ func encryptTextCommand() *cobra.Command {
safeExit()
},
}
encryptTxtCmd.Flags().StringP(textFlag.flagFields())
return encryptTxtCmd
}

Expand Down Expand Up @@ -129,9 +138,9 @@ func encryptFileCommand() *cobra.Command {
safeExit()
},
}
encryptFileCmd.Flags().StringP(fileFlag.name, fileFlag.shorthand, "", fileFlag.usage)
encryptFileCmd.Flags().StringP(outFlag.name, outFlag.shorthand, "", outFlag.usage)
encryptFileCmd.Flags().BoolP(compressFlag.name, compressFlag.shorthand, false, compressFlag.usage)
encryptFileCmd.Flags().StringP(fileFlag.flagFields())
encryptFileCmd.Flags().StringP(outFlag.flagFields())
encryptFileCmd.Flags().BoolP(compressFlag.flagFields())
encryptFileCmd.MarkFlagRequired(fileFlag.name)
return encryptFileCmd
}
21 changes: 20 additions & 1 deletion internal/cli/commands/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"bytes"
"fmt"
"os"
"strings"
"syscall"
"unicode"
Expand Down Expand Up @@ -48,7 +49,9 @@ func pwdCheck(password string) error {

func getVisibleInput(prompt string) (string, error) {
var input string
fmt.Print(prompt)
if prompt != "" {
fmt.Print(prompt)
}
_, err := fmt.Scanln(&input)
return input, err
}
Expand Down Expand Up @@ -83,3 +86,19 @@ func getPasswordFromUser(confirm, ignorePolicyCheck bool) ([]byte, error) {
}
return password, nil
}

func readBufferFromStdin(prompt string) ([]byte, error) {
var input []byte
buffer := make([]byte, 1024)
if prompt != "" {
fmt.Println(prompt)
}
for {
n, err := os.Stdin.Read(buffer)
if err != nil || n == 0 {
break
}
input = append(input, buffer[:n]...)
}
return input, nil
}
8 changes: 4 additions & 4 deletions internal/cli/commands/keygen.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ func keygenCommand() *cobra.Command {
fmt.Println("It is completely safe to share this public key with anyone.")
},
}
keygenCmd.Flags().BoolP(ignorePasswordCheckFlag.name, ignorePasswordCheckFlag.shorthand, false, ignorePasswordCheckFlag.usage)
keygenCmd.Flags().StringP(publicKeyFileFlag.name, publicKeyFileFlag.shorthand, "", publicKeyFileFlag.usage)
keygenCmd.Flags().BoolP(autoGenerateSecretKey.name, autoGenerateSecretKey.shorthand, false, autoGenerateSecretKey.usage)
keygenCmd.Flags().BoolP(quantumSafeFlag.name, quantumSafeFlag.shorthand, false, quantumSafeFlag.usage)
keygenCmd.Flags().BoolP(ignorePasswordCheckFlag.flagFields())
keygenCmd.Flags().StringP(publicKeyFileFlag.flagFields())
keygenCmd.Flags().BoolP(autoGenerateSecretKey.flagFields())
keygenCmd.Flags().BoolP(quantumSafeFlag.flagFields())
return keygenCmd
}
2 changes: 1 addition & 1 deletion internal/cli/commands/xipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func XipherCommand() *cobra.Command {
}
},
}
xipherCmd.Flags().BoolP(versionFlag.name, versionFlag.shorthand, false, versionFlag.usage)
xipherCmd.Flags().BoolP(versionFlag.flagFields())
xipherCmd.AddCommand(versionCommand())
xipherCmd.AddCommand(keygenCommand())
xipherCmd.AddCommand(encryptCommand())
Expand Down

0 comments on commit 28896a1

Please sign in to comment.