diff options
author | Rob Austein <sra@hactrn.net> | 2009-09-30 02:44:08 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2009-09-30 02:44:08 +0000 |
commit | 8ff6e084a319ac1c2c5a2ce613e0c6af4ef7c967 (patch) | |
tree | 67e7941019be8b0a356b301e51486488a949f304 /scripts | |
parent | bfceadc41e1ed51fa0f390b8a6eebe9e2004b78c (diff) |
First pass at cleaning up some of the accumulated clutter
svn path=/rpkid/Makefile; revision=2800
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Old/cronjob.py | 72 | ||||
-rw-r--r-- | scripts/Old/irbe-setup.py | 118 | ||||
-rw-r--r-- | scripts/Old/irbe-setup.sh | 32 | ||||
-rw-r--r-- | scripts/Old/resource-cert-samples.py | 277 | ||||
-rw-r--r-- | scripts/cross_certify.py | 119 | ||||
-rw-r--r-- | scripts/extract-key.py | 88 | ||||
-rw-r--r-- | scripts/missing-oids.py | 38 |
7 files changed, 744 insertions, 0 deletions
diff --git a/scripts/Old/cronjob.py b/scripts/Old/cronjob.py new file mode 100644 index 00000000..eee2b945 --- /dev/null +++ b/scripts/Old/cronjob.py @@ -0,0 +1,72 @@ +""" +Tool to trigger "cron" runs in rpkid. + +Usage: python cronjob.py [ { -c | --config } configfile ] + [ { -d | --debug } ] + [ { -h | --help } ] + +Default configuration file is cronjob.conf, override with --config option. + +$Id$ + +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 getopt, sys +import rpki.config, rpki.https, rpki.async + +cfg_file = "cronjob.conf" +debug = False + +opts, argv = getopt.getopt(sys.argv[1:], "c:h?", ["config=", "help"]) +for o, a in opts: + if o in ("-h", "--help", "-?"): + print __doc__ + sys.exit(0) + elif o in ("-c", "--config"): + cfg_file = a + elif o in ("-d", "--debug"): + debug = True +if argv: + print __doc__ + raise RuntimeError, "Unexpected arguments %s" % argv + +cfg = rpki.config.parser(cfg_file, "cronjob") + +if debug: + rpki.log.init("cronjob") + rpki.log.set_trace(True) + +irbe_key = rpki.x509.RSA( Auto_file = cfg.get("irbe-key")) +irbe_cert = rpki.x509.X509(Auto_file = cfg.get("irbe-cert")) +bpki_ta = rpki.x509.X509(Auto_file = cfg.get("bpki-ta")) +rpkid_cert = rpki.x509.X509(Auto_file = cfg.get("rpkid-cert")) + +def cb(*whatever): + print repr(whatever) + +def eb(e): + print repr(e) + raise e + +rpki.https.client(client_key = irbe_key, + client_cert = irbe_cert, + server_ta = (bpki_ta, rpkid_cert), + url = cfg.get("https-url"), + msg = "Please run cron now.", + callback = cb, + errback = eb) + +rpki.async.event_loop() diff --git a/scripts/Old/irbe-setup.py b/scripts/Old/irbe-setup.py new file mode 100644 index 00000000..11f3a7a0 --- /dev/null +++ b/scripts/Old/irbe-setup.py @@ -0,0 +1,118 @@ +""" +Set up the relationship between an IRBE and an RPKI engine given an +IRDB. Our main task here is to create child objects in the RPKI +engine for every registrant object in the IRDB. + +NB: This code is badly out of date, and has been kept only because +some of what it's doing might be useful in other tools that haven't +been written yet. Don't believe anything you see here. + + +$Id$ + +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 os, MySQLdb +import rpki.left_right, rpki.relaxng, rpki.https +import rpki.x509, rpki.config, rpki.log + +rpki.log.init("irbe-setup") + +cfg = rpki.config.parser("irbe.conf", "irbe_cli") + +db = MySQLdb.connect(user = cfg.get("sql-username", section = "irdbd"), + db = cfg.get("sql-database", section = "irdbd"), + passwd = cfg.get("sql-password", section = "irdbd")) +cur = db.cursor() +db.autocommit(True) + +bpki_ta = rpki.x509.X509(Auto_file = cfg.get("bpki-ta")) +rpkid_cert = rpki.x509.X509(Auto_files = cfg.get("rpkid-cert")) +irbe_cert = rpki.x509.X509(Auto_files = cfg.get("irbe-cert")) +irbe_key = rpki.x509.RSA( Auto_file = cfg.get("irbe-key")) +https_url = cfg.get("https-url") + +def call_rpkid(pdu): + """ + Hand a PDU to rpkid and get back the response. Just throw an + exception if anything bad happens, no fancy error handling. + """ + + msg = rpki.left_right.msg.query((pdu,)) + cms = rpki.left_right.cms_msg.wrap(msg, irbe_key, irbe_cert) + der = rpki.https.client(client_key = irbe_key, + client_cert = irbe_cert, + server_ta = (bpki_ta, rpkid_cert), + url = https_url, + msg = cms) + msg = rpki.left_right.cms_msg.unwrap(der, (bpki_ta, rpkid_cert)) + pdu = msg[0] + assert len(msg) == 1 and msg.is_reply() and not isinstance(pdu, rpki.left_right.report_error_elt) + return pdu + +print "Create a self instance" +pdu = call_rpkid(rpki.left_right.self_elt.make_pdu(action = "create", crl_interval = 84600)) +self_id = pdu.self_id + +print "Create a business signing context" +pdu = rpki.left_right.bsc_elt.make_pdu(action = "create", self_id = self_id, generate_keypair = True) +pdu = call_rpkid(pdu) +bsc_id = pdu.bsc_id + +print "Issue the business cert" +i, o = os.popen2(("openssl", "x509", "-req", + "-CA", "biz-certs/Bob-CA.cer", + "-CAkey", "biz-certs/Bob-CA.key", + "-CAserial", "biz-certs/Bob-CA.srl")) +i.write(pdu.pkcs10_request.get_PEM()) +i.close() +cer = rpki.x509.X509(PEM = o.read()) +o.close() + +print "Set up the business cert chain" +pdu = rpki.left_right.bsc_elt.make_pdu(action = "set", self_id = self_id, bsc_id = bsc_id, signing_cert = cer) +call_rpkid(pdu) + +print "Create a repository context" +pdu = call_rpkid(rpki.left_right.repository_elt.make_pdu(action = "create", self_id = self_id, bsc_id = bsc_id)) +repository_id = pdu.repository_id + +print "Create a parent context" +ta = rpki.x509.X509(Auto_file = "biz-certs/Elena-Root.cer") +pdu = call_rpkid(rpki.left_right.parent_elt.make_pdu( + action = "create", self_id = self_id, bsc_id = bsc_id, repository_id = repository_id, bpki_cms_cert = ta, + peer_contact_uri = "https://localhost:44333/", sia_base = "rsync://wombat.invalid/")) +parent_id = pdu.parent_id + +print "Create child contexts for everybody" +print "Using a single cert for all of these registrants is a crock" + +cer = rpki.x509.X509(Auto_file = "biz-certs/Frank-Root.cer") + +cur.execute("SELECT registrant_id, registrant_name FROM registrant") +registrants = cur.fetchall() + +for registrant_id, registrant_name in registrants: + print "Attempting to bind", registrant_id, registrant_name + pdu = call_rpkid(rpki.left_right.child_elt.make_pdu(action = "create", self_id = self_id, bsc_id = bsc_id, bpki_cms_cert = cer)) + print "Attempting to bind", registrant_id, registrant_name, pdu.child_id + cur.execute( + """ + UPDATE registrant + SET rpki_self_id = %d, rpki_child_id = %d + WHERE registrant_id = %d + """, + (self_id, pdu.child_id, registrant_id)) diff --git a/scripts/Old/irbe-setup.sh b/scripts/Old/irbe-setup.sh new file mode 100644 index 00000000..31342aaa --- /dev/null +++ b/scripts/Old/irbe-setup.sh @@ -0,0 +1,32 @@ +#!/bin/sh - +# $Id$ + +# 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. + +# Run irbe-setup.py, under screen if possible. + +#make test + +if test -n "$STY" +then + screen python rpkid.py +else + python rpkid.py >>rpkid.log 2>&1 & rpkid=$! + trap "kill $rpkid" 0 1 2 3 13 15 +fi + +sleep 5 + +exec python irbe-setup.py 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() diff --git a/scripts/cross_certify.py b/scripts/cross_certify.py new file mode 100644 index 00000000..752fba55 --- /dev/null +++ b/scripts/cross_certify.py @@ -0,0 +1,119 @@ +""" +Cross-certification tool to issue a new certificate based on an old +one that was issued by somebody else. The point of the exercise is to +end up with a valid certificate in our own BPKI which has the same +subject name and subject public key as the one we're replacing. + +Usage: python cross_certify.py { -i | --in } input_cert + { -c | --ca } issuing_cert + { -k | --key } issuing_cert_key + { -s | --serial } serial_filename + [ { -h | --help } ] + [ { -o | --out } filename (default: stdout) ] + [ { -l | --lifetime } timedelta (default: 30 days) ] + +$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 os, time, getopt, sys, POW, rpki.x509, rpki.sundial + +os.environ["TZ"] = "UTC" +time.tzset() + +def usage(errmsg = None): + if errmsg is None: + sys.stdout.write(__doc__) + sys.exit(0) + else: + sys.stderr.write(errmsg + "\n" + __doc__) + sys.exit(1) + +child = None +parent = None +keypair = None +serial_file = None +lifetime = rpki.sundial.timedelta(days = 30) +output = None + +opts, argv = getopt.getopt(sys.argv[1:], "h?i:o:c:k:s:l:", + ["help", "in=", "out=", "ca=", + "key=", "serial=", "lifetime="]) +for o, a in opts: + if o in ("-h", "--help", "-?"): + usage() + elif o in ("-i", "--in"): + child = rpki.x509.X509(Auto_file = a) + elif o in ("-o", "--out"): + output = a + elif o in ("-c", "--ca"): + parent = rpki.x509.X509(Auto_file = a) + elif o in ("-k", "--key"): + keypair = rpki.x509.RSA(Auto_file = a) + elif o in ("-s", "--serial"): + serial_file = a + elif o in ("-l", "--lifetime"): + lifetime = rpki.sundial.timedelta.parse(a) + +if argv: + usage("Unused arguments: %r" % argv) +elif child is None: + usage("--in not specified") +elif parent is None: + usage("--ca not specified") +elif keypair is None: + usage("--key not specified") +elif serial_file is None: + usage("--serial not specified") + +now = rpki.sundial.now() +notAfter = now + lifetime + +try: + f = open(serial_file, "r") + serial = f.read() + f.close() + serial = int(serial.splitlines()[0], 16) +except IOError: + serial = 1 + +cert = parent.cross_certify(keypair, child, serial, notAfter, now) + +f = open(serial_file, "w") +f.write("%02x\n" % (serial + 1)) +f.close() + +if output is None: + print cert.get_PEM() +else: + f = open(output, "w") + f.write(cert.get_PEM()) + f.close() + diff --git a/scripts/extract-key.py b/scripts/extract-key.py new file mode 100644 index 00000000..0944b3ce --- /dev/null +++ b/scripts/extract-key.py @@ -0,0 +1,88 @@ +""" +Extract a private key from rpkid's database. + +This is a debugging tool. rpkid goes to some trouble not to expose +private keys, which is correct for normal operation, but for debugging +it is occasionally useful to be able to extract the private key from +MySQL. This script is just a convenience, it doesn't enable anything +that couldn't be done via the mysql command line tool. + +While we're at this we also extract the corresponding certificate. + +Usage: python extract-key.py [ { -s | --self } self_handle ] + [ { -b | --bsc } bsc_handle ] + [ { -u | --user } mysql_user_id ] + [ { -d | --db } mysql_database ] + [ { -p | --password } mysql_password ] + [ { -h | --help } ] + +Default for both user and db is "rpki". + +$Id$ + +Copyright (C) 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 os, time, getopt, sys, MySQLdb +import rpki.x509 + +os.environ["TZ"] = "UTC" +time.tzset() + +def usage(code): + print __doc__ + sys.exit(code) + +self_handle = None +bsc_handle = None + +user = "rpki" +passwd = "fnord" +db = "rpki" + +opts, argv = getopt.getopt(sys.argv[1:], "s:b:u:p:d:h?", + ["self=", "bsc=", "user=", "password=", "db=", "help"]) +for o, a in opts: + if o in ("-h", "--help", "-?"): + usage(0) + elif o in ("-s", "--self"): + self_handle = a + elif o in ("-b", "--bsc"): + bsc_handle = a + elif o in ("-u", "--user"): + user = a + elif o in ("-p", "--password"): + passwd = a + elif o in ("-d", "--db"): + db = a +if argv: + usage(1) + +cur = MySQLdb.connect(user = user, db = db, passwd = passwd).cursor() + +cur.execute( + """ + SELECT bsc.private_key_id, bsc.signing_cert + FROM bsc, self + WHERE self.self_handle = %s AND self.self_id = bsc.self_id AND bsc_handle = %s + """, + (self_handle, bsc_handle)) + +key, cer = cur.fetchone() + +print rpki.x509.RSA(DER = key).get_PEM() + +if cer: + print rpki.x509.X509(DER = cer).get_PEM() diff --git a/scripts/missing-oids.py b/scripts/missing-oids.py new file mode 100644 index 00000000..f5571753 --- /dev/null +++ b/scripts/missing-oids.py @@ -0,0 +1,38 @@ +""" +Figure out what OIDs from rpki.oids are missing from dumpasn1's database. + +$Id$ + +Copyright (C) 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 POW.pkix, rpki.oids + +need_header = True + +for oid, name in rpki.oids.oid2name.items(): + try: + POW.pkix.oid2obj(oid) + except: + o = POW.pkix.Oid() + o.set(oid) + if need_header: + print + print "# Local additions" + need_header = False + print + print "OID =", " ".join(("%02X" % ord(c)) for c in o.toString()) + print "Comment = RPKI project" + print "Description =", name, "(" + " ".join((str(i) for i in oid)) + ")" |