Added check option and the unattended way to create a certificate

pull/5/head
root-ocvlp-adm001 2017-07-26 10:08:10 +02:00
parent 6549656108
commit cfd34c43f9
1 changed files with 130 additions and 70 deletions

200
csrgen.py
View File

@ -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)