/*
** @(#) 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
|