Skip to content

Commit

Permalink
Add lib functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
DTLP committed Sep 25, 2023
1 parent 763a355 commit 43ab788
Show file tree
Hide file tree
Showing 12 changed files with 334 additions and 209 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.docs
docs/_index.md
docs/README.md
strongbox
bin
153 changes: 153 additions & 0 deletions cmd/strongbox/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
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.FileKeyRing
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 != "" {
err := strongbox.Diff(*flagDiff)
if err != nil {
log.Fatalf("failed to diff: %v", err)
}
return
}

// Set up keyring file name
home, err := strongbox.DeriveHome()
if err != nil {
log.Fatalf("failed to set up keyring file name: %v", err)
}
kr = strongbox.New(filepath.Join(home, ".strongbox_keyring"))

// if keyring flag is set replace default keyRing
if *flagKeyRing != "" {
kr = strongbox.New(*flagKeyRing)
// verify keyring is valid
// if err := kr.Load(); err != nil {
// log.Fatalf("unable to load keyring file:%s err:%s", *flagKeyRing, err)
// }
// TODO: verify the keyring file ////////////////////////////////////////
}

if *flagGenKey != "" {
err := strongbox.GenKey(kr, *flagGenKey)
if err != nil {
log.Fatalf("failed to generate key: %v", err)
}
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("failed to decode given private key %v", err)
}

if err = strongbox.RecursiveDecrypt(kr, target, dk); err != nil {
log.Fatalln(err)
}
return
}

if *flagKey == "" {
log.Fatalf("Must provide a `-key` when using -decrypt")
}
err := strongbox.DecryptCLI(*flagKey)
if err != nil {
log.Fatalf("failed to decrypt: %v", err)
}
return
}

if *flagRecursive {
log.Println("-recursive flag is only supported with -decrypt")
usage()
}

if *flagClean != "" {
strongbox.Clean(kr, os.Stdin, os.Stdout, *flagClean)
return
}
if *flagSmudge != "" {
strongbox.Smudge(kr, os.Stdin, os.Stdout, *flagSmudge)
return
}
}

10 changes: 10 additions & 0 deletions example/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module main.go

go 1.19

require github.com/uw-labs/strongbox/internal/strongbox v1.1.0

require (
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
26 changes: 26 additions & 0 deletions example/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY=
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115/go.mod h1:LadVJg0XuawGk+8L1rYnIED8451UyNxEMdTWCEt5kmU=
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd h1:9GCSedGjMcLZCrusBZuo4tyKLpKUPenUUqi34AkuFmA=
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd/go.mod h1:TlmyIZDpGmwRoTWiakdr+HA1Tukze6C6XbRVidYq02M=
github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff h1:2xRHTvkpJ5zJmglXLRqHiZQNjUoOkhUyhTAhEQvPAWw=
github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff/go.mod h1:gJWba/XXGl0UoOmBQKRWCJdHrr3nE0T65t6ioaj3mLI=
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 h1:BMb8s3ENQLt5ulwVIHVDWFHp8eIXmbfSExkvdn9qMXI=
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11/go.mod h1:+DBdDyfoO2McrOyDemRBq0q9CMEByef7sYl7JH5Q3BI=
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb h1:uSWBjJdMf47kQlXMwWEfmc864bA1wAC+Kl3ApryuG9Y=
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb/go.mod h1:ivcmUvxXWjb27NsPEaiYK7AidlZXS7oQ5PowUS9z3I4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/uw-labs/strongbox v1.1.0 h1:gIFhB+YFkY4wbD6ZU4/nZI26d1O6/TnSPg2ADJTV8Z4=
github.com/uw-labs/strongbox v1.1.0/go.mod h1:MeDTE5Nj3SAPmhZXuqju0KcZWJW3D1HPmU14buyWgqU=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
34 changes: 34 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"log"
"os"

"github.com/uw-labs/strongbox/strongbox"
)

var (
keyPath = "" // Path to strongbox key
targetPath = "" // Path to encrypted file or directory containing encrypted files
)

func main() {
key, err := os.ReadFile(keyPath)
if err != nil {
log.Fatalf("failed to read key file: %v\n", err)
return
}

keyBytes := []byte(key) // Convert key string into byte slice

// Decode the key
dk, err := strongbox.Decode([]byte(keyBytes))
if err != nil {
log.Fatalf("failed to decode given private key %v", err)
}

// Decrypt file(s) at the path provided
if err := strongbox.RecursiveDecrypt(nil, targetPath, dk); err != nil {
log.Fatalln(err)
}
}
18 changes: 10 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
module github.com/uw-labs/strongbox

go 1.21
go 1.19

require (
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd // indirect
github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff // indirect
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 // indirect
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb // indirect
github.com/stretchr/testify v1.7.0
golang.org/x/net v0.7.0 // indirect
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd // indirect
github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff // indirect
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 // indirect
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0 // indirect
golang.org/x/net v0.15.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
22 changes: 16 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY=
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115/go.mod h1:LadVJg0XuawGk+8L1rYnIED8451UyNxEMdTWCEt5kmU=
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd h1:9GCSedGjMcLZCrusBZuo4tyKLpKUPenUUqi34AkuFmA=
Expand All @@ -10,17 +12,25 @@ github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 h1:BMb8s3ENQLt5ul
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11/go.mod h1:+DBdDyfoO2McrOyDemRBq0q9CMEByef7sYl7JH5Q3BI=
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb h1:uSWBjJdMf47kQlXMwWEfmc864bA1wAC+Kl3ApryuG9Y=
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb/go.mod h1:ivcmUvxXWjb27NsPEaiYK7AidlZXS7oQ5PowUS9z3I4=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion integration_tests/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.19-alpine
FROM golang:1.21-alpine

RUN apk --no-cache add git

Expand Down
4 changes: 2 additions & 2 deletions integration_tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

PATH=$PATH:$GOPATH/bin

go get -t .
go install
go get -t ./cmd/strongbox/
go install ./cmd/strongbox/

go get -t ./integration_tests/
go test -v -tags=integration ./integration_tests/
32 changes: 18 additions & 14 deletions keyring.go → strongbox/keyring.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package strongbox

import (
"fmt"
Expand All @@ -10,13 +10,13 @@ import (
)

type keyRing interface {
Load() error
Save() error
AddKey(name string, keyID []byte, key []byte)
Key(keyID []byte) ([]byte, error)
load() error
save() error
addKey(name string, keyID []byte, key []byte)
key(keyID []byte) ([]byte, error)
}

type fileKeyRing struct {
type FileKeyRing struct {
fileName string
KeyEntries []keyEntry
}
Expand All @@ -27,20 +27,24 @@ type keyEntry struct {
Key string `yaml:"key"`
}

func (kr *fileKeyRing) AddKey(desc string, keyID []byte, key []byte) {
func New(path string) (*FileKeyRing) {
return &FileKeyRing{fileName : path}
}

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[:])),
KeyID: string(Encode(keyID[:])),
Key: string(Encode(key[:])),
})
}

func (kr *fileKeyRing) Key(keyID []byte) ([]byte, error) {
b64 := string(encode(keyID[:]))
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))
dec, err := Decode([]byte(ke.Key))
if err != nil {
return []byte{}, err
}
Expand All @@ -54,7 +58,7 @@ func (kr *fileKeyRing) Key(keyID []byte) ([]byte, error) {
return []byte{}, errKeyNotFound
}

func (kr *fileKeyRing) Load() error {
func (kr *FileKeyRing) load() error {

bytes, err := os.ReadFile(kr.fileName)
if err != nil {
Expand All @@ -65,7 +69,7 @@ func (kr *fileKeyRing) Load() error {
return err
}

func (kr *fileKeyRing) Save() error {
func (kr *FileKeyRing) save() error {
ser, err := yaml.Marshal(kr)
if err != nil {
log.Fatal(err)
Expand Down
Loading

0 comments on commit 43ab788

Please sign in to comment.