Created
September 14, 2019 10:57
-
-
Save yosshy/d90a8d6a536e884af5edeefe612e214d to your computer and use it in GitHub Desktop.
gen_cert: Generate X509 Certificate and Private Key
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# usage: gen_cert [-h] [-C COUNTRY] [-ST STATE] [-L LOCALITY] [-O ORGANIZATION] | |
# [-OU ORGANIZATION_UNIT] [-CN COMMON_NAME] [-E EMAIL_ADDRESS] | |
# [-p PERIOD] [-d DNS] [-i IP] [-s SERIAL] | |
# certfile keyfile | |
# | |
# Generate X509 Certificate and Private Key | |
# | |
# positional arguments: | |
# certfile | |
# keyfile | |
# | |
# optional arguments: | |
# -h, --help show this help message and exit | |
# -C COUNTRY, --country COUNTRY | |
# Country Name (2 letter code) | |
# -ST STATE, --state STATE | |
# State or Province Name (full name) | |
# -L LOCALITY, --locality LOCALITY | |
# Location; city name | |
# -O ORGANIZATION, --organization ORGANIZATION | |
# Organization Name (eg, company) | |
# -OU ORGANIZATION_UNIT, --organization-unit ORGANIZATION_UNIT | |
# Organizational Unit Name (eg, section) | |
# -CN COMMON_NAME, --common-name COMMON_NAME | |
# Common Name (e.g. server FQDN or YOUR name) | |
# -E EMAIL_ADDRESS, --email-address EMAIL_ADDRESS | |
# Email Address | |
# -p PERIOD, --period PERIOD | |
# Period to expire in days | |
# -d DNS, --dns DNS Additional DNS name; multiple usage allowed | |
# -i IP, --ip IP Additional IP address; multiple usage allowed | |
# -s SERIAL, --serial SERIAL | |
# Serial number | |
import argparse | |
from OpenSSL import crypto | |
from socket import gethostname | |
def main(certfile=None, keyfile=None, country=None, state=None, | |
locality=None, organization=None, organization_unit=None, | |
common_name=None, email_address=None, period=None, | |
dns=None, ip=None, serial=None): | |
key = crypto.PKey() | |
key.generate_key(crypto.TYPE_RSA, 2048) | |
cert = crypto.X509() | |
subject = cert.get_subject() | |
if country: | |
subject.C = country | |
if state: | |
subject.ST = state | |
if locality: | |
subject.L = locality | |
if organization: | |
subject.O = organization # noqa:E741 | |
if organization_unit: | |
subject.OU = organization_unit | |
subject.CN = common_name | |
if email_address: | |
subject.emailAddress = email_address | |
cert.set_serial_number(serial) | |
cert.gmtime_adj_notBefore(0) | |
cert.gmtime_adj_notAfter(period*24*60*60) | |
cert.set_issuer(cert.get_subject()) | |
cert.set_pubkey(key) | |
extensions = [ | |
crypto.X509Extension( | |
"basicConstraints".encode("ascii"), | |
False, | |
"CA:FALSE".encode("ascii")), | |
] | |
san = [] | |
if dns: | |
san += ["DNS:%s" % x for x in dns] | |
if ip: | |
san += ["IP:%s" % x for x in ip] | |
if san: | |
extensions.append( | |
crypto.X509Extension( | |
"subjectAltName".encode("ascii"), | |
False, | |
",".join(san).encode("ascii")) | |
) | |
cert.add_extensions(extensions) | |
cert.set_version(2) | |
cert.sign(key, "sha256") | |
certfile.write( | |
crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode("utf-8")) | |
certfile.close() | |
keyfile.write( | |
crypto.dump_privatekey(crypto.FILETYPE_PEM, key).decode("utf-8")) | |
keyfile.close() | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser( | |
description="Generate X509 Certificate and Private Key") | |
parser.add_argument("certfile", type=argparse.FileType("wx")) | |
parser.add_argument("keyfile", type=argparse.FileType("wx")) | |
parser.add_argument("-C", "--country", | |
help="Country Name (2 letter code)") | |
parser.add_argument("-ST", "--state", | |
help="State or Province Name (full name)") | |
parser.add_argument("-L", "--locality", | |
help="Location; city name") | |
parser.add_argument("-O", "--organization", | |
help="Organization Name (eg, company)") | |
parser.add_argument("-OU", "--organization-unit", | |
help="Organizational Unit Name (eg, section)") | |
parser.add_argument("-CN", "--common-name", | |
help="Common Name (e.g. server FQDN or YOUR name)", | |
default=gethostname()) | |
parser.add_argument("-E", "--email-address", | |
help="Email Address") | |
parser.add_argument("-p", "--period", type=int, | |
help="Period to expire in days", | |
default=365) | |
parser.add_argument("-d", "--dns", action='append', | |
help="Additional DNS name; multiple usage allowed") | |
parser.add_argument("-i", "--ip", action='append', | |
help="Additional IP address; multiple usage allowed") | |
parser.add_argument("-s", "--serial", type=int, | |
help="Serial number", | |
default=1000) | |
args = parser.parse_args() | |
main(**args.__dict__) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment