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