aboutsummaryrefslogtreecommitdiff
path: root/scripts/rpki
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2007-09-18 21:44:21 +0000
committerRob Austein <sra@hactrn.net>2007-09-18 21:44:21 +0000
commit2c5df0fe0ecf1683bf2935d027411905035042b0 (patch)
tree259f542f3669c0855fe2b9a12e606f7df7bc0888 /scripts/rpki
parentf0d2933a30b05039919a3aecbb53e640d4c9c126 (diff)
Start adding our own exceptions.
svn path=/scripts/rpki/cms.py; revision=988
Diffstat (limited to 'scripts/rpki')
-rw-r--r--scripts/rpki/cms.py4
-rw-r--r--scripts/rpki/exceptions.py30
-rw-r--r--scripts/rpki/https.py35
-rw-r--r--scripts/rpki/left_right.py18
-rw-r--r--scripts/rpki/up_down.py30
-rw-r--r--scripts/rpki/x509.py14
6 files changed, 84 insertions, 47 deletions
diff --git a/scripts/rpki/cms.py b/scripts/rpki/cms.py
index a00d3ba2..633ab1dc 100644
--- a/scripts/rpki/cms.py
+++ b/scripts/rpki/cms.py
@@ -6,7 +6,7 @@ For the moment these just call the OpenSSL CLI tool, which is slow,
requires disk I/O, and likes PEM format. Fix this later.
"""
-import os, rpki.x509
+import os, rpki.x509, rpki.exceptions
# openssl smime -sign -nodetach -outform DER -signer biz-certs/Alice-EE.cer -certfile biz-certs/Alice-CA.cer -inkey biz-certs/Alice-EE.key -in PLAN -out PLAN.der
@@ -64,4 +64,4 @@ def decode(cms, ta):
if status == "Verification successful\n":
return xml
else:
- raise RuntimeError, "CMS verification failed: %s" % status
+ raise rpki.exceptions.CMSVerificationFailed, "CMS verification failed with status %s" % status
diff --git a/scripts/rpki/exceptions.py b/scripts/rpki/exceptions.py
new file mode 100644
index 00000000..76fa4c27
--- /dev/null
+++ b/scripts/rpki/exceptions.py
@@ -0,0 +1,30 @@
+# $Id$
+
+"""Exception definitions for RPKI modules."""
+
+class NotInDatabase(Exception):
+ """Lookup failed for an object expected to be in the database."""
+
+class BadURISyntax(Exception):
+ """Illegal syntax for a URI."""
+
+class BadStatusCode(Exception):
+ """Unrecognized protocol status code."""
+
+class BadQuery(Exception):
+ """Unexpected protocol query."""
+
+class MultipleROAsFound(Exception):
+ """Found multiple ROAs in a relationship that should be one-to-one."""
+
+class CMSVerificationFailed(Exception):
+ """Verification of a CMS message failed."""
+
+class HTTPRequestFailed(Exception):
+ """HTTP request failed."""
+
+class DERObjectConversionError(Exception):
+ """Error trying to convert a DER-based object from one representation to another."""
+
+class NotACertificateChain(Exception):
+ """Certificates don't form a proper chain."""
diff --git a/scripts/rpki/https.py b/scripts/rpki/https.py
index eec5b81d..18a3c738 100644
--- a/scripts/rpki/https.py
+++ b/scripts/rpki/https.py
@@ -7,7 +7,7 @@ subversion repository; generalizing it would not be hard, but the more
general version should use SQL anyway.
"""
-import httplib, BaseHTTPServer, tlslite.api, glob, rpki.x509
+import httplib, BaseHTTPServer, tlslite.api, glob, rpki.x509, traceback, rpki.exceptions
rpki_content_type = "application/x-rpki"
@@ -32,29 +32,32 @@ def client(msg, privateKey, certChain, x509TrustList, host="localhost", port=443
return response.read()
else:
r = response.read()
- raise RuntimeError, (response.status, r)
+ raise rpki.exceptions.HTTPRequestFailed, "HTTP request failed with status %s, response %s" % (response.status, r)
class requestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""Derived type to supply POST handler."""
rpki_handlers = None # Subclass must bind
- def do_POST(self):
- """POST handler."""
- assert self.headers["Content-Type"] == rpki_content_type
- query_string = self.rfile.read(int(self.headers["Content-Length"]))
- handler = None
+ def rpki_find_handler(self):
for s,h in self.rpki_handlers:
if self.path.startswith(s):
- handler = h
- break
- if handler is None:
- rcode, rtext = 404, "No handler found for URL " + self.path
- else:
- try:
- rcode, rtext = handler(query=query_string, path=self.path)
- except Exception, edata:
- rcode, rtext = 500, "Unhandled exception %s" % edata
+ return h
+ return None
+
+ def do_POST(self):
+ """POST handler."""
+ try:
+ handler = self.rpki_find_handler()
+ if self.headers["Content-Type"] != rpki_content_type:
+ rcode, rtext = 415, "Received Content-Type %s, expected %s" % (self.headers["Content-Type"], rpki_content_type)
+ elif handler is None:
+ rcode, rtext = 404, "No handler found for URL " + self.path
+ else:
+ rcode, rtext = handler(query=self.rfile.read(int(self.headers["Content-Length"])), path=self.path)
+ except Exception, edata:
+ traceback.print_exc()
+ rcode, rtext = 500, "Unhandled exception %s" % edata
self.send_response(rcode)
self.send_header("Content-Type", rpki_content_type)
self.end_headers()
diff --git a/scripts/rpki/left_right.py b/scripts/rpki/left_right.py
index 9b1f0d89..ffaa17ad 100644
--- a/scripts/rpki/left_right.py
+++ b/scripts/rpki/left_right.py
@@ -2,7 +2,7 @@
"""RPKI "left-right" protocol."""
-import base64, rpki.sax_utils, rpki.resource_set, lxml.etree, rpki.x509, rpki.sql
+import base64, rpki.sax_utils, rpki.resource_set, lxml.etree, rpki.x509, rpki.sql, rpki.exceptions
xmlns = "http://www.hactrn.net/uris/rpki/left-right-spec/"
@@ -123,12 +123,14 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
r_msg.append(make_error_report(self))
def serve_dispatch(self, db, cur, r_msg):
- assert self.type == "query"
- { "create" : self.serve_create,
- "set" : self.serve_set,
- "get" : self.serve_get,
- "list" : self.serve_list,
- "destroy" : self.serve_destroy }[self.action](db, cur, r_msg)
+ dispatch = { "create" : self.serve_create,
+ "set" : self.serve_set,
+ "get" : self.serve_get,
+ "list" : self.serve_list,
+ "destroy" : self.serve_destroy }
+ if self.type != "query" or self.action not in dispatch:
+ raise rpki.exceptions.BadQuery, "Unexpected query: type %s, action %s" % (self.type, self.action)
+ dispatch[self.action](db, cur, r_msg)
class extension_preference_elt(base_elt):
"""Container for extension preferences."""
@@ -349,7 +351,7 @@ class route_origin_elt(data_elt):
roa = roas[0][0]
ca_detail_id = roas[0][1]
elif len(roas) > 0:
- raise RunTimeError, "Multiple ROAs found, mapping should be one-to-one"
+ raise rpki.exceptions.MultipleROAsFound, "Multiple ROAs found for route_origin %s, mapping should be one-to-one" % self.route_origin_id
def sql_insert_hook(self, db, cur):
if self.ipv4 + self.ipv6:
diff --git a/scripts/rpki/up_down.py b/scripts/rpki/up_down.py
index d1437775..ebff70d0 100644
--- a/scripts/rpki/up_down.py
+++ b/scripts/rpki/up_down.py
@@ -2,7 +2,7 @@
"""RPKI "up-down" protocol."""
-import base64, sax_utils, resource_set, lxml.etree, x509
+import base64, rpki.sax_utils, rpki.resource_set, lxml.etree, x509, rpki.exceptions
xmlns="http://www.apnic.net/specs/rescerts/up-down/"
@@ -55,7 +55,8 @@ class multi_uri(list):
elif isinstance(ini, str):
self[:] = ini.split(",")
for s in self:
- assert s.strip() == s and s.find("://") >= 0, "Bad URI \"%s\"" % s
+ if s.strip() != s or s.find("://") < 0:
+ raise rpki.exceptions.BadURISyntax, "Bad URI \"%s\"" % s
else:
raise TypeError
@@ -76,13 +77,13 @@ class certificate_elt(base_elt):
"""Handle attributes of <certificate/> element."""
assert name == "certificate", "Unexpected name %s, stack %s" % (name, stack)
self.cert_url = multi_uri(attrs["cert_url"])
- self.req_resource_set_as = resource_set.resource_set_as(attrs.get("req_resource_set_as"))
- self.req_resource_set_ipv4 = resource_set.resource_set_ipv4(attrs.get("req_resource_set_ipv4"))
- self.req_resource_set_ipv6 = resource_set.resource_set_ipv6(attrs.get("req_resource_set_ipv6"))
+ self.req_resource_set_as = rpki.resource_set.resource_set_as(attrs.get("req_resource_set_as"))
+ self.req_resource_set_ipv4 = rpki.resource_set.resource_set_ipv4(attrs.get("req_resource_set_ipv4"))
+ self.req_resource_set_ipv6 = rpki.resource_set.resource_set_ipv6(attrs.get("req_resource_set_ipv6"))
def endElement(self, stack, name, text):
"""Handle text content of a <certificate/> element."""
- assert name == "certificate"
+ assert name == "certificate", "Unexpected name %s, stack %s" % (name, stack)
self.cert = x509.X509(Base64=text)
stack.pop()
@@ -110,9 +111,9 @@ class class_elt(base_elt):
self.class_name = attrs["class_name"]
self.cert_url = multi_uri(attrs["cert_url"])
self.suggested_sia_head = attrs.get("suggested_sia_head")
- self.resource_set_as = resource_set.resource_set_as(attrs["resource_set_as"])
- self.resource_set_ipv4 = resource_set.resource_set_ipv4(attrs["resource_set_ipv4"])
- self.resource_set_ipv6 = resource_set.resource_set_ipv6(attrs["resource_set_ipv6"])
+ self.resource_set_as = rpki.resource_set.resource_set_as(attrs["resource_set_as"])
+ self.resource_set_ipv4 = rpki.resource_set.resource_set_ipv4(attrs["resource_set_ipv4"])
+ self.resource_set_ipv6 = rpki.resource_set.resource_set_ipv6(attrs["resource_set_ipv6"])
def endElement(self, stack, name, text):
"""Handle <class/> elements and their children."""
@@ -161,9 +162,9 @@ class issue_pdu(base_elt):
"""Handle "issue" PDU."""
assert name == "request", "Unexpected name %s, stack %s" % (name, stack)
self.class_name = attrs["class_name"]
- self.req_resource_set_as = resource_set.resource_set_as(attrs.get("req_resource_set_as"))
- self.req_resource_set_ipv4 = resource_set.resource_set_ipv4(attrs.get("req_resource_set_ipv4"))
- self.req_resource_set_ipv6 = resource_set.resource_set_ipv6(attrs.get("req_resource_set_ipv6"))
+ self.req_resource_set_as = rpki.resource_set.resource_set_as(attrs.get("req_resource_set_as"))
+ self.req_resource_set_ipv4 = rpki.resource_set.resource_set_ipv4(attrs.get("req_resource_set_ipv4"))
+ self.req_resource_set_ipv6 = rpki.resource_set.resource_set_ipv6(attrs.get("req_resource_set_ipv6"))
def endElement(self, stack, name, text):
"""Handle "issue" PDU."""
@@ -219,7 +220,8 @@ class error_response_pdu(base_elt):
"""Handle "error_response" PDU."""
if name == "status":
code = int(text)
- assert code in self.codes
+ if code not in self.codes:
+ raise rpki.exceptions.BadStatusCode, "%s is not a known status code"
self.status = code
elif name == "last_message_processed":
self.last_message_processed = text
@@ -274,7 +276,7 @@ class message_pdu(base_elt):
def __str__(self):
lxml.etree.tostring(self.toXML(), pretty_print=True, encoding="UTF-8")
-class sax_handler(sax_utils.handler):
+class sax_handler(rpki.sax_utils.handler):
"""SAX handler for Up-Down protocol."""
def create_top_level(self, name, attrs):
diff --git a/scripts/rpki/x509.py b/scripts/rpki/x509.py
index ad3f0e85..3e352baf 100644
--- a/scripts/rpki/x509.py
+++ b/scripts/rpki/x509.py
@@ -12,7 +12,7 @@ bring together the functionality I need in a way that hides at least
some of the nasty details. This involves a lot of format conversion.
"""
-import POW, tlslite.api, POW.pkix, base64
+import POW, tlslite.api, POW.pkix, base64, rpki.exceptions
class PEM_converter(object):
"""Convert between DER and PEM encodings for various kinds of ASN.1 data."""
@@ -108,7 +108,7 @@ class DER_object(object):
self.clear()
self.DER = text
return
- raise TypeError
+ raise rpki.exceptions.DERObjectConversionError, "Can't honor conversion request %s" % repr(kw)
def get_DER(self):
"""Get the DER value of this object.
@@ -118,7 +118,7 @@ class DER_object(object):
assert not self.empty()
if self.DER:
return self.DER
- raise RuntimeError, "No conversion path to DER available"
+ raise rpki.exceptions.DERObjectConversionError, "No conversion path to DER available"
def get_Base64(self):
"""Get the Base64 encoding of the DER value of this object."""
@@ -153,7 +153,7 @@ class X509(DER_object):
if self.POWpkix:
self.DER = self.POWpkix.toString()
return self.get_DER()
- raise RuntimeError
+ raise rpki.exceptions.DERObjectConversionError, "No conversion path to DER available"
def get_POW(self):
"""Get the POW value of this certificate."""
@@ -232,7 +232,7 @@ class X509_chain(list):
chain.append(cert)
bag.remove(cert)
if len(chain) != 1:
- raise RuntimeError, "Certificates in bag don't form a proper chain"
+ raise rpki.exceptions.NotACertificateChain, "Certificates in bag don't form a proper chain"
while bag:
cert = subject_map[chain[-1].getIssuer()]
chain.append(cert)
@@ -274,7 +274,7 @@ class PKCS10_Request(DER_object):
if self.POWpkix:
self.DER = self.POWpkix.toString()
return self.get_DER()
- raise RuntimeError
+ raise rpki.exceptions.DERObjectConversionError, "No conversion path to DER available"
def get_POWpkix(self):
"""Get the POW.pkix value of this certification request."""
@@ -301,7 +301,7 @@ class RSA_Keypair(DER_object):
if self.POW:
self.DER = self.POW.derWrite()
return self.get_DER()
- raise RuntimeError
+ raise rpki.exceptions.DERObjectConversionError, "No conversion path to DER available"
def get_POW(self):
assert not self.empty()