xref: /openssl/providers/common/der/oids_to_c.pm (revision 01290306)
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
9use strict;
10use warnings;
11
12package oids_to_c;
13
14use Carp;
15use File::Spec;
16use OpenSSL::OID;
17
18my $OID_name_re = qr/([a-z](?:[-_A-Za-z0-9]*[A-Za-z0-9])?)/;
19my $OID_value_re = qr/(\{.*?\})/s;
20my $OID_def_re = qr/
21                       ${OID_name_re} \s+ OBJECT \s+ IDENTIFIER \s*
22                       ::=
23                       \s* ${OID_value_re}
24                   /x;
25
26use Data::Dumper;
27
28sub 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}
43extern const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}];
44_____
45}
46
47sub 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
61const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}] = {
62    DER_OID_V_${C_name}
63};
64_____
65}
66
67sub _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
102sub 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
1151;
116