aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2009-09-30 02:44:08 +0000
committerRob Austein <sra@hactrn.net>2009-09-30 02:44:08 +0000
commit8ff6e084a319ac1c2c5a2ce613e0c6af4ef7c967 (patch)
tree67e7941019be8b0a356b301e51486488a949f304 /scripts
parentbfceadc41e1ed51fa0f390b8a6eebe9e2004b78c (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.py72
-rw-r--r--scripts/Old/irbe-setup.py118
-rw-r--r--scripts/Old/irbe-setup.sh32
-rw-r--r--scripts/Old/resource-cert-samples.py277
-rw-r--r--scripts/cross_certify.py119
-rw-r--r--scripts/extract-key.py88
-rw-r--r--scripts/missing-oids.py38
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)) + ")"