diff options
Diffstat (limited to 'rpkid')
-rw-r--r-- | rpkid/rpki/irdb/zookeeper.py | 2 | ||||
-rw-r--r-- | rpkid/rpki/oids.py | 202 | ||||
-rw-r--r-- | rpkid/rpki/resource_set.py | 1 | ||||
-rw-r--r-- | rpkid/rpki/rootd.py | 1 | ||||
-rw-r--r-- | rpkid/rpki/rpkic.py | 1 | ||||
-rw-r--r-- | rpkid/rpki/x509.py | 65 | ||||
-rw-r--r-- | rpkid/tests/testpoke.py | 1 |
7 files changed, 92 insertions, 181 deletions
diff --git a/rpkid/rpki/irdb/zookeeper.py b/rpkid/rpki/irdb/zookeeper.py index d2bd0c75..6c7d2206 100644 --- a/rpkid/rpki/irdb/zookeeper.py +++ b/rpkid/rpki/irdb/zookeeper.py @@ -1646,7 +1646,7 @@ class Zookeeper(object): raise rpki.exceptions.BadX510DN("Subject name doesn't match router profile: %s" % pkcs10.getSubject()) eku = pkcs10.getEKU() - if eku is None or rpki.oids.name2oid["id-kp-bgpsec-router"] not in eku: + if eku is None or rpki.oids.id_kp_bgpsec_router not in eku: raise rpki.exceptions.WrongEKU("Router certificate EKU not present in request") raise NotImplementedError, "Not finished" diff --git a/rpkid/rpki/oids.py b/rpkid/rpki/oids.py index 1acc8035..86be5c53 100644 --- a/rpkid/rpki/oids.py +++ b/rpkid/rpki/oids.py @@ -19,143 +19,83 @@ """ OID database. -""" - -def defoid(name, *numbers): - """ - Define a new OID, including adding it to a few dictionaries and - making an entry for it in the rpki.oids module symbol table, so - other code can refer to it as an ordinary symbol. - """ - - assert all(isinstance(n, (int, long)) for n in numbers) - - dotted = ".".join(str(n) for n in numbers) - name_ = name.replace("-", "_") - - assert name_ not in globals() - - global oid2name - oid2name[numbers] = name - - globals()[name_] = dotted - - global dotted2name - dotted2name[dotted] = name - - global dotted2name_ - dotted2name_[dotted] = name_ - - global name2dotted - name2dotted[name] = dotted - name2dotted[name_] = dotted - - -## @var oid2name -# Mapping table of OIDs to conventional string names. - -oid2name = { - (1, 2, 840, 10045, 4, 3, 2) : "ecdsa-with-SHA256", - (1, 2, 840, 113549, 1, 1, 11) : "sha256WithRSAEncryption", - (1, 2, 840, 113549, 1, 1, 12) : "sha384WithRSAEncryption", - (1, 2, 840, 113549, 1, 1, 13) : "sha512WithRSAEncryption", - (1, 2, 840, 113549, 1, 7, 1) : "id-data", - (1, 2, 840, 113549, 1, 9, 16) : "id-smime", - (1, 2, 840, 113549, 1, 9, 16, 1) : "id-ct", - (1, 2, 840, 113549, 1, 9, 16, 1, 24) : "id-ct-routeOriginAttestation", - (1, 2, 840, 113549, 1, 9, 16, 1, 26) : "id-ct-rpkiManifest", - (1, 2, 840, 113549, 1, 9, 16, 1, 28) : "id-ct-xml", - (1, 2, 840, 113549, 1, 9, 16, 1, 35) : "id-ct-rpkiGhostbusters", - (1, 3, 6, 1, 5, 5, 7, 1, 1) : "authorityInfoAccess", - (1, 3, 6, 1, 5, 5, 7, 1, 11) : "subjectInfoAccess", - (1, 3, 6, 1, 5, 5, 7, 1, 7) : "sbgp-ipAddrBlock", - (1, 3, 6, 1, 5, 5, 7, 1, 8) : "sbgp-autonomousSysNum", - (1, 3, 6, 1, 5, 5, 7, 14, 2) : "id-cp-ipAddr-asNumber", - (1, 3, 6, 1, 5, 5, 7, 3, 666) : "id-kp-bgpsec-router", # {id-kp, 666} -- Real value not known yet - (1, 3, 6, 1, 5, 5, 7, 48, 10) : "id-ad-rpkiManifest", - (1, 3, 6, 1, 5, 5, 7, 48, 11) : "id-ad-signedObject", - (1, 3, 6, 1, 5, 5, 7, 48, 2) : "id-ad-caIssuers", - (1, 3, 6, 1, 5, 5, 7, 48, 5) : "id-ad-caRepository", - (1, 3, 6, 1, 5, 5, 7, 48, 9) : "id-ad-signedObjectRepository", - (2, 16, 840, 1, 101, 3, 4, 2, 1) : "id-sha256", - (2, 5, 29, 14) : "subjectKeyIdentifier", - (2, 5, 29, 15) : "keyUsage", - (2, 5, 29, 19) : "basicConstraints", - (2, 5, 29, 20) : "cRLNumber", - (2, 5, 29, 31) : "cRLDistributionPoints", - (2, 5, 29, 32) : "certificatePolicies", - (2, 5, 29, 35) : "authorityKeyIdentifier", - (2, 5, 29, 37) : "extendedKeyUsage", - (2, 5, 4, 10) : "organizationName", - (2, 5, 4, 11) : "organizationalUnitName", - (2, 5, 4, 3) : "commonName", - (2, 5, 4, 5) : "serialNumber", - (2, 5, 4, 6) : "countryName", - (2, 5, 4, 7) : "localityName", - (2, 5, 4, 8) : "stateOrProvinceName", - (2, 5, 4, 9) : "streetAddress", -} - -## @var name2oid -# Mapping table of string names to OIDs -name2oid = dict((v, k) for k, v in oid2name.items()) +This used to be fairly complicated, with multiple representations and +a collection of conversion functions, but now it is very simple: -def safe_name2oid(name): - """ - Map name to OID, also parsing numeric (dotted decimal) format. - """ - - try: - return name2oid[name] - except KeyError: - fields = name.split(".") - if all(field.isdigit() for field in fields): - return tuple(int(field) for field in fields) - raise - -def safe_oid2name(oid): - """ - Map OID to name. If we have no mapping, generate numeric (dotted - decimal) format. - """ - - try: - return oid2name[oid] - except KeyError: - return oid2dotted(oid) - -def oid2dotted(oid): - """ - Convert OID to numeric (dotted decimal) format. - """ +- We represent OIDs as Python strings, holding the dotted-decimal + form of an OID. Nothing but decimal digits and "." is legal. + This is compatible with the format that rpki.POW uses. - return ".".join(str(field) for field in oid) +- We define symbols in this module whose values are OIDs. -def dotted2oid(dotted): - """ - Convert dotted decimal format to OID tuple. - """ - - fields = dotted.split(".") - if all(field.isdigit() for field in fields): - return tuple(int(field) for field in fields) - raise ValueError("%r is not a dotted decimal OID" % dotted) +That's pretty much it. There's a bit of code at the end which checks +the syntax of the defined strings and provides a pretty-print function +for the rare occasion when we need to print an OID, but other than +that this is just a collection of symbolic names for text strings. +""" -def safe_name2dotted(name): +ecdsa_with_SHA256 = "1.2.840.10045.4.3.2" +sha256WithRSAEncryption = "1.2.840.113549.1.1.11" +sha384WithRSAEncryption = "1.2.840.113549.1.1.12" +sha512WithRSAEncryption = "1.2.840.113549.1.1.13" +id_data = "1.2.840.113549.1.7.1" +id_smime = "1.2.840.113549.1.9.16" +id_ct = "1.2.840.113549.1.9.16.1" +id_ct_routeOriginAttestation = "1.2.840.113549.1.9.16.1.24" +id_ct_rpkiManifest = "1.2.840.113549.1.9.16.1.26" +id_ct_xml = "1.2.840.113549.1.9.16.1.28" +id_ct_rpkiGhostbusters = "1.2.840.113549.1.9.16.1.35" +authorityInfoAccess = "1.3.6.1.5.5.7.1.1" +subjectInfoAccess = "1.3.6.1.5.5.7.1.11" +sbgp_ipAddrBlock = "1.3.6.1.5.5.7.1.7" +sbgp_autonomousSysNum = "1.3.6.1.5.5.7.1.8" +id_cp_ipAddr_asNumber = "1.3.6.1.5.5.7.14.2" +id_kp_bgpsec_router = "1.3.6.1.5.5.7.3.666" # {id_kp, 666} -- Real value not known yet +id_ad_rpkiManifest = "1.3.6.1.5.5.7.48.10" +id_ad_signedObject = "1.3.6.1.5.5.7.48.11" +id_ad_caIssuers = "1.3.6.1.5.5.7.48.2" +id_ad_caRepository = "1.3.6.1.5.5.7.48.5" +id_ad_signedObjectRepository = "1.3.6.1.5.5.7.48.9" +id_sha256 = "2.16.840.1.101.3.4.2.1" +subjectKeyIdentifier = "2.5.29.14" +keyUsage = "2.5.29.15" +basicConstraints = "2.5.29.19" +cRLNumber = "2.5.29.20" +cRLDistributionPoints = "2.5.29.31" +certificatePolicies = "2.5.29.32" +authorityKeyIdentifier = "2.5.29.35" +extendedKeyUsage = "2.5.29.37" +organizationName = "2.5.4.10" +organizationalUnitName = "2.5.4.11" +commonName = "2.5.4.3" +serialNumber = "2.5.4.5" +countryName = "2.5.4.6" +localityName = "2.5.4.7" +stateOrProvinceName = "2.5.4.8" +streetAddress = "2.5.4.9" + +# Make sure all symbols exported so far look like OIDs, and build a +# dictionary to use when pretty-printing. + +_oid2name = {} + +for _sym in dir(): + if not _sym.startswith("_"): + _val = globals()[_sym] + if not isinstance(_val, str) or not all(_v.isdigit() for _v in _val.split(".")): + raise ValueError("Bad OID definition: %s = %r" % (_sym, _val)) + _oid2name[_val] = _sym.replace("_", "-") + +del _sym +del _val + +def oid2name(oid): """ - Convert name to dotted decimal format. + Translate an OID into a string suitable for printing. """ - return oid2dotted(safe_name2oid(name)) - -def safe_dotted2name(dotted): - """ - Convert dotted decimal to name if we know one, - otherwise just return dotted. - """ + if not isinstance(oid, (str, unicode)) or not all(o.isdigit() for o in oid.split(".")): + raise ValueError("Parameter does not look like an OID string: " + repr(oid)) - try: - return oid2name[dotted2oid(dotted)] - except KeyError: - return dotted + return _oid2name.get(oid, oid) diff --git a/rpkid/rpki/resource_set.py b/rpkid/rpki/resource_set.py index f78d37fd..2ec19cab 100644 --- a/rpkid/rpki/resource_set.py +++ b/rpkid/rpki/resource_set.py @@ -30,7 +30,6 @@ We also provide some basic set operations (union, intersection, etc). import re import math -import rpki.oids import rpki.exceptions import rpki.POW diff --git a/rpkid/rpki/rootd.py b/rpkid/rpki/rootd.py index 6723813c..49488602 100644 --- a/rpkid/rpki/rootd.py +++ b/rpkid/rpki/rootd.py @@ -37,7 +37,6 @@ import rpki.exceptions import rpki.relaxng import rpki.sundial import rpki.log -import rpki.oids import rpki.daemonize rootd = None diff --git a/rpkid/rpki/rpkic.py b/rpkid/rpki/rpkic.py index 5914dfc1..e3f57a42 100644 --- a/rpkid/rpki/rpkic.py +++ b/rpkid/rpki/rpkic.py @@ -38,7 +38,6 @@ import time import rpki.config import rpki.sundial import rpki.log -import rpki.oids import rpki.http import rpki.resource_set import rpki.relaxng diff --git a/rpkid/rpki/x509.py b/rpkid/rpki/x509.py index 8d3ea634..99350ce7 100644 --- a/rpkid/rpki/x509.py +++ b/rpkid/rpki/x509.py @@ -78,20 +78,6 @@ def first_rsync_uri(xia): return uri return None -def _find_xia_uri(extension, name): - """ - Find a rsync URI in an SIA or AIA extension. - Returns the URI if found, otherwise None. - """ - oid = rpki.oids.name2oid[name] - - # extension may be None if the AIA is not present - if extension: - for method, location in extension: - if method == oid and location[0] == "uri" and location[1].startswith("rsync://"): - return location[1] - return None - class X501DN(object): """ Class to hold an X.501 Distinguished Name. @@ -126,7 +112,7 @@ class X501DN(object): """ def __str__(self): - return "".join("/" + "+".join("%s=%s" % (rpki.oids.safe_dotted2name(a[0]), a[1]) + return "".join("/" + "+".join("%s=%s" % (rpki.oids.oid2name(a[0]), a[1]) for a in rdn) for rdn in self.dn) @@ -148,7 +134,7 @@ class X501DN(object): def from_cn(cls, s): assert isinstance(s, (str, unicode)) self = cls() - self.dn = (((rpki.oids.safe_name2dotted("commonName"), s),),) + self.dn = (((rpki.oids.commonName, s),),) return self @classmethod @@ -167,14 +153,12 @@ class X501DN(object): for rdn in self.dn: if len(rdn) == 1 and len(rdn[0]) == 2: - oid = rpki.oids.safe_dotted2name(rdn[0][0]) + oid = rdn[0][0] val = rdn[0][1] - print "OID:", oid - print "Val:", val - if oid == "commonName" and cn is None: + if oid == rpki.oids.commonName and cn is None: cn = val continue - if oid == "serialNumber" and sn is None: + if oid == rpki.oids.serialNumber and sn is None: sn = val continue raise rpki.exceptions.BadX510DN("Bad subject name: %s" % (self.dn,)) @@ -703,7 +687,7 @@ class X509(DER_object): cert.setPublicKey(subject_key.get_POW()) cert.setSKI(ski) cert.setAKI(aki) - cert.setCertificatePolicies((POWify_OID("id-cp-ipAddr-asNumber"),)) + cert.setCertificatePolicies((rpki.oids.id_cp_ipAddr_asNumber,)) if crldp is not None: cert.setCRLDP((crldp,)) @@ -861,11 +845,11 @@ class PKCS10(DER_object): ## @var allowed_extensions # Extensions allowed by RPKI profile. - allowed_extensions = frozenset(rpki.oids.safe_name2dotted(name) - for name in ("basicConstraints", - "keyUsage", - "subjectInfoAccess", - "extendedKeyUsage")) + allowed_extensions = frozenset((rpki.oids.basicConstraints, + rpki.oids.keyUsage, + rpki.oids.subjectInfoAccess, + rpki.oids.extendedKeyUsage)) + def get_DER(self): """ @@ -930,9 +914,9 @@ class PKCS10(DER_object): if ver != 0: raise rpki.exceptions.BadPKCS10("PKCS #10 request has bad version number %s" % ver) - alg = rpki.oids.safe_dotted2name(self.get_POW().getSignatureAlgorithm()) + alg = self.get_POW().getSignatureAlgorithm() - if alg != ("ecdsa-with-SHA256" if kind == "router" else "sha256WithRSAEncryption"): + if alg != (rpki.oids.ecdsa_with_SHA256 if kind == "router" else rpki.oids.sha256WithRSAEncryption): raise rpki.exceptions.BadPKCS10("PKCS #10 request has bad signature algorithm %s" % alg) bc = self.get_POW().getBasicConstraints() @@ -956,7 +940,7 @@ class PKCS10(DER_object): if kind == "ca" and eku is not None: raise rpki.exceptions.BadPKCS10("EKU not allowed in CA certificate PKCS #10") - elif kind == "router" and (eku is None or rpki.oids.name2oid["id-kp-bgpsec-router"] not in eku): + elif kind == "router" and (eku is None or rpki.oids.id_kp_bgpsec_router not in eku): raise rpki.exceptions.BadPKCS10("EKU required for router certificate PKCS #10") if any(oid not in self.allowed_extensions @@ -1182,22 +1166,13 @@ class RSApublic(DER_object): """ return self.get_POW().calculateSKI() -def POWify_OID(oid): - """ - Utility function to convert tuple form of an OID to the - dotted-decimal string form that rpki.POW uses. - """ - if isinstance(oid, str): - return POWify_OID(rpki.oids.name2oid[oid]) - else: - return ".".join(str(i) for i in oid) class CMS_object(DER_object): """ Abstract class to hold a CMS object. """ - econtent_oid = POWify_OID("id-data") + econtent_oid = rpki.oids.id_data POW_class = rpki.POW.CMS ## @var dump_on_verify_failure @@ -1542,7 +1517,7 @@ class SignedManifest(DER_CMS_object): Class to hold a signed manifest. """ - econtent_oid = POWify_OID("id-ct-rpkiManifest") + econtent_oid = rpki.oids.id_ct_rpkiManifest POW_class = rpki.POW.Manifest def getThisUpdate(self): @@ -1575,7 +1550,7 @@ class SignedManifest(DER_CMS_object): obj.setManifestNumber(serial) obj.setThisUpdate(thisUpdate) obj.setNextUpdate(nextUpdate) - obj.setAlgorithm(POWify_OID(rpki.oids.name2oid["id-sha256"])) + obj.setAlgorithm(rpki.oids.id_sha256) obj.addFiles(filelist) self = cls(POW = obj) @@ -1587,7 +1562,7 @@ class ROA(DER_CMS_object): Class to hold a signed ROA. """ - econtent_oid = POWify_OID("id-ct-routeOriginAttestation") + econtent_oid = rpki.oids.id_ct_routeOriginAttestation POW_class = rpki.POW.ROA @classmethod @@ -1664,7 +1639,7 @@ class XML_CMS_object(Wrapped_CMS_object): Class to hold CMS-wrapped XML protocol data. """ - econtent_oid = POWify_OID("id-ct-xml") + econtent_oid = rpki.oids.id_ct_xml ## @var dump_outbound_cms # If set, we write all outbound XML-CMS PDUs to disk, for debugging. @@ -1805,7 +1780,7 @@ class Ghostbuster(Wrapped_CMS_object): managed by the back-end. """ - econtent_oid = POWify_OID("id-ct-rpkiGhostbusters") + econtent_oid = rpki.oids.id_ct_rpkiGhostbusters def encode(self): """ diff --git a/rpkid/tests/testpoke.py b/rpkid/tests/testpoke.py index 00dbc300..fd5ab206 100644 --- a/rpkid/tests/testpoke.py +++ b/rpkid/tests/testpoke.py @@ -36,7 +36,6 @@ import rpki.http import rpki.config import rpki.exceptions import rpki.relaxng -import rpki.oids import rpki.log import rpki.async |