Skip to content

Commit

Permalink
Add scripts to manage InCommon SSL certificates.
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanlovett committed Aug 13, 2015
1 parent f8192b6 commit ce6ff60
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 0 deletions.
130 changes: 130 additions & 0 deletions script/gencert
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/python

# Generate a key, self-signed certificate, and certificate request.
# Usage: gencert hostname [hostname...]
#
# When more than one hostname is provided, a SAN (Subject Alternate Name)
# certificate and request are generated. The first hostname is used as the
# primary CN for the request.
#
# Author: James E. Blair <[email protected]> 2010-06-18
# With help from this thread:
# http://www.mail-archive.com/[email protected]/msg47641.html

# Downloaded from
# https://wikihub.berkeley.edu/display/calnet/CalNet+InCommon-Comodo+Certificate+Service#CalNetInCommon-ComodoCertificateService-DCAFAQ
# https://wikihub.berkeley.edu/download/attachments/30212507/gencert?version=2&modificationDate=1410154384790&api=v2
#

import os
import sys
import subprocess
import tempfile

OPENSSL_CNF="""
[ req ]
default_bits = 2048
default_md = sha1
default_days = 1095
distinguished_name = req_distinguished_name
prompt = no
%(req)s
[ req_distinguished_name ]
C=US
ST=California
L=Berkeley
O=University of California at Berkeley
OU=Data Science
%(cn)s
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true
subjectAltName = @alt_names
[ alt_names ]
%(alt)s
"""

SAN_REQ = """
x509_extensions = v3_ca # The extentions to add to the self signed cert
req_extensions = v3_req # The extensions to add to a certificate request
"""

def run(args):
p = subprocess.Popen(args,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, close_fds=True)
p.stdin.close()
while True:
o = p.stdout.read(1)
if not o: break
sys.stdout.write(o)
sys.stdout.flush()
r = p.wait()
if r:
raise Exception('Error running %s'%args)

# main
names = sys.argv[1:]
if not names or names[0][0] == '-':
print '''Usage: gencert hostname [hostname...]
Please provide at least one hostname on the command line.
Mulitple hostnames may be provided to generate a SAN request.'''
sys.exit(1)
params = dict(req='', dn='', alt='')
if len(names)>1:
# SAN
san_names = ""
for i,x in enumerate(names):
san_names += "DNS.%s = %s\n" % (i,x)
params['req']=SAN_REQ
params['alt']=san_names
sanfn = '-san'
else:
sanfn = ''
params['cn']='CN=%s'%names[0]
hostpart = names[0] + sanfn
for dir in [hostpart,
os.path.join(hostpart, 'etc'),
os.path.join(hostpart, 'etc', 'ssl'),
os.path.join(hostpart, 'etc', 'ssl', 'private'),
os.path.join(hostpart, 'etc', 'ssl', 'certs')]:
if not os.path.exists(dir): os.mkdir(dir)
keyfile = os.path.join(hostpart,'etc','ssl','private', hostpart + '.key')
crtfile = os.path.join(hostpart,'etc','ssl','certs', hostpart + '.cert')
csrfile = os.path.join(hostpart,'etc','ssl','certs', hostpart + '.csr')
(fh, cnffile) = tempfile.mkstemp()

os.write(fh, OPENSSL_CNF%params)
os.close(fh)

if os.path.exists(crtfile):
print "Certificate file exists, aborting"
print " ", crtfile
sys.exit(1)

if os.path.exists(csrfile):
print "Certificate request file exists, aborting"
print " ", csrfile
sys.exit(1)

if os.path.exists(keyfile):
print "Key file exists, skipping key generation"
else:
run(['openssl', 'genrsa', '-out', keyfile, '2048'])
os.chmod(keyfile, 0400)

run(['openssl', 'req', '-days', '1095', '-config', cnffile, '-new', '-nodes', '-key', keyfile, '-out', csrfile])
run(['openssl', 'req', '-days', '1095', '-config', cnffile, '-new', '-nodes', '-key', keyfile, '-out', crtfile, '-x509'])
run(['openssl', 'req', '-days', '1095', '-in', csrfile, '-text'])

os.unlink(cnffile)
55 changes: 55 additions & 0 deletions script/split-comodo-email
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/python
#vim: set tabstop=4 shiftwidth=4:

import os
import sys
import urllib

# Usage:
# cat email.txt | python split-email.py
# Output:
# etc/ssl/certs/NFQDN.x509*

def download(url, filename):
print filename
if os.path.exists(filename):
print 'File exists: %s. Skipping.' % filename
return
f = urlopener.open(url)
buf = f.read()
f.close()

f = open(filename, 'w')
f.write(buf)
f.close()

# MAIN
urlopener = urllib.URLopener()

f = sys.stdin
line = f.readline()
while line != '':
line = line.strip()
if line.startswith('Subject:'):
# The Subject long can be line and run over to the next so we combine
# them.
line = line.strip()
nextline = f.readline()
if nextline.startswith(' '):
line = line + ' ' + nextline.strip()
# Subject: Enrollment Successful - Your SSL certificate for
# somehost.berkeley.edu is ready
hostname = line.split()[-3]
cert_dir = ''
for p in [hostname, 'etc', 'ssl', 'certs']:
cert_dir = os.path.join(cert_dir, p)
if not os.path.exists(cert_dir): os.mkdir(cert_dir)
nfqdn = hostname.split('.')[0]
path = os.path.join(cert_dir, nfqdn + '.x509')
else:
for ext in ['CO', 'IO', 'IOR', '']:
if line.endswith('format=x509' + ext):
url = line.split()[-1]
download(url, path + ext)
line = f.readline()
continue

0 comments on commit ce6ff60

Please sign in to comment.