mirror of
https://github.com/laurivosandi/certidude
synced 2024-12-22 16:25:17 +00:00
Fixes, add some screenshots
This commit is contained in:
parent
029ee357fb
commit
9658d8cc83
20
README.rst
20
README.rst
@ -12,15 +12,14 @@ Introduction
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
Certidude is a novel X.509 Certificate Authority management tool
|
Certidude is a novel X.509 Certificate Authority management tool
|
||||||
with privilege isolation mechanism and Kerberos authentication aiming to
|
with privilege isolation mechanism and Kerberos authentication
|
||||||
eventually support PKCS#11 and in far future WebCrypto.
|
mainly designed for OpenVPN gateway operators to make
|
||||||
|
|
||||||
.. figure:: doc/usecase-diagram.png
|
|
||||||
|
|
||||||
Certidude is mainly designed for StrongSwan and OpenVPN gateway operators to make
|
|
||||||
VPN client setup on laptops, desktops and mobile devices as painless as possible.
|
VPN client setup on laptops, desktops and mobile devices as painless as possible.
|
||||||
Certidude can also be used to manage HTTPS client certificates for
|
|
||||||
eg. maintaining an extra layer of protection for intranet websites.
|
.. figure:: doc/certidude.png
|
||||||
|
|
||||||
|
Certidude can also be used to manage IPSec certifcates (StrongSwan)
|
||||||
|
or HTTPS client certificates to limit access to eg. intranet websites.
|
||||||
For a full-blown CA you might want to take a look at
|
For a full-blown CA you might want to take a look at
|
||||||
`EJBCA <http://www.ejbca.org/features.html>`_ or
|
`EJBCA <http://www.ejbca.org/features.html>`_ or
|
||||||
`OpenCA <https://pki.openca.org/>`_.
|
`OpenCA <https://pki.openca.org/>`_.
|
||||||
@ -29,6 +28,8 @@ For a full-blown CA you might want to take a look at
|
|||||||
Usecases
|
Usecases
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
.. figure:: doc/usecase-diagram.png
|
||||||
|
|
||||||
Following usecases are covered:
|
Following usecases are covered:
|
||||||
|
|
||||||
* I am a sysadmin. Employees with different operating systems need to access
|
* I am a sysadmin. Employees with different operating systems need to access
|
||||||
@ -79,6 +80,7 @@ Common:
|
|||||||
|
|
||||||
Virtual private networking:
|
Virtual private networking:
|
||||||
|
|
||||||
|
* Send OpenVPN profile URL tokens via e-mail, for simplified VPN adoption on Android, iOS, Windows, Mac OS X and Ubuntu.
|
||||||
* OpenVPN integration, check out ``certidude setup openvpn server`` and ``certidude setup openvpn client``.
|
* OpenVPN integration, check out ``certidude setup openvpn server`` and ``certidude setup openvpn client``.
|
||||||
* strongSwan integration, check out ``certidude setup strongswan server`` and ``certidude setup strongswan client``.
|
* strongSwan integration, check out ``certidude setup strongswan server`` and ``certidude setup strongswan client``.
|
||||||
* NetworkManager integration, check out ``certidude setup openvpn networkmanager`` and ``certidude setup strongswan networkmanager``.
|
* NetworkManager integration, check out ``certidude setup openvpn networkmanager`` and ``certidude setup strongswan networkmanager``.
|
||||||
@ -95,7 +97,7 @@ TODO
|
|||||||
* `OCSP <https://tools.ietf.org/html/rfc4557>`_ support, needs a bit hacking since OpenSSL wrappers are not exposing the functionality.
|
* `OCSP <https://tools.ietf.org/html/rfc4557>`_ support, needs a bit hacking since OpenSSL wrappers are not exposing the functionality.
|
||||||
* `SCEP <https://tools.ietf.org/html/draft-nourse-scep-23>`_ support, a client implementation available `here <https://github.com/certnanny/sscep>`_. Not sure if we can implement server-side events within current standard.
|
* `SCEP <https://tools.ietf.org/html/draft-nourse-scep-23>`_ support, a client implementation available `here <https://github.com/certnanny/sscep>`_. Not sure if we can implement server-side events within current standard.
|
||||||
* WebCrypto support, meanwhile check out `hwcrypto.js <https://github.com/open-eid/hwcrypto.js>`_.
|
* WebCrypto support, meanwhile check out `hwcrypto.js <https://github.com/open-eid/hwcrypto.js>`_.
|
||||||
* Ability to send OpenVPN profile URL tokens via e-mail, for simplified VPN adoption.
|
* Use `pki.js <https://pkijs.org/>`_ for generating keypair in the browser when claiming a token.
|
||||||
* Signer process logging.
|
* Signer process logging.
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ def revoke(common_name):
|
|||||||
attach_cert = buf, "application/x-pem-file", common_name + ".crt"
|
attach_cert = buf, "application/x-pem-file", common_name + ".crt"
|
||||||
mailer.send("certificate-revoked.md",
|
mailer.send("certificate-revoked.md",
|
||||||
attachments=(attach_cert,),
|
attachments=(attach_cert,),
|
||||||
serial_number="%x" % cert.serial,
|
serial_hex="%x" % cert.serial,
|
||||||
common_name=common_name)
|
common_name=common_name)
|
||||||
return revoked_path
|
return revoked_path
|
||||||
|
|
||||||
@ -298,11 +298,15 @@ def _sign(csr, buf, overwrite=False):
|
|||||||
from xattr import getxattr, listxattr, setxattr
|
from xattr import getxattr, listxattr, setxattr
|
||||||
|
|
||||||
common_name, = csr.subject.get_attributes_for_oid(NameOID.COMMON_NAME)
|
common_name, = csr.subject.get_attributes_for_oid(NameOID.COMMON_NAME)
|
||||||
cert_path = os.path.join(config.SIGNED_DIR, common_name.value + ".pem")
|
cert_path = os.path.join(config.SIGNED_DIR, "%s.pem" % common_name.value)
|
||||||
renew = False
|
renew = False
|
||||||
|
|
||||||
signed_path = os.path.join(config.SIGNED_DIR, "%s.pem" % common_name.value)
|
attachments = [
|
||||||
|
(buf, "application/x-pem-file", common_name.value + ".csr"),
|
||||||
|
]
|
||||||
|
|
||||||
revoked_path = None
|
revoked_path = None
|
||||||
|
overwritten = False
|
||||||
|
|
||||||
# Move existing certificate if necessary
|
# Move existing certificate if necessary
|
||||||
if os.path.exists(cert_path):
|
if os.path.exists(cert_path):
|
||||||
@ -313,12 +317,12 @@ def _sign(csr, buf, overwrite=False):
|
|||||||
renew = prev.public_key().public_numbers() == csr.public_key().public_numbers()
|
renew = prev.public_key().public_numbers() == csr.public_key().public_numbers()
|
||||||
|
|
||||||
if overwrite:
|
if overwrite:
|
||||||
if renew:
|
# TODO: is this the best approach?
|
||||||
# TODO: is this the best approach?
|
prev_serial_hex = "%x" % prev.serial
|
||||||
revoked_path = os.path.join(config.REVOKED_DIR, "%x.pem" % prev.serial)
|
revoked_path = os.path.join(config.REVOKED_DIR, "%s.pem" % prev_serial_hex)
|
||||||
os.rename(signed_path, revoked_path)
|
os.rename(cert_path, revoked_path)
|
||||||
else:
|
attachments += [(prev_buf, "application/x-pem-file", "deprecated.crt" if renew else "overwritten.crt")]
|
||||||
revoked_path = revoke(common_name.value)
|
overwritten = True
|
||||||
else:
|
else:
|
||||||
raise EnvironmentError("Will not overwrite existing certificate")
|
raise EnvironmentError("Will not overwrite existing certificate")
|
||||||
|
|
||||||
@ -328,42 +332,21 @@ def _sign(csr, buf, overwrite=False):
|
|||||||
with open(cert_path + ".part", "wb") as fh:
|
with open(cert_path + ".part", "wb") as fh:
|
||||||
fh.write(cert_buf)
|
fh.write(cert_buf)
|
||||||
os.rename(cert_path + ".part", cert_path)
|
os.rename(cert_path + ".part", cert_path)
|
||||||
|
attachments.append((cert_buf, "application/x-pem-file", common_name.value + ".crt"))
|
||||||
|
cert_serial_hex = "%x" % cert.serial
|
||||||
|
|
||||||
# Copy filesystem attributes to newly signed certificate
|
# Copy filesystem attributes to newly signed certificate
|
||||||
if revoked_path:
|
if revoked_path:
|
||||||
for key in listxattr(revoked_path):
|
for key in listxattr(revoked_path):
|
||||||
if not key.startswith("user."):
|
if not key.startswith("user."):
|
||||||
continue
|
continue
|
||||||
setxattr(signed_path, key, getxattr(revoked_path, key))
|
setxattr(cert_path, key, getxattr(revoked_path, key))
|
||||||
|
|
||||||
# Send mail
|
# Send mail
|
||||||
recipient = None
|
if renew: # Same keypair
|
||||||
|
mailer.send("certificate-renewed.md", **locals())
|
||||||
if renew:
|
else: # New keypair
|
||||||
mailer.send(
|
mailer.send("certificate-signed.md", **locals())
|
||||||
"certificate-renewed.md",
|
|
||||||
to=recipient,
|
|
||||||
attachments=(
|
|
||||||
(prev_buf, "application/x-pem-file", "deprecated.crt"),
|
|
||||||
(cert_buf, "application/x-pem-file", common_name.value + ".crt")
|
|
||||||
),
|
|
||||||
serial_number="%x" % cert.serial,
|
|
||||||
common_name=common_name.value,
|
|
||||||
certificate=cert,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
mailer.send(
|
|
||||||
"certificate-signed.md",
|
|
||||||
to=recipient,
|
|
||||||
attachments=(
|
|
||||||
(buf, "application/x-pem-file", common_name.value + ".csr"),
|
|
||||||
(cert_buf, "application/x-pem-file", common_name.value + ".crt")
|
|
||||||
),
|
|
||||||
serial_number="%x" % cert.serial,
|
|
||||||
common_name=common_name.value,
|
|
||||||
certificate=cert,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if config.LONG_POLL_PUBLISH:
|
if config.LONG_POLL_PUBLISH:
|
||||||
url = config.LONG_POLL_PUBLISH % hashlib.sha256(buf).hexdigest()
|
url = config.LONG_POLL_PUBLISH % hashlib.sha256(buf).hexdigest()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
Renewed {{ common_name }} ({{ serial_number }})
|
Renewed {{ common_name.value }} ({{ cert_serial_hex }})
|
||||||
|
|
||||||
This is simply to notify that certificate for {{ common_name }}
|
This is simply to notify that certificate for {{ common_name.value }}
|
||||||
was renewed and the serial number of the new certificate is {{ serial_number }}.
|
was renewed and the serial number of the new certificate is {{ cert_serial_hex }}.
|
||||||
|
|
||||||
The new certificate is valid from {{ certificate.not_valid_before }} until
|
The new certificate is valid from {{ cert.not_valid_before }} until
|
||||||
{{ certificate.not_valid_after }}.
|
{{ cert.not_valid_after }}.
|
||||||
|
|
||||||
Services making use of those certificates should continue working as expected.
|
Services making use of those certificates should continue working as expected.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Revoked {{ common_name }} ({{ serial_number }})
|
Revoked {{ common_name }} ({{ serial_hex }})
|
||||||
|
|
||||||
This is simply to notify that certificate {{ common_name }}
|
This is simply to notify that certificate {{ common_name }}
|
||||||
was revoked.
|
was revoked.
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
Signed {{ common_name }} ({{ serial_number }})
|
Signed {{ common_name.value }} ({{ cert_serial_hex }})
|
||||||
|
|
||||||
This is simply to notify that certificate {{ common_name }}
|
This is simply to notify that certificate {{ common_name.value }}
|
||||||
with serial number {{ serial_number }}
|
with serial number {{ cert_serial_hex }}
|
||||||
was signed{% if signer %} by {{ signer }}{% endif %}.
|
was signed{% if signer %} by {{ signer }}{% endif %}.
|
||||||
|
|
||||||
The certificate is valid from {{ certificate.not_valid_before }} until
|
The certificate is valid from {{ cert.not_valid_before }} until
|
||||||
{{ certificate.not_valid_after }}.
|
{{ cert.not_valid_after }}.
|
||||||
|
|
||||||
Any existing certificates with the same common name were rejected by doing so
|
{% if overwritten %}
|
||||||
and services making use of those certificates might become unavailable.
|
By doing so existing certificate with the same common name
|
||||||
|
and serial number {{ prev_serial_hex }} was rejected
|
||||||
|
and services making use of that certificate might become unavailable.
|
||||||
|
{% endif %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Token for setting up VPN
|
Token for {{ user.name }}
|
||||||
|
|
||||||
{{ issuer }} has provided {{ user }} a token for retrieving
|
{{ issuer }} has provided {{ user }} a token for retrieving
|
||||||
profile from the link below.
|
profile from the link below.
|
||||||
|
BIN
doc/certidude.png
Normal file
BIN
doc/certidude.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
Loading…
Reference in New Issue
Block a user