Implement a CFSSL issuer plugin (#452)

* Implement CFSSL issuer plugin

Implement a Lemur plugin for generating certificates from the open
source certificate authority CFSSL
(https://github.com/cloudflare/cfssl). The plugin interacts with CFSSL
through the CFSSL REST API. The CFSSL configuration is defined in the
lemur.conf.py property file using property names prefixed with "CFSSL_".

* Update documentation to include CFSSL plugin
This commit is contained in:
Charles Hendrie 2016-10-22 02:52:18 -05:00 committed by kevgliss
parent a8f44944b1
commit cd9c112218
8 changed files with 129 additions and 1 deletions

View File

@ -361,6 +361,26 @@ for those plugins.
This is the root to be used for your CA chain This is the root to be used for your CA chain
CFSSL Issuer Plugin
^^^^^^^^^^^^^^^^^^^
The following configuration properties are required to use the the CFSSL issuer plugin.
.. data:: CFSSL_URL
:noindex:
This is the URL for the CFSSL API
.. data:: CFSSL_ROOT
:noindex:
This is the root to be used for your CA chain
.. data:: CFSSL_INTERMEDIATE
:noindex:
This is the intermediate to be used for your CA chain
AWS Source/Destination Plugin AWS Source/Destination Plugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -836,6 +856,17 @@ Openssl
Leverages Openssl to support additional export formats (pkcs12) Leverages Openssl to support additional export formats (pkcs12)
CFSSL
-----
:Authors:
Charles Hendrie <chad.hendrie@thomsonreuters.com>
:Type:
Issuer
:Description:
Basic support for generating certificates from the private certificate authority CFSSL
3rd Party Plugins 3rd Party Plugins
================= =================
@ -886,4 +917,3 @@ These permissions are applied to the user upon login and refreshed on every requ
.. seealso:: .. seealso::
`Flask-Principal <https://pythonhosted.org/Flask-Principal>`_ `Flask-Principal <https://pythonhosted.org/Flask-Principal>`_

View File

@ -0,0 +1,20 @@
lemur_cfssl Package
===================
:mod:`lemur_cfssl` Package
--------------------------
.. automodule:: lemur.plugins.lemur_cfssl
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`plugin` Module
--------------------
.. automodule:: lemur.plugins.lemur_cfssl.plugin
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -27,5 +27,6 @@ Subpackages
lemur.plugins.base lemur.plugins.base
lemur.plugins.bases lemur.plugins.bases
lemur.plugins.lemur_aws lemur.plugins.lemur_aws
lemur.plugins.lemur_cfssl
lemur.plugins.lemur_email lemur.plugins.lemur_email
lemur.plugins.lemur_verisign lemur.plugins.lemur_verisign

View File

@ -0,0 +1,5 @@
try:
VERSION = __import__('pkg_resources') \
.get_distribution(__name__).version
except Exception as e:
VERSION = 'unknown'

View File

@ -0,0 +1,64 @@
"""
.. module: lemur.plugins.lemur_cfssl.plugin
:platform: Unix
:synopsis: This module is responsible for communicating with the CFSSL private CA.
:copyright: (c) 2016 by Thomson Reuters
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Charles Hendrie <chad.hendrie@tr.com>
"""
import json
import requests
from flask import current_app
from lemur.plugins.bases import IssuerPlugin
from lemur.plugins import lemur_cfssl as cfssl
class CfsslIssuerPlugin(IssuerPlugin):
title = 'CFSSL'
slug = 'cfssl-issuer'
description = 'Enables the creation of certificates by CFSSL private CA'
version = cfssl.VERSION
author = 'Charles Hendrie'
author_url = 'https://github.com/netflix/lemur.git'
def __init__(self, *args, **kwargs):
self.session = requests.Session()
super(CfsslIssuerPlugin, self).__init__(*args, **kwargs)
def create_certificate(self, csr, issuer_options):
"""
Creates a CFSSL certificate.
:param csr:
:param issuer_options:
:return:
"""
current_app.logger.info("Requesting a new cfssl certificate with csr: {0}".format(csr))
url = "{0}{1}".format(current_app.config.get('CFSSL_URL'), '/api/v1/cfssl/sign')
data = {'certificate_request': csr.decode('utf_8')}
data = json.dumps(data)
response = self.session.post(url, data=data.encode(encoding='utf_8', errors='strict'))
response_json = json.loads(response.content.decode('utf_8'))
cert = response_json['result']['certificate']
return cert, current_app.config.get('CFSSL_INTERMEDIATE'),
@staticmethod
def create_authority(options):
"""
Creates an authority, this authority is then used by Lemur to allow a user
to specify which Certificate Authority they want to sign their certificate.
:param options:
:return:
"""
role = {'username': '', 'password': '', 'name': 'cfssl'}
return current_app.config.get('CFSSL_ROOT'), "", [role]

View File

@ -0,0 +1 @@
from lemur.tests.conftest import * # noqa

View File

@ -0,0 +1,6 @@
def test_get_certificates(app):
from lemur.plugins.base import plugins
p = plugins.get('cfssl-issuer')
assert p

View File

@ -184,6 +184,7 @@ setup(
'atlas_metric = lemur.plugins.lemur_atlas.plugin:AtlasMetricPlugin', 'atlas_metric = lemur.plugins.lemur_atlas.plugin:AtlasMetricPlugin',
'kubernetes_destination = lemur.plugins.lemur_kubernetes.plugin:KubernetesDestinationPlugin', 'kubernetes_destination = lemur.plugins.lemur_kubernetes.plugin:KubernetesDestinationPlugin',
'cryptography_issuer = lemur.plugins.lemur_cryptography.plugin:CryptographyIssuerPlugin', 'cryptography_issuer = lemur.plugins.lemur_cryptography.plugin:CryptographyIssuerPlugin',
'cfssl_issuer = lemur.plugins.lemur_cfssl.plugin:CfsslIssuerPlugin',
], ],
}, },
classifiers=[ classifiers=[