diff options
| author | Shulhan <ms@kilabit.info> | 2023-09-23 16:09:51 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-09-23 16:09:51 +0700 |
| commit | d07b8aa2619b78dd22d093d23da890e8ceba26fb (patch) | |
| tree | 4d63f8d22c9a3514c1d385f33d6753bd664750a8 | |
| parent | 92de94df48e52864897db0a032b3df33260a2a2a (diff) | |
| download | awwan-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.go | 23 | ||||
| -rw-r--r-- | awwan_test.go | 20 |
2 files changed, 32 insertions, 11 deletions
@@ -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 { |
