github.com/NBISweden/sda-cli@v0.1.2-0.20240506070033-4c8af88918df/decrypt/decrypt_test.go (about) 1 package decrypt 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8 "runtime" 9 "testing" 10 11 createKey "github.com/NBISweden/sda-cli/create_key" 12 "github.com/NBISweden/sda-cli/encrypt" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/suite" 15 ) 16 17 type DecryptTests struct { 18 suite.Suite 19 tempDir string 20 fileContent []byte 21 testFile *os.File 22 } 23 24 func TestDecryptTestSuite(t *testing.T) { 25 suite.Run(t, new(DecryptTests)) 26 } 27 28 func (suite *DecryptTests) SetupTest() { 29 var err error 30 // Create a temporary directory for our files 31 suite.tempDir, err = os.MkdirTemp(os.TempDir(), "sda-cli-test-") 32 assert.NoError(suite.T(), err) 33 34 // create a test file... 35 suite.testFile, err = os.CreateTemp(suite.tempDir, "testfile-") 36 assert.NoError(suite.T(), err) 37 38 // ... create some content ... 39 suite.fileContent = []byte("This is some fine content right here.") 40 // ... and write the known content to it 41 err = os.WriteFile(suite.testFile.Name(), suite.fileContent, 0600) 42 assert.NoError(suite.T(), err) 43 } 44 45 func (suite *DecryptTests) TearDownTest() { 46 os.Remove(suite.tempDir) 47 } 48 49 func (suite *DecryptTests) TestreadPrivateKeyFile() { 50 testKeyFile := filepath.Join(suite.tempDir, "testkey") 51 // generate key files 52 err := createKey.GenerateKeyPair(testKeyFile, "test") 53 assert.NoError(suite.T(), err) 54 55 // Test reading a non-existent key 56 _, err = readPrivateKeyFile(testKeyFile, "") 57 assert.EqualError(suite.T(), err, fmt.Sprintf("private key file %s doesn't exist", testKeyFile)) 58 59 // Test reading something that isn't a key 60 _, err = readPrivateKeyFile(suite.testFile.Name(), "") 61 assert.ErrorContains(suite.T(), err, fmt.Sprintf("file: %s", suite.testFile.Name())) 62 63 // Test reading a public key 64 _, err = readPrivateKeyFile(fmt.Sprintf("%s.pub.pem", testKeyFile), "") 65 assert.ErrorContains(suite.T(), err, "private key format not supported") 66 67 // Test reading a real key with wrong passphrase 68 _, err = readPrivateKeyFile(fmt.Sprintf("%s.sec.pem", testKeyFile), "wrong") 69 assert.ErrorContains(suite.T(), err, "chacha20poly1305: message authentication failed") 70 71 // Test reading a real key 72 _, err = readPrivateKeyFile(fmt.Sprintf("%s.sec.pem", testKeyFile), "test") 73 assert.NoError(suite.T(), err) 74 } 75 76 func (suite *DecryptTests) Testdecrypt() { 77 testKeyFile := filepath.Join(suite.tempDir, "testkey") 78 encryptedFile := fmt.Sprintf("%s.c4gh", suite.testFile.Name()) 79 decryptedFile := filepath.Join(suite.tempDir, "decrypted_file") 80 81 // generate key files 82 err := createKey.GenerateKeyPair(testKeyFile, "") 83 assert.NoError(suite.T(), err) 84 // and read the private key 85 privateKey, err := readPrivateKeyFile(fmt.Sprintf("%s.sec.pem", testKeyFile), "") 86 assert.NoError(suite.T(), err) 87 88 // Encrypt a file using the encrypt module. change to the test directory to 89 // make sure that the checksum files end up there. 90 cwd, err := os.Getwd() 91 assert.NoError(suite.T(), err) 92 err = os.Chdir(suite.tempDir) 93 assert.NoError(suite.T(), err) 94 encryptArgs := []string{"encrypt", "-key", fmt.Sprintf("%s.pub.pem", testKeyFile), suite.testFile.Name()} 95 err = encrypt.Encrypt(encryptArgs) 96 assert.NoError(suite.T(), err, "encrypting file for testing failed") 97 err = os.Chdir(cwd) 98 assert.NoError(suite.T(), err) 99 100 // Test decrypting a non-existent file 101 msg := "no such file or directory" 102 if runtime.GOOS == "windows" { 103 msg = "The system cannot find the file specified." 104 } 105 err = decryptFile(filepath.Join(suite.tempDir, "non-existent"), "output_file", *privateKey) 106 assert.ErrorContains(suite.T(), err, msg) 107 108 // Test decryption with malformed key 109 fakeKey := [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 110 err = decryptFile(encryptedFile, decryptedFile, fakeKey) 111 assert.EqualError(suite.T(), err, "could not create cryp4gh reader: could not find matching public key header, decryption failed") 112 113 // Test decrypting with the real key 114 err = decryptFile(encryptedFile, decryptedFile, *privateKey) 115 assert.NoError(suite.T(), err) 116 117 // Check content of the decrypted file 118 inFile, err := os.Open(decryptedFile) 119 assert.NoError(suite.T(), err, "unable to open decrypted file") 120 fileData, err := io.ReadAll(inFile) 121 assert.NoError(suite.T(), err, "unable to read decrypted file") 122 assert.Equal(suite.T(), fileData, suite.fileContent) 123 } 124 125 func (suite *DecryptTests) TestDecrypt() { 126 testKeyFile := filepath.Join(suite.tempDir, "testkey") 127 err := createKey.GenerateKeyPair(testKeyFile, "") 128 assert.NoError(suite.T(), err) 129 130 // Encrypt a file using the encrypt module. change to the test directory to 131 // make sure that the checksum files end up there. 132 cwd, err := os.Getwd() 133 assert.NoError(suite.T(), err) 134 err = os.Chdir(suite.tempDir) 135 assert.NoError(suite.T(), err) 136 encryptArgs := []string{"encrypt", "-key", fmt.Sprintf("%s.pub.pem", testKeyFile), suite.testFile.Name()} 137 assert.NoError(suite.T(), encrypt.Encrypt(encryptArgs), "encrypting file for testing failed") 138 assert.NoError(suite.T(), os.Chdir(cwd)) 139 os.Setenv("C4GH_PASSWORD", "") 140 if runtime.GOOS != "windows" { 141 assert.NoError(suite.T(), os.Remove(suite.testFile.Name())) 142 os.Args = []string{"decrypt", "-key", fmt.Sprintf("%s.sec.pem", testKeyFile), fmt.Sprintf("%s.c4gh", suite.testFile.Name())} 143 err = Decrypt(os.Args) 144 assert.NoError(suite.T(), err, "decrypt failed unexpectedly") 145 146 // Check content of the decrypted file 147 inFile, err := os.Open(suite.testFile.Name()) 148 assert.NoError(suite.T(), err, "unable to open decrypted file") 149 fileData, err := io.ReadAll(inFile) 150 assert.NoError(suite.T(), err, "unable to read decrypted file") 151 assert.Equal(suite.T(), string(suite.fileContent), string(fileData)) 152 } 153 154 os.Args = []string{"decrypt", "-key", fmt.Sprintf("%s.sec.pem", testKeyFile), "--force-overwrite", fmt.Sprintf("%s.c4gh", suite.testFile.Name())} 155 err = Decrypt(os.Args) 156 assert.NoError(suite.T(), err, "decrypt failed unexpectedly") 157 os.Args = nil 158 }