Added check option and the unattended way to create a certificate
parent
6549656108
commit
cfd34c43f9
200
csrgen.py
200
csrgen.py
|
@ -13,80 +13,95 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from OpenSSL import crypto
|
from OpenSSL import crypto
|
||||||
|
from OpenSSL.crypto import FILETYPE_PEM
|
||||||
|
|
||||||
|
|
||||||
# Generate Certificate Signing Request (CSR)
|
# Generate Certificate Signing Request (CSR)
|
||||||
def generateCSR(nodename, sans = []):
|
def generateCSR(nodename, unattended, sans = []):
|
||||||
|
|
||||||
while True:
|
default_C = "ES"
|
||||||
C = raw_input("Enter your Country Name (2 letter code) [US]: ")
|
default_ST = "Alicante"
|
||||||
if len(C) != 2:
|
default_L = "Alicante"
|
||||||
|
default_O = "EUIPO"
|
||||||
|
default_OU = "DTD"
|
||||||
|
default_EM = "IECI_ALTIA_Unix@ext.euipo.europa.eu"
|
||||||
|
|
||||||
|
#interactive mode
|
||||||
|
loop = True
|
||||||
|
while loop == True and unattended == False:
|
||||||
|
C = raw_input("Enter your Country Name (2 letter code) [" + default_C + "]: ")
|
||||||
|
if len(C) == 0:
|
||||||
|
C = default_C
|
||||||
|
elif len(C) != 2:
|
||||||
print "You must enter two letters. You entered %r" % (C)
|
print "You must enter two letters. You entered %r" % (C)
|
||||||
continue
|
continue
|
||||||
ST = raw_input("Enter your State or Province <full name> []:California: ")
|
ST = raw_input("Enter your State or Province <full name> [" + default_ST + "]: ")
|
||||||
if len(ST) == 0:
|
if len(ST) == 0:
|
||||||
print "Please enter your State or Province."
|
ST = default_ST
|
||||||
continue
|
L = raw_input("Enter your (Locality Name (eg, city) [" + default_L + "]: ")
|
||||||
L = raw_input("Enter your (Locality Name (eg, city) []:San Francisco: ")
|
|
||||||
if len(L) == 0:
|
if len(L) == 0:
|
||||||
print "Please enter your City."
|
L = default_L
|
||||||
continue
|
O = raw_input("Enter your Organization Name (eg, company) [" + default_O + "]: ")
|
||||||
O = raw_input("Enter your Organization Name (eg, company) []:FTW Enterprise: ")
|
if len(O) == 0:
|
||||||
if len(L) == 0:
|
O = default_O
|
||||||
print "Please enter your Organization Name."
|
OU = raw_input("Enter your Organizational Unit (eg, section) [" + default_OU + "]: ")
|
||||||
continue
|
|
||||||
OU = raw_input("Enter your Organizational Unit (eg, section) []:IT: ")
|
|
||||||
if len(OU) == 0:
|
if len(OU) == 0:
|
||||||
print "Please enter your OU."
|
OU = default_OU
|
||||||
continue
|
EM = raw_input("Enter your e-mail [" + default_EM + "]: ")
|
||||||
|
if len(EM) == 0:
|
||||||
|
EM = default_EM
|
||||||
|
loop = False
|
||||||
|
|
||||||
# Allows you to permanently set values required for CSR
|
#unatended mode
|
||||||
# To use, comment raw_input and uncomment this section.
|
if unattended == True:
|
||||||
# C = 'US'
|
C = default_C
|
||||||
# ST = 'New York'
|
ST = default_ST
|
||||||
# L = 'Location'
|
L = default_L
|
||||||
# O = 'Organization'
|
O = default_O
|
||||||
# OU = 'Organizational Unit'
|
OU = default_OU
|
||||||
|
EM = default_EM
|
||||||
|
|
||||||
csrfile = 'host.csr'
|
csrfile = nodename + '.csr'
|
||||||
keyfile = 'host.key'
|
keyfile = nodename + '.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
|
||||||
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
|
req.get_subject().emailAddress = EM
|
||||||
base_constraints = ([
|
# Add in extensions
|
||||||
crypto.X509Extension("keyUsage", False, "Digital Signature, Non Repudiation, Key Encipherment"),
|
base_constraints = ([
|
||||||
crypto.X509Extension("basicConstraints", False, "CA:FALSE"),
|
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.
|
x509_extensions = base_constraints
|
||||||
if ss:
|
# If there are SAN entries, append the base_constraints to include them.
|
||||||
san_constraint = crypto.X509Extension("subjectAltName", False, ss)
|
if ss:
|
||||||
x509_extensions.append(san_constraint)
|
san_constraint = crypto.X509Extension("subjectAltName", False, ss)
|
||||||
req.add_extensions(x509_extensions)
|
x509_extensions.append(san_constraint)
|
||||||
# Utilizes generateKey function to kick off key generation.
|
req.add_extensions(x509_extensions)
|
||||||
key = generateKey(TYPE_RSA, 2048)
|
|
||||||
req.set_pubkey(key)
|
|
||||||
|
|
||||||
#update sha?
|
# Utilizes generateKey function to kick off key generation.
|
||||||
#req.sign(key, "sha1")
|
key = generateKey(TYPE_RSA, 2048)
|
||||||
req.sign(key, "sha256")
|
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):
|
||||||
|
@ -98,12 +113,11 @@ def generateKey(type, bits):
|
||||||
# Generate .csr/key files.
|
# Generate .csr/key files.
|
||||||
def generateFiles(mkFile, request):
|
def generateFiles(mkFile, request):
|
||||||
|
|
||||||
if mkFile == 'host.csr':
|
if mkFile.endswith('.csr'):
|
||||||
f = open(mkFile, "w")
|
f = open(mkFile, "w")
|
||||||
f.write(crypto.dump_certificate_request(crypto.FILETYPE_PEM, request))
|
f.write(crypto.dump_certificate_request(crypto.FILETYPE_PEM, request))
|
||||||
f.close()
|
f.close()
|
||||||
print crypto.dump_certificate_request(crypto.FILETYPE_PEM, request)
|
elif mkFile.endswith('.key'):
|
||||||
elif mkFile == 'host.key':
|
|
||||||
f = open(mkFile, "w")
|
f = open(mkFile, "w")
|
||||||
f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, request))
|
f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, request))
|
||||||
f.close()
|
f.close()
|
||||||
|
@ -111,14 +125,60 @@ def generateFiles(mkFile, request):
|
||||||
print "Failed."
|
print "Failed."
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
# Check the CRS generated and display the information in there
|
||||||
|
def checkCSR(nodename):
|
||||||
|
|
||||||
# Run Portion
|
try:
|
||||||
parser = argparse.ArgumentParser()
|
f = open(nodename + ".csr", "r")
|
||||||
parser.add_argument("name", help="Provide the FQDN", action="store")
|
csr = f.read()
|
||||||
parser.add_argument("-s", "--san", help="SANS", action="store", nargs='*', default="")
|
f.close()
|
||||||
args = parser.parse_args()
|
except Exception as e:
|
||||||
|
print str(e)
|
||||||
|
return
|
||||||
|
|
||||||
hostname = args.name
|
req = crypto.load_certificate_request(FILETYPE_PEM, csr)
|
||||||
sans = args.san
|
subject = req.get_subject()
|
||||||
|
print
|
||||||
|
print "Information for certificate: " + nodename
|
||||||
|
print "-"*len("Information for certificate: " + nodename)
|
||||||
|
cadena = "{0:<16}{1}{2}"
|
||||||
|
for component in subject.get_components():
|
||||||
|
print cadena.format(component[0], ": ", component[1])
|
||||||
|
|
||||||
|
for i in req.get_extensions():
|
||||||
|
if str(i).startswith('DNS:'):
|
||||||
|
i = str(i).replace('DNS:','').split(',')
|
||||||
|
for san in i:
|
||||||
|
print cadena.format("SAN:", ": ", san.strip())
|
||||||
|
print
|
||||||
|
|
||||||
|
|
||||||
|
# Main program
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Generate the certificate signed by the CA")
|
||||||
|
|
||||||
|
#defined the commands available for the script
|
||||||
|
subparsers = parser.add_subparsers(title='commands') #, help='commands availables')
|
||||||
|
parser_create = subparsers.add_parser('create', help='create the certificates requested')
|
||||||
|
parser_create.set_defaults(which='create')
|
||||||
|
parser_create.add_argument("-s", "--san", required=False, help="SANS", action="store", nargs='*', default="")
|
||||||
|
parser_create.add_argument("-u", "--unattended", required=False, help="Create the certificate unattended, with the options by default", action="store_true")
|
||||||
|
parser_check = subparsers.add_parser('check', help='check the certificate passed')
|
||||||
|
parser_check.set_defaults(which='check')
|
||||||
|
|
||||||
|
#main argument is always required
|
||||||
|
parser.add_argument("name", help="Provide the FQDN", action="store")
|
||||||
|
|
||||||
|
args = vars(parser.parse_args())
|
||||||
|
hostname = args['name']
|
||||||
|
|
||||||
|
|
||||||
|
#execute the apropiate function depending of the command chosen.
|
||||||
|
if args['which'] == 'create':
|
||||||
|
sans = args['san']
|
||||||
|
unattended = args['unattended']
|
||||||
|
generateCSR(hostname, unattended, sans)
|
||||||
|
elif args['which'] == 'check':
|
||||||
|
checkCSR(hostname)
|
||||||
|
|
||||||
generateCSR(hostname, sans)
|
|
||||||
|
|
Loading…
Reference in New Issue