oids_to_c.pm 3.1 KB

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