diff options
| author | Shulhan <ms@kilabit.info> | 2023-09-20 01:15:55 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-09-20 01:28:24 +0700 |
| commit | a201862eec862f013b65864b6b5c74f5e77374ce (patch) | |
| tree | b98dea9dca49d55ee3a1aad7ab9a9914ceac8069 | |
| parent | 332ca03f703b2b380aa1075e60e3cd1cad938a73 (diff) | |
| download | awwan-a201862eec862f013b65864b6b5c74f5e77374ce.tar.xz | |
all: add method Encrypt to Awwan
The Encrypt method encrypt the file using private key from file
"{{.BaseDir}}/.awwan.key".
The encrypted file output will be on the same file path with ".vault"
extension.
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | awwan.go | 85 | ||||
| -rw-r--r-- | awwan_test.go | 80 | ||||
| -rw-r--r-- | go.mod | 6 | ||||
| -rw-r--r-- | go.sum | 4 | ||||
| -rw-r--r-- | testdata/encrypt-with-passphrase/.awwan.env | 2 | ||||
| -rw-r--r-- | testdata/encrypt-with-passphrase/.awwan.key | 39 | ||||
| -rw-r--r-- | testdata/encrypt-with-passphrase/.ssh/empty | 0 | ||||
| l--------- | testdata/encrypt-without-passphrase/.awwan.env | 1 | ||||
| -rw-r--r-- | testdata/encrypt-without-passphrase/.awwan.key | 38 | ||||
| -rw-r--r-- | testdata/encrypt-without-passphrase/.ssh/empty | 0 | ||||
| l--------- | testdata/encrypt-without-rsa/.awwan.env | 1 | ||||
| -rw-r--r-- | testdata/encrypt-without-rsa/.awwan.key | 8 | ||||
| -rw-r--r-- | testdata/encrypt-without-rsa/.ssh/empty | 0 |
14 files changed, 259 insertions, 7 deletions
@@ -12,3 +12,5 @@ /awwan /cover.html /cover.out +/testdata/encrypt-with-passphrase/.awwan.env.vault +/testdata/encrypt-without-passphrase/.awwan.env.vault @@ -5,16 +5,21 @@ package awwan import ( "bytes" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" "fmt" + "io" "log" "os" "path/filepath" + "git.sr.ht/~shulhan/awwan/internal" + libcrypto "github.com/shuLhan/share/lib/crypto" "github.com/shuLhan/share/lib/http" "github.com/shuLhan/share/lib/memfs" "github.com/shuLhan/share/lib/ssh/config" - - "git.sr.ht/~shulhan/awwan/internal" ) // Version current version of this module (library and program). @@ -36,6 +41,9 @@ const ( defTmpDir = "/tmp" ) +// defFilePrivateKey define the default private key file name. +const defFilePrivateKey = `.awwan.key` + var ( cmdMagicGet = []byte("#get:") cmdMagicPut = []byte("#put:") @@ -56,6 +64,14 @@ type Awwan struct { httpd *http.Server // The HTTP server. memfsBase *memfs.MemFS // The files caches. + // privateKey define the key for encrypt and decrypt command. + privateKey *rsa.PrivateKey + + // termrw define the ReadWriter to prompt and read passphrase for + // privateKey. + // This field should be nil, only used during testing. + termrw io.ReadWriter + bufout bytes.Buffer buferr bytes.Buffer } @@ -87,6 +103,49 @@ func New(baseDir string) (aww *Awwan, err error) { return aww, nil } +// Encrypt the file using private key from file "{{.BaseDir}}/.awwan.key". +// The encrypted file output will be on the same file path with ".vault" +// extension. +func (aww *Awwan) Encrypt(file string) (err error) { + var ( + logp = `Encrypt` + fileVault = file + `.vault` + ) + + if aww.privateKey == nil { + err = aww.loadPrivateKey() + if err != nil { + return fmt.Errorf(`%s: %w`, logp, err) + } + } + + var src []byte + + src, err = os.ReadFile(file) + if err != nil { + return fmt.Errorf(`%s: %w`, logp, err) + } + + var ( + hash = sha256.New() + label = []byte(`awwan`) + + ciphertext []byte + ) + + ciphertext, err = rsa.EncryptOAEP(hash, rand.Reader, &aww.privateKey.PublicKey, src, label) + if err != nil { + return fmt.Errorf(`%s: %w`, logp, err) + } + + err = os.WriteFile(fileVault, ciphertext, 0600) + if err != nil { + return fmt.Errorf(`%s: %w`, logp, err) + } + + return nil +} + // Local execute the script in the local machine using shell. func (aww *Awwan) Local(req *Request) (err error) { if len(req.lineRange.list) == 0 { @@ -325,6 +384,28 @@ func (aww *Awwan) loadSshConfig() (err error) { return nil } +// loadPrivateKey from file "{{.BaseDir}}/.awwan.key". +func (aww *Awwan) loadPrivateKey() (err error) { + var ( + fileKey = filepath.Join(aww.BaseDir, defFilePrivateKey) + + pkey crypto.PrivateKey + ok bool + ) + + pkey, err = libcrypto.LoadPrivateKeyInteractive(aww.termrw, fileKey) + if err != nil { + return err + } + + aww.privateKey, ok = pkey.(*rsa.PrivateKey) + if !ok { + return fmt.Errorf(`the private key type must be RSA, got %T`, pkey) + } + + return nil +} + // lookupBaseDir find the directory that contains ".ssh" directory from // current working directory until "/", as the base working directory of // awwan. diff --git a/awwan_test.go b/awwan_test.go new file mode 100644 index 0000000..a216fbf --- /dev/null +++ b/awwan_test.go @@ -0,0 +1,80 @@ +package awwan + +import ( + "os" + "path/filepath" + "testing" + + "github.com/shuLhan/share/lib/test" + "github.com/shuLhan/share/lib/test/mock" +) + +func TestAwwanEncrypt(t *testing.T) { + type testCase struct { + baseDir string + file string + passphrase string + expError string + } + + var cases = []testCase{{ + baseDir: filepath.Join(`testdata`, `encrypt-with-passphrase`), + file: `.awwan.env`, + passphrase: "s3cret\r", + }, { + baseDir: filepath.Join(`testdata`, `encrypt-with-passphrase`), + file: `.awwan.env`, + passphrase: "invalids3cret\r", + expError: `Encrypt: LoadPrivateKeyInteractive: x509: decryption password incorrect`, + }, { + baseDir: filepath.Join(`testdata`, `encrypt-without-rsa`), + file: `.awwan.env`, + passphrase: "s3cret\r", + expError: `Encrypt: the private key type must be RSA, got *ed25519.PrivateKey`, + }, { + baseDir: filepath.Join(`testdata`, `encrypt-without-passphrase`), + file: `.awwan.env`, + }} + + var ( + mockrw = mock.ReadWriter{} + + c testCase + aww *Awwan + err error + ) + + for _, c = range cases { + var ( + filePlain = filepath.Join(c.baseDir, c.file) + fileVault = filepath.Join(c.baseDir, `.awwan.env.vault`) + ) + + _ = os.Remove(fileVault) + + aww, err = New(c.baseDir) + if err != nil { + t.Fatal(err) + } + + if len(c.passphrase) != 0 { + // Write the passphrase to standard input to be read + // interactively. + mockrw.BufRead.WriteString(c.passphrase) + aww.termrw = &mockrw + } else { + aww.termrw = nil + } + + err = aww.Encrypt(filePlain) + if err != nil { + test.Assert(t, `Encrypt`, c.expError, err.Error()) + continue + } + + _, err = os.Stat(fileVault) + if err != nil { + test.Assert(t, `os.Stat`, c.expError, err.Error()) + } + } +} @@ -8,17 +8,17 @@ go 1.20 require ( git.sr.ht/~shulhan/ciigo v0.10.0 github.com/evanw/esbuild v0.17.10 - github.com/shuLhan/share v0.49.2-0.20230917095357-d3957eb89349 - golang.org/x/crypto v0.13.0 - golang.org/x/term v0.12.0 + github.com/shuLhan/share v0.49.2-0.20230919175205-3b7ac793264a ) require ( git.sr.ht/~shulhan/asciidoctor-go v0.4.1 // indirect github.com/yuin/goldmark v1.5.4 // indirect github.com/yuin/goldmark-meta v1.1.0 // indirect + golang.org/x/crypto v0.13.0 // indirect golang.org/x/net v0.15.0 // indirect golang.org/x/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect ) @@ -4,8 +4,8 @@ git.sr.ht/~shulhan/ciigo v0.10.0 h1:s1SJ3/NzBcbOLmEZ4z1Cx9Vf7ZdDIvm45b7KMCZKzEY= git.sr.ht/~shulhan/ciigo v0.10.0/go.mod h1:cG6av+ywJZZp96F43kmLB2QWjm2hYiahbsbeTX/vlgk= github.com/evanw/esbuild v0.17.10 h1:RMwM8ehohA6RSgWVirjnsZ+u9ttNt0gWfRLYCxUbAoc= github.com/evanw/esbuild v0.17.10/go.mod h1:iINY06rn799hi48UqEnaQvVfZWe6W9bET78LbvN8VWk= -github.com/shuLhan/share v0.49.2-0.20230917095357-d3957eb89349 h1:2KUGziFe7WIWzGvaO9UfC2+5XWvvw096dIc1Rt5tW2g= -github.com/shuLhan/share v0.49.2-0.20230917095357-d3957eb89349/go.mod h1:xgun5BOQHu/CrOu5oGUAtKGlSuKVOEL1O10YhPYCQsc= +github.com/shuLhan/share v0.49.2-0.20230919175205-3b7ac793264a h1:7ohg2TOplcnbhfGiIdkPb1fn3D3Qph0ZDRMOkxwM580= +github.com/shuLhan/share v0.49.2-0.20230919175205-3b7ac793264a/go.mod h1:i5/MNWUy/B+b76J96VTNG8HLE/xZ8mVy+i0oR51y6Jc= github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU= github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= diff --git a/testdata/encrypt-with-passphrase/.awwan.env b/testdata/encrypt-with-passphrase/.awwan.env new file mode 100644 index 0000000..a769b9d --- /dev/null +++ b/testdata/encrypt-with-passphrase/.awwan.env @@ -0,0 +1,2 @@ +[secret] +pass = thisisasecret diff --git a/testdata/encrypt-with-passphrase/.awwan.key b/testdata/encrypt-with-passphrase/.awwan.key new file mode 100644 index 0000000..7ff257d --- /dev/null +++ b/testdata/encrypt-with-passphrase/.awwan.key @@ -0,0 +1,39 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +ovQk9w== +-----END OPENSSH PRIVATE KEY----- diff --git a/testdata/encrypt-with-passphrase/.ssh/empty b/testdata/encrypt-with-passphrase/.ssh/empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/testdata/encrypt-with-passphrase/.ssh/empty diff --git a/testdata/encrypt-without-passphrase/.awwan.env b/testdata/encrypt-without-passphrase/.awwan.env new file mode 120000 index 0000000..21a511f --- /dev/null +++ b/testdata/encrypt-without-passphrase/.awwan.env @@ -0,0 +1 @@ +../encrypt-with-passphrase/.awwan.env
\ No newline at end of file diff --git a/testdata/encrypt-without-passphrase/.awwan.key b/testdata/encrypt-without-passphrase/.awwan.key new file mode 100644 index 0000000..068bb84 --- /dev/null +++ b/testdata/encrypt-without-passphrase/.awwan.key @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +Wp7eVxh5y6ynhzAAAACm1zQGluc3Bpcm8= +-----END OPENSSH PRIVATE KEY----- diff --git a/testdata/encrypt-without-passphrase/.ssh/empty b/testdata/encrypt-without-passphrase/.ssh/empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/testdata/encrypt-without-passphrase/.ssh/empty diff --git a/testdata/encrypt-without-rsa/.awwan.env b/testdata/encrypt-without-rsa/.awwan.env new file mode 120000 index 0000000..21a511f --- /dev/null +++ b/testdata/encrypt-without-rsa/.awwan.env @@ -0,0 +1 @@ +../encrypt-with-passphrase/.awwan.env
\ No newline at end of file diff --git a/testdata/encrypt-without-rsa/.awwan.key b/testdata/encrypt-without-rsa/.awwan.key new file mode 100644 index 0000000..6c39222 --- /dev/null +++ b/testdata/encrypt-without-rsa/.awwan.key @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCU+ACQ9d +uYYESV1IV3sSvpAAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAICkvBCCVBn8YcRz2 +PfpyqUULPqlxtXRMleHcRjMgttZPAAAAkIcYu8n88JwJ2P2OWLK0EX8T03SGf8cGrORozG +Rsgd9BsJx5J9BKDOQgoeylPnoNxs031bnhDzHiDn3AvSuXl7inVgjxGyoiqsavZbv7m+Fh +8hmEaIM0y7Uq0Vl8WFRCeHE5L3ESGfOewP4k2timIb/SD3B/0Zmhff/5bZYKxjB9/s2tb3 +h9RYKhcFzSK22Vnw== +-----END OPENSSH PRIVATE KEY----- diff --git a/testdata/encrypt-without-rsa/.ssh/empty b/testdata/encrypt-without-rsa/.ssh/empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/testdata/encrypt-without-rsa/.ssh/empty |
