oids_to_c.pm 3.2 KB

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