Commit f3a43056 authored by Łukasz Nowak's avatar Łukasz Nowak

KeDiFa: Initial implementation

Provided tools are kedifa and kedifa-getter.

kedifa is a server to PUT and GET sensitive information, like SSL keys and
certificates.

kedifa-getter is a client to this server.

As both are closely related to caucase, they allow to use information from
caucase, like CA Certificate, to validate each other.

Caucase is also used to generate certificates for kedifa-getter used to
authenticate to kedifa.

Extracted important points of development of the inital version:

 * kedifa and kedifa-getter has been implemented
 * TODOs list is kept for future improvements
 * IPv6 and SSL-only support came
 * API has been docstring documented
 * PUTting information is based on query string key authorisation
 * GETting information requires SSL authentication
 * only correct keys are stored in KeDiFa database
 * certificates are served orderd by theirs submission date
 * kedifa-csr has been implemented, and dropped, as started to become openssl
   req implementation
 * caucase.http has been used as base for wsgiref approach
 * caucase.utils has been used for certificate management
 * argparse has been used for command line arguments
 * time comparison has been done in python, instead of SQLite
 * reloading, in caucase way, has been implemented
 * CRLs are in-app checked only, as pythons implementation does not allow
   proper reloads
 * in critical places code raises instead of returning False, in order to
   disallow ignoring result value
 * ids to store data has to be reserved
parent 9a55bb02
This diff is collapsed.
KeDiFa TODOs
============
* encapsulate app into raising part and HTTP code returing part
* use ``pylint``, ``coverage`` and other tools in sane manner to improve code quality
* enforce proper ``Content-Type`` on certificate ``PUT``, with nice information in case if wrong value is used; possibly do it in conjunction with providing simple client to upload certificates
* implement ``test_GET_expired_identity`` with doing CA by hand and issuing expired certificate out of caucase, in order to have it expired in time of connection
This diff is collapsed.
# Copyright (C) 2018 Nexedi SA
# Lukasz Nowak <luke@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
# option) any later version, as published by the Free Software Foundation.
#
# You can also Link and Combine this program with other software covered by
# the terms of any of the Free Software licenses or any of the Open Source
# Initiative approved licenses and Convey the resulting work. Corresponding
# source of such a combination shall include the source code for all other
# software used.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
import argparse
import httplib
import requests
import sys
import app
def http(*args):
if not args:
args = sys.argv[1:]
parser = argparse.ArgumentParser(description='KeDiFa webapp')
parser.add_argument(
'--ip',
help='IP to bind to (v4 or v6).',
required=True
)
parser.add_argument(
'--port',
type=int,
help='Port to bind to.',
required=True
)
parser.add_argument(
'--db',
help='Path to the SQLite database.',
required=True
)
parser.add_argument(
'--certificate',
type=argparse.FileType('r'),
help='Path SSL certificate.',
required=True
)
parser.add_argument(
'--ca-certificate',
type=argparse.FileType('r'),
help='Path SSL CA certificate.',
required=True
)
parser.add_argument(
'--crl',
type=argparse.FileType('r'),
help='Path SSL CRL.',
required=True
)
parser.add_argument(
'--pidfile',
type=argparse.FileType('w'),
help='Path to PID file.',
required=True
)
parsed = parser.parse_args(args)
app.http(parsed.ip, parsed.port, parsed.db, parsed.certificate,
parsed.ca_certificate, parsed.crl, parsed.pidfile)
def getter(*args):
"""Downloads a file with SSL client & server authentication, storing
received data only when successful.
"""
if not args:
args = sys.argv[1:]
parser = argparse.ArgumentParser(description='KeDiFa getter')
parser.add_argument(
'url',
nargs=1,
help='URL to fetch certificate from.'
)
parser.add_argument(
'--identity',
type=argparse.FileType('r'),
help='Certificate to identify itself on the URL.',
required=True
)
parser.add_argument(
'--server-ca-certificate',
type=argparse.FileType('r'),
help='CA Certificate of the server.',
required=True
)
parser.add_argument(
'--out',
help='Destination to store the downloaded certificate.',
required=True
)
parsed = parser.parse_args(args)
url = parsed.url[0]
try:
response = requests.get(url, verify=parsed.server_ca_certificate.name,
cert=parsed.identity.name)
except Exception as e:
print '%r not downloaded, problem %s' % (url, e)
sys.exit(1)
else:
if response.status_code != httplib.OK:
print '%r not downloaded, HTTP code %s' % (
url, response.status_code)
sys.exit(1)
if len(response.text) > 0:
with open(parsed.out, 'w') as out:
out.write(response.text.encode('utf-8'))
This diff is collapsed.
# Copyright (C) 2018 Nexedi # Copyright (C) 2018 Nexedi SA
# Lukasz Nowak <luke@nexedi.com> # Lukasz Nowak <luke@nexedi.com>
# #
# KeDiFa is free software: you can redistribute it and/or modify # This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License version 3, or (at your
# the Free Software Foundation, either version 3 of the License, or # option) any later version, as published by the Free Software Foundation.
# (at your option) any later version.
# #
# KeDiFa is distributed in the hope that it will be useful, # You can also Link and Combine this program with other software covered by
# but WITHOUT ANY WARRANTY; without even the implied warranty of # the terms of any of the Free Software licenses or any of the Open Source
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # Initiative approved licenses and Convey the resulting work. Corresponding
# GNU General Public License for more details. # source of such a combination shall include the source code for all other
# software used.
# #
# You should have received a copy of the GNU General Public License # This program is distributed WITHOUT ANY WARRANTY; without even the implied
# along with KeDiFa. If not, see <http://www.gnu.org/licenses/>. # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
from setuptools import setup, find_packages from setuptools import setup, find_packages
import versioneer import versioneer
...@@ -35,9 +38,24 @@ setup( ...@@ -35,9 +38,24 @@ setup(
], ],
keywords='key distribution ssl', keywords='key distribution ssl',
url='https://lab.nexedi.com/luke/kedifa', url='https://lab.nexedi.com/luke/kedifa',
license='GPLv3+', license='GPLv3+ with wide exception for FOSS',
packages=find_packages(), packages=find_packages(),
install_requires=[ install_requires=[
'cryptography', # for working with certificates
'requests', # for getter
'urllib3 >= 1.18', # https://github.com/urllib3/urllib3/issues/258
'caucase >= 0.9.3', # provides utils for certificate management
],
tests_require=[
'capturer',
'urllib3 >= 1.18', # https://github.com/urllib3/urllib3/issues/258
'ipaddress',
], ],
zip_safe=True, zip_safe=True,
entry_points={
'console_scripts': [
'kedifa = kedifa.cli:http',
'kedifa-getter = kedifa.cli:getter',
]
},
) )
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment