summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-09-23 16:09:51 +0700
committerShulhan <ms@kilabit.info>2023-09-23 16:09:51 +0700
commitd07b8aa2619b78dd22d093d23da890e8ceba26fb (patch)
tree4d63f8d22c9a3514c1d385f33d6753bd664750a8
parent92de94df48e52864897db0a032b3df33260a2a2a (diff)
downloadawwan-d07b8aa2619b78dd22d093d23da890e8ceba26fb.tar.xz
all: allow empty passphrase when running command
Even thought the private key exist, not every command execution require private key. In case it is required and private key is nil, it will return an error during decryption.
-rw-r--r--awwan.go23
-rw-r--r--awwan_test.go20
2 files changed, 32 insertions, 11 deletions
diff --git a/awwan.go b/awwan.go
index a3fbddc..6230255 100644
--- a/awwan.go
+++ b/awwan.go
@@ -64,6 +64,10 @@ var (
newLine = []byte("\n")
)
+// errPrivateKeyMissing returned when private key file is missing or not
+// loaded when command require loading encrypted file.
+var errPrivateKeyMissing = errors.New(`private key is missing or not loaded`)
+
// Awwan is the service that run script in local or remote.
// Awwan contains cache of sessions and cache of environment files.
type Awwan struct {
@@ -174,7 +178,7 @@ func (aww *Awwan) Encrypt(file string) (fileVault string, err error) {
var logp = `Encrypt`
if aww.privateKey == nil {
- return ``, fmt.Errorf(`%s: missing private key %s`, logp, defFilePrivateKey)
+ return ``, fmt.Errorf(`%s: %w`, logp, errPrivateKeyMissing)
}
var src []byte
@@ -453,7 +457,7 @@ func (aww *Awwan) loadPrivateKey() (err error) {
ok bool
)
- pkey, err = libcrypto.LoadPrivateKeyInteractive(aww.termrw, fileKey)
+ _, err = os.Stat(fileKey)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil
@@ -461,6 +465,19 @@ func (aww *Awwan) loadPrivateKey() (err error) {
return err
}
+ fmt.Printf("--- Loading private key file %q (enter to skip passphrase) ...\n", fileKey)
+
+ pkey, err = libcrypto.LoadPrivateKeyInteractive(aww.termrw, fileKey)
+ if err != nil {
+ if errors.Is(err, libcrypto.ErrEmptyPassphrase) {
+ // Ignore empty passphrase error, in case the
+ // command does not need to decrypt files when
+ // running.
+ return nil
+ }
+ return err
+ }
+
aww.privateKey, ok = pkey.(*rsa.PrivateKey)
if !ok {
return fmt.Errorf(`the private key type must be RSA, got %T`, pkey)
@@ -471,7 +488,7 @@ func (aww *Awwan) loadPrivateKey() (err error) {
func decrypt(pkey *rsa.PrivateKey, cipher []byte) (plain []byte, err error) {
if pkey == nil {
- return nil, fmt.Errorf(`missing private key file %q`, defFilePrivateKey)
+ return nil, errPrivateKeyMissing
}
var (
diff --git a/awwan_test.go b/awwan_test.go
index 4e2a17a..ff67466 100644
--- a/awwan_test.go
+++ b/awwan_test.go
@@ -37,6 +37,10 @@ func TestAwwanDecrypt(t *testing.T) {
fileVault: `.awwan.env.vault`,
passphrase: "news3cret\r",
expError: `Decrypt: DecryptOaep: crypto/rsa: decryption error`,
+ }, {
+ baseDir: filepath.Join(`testdata`, `decrypt-with-passphrase`),
+ fileVault: `.awwan.env.vault`,
+ expError: `Decrypt: private key is missing or not loaded`,
}}
var (
@@ -89,6 +93,10 @@ func TestAwwanEncrypt(t *testing.T) {
file: `.awwan.env`,
passphrase: "s3cret\r",
}, {
+ baseDir: filepath.Join(`testdata`, `encrypt-with-passphrase`),
+ file: `.awwan.env`,
+ expError: `Encrypt: private key is missing or not loaded`,
+ }, {
baseDir: filepath.Join(`testdata`, `encrypt-with-passphrase`),
file: `.awwan.env`,
passphrase: "invalids3cret\r",
@@ -116,14 +124,10 @@ func TestAwwanEncrypt(t *testing.T) {
var aww = Awwan{}
filePlain = filepath.Join(c.baseDir, c.file)
- 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
- }
+ // Write the passphrase to standard input to be read
+ // interactively.
+ mockrw.BufRead.WriteString(c.passphrase)
+ aww.termrw = &mockrw
err = aww.init(c.baseDir)
if err != nil {