Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 334298
b: refs/heads/master
c: a77ad6e
h: refs/heads/master
v: v3
  • Loading branch information
David Howells authored and Rusty Russell committed Oct 8, 2012
1 parent d4842e4 commit 03e1103
Show file tree
Hide file tree
Showing 7 changed files with 411 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0b1568a4536ff287a87908d7fc35c05bd7736a53
refs/heads/master: a77ad6ea0b0bb1f9d1f52ed494bd72a5fdde208e
90 changes: 90 additions & 0 deletions trunk/include/linux/oid_registry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* ASN.1 Object identifier (OID) registry
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/

#ifndef _LINUX_OID_REGISTRY_H
#define _LINUX_OID_REGISTRY_H

#include <linux/types.h>

/*
* OIDs are turned into these values if possible, or OID__NR if not held here.
*
* NOTE! Do not mess with the format of each line as this is read by
* build_OID_registry.pl to generate the data for look_up_OID().
*/
enum OID {
OID_id_dsa_with_sha1, /* 1.2.840.10030.4.3 */
OID_id_dsa, /* 1.2.840.10040.4.1 */
OID_id_ecdsa_with_sha1, /* 1.2.840.10045.4.1 */
OID_id_ecPublicKey, /* 1.2.840.10045.2.1 */

/* PKCS#1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)} */
OID_rsaEncryption, /* 1.2.840.113549.1.1.1 */
OID_md2WithRSAEncryption, /* 1.2.840.113549.1.1.2 */
OID_md3WithRSAEncryption, /* 1.2.840.113549.1.1.3 */
OID_md4WithRSAEncryption, /* 1.2.840.113549.1.1.4 */
OID_sha1WithRSAEncryption, /* 1.2.840.113549.1.1.5 */
OID_sha256WithRSAEncryption, /* 1.2.840.113549.1.1.11 */
OID_sha384WithRSAEncryption, /* 1.2.840.113549.1.1.12 */
OID_sha512WithRSAEncryption, /* 1.2.840.113549.1.1.13 */
OID_sha224WithRSAEncryption, /* 1.2.840.113549.1.1.14 */
/* PKCS#7 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)} */
OID_data, /* 1.2.840.113549.1.7.1 */
OID_signed_data, /* 1.2.840.113549.1.7.2 */
/* PKCS#9 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)} */
OID_email_address, /* 1.2.840.113549.1.9.1 */
OID_content_type, /* 1.2.840.113549.1.9.3 */
OID_messageDigest, /* 1.2.840.113549.1.9.4 */
OID_signingTime, /* 1.2.840.113549.1.9.5 */
OID_smimeCapabilites, /* 1.2.840.113549.1.9.15 */
OID_smimeAuthenticatedAttrs, /* 1.2.840.113549.1.9.16.2.11 */

/* {iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2)} */
OID_md2, /* 1.2.840.113549.2.2 */
OID_md4, /* 1.2.840.113549.2.4 */
OID_md5, /* 1.2.840.113549.2.5 */

OID_certAuthInfoAccess, /* 1.3.6.1.5.5.7.1.1 */
OID_msOutlookExpress, /* 1.3.6.1.4.1.311.16.4 */
OID_sha1, /* 1.3.14.3.2.26 */

/* Distinguished Name attribute IDs [RFC 2256] */
OID_commonName, /* 2.5.4.3 */
OID_surname, /* 2.5.4.4 */
OID_countryName, /* 2.5.4.6 */
OID_locality, /* 2.5.4.7 */
OID_stateOrProvinceName, /* 2.5.4.8 */
OID_organizationName, /* 2.5.4.10 */
OID_organizationUnitName, /* 2.5.4.11 */
OID_title, /* 2.5.4.12 */
OID_description, /* 2.5.4.13 */
OID_name, /* 2.5.4.41 */
OID_givenName, /* 2.5.4.42 */
OID_initials, /* 2.5.4.43 */
OID_generationalQualifier, /* 2.5.4.44 */

/* Certificate extension IDs */
OID_subjectKeyIdentifier, /* 2.5.29.14 */
OID_keyUsage, /* 2.5.29.15 */
OID_subjectAltName, /* 2.5.29.17 */
OID_issuerAltName, /* 2.5.29.18 */
OID_basicConstraints, /* 2.5.29.19 */
OID_crlDistributionPoints, /* 2.5.29.31 */
OID_certPolicies, /* 2.5.29.32 */
OID_authorityKeyIdentifier, /* 2.5.29.35 */
OID_extKeyUsage, /* 2.5.29.37 */

OID__NR
};

extern enum OID look_up_OID(const void *data, size_t datasize);

#endif /* _LINUX_OID_REGISTRY_H */
2 changes: 1 addition & 1 deletion trunk/lib/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
#
gen_crc32table
crc32table.h

oid_registry_data.c
5 changes: 5 additions & 0 deletions trunk/lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,9 @@ config SIGNATURE
config LIBFDT
bool

config OID_REGISTRY
tristate
help
Enable fast lookup object identifier registry.

endmenu
16 changes: 16 additions & 0 deletions trunk/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,19 @@ quiet_cmd_crc32 = GEN $@

$(obj)/crc32table.h: $(obj)/gen_crc32table
$(call cmd,crc32)

#
# Build a fast OID lookip registry from include/linux/oid_registry.h
#
obj-$(CONFIG_OID_REGISTRY) += oid_registry.o

$(obj)/oid_registry.c: $(obj)/oid_registry_data.c

$(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
$(src)/build_OID_registry
$(call cmd,build_OID_registry)

quiet_cmd_build_OID_registry = GEN $@
cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@

clean-files += oid_registry_data.c
209 changes: 209 additions & 0 deletions trunk/lib/build_OID_registry
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#!/usr/bin/perl -w
#
# Build a static ASN.1 Object Identified (OID) registry
#
# Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public Licence
# as published by the Free Software Foundation; either version
# 2 of the Licence, or (at your option) any later version.
#

use strict;

my @names = ();
my @oids = ();

if ($#ARGV != 1) {
print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n";
exit(2);
}

#
# Open the file to read from
#
open IN_FILE, "<$ARGV[0]" || die;
while (<IN_FILE>) {
chomp;
if (m!\s+OID_([a-zA-z][a-zA-Z0-9_]+),\s+/[*]\s+([012][.0-9]*)\s+[*]/!) {
push @names, $1;
push @oids, $2;
}
}
close IN_FILE || die;

#
# Open the files to write into
#
open C_FILE, ">$ARGV[1]" or die;
print C_FILE "/*\n";
print C_FILE " * Automatically generated by ", $0, ". Do not edit\n";
print C_FILE " */\n";

#
# Split the data up into separate lists and also determine the lengths of the
# encoded data arrays.
#
my @indices = ();
my @lengths = ();
my $total_length = 0;

print "Compiling ", $#names + 1, " OIDs\n";

for (my $i = 0; $i <= $#names; $i++) {
my $name = $names[$i];
my $oid = $oids[$i];

my @components = split(/[.]/, $oid);

# Determine the encoded length of this OID
my $size = $#components;
for (my $loop = 2; $loop <= $#components; $loop++) {
my $c = $components[$loop];

# We will base128 encode the number
my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
$tmp = int($tmp / 7);
$size += $tmp;
}
push @lengths, $size;
push @indices, $total_length;
$total_length += $size;
}

#
# Emit the look-up-by-OID index table
#
print C_FILE "\n";
if ($total_length <= 255) {
print C_FILE "static const unsigned char oid_index[OID__NR + 1] = {\n";
} else {
print C_FILE "static const unsigned short oid_index[OID__NR + 1] = {\n";
}
for (my $i = 0; $i <= $#names; $i++) {
print C_FILE "\t[OID_", $names[$i], "] = ", $indices[$i], ",\n"
}
print C_FILE "\t[OID__NR] = ", $total_length, "\n";
print C_FILE "};\n";

#
# Encode the OIDs
#
my @encoded_oids = ();

for (my $i = 0; $i <= $#names; $i++) {
my @octets = ();

my @components = split(/[.]/, $oids[$i]);

push @octets, $components[0] * 40 + $components[1];

for (my $loop = 2; $loop <= $#components; $loop++) {
my $c = $components[$loop];

# Base128 encode the number
my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
$tmp = int($tmp / 7);

for (; $tmp > 0; $tmp--) {
push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80;
}
push @octets, $c & 0x7f;
}

push @encoded_oids, \@octets;
}

#
# Create a hash value for each OID
#
my @hash_values = ();
for (my $i = 0; $i <= $#names; $i++) {
my @octets = @{$encoded_oids[$i]};

my $hash = $#octets;
foreach (@octets) {
$hash += $_ * 33;
}

$hash = ($hash >> 24) ^ ($hash >> 16) ^ ($hash >> 8) ^ ($hash);

push @hash_values, $hash & 0xff;
}

#
# Emit the OID data
#
print C_FILE "\n";
print C_FILE "static const unsigned char oid_data[", $total_length, "] = {\n";
for (my $i = 0; $i <= $#names; $i++) {
my @octets = @{$encoded_oids[$i]};
print C_FILE "\t";
print C_FILE $_, ", " foreach (@octets);
print C_FILE "\t// ", $names[$i];
print C_FILE "\n";
}
print C_FILE "};\n";

#
# Build the search index table (ordered by length then hash then content)
#
my @index_table = ( 0 .. $#names );

@index_table = sort {
my @octets_a = @{$encoded_oids[$a]};
my @octets_b = @{$encoded_oids[$b]};

return $hash_values[$a] <=> $hash_values[$b]
if ($hash_values[$a] != $hash_values[$b]);
return $#octets_a <=> $#octets_b
if ($#octets_a != $#octets_b);
for (my $i = $#octets_a; $i >= 0; $i--) {
return $octets_a[$i] <=> $octets_b[$i]
if ($octets_a[$i] != $octets_b[$i]);
}
return 0;

} @index_table;

#
# Emit the search index and hash value table
#
print C_FILE "\n";
print C_FILE "static const struct {\n";
print C_FILE "\tunsigned char hash;\n";
if ($#names <= 255) {
print C_FILE "\tenum OID oid : 8;\n";
} else {
print C_FILE "\tenum OID oid : 16;\n";
}
print C_FILE "} oid_search_table[OID__NR] = {\n";
for (my $i = 0; $i <= $#names; $i++) {
my @octets = @{$encoded_oids[$index_table[$i]]};
printf(C_FILE "\t[%3u] = { %3u, OID_%-35s }, // ",
$i,
$hash_values[$index_table[$i]],
$names[$index_table[$i]]);
printf C_FILE "%02x", $_ foreach (@octets);
print C_FILE "\n";
}
print C_FILE "};\n";

#
# Emit the OID debugging name table
#
#print C_FILE "\n";
#print C_FILE "const char *const oid_name_table[OID__NR + 1] = {\n";
#
#for (my $i = 0; $i <= $#names; $i++) {
# print C_FILE "\t\"", $names[$i], "\",\n"
#}
#print C_FILE "\t\"Unknown-OID\"\n";
#print C_FILE "};\n";

#
# Polish off
#
close C_FILE or die;
Loading

0 comments on commit 03e1103

Please sign in to comment.