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