Adding a new flag to export plugins 'requires_key' that specifies whether the export plugin needs access to the private key. Defaults to True.

This commit is contained in:
kevgliss 2016-01-29 12:45:18 -08:00
parent f8b6830013
commit 028d86c0bb
4 changed files with 78 additions and 29 deletions

View File

@ -15,6 +15,8 @@ from cryptography import x509
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
from lemur.plugins import plugins
from lemur.auth.service import AuthenticatedResource from lemur.auth.service import AuthenticatedResource
from lemur.auth.permissions import ViewKeyPermission from lemur.auth.permissions import ViewKeyPermission
from lemur.auth.permissions import AuthorityPermission from lemur.auth.permissions import AuthorityPermission
@ -892,13 +894,18 @@ class CertificateExport(AuthenticatedResource):
permission = UpdateCertificatePermission(certificate_id, getattr(role, 'name', None)) permission = UpdateCertificatePermission(certificate_id, getattr(role, 'name', None))
plugin = plugins.get(args['export']['plugin']['slug'])
if plugin.requires_key:
if permission.can(): if permission.can():
extension, passphrase, data = service.export(cert, args['export']['plugin']) 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'])
# we take a hit in message size when b64 encoding # we take a hit in message size when b64 encoding
return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data)) return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data))
return dict(message='You are not authorized to export this certificate'), 403
api.add_resource(CertificatesList, '/certificates', endpoint='certificates') api.add_resource(CertificatesList, '/certificates', endpoint='certificates')
api.add_resource(Certificates, '/certificates/<int:certificate_id>', endpoint='certificate') api.add_resource(Certificates, '/certificates/<int:certificate_id>', endpoint='certificate')

View File

@ -15,6 +15,7 @@ class ExportPlugin(Plugin):
exporters will inherit from. exporters will inherit from.
""" """
type = 'export' type = 'export'
requires_key = True
def export(self): def export(self):
raise NotImplemented raise NotImplemented

View File

@ -120,10 +120,11 @@ def create_keystore(cert, jks_tmp, key, alias, passphrase):
]) ])
class JavaExportPlugin(ExportPlugin): class JavaTruststoreExportPlugin(ExportPlugin):
title = 'Java' title = 'Java Truststore (JKS)'
slug = 'java-export' slug = 'java-truststore-jks'
description = 'Attempts to generate a JKS keystore or truststore' description = 'Attempts to generate a JKS truststore'
requires_key = False
version = java.VERSION version = java.VERSION
author = 'Kevin Glisson' author = 'Kevin Glisson'
@ -131,11 +132,10 @@ class JavaExportPlugin(ExportPlugin):
options = [ options = [
{ {
'name': 'type', 'name': 'alias',
'type': 'select', 'type': 'str',
'required': True, 'required': False,
'available': ['Truststore (JKS)', 'Keystore (JKS)'], 'helpMessage': 'Enter the alias you wish to use for the truststore.',
'helpMessage': 'Choose the format you wish to export',
}, },
{ {
'name': 'passphrase', '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.', 'helpMessage': 'If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8.',
'validation': '' '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', 'name': 'alias',
'type': 'str', 'type': 'str',
@ -154,7 +203,7 @@ class JavaExportPlugin(ExportPlugin):
def export(self, body, chain, key, options, **kwargs): def export(self, body, chain, key, options, **kwargs):
""" """
Generates a Java Keystore or Truststore Generates a Java Keystore
:param key: :param key:
:param chain: :param chain:
@ -173,22 +222,13 @@ class JavaExportPlugin(ExportPlugin):
else: else:
alias = "blah" alias = "blah"
type = self.get_option('type', options)
with mktemppath() as jks_tmp: with mktemppath() as jks_tmp:
if type == 'Truststore (JKS)':
create_truststore(body, chain, jks_tmp, alias, passphrase)
elif type == 'Keystore (JKS)':
if not key: if not key:
raise Exception("Unable to export, no private key found.") raise Exception("Unable to export, no private key found.")
create_truststore(body, chain, jks_tmp, alias, passphrase) create_truststore(body, chain, jks_tmp, alias, passphrase)
create_keystore(body, jks_tmp, key, alias, passphrase) create_keystore(body, jks_tmp, key, alias, passphrase)
else:
raise Exception("Unable to export, unsupported type: {0}".format(type))
with open(jks_tmp, 'rb') as f: with open(jks_tmp, 'rb') as f:
raw = f.read() raw = f.read()

View File

@ -165,7 +165,8 @@ setup(
'aws_destination = lemur.plugins.lemur_aws.plugin:AWSDestinationPlugin', 'aws_destination = lemur.plugins.lemur_aws.plugin:AWSDestinationPlugin',
'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin', 'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin',
'email_notification = lemur.plugins.lemur_email.plugin:EmailNotificationPlugin', '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' 'openssl_export = lemur.plugins.lemur_openssl.plugin:OpenSSLExportPlugin'
], ],
}, },