/* ** @(#) oid.c - Manage OIDs and their "database" ** @(#) $Id: oid.c,v 1.12 2003/12/08 07:13:57 lucio Exp $ */ /* ** ================================================================== ** ** $Logfile:$ ** $RCSfile: oid.c,v $ ** $Revision: 1.12 $ ** $Date: 2003/12/08 07:13:57 $ ** $Author: lucio $ ** ** ================================================================== ** ** $Log: oid.c,v $ ** Revision 1.12 2003/12/08 07:13:57 lucio ** Weekend developments - mostly OID related ** ** Revision 1.11 2003/12/05 16:00:43 lucio ** Checkpoint - with a view to some homework. ** ** Revision 1.10 2003/12/04 16:13:30 lucio ** Checkpoint - OID rethink (incomplete) ** ** Revision 1.9 2003/12/04 11:31:42 lucio ** Streamlined - specially OID management ** ** Revision 1.8 2003/11/30 19:02:40 lucio ** Advanced - plenty to go still, of course. ** ** Revision 1.7 2003/11/27 19:17:57 lucio ** Checkpoint - DNs almost complete ** ** Revision 1.6 2003/11/27 18:37:53 lucio ** Checkpoint - some progress with DNs ** ** Revision 1.5 2003/11/27 12:04:56 lucio ** Brought oid_append() into line with oid_build() ** ** Revision 1.4 2003/11/27 11:37:00 lucio ** Checkpoint - OID database management ** ** Revision 1.3 2003/11/26 16:34:33 lucio ** Checkpoint - unworkable ** ** Revision 1.2 2003/11/26 06:08:39 lucio ** Partial DN printing development ** ** Revision 1.1 2003/11/25 17:01:37 lucio ** OID management ** ** ================================================================== */ /* TODO: - Make sure that creation of an OID entry returns its index so that its location can be recorded if so desired. - Allow for recording an OID's ASN.1 (BER?) representation so it can be used in comparisons, unless a better approach comes to mind (like looking up the name and checking that, or even passing the name to a function with the OID and seeing that it matches, preferably by the appropriate syntax rules, in the long run. - Develop the necessary infrastructure to allow insertions and lookups of the database, together with any useful access features. */ #include #include #include #include #include "ber.h" #include "oid.h" static void debug (char *fmt, ...) { va_list arg; va_start (arg, fmt); vfprint (2, fmt, arg); va_end(arg); } /* Definitions for the structures below are to be found in the oid.h header file. These ought to become part of a file service specification that facilitates use of the algorithms and/or procedures for data manipulation. It is not yet clear how best to build such a file service, as no complete target application occurs yet. Eventually, however, mail certification as well as the distribution of identity certificates will probably become the core clients to the service. In the meantime we'll use conventional data structures to coordinate the identifiers of algorithms and their actual utilisation in our operations. The structures provide for the OID as a printable string - mostly for human consumption, its BER representation together with a (hopefully redundant) length and a function, whose interface is still undefined, but which will presumably include a pointer to the ASN.1 object to which the function must be applied and some consistent return type and value. Unlike as suggested by the code under development, we will not build the OID database from these structures, the database itself contains information that is only occasionally required and we do not want to be burdened with it all the time. In particular, we do not want to initialise these details every time our utilities are activated, hence the desire to relegate the database to a permanently active file service. The structures below, on the other hand, define the range of valid algorithms we are able to use. Once they have been initialised from the database with the missing details (BER representation of the OID, which is hopefully more readily and specifically more reliably looked up than computed (the assumption here is that there ought to be only one location where the OID is manipulated), they remain as lookup tables for further computation. The initialisation code, therefore, will change from setting up the database to merely looking up each entry in the database and filling in the missing fields. As an interim measure, we'll have the present database build function return the location of the OID object so that we can retrieve the BER value from it. It is tempting to include object attribute values in a similar fashion, but in fact this should not be necessary. The initial intent of the OID database was to be able to obtain easily the name of attributes for the purpose of expanding distinguished names and this facility is still a primary function, at best extending this back into our utility will make it possible to restrict the range of attributes we are willing to accept, but this seems to reduce our options rather than extend the usefulness of our tools. */ static OidAlg algoid[] = { // algorithms [OID_RSAENCRYPTION] { "1.2.840.113549.1.1.1", nil, 0, nil, }, [OID_MD2RSAENCRYPTION] { "1.2.840.113549.1.1.2", nil, 0, nil, }, [OID_MD4RSAENCRYPTION] { "1.2.840.113549.1.1.3", nil, 0, nil, }, [OID_MD5RSAENCRYPTION] { "1.2.840.113549.1.1.4", nil, 0, nil, }, [OID_SHA1RSAENCRYPTION] { "1.2.840.113549.1.1.5", nil, 0, nil, }, [OID_MD2] { "1.2.840.113549.2.2", nil, 0, nil, }, [OID_MD4] { "1.2.840.113549.2.4", nil, 0, nil, }, [OID_MD5] { "1.2.840.113549.2.5", nil, 0, nil, }, [OID_RSA] { "2.5.8.1.1", nil, 0, nil, }, { -1, nil, 0, nil, }, }; static OidCrypt cryptoid[] = { // S/MIME message type [OID_MSGDATA] {"1.2.840.113549.1.7.1", nil, 0, nil, }, [OID_MSGSIGNEDDATA] {"1.2.840.113549.1.7.2", nil, 0, nil, }, [OID_MSGENVELOPEDDATA] {"1.2.840.113549.1.7.3", nil, 0, nil, }, [OID_MSGSIGNEDANDENVELOPEDDATA] {"1.2.840.113549.1.7.4", nil, 0, nil, }, [OID_MSGDIGESTEDDATA] {"1.2.840.113549.1.7.5", nil, 0, nil, }, [OID_MSGENCRYPTEDDATA] {"1.2.840.113549.1.7.6", nil, 0, nil, }, { -1, nil, 0, nil, }, }; static void oid_display (char *s, OidHier *h) { char qd[OIDMAX]; char qn[OIDMAX]; int ld, ln; ld = snprint (qd, sizeof (qd), "D %s ", s); ln = snprint (qn, sizeof (qn), "N %s ", s); if (h) { snprint (qn + ln, sizeof (qn) - ln, "%lld", h->roid); oid_display (qn, h->next); snprint (qd + ld, sizeof (qd) - ld, "%lld", h->roid); oid_display (qd, h->down); print ("%s .%lld", s, h->roid); if (h->name) print (" %s %s", h->name, h->descr); print ("\n"); } } static void oid_print (char *s, int n, int l, OidHier *h) { int l0; if (h) { print ("%.*s.%lld", l, s, h->roid); if (h->name) print (" %s %s", h->name, h->descr); else print (" *** unknown OID ***"); print ("\n"); l0 = snprint (s + l, n - l, ".%lld", h->roid); oid_print (s, n, l + l0, h->down); oid_print (s, n, l, h->next); } } void oid_hdump (OidHier *h) { char s[OIDMAX]; int l; for (; h; h = h->next) { l = snprint (s, sizeof (s), "%lld", h->roid); print (s); if (h->name) print (" %s %s", h->name, h->descr); else print (" *** unknown OID ***"); print ("\n"); oid_print (s, sizeof (s), l, h->down); } } /* These utilities are utterly crazy. Create() is used when a new entry is to be added to the database because no corresponding OID was found. It creates an ASN.1 object merely for the benefit of its representation. In most cases, the effort is duplicated at a higher level, so we need to be aware of this and avoid it. Locate() is a misnomer: it may be instructed to add the OID to the database if it does not find it, which is acceptable in that we don't want to rescan the database hierarchy to find where to add an entry when we already had the information at hand. Here we need to be able to determine whether we already have the BER representation of the OID or not before we call create() to make one up. A simple "nil" argument may suffice, but perhaps more is required. Append() has recently been updated to use the BER object instead of the string ID to identify the desired entry. In this case there is no doubt as to the availability of a BER representation and this information must be propagated further. Build() performs a more rational, but still redundant version of append()'s operation. Here we presently wait for the object to be added to the database, then we (unnecessarily) produce the BER representation for the OID in it. This last is presumably the simplest problem to address: we just discard the superfluous code (done). One seemingly sensible approach will be to pass a pointer to the ASN.1 object as an argument to create(). If "nil", create() will need to manufacture its own object, if not, it may use (and otherwise leave untouched) the existing one. However, part of the purpose of create() was to accept a string representation of the OID, which is used exclusively to create the ASN.1 object. As a result, we may as well replace the ID string with the ASN.1 object and leave it to the caller to manufacture the object before calling create(). This may well bring append() and build() much closer together. In fact, we create a difficulty, but it must be surmountable: locate() was originally intended to walk the hierarchy one level at the time, creating nodes as the need arose (we assume in our existing use that missing nodes will have to be created, which is not unreasonable - a different search approach will terminate as soon as a node is not located), which is easier to do if one does not have to create a new object in advance. This suggests that object creation ought to be in locate(), not append() or build(), leaving the API unchanged from the previous implementation. The disadvantage is that now we create an unnecessary object when locate() is called by append() which already has an object. On the other hand, it is only for the very last entry in the search that this condition applies, which is a common but still special case. Providing a locate() that accepts an object instead of an ID for this will make append() more complex rather than simpler, an instance of premature optimisation. If performance is then found to be lacking, it may make sense to deal with this problem. On the other hand, it seems that locate() itself may benefit from some (later) optimisation, avoiding the creation of an entire object when only the BER representation is required. This is left for a future revision. Note that ber_packobjid(), a private entry in the BER module could be used to generate a BER representation of the given value, but it is essential to highlight that we only deal with a value segment (the "relative" OID - we hope that 64 bits will suffice for this purpose) and that in the BER module we may stupidly assume that the full "decoded" value is only 64 bits wide. Somehow, this does not ring true, it will need investigating, after all some of the values we use presently seem larger than 64 bits and the entire approach does not lend itself to such stupidity. */ static OidHier * oid_create (BerObj *o, long long v) { OidHier *h0; if (!(h0 = malloc (sizeof (OidHier)))) { debug ("oid_create entry: %r\n"); return 0; } if (!(h0->oid = malloc (h0->len = o->len))) { debug ("oid_create BER: %r\n"); return 0; } memcpy (h0->oid, o->buf, o->len); h0->roid = v; h0->name = nil; h0->descr = nil; h0->alias = nil; h0->next = h0->down = nil; return h0; } /* Locate will attempt to find the given OID in the database, looking for "v" at the hierarchy level specified by the "h" parameter. If requested (create != 0), a missing entry will be generated with the object ID string specified in "id". The combination of Append and Locate is a little confused, it should be re-examined before being put into production. Locate will return the position (in the database) of the located or newly created entry. As Locate does not have complete specifications for the entry, the description fields are set to nil. It seems to me that some of the comments above are obsolete. Definitely, it is important to emphasise that Locate will start a hierarchy if none is given. That, perhaps surprisingly, turns out to be a simple task. What I find hard to remember, is the role played by "v" in the operation. In fact, the idea was to split the OID as a prefix (ID) and a relative value (roid) and search for the prefix, then determine with the help of "v" whether to return an existing value or the location for a new one. */ static OidHier * oid_locate (OidHier **h, char *id, long long v, int create) { OidHier *h0, *h9 = nil, *hh = *h; BerObj *o = nil; if (create) { if ((o = ber_objid (id)) == nil) { fprint (2, "oid_locate objid %s: \r", id); exits ("locate objid"); } } if (*h) { h0 = nil; while (hh && hh->roid < v) { h0 = hh; hh = hh->next; } if (hh) { if (hh->roid == v) { return hh; } if (create && (h9 = oid_create (o, v))) { h9->next = hh; if (h0) { h0->next = h9; } else { *h = h9; } } } else if (create && (h9 = oid_create (o, v))) { if (h0) { h9->next = h0->next; h0->next = h9; } else { h9->next = *h; *h = h9; } } } else { if (create) { *h = oid_create (o, v); ber_free (o); } return *h; } if (create) { ber_free (o); } return h9; } /* Append attaches or updates an OID entry in the database. As implemented here, append decomposes the OID (BER) object to construct a string ID which is then used to scan the database. */ OidHier * oid_append (OidHier *h, BerObj *oid, char *name, char *descr, ...) { OidHier *h0; long long v, v0; int l; uchar *p, *pe; char *s; char id[OIDMAX]; va_list alias; p = oid->buf; pe = p + oid->len; v = *p++ & 0x7F; v0 = v / 40; l = snprint (id, sizeof (id), "%lld", v0); // start search here (at v0) if ((h0 = oid_locate (&h, id, v0, 1)) == nil) { debug ("oid_append locate root %s: %r\n", id); return 0; } v = v % 40; l += snprint (id + l, sizeof (id) - l, ".%lld", v); if ((h0 = oid_locate (&(h0->down), id, v, 1)) == nil) { debug ("oid_append locate branch %s: %r\n", id); return 0; } v = 0; while (p < pe) { v = (v << 7) | (*p & 0x7F); if (!(*p++ & 0x80)) { l += snprint (id + l, sizeof (id) - l, ".%lld", v); if ((h0 = oid_locate (&(h0->down), id, v, 1)) == nil) { debug ("oid_append locate branch %s: %r\n", id); return 0; } v = 0; } } memcpy (h0->oid, oid->buf, h0->len = oid->len); if (!h0->name) { h0->name = name; h0->descr = descr; va_start (alias, descr); h0->alias = nil; for (l = 0; s = va_arg (alias, char *); l++) { h0->alias = realloc (h0->alias, (l + 2) * sizeof (char *)); h0->alias[l] = s; h0->alias[l + 1] = nil; } va_end (alias); } return h; } /* Let me try to make some sense of the reasons why I find this module so difficult to implement. There are a few conflicting requirements whose resolution may need careful compromising, not least of which is the need to be able to add missing nodes to the hierarchy (database) while at the same time retaining the location of the most recently identified node. Let's call the critical node "hx", that is, let "hx" be the return value from each node identification call. If "hx" is not empty, it points to the current node, which is also implicitly the start of the next descent. Our primary problem is that occasionally (frequently when we start accumulating entries, less frequently as the database starts getting populated) we need more detail returned by the allocation procedure than merely a pointer to the node, we also need to know where to add it when the predecessor node is not available within the allocation procedure. Let's try to explain this more clearly: lack of clarity has been dogging me for days. Within build(), we descend the hierarchy exclusively. In other words, as we decompose the OID - irrespective of technique employed - we trace a path through the database that consists of moving down to a new level on each element. When allocating each element, on the other hand, we will cross the hierarchy horizontally, given the start node, we'll need to examine its siblings to determine where it belongs. Our biggest problem arises in both instances when the predecessor to the given node is empty as we are faced by a dilemma: whether to return the (al)located node or the details of where it ought to be inserted. Note that this is a common occurrence, but not the norm. To achieve the desired objective requires some additional information to be returned with the (al)located node, information that, at least in the descent p[rocedure may not even be available. Let's consider then this particular detail. Within build() (once again) our vertical scan is always no more than a step down from our most recent operation: we pass to locate() our present position in the hierarchy - which may be empty, a problem we need to address, in fact that situation does not seem reasonable at all, when inspected more closely, after all we _know_ that we need to attach a node to _something_ - and within locate() we search horizontally for the position of the given element. Again, our problem is that prefixing an element to the existing list is impossible if we do have access to the predecessor node. In turn, the predecessor node would be _higher_ in the hierarchy, which is where our earlier efforts chose to start the descent: our first step was to move downwards, then across. This, of course, collapses miserably at the very beginning of the operation, when there is no node available at all. Let's then return to what information is available. Should we _know_ in advance that our starting position is empty, we can claim without fear of contradition that the new node will occupy that position: if (!h) h = h0 = oid_locate (nil, v, 1); else h0 = oid_locate (h, v, 1); which of course resolves to: h0 = oid_locate (nil, v, 1); if (!h) h = h0; as we have already implemented this. If we now freeze "h", it will serve adequately as the new start of hierarchy. We only need to do this at the top level and only once, so it is pretty trivial. What is considerably less trivial is what is demanded when a new node is allocated that needs to be prefixed to a non-empty hierarchy. This is very much what I have been unable to resolve so far. Let's explore some possibilities. hx = oid_locate (h0, v, 1); will use "h0" as the location from which to start a horizontal search, but will fail to attach the new nodes ahead of "h0" when its properties require it. We happen to know that hx->roid < h0.roid in this situation, but it is not even a given that we have the predecessor of "h0" whose "h?->down" should be replaced with "hx". I suppose that determines very clearly one minimum requirement, that a predecessor to "h0" has to be available on return from append(). In addition, it should be left to locate() to specify where "hx" should be added, another special case that needs to be allowed for everywhere and be distinct from insertion at the top of the hierarchy, but not as clearly as it may seem, after all, we may also need to deal with this situation at the very beginning - consider OID "1" being created _after_ OID "2" - the code above does not deal properly with it. h0 = oid_locate (h, v, 1); if (!h) h = h0; else if (h->roid > h0->roid) h = h0; where the (h-roid > h0->roid) comparison is extremely poor technique (what happens if the criterion changes, and why is this comparison duplicating something already done within locate()?). This still points to the need for an indication in locate() not only of the pointer to the new entry, but also of some special treatment being required for its insertion in the hierarchy. Often, my thinking veered towards the creation of a node to be used as the argument to locate() if the hierarchy is empty, but this does not seem to address our more complex problem of a missing predecessor: hh = malloc (sizeof (OidHier)); hh->down = h; h0 = oid_locate (hh, v, 1); h = hh->down; which really ought to be expressed, with suitable changes to locate(), as the following: h0 = oid_locate (&h, v, 1); with locate() now being responsible for ensuring that insertion at the top of the hierarchy is dealt with correctly. This seems to be the correct way to deal with the problem. */ static OidHier * oid_build (OidHier *h, char *id, char *name, char *descr, ...) { OidHier *h0; long long v; char dot, *p; va_list alias; int l; v = strtoll (id, &p, 10); dot = *p; *p = '\0'; if ((h0 = oid_locate (&h, id, v, 1)) == nil) { debug ("oid_build locate root %s: %r\n", id); return 0; } while (dot == '.') { *p++ = dot; v = strtoll (p, &p, 10); dot = *p; *p = '\0'; if ((h0 = oid_locate (&(h0->down), id, v, 1)) == nil) { debug ("oid_build locate root %s: %r\n", id); return 0; } *p = dot; } h0->name = name; h0->descr = descr; va_start (alias, descr); h0->alias = nil; for (l = 0; p = va_arg (alias, char *); l++) { h0->alias = realloc (h0->alias, (l + 2) * sizeof (char *)); h0->alias[l] = p; h0->alias[l + 1] = nil; } va_end (alias); return h; } OidHier * oid_ident (OidHier *h, char *id) { OidHier *h0; long long v; char dot, *p; v = strtoll (id, &p, 10); dot = *p; *p = '\0'; if ((h0 = oid_locate (&h, id, v, 0)) == nil) { debug ("oid_ident locate root %s: %r\n", id); return 0; } while (dot == '.') { *p++ = dot; v = strtoll (p, &p, 10); dot = *p; *p = '\0'; if ((h0 = oid_locate (&(h0->down), id, v, 0)) == nil) { debug ("oid_ident locate root %s: %r\n", id); return 0; } *p = dot; } return h0; } /* ** Format a distinguished name (DN) as best as possible */ /* The normal format produces an X.500 result (most significant component first, with slash separators); the hash flag indicates that LDAP is wanted: least significant component first, comma separated. Quoting as soon as we can confirm the desired approach (I do know what LDAP wants, but I haven't figured out how to reverse the result yet, so that will keep too. */ int oid_fmtdn (Fmt *f) { char q[OIDMAX], s[OIDMAX]; BerObj *opd, *op1, *op2; int l = 0; OidHier *oid; OidObj *o; if ((o = va_arg (f->args, OidObj *)) == nil) return -1; if ((opd = o->obj) == nil) { fprint (2, "Unrecognisable as DN\n"); return -1; } while (opd && opd->tag == BER_TAG_SETOF) { op1 = opd->down->down; if (op1->tag != BER_TAG_OBJECTID) { fprint (2, "Unrecognised component in distinguished name (%d): %O\n", op1->tag, op1); return -1; } op2 = op1->next; if (op2->tag != BER_TAG_PRINTABLESTRING) { fprint (2, "Unrecognised component in distinguished name (%d): %O\n", op2->tag, op2); return -1; } snprint (s, sizeof (s), "%O", op1); if (!(oid = oid_ident (o->hier, s))) { fprint (2, "Unregistered OID: %s\n", s); return -1; } // print ("LEN: %d - SIZE: %d - BUF: %*.*s\n", op2->len, op2->size, op2->size, op2->buf); l += snprint (q + l, sizeof (q) - l, "/%s=%.*s", oid->name, op2->size, (char *) op2->buf); opd = opd->next; } return fmtprint (f, q); } OidHier * oid_initdb (OidHier *h) { h = oid_build (h, "0", "itu-t", "ITU-T", nil); h = oid_build (h, "0.9.2342.19200300.100.1.3", "mail", "RFC 1274: RFC822 mailbox", "rfc822Mailbox", nil); h = oid_build (h, "0.9.2342.19200300.100.1.25", "domainComponent", "RFC 2247: Domain Component", nil); h = oid_build (h, "1", "iso", "iso", nil); h = oid_build (h, "1.2", "member-body", "iso.member-body", nil); h = oid_build (h, "1.2.840", "US", "iso.member-body.US", nil); h = oid_build (h, "1.2.840.10040", "x9-57", "iso.member-body.US.x9-57", nil); h = oid_build (h, "1.2.840.10040.4", "x9cm", "iso.member-body.US.x9-57.x9cm", nil); h = oid_build (h, "1.2.840.10040.4.1", "dsa", "iso.member-body.US.x9-57.x9cm.dsa", nil); h = oid_build (h, "1.2.840.10040.4.3", "dsa-with-sha1", "iso.member-body.US.x9-57.x9cm.dsa-with-sha1", nil); h = oid_build (h, "1.2.840.10045", "x9-62", "iso.member-body.US.x9-62", nil); h = oid_build (h, "1.2.840.10045.4", "signatures", "iso.member-body.US.x9-62.signatures", nil); h = oid_build (h, "1.2.840.10045.4.1", "ecdsa-with-sha1", "iso.member-body.US.x9-62.signatures.ecdsa-with-sha1", nil); h = oid_build (h, "1.2.840.10046", "x9-42", "iso.member-body.US.x9-42", nil); h = oid_build (h, "1.2.840.10046.2", "number-type", "iso.member-body.US.x9-42.number-type", nil); h = oid_build (h, "1.2.840.10046.2.1", "dhpublicnumber", "iso.member-body.US.x9-42.number-type.dhpublicnumber", nil); h = oid_build (h, "1.2.840.113549", "rsadsi", "iso.member-body.US.rsadsi", nil); h = oid_build (h, "1.2.840.113549.1", "pkcs", "iso.member-body.US.rsadsi.pkcs", nil); h = oid_build (h, "1.2.840.113549.1.1", "pkcs-1", "iso.member-body.US.rsadsi.pkcs.pkcs-1", nil); h = oid_build (h, algoid[OID_RSAENCRYPTION].str, "rsaEncryption", "iso.member-body.US.rsadsi.pkcs.pkcs-1.rsaEncryption", nil); h = oid_build (h, algoid[OID_MD2RSAENCRYPTION].str, "md2WithRSAEncryption", "iso.member-body.US.rsadsi.pkcs.pkcs-1.md2WithRSAEncryption", nil); h = oid_build (h, algoid[OID_MD4RSAENCRYPTION].str, "md4WithRSAEncryption", "iso.member-body.US.rsadsi.pkcs.pkcs-1.md4WithRSAEncryption", nil); h = oid_build (h, algoid[OID_MD5RSAENCRYPTION].str, "md5WithRSAEncryption", "iso.member-body.US.rsadsi.pkcs.pkcs-1.md5WithRSAEncryption", nil); h = oid_build (h, algoid[OID_SHA1RSAENCRYPTION].str, "sha-1WithRSAEncryption", "iso.member-body.US.rsadsi.pkcs.pkcs-1.sha-1WithRSAEncryption", nil); h = oid_build (h, "1.2.840.113549.1.7", "pkcs-7", "iso.member-body.US.rsadsi.pkcs.pkcs-7", nil); h = oid_build (h, cryptoid[OID_MSGDATA].str, "data", "iso.member-body.US.rsadsi.pkcs.pkcs-7.data", nil); h = oid_build (h, cryptoid[OID_MSGSIGNEDDATA].str, "signedData", "iso.member-body.US.rsadsi.pkcs.pkcs-7.signedData", nil); h = oid_build (h, cryptoid[OID_MSGENVELOPEDDATA].str, "envelopedData", "iso.member-body.US.rsadsi.pkcs.pkcs-7.envelopedData", nil); h = oid_build (h, cryptoid[OID_MSGSIGNEDANDENVELOPEDDATA].str, "signedAndEnvelopedData", "iso.member-body.US.rsadsi.pkcs.pkcs-7.signedAndEnvelopedData", nil); h = oid_build (h, cryptoid[OID_MSGDIGESTEDDATA].str, "digestedData", "iso.member-body.US.rsadsi.pkcs.pkcs-7.digestedData", nil); h = oid_build (h, cryptoid[OID_MSGENCRYPTEDDATA].str, "encryptedData", "iso.member-body.US.rsadsi.pkcs.pkcs-7.encryptedData", nil); h = oid_build (h, "1.2.840.113549.1.9", "pkcs-9", "iso.member-body.US.rsadsi.pkcs.pkcs-9", nil); h = oid_build (h, "1.2.840.113549.1.9.1", "emailAddress", "iso.member-body.US.rsadsi.pkcs.pkcs-9.emailAddress", nil); h = oid_build (h, "1.2.840.113549.2", "digestAlgorithm", "iso.member-body.US.rsadsi.digestAlgorithm", nil); h = oid_build (h, algoid[OID_MD2].str, "md2", "iso.member-body.US.rsadsi.digestAlgorithm.md2", nil); h = oid_build (h, algoid[OID_MD5].str, "md5", "iso.member-body.US.rsadsi.digestAlgorithm.md5", nil); h = oid_build (h, "1.3", "identified-organization", "iso.identified-organization", nil); h = oid_build (h, "1.3.6", "dod", "iso.identified-organization.dod", nil); h = oid_build (h, "1.3.6.1", "internet", "iso.identified-organization.dod.internet", nil); h = oid_build (h, "1.3.6.1.5", "security", "iso.identified-organization.dod.internet.security", nil); h = oid_build (h, "1.3.6.1.5.5", "mechanisms", "iso.identified-organization.dod.internet.security.mechanisms", nil); h = oid_build (h, "1.3.6.1.5.5.7", "pkix", "iso.identified-organization.dod.internet.security.mechanisms.pkix", nil); h = oid_build (h, "1.3.6.1.5.5.7.1", "private-extensions", "iso.identified-organization.dod.internet.security.mechanisms.pkix.private-extensions", "id-pe", nil); h = oid_build (h, "1.3.6.1.5.5.7.1.1", "authorityInfoAccess", "iso.identified-organization.dod.internet.security.mechanisms.pkix.private-extensions.authorityInfoAccess", "id-pe-authorityInfoAccess", nil); h = oid_build (h, "1.3.6.1.5.5.7.1.11", "subjectInfoAccess", "iso.identified-organization.dod.internet.security.mechanisms.pkix.private-extensions.subjectInfoAccess", "id-pe-authorityInfoAccess", nil); h = oid_build (h, "1.3.6.1.5.5.7.2", "policy-qualifier-types", "iso.identified-organization.dod.internet.security.mechanisms.pkix.policy-qualifier-types", "id-qt", nil); h = oid_build (h, "1.3.6.1.5.5.7.3", "extended-key-OIDs", "iso.identified-organization.dod.internet.security.mechanisms.pkix.extended-key-OIDs", "id-kp", nil); h = oid_build (h, "1.3.6.1.5.5.7.48", "access-descriptors", "iso.identified-organization.dod.internet.security.mechanisms.pkix.access-descriptors", "id-ad", nil); h = oid_build (h, "1.3.6.1.5.5.7.48.1", "ocsp", "iso.identified-organization.dod.internet.security.mechanisms.pkix.access-descriptors.ocsp", "id-ad-ocsp", nil); h = oid_build (h, "1.3.6.1.5.5.7.48.2", "caIssuers", "iso.identified-organization.dod.internet.security.mechanisms.pkix.access-descriptors.caIssuers", "id-ad-caIssuers", nil); h = oid_build (h, "1.3.6.1.5.5.7.48.3", "timeStamping", "iso.identified-organization.dod.internet.security.mechanisms.pkix.access-descriptors.timeStamping", "id-ad-timeStamping", nil); h = oid_build (h, "1.3.6.1.5.5.7.48.5", "caRepository", "iso.identified-organization.dod.internet.security.mechanisms.pkix.access-descriptors.caRepository", "id-ad-caRepository", nil); h = oid_build (h, "1.3.14", "oiw", "iso.identified-organization.oiw", nil); h = oid_build (h, "1.3.14.3", "secsig", "iso.identified-organization.oiw.secsig", nil); h = oid_build (h, "1.3.14.3.2", "algorithm", "iso.identified-organization.oiw.secsig.algorithm", nil); h = oid_build (h, "1.3.14.3.2.26", "sha-1", "iso.identified-organization.oiw.secsig.algorithm.sha-1", nil); h = oid_build (h, "2", "joint-iso-itu-t", "Joint ISO-ITU-T", nil); h = oid_build (h, "2.5", "ds", "joint-iso-itu-t.ds", nil); h = oid_build (h, "2.5.4", "attribute", "joint-iso-itu-t.ds.attribute", "id-at", nil); h = oid_build (h, "2.5.4.3", "cn", "Common name", "commonName", nil); h = oid_build (h, "2.5.4.4", "sn", "Surname", "surname", nil); h = oid_build (h, "2.5.4.5", "serialNumber", "Serial number", nil); h = oid_build (h, "2.5.4.6", "c", "Country", "countryName", nil); h = oid_build (h, "2.5.4.7", "l", "Locality", "localityName", nil); h = oid_build (h, "2.5.4.8", "st", "State or province name", "stateOrProvinceName", nil); h = oid_build (h, "2.5.4.9", "street", "Street address", "streetAddress", nil); h = oid_build (h, "2.5.4.10", "o", "Organization", "organizationName", nil); h = oid_build (h, "2.5.4.11", "ou", "Organizational unit", "organizationalUnitName", nil); h = oid_build (h, "2.5.4.12", "title", "Title", nil); h = oid_build (h, "2.5.4.35", "userPassword", "id-at-userPassword", nil); h = oid_build (h, "2.5.4.36", "userCertificate", "id-at-userCertificate", nil); h = oid_build (h, "2.5.4.37", "CACertificate", "id-at-CACertificate", nil); h = oid_build (h, "2.5.4.38", "authorityRevocationList", "id-at-authorityRevocationList", nil); h = oid_build (h, "2.5.4.39", "certificateRevocationList", "id-at-certificateRevocationList", nil); h = oid_build (h, "2.5.4.40", "crossCertificatePair", "id-at-crossCertificatePair", nil); h = oid_build (h, "2.5.4.41", "name", "id-at-name", nil); h = oid_build (h, "2.5.4.42", "givenName", "id-at-givenName", nil); h = oid_build (h, "2.5.4.43", "initials", "id-at-initials", nil); h = oid_build (h, "2.5.4.44", "generationQualifier", "id-at-generationQualifier", nil); h = oid_build (h, "2.5.4.46", "dnQualifier", "id-at-dnQualifier", nil); h = oid_build (h, "2.5.4.65", "pseudonym", "id-at-pseudonym", nil); h = oid_build (h, "2.5.8", "algorithm", "joint-iso-itu-t.ds.algorithm", nil); h = oid_build (h, "2.5.8.1", "encryptionAlgorithm", "joint-iso-itu-t.ds.algorithm.encryptionAlgorithm", nil); h = oid_build (h, algoid[OID_RSA].str, "rsa", "joint-iso-ccitt.ds.algorithm.encryptionAlgorithm.rsa", nil); h = oid_build (h, "2.5.29", "standard-certificate", "joint-iso-itu-t.ds.standard-certificate", nil); h = oid_build (h, "2.5.29.9", "subjectDirectoryAttribute", "joint-iso-itu-t.ds.standard-certificate.subjectDirectoryAttribute", nil); h = oid_build (h, "2.5.29.14", "subjectKeyIdentifier", "joint-iso-itu-t.ds.standard-certificate.subjectKeyIdentifier", nil); h = oid_build (h, "2.5.29.15", "keyUsage", "joint-iso-itu-t.ds.standard-certificate.keyUsage", nil); h = oid_build (h, "2.5.29.16", "privateKeyUsagePeriod", "joint-iso-itu-t.ds.standard-certificate.privateKeyUsagePeriod", nil); h = oid_build (h, "2.5.29.17", "subjectAltName", "joint-iso-itu-t.ds.standard-certificate.subjectAltName", nil); h = oid_build (h, "2.5.29.18", "issuerAltName", "joint-iso-itu-t.ds.standard-certificate.issuerAltName", nil); h = oid_build (h, "2.5.29.19", "basicConstraints", "joint-iso-itu-t.ds.standard-certificate.basicConstraints", nil); h = oid_build (h, "2.5.29.20", "cRLNumber", "joint-iso-itu-t.ds.standard-certificate.cRLNumber", nil); h = oid_build (h, "2.5.29.21", "cRLReason", "joint-iso-itu-t.ds.standard-certificate.cRLReason", nil); h = oid_build (h, "2.5.29.23", "holdInstructionCode", "joint-iso-itu-t.ds.standard-certificate.holdInstructionCode", nil); h = oid_build (h, "2.5.29.24", "invalidityDate", "joint-iso-itu-t.ds.standard-certificate.invalidityDate", nil); h = oid_build (h, "2.5.29.27", "deltaCRLIndicator", "joint-iso-itu-t.ds.standard-certificate.deltaCRLIndicator", nil); h = oid_build (h, "2.5.29.28", "issuingDistributionPoint", "joint-iso-itu-t.ds.standard-certificate.issuingDistributionPoint", nil); h = oid_build (h, "2.5.29.29", "certificateIssuer", "joint-iso-itu-t.ds.standard-certificate.certificateIssuer", nil); h = oid_build (h, "2.5.29.30", "nameConstraints", "joint-iso-itu-t.ds.standard-certificate.nameConstraints", nil); h = oid_build (h, "2.5.29.31", "cRLDistributionPoints", "joint-iso-itu-t.ds.standard-certificate.cRLDistributionPoints", nil); h = oid_build (h, "2.5.29.32", "certificatePolicies", "joint-iso-itu-t.ds.standard-certificate.certificatePolicies", nil); h = oid_build (h, "2.5.29.33", "policyMappings", "joint-iso-itu-t.ds.standard-certificate.policyMappings", nil); h = oid_build (h, "2.5.29.35", "authorityKeyIdentifier", "joint-iso-itu-t.ds.standard-certificate.authorityKeyIdentifier", nil); h = oid_build (h, "2.5.29.36", "policyConstraints", "joint-iso-itu-t.ds.standard-certificate.policyConstraints", nil); h = oid_build (h, "2.5.29.37", "extKeyUsage", "joint-iso-itu-t.ds.standard-certificate.extKeyUsage", nil); h = oid_build (h, "2.5.29.46", "freshestCRL", "joint-iso-itu-t.ds.standard-certificate.freshestCRL", nil); h = oid_build (h, "2.5.29.54", "inhibitAnyPolicy", "joint-iso-itu-t.ds.standard-certificate.inhibitAnyPolicy", nil); return h; } #undef TEST #ifdef TEST static OidHier *hierarchy; main (int argc, char *argv) { hierarchy = oid_initdb (nil); oid_display ("main", hierarchy); fmtinstall ("D", oid_fmtdn); } #endif