aboutsummaryrefslogtreecommitdiff
path: root/scripts/rpki
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/rpki')
-rw-r--r--scripts/rpki/config.py1
-rw-r--r--scripts/rpki/https.py1
-rw-r--r--scripts/rpki/ipaddrs.py4
-rw-r--r--scripts/rpki/left_right.py31
-rw-r--r--scripts/rpki/pkcs10.py1
-rw-r--r--scripts/rpki/resource_set.py9
-rw-r--r--scripts/rpki/sax_utils.py1
-rw-r--r--scripts/rpki/sql.py17
-rw-r--r--scripts/rpki/up_down.py31
-rw-r--r--scripts/rpki/x509.py19
10 files changed, 103 insertions, 12 deletions
diff --git a/scripts/rpki/config.py b/scripts/rpki/config.py
index 01dfb522..962f28fd 100644
--- a/scripts/rpki/config.py
+++ b/scripts/rpki/config.py
@@ -10,6 +10,7 @@ import ConfigParser
class parser(ConfigParser.RawConfigParser):
def __init__(self, file=None):
+ """Initialize this parser."""
ConfigParser.RawConfigParser.__init__(self)
if file:
self.read(file)
diff --git a/scripts/rpki/https.py b/scripts/rpki/https.py
index 70e035f8..6aeba62a 100644
--- a/scripts/rpki/https.py
+++ b/scripts/rpki/https.py
@@ -50,6 +50,7 @@ class requestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
rpki_handlers = None # Subclass must bind
def rpki_find_handler(self):
+ """Helper method to search self.rpki_handlers."""
for s,h in self.rpki_handlers:
if self.path.startswith(s):
return h
diff --git a/scripts/rpki/ipaddrs.py b/scripts/rpki/ipaddrs.py
index 26beb4a1..161ffae4 100644
--- a/scripts/rpki/ipaddrs.py
+++ b/scripts/rpki/ipaddrs.py
@@ -24,12 +24,14 @@ class v4addr(long):
bits = 32
def __new__(cls, x):
+ """Construct a v4addr object."""
if isinstance(x, str):
y = struct.unpack("!I", socket.inet_pton(socket.AF_INET, x))
x = y[0]
return long.__new__(cls, x)
def __str__(self):
+ """Convert a v4addr object to string format."""
return socket.inet_ntop(socket.AF_INET, struct.pack("!I", long(self)))
class v6addr(long):
@@ -41,10 +43,12 @@ class v6addr(long):
bits = 128
def __new__(cls, x):
+ """Construct a v6addr object."""
if isinstance(x, str):
y = struct.unpack("!QQ", socket.inet_pton(socket.AF_INET6, x))
x = (y[0] << 64) | y[1]
return long.__new__(cls, x)
def __str__(self):
+ """Convert a v6addr object to string format."""
return socket.inet_ntop(socket.AF_INET6, struct.pack("!QQ", long(self) >> 64, long(self) & 0xFFFFFFFFFFFFFFFF))
diff --git a/scripts/rpki/left_right.py b/scripts/rpki/left_right.py
index 52a02d5d..73d2130d 100644
--- a/scripts/rpki/left_right.py
+++ b/scripts/rpki/left_right.py
@@ -54,12 +54,14 @@ class base_elt(object):
lxml.etree.SubElement(elt, "{%s}%s" % (xmlns, name), nsmap=nsmap).text = base64.b64encode(value)
def __str__(self):
+ """Convert a base_elt object to string format."""
lxml.etree.tostring(self.toXML(), pretty_print=True, encoding="us-ascii")
class data_elt(base_elt, rpki.sql.sql_persistant):
"""Virtual class for top-level left-right protocol data elements."""
def sql_decode(self, vals):
+ """Decode SQL form of a data_elt object."""
rpki.sql.sql_persistant.sql_decode(self, vals)
if "cms_ta" in vals:
self.cms_ta = rpki.x509.X509(DER=vals["cms_ta"])
@@ -71,6 +73,7 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
self.public_key = rpki.x509.RSA(DER=vals["public_key"])
def sql_encode(self):
+ """Encode SQL form of a data_elt object."""
d = rpki.sql.sql_persistant.sql_encode(self)
for i in ("cms_ta", "https_ta", "private_key_id", "public_key"):
if i in d:
@@ -78,6 +81,7 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
return d
def make_reply(self, r_pdu=None):
+ """Construct a reply PDU."""
if r_pdu is None:
r_pdu = self.__class__()
r_pdu.self_id = self.self_id
@@ -87,12 +91,15 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
return r_pdu
def serve_pre_save_hook(self, q_pdu, r_pdu):
+ """Overridable hook."""
pass
def serve_post_save_hook(self, q_pdu, r_pdu):
+ """Overridable hook."""
pass
def serve_create(self, gctx, r_msg):
+ """Handle a create action."""
r_pdu = self.make_reply()
self.serve_pre_save_hook(self, r_pdu)
self.sql_store(gctx.db, gctx.cur)
@@ -101,6 +108,7 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
r_msg.append(r_pdu)
def serve_set(self, gctx, r_msg):
+ """Handle a set action."""
db_pdu = self.sql_fetch(gctx, getattr(self, self.sql_template.index))
if db_pdu is not None:
r_pdu = self.make_reply()
@@ -117,6 +125,7 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
r_msg.append(make_error_report(self))
def serve_get(self, gctx, r_msg):
+ """Handle a get action."""
r_pdu = self.sql_fetch(gctx, getattr(self, self.sql_template.index))
if r_pdu is not None:
self.make_reply(r_pdu)
@@ -125,11 +134,13 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
r_msg.append(make_error_report(self))
def serve_list(self, gctx, r_msg):
+ """Handle a list action."""
for r_pdu in self.sql_fetch_all(gctx.db, gctx.cur):
self.make_reply(r_pdu)
r_msg.append(r_pdu)
def serve_destroy(self, gctx, r_msg):
+ """Handle a destroy action."""
db_pdu = self.sql_fetch(gctx, getattr(self, self.sql_template.index))
if db_pdu is not None:
db_pdu.sql_delete(gctx.db, gctx.cur)
@@ -138,6 +149,7 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
r_msg.append(make_error_report(self))
def serve_dispatch(self, gctx, r_msg):
+ """Action dispatch handler."""
dispatch = { "create" : self.serve_create,
"set" : self.serve_set,
"get" : self.serve_get,
@@ -183,9 +195,11 @@ class self_elt(data_elt):
use_hsm = False
def __init__(self):
+ """Initialize a self_elt."""
self.prefs = []
def sql_fetch_hook(self, gctx):
+ """Extra SQL fetch actions for self_elt -- handle extension preferences."""
gctx.cur.execute("SELECT pref_name, pref_value FROM self_pref WHERE self_id = %s", self.self_id)
for name, value in gctx.cur.fetchall():
e = extension_preference_elt()
@@ -194,20 +208,24 @@ class self_elt(data_elt):
self.prefs.append(e)
def sql_insert_hook(self, gctx):
+ """Extra SQL insert actions for self_elt -- handle extension preferences."""
if self.prefs:
gctx.cur.executemany("INSERT self_pref (self_id, pref_name, pref_value) VALUES (%s, %s, %s)",
((e.name, e.value, self.self_id) for e in self.prefs))
def sql_delete_hook(self, gctx):
+ """Extra SQL delete actions for self_elt -- handle extension preferences."""
gctx.cur.execute("DELETE FROM self_pref WHERE self_id = %s", self.self_id)
def serve_pre_save_hook(self, q_pdu, r_pdu):
+ """Extra server actions for self_elt -- handle extension preferences."""
if self is not q_pdu:
if q_pdu.clear_extension_preferences:
self.prefs = []
self.prefs.extend(pdu.prefs)
def serve_post_save_hook(self, q_pdu, r_pdu):
+ """Extra server actions for self_elt."""
if self.rekey or self.reissue or self.revoke or self.run_now or self.publish_world_now:
raise NotImplementedError, "Unimplemented control %s" % ", ".join(b for b in ("rekey", "reissue", "revoke", "run_now", "publish_world_now") if getattr(self, b))
@@ -264,20 +282,25 @@ class bsc_elt(data_elt):
private_key_id = None
def __init__(self):
+ """Initialize bsc_elt."""
self.signing_cert = []
def sql_fetch_hook(self, gctx):
+ """Extra SQL fetch actions for bsc_elt -- handle signing certs."""
gctx.cur.execute("SELECT cert FROM bsc_cert WHERE bsc_id = %s", self.bsc_id)
self.signing_cert = [rpki.x509.X509(DER=x) for (x,) in gctx.cur.fetchall()]
def sql_insert_hook(self, gctx):
+ """Extra SQL insert actions for bsc_elt -- handle signing certs."""
if self.signing_cert:
gctx.cur.executemany("INSERT bsc_cert (cert, bsc_id) VALUES (%s, %s)", ((x.get_DER(), self.bsc_id) for x in self.signing_cert))
def sql_delete_hook(self, gctx):
+ """Extra SQL delete actions for bsc_elt -- handle signing certs."""
gctx.cur.execute("DELETE FROM bsc_cert WHERE bsc_id = %s", self.bsc_id)
def serve_pre_save_hook(self, q_pdu, r_pdu):
+ """Extra server actions for bsc_elt -- handle signing certs and key generation."""
if self is not q_pdu:
if q_pdu.clear_signing_certs:
self.signing_cert = []
@@ -336,6 +359,7 @@ class parent_elt(data_elt):
https_ta = None
def serve_post_save_hook(self, q_pdu, r_pdu):
+ """"Extra server actions for parent_elt."""
if self.rekey or self.reissue or self.revoke:
raise NotImplementedError, "Unimplemented control %s" % ", ".join(b for b in ("rekey", "reissue", "revoke") if getattr(self, b))
@@ -402,6 +426,7 @@ class child_elt(data_elt):
cms_ta = None
def serve_post_save_hook(self, q_pdu, r_pdu):
+ """Extra server actions for child_elt."""
if self.reissue:
raise NotImplementedError, "Unimplemented control %s" % ", ".join(b for b in ("reissue",) if getattr(self, b))
@@ -491,6 +516,7 @@ class route_origin_elt(data_elt):
roa = None
def sql_fetch_hook(self, gctx):
+ """Extra SQL fetch actions for route_origin_elt -- handle address ranges."""
self.ipv4 = rpki.resource_set.resource_set_ipv4.from_sql(gctx.cur,
"SELECT start_ip, end_ip FROM route_origin_range WHERE route_origin_id = %s AND start_ip NOT LIKE '%:%'",
self.route_origin_id)
@@ -499,14 +525,17 @@ class route_origin_elt(data_elt):
self.route_origin_id)
def sql_insert_hook(self, gctx):
+ """Extra SQL insert actions for route_origin_elt -- handle address ranges."""
if self.ipv4 + self.ipv6:
gctx.cur.executemany("INSERT route_origin_range (route_origin_id, start_ip, end_ip) VALUES (%s, %s, %s)",
((self.route_origin_id, x.min, x.max) for x in self.ipv4 + self.ipv6))
def sql_delete_hook(self, gctx):
+ """Extra SQL delete actions for route_origin_elt -- handle address ranges."""
gctx.cur.execute("DELETE FROM route_origin_range WHERE route_origin_id = %s", self.route_origin_id)
def serve_post_save_hook(self, q_pdu, r_pdu):
+ """Extra server actions for route_origin_elt."""
if self.suppress_publication:
raise NotImplementedError, "Unimplemented control %s" % ", ".join(b for b in ("suppress_publication",) if getattr(self, b))
@@ -601,6 +630,7 @@ class msg(list):
stack.pop()
def __str__(self):
+ """Convert msg object to string."""
lxml.etree.tostring(self.toXML(), pretty_print=True, encoding="us-ascii")
def toXML(self):
@@ -610,6 +640,7 @@ class msg(list):
return elt
def serve_top_level(self, gctx):
+ """Serve one msg PDU."""
r_msg = self.__class__()
for q_pdu in self:
q_pdu.serve_dispatch(gctx, r_msg)
diff --git a/scripts/rpki/pkcs10.py b/scripts/rpki/pkcs10.py
index 3617a837..25326c20 100644
--- a/scripts/rpki/pkcs10.py
+++ b/scripts/rpki/pkcs10.py
@@ -23,6 +23,7 @@ CN = %s
'''
def make_request(keypair):
+ """Generate a PKCS #10 request."""
digest = POW.Digest(POW.SHA1_DIGEST)
digest.update(keypair.get_POW().derWrite(POW.RSA_PUBLIC_KEY))
diff --git a/scripts/rpki/resource_set.py b/scripts/rpki/resource_set.py
index b57d3424..d176e70a 100644
--- a/scripts/rpki/resource_set.py
+++ b/scripts/rpki/resource_set.py
@@ -20,11 +20,13 @@ class resource_range(object):
"""
def __init__(self, min, max):
+ """Initialize and sanity check a resource_range."""
assert min <= max, "Mis-ordered range: %s before %s" % (str(min), str(max))
self.min = min
self.max = max
def __cmp__(self, other):
+ """Compare two resource_range objects."""
c = self.min - other.min
if c == 0: c = self.max - other.max
if c < 0: c = -1
@@ -38,12 +40,14 @@ class resource_range_as(resource_range):
"""
def __str__(self):
+ """Convert a resource_range_as to string format."""
if self.min == self.max:
return str(self.min)
else:
return str(self.min) + "-" + str(self.max)
def to_tuple(self):
+ """Convert a resource_range_as to tuple format for ASN.1 encoding."""
if self.min == self.max:
return ("id", self.min)
else:
@@ -57,6 +61,7 @@ class resource_range_ip(resource_range):
"""
def _prefixlen(self):
+ """Determine whether a resource_range_ip can be expressed as a prefix."""
mask = self.min ^ self.max
prefixlen = self.addr_type.bits
while mask & 1:
@@ -68,6 +73,7 @@ class resource_range_ip(resource_range):
return prefixlen
def __str__(self):
+ """Convert a resource_range_ip to string format."""
prefixlen = self._prefixlen()
if prefixlen < 0:
return str(self.min) + "-" + str(self.max)
@@ -75,6 +81,7 @@ class resource_range_ip(resource_range):
return str(self.min) + "/" + str(prefixlen)
def to_tuple(self):
+ """Convert a resource_range_ip to tuple format for ASN.1 encoding."""
prefixlen = self._prefixlen()
if prefixlen < 0:
return ("addressRange", (_long2bs(self.min, self.addr_type.bits, strip = 0),
@@ -113,6 +120,7 @@ class resource_set(list):
"""
def __init__(self, ini=None):
+ """Initialize a resource_set."""
if isinstance(ini, long):
ini = str(ini)
if isinstance(ini, str) and len(ini):
@@ -129,6 +137,7 @@ class resource_set(list):
assert self[i].max < self[i+1].min, "Resource overlap: %s %s" % (self[i], self[i+1])
def __str__(self):
+ """Convert a resource_set to string format."""
return ",".join(map(str, self))
def _comm(self, other):
diff --git a/scripts/rpki/sax_utils.py b/scripts/rpki/sax_utils.py
index 058deeb2..f1531c24 100644
--- a/scripts/rpki/sax_utils.py
+++ b/scripts/rpki/sax_utils.py
@@ -19,6 +19,7 @@ class handler(xml.sax.handler.ContentHandler):
"""
def __init__(self):
+ """Initialize SAX handler."""
self.text = ""
self.stack = []
diff --git a/scripts/rpki/sql.py b/scripts/rpki/sql.py
index e0b3a23b..9bc72679 100644
--- a/scripts/rpki/sql.py
+++ b/scripts/rpki/sql.py
@@ -13,6 +13,7 @@ def connect(cfg, section="sql"):
class template(object):
"""SQL template generator."""
def __init__(self, table_name, *columns):
+ """Build a SQL template."""
index_column = columns[0]
data_columns = columns[1:]
self.table = table_name
@@ -61,6 +62,7 @@ class sql_persistant(object):
@classmethod
def sql_fetch(cls, gctx, id):
+ """Fetch one object from SQL, based on its primary key."""
results = cls.sql_fetch_where(gctx, "%s = %s" % (cls.sql_template.index, id))
assert len(results) <= 1
if len(results) == 0:
@@ -72,10 +74,12 @@ class sql_persistant(object):
@classmethod
def sql_fetch_all(cls, gctx):
+ """Fetch all objects of this type from SQL."""
return cls.sql_fetch_where(gctx, None)
@classmethod
def sql_fetch_where(cls, gctx, where):
+ """Fetch objects of this type matching an arbitrary SQL WHERE expression."""
if where is None:
gctx.cur.execute(cls.sql_template.select)
else:
@@ -91,6 +95,7 @@ class sql_persistant(object):
@classmethod
def sql_init(cls, gctx, row, key):
+ """Initialize one Python object from the result of a SQL query."""
self = cls()
self.sql_decode(dict(zip(cls.sql_template.columns, row)))
sql_cache[key] = self
@@ -99,15 +104,19 @@ class sql_persistant(object):
return self
def sql_mark_dirty(self):
+ """Mark this object as needing to be written back to SQL."""
sql_dirty.add(self)
def sql_mark_clean(self):
+ """Mark this object as not needing to be written back to SQL."""
sql_dirty.discard(self)
def sql_is_dirty(self):
+ """Query whether this object needs to be written back to SQL."""
return self in sql_dirty
def sql_store(self, gctx):
+ """Store this object to SQL."""
if not self.sql_in_db:
gctx.cur.execute(self.sql_template.insert, self.sql_encode())
setattr(self, self.sql_template.index, gctx.cur.lastrowid)
@@ -122,6 +131,7 @@ class sql_persistant(object):
self.sql_in_db = True
def sql_delete(self, gctx):
+ """Delete this object from SQL."""
if self.sql_in_db:
id = getattr(self, self.sql_template.index)
gctx.cur.execute(self.sql_template.delete, id)
@@ -264,6 +274,7 @@ class ca_detail_obj(sql_persistant):
"manifest_public_key", "latest_manifest_cert", "latest_manifest", "latest_crl", "state", "ca_cert_uri", "ca_id")
def sql_decode(self, vals):
+ """Decode SQL representation of a ca_detail_obj."""
sql_persistant.sql_decode(self, vals)
self.private_key_id = rpki.x509.RSA(DER = self.private_key_id)
self.public_key = rpki.x509.RSApublic(DER = self.public_key)
@@ -277,6 +288,7 @@ class ca_detail_obj(sql_persistant):
self.latest_crl = rpki.x509.CRL(DER = self.latest_crl)
def sql_encode(self):
+ """Encode SQL representation of a ca_detail_obj."""
d = sql_persistant.sql_encode(self)
for i in ("private_key_id", "public_key", "latest_ca_cert", "manifest_private_key_id", "manifest_public_key", "latest_manifest_cert", "latest_manifest", "latest_crl"):
d[i] = getattr(self, i).get_DER()
@@ -284,6 +296,7 @@ class ca_detail_obj(sql_persistant):
@classmethod
def sql_fetch_active(cls, gctx, ca_id):
+ """Fetch the current active ca_detail_obj associated with a given ca_id."""
actives = cls.sql_fetch_where(gctx, "ca_id = %s AND state = 'active'" % ca_id)
assert len(actives) < 2, "Found more than one 'active' ca_detail record, this should not happen!"
if actives:
@@ -336,6 +349,7 @@ class child_cert_obj(sql_persistant):
sql_template = template("child_cert", "child_cert_id", "cert", "child_id", "ca_detail_id")
def __init__(self, child_id = None, ca_detail_id = None, cert = None):
+ """Initialize a child_cert_obj."""
self.child_id = child_id
self.ca_detail_id = ca_detail_id
self.cert = cert
@@ -343,13 +357,16 @@ class child_cert_obj(sql_persistant):
self.sql_mark_dirty()
def sql_decode(self, vals):
+ """Decode SQL representation of a child_cert_obj."""
sql_persistant.sql_decode(self, vals)
self.cert = rpki.x509.X509(DER = self.cert)
def sql_encode(self):
+ """Encode SQL representation of a child_cert_obj."""
d = sql_persistant.sql_encode(self)
d["cert"] = self.cert.get_DER()
return d
def reissue(self, gctx, ca_detail, as, v4, v6):
+ """Reissue an existing child_cert_obj."""
raise NotImplementedError, "NIY"
diff --git a/scripts/rpki/up_down.py b/scripts/rpki/up_down.py
index d2644f52..a950176c 100644
--- a/scripts/rpki/up_down.py
+++ b/scripts/rpki/up_down.py
@@ -62,6 +62,7 @@ class base_elt(object):
lxml.etree.SubElement(elt, "{%s}%s" % (xmlns, name), nsmap=nsmap).text = base64.b64encode(value)
def serve_pdu(self, gctx, q_msg, r_msg, child):
+ """Default PDU handler to catch unexpected types."""
raise rpki.exceptions.BadQuery, "Unexpected query type %s" % q_msg.type
class multi_uri(list):
@@ -80,6 +81,7 @@ class multi_uri(list):
raise TypeError
def __str__(self):
+ """Convert a multi_uri back to a string representation."""
return ",".join(self)
def rsync(self):
@@ -116,6 +118,7 @@ class class_elt(base_elt):
"""Up-Down protocol representation of a resource class."""
def __init__(self):
+ """Initialize class_elt."""
self.certs = []
def startElement(self, stack, name, attrs):
@@ -189,6 +192,7 @@ class class_response_syntax(base_elt):
"""Syntax for Up-Down protocol "list_response" and "issue_response" PDUs."""
def __init__(self):
+ """Initialize class_response_syntax."""
self.classes = []
def startElement(self, stack, name, attrs):
@@ -232,6 +236,7 @@ class issue_pdu(base_elt):
return [elt]
def serve_pdu(self, gctx, q_msg, r_msg, child):
+ """Serve one issue request PDU."""
#
# Step 1: Check the request
if not self.class_name.isdigit():
@@ -247,13 +252,10 @@ class issue_pdu(base_elt):
rc_as, rc_v4, rc_v6 = ca_detail.latest_ca_cert.get_3779resources(rpki.left_right.irdb_query(gctx, child.self_id, child.child_id))
req_key = self.pkcs10.getPublicKey()
req_sia = self.pkcs10.get_SIA()
- #
- # This next search loop might be an argument for a child_cert.ski column
- for child_cert in rpki.sql.child_cert_obj.sql_fetch_where(gctx, "child_id = %s AND ca_detail_id = %s" % (child.child_id, ca_detail.ca_detail_id)):
- if child_cert.cert.getPublicKey() == req_key:
- break
- else:
- child_cert = None
+ req_ski = self.pkcs10.get_SKI()
+ child_cert = rpki.sql.child_cert_obj.sql_fetch_where(gctx, "child_id = %s AND ca_detail_id = %s AND ski = %s" % (child.child_id, ca_detail.ca_detail_id, req_ski))
+ assert len(child_cert) < 2
+ child_cert = child_cert[0] if child_cert else None
# Hmm, these next checks no longer seem reasonable in context. If
# we found the matching public key/SKI, we've found the right
@@ -346,8 +348,13 @@ class revoke_syntax(base_elt):
class revoke_pdu(revoke_syntax):
"""Up-Down protocol "revoke" PDU."""
+
+ def get_SKI(self):
+ """Convert g(SKI) encoding from PDU back to raw SKI."""
+ return base64.b64decode(self.ski.replace("_", "/").replace("-", "+"))
def serve_pdu(self, gctx, q_msg, r_msg, child):
+ """Serve one revoke request PDU."""
if not self.class_name.isdigit():
raise rpki.exceptions.BadClassNameSyntax, "Bad class name %s" % self.class_name
ca_id = long(self.class_name)
@@ -355,11 +362,8 @@ class revoke_pdu(revoke_syntax):
ca_detail = rpki.sql.ca_detail_obj.sql_fetch_active(gctx, ca_id)
if ca is None or ca_detail is None:
raise rpki.exceptions.NotInDatabase
- ski = base64.b64decode(self.ski.replace("_", "/").replace("-", "+"))
- # This next search loop might be an argument for a child_cert.ski column
- for c in rpki.sql.child_cert_obj.sql_fetch_where(gctx, "child_id = %s AND ca_detail_id = %s" % (child.child_id, ca_detail.ca_detail_id)):
- if c.cert.get_SKI() == ski:
- c.sql_delete()
+ for c in rpki.sql.child_cert_obj.sql_fetch_where(gctx, "child_id = %s AND ca_detail_id = %s AND ski = %s" % (child.child_id, ca_detail.ca_detail_id, self.get_SKI())):
+ c.sql_delete()
r_msg.payload = revoke_response_pdu()
r_msg.payload.class_name = self.class_name
r_msg.payload.ski = self.ski
@@ -454,9 +458,11 @@ class message_pdu(base_elt):
stack.append(self.payload)
def __str__(self):
+ """Convert a message PDU to a string."""
lxml.etree.tostring(self.toXML(), pretty_print=True, encoding="UTF-8")
def serve_top_level(self, gctx, child):
+ """Serve one message request PDU."""
r_msg = message_pdu()
r_msg.sender = self.receiver
r_msg.receiver = self.sender
@@ -465,6 +471,7 @@ class message_pdu(base_elt):
@classmethod
def make_query(cls, payload, sender = "tweedledee", recipient = "tweedledum"):
+ """Construct one message PDU."""
assert not self.type2name[type(payload)].endswith("_response")
self = cls()
self.sender = sender
diff --git a/scripts/rpki/x509.py b/scripts/rpki/x509.py
index 0178a33d..96503f3d 100644
--- a/scripts/rpki/x509.py
+++ b/scripts/rpki/x509.py
@@ -19,10 +19,12 @@ class PEM_converter(object):
"""Convert between DER and PEM encodings for various kinds of ASN.1 data."""
def __init__(self, kind): # "CERTIFICATE", "RSA PRIVATE KEY", ...
+ """Initialize PEM_converter."""
self.b = "-----BEGIN %s-----" % kind
self.e = "-----END %s-----" % kind
def looks_like_PEM(self, text):
+ """Guess whether text looks like a PEM encoding."""
b = text.find(self.b)
return b >= 0 and text.find(self.e) > b + len(self.b)
@@ -73,6 +75,7 @@ class DER_object(object):
setattr(self, a, None)
def __init__(self, **kw):
+ """Initialize a DER_object."""
self.clear()
if len(kw):
self.set(**kw)
@@ -243,6 +246,7 @@ class X509(DER_object):
return RSApublic(DER = self.get_POWpkix().tbs.subjectPublicKeyInfo.toString())
def issue(self, keypair, subject_key, serial, sia, aia, crldp, cn = None, notAfter = None, as = None, v4 = None, v6 = None, is_ca = True):
+ """Issue a certificate."""
now = time.time()
@@ -301,6 +305,7 @@ class X509_chain(list):
"""
def __init__(self, *args, **kw):
+ """Initialize an X509_chain."""
if args:
self[:] = args
elif "PEM_files" in kw:
@@ -459,6 +464,7 @@ class RSA(DER_object):
pem_converter = PEM_converter("RSA PRIVATE KEY")
def get_DER(self):
+ """Get the DER value of this keypair."""
assert not self.empty()
if self.DER:
return self.DER
@@ -468,30 +474,36 @@ class RSA(DER_object):
raise rpki.exceptions.DERObjectConversionError, "No conversion path to DER available"
def get_POW(self):
+ """Get the POW value of this keypair."""
assert not self.empty()
if not self.POW:
self.POW = POW.derRead(POW.RSA_PRIVATE_KEY, self.get_DER())
return self.POW
def get_tlslite(self):
+ """Get the tlslite value of this keypair."""
assert not self.empty()
if not self.tlslite:
self.tlslite = tlslite.api.parsePEMKey(self.get_PEM(), private=True)
return self.tlslite
def generate(self, keylength = 2048):
+ """Generate a new keypair."""
self.clear()
self.set(POW=POW.Asymmetric(POW.RSA_CIPHER, keylength))
def get_public_DER(self):
+ """Get the DER encoding of the public key from this keypair."""
return self.get_POW().derWrite(POW.RSA_PUBLIC_KEY)
def get_SKI(self):
+ """Calculate the SKI of this keypair."""
d = POW.Digest(POW.SHA1_DIGEST)
d.update(self.get_public_DER())
return d.digest()
def get_RSApublic(self):
+ """Convert the public key of this keypair into a RSApublic object."""
return RSApublic(DER = self.get_public_DER())
class RSApublic(DER_object):
@@ -501,6 +513,7 @@ class RSApublic(DER_object):
pem_converter = PEM_converter("RSA PUBLIC KEY")
def get_DER(self):
+ """Get the DER value of this public key."""
assert not self.empty()
if self.DER:
return self.DER
@@ -510,12 +523,14 @@ class RSApublic(DER_object):
raise rpki.exceptions.DERObjectConversionError, "No conversion path to DER available"
def get_POW(self):
+ """Get the POW value of this public key."""
assert not self.empty()
if not self.POW:
self.POW = POW.derRead(POW.RSA_PUBLIC_KEY, self.get_DER())
return self.POW
def get_SKI(self):
+ """Calculate the SKI of this public key."""
d = POW.Digest(POW.SHA1_DIGEST)
d.update(self.get_DER())
return d.digest()
@@ -549,19 +564,23 @@ class SignedManifest(DER_object):
return self.content
def set_content(self, content):
+ """Set the (inner) content of this manifest, clearing the wrapper."""
self.clear()
self.content = content
def sign(self, keypair, certs):
+ """Sign this manifest."""
self.DER = rpki.cms.sign(self.content.toString(), keypair, certs)
def verify(self, ta):
+ """Verify this manifest."""
m = rpki.manifest.Manifest()
s = rpki.cms.verify(self.get_DER(), ta)
m.fromString(s)
self.content = m
def build(self, serial, nextUpdate, names_and_objs):
+ """Build the inner content of this manifest."""
filelist = []
for name, obj in names_and_objs:
d = POW.Digest(POW.SHA256_DIGEST)