Skip to content

Commit

Permalink
Merge branch 'main' into feature/config-before-command
Browse files Browse the repository at this point in the history
  • Loading branch information
pahatz authored Nov 21, 2024
2 parents 9f0ef6d + 053c7be commit 42d0763
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
run: go test -v -coverprofile=coverage -covermode=atomic ./...

- name: Codecov
uses: codecov/codecov-action@v4.6.0
uses: codecov/codecov-action@v5.0.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage
Expand Down
53 changes: 27 additions & 26 deletions encrypt/encrypt.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package encrypt

import (
"bytes"
"crypto/md5"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"errors"
"flag"
Expand Down Expand Up @@ -69,43 +71,52 @@ func init() {
// Encrypt takes a set of arguments, parses them, and attempts to encrypt the
// given data files with the given public key file
func Encrypt(args []string) error {

publicKeyFileList = nil
var pubKeyList [][32]byte
// Call ParseArgs to take care of all the flag parsing
err := helpers.ParseArgs(args, Args)
if err != nil {
return err
}

if publicKeyFileList != nil && *target != "" {
switch {
case publicKeyFileList != nil && *target != "":
return errors.New("only one of -key or -target can be used")
}

if *target != "" {
case *target != "":
// fetch info endpoint values
log.Println("fetching public key")
info, err := login.GetAuthInfo(*target)
if err != nil {
return err
}
// create pub file
pubKeyFile, err := helpers.CreatePubFile(info.PublicKey, "crypt4gh_key.pub")

data, err := base64.StdEncoding.DecodeString(info.PublicKey)
if err != nil {
return err
}
// no key provided, no key in session file, target provided
publicKeyFileList = append(publicKeyFileList, pubKeyFile)
}
// no key provided, no key in session file, no target provided
if publicKeyFileList == nil && *target == "" {

pubkey, err := keys.ReadPublicKey(bytes.NewReader(data))
if err != nil {
return err
}

pubKeyList = append(pubKeyList, pubkey)
case publicKeyFileList == nil:
// check for public key in .sda-cli-session file from login
pubKey, err := helpers.GetPublicKeyFromSession()
if err != nil {
return err
}
// key from session file found
if len(publicKeyFileList) == 0 && pubKey != "" {
publicKeyFileList = append(publicKeyFileList, pubKey)

if pubKey == "" {
return errors.New("no public key supplied")
}

publicKeyFileList = append(publicKeyFileList, pubKey)
default:
// Read the public key(s) to be used for encryption. The matching private key will be able to decrypt the file.
pubKeyList, err = createPubKeyList(publicKeyFileList, newKeySpecs())
if err != nil {
return err
}
}

Expand Down Expand Up @@ -160,16 +171,6 @@ func Encrypt(args []string) error {

log.Infof("Ready to encrypt %d file(s)", len(files))

// Initialize a c4gh public key specs instance
c4ghKeySpecs := newKeySpecs()

// Read the public key(s) to be used for encryption. The matching private
// key will be able to decrypt the file.
pubKeyList, err := createPubKeyList(publicKeyFileList, c4ghKeySpecs)
if err != nil {
return err
}

// Generate a random private key to encrypt the data
privateKey, err := generatePrivateKey()
if err != nil {
Expand Down
53 changes: 47 additions & 6 deletions encrypt/encrypt_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package encrypt

import (
"encoding/base64"
"encoding/json"
"fmt"
"log"
"net/http"
"net/http/httptest"
"os"
"runtime"
"testing"

"github.com/NBISweden/sda-cli/decrypt"
"github.com/NBISweden/sda-cli/helpers"
"github.com/NBISweden/sda-cli/login"
"github.com/neicnordic/crypt4gh/keys"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -107,12 +113,11 @@ func (suite *EncryptTests) SetupTest() {
}

func (suite *EncryptTests) TearDownTest() {
os.Remove(suite.publicKey.Name())
os.Remove(suite.privateKey.Name())
os.Remove(suite.multiPublicKey.Name())
os.Remove(suite.fileOk.Name())
os.Remove(suite.encryptedFile.Name())
os.Remove(suite.tempDir)
os.Remove("checksum_encrypted.md5")
os.Remove("checksum_encrypted.sha256")
os.Remove("checksum_unencrypted.md5")
os.Remove("checksum_unencrypted.sha256")
os.RemoveAll(suite.tempDir)
}

func (suite *EncryptTests) TestcheckFiles() {
Expand Down Expand Up @@ -221,3 +226,39 @@ func (suite *EncryptTests) TestEncryptFunction() {
err = Encrypt(os.Args)
assert.EqualError(suite.T(), err, msg)
}

func (suite *EncryptTests) TestPubKeyFromInfo() {
publicKeyFileList = nil
keyData, err := os.ReadFile(suite.publicKey.Name())
if err != nil {
suite.FailNow("failed to read public key from disk")
}

infoData := login.AuthInfo{
PublicKey: base64.StdEncoding.EncodeToString(keyData),
}
responseData, err := json.Marshal(infoData)
if err != nil {
suite.FailNow("failed to marshal JSON response")
}

mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write(responseData)
}))
defer mockServer.Close()

os.Args = []string{"encrypt", "-target", mockServer.URL, suite.fileOk.Name()}
assert.NoError(suite.T(), Encrypt(os.Args), "Encrypt from info failed unexpectedly")

os.Setenv("C4GH_PASSWORD", "")
if runtime.GOOS != "windows" {
// verify that the file can be decrypted
os.Remove(suite.fileOk.Name())
os.Args = []string{"decrypt", "-key", suite.privateKey.Name(), fmt.Sprintf("%s.c4gh", suite.fileOk.Name())}
assert.NoError(suite.T(), decrypt.Decrypt(os.Args), "decrypting encrypted file failed unexpectedly")
}

os.Args = []string{"decrypt", "-key", suite.privateKey.Name(), "--force-overwrite", fmt.Sprintf("%s.c4gh", suite.fileOk.Name())}
assert.NoError(suite.T(), decrypt.Decrypt(os.Args), "decrypting encrypted file failed unexpectedly")
}

0 comments on commit 42d0763

Please sign in to comment.