-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
766 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
.docs | ||
docs/_index.md | ||
docs/README.md | ||
strongbox | ||
bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"flag" | ||
"fmt" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/uw-labs/strongbox/strongbox" | ||
) | ||
|
||
var ( | ||
version = "dev" | ||
commit = "none" | ||
date = "unknown" | ||
builtBy = "unknown" | ||
|
||
keyLoader = strongbox.Key | ||
kr strongbox.KeyRing | ||
prefix = []byte("# STRONGBOX ENCRYPTED RESOURCE ;") | ||
defaultPrefix = []byte("# STRONGBOX ENCRYPTED RESOURCE ; See https://github.com/uw-labs/strongbox\n") | ||
|
||
errKeyNotFound = errors.New("key not found") | ||
|
||
// flags | ||
flagGitConfig = flag.Bool("git-config", false, "Configure git for strongbox use") | ||
flagGenKey = flag.String("gen-key", "", "Generate a new key and add it to your strongbox keyring") | ||
flagDecrypt = flag.Bool("decrypt", false, "Decrypt single resource") | ||
flagKey = flag.String("key", "", "Private key to use to decrypt") | ||
flagKeyRing = flag.String("keyring", "", "strongbox keyring file path, if not set default '$HOME/.strongbox_keyring' will be used") | ||
flagRecursive = flag.Bool("recursive", false, "Recursively decrypt all files under given folder, must be used with -decrypt flag") | ||
|
||
flagClean = flag.String("clean", "", "intended to be called internally by git") | ||
flagSmudge = flag.String("smudge", "", "intended to be called internally by git") | ||
flagDiff = flag.String("diff", "", "intended to be called internally by git") | ||
|
||
flagVersion = flag.Bool("version", false, "Strongbox version") | ||
) | ||
|
||
func usage() { | ||
fmt.Fprintf(os.Stderr, "Usage:\n\n") | ||
fmt.Fprintf(os.Stderr, "\tstrongbox -git-config\n") | ||
fmt.Fprintf(os.Stderr, "\tstrongbox [-keyring <keyring_file_path>] -gen-key key-name\n") | ||
fmt.Fprintf(os.Stderr, "\tstrongbox [-keyring <keyring_file_path>] -decrypt -recursive <path>\n") | ||
fmt.Fprintf(os.Stderr, "\tstrongbox -decrypt -recursive -key <key> <path>\n") | ||
fmt.Fprintf(os.Stderr, "\tstrongbox -decrypt -key <key>\n") | ||
fmt.Fprintf(os.Stderr, "\tstrongbox -version\n") | ||
fmt.Fprintf(os.Stderr, "\nif -keyring flag is not set default file '$HOME/.strongbox_keyring' or '$STRONGBOX_HOME/.strongbox_keyring' will be used as keyring\n") | ||
os.Exit(2) | ||
} | ||
|
||
func main() { | ||
log.SetPrefix("strongbox: ") | ||
log.SetFlags(log.LstdFlags | log.Lshortfile) | ||
|
||
flag.Usage = usage | ||
flag.Parse() | ||
|
||
if *flagVersion || (flag.NArg() == 1 && flag.Arg(0) == "version") { | ||
fmt.Printf("version=%s commit=%s date=%s builtBy=%s\n", version, commit, date, builtBy) | ||
return | ||
} | ||
|
||
if *flagGitConfig { | ||
strongbox.GitConfig() | ||
return | ||
} | ||
|
||
if *flagDiff != "" { | ||
strongbox.Diff(*flagDiff) | ||
return | ||
} | ||
|
||
// Set up keyring file name | ||
home := strongbox.DeriveHome() | ||
kr = &strongbox.FileKeyRing{FileName: filepath.Join(home, ".strongbox_keyring")} | ||
|
||
// if keyring flag is set replace default keyRing | ||
if *flagKeyRing != "" { | ||
kr = &strongbox.FileKeyRing{FileName: *flagKeyRing} | ||
// verify keyring is valid | ||
if err := kr.Load(); err != nil { | ||
log.Fatalf("unable to load keyring file:%s err:%s", *flagKeyRing, err) | ||
} | ||
} | ||
|
||
if *flagGenKey != "" { | ||
strongbox.GenKey(*flagGenKey) | ||
return | ||
} | ||
|
||
if *flagDecrypt { | ||
// handle recursive | ||
if *flagRecursive { | ||
var err error | ||
|
||
target := flag.Arg(0) | ||
if target == "" { | ||
target, err = os.Getwd() | ||
if err != nil { | ||
log.Fatalf("target path not provided and unable to get cwd err:%s", err) | ||
} | ||
} | ||
// for recursive decryption 'key' flag is optional but if provided | ||
// it should be valid and all encrypted file will be decrypted using it | ||
dk, err := strongbox.Decode([]byte(*flagKey)) | ||
if err != nil && *flagKey != "" { | ||
log.Fatalf("Unable to decode given private key %v", err) | ||
} | ||
|
||
if err = strongbox.RecursiveDecrypt(target, dk); err != nil { | ||
log.Fatalln(err) | ||
} | ||
return | ||
} | ||
|
||
if *flagKey == "" { | ||
log.Fatalf("Must provide a `-key` when using -decrypt") | ||
} | ||
strongbox.DecryptCLI(*flagKey) | ||
return | ||
} | ||
|
||
if *flagRecursive { | ||
log.Println("-recursive flag is only supported with -decrypt") | ||
usage() | ||
} | ||
|
||
if *flagClean != "" { | ||
strongbox.Clean(os.Stdin, os.Stdout, *flagClean) | ||
return | ||
} | ||
if *flagSmudge != "" { | ||
strongbox.Smudge(os.Stdin, os.Stdout, *flagSmudge) | ||
return | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package strongbox | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
|
||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
type KeyRing interface { | ||
Load() error | ||
Save() error | ||
AddKey(name string, keyID []byte, key []byte) | ||
Key(keyID []byte) ([]byte, error) | ||
} | ||
|
||
type FileKeyRing struct { | ||
FileName string | ||
KeyEntries []keyEntry | ||
} | ||
|
||
type keyEntry struct { | ||
Description string `yaml:"description"` | ||
KeyID string `yaml:"key-id"` | ||
Key string `yaml:"key"` | ||
} | ||
|
||
func (kr *FileKeyRing) AddKey(desc string, keyID []byte, key []byte) { | ||
kr.KeyEntries = append(kr.KeyEntries, keyEntry{ | ||
Description: desc, | ||
KeyID: string(Encode(keyID[:])), | ||
Key: string(Encode(key[:])), | ||
}) | ||
} | ||
|
||
func (kr *FileKeyRing) Key(keyID []byte) ([]byte, error) { | ||
b64 := string(Encode(keyID[:])) | ||
|
||
for _, ke := range kr.KeyEntries { | ||
if ke.KeyID == b64 { | ||
dec, err := Decode([]byte(ke.Key)) | ||
if err != nil { | ||
return []byte{}, err | ||
} | ||
if len(dec) != 32 { | ||
return []byte{}, fmt.Errorf("unexpected length of key: %d", len(dec)) | ||
} | ||
return dec, nil | ||
} | ||
} | ||
|
||
return []byte{}, errKeyNotFound | ||
} | ||
|
||
func (kr *FileKeyRing) Load() error { | ||
|
||
fmt.Println("kr.Load") | ||
bytes, err := os.ReadFile(kr.FileName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = yaml.Unmarshal(bytes, kr) | ||
return err | ||
} | ||
|
||
func (kr *FileKeyRing) Save() error { | ||
ser, err := yaml.Marshal(kr) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
path := filepath.Dir(kr.FileName) | ||
_, err = os.Stat(path) | ||
if os.IsNotExist(err) { | ||
err := os.MkdirAll(path, 0700) | ||
if err != nil { | ||
return fmt.Errorf("error creating strongbox home folder: %s", err) | ||
} | ||
} | ||
|
||
return os.WriteFile(kr.FileName, ser, 0600) | ||
} |
Oops, something went wrong.