forked from compmodels/jupyterhub-deploy
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add scripts to manage InCommon SSL certificates.
- Loading branch information
1 parent
f8192b6
commit ce6ff60
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
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
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) |
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
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 |