(#14) feat(openpgp): increase test coverage
Adds new tests to the `pkg/crypt/openpgp` package to cover error handling and edge cases in the `EncryptPGP` and `DecryptPGP` functions. - Adds a new test file, `encrypt_extra_test.go`, with tests for incorrect passphrases, malformed messages, and signing failures. - Adds a pre-generated, encrypted PGP key to be used in tests, working around a limitation in the `go-crypto` library that prevents programmatic generation of encrypted keys. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
parent
3525cdd4cb
commit
41ed9baa12
2 changed files with 167 additions and 0 deletions
71
pkg/crypt/openpgp/encrypt_extra_test.go
Normal file
71
pkg/crypt/openpgp/encrypt_extra_test.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
package openpgp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestDecryptWithWrongPassphrase checks that DecryptPGP returns an error when the wrong passphrase is used.
|
||||
func TestDecryptWithWrongPassphrase(t *testing.T) {
|
||||
recipientPub, _, cleanup := generateTestKeys(t, "recipient", "") // Unencrypted key for encryption
|
||||
defer cleanup()
|
||||
|
||||
// Use the pre-generated encrypted key for decryption test
|
||||
encryptedPrivKeyPath, cleanup2 := createEncryptedKeyFile(t)
|
||||
defer cleanup2()
|
||||
|
||||
originalMessage := "This message should fail to decrypt."
|
||||
|
||||
var encryptedBuf bytes.Buffer
|
||||
err := EncryptPGP(&encryptedBuf, recipientPub, originalMessage, nil, nil)
|
||||
assert.NoError(t, err, "Encryption failed unexpectedly")
|
||||
encryptedMessage := encryptedBuf.String()
|
||||
|
||||
_, err = DecryptPGP(encryptedPrivKeyPath, encryptedMessage, "wrong-passphrase", nil)
|
||||
assert.Error(t, err, "Decryption was expected to fail with wrong passphrase, but it succeeded.")
|
||||
assert.Contains(t, err.Error(), "failed to read PGP message", "Expected error message about failing to read PGP message")
|
||||
}
|
||||
|
||||
// TestDecryptMalformedMessage checks that DecryptPGP handles non-PGP or malformed input gracefully.
|
||||
func TestDecryptMalformedMessage(t *testing.T) {
|
||||
// Generate an unencrypted key for this test, as we expect failure before key usage.
|
||||
_, recipientPriv, cleanup := generateTestKeys(t, "recipient", "")
|
||||
defer cleanup()
|
||||
|
||||
malformedMessage := "This is not a PGP message."
|
||||
|
||||
// The passphrase here is irrelevant as the key is not encrypted, but we pass one
|
||||
// to satisfy the function signature.
|
||||
_, err := DecryptPGP(recipientPriv, malformedMessage, "any-pass", nil)
|
||||
assert.Error(t, err, "Decryption should fail for a malformed message, but it did not.")
|
||||
assert.Contains(t, err.Error(), "failed to decode armored message", "Expected error about decoding armored message")
|
||||
}
|
||||
|
||||
// TestEncryptWithNonexistentRecipient checks that EncryptPGP fails when the recipient's public key file does not exist.
|
||||
func TestEncryptWithNonexistentRecipient(t *testing.T) {
|
||||
var encryptedBuf bytes.Buffer
|
||||
err := EncryptPGP(&encryptedBuf, "/path/to/nonexistent/key.pub", "message", nil, nil)
|
||||
assert.Error(t, err, "Encryption should fail if recipient key does not exist, but it succeeded.")
|
||||
assert.Contains(t, err.Error(), "failed to open recipient public key file", "Expected file open error for recipient key")
|
||||
}
|
||||
|
||||
// TestEncryptAndSignWithWrongPassphrase checks that signing during encryption fails with an incorrect passphrase.
|
||||
func TestEncryptAndSignWithWrongPassphrase(t *testing.T) {
|
||||
recipientPub, _, rCleanup := generateTestKeys(t, "recipient", "")
|
||||
defer rCleanup()
|
||||
|
||||
// Use the pre-generated encrypted key for the signer
|
||||
signerPriv, sCleanup := createEncryptedKeyFile(t)
|
||||
defer sCleanup()
|
||||
|
||||
originalMessage := "This message should fail to sign."
|
||||
wrongPassphrase := "wrong-signer-pass"
|
||||
|
||||
var encryptedBuf bytes.Buffer
|
||||
err := EncryptPGP(&encryptedBuf, recipientPub, originalMessage, &signerPriv, &wrongPassphrase)
|
||||
|
||||
assert.Error(t, err, "Encryption with signing was expected to fail with a wrong passphrase, but it succeeded.")
|
||||
assert.Contains(t, err.Error(), "failed to decrypt private key", "Expected error about private key decryption failure")
|
||||
}
|
||||
96
pkg/crypt/openpgp/test_util.go
Normal file
96
pkg/crypt/openpgp/test_util.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
package openpgp
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// encryptedPrivateKey is a pre-generated, armored PGP private key, encrypted with the passphrase "test-passphrase".
|
||||
// This key is used in tests where programmatic key generation and encryption is not feasible due to library limitations.
|
||||
const encryptedPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
lQPGBGkD3McBCADPlKJ5MflaxEcDWyMowoNJltHrB9fIsrOY8aaGgm0kzTcWTmi+
|
||||
sdlpLpb4ADWZbtrs/3LbuXAFvhb+Zu+ZN/CO5D5RnZLNd2N+eGCNz/v6p87HCvM6
|
||||
aWxufD+ZJaWvDnWjBt7aO7XydRPx/GyrZ2s8513WYgF83R603bcRv4zdhA7aJHGA
|
||||
IG++PO0jkHKkv0xQ7OmUmjQrYVLV5cG2vQzpQeL81tyfkxb4Rz9gm+Gho5T2v9me
|
||||
Y2ss58/Lny00aneJokBY+x1nGOQKB/Liy7Ub2au9MKKDkitP1F2f2tnp1O/IXqgI
|
||||
tKDKbRz/KipgKbwFrhYBCOl5JjiwzHud/3/HABEBAAH+BwMCZZwQKhGMMAz/Q405
|
||||
dgMVbXRdhSS6jyOCkL5AOKhJWddMEo4/52Sq30pfsT+n0zZjGE7ivpXbJa6ekQYD
|
||||
MFtfueuz2W8cbn+3wP7W2NFnl+UWcw6BlskzPusd7eIqEjCToic1aJLdbs32Q5B/
|
||||
FE7hJrCRzUOeByfEl1e2Uzmy5JJ3Y6bgpDHPhC38uLMZXdpbkboi5R20UmNe0iDo
|
||||
X3v52Wv2Sdb2d8LUrXo7spTGfEDe1f0NTq9NbYMOPSwz912bDmf+nWjjRUPrBh/H
|
||||
w1d66oLtJlQSCt6vLkqoMMViFa8V57XzKrqdpcfu70ydEr7mCmpOgch9OopTM2Dk
|
||||
MlDldUqWt5YCABybmKYOyA2bWX3yYEWi4OiGNhZP1VZwoSiFcsm6/s+p4xHGGWwR
|
||||
+tdakCBqoRaDaMjdVGNA9+mebRJVHcKFsivl4qjT8E55ky8Qq70KhKJ+Vzu9Om3O
|
||||
NiEsrNofdcXiRjVZLejuNbqkO1wDfW0CoNSbFYscOv85AHVk/93w8IvGzvEmOZ3X
|
||||
ILcoIZmIrtoSj4Fu8qQXUD1f+t+hYFV8V+T6YDDmtWIn73VQpHYB7j2UJpq9mZAp
|
||||
CDXxgzm1zgYwZEQ1p/yR8tVeP/hnsE+Dc79iJO72BMzbhuXEkqMWzs9AurdeAaSD
|
||||
p6l0+hr08w9v9d9YEXn8Cjx2p3G6iUA3Rd2vXwuBT2dEtbf+qcskFGqyGo4hOCzW
|
||||
qvbszNMR4yIqtiPipmFq9UCPgBceXb8zJjOylXsf+kKQkBrm4vpMfo+m4xYO8kAp
|
||||
w2gXAs5ozEfkPBYx132QTpYY+dx8lgZ9lD2EgrELfCU0IfCo2C+MksF/v6Ib5rY3
|
||||
eOTNfmsmsnsOr9pfGs65weWxO0VXe39IW4327cSetaviGophWrGsmgRTzs8KBU9j
|
||||
9OBmtXbmGr0LtBlKdWxlcyA8anVsZXNAZXhhbXBsZS5jb20+iQFSBBMBCgA8FiEE
|
||||
lfAo9dBZEKASnLDSjhMM0QOAK2wFAmkD3McDGy8EBQsJCAcCAiICBhUKCQgLAgQW
|
||||
AgMBAh4HAheAAAoJEI4TDNEDgCtsnCoH+wWmcrRgvrO2qHzPROkP9J7xrHnKO7qF
|
||||
+G/1DsCMMkn6fmIgpkCpEYjfZXHIyA6vsOlxDdoxyjpTQUh6lyDlZbrr0klMtgq1
|
||||
9yDyPF3ONJyoLLJeHlLbN+Zgv68R+EkXFI/7w5w8DMc7dq//wibDaBeQ390KjxOc
|
||||
k3lQF+239D0tZ3x9Fdt6JXNrksfkJ8vIQvgANOBFXYIL0KtwqdRbe+L1pKtQXehG
|
||||
7jVgaLgPrC6hqc0dGqLliuxyijA5MgnRUXBX2cNXoUpJBDbgKyuVKzRYQ2X3U4Gz
|
||||
g12Vlt/b19O70j2SfQdBY5sPlJjP6FBfXd299GL4HnNrcVJqwmfPnVCdA8YEaQPc
|
||||
xwEIALEansmoX/FrDCubfde3cXyJ3jOtHXjBgFyWd8J2ad1gvfMbCHteoR86azaR
|
||||
JkUN+zwDpjkYslUy9xVVIL2b4sTXHO6+hw14dQS8mq0+tEKXzGcKuTrno9lU02l3
|
||||
My5ZHY/PB7dfeLC6sGBMXwdbT68wIAy6/guEWRaZWPNJy3l9IrvjxBdMALLAsGTH
|
||||
ol4hKUBRCd0/cAsaIpbq4JOu1os3kRAgfZqeqXSY8G6ioZ/ft5s6nMN4IjUD/tdJ
|
||||
48ZOfoaMRZcSOv8jgoRvYksYNeiqmgYrn17tgCL1z14cjvXrijd8f90dJxeseIEL
|
||||
exETG/Bu0G+lpKU4XC014Vk4l2EAEQEAAf4HAwKcyR3KYk6DBP/wZlQffclC9iAU
|
||||
Oifv5Dxzw1KaloYEir4cBUGYTlcuXcdJV4GXpytX4d+4fTKBO5Kr60I3NYHj3Zs+
|
||||
yK9Vm0ZXjFFMikSxymDdsVaW6PA4WdVpPEam7bqCmApeKT0SSPwVhaBBVALGB55i
|
||||
KFSXyB2DExSzKEuH0sKOLoy+jGqCBVTwUEFVMN7sInXVog1PQGjy472fyI5od/GD
|
||||
F6utVttmthnvVNAHleIeDYzWZD7iOQkl6S7bT/zn4eggTMz/9B5GJ1KkQtjXGfrW
|
||||
9VezVdpUeWLI11WyMxFLBLGQOoVrNWZA4AAPTDReCPT4uGTSnmTVrBSWgOg+2e55
|
||||
aiPak7TXxm3UShqk7A9okgxKkndVsqKYQ2Ry6xfmgdYW68/4xQjqNcPFCVg5YGnk
|
||||
+DbaOS6XVUl6v2QMSNtdONQ3ybhH/ervNV/KLIweg1DRfdi34ixO19QEOEONpenq
|
||||
C2Ap8knptxcBd+M0e6l9vppndrx5R/Y4reg7ZTLt0OX9Gdkwsb9DRLfVFwLmsZ5+
|
||||
hw0e/k5NYkLB3lWw+m+JtKCOpU69U+MY8t4OhvosOFW0Kxm/6tJZKKkpRTfewd1f
|
||||
qbPc4RLE9K0kZW8BDqig6m3flV54jpR7bmPTW1Y/YUn33QXj6wqUec+CSLm349UQ
|
||||
NhwmF7opapbo+XYD8by6xdeOZ/WnTtKKBy3x6uEIRes3zGcGkZ+ROx564i1v1/h3
|
||||
yZ5zrWggWUkeoPzenqWqj1i2QxxgzkxtkqAf/9aKmpp5MNXs25K+ZHFxiwHcCPOe
|
||||
8pVQF0sY61b7EzHoUhq7CkpTYOuvPoHii3m5EAnH+EO66EqSbEemo3FEQQemeQi0
|
||||
EGEiqfh2g1iLSxW54L3Y9Qzh+6B22/ydgccQIL/CxIdofipp4NdoN8iF6gHLm/nS
|
||||
GzKJAmwEGAEKACAWIQSV8Cj10FkQoBKcsNKOEwzRA4ArbAUCaQPcxwIbLgFACRCO
|
||||
EwzRA4ArbMB0IAQZAQoAHRYhBDR5obYfDIFSrsYWVYf4NG7oaR8CBQJpA9zHAAoJ
|
||||
EIf4NG7oaR8CaHYH/1LxfQ+AHKsrYDul0U/h165EPzeX+mhHyBAqVuYIlyBPDMc/
|
||||
sAN83WW7yTXh2VWeE+BQVzdOdz2Mu53Al42+TJVnmc6YrRu2th5vdVvOTPKUFqJ+
|
||||
mbWg8xJPrBoQ2UrZ5oFMgwYUfMvYG94mVxA8K0Uw6LXjmxZ2P816j68FqIPn+o42
|
||||
GoL8muMAWZ4Xd/GJwdtj9R/xJA9DZlNgYH2/I5qK5OMrlDTJ09jivFO1deVhMHbC
|
||||
LH+zdIt5uNoLT6VNANBmbfYn0gX46goeu8jdpusN+8QC7Phq1/L3x8IfHTbmBbKN
|
||||
0NyfETsLs2pmAC+7av8JClw/SxFQppispaBRXm3RfwgAtvzV16+0HT0uQHWulkk+
|
||||
RzulVS8s3BwtjCp1ZPsprJ/AyAxGpU+7iquqe+Voe6Tv5AJ3ongccYTwqFMeElkf
|
||||
JAI+iWfgV1NF2bxm2Wq+nMSL9jrO9aF0unQ9/CI/gKca1656n2ZPSuG4s7mjC1Sl
|
||||
9+GqgZGNR+Isg2dx1yzt7wT0H8SO0fyadp71JMuGI9F5ftUw7jQYvqIuI37an5Mx
|
||||
l3PZ2jSJ4ozNpaAWkNUOQz+o8xCr8qcumXct0FME8H5tiMe3KJn6TJ7eOwfEZ7oD
|
||||
BYR9EUvXQxCicuW/pne/wtn78JvpRxiJxcwVYy+azfunx/Cl8BbxMVLDr0y49lNM
|
||||
hw==
|
||||
=u7WH
|
||||
-----END PGP PRIVATE KEY BLOCK-----`
|
||||
|
||||
// createEncryptedKeyFile creates a temporary file containing a pre-generated, encrypted private key.
|
||||
// It returns the path to the temporary file and a cleanup function to remove the temporary directory.
|
||||
func createEncryptedKeyFile(t *testing.T) (string, func()) {
|
||||
t.Helper()
|
||||
|
||||
tempDir, err := os.MkdirTemp("", "pgp-test-key-*")
|
||||
if err != nil {
|
||||
t.Fatalf("test setup: failed to create temp dir for encrypted key: %v", err)
|
||||
}
|
||||
|
||||
privKeyPath := filepath.Join(tempDir, "encrypted-key.asc")
|
||||
err = os.WriteFile(privKeyPath, []byte(encryptedPrivateKey), 0600)
|
||||
if err != nil {
|
||||
t.Fatalf("test setup: failed to write encrypted key to file: %v", err)
|
||||
}
|
||||
|
||||
cleanup := func() { os.RemoveAll(tempDir) }
|
||||
return privKeyPath, cleanup
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue