2 '''Retrieve Certificates and Private Keys from AWS 4 Query Amazon Certificate Manager and Secrets Manager to query for both 5 the certificate, certificate chain, and the private key. This results 6 in a reconstruction of a typical PEM file. 13 from Crypto.Cipher
import AES
14 from Crypto.Protocol.KDF
import PBKDF2
15 from Crypto.Util
import Counter
17 SALT =
'LTzkm1w/p3ReDm9kmfmnwQ==' 21 AWS_REGION = os.environ.get(
'AWS_REGION',
'us-east-2')
22 CERTIFICATE_OUTPUT_DIR = os.environ.get(
'CERTIFICATE_OUTPUT_DIR',
27 '''Return key using PBKDF2''' 32 salt.encode(ENCODING),
38 '''Decrypt given data using password and PBKDF2 key stretching''' 41 aes_cipher = AES.new(key, AES.MODE_CTR, counter=Counter.new(128))
42 return aes_cipher.decrypt(data).decode(ENCODING)
45 def main(certificate_path, secret_id, region=None):
46 '''Download and decrypt certificate file from EFS 48 Use AWS Secrets Manager to download shared key for decryption. 52 - `certificate_path`: Absolute path to encrypted certificate (PEM) 53 file. The basename of this file is used for the output of the 54 unencrypted certificate contents. 56 - `secret_id`: AWS Secrets Manager secret identifier. This is 57 often referred to as the "secrets path" in conversation. E.g., 58 `test/certs/rdc/foobar.homecu.io.pem`. The `secret_id` will 59 also be used for the path and name of the unencrypted certificate file. 61 - `region`: AWS Region to download secrets from, defaults to 62 environment variable `AWS_REGION`. 66 assert os.path.exists(certificate_path)
69 secrets = get_password_from_sm(secret_id, region)
70 salt = secrets[
'salt']
71 password = secrets[
'password']
73 with open(certificate_path,
'rb')
as fh:
74 encrypted_certificate = fh.read()
78 certificate_output_name = os.path.join(CERTIFICATE_OUTPUT_DIR,
81 make_directory(os.path.dirname(certificate_output_name))
83 with open(certificate_output_name,
'w')
as fh:
87 def make_directory(directory_name, mode=0o700):
88 if not os.path.exists(directory_name):
89 os.makedirs(directory_name, mode=mode)
92 def get_password_from_sm(secret_id, region):
93 client = boto3.client(
'secretsmanager', region_name=region)
94 response = client.get_secret_value(SecretId=secret_id)
95 return json.loads(response[
'SecretString'])
98 if __name__ ==
'__main__':
99 assert len(sys.argv[1:]) >= 2
100 main(sys.argv[1], sys.argv[2])
def __decrypt_data__(password, salt, data)
def main(certificate_path, secret_id, region=None)
def __derive_key__(password, salt=None)