Skip to content

Commit

Permalink
utils scripts enhancements (#288)
Browse files Browse the repository at this point in the history
* ignore of vim swap files added

* Client certificate creation variables moved to external JSON template file

* AWS session usage processing added

* Original variable values reverted

* AWS session processing added. File and directory names adapted

* black code style check errors fixed

* black code style check errors fixed. try2

* python venv and pyenv staff added

* certififcate variables moved to dedicated directory

* common generate cert script added

* arg description fixed

* function for aws session opening modified

* code styling fixes

* code styling fixes

* server certificate generation file adapted to use session

* default varfile name fixed

* empty session creation fixed

* empty session creation is server cert generation script fixed

* Certificate chain export description fixed

---------

Co-authored-by: Boris Gorbuntsov <[email protected]>
Co-authored-by: Paul Schwarzenberger <[email protected]>
  • Loading branch information
3 people authored Dec 19, 2024
1 parent cc803bf commit ba06ab7
Show file tree
Hide file tree
Showing 10 changed files with 486 additions and 46 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ modules/terraform-aws-ca-lambda/build/
# Python
__pycache__
.venv
.python-version
**/pyvenv.cfg
**/bin
**/lib
**/lib64

# Terraform
.terraform/
Expand All @@ -22,3 +27,6 @@ terraform.tfvars

# MacOS
.DS_Store

# Vim
**.swp
70 changes: 58 additions & 12 deletions utils/client-cert.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/usr/bin/env python3
import os
import sys
import json
import base64
import argparse
import boto3
import os
from cryptography.hazmat.primitives.serialization import load_der_private_key
from modules.certs.crypto import create_csr_info, crypto_encode_private_key, crypto_tls_cert_signing_request
from modules.certs.kms import kms_generate_key_pair, kms_get_kms_key_id
Expand All @@ -16,11 +18,50 @@
os.makedirs(base_path)


def main(): # pylint:disable=too-many-locals
def create_session(profile):
"""
Creates and returns AWS session using profile
"""

try:
if profile is not None:
session = boto3.session.Session(profile_name=profile)
else:
session = boto3.session.Session()
except Exception as e:
session = {"error": e}
if isinstance(session, dict):
print(f"Error: Unable to open session using profile {profile}. {session['error']}")
sys.exit(1)
else:
print(f"AWS session opened using profile: {profile}")
return session


def parse_arguments():
"""
Read arguments and return arguments dictonary
"""

arguments = {}
parser = argparse.ArgumentParser()
parser.add_argument("--profile", default=None, help="AWS profile described in .aws/config file")
parser.add_argument("--verbose", action="store_true", help="Output of all generated payload data")
arguments = vars(parser.parse_args())

return arguments


def main(): # pylint:disable=too-many-locals,too-many-statements
"""
Create test client certificate for default Serverless CA environment
"""

args = parse_arguments()

# create AWS session
session = create_session(args["profile"])

# set variables
lifetime = 90
common_name = "My Test Certificate"
Expand All @@ -31,14 +72,17 @@ def main(): # pylint:disable=too-many-locals
organizational_unit = "Security Operations"
purposes = ["client_auth"]
output_path_cert_key = f"{base_path}/client-key.pem"
output_path_cert_pem = f"{base_path}/client-cert.pem"
output_path_cert_pem = f"{base_path}/ca-bundle.pem"
output_path_cert_crt = f"{base_path}/client-cert.crt"
output_path_cert_combined = f"{base_path}/client-cert-key.pem"
output_path_cert_combined = f"{base_path}/ca-cert-key-bundle.pem"
key_alias = "serverless-tls-keygen-dev"

# create key pair using symmetric KMS key to provide entropy
key_id = kms_get_kms_key_id(key_alias)
kms_response = kms_generate_key_pair(key_id)
key_id = kms_get_kms_key_id(key_alias, session=session)
if isinstance(key_id, dict):
print(f'Error: {key_id["error"]}')
sys.exit(1)
kms_response = kms_generate_key_pair(key_id, session=session)
private_key = load_der_private_key(kms_response["PrivateKeyPlaintext"], None)

# create CSR
Expand All @@ -58,8 +102,8 @@ def main(): # pylint:disable=too-many-locals
request_payload_bytes = json.dumps(request_payload)

# Invoke TLS certificate Lambda function
lambda_name = get_lambda_name("tls-cert")
client = boto3.client("lambda")
lambda_name = get_lambda_name("tls-cert", session=session)
client = session.client("lambda")
response = client.invoke(
FunctionName=lambda_name,
InvocationType="RequestResponse",
Expand All @@ -71,7 +115,8 @@ def main(): # pylint:disable=too-many-locals
response_payload = response["Payload"]
payload_data = json.load(response_payload)
print(f"Certificate issued for {common_name}")
print(payload_data)
if args["verbose"]:
print(payload_data)

# Extract certificate and private key from response
base64_cert_data = payload_data["Base64Certificate"]
Expand All @@ -87,7 +132,7 @@ def main(): # pylint:disable=too-many-locals
if output_path_cert_pem:
with open(output_path_cert_pem, "w", encoding="utf-8") as f:
f.write(cert_data.decode("utf-8"))
print(f"Certificate written to {output_path_cert_pem}")
print(f"Combined client certificate and CA bundle written to {output_path_cert_pem}")

if output_path_cert_crt:
with open(output_path_cert_crt, "w", encoding="utf-8") as f:
Expand All @@ -98,8 +143,9 @@ def main(): # pylint:disable=too-many-locals
with open(output_path_cert_combined, "w", encoding="utf-8") as f:
f.write(key_data.decode("utf-8"))
f.write(cert_data.decode("utf-8"))

print(f"Certificate and key written to {output_path_cert_combined}")
print(
f"Combined issuing and root certificate bundle and private key written to {output_path_cert_combined}"
)


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit ba06ab7

Please sign in to comment.