Skip to content

Commit ab2fef1

Browse files
authored
Merge pull request #22 from malnick/malnick/use-kms
Use KMS and AES256 with Cipher Block Chaining
2 parents 2391c96 + 317d555 commit ab2fef1

File tree

173 files changed

+36759
-642
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+36759
-642
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
cryptorious_*
2+
release
3+
**/*.test

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM golang:1.10
2+
RUN mkdir -p /go/src/github.com/malnick/cryptorious
3+
WORKDIR /go/src/github.com/malnick/cryptorious
4+
COPY . .

Makefile

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
1-
VERSION := $(shell git describe --tags)
2-
REVISION := $(shell git rev-parse --short HEAD)
1+
.PHONY: all build test clean
2+
THIS_FILE := $(lastword $(MAKEFILE_LIST))
33

4-
BINARY_NAME := cryptorious
4+
os?="darwin"
55

6-
LDFLAGS := -X github.com/malnick/cryptorious/config.VERSION=$(VERSION) -X github.com/malnick/cryptorious/config.REVISION=$(REVISION)
6+
all: clean test build-all
77

8-
FILES := $(shell go list ./... | grep -v vendor)
8+
build-all:
9+
@$(MAKE) -f $(THIS_FILE) build os=linux
10+
@$(MAKE) -f $(THIS_FILE) build os=darwin
11+
@$(MAKE) -f $(THIS_FILE) build os=freebsd
12+
@$(MAKE) -f $(THIS_FILE) build os=windows
913

10-
all: test install
14+
build:
15+
$(call i,building cryptorious for $(os))
16+
@bash -c "scripts/build.sh $(os)"
1117

1218
test:
13-
@echo "+$@"
14-
go test $(FILES) -cover
19+
bash -c "./scripts/test.sh libraries unit"
1520

16-
build:
17-
@echo "+$@"
18-
go build -v -o cryptorious_$(VERSION) -ldflags '$(LDFLAGS)' cryptorious.go
21+
docker-test:
22+
bash -c "./scripts/docker-test.sh"
23+
24+
clean:
25+
rm -rf ./release
26+
27+
# Helper Functions
28+
define i
29+
@tput setaf 6 && echo "[INFO] ==> $(1)"
30+
@tput sgr0
31+
endef
1932

20-
install:
21-
@echo "+$@"
22-
go install -v -ldflags '$(LDFLAGS)' $(FILES)

action/action_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package action
2+
3+
import "github.com/malnick/cryptorious/vault"
4+
5+
var (
6+
expectedUsername = "test-username"
7+
expectedPassword = "test-password"
8+
expectedSecureNote = "test-secure-note"
9+
10+
testVaultSet = vault.Set{
11+
Username: vault.EncryptedEntry{
12+
Ciphertext: "AAAAAAAAAAAAAAAAAAAAALthIXEjHFp2BzZFaM2NzZI=",
13+
Key: "AQIBAHjjCeNKbXvpFm2HyIXoKqPvjyyCDoSbmOkO8uSNKqBm0wE/eSqj6B0NnrczvwcLSlzrAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMrzjLCH0Te9Egi1UsAgEQgDtiaSFOxBU3jpEU1+OBCg0fOMTCin1IO7uWMtPB5Rq+MArZiFDNNIl4V7P7WTGZk5p9nEVXZibi0evnKA==",
14+
IV: "4VvVxXdouSf+ANN+PJ5+tg==",
15+
},
16+
17+
Password: vault.EncryptedEntry{
18+
Ciphertext: "AAAAAAAAAAAAAAAAAAAAAGbAqmydcY5wALQOAz0/m28=",
19+
IV: "fbAcI8NkQbFYWHCtOkCm/Q==",
20+
Key: "AQIBAHjjCeNKbXvpFm2HyIXoKqPvjyyCDoSbmOkO8uSNKqBm0wFX/eO80576OpuMIJRk6ZvlAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMfYDlWalA7BKoXxJEAgEQgDvLKQigz+X1DDNGf0KAhWLcBXKh1DItzyZsPodwArUoU0wAj7tb3MWhQXJN4XcDFLfh4sln0ozr4vxtYA==",
21+
},
22+
23+
SecureNote: vault.EncryptedEntry{
24+
Ciphertext: "AAAAAAAAAAAAAAAAAAAAAD+/u65AUMH576+xZgGZexMmaWcbhxwSkHm0SMt1Xh4Z",
25+
Key: "AQIBAHjjCeNKbXvpFm2HyIXoKqPvjyyCDoSbmOkO8uSNKqBm0wG7UlVRaAOaTAbr9fqcochxAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMCupa+YgNV/EQizynAgEQgDuQ14WOf0gVBLYvjfXMAREMzygPGVfmNxRsx7SExpyHTRl0tQIE//7LztBvIFCjN7PNuDWACQuiHcW1Yw==`",
26+
IV: "DRE6jVdAjY/cIsVsl1/lug==",
27+
},
28+
}
29+
)

action/decrypt.go

Lines changed: 9 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
package action
22

33
import (
4-
"crypto/rand"
5-
"crypto/rsa"
6-
"crypto/x509"
7-
"encoding/pem"
8-
"errors"
94
"fmt"
10-
"io/ioutil"
115

126
log "github.com/Sirupsen/logrus"
137
"github.com/atotto/clipboard"
@@ -16,34 +10,23 @@ import (
1610
"github.com/skratchdot/open-golang/open"
1711
)
1812

13+
// Decrypt accepts a key and cryptorioius config and returns an error if found
14+
// during the decryption process
1915
func Decrypt(key string, c config.Config) error {
20-
priv, err := createPrivateKey(c.PrivateKeyPath)
21-
if err != nil {
22-
return err
23-
}
24-
2516
log.Debug("Retreiving encrypted values from vault...")
26-
username, encryptedPassword, encryptedNote, err := lookUpVault(key, c)
27-
if err != nil {
28-
return err
29-
}
30-
31-
log.Debug("Decrypting password...")
32-
decryptedPassword, err := decryptValue(priv, encryptedPassword)
17+
vs, err := lookUpVaultSet(key, c)
3318
if err != nil {
34-
log.Error(err.Error())
3519
return err
3620
}
3721

38-
log.Debug("Decrypting notes...")
39-
decryptedNote, err := decryptValue(priv, encryptedNote)
22+
clr, err := vs.Decrypt(c.KMSClient)
4023
if err != nil {
4124
return err
4225
}
4326

4427
if c.Clipboard {
4528
log.Info("Copying decrypted password to clipboard!")
46-
if err := clipboard.WriteAll(string(decryptedPassword)); err != nil {
29+
if err := clipboard.WriteAll(clr.Password); err != nil {
4730
return err
4831
}
4932
}
@@ -55,52 +38,17 @@ func Decrypt(key string, c config.Config) error {
5538
}
5639
}
5740

58-
printDecrypted(key, username, string(decryptedPassword), string(decryptedNote), c.DecryptSessionTimeout)
41+
printDecrypted(key, clr.Username, clr.Password, clr.SecureNote, c.DecryptSessionTimeout)
5942

6043
return nil
6144
}
6245

63-
func createPrivateKey(path string) (*rsa.PrivateKey, error) {
64-
privData, err := ioutil.ReadFile(path)
65-
if err != nil {
66-
log.Errorf("%s was not found. Try `generate` first.", path)
67-
return nil, err
68-
}
69-
log.Debug("Private key file: ", path)
70-
71-
// Extract the PEM-encoded data block
72-
block, _ := pem.Decode(privData)
73-
if block == nil {
74-
log.Error("bad key data: %s", "not PEM-encoded")
75-
return nil, err
76-
}
77-
if got, want := block.Type, "RSA PRIVATE KEY"; got != want {
78-
log.Error("unknown key type %q, want %q", got, want)
79-
return nil, err
80-
}
81-
// Decode the RSA private key
82-
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
83-
if err != nil {
84-
log.Error("bad private key: %s", err)
85-
return nil, err
86-
}
87-
return priv, nil
88-
}
89-
90-
func decryptValue(privkey *rsa.PrivateKey, encryptedValue string) ([]byte, error) {
91-
if encryptedValue == "" {
92-
log.Warn("Encrypted value empty, skipping.")
93-
return []byte(""), nil
94-
}
95-
return rsa.DecryptPKCS1v15(rand.Reader, privkey, []byte(encryptedValue))
96-
}
97-
98-
func lookUpVault(key string, c config.Config) (string, string, string, error) {
46+
func lookUpVaultSet(key string, c config.Config) (*vault.Set, error) {
9947
var vault = vault.Vault{}
10048
vault.Path = c.VaultPath
10149
vault.Load()
10250
if _, ok := vault.Data[key]; !ok {
103-
return "", "", "", errors.New(fmt.Sprintf("%s not found in %s", key, vault.Path))
51+
return nil, fmt.Errorf("%s not found in %s", key, vault.Path)
10452
}
105-
return vault.Data[key].Username, vault.Data[key].Password, vault.Data[key].SecureNote, nil
53+
return vault.Data[key], nil
10654
}

action/delete.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/malnick/cryptorious/vault"
66
)
77

8+
// DeleteVaultEntry remove a key and its values from the vault
89
func DeleteVaultEntry(key string, vaultPath string) error {
910
vault, err := vault.New(vaultPath)
1011
if err != nil {

action/delete_test.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ import (
99
"github.com/malnick/cryptorious/vault"
1010
)
1111

12-
var testVaultSet = &vault.VaultSet{
13-
Username: "test",
14-
Password: "notsafe",
15-
}
16-
1712
func TestDeleteVaultEntry(t *testing.T) {
1813
tmpfile, err := ioutil.TempFile("", "testVault")
1914
if err != nil {
@@ -27,7 +22,7 @@ func TestDeleteVaultEntry(t *testing.T) {
2722
t.Error(err)
2823
}
2924

30-
err = tv.Update("testKey", testVaultSet)
25+
err = tv.Add("testKey", &testVaultSet)
3126
if err != nil {
3227
t.Error(err)
3328
}

action/encrypt.go

Lines changed: 45 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,79 @@
11
package action
22

33
import (
4-
"crypto/rand"
5-
"crypto/rsa"
6-
"crypto/x509"
7-
"encoding/pem"
8-
"errors"
94
"fmt"
10-
"io/ioutil"
115

12-
log "github.com/Sirupsen/logrus"
136
"github.com/malnick/cryptorious/config"
147
"github.com/malnick/cryptorious/vault"
8+
gc "github.com/rthornton128/goncurses"
159
)
1610

17-
func Encrypt(key string, vs *vault.VaultSet, c config.Config) error {
18-
pubkey, err := createPublicKey(c.PublicKeyPath)
11+
// Encrypt accepts a key and cryptorious config and returns an error
12+
// if found during the encryption process
13+
func Encrypt(key string, c config.Config) error {
14+
thisVault, err := vault.New(c.VaultPath)
1915
if err != nil {
2016
return err
2117
}
2218

23-
thisVault, err := vault.New(c.VaultPath)
19+
clr, err := cleartextFromCurses()
2420
if err != nil {
2521
return err
2622
}
2723

28-
if len(vs.Password) > 0 {
29-
if encoded, err := encryptValue(pubkey, vs.Password); err == nil {
30-
vs.Password = string(encoded)
31-
} else {
32-
return err
33-
}
34-
}
35-
36-
if len(vs.SecureNote) > 0 {
37-
if encoded, err := encryptValue(pubkey, vs.SecureNote); err == nil {
38-
vs.SecureNote = string(encoded)
39-
} else {
40-
return err
41-
}
42-
}
43-
44-
if len(vs.Username) > 0 {
45-
vs.Username = vs.Username
46-
}
47-
48-
if err := thisVault.Update(key, vs); err != nil {
24+
vs, err := clr.Encrypt(c.KMSClient, c.KMSKeyARN)
25+
if err != nil {
4926
return err
5027
}
5128

52-
return nil
29+
return thisVault.Add(key, vs)
5330
}
5431

55-
func encryptValue(pubkey interface{}, value string) ([]byte, error) {
56-
// Encode the passed in value
57-
log.Debugf("Encoding value: %s", value)
58-
encodedValue, err := rsa.EncryptPKCS1v15(rand.Reader, pubkey.(*rsa.PublicKey), []byte(value))
59-
return encodedValue, err
60-
}
32+
func cleartextFromCurses() (*vault.CleartextEntry, error) {
33+
clr := &vault.CleartextEntry{}
6134

62-
func createPublicKey(path string) (*rsa.PublicKey, error) {
63-
pubData, err := ioutil.ReadFile(path)
35+
username, err := getValuesFor("Username")
6436
if err != nil {
65-
return nil, err
37+
return clr, err
6638
}
67-
log.Debug("using public key file: ", path)
68-
log.Debug(string(pubData))
39+
clr.Username = username
6940

70-
pubkey, err := createPublicKeyBlockCipher(pubData)
41+
password, err := getValuesFor("Password")
7142
if err != nil {
72-
return nil, err
43+
return clr, err
7344
}
45+
clr.Password = password
7446

75-
return pubkey.(*rsa.PublicKey), nil
47+
note, err := getValuesFor("Secure Note")
48+
if err != nil {
49+
return clr, err
50+
}
51+
clr.SecureNote = note
52+
53+
return clr, nil
7654
}
7755

78-
func createPublicKeyBlockCipher(pubData []byte) (interface{}, error) {
79-
// Create block cipher from RSA key
80-
block, _ := pem.Decode(pubData)
81-
// Ensure key is PEM encoded
82-
if block == nil {
83-
return nil, errors.New(fmt.Sprintf("Bad key data: %s, not PEM encoded", string(pubData)))
84-
}
85-
// Ensure this is actually a RSA pub key
86-
if got, want := block.Type, "RSA PUBLIC KEY"; got != want {
87-
return nil, errors.New(fmt.Sprintf("Unknown key type %q, want %q", got, want))
88-
}
89-
// Lastly, create the public key using the new block
90-
pubkey, err := x509.ParsePKIXPublicKey(block.Bytes)
56+
func getValuesFor(key string) (string, error) {
57+
stdscr, _ := gc.Init()
58+
defer gc.End()
59+
60+
prompt := fmt.Sprintf("Enter %s: ", key)
61+
row, col := stdscr.MaxYX()
62+
row, col = (row/2)-1, (col-len(prompt))/2
63+
stdscr.MovePrint(row, col, prompt)
64+
65+
/* GetString will only retieve the specified number of characters. Any
66+
attempts by the user to enter more characters will elicit an audiable
67+
beep */
68+
var value string
69+
value, err := stdscr.GetString(10000)
9170
if err != nil {
92-
return nil, err
71+
return value, err
9372
}
94-
return pubkey, nil
73+
74+
// stdscr.Refresh()
75+
stdscr.GetChar()
76+
stdscr.Erase()
77+
78+
return value, nil
9579
}

0 commit comments

Comments
 (0)