#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1+

import os
import sys
import subprocess
import tempfile
from datetime import datetime, timedelta

def _build_certs():

    # expire in 7 days to avoid people using these in production
    dt_activation = datetime.utcnow().isoformat()
    dt_expiration = (datetime.utcnow()+timedelta(days=7)).isoformat()

    # certificate authority
    ca = 'ACME'
    ca_privkey = f'{ca}-CA.key'
    ca_certificate = f'{ca}-CA.pem'
    if not os.path.exists(ca_privkey):
        print('generating private key...')
        argv = ['certtool', '--generate-privkey',
                '--outfile', ca_privkey]
        rc = subprocess.run(argv, check=True)
        if rc.returncode != 0:
            return 1
    if not os.path.exists(ca_certificate):
        print('generating self-signed certificate...')

        # build config
        lines = []
        lines.append('organization = "ACME Corp."')
        lines.append('cn = "ACME CA"')
        lines.append('uri = "http://www.example.com/"')
        lines.append('email = "admin@example.com"')
        lines.append('crl_dist_points = "http://www.example.com/pki/"')
        lines.append('serial = 1')
        lines.append('crl_number = 1')
        lines.append('path_len = 1')
        lines.append('activation_date = "{}"'.format(dt_activation))
        lines.append('expiration_date = "{}"'.format(dt_expiration))
        lines.append('ca')
        lines.append('cert_signing_key')
        lines.append('crl_signing_key')
        lines.append('code_signing_key')
        cfg = tempfile.NamedTemporaryFile(mode='w',
                                          prefix='cert_',
                                          suffix=".cfg",
                                          dir=None,
                                          delete=True)
        cfg.write('\n'.join(lines))
        cfg.flush()
        argv = ['certtool',
                '--generate-self-signed',
                '--load-privkey', ca_privkey,
                '--template', cfg.name,
                '--outfile', ca_certificate]
        rc = subprocess.run(argv, check=True)
        if rc.returncode != 0:
            return 1

    # per-user key
    user = 'rhughes'
    user_privkey = f'{user}.key'
    user_certificate = f'{user}.pem'
    user_certificate_signed = f'{user}_signed.pem'
    user_request = f'{user}.csr'

    # build config
    lines = []
    lines.append('cn = "Richard Hughes"')
    lines.append('uri = "https://hughsie.com/"')
    lines.append('email = "richard@hughsie.com"')
    lines.append('activation_date = "{}"'.format(dt_activation))
    lines.append('expiration_date = "{}"'.format(dt_expiration))
    lines.append('signing_key')
    lines.append('code_signing_key')
    cfg = tempfile.NamedTemporaryFile(mode='w',
                                      prefix='cert_',
                                      suffix=".cfg",
                                      dir=None,
                                      delete=True)
    cfg.write('\n'.join(lines))
    cfg.flush()

    if not os.path.exists(user_privkey):
        print('generating user private key...')
        argv = ['certtool', '--generate-privkey', '--rsa',
                '--bits', '2048',
                '--outfile', user_privkey]
        rc = subprocess.run(argv, check=True)
        if rc.returncode != 0:
            return 1
    if not os.path.exists(user_certificate):
        print('generating self-signed certificate...')
        argv = ['certtool', '--generate-self-signed', '--rsa',
                '--bits', '2048',
                '--load-privkey', user_privkey,
                '--template', cfg.name,
                '--outfile', user_certificate]
        rc = subprocess.run(argv, check=True)
        if rc.returncode != 0:
            return 1

    if not os.path.exists(user_request):
        print('generating certificate...')
        argv = ['certtool', '--generate-request',
                '--load-privkey', user_privkey,
                '--template', cfg.name,
                '--outfile', user_request]
        rc = subprocess.run(argv, check=True)
        if rc.returncode != 0:
            return 1

    # sign the user
    if not os.path.exists(user_certificate_signed):
        print('generating CA-signed certificate...')
        argv = ['certtool', '--generate-certificate', '--rsa',
                '--bits', '2048',
                '--load-request', user_request,
                '--load-ca-certificate', ca_certificate,
                '--load-ca-privkey', ca_privkey,
                '--template', cfg.name,
                '--outfile', user_certificate_signed]
        rc = subprocess.run(argv, check=True)
        if rc.returncode != 0:
            return 1

    # success
    return 0

if __name__ == '__main__':
    sys.exit(_build_certs())
