Skip to content

Commit

Permalink
feat: add support to generate contract expiry enabled contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
Sashwat-K committed May 6, 2024
1 parent fbf7637 commit b2aa707
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 20 deletions.
49 changes: 42 additions & 7 deletions contract/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,31 +60,66 @@ func HpcrTgz(folderPath string) (string, error) {
}

// HpcrContractSignedEncrypted - function to generate Signed and Encrypted contract
func HpcrContractSignedEncrypted(contract, privateKey, encryptionCertificate string) (string, error) {
var contractMap map[string]interface{}

func HpcrContractSignedEncrypted(contract, encryptionCertificate, privateKey string) (string, error) {
if contract == "" || privateKey == "" {
return "", fmt.Errorf("either contract or private key not parsed")
}

encryptCertificate := gen.FetchEncryptionCertificate(encryptionCertificate)

err := yaml.Unmarshal([]byte(contract), &contractMap)
publicKey, err := enc.GeneratePublicKey(privateKey)
if err != nil {
return "", err
}

workloadData, err := gen.MapToYaml(contractMap["workload"].(map[string]interface{}))
signedEncryptContract, err := EncryptWrapper(contract, encryptCertificate, privateKey, publicKey)
if err != nil {
return "", err
}

encryptedWorkload, _, err := Encrypter(workloadData, encryptCertificate)
return signedEncryptContract, nil
}

// HpcrContractSignedEncryptedContractExpiry - function to generate sign with contract expiry enabled and encrypt contract (with CSR parameters and CSR file)
func HpcrContractSignedEncryptedContractExpiry(contract, encryptionCertificate, privateKey, cacert, caKey, csrDataStr, csrPemData string, expiryDays int) (string, error) {
if contract == "" || privateKey == "" || cacert == "" || caKey == "" {
return "", fmt.Errorf("required parameters missing")
}

if csrPemData == "" && csrDataStr == "" || len(csrPemData) > 0 && len(csrDataStr) > 0 {
return "", fmt.Errorf("the CSR parameters and CSR PEM file are parsed together or both are nil")
}

signingCert, err := enc.CreateSigningCert(privateKey, cacert, caKey, csrDataStr, csrPemData, expiryDays)
if err != nil {
return "", err
}

publicKey, err := enc.GeneratePublicKey(privateKey)
finalContract, err := EncryptWrapper(contract, encryptionCertificate, privateKey, signingCert)
if err != nil {
return "", err
}

return finalContract, nil
}

// EncryptWrapper - wrapper function to sign (with and without contract expiry) and encrypt contract
func EncryptWrapper(contract, encryptionCertificate, privateKey, publicKey string) (string, error) {
var contractMap map[string]interface{}

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
}
Expand Down
160 changes: 147 additions & 13 deletions contract/contract_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package contract

import (
"encoding/json"
"fmt"
"io"
"os"
"testing"

"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"

gen "github.com/Sashwat-K/lib-hpcr/common/general"
)

const (
Expand All @@ -29,8 +27,108 @@ const (
simpleContractPath = "../samples/simple_contract.yaml"

samplePrivateKeyPath = "../samples/encrypt/private.pem"
samplePublicKeyPath = "../samples/encrypt/public.pem"

sampleCePrivateKeyPath = "../samples/contract-expiry/private.pem"
sampleCeCaCertPath = "../samples/contract-expiry/personal_ca.crt"
sampleCeCaKeyPath = "../samples/contract-expiry/personal_ca.pem"
sampleCeCsrPath = "../samples/contract-expiry/csr.pem"
sampleContractExpiryDays = 365
)

var (
sampleCeCSRPems = map[string]interface{}{
"country": "IN",
"state": "Karnataka",
"location": "Bangalore",
"org": "IBM",
"unit": "ISDL",
"domain": "HPVS",
"mail": "[email protected]",
}
)

// common - common function to pull data from files
func common(testType string) (string, string, string, string, string, error) {
simpleContractFile, err := os.Open(simpleContractPath)
if err != nil {
return "", "", "", "", "", err
}
defer simpleContractFile.Close()

contract, err := io.ReadAll(simpleContractFile)
if err != nil {
return "", "", "", "", "", err
}

privateKeyFile, err := os.Open(samplePrivateKeyPath)
if err != nil {
return "", "", "", "", "", err
}
defer privateKeyFile.Close()

privateKey, err := io.ReadAll(privateKeyFile)
if err != nil {
return "", "", "", "", "", err
}

if testType == "TestHpcrContractSignedEncrypted" {
return string(contract), string(privateKey), "", "", "", nil
} else if testType == "TestEncryptWrapper" {
publicKeyFile, err := os.Open(samplePublicKeyPath)
if err != nil {
return "", "", "", "", "", err
}
defer privateKeyFile.Close()

publicKey, err := io.ReadAll(publicKeyFile)
if err != nil {
return "", "", "", "", "", err
}
return string(contract), string(privateKey), string(publicKey), "", "", nil
} else if testType == "TestHpcrContractSignedEncryptedContractExpiryCsrParams" || testType == "TestHpcrContractSignedEncryptedContractExpiryCsrPem" {
cePrivateKeyPath, err := os.Open(sampleCePrivateKeyPath)
if err != nil {
return "", "", "", "", "", err
}
defer cePrivateKeyPath.Close()

cePrivateKey, err := io.ReadAll(cePrivateKeyPath)
if err != nil {
return "", "", "", "", "", err
}

caCertPath, err := os.Open(sampleCeCaCertPath)
if err != nil {
fmt.Println("Error parsing CA certificate - ", err)
return "", "", "", "", "", err
}
defer caCertPath.Close()

caCert, err := io.ReadAll(caCertPath)
if err != nil {
fmt.Println(err)
return "", "", "", "", "", err
}

caKeyPath, err := os.Open(sampleCeCaKeyPath)
if err != nil {
fmt.Println("Error parsing CA certificate - ", err)
return "", "", "", "", "", err
}
defer caCertPath.Close()

caKey, err := io.ReadAll(caKeyPath)
if err != nil {
fmt.Println(err)
return "", "", "", "", "", err
}

return string(contract), string(cePrivateKey), "", string(caCert), string(caKey), err
}
return "", "", "", "", "", err
}

// Testcase to check if TestHpcrText() is able to encode text and generate SHA256
func TestHpcrText(t *testing.T) {
base64, sha256, err := HpcrText(sampleStringData)
Expand Down Expand Up @@ -88,41 +186,77 @@ func TestHpcrTgz(t *testing.T) {

// Testcase to check if HpcrContractSignedEncrypted() is able to generate
func TestHpcrContractSignedEncrypted(t *testing.T) {
var contractMap map[string]interface{}

file, err := os.Open(simpleContractPath)
contract, privateKey, _, _, _, err := common("TestHpcrContractSignedEncrypted")
if err != nil {
fmt.Println(err)
}
defer file.Close()

contract, err := io.ReadAll(file)
result, err := HpcrContractSignedEncrypted(contract, "", privateKey)
if err != nil {
fmt.Println(err)
}

err = yaml.Unmarshal([]byte(contract), &contractMap)
assert.NotEmpty(t, result)
assert.NoError(t, err)
}

// Testcase to check if HpcrContractSignedEncryptedContractExpiry() is able to create signed and encrypted contract with contract expiry enabled with CSR parameters
func TestHpcrContractSignedEncryptedContractExpiryCsrParams(t *testing.T) {
contract, privateKey, _, caCert, caKey, err := common("TestHpcrContractSignedEncryptedContractExpiryCsrParams")
if err != nil {
fmt.Println(err)
}

privateKeyFile, err := os.Open(samplePrivateKeyPath)
csrParams, err := json.Marshal(sampleCeCSRPems)
if err != nil {
fmt.Println(err)
}
defer privateKeyFile.Close()

privateKey, err := io.ReadAll(privateKeyFile)
result, err := HpcrContractSignedEncryptedContractExpiry(contract, "", privateKey, caCert, caKey, string(csrParams), "", sampleContractExpiryDays)
if err != nil {
fmt.Println(err)
}

assert.NotEmpty(t, result)
assert.NoError(t, err)
}

// Testcase to check if HpcrContractSignedEncryptedContractExpiry() is able to create signed and encrypted contract with contract expiry enabled with CSR PEM data
func TestHpcrContractSignedEncryptedContractExpiryCsrPem(t *testing.T) {
contract, privateKey, _, caCert, caKey, err := common("TestHpcrContractSignedEncryptedContractExpiryCsrPem")
if err != nil {
fmt.Println(err)
}

contractStr, err := gen.MapToYaml(contractMap)
csrPemFile, err := os.Open(sampleCeCsrPath)
if err != nil {
fmt.Println("Error parsing CSR - ", err)
}
defer csrPemFile.Close()

csr, err := io.ReadAll(csrPemFile)
if err != nil {
fmt.Println(err)
}

result, err := HpcrContractSignedEncryptedContractExpiry(contract, "", privateKey, caCert, caKey, "", string(csr), sampleContractExpiryDays)
if err != nil {
fmt.Println(err)
}

assert.NotEmpty(t, result)
assert.NoError(t, err)
}

// Testcase to check if EncryptWrapper() is able to sign and encrypt a contract
func TestEncryptWrapper(t *testing.T) {
contract, privateKey, publicKey, _, _, err := common("TestEncryptWrapper")
if err != nil {
fmt.Println(err)
}

result, err := HpcrContractSignedEncrypted(contractStr, string(privateKey), "")
result, err := EncryptWrapper(contract, "", privateKey, publicKey)
if err != nil {
fmt.Println(err)
}
Expand Down

0 comments on commit b2aa707

Please sign in to comment.