diff options
-rw-r--r-- | scripts/rpki/https.py | 8 | ||||
-rw-r--r-- | scripts/rpki/left_right.py | 11 | ||||
-rw-r--r-- | scripts/rpki/sql.py | 53 | ||||
-rw-r--r-- | scripts/rpki/up_down.py | 13 | ||||
-rw-r--r-- | scripts/rpki/x509.py | 6 |
5 files changed, 67 insertions, 24 deletions
diff --git a/scripts/rpki/https.py b/scripts/rpki/https.py index eec9e3a0..6c56123f 100644 --- a/scripts/rpki/https.py +++ b/scripts/rpki/https.py @@ -7,11 +7,17 @@ subversion repository; generalizing it would not be hard, but the more general version should use SQL anyway. """ -import httplib, BaseHTTPServer, tlslite.api, glob, traceback, urlparse +import httplib, BaseHTTPServer, tlslite.api, glob, traceback, urlparse, socket import rpki.x509, rpki.exceptions rpki_content_type = "application/x-rpki" +# Setting this here is a crock, but the default is much too short and +# this is the easiest way to make sure that all of our scripts use a +# more reasonable value. + +socket.setdefaulttimeout(90) # Seconds + def client(msg, privateKey, certChain, x509TrustList, url): """Open client HTTPS connection, send a message, wait for response. diff --git a/scripts/rpki/left_right.py b/scripts/rpki/left_right.py index 181a1d13..af0282e2 100644 --- a/scripts/rpki/left_right.py +++ b/scripts/rpki/left_right.py @@ -510,7 +510,12 @@ class child_elt(data_elt): # May require refactoring, ignore the issue for now. # r_elt = r_msg.toXML() - rpki.relaxng.up_down.assertValid(r_elt) + try: + rpki.relaxng.up_down.assertValid(r_elt) + except: + print lxml.etree.tostring(r_elt, pretty_print = True, encoding = "UTF-8") + traceback.print_exc() + raise return rpki.cms.xml_sign(r_elt, bsc.private_key_id, bsc.signing_cert, encoding = "UTF-8") class repository_elt(data_elt): @@ -554,12 +559,12 @@ class repository_elt(data_elt): def publish(self, *things): """Placeholder for publication operation (not yet written).""" for thing in things: - print "Should publish %s to repository %s" % (thing, self) + print "Should publish %s to repository %s" % (repr(thing), repr(self)) def withdraw(self, *things): """Placeholder for publication withdrawal operation (not yet written).""" for thing in things: - print "Should withdraw %s from repository %s" % (thing, self) + print "Should withdraw %s from repository %s" % (repr(thing), repr(self)) class route_origin_elt(data_elt): """<route_origin/> element.""" diff --git a/scripts/rpki/sql.py b/scripts/rpki/sql.py index 784e5b01..cef8eb43 100644 --- a/scripts/rpki/sql.py +++ b/scripts/rpki/sql.py @@ -1,7 +1,7 @@ # $Id$ import MySQLdb, time -import rpki.x509 +import rpki.x509, rpki.resource_set def connect(cfg, section="sql"): """Connect to a MySQL database using connection parameters from an @@ -264,6 +264,7 @@ class ca_obj(sql_persistant): issue_response.payload.check_syntax() ca_detail.latest_ca_cert = issue_response.payload.classes[0].certs[0].cert ca_detail.ca_cert_uri = issue_response.payload.classes[0].certs[0].cert_url.rsync() + ca_detail.generate_manifest_cert(self) ca_detail.state = "active" ca_detail.sql_mark_dirty() @@ -395,6 +396,20 @@ class ca_detail_obj(sql_persistant): self.sql_store(gctx) return self + def generate_manifest_cert(self, ca): + """Generate a new manifest certificate for this ca_detail.""" + + self.latest_manifest_cert = self.latest_ca_cert.issue(keypair = self.private_key_id, + subject_key = self.manifest_public_key, + serial = ca.next_serial_number(), + sia = None, + aia = self.ca_cert_uri, + crldp = ca.sia_uri + self.latest_ca_cert.gSKI() + ".crl", + as = rpki.resource_set.resource_set_as("<inherit>"), + v4 = rpki.resource_set.resource_set_ipv4("<inherit>"), + v6 = rpki.resource_set.resource_set_ipv6("<inherit>"), + is_ca = False) + def issue(self, gctx, ca, child, subject_key, sia, as, v4, v6, child_cert = None): """Issue a new certificate to a child. @@ -409,6 +424,9 @@ class ca_detail_obj(sql_persistant): the right information out of the existing cert then calls this method to finish the job. """ + assert child_cert is None or (child_cert.child_id == child.child_id and + child_cert.ca_detail_id == self.ca_detail_id) + cert = self.latest_ca_cert.issue(keypair = self.private_key_id, subject_key = subject_key, serial = ca.next_serial_number(), @@ -419,24 +437,26 @@ class ca_detail_obj(sql_persistant): v4 = v4, v6 = v6) + + if child_cert is None: + child_cert = rpki.sql.child_cert_obj(child_id = child.child_id, + ca_detail_id = self.ca_detail_id, + cert = cert) + else: + child_cert.cert = cert + + child_cert.ski = cert.get_SKI() + + child_cert.sql_store(gctx) + manifest = self.generate_manifest(gctx) - repository = rpki.left_right.repository_elt.sql_fetch_where1(gctx, """ - repository.repository_id = parent.repository_id AND - parent.parent_id = ca.parent_id AND - ca.ca_id = %s - """ % self.ca_id) + parent = rpki.left_right.parent_elt.sql_fetch(gctx, ca.parent_id) + repository = rpki.left_right.repository_elt.sql_fetch(gctx, parent.repository_id) repository.publish(cert, manifest) - if child_cert is None: - return rpki.sql.child_cert_obj(child_id = child.child_id, - ca_detail_id = self.ca_detail_id, - cert = cert) - else: - assert child_cert.child_id == child.child_id and child_cert.ca_detail_id == self.ca_detail_id - child_cert.cert = cert - return child_cert + return child_cert def generate_crl(self, gctx): """Generate a new CRL for this ca_detail. At the moment this is @@ -487,7 +507,7 @@ class ca_detail_obj(sql_persistant): m = rpki.x509.SignedManifest() m.build(serial = ca.next_manifest_number(), nextUpdate = time.time() + self_obj.crl_interval, - names_and_objs = [(c.gSKI() + ".cer", c) for c in certs]) + names_and_objs = [(c.cert.gSKI() + ".cer", c.cert) for c in certs]) m.sign(keypair = self.manifest_private_key_id, certs = rpki.x509.X509_chain(self.latest_manifest_cert)) @@ -497,7 +517,7 @@ class ca_detail_obj(sql_persistant): class child_cert_obj(sql_persistant): """Certificate that has been issued to a child.""" - sql_template = template("child_cert", "child_cert_id", "cert", "child_id", "ca_detail_id", "revoked") + sql_template = template("child_cert", "child_cert_id", "cert", "child_id", "ca_detail_id", "ski", "revoked") def __init__(self, child_id = None, ca_detail_id = None, cert = None): """Initialize a child_cert_obj.""" @@ -524,6 +544,7 @@ class child_cert_obj(sql_persistant): if sia is None: sia = self.cert.get_SIA() return ca_detail.issue(gctx = gctx, + ca = ca_obj.sql_fetch(gctx, ca_detail.ca_id), child = rpki.left_right.child_elt.sql_fetch(gctx, self.child_id), subject_key = self.cert.getPublicKey(), sia = sia, diff --git a/scripts/rpki/up_down.py b/scripts/rpki/up_down.py index 9dd92b7d..520b0ddf 100644 --- a/scripts/rpki/up_down.py +++ b/scripts/rpki/up_down.py @@ -270,6 +270,7 @@ class issue_pdu(base_elt): # Generate new cert or regenerate old one if necessary if child_cert is None: + print "Issuing because no child cert (yet)" child_cert = ca_detail.issue(gctx = gctx, ca = ca, child = child, @@ -280,11 +281,16 @@ class issue_pdu(base_elt): v6 = rc_v6) elif (child_cert is not None and ((rc_as, rc_v4, rc_v6) != child_cert.cert.get_3779resources())) or \ (child_cert is not None and child_cert.cert.get_SIA() != req_sia): + print "Reissuing:" + print " Requested resources:", repr((rc_as, rc_v4, rc_v6)) + print " Previous resources: ", repr(child_cert.cert.get_3779resources()) + print " Requested SIA:", repr(req_sia) + print " Previous SIA: ", repr(child_cert.cert.get_SIA()) child_cert.reissue(gctx = gctx, ca_detail = ca_detail, - as = as, - v4 = v4, - v6 = v6, + as = rc_as, + v4 = rc_v4, + v6 = rc_v6, sia = req_sia) # Save anything we modified and generate response @@ -294,6 +300,7 @@ class issue_pdu(base_elt): c.cert_url = multi_uri(ca.sia_uri + child_cert.cert.gSKI() + ".cer") c.cert = child_cert.cert rc = class_elt() + rc.class_name = str(ca_id) rc.cert_url = multi_uri(ca_detail.ca_cert_uri) rc.resource_set_as, rc.resource_set_ipv4, rc.resource_set_ipv6 = rc_as, rc_v4, rc_v6 rc.certs.append(c) diff --git a/scripts/rpki/x509.py b/scripts/rpki/x509.py index f15109ae..c3af0ebf 100644 --- a/scripts/rpki/x509.py +++ b/scripts/rpki/x509.py @@ -294,7 +294,6 @@ class X509(DER_object): ["authorityKeyIdentifier", False, (aki, (), None)], ["cRLDistributionPoints", False, ((("fullName", (("uri", crldp),)), None, ()),)], ["authorityInfoAccess", False, (((1, 3, 6, 1, 5, 5, 7, 48, 2), ("uri", aia)),)], - ["subjectInfoAccess", False, sia], ["certificatePolicies", True, (((1, 3, 6, 1, 5, 5, 7, 14, 2), ()),)] ] if is_ca: @@ -303,6 +302,11 @@ class X509(DER_object): else: exts.append(["keyUsage", True, (1,)]) + if sia is not None: + exts.append(["subjectInfoAccess", False, sia]) + else: + assert not is_ca + if as: exts.append(["sbgp-autonomousSysNum", True, (as.to_tuple(), None)]) if v4 or v6: |