예제 #1
0
def submit_domain(did):
    choices = ['ov', 'ev', 'ovcs', 'evcs']
    type = input('Validate for [ov, ev, ovcs, evcs]? ')
    while type not in choices:
        colorize('red')
        choices = input(
            'Please choose one of the following validation types: [ov, ev, ovcs, evcs] '
        )
        colorize_edit('reset')
        type = choices
    payload = json.dumps(
        {"validations": [{
            "type": type,
            "user": {
                "id": did
            }
        }]})
    req_url = url + '/' + did + '/validation'
    req = requests.post(req_url, headers=headers_post, data=payload)
    rest_status(req)
    if req.status_code == 204:
        colorize('green')
        print('Domain submitted for ' + type + ' validation.\n')
        colorize_edit('reset')
    return req
예제 #2
0
파일: crypto.py 프로젝트: kuan51/dcli
def gen_key(alg):
    if alg == 'rsa':
        print('Generating new private key')
        size = int(input('Choose a bit size between [2048-4096]: '))
        while not size >= 2048 and size <= 4096:
            print('Choose 2048, 3072, or 4096.')
            size = int(input(''))
        key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=size,
            backend=default_backend()
        )
    elif alg == 'ecc':
        curve = input('Use a p256, p384, or p521 curve? ')
        while not curve in ['p256','p384','p521']:
            colorize('red')
            curve = input('Use a p256, p384, or p521 curve? ')
            colorize_edit('reset')
        if curve == 'p256':
            key = ec.generate_private_key(ec.SECP256R1(), default_backend())
        elif curve == 'p384':
            key = ec.generate_private_key(ec.SECP384R1(), default_backend())
        elif curve == 'p521':
            key = ec.generate_private_key(ec.SECP521R1(), default_backend())
    return key
예제 #3
0
def delete_usr(uid):
    req_url = url + '/' + str(uid)
    req = requests.delete(req_url, headers=headers_get)
    rest_status(req)
    if req.status_code == 204:
        colorize('green')
        print('Successfully deleted user.\n')
        colorize_edit('reset')
예제 #4
0
def update_request(rid, status, comment):
    req_url = 'https://www.digicert.com/services/v2/request/' + str(rid) + '/status'
    if status == 'submitted' or 'pending' or 'approved' or 'rejected':
        payload = json.dumps({ 'status': status, 'processor_comment': comment})
        req = requests.put(req_url, headers=headers_post, data=payload)
        rest_status(req)
    else:
        colorize('red')
        print('Please enter valid status. [ submitted, pending, approved, rejected ]')
        colorize_edit('reset')
예제 #5
0
def revoke_cert(cid, comment):
    req_url = 'https://www.digicert.com/services/v2/order/certificate/' + cid + '/revoke'
    payload = json.dumps( { 'comments': comment } )
    req = requests.put(req_url, headers=headers_post, data=payload)
    rest_status(req)
    resp = req.json()
    if resp.get('status'):
        colorize('cyan')
        print('A request to revoke order ' + cid + ' was successfully submitted on ' + resp['date'])
        colorize_edit('reset')
    return resp
예제 #6
0
파일: crypto.py 프로젝트: kuan51/dcli
def decode_cert(cert_path):
    # Open certificate and deserialize
    with open(str(cert_path),'rb') as rf:
        pem_obj = rf.read()
        if pem.detect(pem_obj):
            type, _, _ = pem.unarmor(pem_obj)
            # Determine type of certificate
            if type == "PKCS7":
                pkcs7 = crypto.load_pkcs7_data(crypto.FILETYPE_PEM,pem_obj)
                certs = get_certificates(pkcs7)
                count = 0
                for cert in certs:
                    pem_cert = x509.load_pem_x509_certificate(cert, default_backend())
                    # Print cert issued to
                    colorize('green')
                    print('Issued to: (Chain ' + str(count) + ')')
                    count += 1
                    colorize_edit('reset')
                    print(pem_cert.subject.rfc4514_string())
                    print("Serial No: " + str(pem_cert.serial_number))
                    print("Fingerprint: " + str(base64.b64encode(pem_cert.fingerprint(hashes.SHA256())), 'utf-8'))
                    print("Valid from: " + str(pem_cert.not_valid_before))
                    print("Valid to: " + str(pem_cert.not_valid_after))
                    print("Signature hash algorithm: " + pem_cert.signature_hash_algorithm.name)
                    # Print issued by
                    colorize('green')
                    print('Issued by: ')
                    colorize_edit('reset')
                    print(pem_cert.issuer.rfc4514_string())
                    print('\n')

            elif type == "CERTIFICATE":
                cert = x509.load_pem_x509_certificate(pem_obj, default_backend())
                # Print cert issued to
                colorize('green')
                print('Issued to: ')
                colorize_edit('reset')
                print(cert.subject.rfc4514_string())
                print("Serial No: " + str(cert.serial_number))
                print("Fingerprint: " + str(base64.b64encode(cert.fingerprint(hashes.SHA256())), 'utf-8'))
                print("Valid from: " + str(cert.not_valid_before))
                print("Valid to: " + str(cert.not_valid_after))
                print("Signature hash algorithm: " + cert.signature_hash_algorithm.name)
                # Print issued by
                colorize('green')
                print('Issued by: ')
                colorize_edit('reset')
                print(cert.issuer.rfc4514_string())
            else:
                raise TypeError('Not a PEM or PKCS7 file.')
예제 #7
0
def edit_usr(uid):
    req_url = url + '/' + str(uid)
    uname = input('Enter a new username: '******'Enter a new first name: ')
    lname = input('Enter a new last name: ')
    email = input('Enter a new email: ')
    job = input('Enter a new job title: ')
    phone = input('Enter a new phone number: ')
    payload = json.dumps({
        'username': uname,
        'first_name': fname,
        'last_name': lname,
        'email': email,
        'job_title': job,
        'telephone': phone
    })
    req = requests.put(req_url, headers=headers_post, data=payload)
    rest_status(req)
    if req.status_code == 204:
        colorize('green')
        print('Successfully updated user.\n')
        colorize_edit('reset')
예제 #8
0
def new_usr():
    username = input("Enter a username: "******"Enter a firstname: ")
        l_name = input("Enter a lastname: ")
        email = input("Enter a email: ")
        job = input("Enter a job title: ")
        phone = input("Enter a phone number: ")
        payload = json.dumps({
            'username': username,
            'first_name': f_name,
            'last_name': l_name,
            'email': email,
            'job_title': job,
            'telephone': phone,
            'container': {
                'id': root_container()
            },
            'access_roles': [{
                'id': rid
            }]
        })
        req = requests.post(url, headers=headers_post, data=payload)
        rest_status(req)
        if req.status_code == 201:
            colorize('green')
            print('Successfully created new user. New User ID: ' +
                  str(req.json()['id']))
            print('\n')
            colorize_edit('reset')
        else:
            colorize('red')
            print('Error: ' + str(req.status_code))
            colorize_edit('reset')
    else:
        colorize('red')
        print("Username is taken. Try a different one.\n")
        colorize_edit('reset')
예제 #9
0
def dcli():
    # Main ArgParse Parser
    parser = argparse.ArgumentParser(prog='dcli', add_help=True)
    subparsers = parser.add_subparsers(dest='cmd')

    # Main options
    parser.add_argument("--init", help="Initialize configuration scripts", action="store_true")
    parser.add_argument("--init-org", help="Validate a organization", action="store_true")
    parser.add_argument("--init-dom", help="Validate a domain", action="store_true")

    # Argparse Certificate Management Sub Parser
    parser_cert = subparsers.add_parser('crt')
    parser_cert.add_argument("-l", "--list-crt", help="List all orders", action='store_true')
    parser_cert.add_argument("-v", "--view-crt", help="View order details by id")
    parser_cert.add_argument("-n", "--new-crt", help="New order, requires csr", choices=['ov', 'ev', 'cs', 'evcs'])
    parser_cert.add_argument("-r", "--revoke-crt", help="Revoke order")
    parser_cert.add_argument("-e", "--edit-crt", help="Edit order (reissue)")
    parser_cert.add_argument("-d", "--duplicate-crt", help="Create copy of an order with a different CSR")
    parser_cert.add_argument("-a", "--duplicate-list", help="List the duplicate certificates of an order")

    # Argparse Domain Management Sub Parser
    parser_dom = subparsers.add_parser('dom')
    parser_dom.add_argument("-l", "--list-dom", help="List active domains", action="store_true")
    parser_dom.add_argument("-a", "--activate-dom", help="Activate domain")
    parser_dom.add_argument("-d", "--deactivate-dom", help="Deactivate domain")
    parser_dom.add_argument("-s", "--submit-dom", help="Submit domain for validation")
    parser_dom.add_argument("-dcv", help="Domain control verification", choices=['txt', 'cname', 'email', 'http'])
    parser_dom.add_argument("-dns", help ="Test DNS to complete DCV", choices=['txt','cname'])
    parser_dom.add_argument("-n", "--new-dom", help="New domain", choices=['ov','ev'])
    parser_dom.add_argument("-v", "--view-dom", help="View domain details by id")

    # Argparse Organization Management Sub Parser
    parser_org = subparsers.add_parser('org')
    parser_org.add_argument("-l", "--list-org", help="List organizations", action="store_true")
    parser_org.add_argument("-v", "--view-org", help="View details of organization by org id")

    # argparse Request Management Sub Parser
    parser_req = subparsers.add_parser('req')
    parser_req.add_argument('-l', '--list-req', help='List all pending requests', choices=['pending','all'])
    parser_req.add_argument('-v', '--view-req', help='View request details')
    parser_req.add_argument('-r', '--reject-req', help='Reject a pending certificate request by id.')
    parser_req.add_argument('-a', '--approve-req', help='Approve a pending certificate request by id.')

    # Argparse User Management Sub Parser
    parser_usr = subparsers.add_parser('usr')
    parser_usr.add_argument("-n", "--new-usr", help="New user account", action='store_true')
    parser_usr.add_argument("-e", "--edit-usr", help="Edit user account")
    parser_usr.add_argument("-v", "--view-usr", help="View existing user account")
    parser_usr.add_argument("-d", "--delete-usr", help="Delete user account")
    parser_usr.add_argument("-l", "--list-usr", help="List user accounts", action="store_true")
    parser_usr.add_argument("-c", "--check-api", help="Check Digicert API key for permissions.", action="store_true")

    # Argparse Cryptography Sub Parser
    parser_crypto = subparsers.add_parser('crypto')
    parser_crypto.add_argument('--new-csr', help="Create a new CSR and private key", choices=['ecc', 'rsa'])
    parser_crypto.add_argument('--new-key', help='Create a new private key', choices=['ecc', 'rsa'])
    parser_crypto.add_argument('--decode-crt', help='View encoded details in the certificate')
    parser_crypto.add_argument('--decode-csr', help='View encoded details in the CSR')
    parser_crypto.add_argument('--test-csr', help='Generate hash of CSR')
    parser_crypto.add_argument('--test-key', help='Generate hash of private key')
    parser_crypto.add_argument('--test-crt', help='Generate hash of certificate')

    # Parse argument list
    args = parser.parse_args()

    # Initial configuration
    if args.init:
        print("Running configuration scripts. This will overwrite any existing files.")
        # Collect user input
        key = input("Enter your Digicert API key: ")
        dir = Path(input("Where do you want to save everything? [./] "))
        conf = Path(dir / 'conf.d')
        file = str(Path(conf / 'init.conf'))
        # If dir exists
        if dir.exists():
            print('Directory already exists')
        # Else create dir
        else:
            os.mkdir(str(dir))
            os.mkdir(str(conf))
        # Delete existing init.conf
        if main_conf.exists():
            os.remove(str(main_conf.resolve()))
            # Create init.conf
            parser = configparser.ConfigParser()
            parser.read(file)
            parser.add_section('DigiUtil-Cli Conf')
            parser.add_section('Organization Validation')
            parser.add_section('Domain Validation')
            parser.set('DigiUtil-Cli Conf', 'api_key', key)
            parser.set('DigiUtil-Cli Conf', 'cert_lib', str(dir.resolve()))
            with open(file, "w+") as f:
                parser.write(f)
            print('init.conf was saved in: ' + str(conf.resolve()))
        else:
            # Create init.conf
            parser = configparser.ConfigParser()
            parser.read('init.conf')
            parser.add_section('DigiUtil-Cli Conf')
            parser.add_section('Organization Validation')
            parser.add_section('Domain Validation')
            parser.set('DigiUtil-Cli Conf', 'api_key', key)
            parser.set('DigiUtil-Cli Conf', 'cert_lib', str(dir))
            with open(file, 'w+') as f:
                parser.write(f)
            print('init.conf was saved in: ' + str(conf.resolve()))

    # Validate org
    if args.init_org:
        reval = input('Is this the FIRST time registering the org with Digicert? (Create new org) [y/n] ')
        if reval == 'y':
            new_org()
        elif reval == 'n':
            list = list_org('n', 'y')
            pages = paginate(list, 5)
            org = input('Enter the id of the org you want to validate: ')
            # Get org name and confd path
            org_name = view_org(org)['name']
            conf = Path(confd_org / str(org + '.conf'))
            if os.path.exists(str(conf)):
                os.remove(str(conf))
            # Add org to init.conf
            p1 = configparser.ConfigParser()
            p1.read(str(main_conf.resolve()))
            p1.set('Organization Validation', str('org_' + org), str(Path(conf)))
            with open(str(main_conf.resolve()), 'w') as f:
                p1.write(f)
            # Create org entry in key.d
            key_dir = Path( keyd / org_name )
            if not os.path.exists(str(key_dir)):
                os.makedirs(str(key_dir))
            # Get active org validations
            vals = active_org_val(org)
            a = []
            if vals.get('validations'):
                for val in vals['validations']:
                    # If active, set in configuration file
                    if val['status'] == 'active':
                        a.append(val['type'])
            # Else submit for validation
            else:
                submit_org(org)
            # Create org.conf
            p2 = configparser.ConfigParser()
            p2.read(str(conf))
            p2.add_section('Initialized Org')
            p2.set('Initialized Org', 'id', org)
            p2.set('Initialized Org', 'name', org_name)
            p2.set('Initialized Org', 'validated_for', ', '.join(a))
            p2.set('Initialized Org', 'key_dir', str(key_dir.resolve()))
            with open(str(conf), 'w+') as f:
                p2.write(f)
        else:
            'Please choose y or n'
        # If no active validations, submit for validation
        print('Org ' + org + ' was initialized: ' + str(conf))

    # Validate domain
    if args.init_dom:
        print('Initializing domain...')
        # Pick from list of existing domains
        resp = list_domains()
        list = []
        col = ['Domain ID', 'Domain', 'Activated', 'Validation Status']
        list.append(col)
        for dom in resp["domains"]:
            if dom.get('validations'):
                array = []
                array.append(str(dom['id']))
                array.append(dom['name'])
                if dom['is_active'] == True:
                    array.append('yes')
                else:
                    array.append('no')
                for validated in dom['validations']:
                    val_array = []
                    val_array.append(validated['type'])
                array.append(', '.join(val_array))
                list.append(array)
            else:
                array = []
                array.append(str(dom['id']))
                array.append(dom['name'])
                if dom['is_active'] == True:
                    array.append('yes')
                else:
                    array.append('no')
                array.append('')
                list.append(array)
        paginate(list, 10)
        # Get domain info by did
        did = input('Which domain do you want to configure? (Use domain id) ')
        dom_resp = view_domain(did,'json')
        # Get org.conf path
        x = str(dom_resp['organization']['id']) + '.conf'
        org_conf = Path(confd_org / x)
        # Print error if org.conf doesnt exist
        if not os.path.exists(str(org_conf)):
            print('Error: Initialize org ' + str(dom_resp['organization']['id']))
        else:
            conf = Path(confd_dom / str(did + '.conf'))
            if os.path.exists(str(conf)):
                os.remove(str(conf))
            # Add domain to init.conf
            p1 = configparser.ConfigParser()
            p1.read(str(main_conf))
            p1.set('Domain Validation', str('dom_' + did), str(Path(conf)))
            with open(str(main_conf), 'w') as f:
                p1.write(f)
            # Create domain.conf
            p2 = configparser.ConfigParser()
            p2.read(str(conf))
            p2.add_section('Initialized Domain')
            p2.set('Initialized Domain', 'id', did)
            p2.set('Initialized Domain', 'name', dom_resp['name'])
            p2.set('Initialized Domain', 'org', str(dom_resp['organization']['id']))
            p2.set('Initialized Domain', 'dcv_status', dom_resp['status'])
            # If domain is validated, set validation
            if dom['is_active'] == True:
                p2.set('Initialized Domain', 'activated', 'yes')
            # Else submit domain for validation
            else:
                p2.set('Initialized Domain', 'activated', 'no')
                submit_domain(did)
            with open(str(conf), 'w+') as f:
                p2.write(f)
            print('Domain ' + did + ' was initialized: ' + str(conf))

    # If crt subparser
    if args.cmd == 'crt':
        # List orders on account
        if args.list_crt:
            try:
                resp = list_cert()
                paginate(resp,10)
            except:
                raise Exception('Unable to list certificates.')

        # View a orders details
        if args.view_crt:
            try:
                resp = view_cert(args.view_crt, 'list')
                paginate(resp,10)
            except:
                raise TypeError('Argument is not an integer.')

        # Enroll in new certificate
        if args.new_crt:
            try:
                new_cert(args.new_crt)
            except:
                raise Exception('Unable to enroll new certificate.')

        # Revoke certificate
        if args.revoke_crt:
            try:
                cmt = input('Why are you revoking this order? ')
                revoke_cert(args.revoke_crt, cmt)
            except:
                raise Exception('Unable to revoke certificate.')

        # Edit certificate order
        if args.edit_crt:
            try:
                reissue_cert(args.edit_crt)
            except:
                raise Exception('Unable to reissue certificate.')
        # Get duplicate certificate
        if args.duplicate_crt:
            try:
                duplicate_cert(args.duplicate_crt)
            except:
                raise Exception('Unable to request duplicate certificate.')
        # List all created duplicates on an order
        if args.duplicate_list:
            try:
                resp = list_duplicates(args.duplicate_list)
                # Create pages from json
                list = []
                col = ['Commmon Name', 'Serial Number', 'Status', 'Date Issued', 'Valid Till', 'Key Size', 'Requested By']
                list.append(col)
                for i in resp['certificates']:
                    array = []
                    array.append(i['common_name'])
                    array.append(i['serial_number'])
                    array.append(i['status'])
                    array.append(i['valid_from'])
                    array.append(i['valid_till'])
                    array.append(str(i['key_size']))
                    fname = i['firstname']
                    lname = i['lastname']
                    usrname = fname + ' ' + lname
                    array.append(usrname)
                    list.append(array)
                paginate(list,10)
            except:
                raise Exception('Unable to list duplicate certificates of order ' + str(args.duplicate_list))
    # If dom subparser
    if args.cmd == 'dom':
        # List Domains
        if args.list_dom:
            try:
                resp = list_domains()
                list = []
                col = ['Domain ID','Domain Name','Parent Org','Parent Org ID','DCV Method','Validated For']
                list.append(col)
                for domain in resp['domains']:
                    if domain['is_active'] == True:
                        array = []
                        array.append(str(domain['id']))
                        array.append(domain['name'])
                        array.append(domain['organization']['name'])
                        array.append(str(domain['organization']['id']))
                        if domain.get('dcv_method'):
                            if domain['dcv_method'] == 'dns-cname-token':
                                array.append('cname')
                            elif domain['dcv_method'] == 'dns-txt-token':
                                array.append('txt')
                            elif domain['dcv_method'] == 'http-token':
                                array.append('http')
                            elif domain['dcv_method'] == 'email':
                                array.append('email')
                        else:
                            array.append('')
                        array_val = []
                        if domain.get('validations'):
                            for val in domain['validations']:
                                if val['status'] == 'active':
                                    array_val.append(val['type'])
                        array.append(', '.join(array_val))
                        list.append(array)
                paginate(list,10)
            except:
                raise LookupError('Unable to list domains on account.')
        # Activate domain
        if args.activate_dom:
            try:
                resp = activate_domain(args.activate_dom)
                if resp.status_code == 204:
                    colorize('green')
                    print('Domain ' + str(args.activate_dom) + ' has been activated.\n')
                    colorize_edit('reset')
            except:
                raise LookupError('Unable to activate the domain with Digicert.')
        # Deactivate domain
        if args.deactivate_dom:
            try:
                resp = deactivate_domain(args.deactivate_dom)
                if resp.status_code == 204:
                    colorize('green')
                    print('Domain ' + str(args.deactivate_dom) + ' has been deactivated.\n')
                    colorize_edit('reset')
            except:
                raise LookupError('Unable to deactivate the domain with Digicert.')
        # Submit domain for validation
        if args.submit_dom:
            try:
                resp = submit_domain(args.submit_dom)
            except:
                raise LookupError('Unable to submit domain for validation.')
        # Domain control verification
        if args.dcv:
            try:
                do_dcv(args.dcv)
            except:
                raise LookupError('Unable to submit domain for domain control verification.')
        # Check DNS for DCV
        if args.dns:
            try:
                token = input('Enter the random string: ')
                did = input('Enter the domain ID: ')
                resp = test_dns(did, args.dns, token)
                print('Domain ID ' + did + ' has been approved. Status: ' + resp['status'])
            except:
                raise LookupError('Failed to test DNS records.')
        # Add a new domain
        if args.new_dom:
            try:
                print('Org must first be approved for OV or EV to create domain.')
                dom_name = input('Enter the new domain name: ')
                while not regex_test.match(dom_name):
                    dom_name = input('Enter a valid domain name: ')
                list = []
                col = ['Org ID','Org Name','St Address', 'Validation Status']
                list.append(col)
                org_list = list_org('y','y')
                paginate(org_list,10)
                oid = input('Create domain under which org? [Enter Org ID] ')
                resp = new_domain(dom_name, oid, args.new_dom)
                print('Domain ' + dom_name + ' has been created. Domain ID: ' + str(resp['id']))
            except:
                raise LookupError('Unable to create new domain with Digicert.')
        # View domain information by domain id
        if args.view_dom:
            try:
                resp = view_domain(args.view_dom, 'list')
                paginate(resp,10)
            except:
                raise LookupError('Unable to grab domain information from Digicert.')
    # If crt subparser
    if args.cmd == 'org':
        # List organization
        if args.list_org:
            try:
                resp = list_org('y','y')
                paginate(resp,10)
            except:
                raise LookupError('Unable to retrieve information from Digicert.')
        # View organization details
        if args.view_org:
            try:
                resp = view_org(args.view_org)
                list = []
                col = ['Org ID', 'Org Name', 'Address', 'Phone', 'Org Contact', 'Activated']
                list.append(col)
                array = []
                array.append(str(resp['id']))
                array.append(resp['name'])
                array.append(resp['address'])
                array.append(resp['telephone'])
                contact = resp['organization_contact']['first_name'] + ' ' + resp['organization_contact']['last_name']
                array.append(contact)
                array.append(str(resp['is_active']))
                list.append(array)
                paginate(list,10)
            except:
                raise LookupError('Unable to vretrieve org information from Digicert.')

    # If request subparser
    if args.cmd == 'req':
        # List requests
        if args.list_req:
            try:
                if args.list_req == 'pending':
                    resp = list_requests('y','y')
                    paginate(resp,10)
                if args.list_req == 'all':
                    resp = list_requests('y','n')
                    paginate(resp,10)
            except:
                raise LookupError('Unable to retrieve request information from Digicert.')
        # View request
        if args.view_req:
            try:
                req = view_request(args.view_req)
                list = []
                col = ['Request ID', 'Date Requested', 'Status', 'Type', 'Order ID', 'Requested By', 'Approved By']
                list.append(col)
                array = []
                array.append(str(req['id']))
                array.append(req['date'])
                array.append(req['status'])
                array.append(req['type'])
                array.append(str(req['order']['id']))
                requester_fname = req['requester']['first_name']
                requester_lname = req['requester']['last_name']
                requester_name = requester_fname + ' ' + requester_lname
                array.append(requester_name)
                if req.get('processor'):
                    approver_fname = req['processor']['first_name']
                    approver_lname = req['processor']['last_name']
                    approver_name = approver_fname + ' ' + approver_lname
                    array.append(approver_name)
                else:
                    approver_name = ' '
                    array.append(approver_name)
                list.append(array)
                paginate(list,10)
            except:
                raise LookupError('Unable to retrieve request information from Digicert.')
        # Reject pending request
        if args.reject_req:
            try:
                cmt = input('Why are you rejecting this request? ')
                update_request(args.reject_req,'rejected',cmt)
                colorize('cyan')
                print('Successfully rejected request.')
                colorize_edit('reset')
            except:
                raise LookupError('Unable to update request status with Digicert.')
        # Approve pending request
        if args.approve_req:
            try:
                cmt = input('Why are you approving this request? ')
                update_request(args.approve_req,'approved',cmt)
                colorize('cyan')
                print('Successfully approved request.')
                colorize_edit('reset')
            except:
                raise LookupError('Unable to update request status with Digicert.')
    # If user subparser
    if args.cmd == 'usr':
        # Add a new user
        if args.new_usr:
            try:
                resp = new_usr()
            except:
                raise LookupError('Unable to create new user with Digicert.')
        # Edit an existing user
        if args.edit_usr:
            try:
                edit_usr(args.edit_usr)
            except:
                raise LookupError('Unable to edit user information with Digicert.')
        # View information about a user
        if args.view_usr:
            try:
                view_usr(args.view_usr)
            except:
                raise LookupError('Unable to retrieve user information from Digicert.')
        # Delete a user
        if args.delete_usr:
            try:
                delete_usr(args.del_usr)
            except:
                raise LookupError('Unable to delete user from the Digicert account.')
        # List all users on account
        if args.list_usr:
            try:
                resp = list_usr('y')
                paginate(resp,10)
            except:
                raise LookupError('Unable to retrieve user information from Digicert.')
        # Check API Key permissions
        if args.check_api:
            try:
                resp = check_api_key()
                list = []
                col = ['Username', 'Status',  'Access Role', 'Division']
                list.append(col)
                array = []
                array.append(resp['username'])
                array.append(resp['status'])
                roles = []
                for role in resp['access_roles']:
                    roles.append(role['name'])
                array.append(', '.join(roles))
                array.append(resp['container']['name'])
                list.append(array)
                paginate(list, 10)
            except:
                raise Exception('Unable to check status of API key.')
    # If cryptography subparser
    if args.cmd == 'crypto':
        if args.new_csr:
            try:
                # Get UTF 8 encoded CSR
                gen_custom_csr(args.new_csr)
            except:
                raise Exception('Failed to generate new CSR and private key.')
        if args.new_key:
            try:
                # Get UTF 8 encoded key
                key = gen_key(args.new_key)
                with open('private.key','wb') as sf:
                    sf.write(key.private_bytes(
                        encoding=serialization.Encoding.PEM,
                        format=serialization.PrivateFormat.TraditionalOpenSSL,
                        encryption_algorithm=serialization.NoEncryption()
                        ))
            except:
                raise Exception('Failed to generate new private key')
        if args.decode_crt:
            cert_path = Path(str(args.decode_crt))
            # Validate filepath to cert
            try:
                if cert_path.exists() and cert_path.is_file():
                    serialized = decode_cert(cert_path)
            except:
                raise Exception('Failed to decode certificate.')
예제 #10
0
def new_cert(type):
    # Pick org
    orgs = get_active_org()
    list = []
    col = ['Org id', 'Org Name', 'Display Name']
    list.append(col)
    for org in orgs['organizations']:
        array = []
        array.append(str(org['id']))
        array.append(org['name'])
        array.append(org['display_name'])
        list.append(array)
    paginate(list,10)
    oid = input('Pick organization id: ')
    # Get org name with oid
    org_name = view_org(oid)['name']
    # Test common name
    cn = input('Enter a common name: ')
    while not regex_test.match(cn):
        cn = input('Enter a valid common name: ')
    # Get array of SANs
    sans = []
    print('Type Subject Alternate Name and press enter (Enter d when done):')
    while 1 == 1:
        san = input('')
        if san == 'd':
            break
        elif not regex_test.match(san):
            print(san + ' is not a valid SAN')
        else:
            sans.append(san)
    # Create new entry in key.d for order
    x = oid + '.conf'
    org_conf = Path(confd_org / x)
    if not os.path.exists(str(org_conf)):
        print('Error: Initialize org ' + oid)
    else:
        # Saves key and csr temporarily in the org folder until order id is created
        with open(str(org_conf)) as oc:
            p = ConfigParser()
            p.read(str(org_conf))
            safe = p.get('Initialized Org', 'key_dir')
            key_path = safe + '/private.key'
            csr_path = safe + '/request.csr'
        # Generate and save private key
        alg = input('Create a ECC or RSA private key? ' )
        while not alg in ['ecc','rsa']:
            colorize('red')
            alg = input('Enter ECC or RSA: ')
            colorize_edit('reset')
        key = gen_key(alg)
        with open(key_path, 'wb+') as f:
            f.write(key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption()
                ))
        # Generate a CSR from private key
        csr = gen_csr(key)
        # Save csr
        with open(csr_path, 'w+') as f:
            f.write(csr)
        # Choose signature hash
        algs = ['1] sha256', '2] sha384', '3] sha512']
        print('Signature hash algorithms')
        print(*algs, sep='\t')
        alg = int(input('Choose an algorithm [1-3]: '))
        if alg == 1:
            hash_alg = 'sha256'
        elif alg == 2:
            hash_alg = 'sha384'
        elif alg == 3:
            hash_alg = 'sha512'
        else:
            hash_alg = 'sha256'
            print('Default delected: sha256')
        # Choose validity period
        val_periods = ['1] 1 year', '2] 2 year', '3] Custom Expiration']
        print(*val_periods, sep='\t')
        val_period = int(input('Choose certificate lifetime [1-3]: '))
        if val_period == 1:
            time = 1
        elif val_period == 2:
            time = 2
        else:
            time = 3
            custom = input('Pick a custom certificate lifetime in format YYYY-MM-DD: ')
            regx = re.compile('([0-9]{4}(\-){1}([0-9]){2}(\-){1}([0-9]){2})')
            while not regx.match(custom):
                print('Incorrect format. Try again.')
                custom = input('Pick a custom certificate lifetime in format YYYY-MM-DD: ')
        # List options for file format
        formats = ['1] p7b', '2] pem', '3] pem bundle', '4] code signing', '5] other']
        print('Possible file formats: ')
        print(*formats, sep='\t')
        format = int(input('Choose a format [1-5]: '))
        # Choose server platform
        if format == 1:
            platform = 10
        elif format == 2:
            platform = 2
        elif format == 3:
            platform = 45
        elif format == 4:
            platform = 55
        elif format == 5:
            platform = -1
        # Set server platform to Sun Java for code signing
        elif args.new_cert == 'cs':
            platform = 55
        else:
            print('Default chosen: pem format')
            platform = -1
        # If custom expiraion, include correct payload
        if time == 1 or time == 2:
            payload = {
              'certificate': {
                'common_name': cn,
                'dns_names': sans,
                'csr': csr,
                'server_platform': {
                  'id': int(platform)
                },
                'signature_hash': hash_alg
              },
              'organization': {
                'id': int(oid)
              },
              'validity_years': int(time),
              'product': {
                'type_hint': type
              }
            }
        else:
            print('Time == 3')
            payload = {
              'certificate': {
                'common_name': cn,
                'dns_names': sans,
                'csr': str(csr.public_bytes(serialization.Encoding.PEM), 'utf-8'),
                'server_platform': {
                  'id': int(platform)
                },
                'signature_hash': hash_alg
              },
              'organization': {
                'id': int(oid)
              },
              'validity_years': 1,
              'custom_expiration_date': custom,
              'product': {
                'type_hint': type
              }
            }
        payload_data = json.dumps(payload)
        req_url = url + '/ssl'
        req = requests.post(req_url, headers=headers_post, data=payload_data)
        rest_status(req)
        # Move key to new key.d
        with open(str(org_conf)):
            p = ConfigParser()
            p.read(str(org_conf))
            safe = p.get('Initialized Org', 'key_dir')
            temp_key = safe + '/private.key'
        dir = Path(safe + '/' + str(req.json()['id']) + '.d')
        if not os.path.exists(str(dir)):
            os.makedirs(str(dir))
        key_name = Path(str(str(req.json()['id']) + '.key'))
        saved_key = Path( dir / key_name )
        with open(temp_key, 'r') as tk:
            t = tk.read()
        with open(str(saved_key), 'w+') as sk:
            sk.write(t)
        os.remove(temp_key)
        # Move csr to order.d
        temp_csr = Path( safe + '/request.csr')
        saved_csr = Path( dir / Path(str(str(req.json()['id']) + '.csr')) )
        with open(str(temp_csr), 'r') as tc:
            tcsr = tc.read()
        with open(str(saved_csr), 'w+') as sc:
            sc.write(tcsr)
        os.remove(str(temp_csr))
        # Create pending req in cert.d
        conf_name = str(req.json()['id']) + '.conf'
        cert_conf = Path( confd_cert / conf_name )
        with open(str(cert_conf), 'w+') as cc:
            scp = ConfigParser()
            scp.read(str(cert_conf))
            scp.add_section('Initialized Cert')
            scp.set('Initialized Cert', 'id', str(req.json()['id']))
            scp.set('Initialized Cert', 'key_dir', str(dir))
            scp.set('Initialized Cert', 'status', 'pending')
            scp.write(cc)
        print('Successfully placed new order # ' + str(req.json()['id']) + '\n')
    return req.json()
예제 #11
0
def duplicate_cert(cid):
    # Get order information and load cert conf
    try:
        info = view_cert(cid,'json')
        ordernum = info['id']
        cert_path = Path(str(confd_cert) + '/' + cid + '.conf')
        r = ConfigParser()
        r.read(str(cert_path))
        cert_keyd = r.get('Initialized Cert', 'key_dir')
    except:
        raise LookupError('Missing cert.d entry. Reissue order with --reissue-crt.')
    # Get org information to create key.d
    org_id = info['organization']['id']
    org_name = info['organization']['name']
    # Generate and save private key
    alg = input('Create a ECC or RSA private key? ' )
    while not alg in ['ecc','rsa']:
        colorize('red')
        alg = input('Enter ECC or RSA: ')
        colorize_edit('reset')
    key = gen_key(alg)
    # Generate a CSR from private key
    dup_csr = gen_csr(key)
    # Get duplicate certificate information
    dups = list_duplicates(cid)
    # If no duplicates, create folder 001
    if not dups.get('certificates'):
        dup_keyd = Path(str(cert_keyd) + '/01.d')
        os.makedirs(str(dup_keyd))
    # Else count the number of dups and create new dup folder
    else:
        count = len(dups['certificates'])
        dup_num = count + 1
        dup_keyd = Path(str(cert_keyd) + '/0' + str(dup_num) + '.d')
        if dup_keyd.exists():
            try:
                shutil.rmtree(str(dup_keyd))
            except OSError as e:
                print("Error: %s - %s." % (e.filename,e.strerror))
        os.makedirs(str(dup_keyd))
    # Write CSR and KEY to new dup folder
    key_path = Path(str(dup_keyd) + '/private.key')
    with open(str(key_path), 'wb+') as f:
        f.write(key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()
            ))
    csr_path = Path(str(dup_keyd) + '/request.csr')
    with open(str(csr_path), 'w+') as f:
        f.write(dup_csr)
    # List options for file format
    formats = ['1] p7b', '2] pem', '3] pem bundle', '4] code signing', '5] other']
    print('Possible file formats: ')
    print(*formats, sep='\t')
    format = int(input('Choose a format [1-5]: '))
    # Choose server platform
    if format == 1:
        platform = 10
    elif format == 2:
        platform = 2
    elif format == 3:
        platform = 45
    elif format == 4:
        platform = 55
    elif format == 5:
        platform = -1
    else:
        print('Default chosen: pem format')
        platform = -1
    # Choose signature hash
    algs = ['1] sha256', '2] sha384', '3] sha512']
    print('Signature hash algorithms')
    print(*algs, sep='\t')
    alg = int(input('Choose an algorithm [1-3]: '))
    if alg == 1:
        hash_alg = 'sha256'
    elif alg == 2:
        hash_alg = 'sha384'
    elif alg == 3:
        hash_alg = 'sha512'
    else:
        hash_alg = 'sha256'
        print('Default selected: sha256')
    # Set common name
    cn = info['certificate']['common_name']
    colorize('blue')
    print("Current common name: " + cn)
    colorize_edit('reset')
    if info['product']['name_id'] == 'ssl_multi_domain' or info['product']['name_id'] == 'ssl_ev_multi_domain':
        # Convert sans list to array
        sans = info['certificate']['dns_names']
    if info['product']['name_id'] == 'ssl_cloud_wildcard' or info['product']['name_id'] == 'ssl_wildcard':
        # Get array of SANs
        sans = []
        print('Type Subject Alternate Name and press enter (Enter d when done):')
        while 1 == 1:
            san = input('')
            if san == 'd':
                break
            elif not regex_test.match(san):
                print(san + ' is not a valid SAN')
            else:
                sans.append(san)
    # Make payload and submit to Digicert
    payload = json.dumps({
        'certificate': {
        'common_name': cn,
        'dns_names':
            sans
        ,
        'csr': dup_csr,
        'server_platform': {
          'id': platform
        },
        'signature_hash': 'sha256'
        }
    })
    req_url = url + '/' + str(ordernum) + '/duplicate'
    req = requests.post(req_url, headers=headers_post, data=payload)
    rest_status(req)
    # Get certificate id by listing new duplicate
    ld = list_duplicates(ordernum)
    cert_id = ld['certificates'][0]['id']
    # Download based on server platform
    if format == 1:
        # Download new duplicate from Digicert
        dup_cert = download_cert_by_format(cert_id,'p7b')
        # Set filename based on server platform to p7b
        dup_cert_path = Path( str(dup_keyd) + '/cert.p7b' )
        with open(str(dup_cert_path), 'wb+') as save:
            save.write(dup_cert)
    elif format == 2:
        # Download new duplicate from Digicert
        dup_cert = download_cert_by_format(cert_id,'apache')
        # Set filename based on server platform to pem (individual pem without root)
        dup_cert_path = Path( str(dup_keyd) + '/cert.zip' )
        with open(str(dup_cert_path), 'wb+') as save:
            save.write(dup_cert)
    elif format == 3:
        # Download new duplicate from Digicert
        dup_cert = download_cert_by_format(cert_id,'pem_all')
        # Set filename based on server platform to pem bundle
        dup_cert_path = Path( str(dup_keyd) + '/cert.pem' )
        with open(str(dup_cert_path), 'wb+') as save:
            save.write(dup_cert)
    elif format == 4:
        # Download new duplicate from Digicert
        dup_cert = download_cert_by_format(cert_id,'cer')
        # Set filename based on server platform to code signing
        dup_cert_path = Path( str(dup_keyd) + '/cert.cer' )
        with open(str(dup_cert_path), 'wb+') as save:
            save.write(dup_cert)
    elif format == 5:
        # Download new duplicate from Digicert
        dup_cert = download_cert_by_format(cert_id,'default_pem')
        # Set filename based on server platform to other (individual pem including root)
        dup_cert_path = Path( str(dup_keyd) + '/cert.zip' )
        with open(str(dup_cert_path), 'wb+') as save:
            save.write(dup_cert)
    colorize('green')
    print('Duplicate successfully created in:\n' + str(dup_cert_path))
    colorize_edit('reset')
예제 #12
0
def reissue_cert(cid):
    # Get cid
    cert_info = view_cert(cid, 'json')
    order_no = str(cert_info['id'])
    req_url = url + '/' + order_no + '/reissue'
    # Get request org info
    org_name = cert_info['organization']['name']
    org_city = cert_info['organization']['city']
    org_state = cert_info['organization']['state']
    org_country = cert_info['organization']['country']
    oid = cert_info['organization']['id']
    # Print current information
    old_cn = str(cert_info['certificate']['common_name'])
    old_sans = ', '.join(cert_info['certificate']['dns_names'])
    colorize('blue')
    print('Current Certificate:')
    print('CN = ' + old_cn)
    print('SANs = ' + old_sans)
    colorize_edit('reset')
    # Get common name
    cn = input('Enter a new common name: ')
    while not regex_test.match(cn):
        cn = input('Enter a valid common name: ')
    # Get array of SANs
    sans = []
    print('Type Subject Alternate Name and press enter (Enter d when done):')
    while 1 == 1:
        san = input('')
        if san == 'd':
            break
        elif not regex_test.match(san):
            print(san + ' is not a valid SAN')
        else:
            sans.append(san)
    # Load existing conf and private key if exists
    order_conf = Path( str(confd_cert) + '/' + str(order_no) + '.conf')
    org_conf = Path( str(confd_org) + '/' + str(oid) + '.conf' )
    if os.path.exists(str(order_conf)):
        with open(str(order_conf), 'r'):
            scp = ConfigParser()
            scp.read(str(order_conf))
            key_dir = scp.get('Initialized Cert', 'key_dir')
            key_path = Path( key_dir + '/' + str(order_no) + '.key')
            csr_path = Path( key_dir + '/' + str(order_no) + '.csr')
            with open(str(key_path), 'rb') as f:
                key_bytes = f.read()
                key = load_pem_private_key(key_bytes, None, default_backend())
                # Generate a CSR from private key and org info
                signed_req = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
                    x509.NameAttribute(NameOID.COUNTRY_NAME, org_country),
                    x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, org_state),
                    x509.NameAttribute(NameOID.LOCALITY_NAME, org_city),
                    x509.NameAttribute(NameOID.ORGANIZATION_NAME, org_name),
                    x509.NameAttribute(NameOID.COMMON_NAME, cn),
                    ])).sign(key, hashes.SHA256(), default_backend())
                csr = str(signed_req.public_bytes(serialization.Encoding.PEM), 'utf-8')
                # Save CSR
                with open(str(csr_path), 'w+') as f:
                    f.write(csr)
    # Create new conf file
    else:
        order_keyd = Path( str(keyd) + '/' + org_name + '/' + str(order_no) + '.d' )
        with open(str(order_conf), 'w+') as f:
            scp = ConfigParser()
            scp.read(str(order_conf))
            scp.add_section('Initialized Cert')
            scp.set('Initialized Cert', 'id', str(order_no))
            scp.set('Initialized Cert', 'key_dir', str(order_keyd))
            scp.set('Initialized Cert', 'status', cert_info['status'])
            scp.write(f)
        # Generate and save private key
        alg = input('Create a ECC or RSA private key? ' )
        while not alg in ['ecc','rsa']:
            colorize('red')
            alg = input('Enter ECC or RSA: ')
            colorize_edit('reset')
        key = gen_key(alg)
        key_path = Path( str(order_keyd) + '/' + str(order_no) + '.key' )
        if not os.path.exists(str(order_keyd)):
            os.makedirs(str(order_keyd))
        with open(str(key_path), 'wb+') as f:
            f.write(key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption()
                ))
        # Generate csr
        csr_path = Path( str(order_keyd) + '/' + str(order_no) + '.csr' )
        csr = gen_csr(key)
        with open(str(csr_path), 'w+') as f:
            f.write(csr, 'utf-8')
    # Choose signature hash
    algs = ['1] sha256', '2] sha384', '3] sha512']
    print('Signature hash algorithms')
    print(*algs, sep='\t')
    alg = int(input('Choose an algorithm [1-3]: '))
    if alg == 1:
        hash_alg = 'sha256'
    elif alg == 2:
        hash_alg = 'sha384'
    elif alg == 3:
        hash_alg = 'sha512'
    else:
        hash_alg = 'sha256'
        print('Default selected: sha256')
    # Create payload
    payload = json.dumps({
      'certificate': {
        'common_name': cn,
        'dns_names': sans,
        'csr': csr,
        'signature_hash': hash_alg
      }
    })
    req = requests.post(req_url, headers=headers_post, data=payload)
    rest_status(req)
    colorize('green')
    print('Reissue for ' + cn + ' has been submitted to Digicert for processing.\n')
    colorize_edit('reset')
    return req.json()
예제 #13
0
def do_dcv(type):
    # List pending/expired domains
    resp = list_domains()
    list = []
    col = ['Domain ID', 'Domain Name', 'Status']
    list.append(col)
    for dom in resp['domains']:
        if dom.get('validations'):
            for val in dom['validations']:
                if val.get('dcv_status'):
                    if val['dcv_status'] == 'expired':
                        array = []
                        array.append(dom['id'])
                        array.append(dom['name'])
                        array.append(val['dcv_status'])
                        list.append(array)
                    elif val['dcv_status'] == 'pending':
                        array = []
                        array.append(dom['id'])
                        array.append(dom['name'])
                        array.append(val['dcv_status'])
                        list.append(array)
    print('Showing Pending/Expired DCV\'s: ')
    paginate(list, 10)
    # Prompt user for domain id to submit DCV for
    did = input('\nEnter Domain ID: ')
    # Choose DCV option by switch value
    if type == 'email':
        # Change domain to new DCV
        payload = json.dumps({'dcv_method': 'email'})
        choose_dcv(did, payload)
        # Get domain control emails
        emails = dcv_emails(did)
        colorize('green')
        print('\nEmails were sent to:\n')
        colorize_edit('reset')
        for email in emails['base_emails']:
            print(' ' + email)
        for email in emails['whois_emails']:
            print(' ' + email)
        print('\n')
    if type == 'txt':
        # Change domain to new DCV
        payload = json.dumps({'dcv_method': 'dns-txt-token'})
        resp = choose_dcv(did, payload)
        dcv = resp['dcv_token']
        colorize('green')
        print('Create a TXT record in your domains DNS: \n')
        colorize_edit('reset')
        print('Random String: ' + dcv['token'])
        print('Status: ' + dcv['status'])
        print('String Expires On: ' + dcv['expiration_date'])
        print('\n')
    if type == 'cname':
        # Change domain to new DCV
        payload = json.dumps({'dcv_method': 'dns-cname-token'})
        resp = choose_dcv(did, payload)
        dcv = resp['dcv_token']
        colorize('green')
        print('Create a CNAME record in your DNS: \n')
        colorize_edit('reset')
        print('Random String: ' + dcv['token'])
        print('Target: ' + dcv['verification_value'])
        print('Domain Status: ' + dcv['status'])
        print('Example: ' + dcv['token'] + '.[yourdomain].com -> ' +
              dcv['verification_value'])
        print('\n')
예제 #14
0
파일: crypto.py 프로젝트: kuan51/dcli
def gen_custom_csr(alg):
    # Generate private key
    key = gen_key(alg)
    with open('private.key','xb') as sf:
        sf.write(key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()
            ))
    # Compile custom csr info
    try:
        ctry = input('What country are you located in: ')
        ctry_code = get_ctry_code(ctry)
    except:
        raise LookupError('Unable to find matching country code for ' + ctry)
    st = input('What locality are you located in: ')
    city = input('What city are you located in: ')
    org = input('What organization is the request for (Example, Inc): ')
    cn = input('Enter a common name (example.com): ')
    while not regex_test.match(cn):
        colorize('red')
        print(cn + ' is not a valid common name.')
        colorize_edit('reset')
        cn = input('Enter a common name (example.com): ')
    # Get array of SANs
    test = input('Enter SANs? [y/n]: ')
    while not test in [ 'y', 'n']:
        print('Choose y or n')
        test = input('Enter SANs? [y/n]: ')
    if test == 'y':
        sans = []
        print('Type Subject Alternate Name and press enter (Enter d when done):')
        while 1 == 1:
            san = input('')
            if san == 'd':
                break
            elif not regex_test.match(san):
                print(san + ' is not a valid SAN')
            else:
                sans.append(san)
        csr_sans = []
        for san in sans:
            string = x509.DNSName("(%s)" % san)
            csr_sans.append(string)
        csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
            x509.NameAttribute(NameOID.COUNTRY_NAME, ctry_code ),
            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, st ),
            x509.NameAttribute(NameOID.LOCALITY_NAME, city ),
            x509.NameAttribute(NameOID.ORGANIZATION_NAME, org ),
            x509.NameAttribute(NameOID.COMMON_NAME, cn ),
        ])).add_extension(
            # Define SANs
            x509.SubjectAlternativeName(csr_sans),
        critical=False,
        # Sign the CSR with key
        ).sign(key, hashes.SHA256(), default_backend())
    else:
        csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
            x509.NameAttribute(NameOID.COUNTRY_NAME, ctry_code ),
            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, st ),
            x509.NameAttribute(NameOID.LOCALITY_NAME, city ),
            x509.NameAttribute(NameOID.ORGANIZATION_NAME, org ),
            x509.NameAttribute(NameOID.COMMON_NAME, cn ),
        ])).add_extension(
            # Define SANs
            x509.SubjectAlternativeName(''),
        critical=False,
        # Sign the CSR with key
        ).sign(key, hashes.SHA256(), default_backend())
    with open('request.csr', 'xt') as sf:
        sf.write(str(csr.public_bytes(serialization.Encoding.PEM), 'utf-8'))