diff options
author | Rob Austein <sra@hactrn.net> | 2007-10-11 03:45:06 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2007-10-11 03:45:06 +0000 |
commit | e18315c69f2044d6e6d4e684a42183b0218df66f (patch) | |
tree | 2ebea6220a386b1459ae6be3683a6ed229bc7375 /scripts | |
parent | 7f56c3d9d33a0ee814cba03966d6a0851804e9a4 (diff) |
Doc
svn path=/docs/rpki-db-schema.pdf; revision=1155
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/rpki/config.py | 1 | ||||
-rw-r--r-- | scripts/rpki/https.py | 1 | ||||
-rw-r--r-- | scripts/rpki/ipaddrs.py | 4 | ||||
-rw-r--r-- | scripts/rpki/left_right.py | 31 | ||||
-rw-r--r-- | scripts/rpki/pkcs10.py | 1 | ||||
-rw-r--r-- | scripts/rpki/resource_set.py | 9 | ||||
-rw-r--r-- | scripts/rpki/sax_utils.py | 1 | ||||
-rw-r--r-- | scripts/rpki/sql.py | 17 | ||||
-rw-r--r-- | scripts/rpki/up_down.py | 31 | ||||
-rw-r--r-- | scripts/rpki/x509.py | 19 |
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) |