source: trunk/server/fedora/config/etc/pki/tls/gencsr @ 2719

Last change on this file since 2719 was 2693, checked in by btidor, 10 years ago
Add a CSR-generating script
  • Property svn:executable set to *
File size: 2.5 KB
Line 
1#!/usr/bin/env python2
2
3from OpenSSL import *
4
5PRIVATE_KEY = "/etc/pki/tls/private/scripts-2048.key"
6# PEM format with no passphrase
7
8SUBJECT_ATTRIBUTES = [
9    ("countryName", "US"),
10    ("stateOrProvinceName", "Massachusetts"),
11    ("localityName", "Cambridge"),
12    ("organizationName", "Massachusetts Institute of Technology"),
13    ("organizationalUnitName", "scripts.mit.edu web hosting service"),
14    ("CN", None),  # to be filled in below
15    ("emailAddress", "scripts@mit.edu"),
16]
17
18EXTENSIONS = [
19    # apparently OpenSSL marks CSR extensions as non-critical; it's not our
20    # fault if the CA messes up and forgets CA:FALSE, right?
21    ("basicConstraints", False, "CA:FALSE"),
22    ("keyUsage", False, "nonRepudiation, digitalSignature, keyEncipherment"),
23]
24
25def generate_csr(cn, alt_names=None):
26    """
27    Generate a CSR for the given Common Name (a hostname) with the provided
28    subjectAltName's (a list of hostnames) using the above settings.
29
30    Returns a PEM string.
31    """
32    req = crypto.X509Req()
33
34    # set the subject fields (in the same order as OpenSSL XD)
35    subject = req.get_subject()
36    for attr, val in SUBJECT_ATTRIBUTES:
37        if attr == "CN":  # fills in the CN in the right place
38            val = cn
39        setattr(subject, attr, val)  # subject.attr = val
40
41    # initialize the extensions
42    extensions = []
43    for type_name, critical, value in EXTENSIONS:
44        ext = crypto.X509Extension(type_name, critical, value)
45        extensions.append(ext)
46
47    # ...including subjectAltName
48    san_string = ", ".join("DNS:"+name for name in alt_names)
49    ext = crypto.X509Extension("subjectAltName", False, san_string)
50    extensions.append(ext)
51
52    # and add them to the CSR
53    req.add_extensions(extensions)
54
55    # load the private key
56    with open(PRIVATE_KEY) as f:
57        pk_pem = f.read()
58    private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, pk_pem)
59
60    # do the bit with the key!
61    req.set_pubkey(private_key)  # yeah...I know
62    req.sign(private_key, "sha256")
63
64    # dump the CSR to PEM
65    return crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
66
67if __name__=="__main__":
68    import sys
69    if len(sys.argv) != 2:
70        print "usage: %s HOSTNAME" % sys.argv[0]
71        exit(1)
72
73    hostname = sys.argv[1].lower()
74    if not hostname.endswith(".mit.edu"):
75        hostname += ".mit.edu"
76
77    print generate_csr(hostname, [hostname]),  # with subjectAltName
78    print >> sys.stderr, "Generated a CSR for %s using %s" % (
79        hostname, PRIVATE_KEY)
80    exit(0)
Note: See TracBrowser for help on using the repository browser.