linux-yocto/lib/build_OID_registry
Arnd Bergmann a857c6e7d5 X.509: do not emit any informational output
When building a kernel using 'make -s', I expect to see an empty output,
except for build warnings and errors. The build_OID_registry code
always prints one line when run, which is not helpful to most people
building the kernels, and which makes it harder to automatically
check for build warnings.

Let's just remove the one line output.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: David Howells <dhowells@redhat.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
2013-06-19 17:54:06 +02:00

4.7 KiB
Executable File

#!/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, " \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;

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;