Home | History | Annotate | Line # | Download | only in der
      1 #! /usr/bin/env perl
      2 # Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
      3 #
      4 # Licensed under the Apache License 2.0 (the "License").  You may not use
      5 # this file except in compliance with the License.  You can obtain a copy
      6 # in the file LICENSE in the source distribution or at
      7 # https://www.openssl.org/source/license.html
      8 
      9 use strict;
     10 use warnings;
     11 
     12 package oids_to_c;
     13 
     14 use Carp;
     15 use File::Spec;
     16 use OpenSSL::OID;
     17 
     18 my $OID_name_re = qr/([a-z](?:[-_A-Za-z0-9]*[A-Za-z0-9])?)/;
     19 my $OID_value_re = qr/(\{.*?\})/s;
     20 my $OID_def_re = qr/
     21                        ${OID_name_re} \s+ OBJECT \s+ IDENTIFIER \s*
     22                        ::=
     23                        \s* ${OID_value_re}
     24                    /x;
     25 
     26 sub filter_to_H {
     27     my ($name, $comment) = @{ shift() };
     28     my @oid_nums = @_;
     29     my $oid_size = scalar @oid_nums;
     30 
     31     (my $C_comment = $comment) =~ s|^| * |msg;
     32     $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne '';
     33     (my $C_name = $name) =~ s|-|_|g;
     34     my $C_bytes_size = 2 + scalar @_;
     35     my $C_bytes = join(', ', map { sprintf("0x%02X", $_) } @oid_nums );
     36 
     37     return <<"_____";
     38 $C_comment
     39 #define DER_OID_V_${C_name} DER_P_OBJECT, $oid_size, ${C_bytes}
     40 #define DER_OID_SZ_${C_name} ${C_bytes_size}
     41 extern const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}];
     42 _____
     43 }
     44 
     45 sub filter_to_C {
     46     my ($name, $comment) = @{ shift() };
     47     my @oid_nums = @_;
     48     my $oid_size = scalar @oid_nums;
     49 
     50     croak "Unsupported OID size (>127 bytes)" if $oid_size > 127;
     51 
     52     (my $C_comment = $comment) =~ s|^| * |msg;
     53     $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne '';
     54     (my $C_name = $name) =~ s|-|_|g;
     55     my $C_bytes_size = 2 + $oid_size;
     56 
     57     return <<"_____";
     58 $C_comment
     59 const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}] = {
     60     DER_OID_V_${C_name}
     61 };
     62 _____
     63 }
     64 
     65 sub _process {
     66     my %opts = %{ pop @_ } if ref $_[$#_] eq 'HASH';
     67 
     68     # To maintain input order
     69     my @OID_names = ();
     70 
     71     foreach my $file (@_) {
     72         my $input = File::Spec->catfile($opts{dir}, $file);
     73         open my $fh, $input or die "Reading $input: $!\n";
     74 
     75         my $text = join('',
     76                         map {
     77                             s|--.*(\R)$|$1|;
     78                             $_;
     79                         } <$fh>);
     80         # print STDERR "-----BEGIN DEBUG-----\n";
     81         # print STDERR $text;
     82         # print STDERR "-----END DEBUG-----\n";
     83         use re 'debugcolor';
     84         while ($text =~ m/${OID_def_re}/sg) {
     85             my $comment = $&;
     86             my $name = $1;
     87             my $value = $2;
     88 
     89             # print STDERR "-----BEGIN DEBUG $name-----\n";
     90             # print STDERR $value,"\n";
     91             # print STDERR "-----END DEBUG $name-----\n";
     92             register_oid($name, $value);
     93             push @OID_names, [ $name, $comment ];
     94         }
     95     }
     96 
     97     return @OID_names;
     98 }
     99 
    100 sub process_leaves {
    101     my %opts = %{ $_[$#_] } if ref $_[$#_] eq 'HASH';
    102     my @OID_names = _process @_;
    103 
    104     my $text = '';
    105     my %leaves = map { $_ => 1 } registered_oid_leaves;
    106     foreach (grep { defined $leaves{$_->[0]} } @OID_names) {
    107         my $lines = $opts{filter}->($_, encode_oid($_->[0]));
    108         $text .= $lines;
    109     }
    110     return $text;
    111 }
    112 
    113 1;
    114