diff options
Diffstat (limited to 'scripts/Old/resource-cert-samples.py')
-rw-r--r-- | scripts/Old/resource-cert-samples.py | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/scripts/Old/resource-cert-samples.py b/scripts/Old/resource-cert-samples.py new file mode 100644 index 00000000..16986d9b --- /dev/null +++ b/scripts/Old/resource-cert-samples.py @@ -0,0 +1,277 @@ +""" +Generate an RPKI test repository. + +This script generates a toy RPKI repository for test purposes. It's +designed to be relatively easy to reconfigure, making it simple to +test whatever is of interest on a given day, without a lot of setup +overhead. + +Outputs are a bunch of config files for the OpenSSL CLI tool and a +makefile to drive everything. + +$Id$ + +Copyright (C) 2009 Internet Systems Consortium ("ISC") + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +Portions copyright (C) 2007--2008 American Registry for Internet Numbers ("ARIN") + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +""" + +import rpki.resource_set, os + +subdir = "resource-cert-samples" +openssl = "../../openssl/openssl/apps/openssl" +keybits = 2048 + +def main(): + """ + Main program, including the toy database itself. + """ + + db = allocation_db() + db.add("ISP1", ipv4 = "192.0.2.1-192.0.2.33", asn = "64533") + db.add("ISP2", ipv4 = "192.0.2.44-192.0.2.100") + db.add("ISP3", ipv6 = "2001:db8::44-2001:db8::100") + db.add("ISP4", ipv6 = "2001:db8::10:0:44/128", asn = "64544") + db.add("ISP5a", ipv4 = "10.0.0.0/24", ipv6 = "2001:db8::a00:0/120") + db.add("ISP5b", ipv4 = "10.3.0.0/24", ipv6 = "2001:db8::a03:0/120") + db.add("ISP5c", asn = "64534-64540") + db.add("LIR1", children = ["ISP1", "ISP2"]) + db.add("LIR2", children = ["ISP3", "ISP4"]) + db.add("LIR3", children = ["ISP5a", "ISP5b", "ISP5c"]) + db.add("RIR", children = ["LIR1", "LIR2", "LIR3"]) + + if not os.path.isdir(subdir): + os.mkdir(subdir) + + for i in db: + write_maybe("%s/%s.cnf" % (subdir, i.name), i.cfg_string()) + + write_maybe("%s/Makefile" % subdir, + "# Automatically generated, do not edit.\n" + + "".join([i.makefile_rules() for i in db])) + +def write_maybe(name, new_content): + """ + Write a file if and only if its contents have changed. This + simplifies interactions with "make". + """ + old_content = None + if os.path.isfile(name): + f = open(name, "r") + old_content = f.read() + f.close() + if old_content != new_content: + print "Writing", name + f = open(name, "w") + f.write(new_content) + f.close() + +class allocation_db(list): + """ + Class to represent an allocation database. + """ + + def __init__(self): + self.allocation_map = {} + + def add(self, name, **kw): + """ + Add a new entry to this allocation database. All arguments passed + through to the allocation constructor. + """ + self.insert(0, allocation(name = name, allocation_map = self.allocation_map, **kw)) + +class allocation(object): + """ + Class representing one entity holding allocated resources. + + In order to simplify configuration, this class automatically + computes the set of resources that this entity must hold in order to + serve both itself and its children. + """ + + parent = None + + def __init__(self, name, asn = None, ipv4 = None, ipv6 = None, children = (), allocation_map = None): + """ + Create a new allocation entry. + + This binds the parent attributes of any children, and computes the + transitive closure of the set of resources this entity needs. + """ + self.name = name + self.children = [allocation_map[i] for i in children] + for child in self.children: + assert child.parent is None + child.parent = self + self.asn = self.summarize("asn", rpki.resource_set.resource_set_as(asn)) + self.ipv4 = self.summarize("ipv4", rpki.resource_set.resource_set_ipv4(ipv4)) + self.ipv6 = self.summarize("ipv6", rpki.resource_set.resource_set_ipv6(ipv6)) + allocation_map[name] = self + + def summarize(self, attrname, seed = None): + """ + Compute the transitive resource closure for one resource attribute. + """ + if seed is None: + seed = getattr(self, attrname) + for child in self.children: + seed = seed.union(child.summarize(attrname)) + return seed + + def __str__(self): + return "%s\n ASN: %s\n IPv4: %s\n IPv6: %s" % (self.name, self.asn, self.ipv4, self.ipv6) + + def cfg_string(self): + """ + Generate the OpenSSL configuration file needed for this entity. + """ + keys = { "self" : self.name, + "keybits" : keybits, + "no_parent" : "#", + "no_asid" : "#", + "no_addr" : "#", + "parent" : "???", + "asid" : "???", + "addr" : "???" } + if self.parent: + keys["no_parent"] = "" + keys["parent"] = self.parent.name + if self.asn: + keys["no_asid"] = "" + keys["asid"] = ",".join(["AS:" + str(x) for x in self.asn]) + if self.ipv4 or self.ipv6: + keys["no_addr"] = "" + keys["addr"] = ",".join(["IPv4:" + str(x) for x in self.ipv4] + ["IPv6:" + str(x) for x in self.ipv6]) + return openssl_cfg_fmt % keys + + def makefile_rules(self): + """ + Generate the makefile rules needed for this entity. + """ + keys = { "self" : self.name, + "keybits" : keybits, + "openssl" : openssl } + if self.parent: + keys["signconf"] = "%s.cnf" % self.parent.name + keys["signdeps"] = "%s.key" % self.parent.name + else: + keys["signconf"] = "%s.cnf -selfsign" % self.name + keys["signdeps"] = "%s.key" % self.name + return makefile_fmt % keys + +makefile_fmt = '''\ + +all:: %(self)s.cer + +%(self)s.key: + %(openssl)s genrsa -out $@ %(keybits)d + +%(self)s.req: %(self)s.key %(self)s.cnf Makefile + %(openssl)s req -new -config %(self)s.cnf -key %(self)s.key -out $@ + +%(self)s.cer: %(self)s.req %(self)s.cnf %(signdeps)s Makefile + @test -d %(self)s || mkdir %(self)s + @test -f %(self)s/index || touch %(self)s/index + @test -f %(self)s/serial || echo 01 >%(self)s/serial + %(openssl)s ca -batch -out $@ -in %(self)s.req -extfile %(self)s.cnf -config %(signconf)s + + +show_req:: + %(openssl)s req -noout -text -in %(self)s.req -config /dev/null + +show_cer:: + %(openssl)s x509 -noout -text -in %(self)s.cer +''' + +openssl_cfg_fmt = '''# Automatically generated, do not edit. + +[ ca ] +default_ca = ca_default + +[ ca_default ] +certificate = %(self)s.cer +serial = %(self)s/serial +private_key = %(self)s.key +database = %(self)s/index +new_certs_dir = %(self)s +name_opt = ca_default +cert_opt = ca_default +default_days = 365 +default_crl_days = 30 +default_md = sha256 +preserve = no +copy_extensions = copy +policy = ca_policy_anything +unique_subject = no +x509_extensions = ca_x509_ext +crl_extensions = crl_x509_ext + +[ ca_policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional +givenName = optional +surname = optional + +[ req ] +default_bits = %(keybits)d +encrypt_key = no +distinguished_name = req_dn +req_extensions = req_x509_ext +prompt = no + +[ req_dn ] +CN = TEST ENTITY %(self)s + +[ req_x509_ext ] +basicConstraints = critical,CA:true +subjectKeyIdentifier = hash +keyUsage = critical,keyCertSign,cRLSign +subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:rsync://wombats-r-us.hactrn.net/%(self)s/ +%(no_parent)sauthorityInfoAccess = caIssuers;URI:rsync://wombats-r-us.hactrn.net/%(parent)s.cer +%(no_asid)ssbgp-autonomousSysNum = critical,%(asid)s +%(no_addr)ssbgp-ipAddrBlock = critical,%(addr)s + +[ ca_x509_ext ] +basicConstraints = critical,CA:true +%(no_parent)sauthorityKeyIdentifier = keyid:always +keyUsage = critical,keyCertSign,cRLSign +subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:rsync://wombats-r-us.hactrn.net/%(self)s/ +%(no_parent)sauthorityInfoAccess = caIssuers;URI:rsync://wombats-r-us.hactrn.net/%(parent)s.cer +%(no_asid)ssbgp-autonomousSysNum = critical,%(asid)s +%(no_addr)ssbgp-ipAddrBlock = critical,%(addr)s + +[ crl_x509_ext ] +authorityKeyIdentifier = keyid:always +''' + +main() |