Skip to content

Commit dfbec61

Browse files
Merge pull request #67 from avoidik/feature-compressed-key
Compressed CA private key support
2 parents a9ad291 + b685728 commit dfbec61

8 files changed

Lines changed: 274 additions & 12 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ def lambda_handler(event, context):
114114
- Provide your desired ./lambda_configs/ca_key_name.pem prior to Publishing a new Lambda .zip
115115
- Set the permissions of ./lambda_configs/ca_key_name.pem to 444.
116116

117+
You can now provide your private key and/or encrypted private key password via the lambda environment or config file.
118+
In the `[Bless CA]` section, you can set `ca_private_key` instead of the `ca_private_key_file` with a base64 encoded
119+
version of your .pem (e.g. `cat key.pem | base64` ).
120+
121+
Because every config file option is supported in the environment, you can also just set `bless_ca_default_password`
122+
and/or `bless_ca_ca_private_key`. Due to limits on AWS Lambda environment variables, you'll need to compress RSA 4096
123+
private keys, which you can now do by setting `bless_ca_ca_private_key_compression`. For example, set
124+
`bless_ca_ca_private_key_compression = bz2` and `bless_ca_ca_private_key` to the output of
125+
`cat ca-key.pem | bzip2 | base64`.
126+
117127
### BLESS Config File
118128
- Refer to the the [Example BLESS Config File](bless/config/bless_deploy_example.cfg) and its
119129
included documentation.

bless/config/bless_config.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import base64
88
import os
99
import re
10+
import zlib
11+
import bz2
1012

1113
BLESS_OPTIONS_SECTION = 'Bless Options'
1214
CERTIFICATE_VALIDITY_BEFORE_SEC_OPTION = 'certificate_validity_before_seconds'
@@ -36,6 +38,8 @@
3638
BLESS_CA_SECTION = 'Bless CA'
3739
CA_PRIVATE_KEY_FILE_OPTION = 'ca_private_key_file'
3840
CA_PRIVATE_KEY_OPTION = 'ca_private_key'
41+
CA_PRIVATE_KEY_COMPRESSION_OPTION = 'ca_private_key_compression'
42+
CA_PRIVATE_KEY_COMPRESSION_OPTION_DEFAULT = None
3943

4044
REGION_PASSWORD_OPTION_SUFFIX = '_password'
4145

@@ -96,11 +100,15 @@ def __init__(self, aws_region, config_file):
96100
REMOTE_USERNAMES_VALIDATION_OPTION: REMOTE_USERNAMES_VALIDATION_DEFAULT,
97101
VALIDATE_REMOTE_USERNAMES_AGAINST_IAM_GROUPS_OPTION: VALIDATE_REMOTE_USERNAMES_AGAINST_IAM_GROUPS_DEFAULT,
98102
IAM_GROUP_NAME_VALIDATION_FORMAT_OPTION: IAM_GROUP_NAME_VALIDATION_FORMAT_DEFAULT,
99-
REMOTE_USERNAMES_BLACKLIST_OPTION: REMOTE_USERNAMES_BLACKLIST_DEFAULT
103+
REMOTE_USERNAMES_BLACKLIST_OPTION: REMOTE_USERNAMES_BLACKLIST_DEFAULT,
104+
CA_PRIVATE_KEY_COMPRESSION_OPTION: CA_PRIVATE_KEY_COMPRESSION_OPTION_DEFAULT
100105
}
101106
configparser.RawConfigParser.__init__(self, defaults=defaults)
102107
self.read(config_file)
103108

109+
if not self.has_section(BLESS_CA_SECTION):
110+
self.add_section(BLESS_CA_SECTION)
111+
104112
if not self.has_section(BLESS_OPTIONS_SECTION):
105113
self.add_section(BLESS_OPTIONS_SECTION)
106114

@@ -129,14 +137,21 @@ def getkmsauthkeyids(self):
129137
return list(map(str.strip, self.get(KMSAUTH_SECTION, KMSAUTH_KEY_ID_OPTION).split(',')))
130138

131139
def getprivatekey(self):
140+
"""
141+
Get a private key from either a file specified in the config file, or from an environment variable. Env
142+
Vars in Lambda can't contain a 4096 RSA key uncompressed, so compressed keys are also supported.
143+
:return: byte string that contains the private key in PEM format (ascii).
144+
"""
145+
compression = self.get(BLESS_CA_SECTION, CA_PRIVATE_KEY_COMPRESSION_OPTION)
146+
132147
if self.has_option(BLESS_CA_SECTION, CA_PRIVATE_KEY_OPTION):
133-
return base64.b64decode(self.get(BLESS_CA_SECTION, CA_PRIVATE_KEY_OPTION))
148+
return self._decompress(base64.b64decode(self.get(BLESS_CA_SECTION, CA_PRIVATE_KEY_OPTION)), compression)
134149

135150
ca_private_key_file = self.get(BLESS_CA_SECTION, CA_PRIVATE_KEY_FILE_OPTION)
136151

137152
# read the private key .pem
138-
with open(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, ca_private_key_file), 'r') as f:
139-
return f.read().encode('ascii')
153+
with open(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, ca_private_key_file), 'rb') as f:
154+
return self._decompress(f.read(), compression)
140155

141156
def has_option(self, section, option):
142157
"""
@@ -171,3 +186,22 @@ def get(self, section, option, **kwargs):
171186
@staticmethod
172187
def _environment_key(section, option):
173188
return (re.sub('\W+', '_', section) + '_' + re.sub('\W+', '_', option)).lower()
189+
190+
@staticmethod
191+
def _decompress(data, algorithm):
192+
"""
193+
Decompress a byte string based of the provided algorithm.
194+
:param data: byte string
195+
:param algorithm: string with the name of the compression algorithm used
196+
:return: decompressed byte string.
197+
"""
198+
if algorithm is None or algorithm == 'none':
199+
result = data
200+
elif algorithm == 'zlib':
201+
result = zlib.decompress(data)
202+
elif algorithm == 'bz2':
203+
result = bz2.decompress(data)
204+
else:
205+
raise ValueError("Compression {} is not supported.".format(algorithm))
206+
207+
return result
2.63 KB
Binary file not shown.
2.49 KB
Binary file not shown.

tests/aws_lambda/test_bless_lambda.py

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import zlib
23

34
import pytest
45

@@ -230,6 +231,138 @@ def test_basic_local_username_validation_email_remote_usernames_useradd(monkeypa
230231
assert output['certificate'].startswith('ssh-rsa-cert-v01@openssh.com ')
231232

232233

234+
def test_basic_ca_private_key_file_bz2(monkeypatch):
235+
extra_environment_variables = {
236+
'bless_ca_default_password': '<INSERT_DEFAULT_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>',
237+
'bless_ca_ca_private_key_file': 'tests/aws_lambda/only-use-for-unit-tests.pem.bz2',
238+
'bless_ca_ca_private_key_compression': 'bz2',
239+
'bless_options_username_validation': 'email',
240+
'bless_options_remote_usernames_validation': 'useradd',
241+
}
242+
243+
for k, v in extra_environment_variables.items():
244+
monkeypatch.setenv(k, v)
245+
246+
output = lambda_handler(VALID_TEST_REQUEST_USERNAME_VALIDATION_EMAIL_REMOTE_USERNAMES_USERADD, context=Context,
247+
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,
248+
entropy_check=False,
249+
config_file=os.path.join(os.path.dirname(__file__), ''))
250+
assert output['certificate'].startswith('ssh-rsa-cert-v01@openssh.com ')
251+
252+
253+
def test_basic_ca_private_key_env_bz2(monkeypatch):
254+
extra_environment_variables = {
255+
'bless_ca_default_password': '<INSERT_DEFAULT_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>',
256+
'bless_ca_ca_private_key': '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',
257+
'bless_ca_ca_private_key_compression': 'bz2',
258+
'bless_options_username_validation': 'email',
259+
'bless_options_remote_usernames_validation': 'useradd',
260+
}
261+
262+
for k, v in extra_environment_variables.items():
263+
monkeypatch.setenv(k, v)
264+
265+
output = lambda_handler(VALID_TEST_REQUEST_USERNAME_VALIDATION_EMAIL_REMOTE_USERNAMES_USERADD, context=Context,
266+
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,
267+
entropy_check=False,
268+
config_file=os.path.join(os.path.dirname(__file__), ''))
269+
assert output['certificate'].startswith('ssh-rsa-cert-v01@openssh.com ')
270+
271+
272+
def test_basic_ca_private_key_file_zlib(monkeypatch):
273+
extra_environment_variables = {
274+
'bless_ca_default_password': '<INSERT_DEFAULT_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>',
275+
'bless_ca_ca_private_key_file': 'tests/aws_lambda/only-use-for-unit-tests.zlib',
276+
'bless_ca_ca_private_key_compression': 'zlib',
277+
'bless_options_username_validation': 'email',
278+
'bless_options_remote_usernames_validation': 'useradd',
279+
}
280+
281+
for k, v in extra_environment_variables.items():
282+
monkeypatch.setenv(k, v)
283+
284+
output = lambda_handler(VALID_TEST_REQUEST_USERNAME_VALIDATION_EMAIL_REMOTE_USERNAMES_USERADD, context=Context,
285+
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,
286+
entropy_check=False,
287+
config_file=os.path.join(os.path.dirname(__file__), ''))
288+
assert output['certificate'].startswith('ssh-rsa-cert-v01@openssh.com ')
289+
290+
def test_basic_ca_private_key_env_zlib(monkeypatch):
291+
extra_environment_variables = {
292+
'bless_ca_default_password': '<INSERT_DEFAULT_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>',
293+
'bless_ca_ca_private_key': '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',
294+
'bless_ca_ca_private_key_compression': 'zlib',
295+
'bless_options_username_validation': 'email',
296+
'bless_options_remote_usernames_validation': 'useradd',
297+
}
298+
299+
for k, v in extra_environment_variables.items():
300+
monkeypatch.setenv(k, v)
301+
302+
output = lambda_handler(VALID_TEST_REQUEST_USERNAME_VALIDATION_EMAIL_REMOTE_USERNAMES_USERADD, context=Context,
303+
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,
304+
entropy_check=False,
305+
config_file=os.path.join(os.path.dirname(__file__), ''))
306+
assert output['certificate'].startswith('ssh-rsa-cert-v01@openssh.com ')
307+
308+
309+
def test_basic_ca_private_key_file_none_compression(monkeypatch):
310+
extra_environment_variables = {
311+
'bless_ca_default_password': '<INSERT_DEFAULT_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>',
312+
'bless_ca_ca_private_key_file': 'tests/aws_lambda/only-use-for-unit-tests.pem',
313+
'bless_ca_ca_private_key_compression': 'none',
314+
'bless_options_username_validation': 'email',
315+
'bless_options_remote_usernames_validation': 'useradd',
316+
}
317+
318+
for k, v in extra_environment_variables.items():
319+
monkeypatch.setenv(k, v)
320+
321+
output = lambda_handler(VALID_TEST_REQUEST_USERNAME_VALIDATION_EMAIL_REMOTE_USERNAMES_USERADD, context=Context,
322+
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,
323+
entropy_check=False,
324+
config_file=os.path.join(os.path.dirname(__file__), ''))
325+
assert output['certificate'].startswith('ssh-rsa-cert-v01@openssh.com ')
326+
327+
328+
def test_invalid_uncompressed_with_zlib(monkeypatch):
329+
extra_environment_variables = {
330+
'bless_ca_default_password': '<INSERT_DEFAULT_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>',
331+
'bless_ca_ca_private_key_file': 'tests/aws_lambda/only-use-for-unit-tests.pem',
332+
'bless_ca_ca_private_key_compression': 'zlib',
333+
'bless_options_username_validation': 'email',
334+
'bless_options_remote_usernames_validation': 'useradd',
335+
}
336+
337+
for k, v in extra_environment_variables.items():
338+
monkeypatch.setenv(k, v)
339+
340+
with pytest.raises(zlib.error):
341+
lambda_handler(VALID_TEST_REQUEST_USERNAME_VALIDATION_EMAIL_REMOTE_USERNAMES_USERADD, context=Context,
342+
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,
343+
entropy_check=False,
344+
config_file=os.path.join(os.path.dirname(__file__), ''))
345+
346+
347+
def test_invalid_uncompressed_with_bz2(monkeypatch):
348+
extra_environment_variables = {
349+
'bless_ca_default_password': '<INSERT_DEFAULT_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>',
350+
'bless_ca_ca_private_key_file': 'tests/aws_lambda/only-use-for-unit-tests.pem',
351+
'bless_ca_ca_private_key_compression': 'bz2',
352+
'bless_options_username_validation': 'email',
353+
'bless_options_remote_usernames_validation': 'useradd',
354+
}
355+
356+
for k, v in extra_environment_variables.items():
357+
monkeypatch.setenv(k, v)
358+
359+
with pytest.raises(OSError):
360+
lambda_handler(VALID_TEST_REQUEST_USERNAME_VALIDATION_EMAIL_REMOTE_USERNAMES_USERADD, context=Context,
361+
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,
362+
entropy_check=False,
363+
config_file=os.path.join(os.path.dirname(__file__), ''))
364+
365+
233366
def test_invalid_username_request():
234367
output = lambda_handler(INVALID_TEST_REQUEST_USERNAME_INVALID, context=Context,
235368
ca_private_key_password=RSA_CA_PRIVATE_KEY_PASSWORD,

tests/config/full-zlib.cfg

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[Bless Options]
2+
# The default values are sane, these are not.
3+
certificate_validity_after_seconds = 1
4+
certificate_validity_before_seconds = 1
5+
entropy_minimum_bits = 2
6+
random_seed_bytes = 3
7+
logging_level = DEBUG
8+
username_validation = debian
9+
10+
[Bless CA]
11+
us-east-1_password = <INSERT_US-EAST-1_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>
12+
us-west-2_password = <INSERT_US-WEST-2_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>
13+
ca_private_key = <INSERT_YOUR_ENCRYPTED_PEM_FILE_NAME>
14+
ca_private_key_compression = zlib

tests/config/full.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ username_validation = debian
1111
us-east-1_password = <INSERT_US-EAST-1_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>
1212
us-west-2_password = <INSERT_US-WEST-2_KMS_ENCRYPTED_BASE64_ENCODED_PEM_PASSWORD_HERE>
1313
ca_private_key_file = <INSERT_YOUR_ENCRYPTED_PEM_FILE_NAME>
14+
ca_private_key_compression = zlib

0 commit comments

Comments
 (0)