From 853c1621b3c87ee7a4e1d1e91f49b3634f650e72 Mon Sep 17 00:00:00 2001 From: Panos Chatzopoulos Date: Tue, 14 Nov 2023 13:29:34 +0100 Subject: [PATCH] Encrypt fetches pub key from auth Change encrypt module to fetch the public key from auth's endpoint info. Encrypt will now try to find a public key in the following order from: - provided as an argument - lookup in the .sda-cli-session from a previous login - fetch it from auth and store it as crypth4gh.pub --- README.md | 2 +- encrypt/encrypt.go | 40 ++++++++++++++++++++++++++++++++++------ encrypt/encrypt_test.go | 2 +- helpers/helpers.go | 21 +++++++++++++++++---- helpers/helpers_test.go | 4 ++-- 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b5b39b79..3fceb7ee 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ You can login to download the configuration file needed for some of the the tool ```bash ./sda-cli login ``` -where `login_target` is the URL can be the login endpoint for Big Picture (https://login.bp.nbis.se/), Federated EGA (https://login.test.fega.nbis.se/) or Genomic Data Infrastructure (https://login.gdi.nbis.se/) +where `login_target` is the URL can be the login endpoint for Big Picture (https://login.bp.nbis.se/), Federated EGA (https://login.fega.nbis.se/) or Genomic Data Infrastructure (https://login.gdi.nbis.se/) This will open a link for the user where they can go and log in. After the login is complete, a configuration file will be created in the tool's directory with the name of `.sda-cli-session` diff --git a/encrypt/encrypt.go b/encrypt/encrypt.go index c5c36452..b5fcd46c 100644 --- a/encrypt/encrypt.go +++ b/encrypt/encrypt.go @@ -15,7 +15,7 @@ import ( "strings" "github.com/NBISweden/sda-cli/helpers" - + "github.com/NBISweden/sda-cli/login" "github.com/neicnordic/crypt4gh/keys" "github.com/neicnordic/crypt4gh/streaming" log "github.com/sirupsen/logrus" @@ -26,7 +26,12 @@ import ( // Usage text that will be displayed as command line help text when using the // `help encrypt` command var Usage = ` -USAGE: %s encrypt -key (-outdir ) (-continue=true) [file(s)] +USAGE: %s encrypt -key (-target ) (-outdir ) (-continue=true) [file(s)] + +The target can be one of the following: + bp.nbis.se + fega.nbis.se + gdc.nbis.se encrypt: Encrypts files according to the crypt4gh standard used in the @@ -54,6 +59,8 @@ var outDir = Args.String("outdir", "", var continueEncrypt = Args.Bool("continue", false, "Do not exit on file errors but skip and continue.") +var target = Args.String("target", "", "Client target for public key.") + var publicKeyFileList []string func init() { @@ -75,15 +82,36 @@ func Encrypt(args []string) error { return err } - // no key provided, check for one in the session file + var sesKey string if len(publicKeyFileList) == 0 { - - sesKey, err := helpers.GetPublicKey() + // check for public key in .sda-cli-session file from login + sesKey, err = helpers.GetPublicKeyFromSession() if err != nil { - return fmt.Errorf("public key not provided or %v", err) + log.Println("could not read key from previous login,", err) } + } + if len(publicKeyFileList) == 0 && sesKey != "" { publicKeyFileList = append(publicKeyFileList, sesKey) } + if len(publicKeyFileList) == 0 && sesKey == "" && *target != "" { + // fetch info endpoint values + info, err := login.GetAuthInfo(*target) + if err != nil { + return err + } + // create pub file + pubFile, err := helpers.CreatePubFile(info.PublicKey, "crypt4gh_key.pub") + if err != nil { + return err + } + log.Println("fetching public key") + // case 4: no key provided, no key in session file, target provided + publicKeyFileList = append(publicKeyFileList, pubFile) + } + // case 3: no key provided, no key in session file, no target provided + if len(publicKeyFileList) == 0 && sesKey == "" && *target == "" { + return errors.New("no public key could be obtained") + } // Each filename is first read into a helper struct (sliced for combatibility with checkFiles) eachFile := make([]helpers.EncryptionFileSet, 1) diff --git a/encrypt/encrypt_test.go b/encrypt/encrypt_test.go index 2830782a..d15860ab 100644 --- a/encrypt/encrypt_test.go +++ b/encrypt/encrypt_test.go @@ -210,7 +210,7 @@ func (suite *EncryptTests) TestEncryptFunction() { // pub key not given os.Args = []string{"encrypt", suite.fileOk.Name()} err := Encrypt(os.Args) - assert.EqualError(suite.T(), err, "public key not provided or configuration file (.sda-cli-session) not found") + assert.EqualError(suite.T(), err, "no public key could be obtained") // no such pub key file msg := "open somekey: no such file or directory" diff --git a/helpers/helpers.go b/helpers/helpers.go index dc74867d..346d9524 100644 --- a/helpers/helpers.go +++ b/helpers/helpers.go @@ -290,7 +290,8 @@ func GetAuth(path string) (*Config, error) { return nil, errors.New("failed to read the configuration file") } -func GetPublicKey() (string, error) { +// reads the .sda-cli-session file, creates the public key file and returns the name of the file +func GetPublicKeyFromSession() (string, error) { // Check if the ".sda-cli-session" file exists if !FileExists(".sda-cli-session") { return "", errors.New("configuration file (.sda-cli-session) not found") @@ -314,13 +315,25 @@ func GetPublicKey() (string, error) { return "", errors.New("public key not found in the configuration") } + pubFile, err := CreatePubFile(config.PublicKey, "key-from-oidc.pub.pem") + if err != nil { + return "", fmt.Errorf("failed to create public key file: %w", err) + } + + return pubFile, nil + +} + +// Create public key file +func CreatePubFile(publicKey string, filename string) (string, error) { + // Create a fixed-size array to hold the public key data var publicKeyData [32]byte - b := []byte(config.PublicKey) + b := []byte(publicKey) copy(publicKeyData[:], b) // Open or create a file named "key-from-oidc.pub.pem" in write-only mode with file permissions 0600 - pubFile, err := os.OpenFile(filepath.Clean("key-from-oidc.pub.pem"), os.O_WRONLY|os.O_CREATE, 0600) + pubFile, err := os.OpenFile(filepath.Clean(filename), os.O_WRONLY|os.O_CREATE, 0600) if err != nil { return "", fmt.Errorf("failed to open or create the public key file: %w", err) } @@ -338,7 +351,7 @@ func GetPublicKey() (string, error) { } // If everything is successful, return the name of the generated public key file - return "key-from-oidc.pub.pem", nil + return filename, nil } // CheckTokenExpiration is used to determine whether the token is expiring in less than a day diff --git a/helpers/helpers_test.go b/helpers/helpers_test.go index 5d025802..b4e039c4 100644 --- a/helpers/helpers_test.go +++ b/helpers/helpers_test.go @@ -335,7 +335,7 @@ encrypt = False log.Printf("failed to write temp config file, %v", err) } - _, err = GetPublicKey() + _, err = GetPublicKeyFromSession() assert.EqualError(suite.T(), err, "public key not found in the configuration") } @@ -370,7 +370,7 @@ public_key = 27be42445fd9e39c9be39e6b36a55e61e3801fc845f63781a813d3fe9977e17a log.Printf("failed to write temp config file, %v", err) } - _, err = GetPublicKey() + _, err = GetPublicKeyFromSession() assert.NoError(suite.T(), err) if assert.FileExists(suite.T(), "key-from-oidc.pub.pem") {