From 028d86c0bb1d9fde0528a1bf54ce5ee2c163955f Mon Sep 17 00:00:00 2001 From: kevgliss Date: Fri, 29 Jan 2016 12:45:18 -0800 Subject: [PATCH] Adding a new flag to export plugins 'requires_key' that specifies whether the export plugin needs access to the private key. Defaults to True. --- lemur/certificates/views.py | 17 ++++-- lemur/plugins/bases/export.py | 1 + lemur/plugins/lemur_java/plugin.py | 86 ++++++++++++++++++++++-------- setup.py | 3 +- 4 files changed, 78 insertions(+), 29 deletions(-) diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index 26da8a88..d31f304b 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -15,6 +15,8 @@ from cryptography import x509 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization +from lemur.plugins import plugins + from lemur.auth.service import AuthenticatedResource from lemur.auth.permissions import ViewKeyPermission from lemur.auth.permissions import AuthorityPermission @@ -892,12 +894,17 @@ class CertificateExport(AuthenticatedResource): permission = UpdateCertificatePermission(certificate_id, getattr(role, 'name', None)) - if permission.can(): - extension, passphrase, data = service.export(cert, args['export']['plugin']) - # we take a hit in message size when b64 encoding - return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data)) + plugin = plugins.get(args['export']['plugin']['slug']) + if plugin.requires_key: + if permission.can(): + extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, args['export']['plugin']['pluginOptions']) + else: + return dict(message='You are not authorized to export this certificate'), 403 + else: + extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, args['export']['plugin']['pluginOptions']) - return dict(message='You are not authorized to export this certificate'), 403 + # we take a hit in message size when b64 encoding + return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data)) api.add_resource(CertificatesList, '/certificates', endpoint='certificates') diff --git a/lemur/plugins/bases/export.py b/lemur/plugins/bases/export.py index 2c504615..b93e0aff 100644 --- a/lemur/plugins/bases/export.py +++ b/lemur/plugins/bases/export.py @@ -15,6 +15,7 @@ class ExportPlugin(Plugin): exporters will inherit from. """ type = 'export' + requires_key = True def export(self): raise NotImplemented diff --git a/lemur/plugins/lemur_java/plugin.py b/lemur/plugins/lemur_java/plugin.py index e16384c1..873fbc28 100644 --- a/lemur/plugins/lemur_java/plugin.py +++ b/lemur/plugins/lemur_java/plugin.py @@ -120,10 +120,11 @@ def create_keystore(cert, jks_tmp, key, alias, passphrase): ]) -class JavaExportPlugin(ExportPlugin): - title = 'Java' - slug = 'java-export' - description = 'Attempts to generate a JKS keystore or truststore' +class JavaTruststoreExportPlugin(ExportPlugin): + title = 'Java Truststore (JKS)' + slug = 'java-truststore-jks' + description = 'Attempts to generate a JKS truststore' + requires_key = False version = java.VERSION author = 'Kevin Glisson' @@ -131,11 +132,10 @@ class JavaExportPlugin(ExportPlugin): options = [ { - 'name': 'type', - 'type': 'select', - 'required': True, - 'available': ['Truststore (JKS)', 'Keystore (JKS)'], - 'helpMessage': 'Choose the format you wish to export', + 'name': 'alias', + 'type': 'str', + 'required': False, + 'helpMessage': 'Enter the alias you wish to use for the truststore.', }, { 'name': 'passphrase', @@ -144,6 +144,55 @@ class JavaExportPlugin(ExportPlugin): 'helpMessage': 'If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8.', 'validation': '' }, + ] + + def export(self, body, chain, key, options, **kwargs): + """ + Generates a Java Truststore + + :param key: + :param chain: + :param body: + :param options: + :param kwargs: + """ + + if self.get_option('alias', options): + alias = self.get_option('alias', options) + else: + alias = "blah" + + if self.get_option('passphrase', options): + passphrase = self.get_option('passphrase', options) + else: + passphrase = get_psuedo_random_string() + + with mktemppath() as jks_tmp: + create_truststore(body, chain, jks_tmp, alias, passphrase) + + with open(jks_tmp, 'rb') as f: + raw = f.read() + + return "jks", passphrase, raw + + +class JavaKeystoreExportPlugin(ExportPlugin): + title = 'Java Keystore (JKS)' + slug = 'java-keystore-jks' + description = 'Attempts to generate a JKS keystore' + version = java.VERSION + + author = 'Kevin Glisson' + author_url = 'https://github.com/netflix/lemur' + + options = [ + { + 'name': 'passphrase', + 'type': 'str', + 'required': False, + 'helpMessage': 'If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8.', + 'validation': '' + }, { 'name': 'alias', 'type': 'str', @@ -154,7 +203,7 @@ class JavaExportPlugin(ExportPlugin): def export(self, body, chain, key, options, **kwargs): """ - Generates a Java Keystore or Truststore + Generates a Java Keystore :param key: :param chain: @@ -173,21 +222,12 @@ class JavaExportPlugin(ExportPlugin): else: alias = "blah" - type = self.get_option('type', options) - with mktemppath() as jks_tmp: - if type == 'Truststore (JKS)': - create_truststore(body, chain, jks_tmp, alias, passphrase) + if not key: + raise Exception("Unable to export, no private key found.") - elif type == 'Keystore (JKS)': - if not key: - raise Exception("Unable to export, no private key found.") - - create_truststore(body, chain, jks_tmp, alias, passphrase) - create_keystore(body, jks_tmp, key, alias, passphrase) - - else: - raise Exception("Unable to export, unsupported type: {0}".format(type)) + create_truststore(body, chain, jks_tmp, alias, passphrase) + create_keystore(body, jks_tmp, key, alias, passphrase) with open(jks_tmp, 'rb') as f: raw = f.read() diff --git a/setup.py b/setup.py index 72726cd4..ff405f03 100644 --- a/setup.py +++ b/setup.py @@ -165,7 +165,8 @@ setup( 'aws_destination = lemur.plugins.lemur_aws.plugin:AWSDestinationPlugin', 'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin', 'email_notification = lemur.plugins.lemur_email.plugin:EmailNotificationPlugin', - 'java_export = lemur.plugins.lemur_java.plugin:JavaExportPlugin', + 'java_truststore_export = lemur.plugins.lemur_java.plugin:JavaTruststoreExportPlugin', + 'java_keystore_export = lemur.plugins.lemur_java.plugin:JavaKeystoreExportPlugin', 'openssl_export = lemur.plugins.lemur_openssl.plugin:OpenSSLExportPlugin' ], },