Skip to content

Commit

Permalink
feat: add share data with partner integration test (GoogleCloudPlatfo…
Browse files Browse the repository at this point in the history
  • Loading branch information
romanini-ciandt authored Jun 19, 2024
1 parent 22e535f commit 995db3b
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* The resources in this file provide a usage example of
* Cloud KMS-based encryption and decryption, using sample python scripts.
*/

resource "null_resource" "install_python_deps" {

provisioner "local-exec" {
command = <<EOF
python -m venv ./venv &&
. ./venv/bin/activate &&
pip install -r ../../share-encrypted-data-with-partners/examples/python/requirements.txt
EOF
}
}

resource "null_resource" "encrypt_using_python_example" {

provisioner "local-exec" {
command = <<EOF
./venv/bin/python ../../share-encrypted-data-with-partners/examples/python/encrypt.py \
--data_encryption_key_path ./testing_only_dek.bin.index \
--data "a secret message to be shared" \
--aad "pre-determined authenticated but unencrypted data" \
--json > test.json
EOF
}

depends_on = [null_resource.install_python_deps]
}

resource "null_resource" "decrypt_using_python_example" {

provisioner "local-exec" {
command = <<EOF
./venv/bin/python ../../share-encrypted-data-with-partners/examples/python/decrypt.py \
--gcp_project ${var.project_id} \
--gcp_location us-central1 \
--gcp_keyring ${module.consumer_bootstrap.keyring} \
--gcp_key ${module.consumer_bootstrap.key} \
--iv "" --aad "" --ciphertext "" \
--json_file "./test.json" > decrypted_text.txt
EOF
}

depends_on = [module.consumer_key_import, null_resource.encrypt_using_python_example, null_resource.install_python_deps]
}
16 changes: 13 additions & 3 deletions share-encrypted-data-with-partners/examples/python/decrypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# limitations under the License.

import argparse
import json
from google.cloud import kms_v1
from base64 import b64decode

Expand All @@ -34,14 +35,23 @@
parser.add_argument("--gcp_keyring", required=True, help="GCP KMS Keyring")
parser.add_argument("--gcp_key", required=True, help="GCP Key")
parser.add_argument("--gcp_key_version", help="GCP Key Version", default="1")
parser.add_argument(
"--json_file", required=False,
help="To pass the inputs as JSON", default=False,
)

# Parse the arguments
args = parser.parse_args()
json_file = args.json_file

if json_file:
with open(json_file, "r") as f:
data = json.load(f)

# Access the parameters and convert what is needed
ciphertext = b64decode(args.ciphertext)
iv = b64decode(args.iv)
aad = str(args.aad).encode()
ciphertext = b64decode(args.ciphertext) or b64decode(data['ciphertext'])
iv = b64decode(args.iv) or b64decode(data['iv'])
aad = str(args.aad).encode() or str(data['aad']).encode()

# Create a client
client = kms_v1.KeyManagementServiceClient()
Expand Down
28 changes: 23 additions & 5 deletions share-encrypted-data-with-partners/examples/python/encrypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import argparse
import json
from base64 import b64encode

# Define the argument parser
Expand All @@ -30,24 +31,41 @@
parser.add_argument(
"--aad", required=True, help="Additional Authenticated Data"
)
parser.add_argument(
"--json", required=False, action="store_true",
help="Format output as JSON", default=False,
)

# Parse the arguments
args = parser.parse_args()

# Access the parameters
data_encryption_key_path = args.data_encryption_key_path
data = str(args.data).encode()
aad = str(args.aad).encode()
aad = str(args.aad)

# Reading key bytes
key = open(data_encryption_key_path, "rb").read()
aesgcm = AESGCM(key)
nonce = os.urandom(12)

# Encrypting data with key bytes
ciphertext = aesgcm.encrypt(nonce, data, aad)
ciphertext = aesgcm.encrypt(nonce, data, aad.encode())

# Printing the outputs needed for decrypt process
print(f"Ciphertext base 64: {b64encode(ciphertext)}")
print(f"Generated IV base64 for encryption: {b64encode(nonce)}")
print(f"Additional Authenticated Data (AAD): {aad}")
ciphertext = b64encode(ciphertext)
nonce = b64encode(nonce)

if bool(args.json):
print(json.dumps(
dict(
ciphertext=ciphertext.decode("utf-8"),
iv=nonce.decode("utf-8"),
aad=aad,
)
)
)
else:
print(f"Ciphertext base 64: {ciphertext}")
print(f"Generated IV base64 for encryption: {nonce}")
print(f"Additional Authenticated Data (AAD): {aad}")
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package share_encrypted_data_with_partner

import (
"os"
"testing"

"github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft"
"github.com/stretchr/testify/assert"
)

func TestShareEncryptedDataModule(t *testing.T) {
cryptT := tft.NewTFBlueprintTest(t)
cryptT.DefineVerify(func(assert *assert.Assertions) {
cryptT.DefaultVerify(assert)

filePath := "../../../examples/share_encrypted_data_with_partners/decrypted_text.txt"
data, err := os.ReadFile(filePath)

assert.Contains(string(data), "plaintext: \"a secret message to be shared\"", "Expected decrypted plaintext message not found!")
assert.Nil(err)
})
cryptT.Test()
}

0 comments on commit 995db3b

Please sign in to comment.