mirror of
https://github.com/laurivosandi/certidude
synced 2024-12-22 16:25:17 +00:00
Add OpenVPN bundle generation
This commit is contained in:
parent
cca9d2ab2d
commit
1925207a6d
@ -12,6 +12,8 @@ KEYWORDS = (
|
||||
(u"iPhone", u"iphone"),
|
||||
(u"iPad", u"ipad"),
|
||||
(u"Ubuntu", u"ubuntu"),
|
||||
(u"Fedora", u"fedora"),
|
||||
(u"Linux", u"linux"),
|
||||
)
|
||||
|
||||
class BundleResource(object):
|
||||
@ -29,8 +31,15 @@ class BundleResource(object):
|
||||
hashlib.sha256(req.user_agent).hexdigest()[:8])
|
||||
|
||||
logger.info(u"Signing bundle %s for %s", common_name, req.context.get("user"))
|
||||
resp.set_header("Content-Type", "application/x-pkcs12")
|
||||
resp.set_header("Content-Disposition", "attachment; filename=%s.p12" % common_name.encode("ascii"))
|
||||
resp.body, cert = authority.generate_pkcs12_bundle(common_name,
|
||||
owner=req.context.get("user"))
|
||||
|
||||
if config.BUNDLE_FORMAT == "p12":
|
||||
resp.set_header("Content-Type", "application/x-pkcs12")
|
||||
resp.set_header("Content-Disposition", "attachment; filename=%s.p12" % common_name.encode("ascii"))
|
||||
resp.body, cert = authority.generate_pkcs12_bundle(common_name,
|
||||
owner=req.context.get("user"))
|
||||
elif config.BUNDLE_FORMAT == "ovpn":
|
||||
resp.set_header("Content-Type", "application/x-openvpn")
|
||||
resp.set_header("Content-Disposition", "attachment; filename=%s.ovpn" % common_name.encode("ascii"))
|
||||
resp.body, cert = authority.generate_ovpn_bundle(common_name,
|
||||
owner=req.context.get("user"))
|
||||
else:
|
||||
raise ValueError("Unknown bundle format %s" % config.BUNDLE_FORMAT)
|
||||
|
@ -14,6 +14,7 @@ from cryptography.hazmat.primitives import hashes, serialization
|
||||
from certidude import config, push, mailer, const
|
||||
from certidude.wrappers import Certificate, Request
|
||||
from certidude import errors
|
||||
from jinja2 import Template
|
||||
|
||||
RE_HOSTNAME = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])(@(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9]))?$"
|
||||
|
||||
@ -21,7 +22,6 @@ RE_HOSTNAME = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z
|
||||
# https://jamielinux.com/docs/openssl-certificate-authority/
|
||||
# http://pycopia.googlecode.com/svn/trunk/net/pycopia/ssl/certs.py
|
||||
|
||||
|
||||
# Cache CA certificate
|
||||
certificate = Certificate(open(config.AUTHORITY_CERTIFICATE_PATH))
|
||||
|
||||
@ -185,6 +185,39 @@ def delete_request(common_name):
|
||||
requests.delete(config.PUSH_PUBLISH % request.fingerprint(),
|
||||
headers={"User-Agent": "Certidude API"})
|
||||
|
||||
def generate_ovpn_bundle(common_name, owner=None):
|
||||
# Construct private key
|
||||
click.echo("Generating 4096-bit RSA key...")
|
||||
|
||||
key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=4096,
|
||||
backend=default_backend()
|
||||
)
|
||||
|
||||
csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
|
||||
x509.NameAttribute(k, v) for k, v in (
|
||||
(NameOID.COMMON_NAME, common_name),
|
||||
(NameOID.GIVEN_NAME, owner and owner.given_name),
|
||||
(NameOID.SURNAME, owner and owner.surname),
|
||||
) if v
|
||||
]))
|
||||
|
||||
# Sign CSR
|
||||
cert = sign(Request(
|
||||
csr.sign(key, hashes.SHA512(), default_backend()).public_bytes(serialization.Encoding.PEM)), overwrite=True)
|
||||
|
||||
bundle = Template(open(config.OPENVPN_BUNDLE_TEMPLATE).read()).render(
|
||||
ca = certificate.dump(),
|
||||
key = key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
),
|
||||
cert = cert.dump(),
|
||||
crl=export_crl(),
|
||||
)
|
||||
return bundle, cert
|
||||
|
||||
def generate_pkcs12_bundle(common_name, key_size=4096, owner=None):
|
||||
"""
|
||||
|
@ -40,6 +40,9 @@ SIGNED_DIR = cp.get("authority", "signed dir")
|
||||
REVOKED_DIR = cp.get("authority", "revoked dir")
|
||||
OUTBOX = cp.get("authority", "outbox")
|
||||
|
||||
BUNDLE_FORMAT = cp.get("authority", "bundle format")
|
||||
OPENVPN_BUNDLE_TEMPLATE = cp.get("authority", "openvpn bundle template")
|
||||
|
||||
USER_CERTIFICATE_ENROLLMENT = {
|
||||
"forbidden": False, "single allowed": True, "multiple allowed": True }[
|
||||
cp.get("authority", "user certificate enrollment")]
|
||||
|
@ -95,3 +95,8 @@ revoked dir = {{ directory }}/revoked/
|
||||
expired dir = {{ directory }}/expired/
|
||||
outbox = {{ outbox }}
|
||||
|
||||
bundle format = p12
|
||||
;bundle format = ovpn
|
||||
|
||||
openvpn bundle template = /etc/certidude/template.ovpn
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user