1e1051a39Sopenharmony_ci#! /usr/bin/env perl 2e1051a39Sopenharmony_ci# Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci# 4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci# this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci 9e1051a39Sopenharmony_ciuse integer; 10e1051a39Sopenharmony_ciuse strict; 11e1051a39Sopenharmony_ciuse warnings; 12e1051a39Sopenharmony_ciuse FindBin; 13e1051a39Sopenharmony_ciuse lib "$FindBin::Bin/../../util/perl"; 14e1051a39Sopenharmony_ciuse OpenSSL::copyright; 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci# Generate the DER encoding for the given OID. 17e1051a39Sopenharmony_cisub der_it 18e1051a39Sopenharmony_ci{ 19e1051a39Sopenharmony_ci # Prologue 20e1051a39Sopenharmony_ci my ($v) = @_; 21e1051a39Sopenharmony_ci my @a = split(/\s+/, $v); 22e1051a39Sopenharmony_ci my $ret = pack("C*", $a[0] * 40 + $a[1]); 23e1051a39Sopenharmony_ci shift @a; 24e1051a39Sopenharmony_ci shift @a; 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci # Loop over rest of bytes; or in 0x80 for multi-byte numbers. 27e1051a39Sopenharmony_ci my $t; 28e1051a39Sopenharmony_ci foreach (@a) { 29e1051a39Sopenharmony_ci my @r = (); 30e1051a39Sopenharmony_ci $t = 0; 31e1051a39Sopenharmony_ci while ($_ >= 128) { 32e1051a39Sopenharmony_ci my $x = $_ % 128; 33e1051a39Sopenharmony_ci $_ /= 128; 34e1051a39Sopenharmony_ci push(@r, ($t++ ? 0x80 : 0) | $x); 35e1051a39Sopenharmony_ci } 36e1051a39Sopenharmony_ci push(@r, ($t++ ? 0x80 : 0) | $_); 37e1051a39Sopenharmony_ci $ret .= pack("C*", reverse(@r)); 38e1051a39Sopenharmony_ci } 39e1051a39Sopenharmony_ci return $ret; 40e1051a39Sopenharmony_ci} 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci# The year the output file is generated. 43e1051a39Sopenharmony_cimy $YEAR = OpenSSL::copyright::latest(($0, $ARGV[0])); 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ci# Read input, parse all #define's into OID name and value. 46e1051a39Sopenharmony_ci# Populate %ln and %sn with long and short names (%dupln and %dupsn) 47e1051a39Sopenharmony_ci# are used to watch for duplicates. Also %nid and %obj get the 48e1051a39Sopenharmony_ci# NID and OBJ entries. 49e1051a39Sopenharmony_cimy %ln; 50e1051a39Sopenharmony_cimy %sn; 51e1051a39Sopenharmony_cimy %dupln; 52e1051a39Sopenharmony_cimy %dupsn; 53e1051a39Sopenharmony_cimy %nid; 54e1051a39Sopenharmony_cimy %obj; 55e1051a39Sopenharmony_cimy %objd; 56e1051a39Sopenharmony_ciopen(IN, "$ARGV[0]") || die "Can't open input file $ARGV[0], $!"; 57e1051a39Sopenharmony_ciwhile (<IN>) { 58e1051a39Sopenharmony_ci next unless /^\#define\s+(\S+)\s+(.*)$/; 59e1051a39Sopenharmony_ci my $v = $1; 60e1051a39Sopenharmony_ci my $d = $2; 61e1051a39Sopenharmony_ci $d =~ s/^\"//; 62e1051a39Sopenharmony_ci $d =~ s/\"$//; 63e1051a39Sopenharmony_ci if ($v =~ /^SN_(.*)$/) { 64e1051a39Sopenharmony_ci if (defined $dupsn{$d}) { 65e1051a39Sopenharmony_ci print "WARNING: Duplicate short name \"$d\"\n"; 66e1051a39Sopenharmony_ci } else { 67e1051a39Sopenharmony_ci $dupsn{$d} = 1; 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci $sn{$1} = $d; 70e1051a39Sopenharmony_ci } 71e1051a39Sopenharmony_ci elsif ($v =~ /^LN_(.*)$/) { 72e1051a39Sopenharmony_ci if (defined $dupln{$d}) { 73e1051a39Sopenharmony_ci print "WARNING: Duplicate long name \"$d\"\n"; 74e1051a39Sopenharmony_ci } else { 75e1051a39Sopenharmony_ci $dupln{$d} = 1; 76e1051a39Sopenharmony_ci } 77e1051a39Sopenharmony_ci $ln{$1} = $d; 78e1051a39Sopenharmony_ci } 79e1051a39Sopenharmony_ci elsif ($v =~ /^NID_(.*)$/) { 80e1051a39Sopenharmony_ci $nid{$d} = $1; 81e1051a39Sopenharmony_ci } 82e1051a39Sopenharmony_ci elsif ($v =~ /^OBJ_(.*)$/) { 83e1051a39Sopenharmony_ci $obj{$1} = $v; 84e1051a39Sopenharmony_ci $objd{$v} = $d; 85e1051a39Sopenharmony_ci } 86e1051a39Sopenharmony_ci} 87e1051a39Sopenharmony_ciclose IN; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci# For every value in %obj, recursively expand OBJ_xxx values. That is: 90e1051a39Sopenharmony_ci# #define OBJ_iso 1L 91e1051a39Sopenharmony_ci# #define OBJ_identified_organization OBJ_iso,3L 92e1051a39Sopenharmony_ci# Modify %objd values in-place. Create an %objn array that has 93e1051a39Sopenharmony_cimy $changed; 94e1051a39Sopenharmony_cido { 95e1051a39Sopenharmony_ci $changed = 0; 96e1051a39Sopenharmony_ci foreach my $k (keys %objd) { 97e1051a39Sopenharmony_ci $changed = 1 if $objd{$k} =~ s/(OBJ_[^,]+),/$objd{$1},/; 98e1051a39Sopenharmony_ci } 99e1051a39Sopenharmony_ci} while ($changed); 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_cimy @a = sort { $a <=> $b } keys %nid; 102e1051a39Sopenharmony_cimy $n = $a[$#a] + 1; 103e1051a39Sopenharmony_cimy @lvalues = (); 104e1051a39Sopenharmony_cimy $lvalues = 0; 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci# Scan all defined objects, building up the @out array. 107e1051a39Sopenharmony_ci# %obj_der holds the DER encoding as an array of bytes, and %obj_len 108e1051a39Sopenharmony_ci# holds the length in bytes. 109e1051a39Sopenharmony_cimy @out; 110e1051a39Sopenharmony_cimy %obj_der; 111e1051a39Sopenharmony_cimy %obj_len; 112e1051a39Sopenharmony_cifor (my $i = 0; $i < $n; $i++) { 113e1051a39Sopenharmony_ci if (!defined $nid{$i}) { 114e1051a39Sopenharmony_ci push(@out, " { NULL, NULL, NID_undef },\n"); 115e1051a39Sopenharmony_ci next; 116e1051a39Sopenharmony_ci } 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ci my $sn = defined $sn{$nid{$i}} ? "$sn{$nid{$i}}" : "NULL"; 119e1051a39Sopenharmony_ci my $ln = defined $ln{$nid{$i}} ? "$ln{$nid{$i}}" : "NULL"; 120e1051a39Sopenharmony_ci if ($sn eq "NULL") { 121e1051a39Sopenharmony_ci $sn = $ln; 122e1051a39Sopenharmony_ci $sn{$nid{$i}} = $ln; 123e1051a39Sopenharmony_ci } 124e1051a39Sopenharmony_ci if ($ln eq "NULL") { 125e1051a39Sopenharmony_ci $ln = $sn; 126e1051a39Sopenharmony_ci $ln{$nid{$i}} = $sn; 127e1051a39Sopenharmony_ci } 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci my $out = " {\"$sn\", \"$ln\", NID_$nid{$i}"; 130e1051a39Sopenharmony_ci if (defined $obj{$nid{$i}} && $objd{$obj{$nid{$i}}} =~ /,/) { 131e1051a39Sopenharmony_ci my $v = $objd{$obj{$nid{$i}}}; 132e1051a39Sopenharmony_ci $v =~ s/L//g; 133e1051a39Sopenharmony_ci $v =~ s/,/ /g; 134e1051a39Sopenharmony_ci my $r = &der_it($v); 135e1051a39Sopenharmony_ci my $z = ""; 136e1051a39Sopenharmony_ci my $length = 0; 137e1051a39Sopenharmony_ci # Format using fixed-with because we use strcmp later. 138e1051a39Sopenharmony_ci foreach (unpack("C*",$r)) { 139e1051a39Sopenharmony_ci $z .= sprintf("0x%02X,", $_); 140e1051a39Sopenharmony_ci $length++; 141e1051a39Sopenharmony_ci } 142e1051a39Sopenharmony_ci $obj_der{$obj{$nid{$i}}} = $z; 143e1051a39Sopenharmony_ci $obj_len{$obj{$nid{$i}}} = $length; 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci push(@lvalues, 146e1051a39Sopenharmony_ci sprintf(" %-45s /* [%5d] %s */\n", 147e1051a39Sopenharmony_ci $z, $lvalues, $obj{$nid{$i}})); 148e1051a39Sopenharmony_ci $out .= ", $length, &so[$lvalues]"; 149e1051a39Sopenharmony_ci $lvalues += $length; 150e1051a39Sopenharmony_ci } 151e1051a39Sopenharmony_ci $out .= "},\n"; 152e1051a39Sopenharmony_ci push(@out, $out); 153e1051a39Sopenharmony_ci} 154e1051a39Sopenharmony_ci 155e1051a39Sopenharmony_ci# Finally ready to generate the output. 156e1051a39Sopenharmony_ciprint <<"EOF"; 157e1051a39Sopenharmony_ci/* 158e1051a39Sopenharmony_ci * WARNING: do not edit! 159e1051a39Sopenharmony_ci * Generated by crypto/objects/obj_dat.pl 160e1051a39Sopenharmony_ci * 161e1051a39Sopenharmony_ci * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. 162e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 163e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 164e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 165e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 166e1051a39Sopenharmony_ci */ 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_ciEOF 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ciprint "/* Serialized OID's */\n"; 171e1051a39Sopenharmony_ciprintf "static const unsigned char so[%d] = {\n", $lvalues + 1; 172e1051a39Sopenharmony_ciprint @lvalues; 173e1051a39Sopenharmony_ciprint "};\n\n"; 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_ciprintf "#define NUM_NID %d\n", $n; 176e1051a39Sopenharmony_ciprintf "static const ASN1_OBJECT nid_objs[NUM_NID] = {\n"; 177e1051a39Sopenharmony_ciprint @out; 178e1051a39Sopenharmony_ciprint "};\n\n"; 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ci{ 181e1051a39Sopenharmony_ci no warnings "uninitialized"; 182e1051a39Sopenharmony_ci @a = grep(defined $sn{$nid{$_}}, 0 .. $n); 183e1051a39Sopenharmony_ci} 184e1051a39Sopenharmony_ciprintf "#define NUM_SN %d\n", $#a + 1; 185e1051a39Sopenharmony_ciprintf "static const unsigned int sn_objs[NUM_SN] = {\n"; 186e1051a39Sopenharmony_ciforeach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a) { 187e1051a39Sopenharmony_ci printf " %4d, /* \"$sn{$nid{$_}}\" */\n", $_; 188e1051a39Sopenharmony_ci} 189e1051a39Sopenharmony_ciprint "};\n\n"; 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ci{ 192e1051a39Sopenharmony_ci no warnings "uninitialized"; 193e1051a39Sopenharmony_ci @a = grep(defined $ln{$nid{$_}}, 0 .. $n); 194e1051a39Sopenharmony_ci} 195e1051a39Sopenharmony_ciprintf "#define NUM_LN %d\n", $#a + 1; 196e1051a39Sopenharmony_ciprintf "static const unsigned int ln_objs[NUM_LN] = {\n"; 197e1051a39Sopenharmony_ciforeach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a) { 198e1051a39Sopenharmony_ci printf " %4d, /* \"$ln{$nid{$_}}\" */\n", $_; 199e1051a39Sopenharmony_ci} 200e1051a39Sopenharmony_ciprint "};\n\n"; 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci{ 203e1051a39Sopenharmony_ci no warnings "uninitialized"; 204e1051a39Sopenharmony_ci @a = grep(defined $obj{$nid{$_}}, 0 .. $n); 205e1051a39Sopenharmony_ci} 206e1051a39Sopenharmony_ciprintf "#define NUM_OBJ %d\n", $#a + 1; 207e1051a39Sopenharmony_ciprintf "static const unsigned int obj_objs[NUM_OBJ] = {\n"; 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_ci# Compare DER; prefer shorter; if some length, use the "smaller" encoding. 210e1051a39Sopenharmony_cisub obj_cmp 211e1051a39Sopenharmony_ci{ 212e1051a39Sopenharmony_ci no warnings "uninitialized"; 213e1051a39Sopenharmony_ci my $A = $obj_len{$obj{$nid{$a}}}; 214e1051a39Sopenharmony_ci my $B = $obj_len{$obj{$nid{$b}}}; 215e1051a39Sopenharmony_ci my $r = $A - $B; 216e1051a39Sopenharmony_ci return $r if $r != 0; 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci $A = $obj_der{$obj{$nid{$a}}}; 219e1051a39Sopenharmony_ci $B = $obj_der{$obj{$nid{$b}}}; 220e1051a39Sopenharmony_ci return $A cmp $B; 221e1051a39Sopenharmony_ci} 222e1051a39Sopenharmony_ciforeach (sort obj_cmp @a) { 223e1051a39Sopenharmony_ci my $m = $obj{$nid{$_}}; 224e1051a39Sopenharmony_ci my $v = $objd{$m}; 225e1051a39Sopenharmony_ci $v =~ s/L//g; 226e1051a39Sopenharmony_ci $v =~ s/,/ /g; 227e1051a39Sopenharmony_ci printf " %4d, /* %-32s %s */\n", $_, $m, $v; 228e1051a39Sopenharmony_ci} 229e1051a39Sopenharmony_ciprint "};\n"; 230