1 #! /usr/bin/env perl 2 # Copyright 1995-2023 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 # Generate progs.h file by looking for command mains in list of C files 10 # passed on the command line. 11 12 use strict; 13 use warnings; 14 use lib '.'; 15 use configdata qw/@disablables %unified_info/; 16 17 my $opt = shift @ARGV; 18 die "Unrecognised option, must be -C or -H\n" 19 unless ($opt eq '-H' || $opt eq '-C'); 20 21 my %commands = (); 22 # I think it is best reconsidered in favour of just a table 23 # of commands instead of this fragile regex. There really are not that 24 # many commands. 25 my $cmdre = qr/^\s*(int\s+|)\s*([a-z_][a-z0-9_]*)_main\s*\(\s*int\s+argc\s*,/; 26 my $apps_openssl = shift @ARGV; 27 my $YEAR = [gmtime($ENV{SOURCE_DATE_EPOCH} || time())]->[5] + 1900; 28 29 # because the program apps/openssl has object files as sources, and 30 # they then have the corresponding C files as source, we need to chain 31 # the lookups in %unified_info 32 my @openssl_source = 33 map { @{$unified_info{sources}->{$_}} } 34 grep { /\.o$/ 35 && !$unified_info{attributes}->{sources}->{$apps_openssl}->{$_}->{nocheck} } 36 @{$unified_info{sources}->{$apps_openssl}}; 37 38 foreach my $filename (@openssl_source) { 39 open F, $filename or die "Couldn't open $filename: $!\n"; 40 foreach ( grep /$cmdre/, <F> ) { 41 my @foo = /$cmdre/; 42 $commands{$2} = 1; 43 } 44 close F; 45 } 46 47 @ARGV = sort keys %commands; 48 49 if ($opt eq '-H') { 50 print <<"EOF"; 51 /* 52 * WARNING: do not edit! 53 * Generated by apps/progs.pl 54 * 55 * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. 56 * 57 * Licensed under the Apache License 2.0 (the "License"). You may not use 58 * this file except in compliance with the License. You can obtain a copy 59 * in the file LICENSE in the source distribution or at 60 * https://www.openssl.org/source/license.html 61 */ 62 63 #include "function.h" 64 65 EOF 66 67 foreach (@ARGV) { 68 printf "extern int %s_main(int argc, char *argv[]);\n", $_; 69 } 70 print "\n"; 71 72 foreach (@ARGV) { 73 printf "extern const OPTIONS %s_options[];\n", $_; 74 } 75 print "\n"; 76 print "extern FUNCTION functions[];\n"; 77 } 78 79 if ($opt eq '-C') { 80 print <<"EOF"; 81 /* 82 * WARNING: do not edit! 83 * Generated by apps/progs.pl 84 * 85 * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. 86 * 87 * Licensed under the Apache License 2.0 (the "License"). You may not use 88 * this file except in compliance with the License. You can obtain a copy 89 * in the file LICENSE in the source distribution or at 90 * https://www.openssl.org/source/license.html 91 */ 92 93 #include "progs.h" 94 95 EOF 96 97 my %cmd_disabler = ( 98 ciphers => "sock", 99 genrsa => "rsa", 100 gendsa => "dsa", 101 dsaparam => "dsa", 102 gendh => "dh", 103 dhparam => "dh", 104 ecparam => "ec", 105 ); 106 my %cmd_deprecated = ( 107 # The format of this table is: 108 # [0] = alternative command to use instead 109 # [1] = deprecented in this version 110 # [2] = preprocessor conditional for excluding irrespective of deprecation 111 # rsa => [ "pkey", "3_0", "rsa" ], 112 # genrsa => [ "genpkey", "3_0", "rsa" ], 113 rsautl => [ "pkeyutl", "3_0", "rsa" ], 114 # dhparam => [ "pkeyparam", "3_0", "dh" ], 115 # dsaparam => [ "pkeyparam", "3_0", "dsa" ], 116 # dsa => [ "pkey", "3_0", "dsa" ], 117 # gendsa => [ "genpkey", "3_0", "dsa" ], 118 # ec => [ "pkey", "3_0", "ec" ], 119 # ecparam => [ "pkeyparam", "3_0", "ec" ], 120 ); 121 122 print "FUNCTION functions[] = {\n"; 123 foreach my $cmd ( @ARGV ) { 124 my $str = 125 " {FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options, NULL, NULL},\n"; 126 if ($cmd =~ /^s_/) { 127 print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n"; 128 } elsif (my $deprecated = $cmd_deprecated{$cmd}) { 129 my @dep = @{$deprecated}; 130 my $daltprg = $dep[0]; 131 my $dver = $dep[1]; 132 my $dsys = $dep[2]; 133 print "#if !defined(OPENSSL_NO_DEPRECATED_" . $dver . ")"; 134 if ($dsys) { 135 print " && !defined(OPENSSL_NO_" . uc($dsys) . ")"; 136 } 137 $dver =~ s/_/./g; 138 my $dalt = "\"" . $daltprg . "\", \"" . $dver . "\""; 139 $str =~ s/NULL, NULL/$dalt/; 140 print "\n${str}#endif\n"; 141 } elsif (grep { $cmd eq $_ } @disablables) { 142 print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; 143 } elsif (my $disabler = $cmd_disabler{$cmd}) { 144 print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; 145 } else { 146 print $str; 147 } 148 } 149 150 my %md_disabler = ( 151 blake2b512 => "blake2", 152 blake2s256 => "blake2", 153 ); 154 foreach my $cmd ( 155 "md2", "md4", "md5", 156 "sha1", "sha224", "sha256", "sha384", 157 "sha512", "sha512-224", "sha512-256", 158 "sha3-224", "sha3-256", "sha3-384", "sha3-512", 159 "shake128", "shake256", 160 "mdc2", "rmd160", "blake2b512", "blake2s256", 161 "sm3" 162 ) { 163 my $str = " {FT_md, \"$cmd\", dgst_main, NULL, NULL},\n"; 164 if (grep { $cmd eq $_ } @disablables) { 165 print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; 166 } elsif (my $disabler = $md_disabler{$cmd}) { 167 print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; 168 } else { 169 print $str; 170 } 171 } 172 173 my %cipher_disabler = ( 174 des3 => "des", 175 desx => "des", 176 cast5 => "cast", 177 ); 178 foreach my $cmd ( 179 "aes-128-cbc", "aes-128-ecb", 180 "aes-192-cbc", "aes-192-ecb", 181 "aes-256-cbc", "aes-256-ecb", 182 "aria-128-cbc", "aria-128-cfb", 183 "aria-128-ctr", "aria-128-ecb", "aria-128-ofb", 184 "aria-128-cfb1", "aria-128-cfb8", 185 "aria-192-cbc", "aria-192-cfb", 186 "aria-192-ctr", "aria-192-ecb", "aria-192-ofb", 187 "aria-192-cfb1", "aria-192-cfb8", 188 "aria-256-cbc", "aria-256-cfb", 189 "aria-256-ctr", "aria-256-ecb", "aria-256-ofb", 190 "aria-256-cfb1", "aria-256-cfb8", 191 "camellia-128-cbc", "camellia-128-ecb", 192 "camellia-192-cbc", "camellia-192-ecb", 193 "camellia-256-cbc", "camellia-256-ecb", 194 "base64", "zlib", "brotli", "zstd", 195 "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", 196 "rc2", "bf", "cast", "rc5", 197 "des-ecb", "des-ede", "des-ede3", 198 "des-cbc", "des-ede-cbc","des-ede3-cbc", 199 "des-cfb", "des-ede-cfb","des-ede3-cfb", 200 "des-ofb", "des-ede-ofb","des-ede3-ofb", 201 "idea-cbc","idea-ecb", "idea-cfb", "idea-ofb", 202 "seed-cbc","seed-ecb", "seed-cfb", "seed-ofb", 203 "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc", 204 "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb", 205 "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb", 206 "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb", 207 "sm4-cbc", "sm4-ecb", "sm4-cfb", "sm4-ofb", "sm4-ctr" 208 ) { 209 my $str = " {FT_cipher, \"$cmd\", enc_main, enc_options, NULL},\n"; 210 (my $algo = $cmd) =~ s/-.*//g; 211 if (grep { $algo eq $_ } @disablables) { 212 print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n"; 213 } elsif (my $disabler = $cipher_disabler{$algo}) { 214 print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; 215 } else { 216 print $str; 217 } 218 } 219 220 print " {0, NULL, NULL, NULL, NULL}\n};\n"; 221 } 222