From 58bba901a0a35714b1cb7a20cf1b3d21294acd1d Mon Sep 17 00:00:00 2001 From: Sashwat K Date: Fri, 3 May 2024 22:23:37 +0530 Subject: [PATCH] feat: add HpcrContractSignedEncrypted() to encrypt and sign contract --- common/encrypt/encrypt_test.go | 1 + contract/contract.go | 54 ++++++++++++++++++++++++++++++++++ contract/contract_test.go | 53 +++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/common/encrypt/encrypt_test.go b/common/encrypt/encrypt_test.go index e4ce5dd..43bdd13 100644 --- a/common/encrypt/encrypt_test.go +++ b/common/encrypt/encrypt_test.go @@ -72,6 +72,7 @@ func TestGeneratePublicKey(t *testing.T) { } assert.Equal(t, result, string(publicKey)) + assert.NotEmpty(t, err) } // Testcase to check if RandomPasswordGenerator() is able to generate random password diff --git a/contract/contract.go b/contract/contract.go index 5656c3c..5c3cfe3 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -5,6 +5,7 @@ import ( enc "github.com/Sashwat-K/lib-hpcr/common/encrypt" gen "github.com/Sashwat-K/lib-hpcr/common/general" + "gopkg.in/yaml.v3" ) // HpcrText - function to generate base64 data and checksum from string @@ -58,6 +59,59 @@ func HpcrTgz(folderPath string) (string, error) { return tgzBase64, nil } +// HpcrContractSignedEncrypted - function to generate Signed and Encrypted contract +func HpcrContractSignedEncrypted(contract, privateKey, encryptionCertificate string) (string, error) { + var contractMap map[string]interface{} + + if contract == "" || privateKey == "" { + return "", fmt.Errorf("either contract or private key not parsed") + } + + encryptCertificate := gen.FetchEncryptionCertificate(encryptionCertificate) + + err := yaml.Unmarshal([]byte(contract), &contractMap) + if err != nil { + return "", err + } + + workloadData, err := gen.MapToYaml(contractMap["workload"].(map[string]interface{})) + if err != nil { + return "", err + } + + encryptedWorkload, _, err := Encrypter(workloadData, encryptCertificate) + if err != nil { + return "", err + } + + publicKey, err := enc.GeneratePublicKey(privateKey) + if err != nil { + return "", err + } + + updatedEnv, err := gen.KeyValueInjector(contractMap["env"].(map[string]interface{}), "signingKey", gen.EncodeToBase64(publicKey)) + if err != nil { + return "", err + } + + encryptedEnv, _, err := Encrypter(updatedEnv, encryptCertificate) + if err != nil { + return "", err + } + + workloadEnvSignature, err := enc.SignContract(encryptedWorkload, encryptedEnv, privateKey) + if err != nil { + return "", err + } + + finalContract, err := enc.GenFinalSignedContract(encryptedWorkload, encryptedEnv, workloadEnvSignature) + if err != nil { + return "", err + } + + return finalContract, nil +} + // Encrypter - function to generate encrypted hyper protect data from plain string func Encrypter(stringText, encryptionCertificate string) (string, string, error) { encCert := gen.FetchEncryptionCertificate(encryptionCertificate) diff --git a/contract/contract_test.go b/contract/contract_test.go index f5de310..4a5b3bd 100644 --- a/contract/contract_test.go +++ b/contract/contract_test.go @@ -2,9 +2,14 @@ package contract import ( "fmt" + "io" + "os" "testing" "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + + gen "github.com/Sashwat-K/lib-hpcr/common/general" ) const ( @@ -21,6 +26,9 @@ const ( sampleChecksumJson = "f932f8ad556280f232f4b42d55b24ce7d2e909d3195ef60d49e92d49b735de2b" sampleComposeFolderPath = "../samples/tgz" + simpleContractPath = "../samples/simple_contract.yaml" + + samplePrivateKeyPath = "../samples/encrypt/private.pem" ) // Testcase to check if TestHpcrText() is able to encode text and generate SHA256 @@ -78,6 +86,51 @@ func TestHpcrTgz(t *testing.T) { assert.NoError(t, err) } +// Testcase to check if HpcrContractSignedEncrypted() is able to generate +func TestHpcrContractSignedEncrypted(t *testing.T) { + var contractMap map[string]interface{} + + file, err := os.Open(simpleContractPath) + if err != nil { + fmt.Println(err) + } + defer file.Close() + + contract, err := io.ReadAll(file) + if err != nil { + fmt.Println(err) + } + + err = yaml.Unmarshal([]byte(contract), &contractMap) + if err != nil { + fmt.Println(err) + } + + privateKeyFile, err := os.Open(samplePrivateKeyPath) + if err != nil { + fmt.Println(err) + } + defer privateKeyFile.Close() + + privateKey, err := io.ReadAll(privateKeyFile) + if err != nil { + fmt.Println(err) + } + + contractStr, err := gen.MapToYaml(contractMap) + if err != nil { + fmt.Println(err) + } + + result, err := HpcrContractSignedEncrypted(contractStr, string(privateKey), "") + if err != nil { + fmt.Println(err) + } + + assert.NotEmpty(t, result) + assert.NoError(t, err) +} + // Testcase to check if Encrypter() is able to encrypt and generate SHA256 from string func TestEncrypter(t *testing.T) { result, sha256, err := Encrypter(sampleStringJson, "")