Plan 9 from Bell Labs’s /usr/web/sources/contrib/lucio/asn1/devel/oid.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
**	@(#) 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 <u.h>
#include <libc.h>
#include <ctype.h>
#include <mp.h>

#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

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.