Merge 1a3075bd9c
into 6549656108
commit
3869b008c0
|
@ -22,3 +22,11 @@ csrgen <hostname> -s <san0> <san1>
|
||||||
```
|
```
|
||||||
python csrgen test.test.com -s mushu.test.com pushu.test.com
|
python csrgen test.test.com -s mushu.test.com pushu.test.com
|
||||||
```
|
```
|
||||||
|
When you do not want to be prompted for locality, you can use a config file.
|
||||||
|
This can be acheived by adding -c. (SAN request still work)
|
||||||
|
|
||||||
|
Usage: csrgen <hostnaem> -c your_config -s <san0> <san1>
|
||||||
|
|
||||||
|
```
|
||||||
|
python csrgen test.test.com -c csrgen.conf -s mushu.test.com pushu.test.com
|
||||||
|
```
|
||||||
|
|
113
csrgen.py
113
csrgen.py
|
@ -9,16 +9,18 @@
|
||||||
#
|
#
|
||||||
# Author: Courtney Cotton <cotton@cottoncourtney.com> 06-25-2014
|
# Author: Courtney Cotton <cotton@cottoncourtney.com> 06-25-2014
|
||||||
|
|
||||||
# Libraries/Modules
|
# Contributor: Gary Waters <gwaters@caltech.edu> 01-05-2017 (added external config file)
|
||||||
|
|
||||||
|
# Libraries/Modules
|
||||||
import argparse
|
import argparse
|
||||||
|
import ConfigParser
|
||||||
from OpenSSL import crypto
|
from OpenSSL import crypto
|
||||||
|
|
||||||
|
|
||||||
# Generate Certificate Signing Request (CSR)
|
# Generate Certificate Signing Request (CSR)
|
||||||
def generateCSR(nodename, sans = []):
|
def generateCSR(nodename, sans = [], config_file = None):
|
||||||
|
|
||||||
while True:
|
while not config_file:
|
||||||
C = raw_input("Enter your Country Name (2 letter code) [US]: ")
|
C = raw_input("Enter your Country Name (2 letter code) [US]: ")
|
||||||
if len(C) != 2:
|
if len(C) != 2:
|
||||||
print "You must enter two letters. You entered %r" % (C)
|
print "You must enter two letters. You entered %r" % (C)
|
||||||
|
@ -40,53 +42,80 @@ def generateCSR(nodename, sans = []):
|
||||||
print "Please enter your OU."
|
print "Please enter your OU."
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Allows you to permanently set values required for CSR
|
# Allows you to permanently set values required for CSR
|
||||||
# To use, comment raw_input and uncomment this section.
|
# To use, comment raw_input and uncomment this section.
|
||||||
# C = 'US'
|
# C = 'US'
|
||||||
# ST = 'New York'
|
# ST = 'New York'
|
||||||
# L = 'Location'
|
# L = 'Location'
|
||||||
# O = 'Organization'
|
# O = 'Organization'
|
||||||
# OU = 'Organizational Unit'
|
# OU = 'Organizational Unit'
|
||||||
|
|
||||||
csrfile = 'host.csr'
|
csrfile = 'host.csr'
|
||||||
keyfile = 'host.key'
|
keyfile = 'host.key'
|
||||||
TYPE_RSA = crypto.TYPE_RSA
|
TYPE_RSA = crypto.TYPE_RSA
|
||||||
# Appends SAN to have 'DNS:'
|
# Appends SAN to have 'DNS:'
|
||||||
ss = []
|
ss = []
|
||||||
for i in sans:
|
for i in sans:
|
||||||
ss.append("DNS: %s" % i)
|
ss.append("DNS: %s" % i)
|
||||||
ss = ", ".join(ss)
|
ss = ", ".join(ss)
|
||||||
|
|
||||||
req = crypto.X509Req()
|
req = crypto.X509Req()
|
||||||
req.get_subject().CN = nodename
|
req.get_subject().CN = nodename
|
||||||
|
|
||||||
|
if config_file:
|
||||||
|
config = ConfigParser.ConfigParser()
|
||||||
|
conf = {}
|
||||||
|
try:
|
||||||
|
file = open(config_file, 'r')
|
||||||
|
config.read(config_file)
|
||||||
|
conf.update({"country_name": config.get("location", "country_name")})
|
||||||
|
conf.update({"state_or_province_name": config.get("location", "state_or_province_name")})
|
||||||
|
conf.update({"locality_name": config.get("location", "locality_name")})
|
||||||
|
conf.update({"organization_name": config.get("location", "organization_name")})
|
||||||
|
conf.update({"organizational_unit_name": config.get("location", "organizational_unit_name")})
|
||||||
|
req.get_subject().countryName = conf['country_name']
|
||||||
|
req.get_subject().stateOrProvinceName = conf['state_or_province_name']
|
||||||
|
req.get_subject().localityName = conf['locality_name']
|
||||||
|
req.get_subject().organizationName = conf['organization_name']
|
||||||
|
req.get_subject().organizationalUnitName = conf['organizational_unit_name']
|
||||||
|
file.close()
|
||||||
|
except IOError:
|
||||||
|
print "Error: File not found: %s" % config_file
|
||||||
|
exit(-1)
|
||||||
|
except Exception, error:
|
||||||
|
print "Error: %s " % error
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
else:
|
||||||
req.get_subject().countryName = C
|
req.get_subject().countryName = C
|
||||||
req.get_subject().stateOrProvinceName = ST
|
req.get_subject().stateOrProvinceName = ST
|
||||||
req.get_subject().localityName = L
|
req.get_subject().localityName = L
|
||||||
req.get_subject().organizationName = O
|
req.get_subject().organizationName = O
|
||||||
req.get_subject().organizationalUnitName = OU
|
req.get_subject().organizationalUnitName = OU
|
||||||
# Add in extensions
|
|
||||||
base_constraints = ([
|
|
||||||
crypto.X509Extension("keyUsage", False, "Digital Signature, Non Repudiation, Key Encipherment"),
|
|
||||||
crypto.X509Extension("basicConstraints", False, "CA:FALSE"),
|
|
||||||
])
|
|
||||||
x509_extensions = base_constraints
|
|
||||||
# If there are SAN entries, append the base_constraints to include them.
|
|
||||||
if ss:
|
|
||||||
san_constraint = crypto.X509Extension("subjectAltName", False, ss)
|
|
||||||
x509_extensions.append(san_constraint)
|
|
||||||
req.add_extensions(x509_extensions)
|
|
||||||
# Utilizes generateKey function to kick off key generation.
|
|
||||||
key = generateKey(TYPE_RSA, 2048)
|
|
||||||
req.set_pubkey(key)
|
|
||||||
|
|
||||||
#update sha?
|
# Add in extensions
|
||||||
#req.sign(key, "sha1")
|
base_constraints = ([
|
||||||
req.sign(key, "sha256")
|
crypto.X509Extension("keyUsage", False, "Digital Signature, Non Repudiation, Key Encipherment"),
|
||||||
|
crypto.X509Extension("basicConstraints", False, "CA:FALSE"),
|
||||||
|
])
|
||||||
|
x509_extensions = base_constraints
|
||||||
|
# If there are SAN entries, append the base_constraints to include them.
|
||||||
|
if ss:
|
||||||
|
san_constraint = crypto.X509Extension("subjectAltName", False, ss)
|
||||||
|
x509_extensions.append(san_constraint)
|
||||||
|
req.add_extensions(x509_extensions)
|
||||||
|
# Utilizes generateKey function to kick off key generation.
|
||||||
|
key = generateKey(TYPE_RSA, 2048)
|
||||||
|
req.set_pubkey(key)
|
||||||
|
|
||||||
generateFiles(csrfile, req)
|
#update sha?
|
||||||
generateFiles(keyfile, key)
|
#req.sign(key, "sha1")
|
||||||
|
req.sign(key, "sha256")
|
||||||
|
|
||||||
return req
|
generateFiles(csrfile, req)
|
||||||
|
generateFiles(keyfile, key)
|
||||||
|
|
||||||
|
return req
|
||||||
|
|
||||||
# Generate Private Key
|
# Generate Private Key
|
||||||
def generateKey(type, bits):
|
def generateKey(type, bits):
|
||||||
|
@ -116,9 +145,11 @@ def generateFiles(mkFile, request):
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("name", help="Provide the FQDN", action="store")
|
parser.add_argument("name", help="Provide the FQDN", action="store")
|
||||||
parser.add_argument("-s", "--san", help="SANS", action="store", nargs='*', default="")
|
parser.add_argument("-s", "--san", help="SANS", action="store", nargs='*', default="")
|
||||||
|
parser.add_argument("-c", "--config", help="Config_File", action="store", default="")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
hostname = args.name
|
hostname = args.name
|
||||||
sans = args.san
|
sans = args.san
|
||||||
|
config_file = args.config
|
||||||
|
|
||||||
generateCSR(hostname, sans)
|
generateCSR(hostname, sans, config_file)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
[location]
|
||||||
|
country_name = US
|
||||||
|
state_or_province_name = California
|
||||||
|
locality_name = San Francisco
|
||||||
|
organization_name = FTW Enterprise
|
||||||
|
organizational_unit_name = WOW
|
Loading…
Reference in New Issue