Refactor the provider side DER constants and writers
[openssl.git] / providers / common / der / oids_to_c.pm
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 use Data::Dumper;
27
28 sub filter_to_H {
29     my ($name, $comment) = @{ shift() };
30     my @oid_nums = @_;
31     my $oid_size = scalar @oid_nums;
32
33     (my $C_comment = $comment) =~ s|^| * |msg;
34     $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne '';
35     (my $C_name = $name) =~ s|-|_|g;
36     my $C_bytes_size = 2 + scalar @_;
37     my $C_bytes = join(', ', map { sprintf("0x%02X", $_) } @oid_nums );
38
39     return <<"_____";
40 $C_comment
41 #define DER_OID_V_${C_name} DER_P_OBJECT, $oid_size, ${C_bytes}
42 #define DER_OID_SZ_${C_name} ${C_bytes_size}
43 extern const unsigned char der_oid_${C_name}[DER_OID_SZ_${C_name}];
44 _____
45 }
46
47 sub filter_to_C {
48     my ($name, $comment) = @{ shift() };
49     my @oid_nums = @_;
50     my $oid_size = scalar @oid_nums;
51
52     croak "Unsupported OID size (>127 bytes)" if $oid_size > 127;
53
54     (my $C_comment = $comment) =~ s|^| * |msg;
55     $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne '';
56     (my $C_name = $name) =~ s|-|_|g;
57     my $C_bytes_size = 2 + $oid_size;
58
59     return <<"_____";
60 $C_comment
61 const unsigned char der_oid_${C_name}[DER_OID_SZ_${C_name}] = {
62     DER_OID_V_${C_name}
63 };
64 _____
65 }
66
67 sub _process {
68     my %opts = %{ pop @_ } if ref $_[$#_] eq 'HASH';
69
70     # To maintain input order
71     my @OID_names = ();
72
73     foreach my $file (@_) {
74         my $input = File::Spec->catfile($opts{dir}, $file);
75         open my $fh, $input or die "Reading $input: $!\n";
76
77         my $text = join('',
78                         map {
79                             s|--.*(\R)$|$1|;
80                             $_;
81                         } <$fh>);
82         # print STDERR "-----BEGIN DEBUG-----\n";
83         # print STDERR $text;
84         # print STDERR "-----END DEBUG-----\n";
85         use re 'debugcolor';
86         while ($text =~ m/${OID_def_re}/sg) {
87             my $comment = $&;
88             my $name = $1;
89             my $value = $2;
90
91             # print STDERR "-----BEGIN DEBUG $name-----\n";
92             # print STDERR $value,"\n";
93             # print STDERR "-----END DEBUG $name-----\n";
94             register_oid($name, $value);
95             push @OID_names, [ $name, $comment ];
96         }
97     }
98
99     return @OID_names;
100 }
101
102 sub process_leaves {
103     my %opts = %{ $_[$#_] } if ref $_[$#_] eq 'HASH';
104     my @OID_names = _process @_;
105
106     my $text = '';
107     my %leaves = map { $_ => 1 } registered_oid_leaves;
108     foreach (grep { defined $leaves{$_->[0]} } @OID_names) {
109         my $lines = $opts{filter}->($_, encode_oid($_->[0]));
110         $text .= $lines;
111     }
112     return $text;
113 }
114
115 1;