X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=util%2Fmkdef.pl;h=26cf3f4b45d102cd396b205afef5a2660eb52b6a;hb=e863d92010f250164d0f90cb61e51e3d9429942a;hp=fa3f3dbe76ceadf1f554d9d994d06291ed3ae1bb;hpb=07c4c14c4739da0c44562328afb6e7273e51298c;p=openssl.git diff --git a/util/mkdef.pl b/util/mkdef.pl index fa3f3dbe76..26cf3f4b45 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -5,30 +5,14 @@ # It does this by parsing the header files and looking for the # prototyped functions: it then prunes the output. # -# Intermediary files are created, call libeay.num and ssleay.num,... -# Previously, they had the following format: +# Intermediary files are created, call libeay.num and ssleay.num, +# The format of these files is: # -# routine-name nnnn +# routine-name nnnn vers info # -# But that isn't enough for a number of reasons, the first on being that -# this format is (needlessly) very Win32-centric, and even then... -# One of the biggest problems is that there's no information about what -# routines should actually be used, which varies with what crypto algorithms -# are disabled. Also, some operating systems (for example VMS with VAX C) -# need to keep track of the global variables as well as the functions. -# -# So, a remake of this script is done so as to include information on the -# kind of symbol it is (function or variable) and what algorithms they're -# part of. This will allow easy translating to .def files or the corresponding -# file in other operating systems (a .opt file for VMS, possibly with a .mar -# file). -# -# The format now becomes: -# -# routine-name nnnn info -# -# and the "info" part is actually a colon-separated string of fields with -# the following meaning: +# The "nnnn" and "vers" fields are the numeric id and version for the symbol +# respectively. The "info" part is actually a colon-separated string of fields +# with the following meaning: # # existence:platform:kind:algorithms # @@ -72,21 +56,22 @@ my $VMSVAX=0; my $VMSNonVAX=0; my $VMS=0; my $W32=0; -my $W16=0; my $NT=0; my $OS2=0; +my $linux=0; # Set this to make typesafe STACK definitions appear in DEF my $safe_stack_def = 0; -my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT", +my @known_platforms = ( "__FreeBSD__", "PERL5", "EXPORT_VAR_AS_FUNCTION", "ZLIB", "OPENSSL_FIPS", "OPENSSL_FIPSCAPABLE" ); -my @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" ); +my @known_ossl_platforms = ( "VMS", "WIN32", "WINNT", "OS2" ); my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1", - "SHA256", "SHA512", "RIPEMD", - "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M", + "SHA256", "SHA512", "RMD160", + "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "EC2M", "HMAC", "AES", "CAMELLIA", "SEED", "GOST", + "SCRYPT", "CHACHA", "POLY1305", # EC_NISTP_64_GCC_128 "EC_NISTP_64_GCC_128", # Envelope "algorithms" @@ -95,13 +80,15 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", "BIO", "COMP", "BUFFER", "LHASH", "STACK", "ERR", "LOCKING", # External "algorithms" - "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM", + "FP_API", "STDIO", "SOCK", "DGRAM", # Engines - "STATIC_ENGINE", "ENGINE", "HW", "GMP", + "STATIC_ENGINE", "ENGINE", "HW", "GMP", + # X.509v3 Signed Certificate Timestamps + "SCT", # RFC3779 "RFC3779", # TLS - "TLSEXT", "PSK", "SRP", "HEARTBEATS", + "PSK", "SRP", "HEARTBEATS", # CMS "CMS", # CryptoAPI Engine @@ -114,8 +101,6 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", "NEXTPROTONEG", # Deprecated functions "DEPRECATED", - # Hide SSL internals - "SSL_INTERN", # SCTP "SCTP", # SRTP @@ -123,7 +108,12 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", # SSL TRACE "SSL_TRACE", # Unit testing - "UNIT_TEST"); + "UNIT_TEST", + # OCB mode + "OCB", + # APPLINK (win build feature?) + "APPLINK" + ); my $options=""; open(IN,") { if($parens > 0) { #Inside a DECLARE_DEPRECATED - $parens += count_parens($_); + $stored_multiline .= $_; + chomp $stored_multiline; + print STDERR "DEBUG: Continuing multiline DEPRECATED: $stored_multiline\n" if $debug; + $parens = count_parens($stored_multiline); + if ($parens == 0) { + $stored_multiline =~ /^\s*DECLARE_DEPRECATED\s*\(\s*(\w*(\s|\*|\w)*)/; + $def .= "$1(void);"; + } next; } if (/\/\* Error codes for the \w+ functions\. \*\//) @@ -840,10 +834,9 @@ sub do_defs } elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ || /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ || /^DECLARE_PEM_rw_const\s*\(\s*(\w*)\s*,/ ) { - # Things not in Win16 $def .= "#INFO:" - .join(',',"!WIN16",@current_platforms).":" + .join(',',@current_platforms).":" .join(',',@current_algorithms).";"; $def .= "int PEM_read_$1(void);"; $def .= "int PEM_write_$1(void);"; @@ -858,10 +851,9 @@ sub do_defs } elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ || /^DECLARE_PEM_write_const\s*\(\s*(\w*)\s*,/ || /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) { - # Things not in Win16 $def .= "#INFO:" - .join(',',"!WIN16",@current_platforms).":" + .join(',',@current_platforms).":" .join(',',@current_algorithms).";"; $def .= "int PEM_write_$1(void);"; $def .= @@ -873,10 +865,9 @@ sub do_defs next; } elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ || /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) { - # Things not in Win16 $def .= "#INFO:" - .join(',',"!WIN16",@current_platforms).":" + .join(',',@current_platforms).":" .join(',',@current_algorithms).";"; $def .= "int PEM_read_$1(void);"; $def .= @@ -906,9 +897,15 @@ sub do_defs "EXPORT_VAR_AS_FUNCTION", "FUNCTION"); } elsif (/^\s*DECLARE_DEPRECATED\s*\(\s*(\w*(\s|\*|\w)*)/) { - $def .= "$1(void);"; $parens = count_parens($_); - next; + if ($parens == 0) { + $def .= "$1(void);"; + } else { + $stored_multiline = $_; + chomp $stored_multiline; + print STDERR "DEBUG: Found multiline DEPRECATED starting with: $stored_multiline\n" if $debug; + next; + } } elsif ($tag{'CONST_STRICT'} != 1) { if (/\{|\/\*|\([^\)]*$/) { $line = $_; @@ -982,8 +979,7 @@ sub do_defs $a .= ",RC2" if($s =~ /EVP_rc2/); $a .= ",RC4" if($s =~ /EVP_rc4/); $a .= ",RC5" if($s =~ /EVP_rc5/); - $a .= ",RIPEMD" if($s =~ /EVP_ripemd/); - $a .= ",SHA" if($s =~ /EVP_sha/); + $a .= ",RMD160" if($s =~ /EVP_ripemd/); $a .= ",RSA" if($s =~ /EVP_(Open|Seal)(Final|Init)/); $a .= ",RSA" if($s =~ /PEM_Seal(Final|Init|Update)/); $a .= ",RSA" if($s =~ /RSAPrivateKey/); @@ -1013,7 +1009,7 @@ sub do_defs # Prune the returned symbols delete $syms{"bn_dump1"}; - $platform{"BIO_s_log"} .= ",!WIN32,!WIN16,!macintosh"; + $platform{"BIO_s_log"} .= ",!WIN32,!macintosh"; $platform{"PEM_read_NS_CERT_SEQ"} = "VMS"; $platform{"PEM_write_NS_CERT_SEQ"} = "VMS"; @@ -1160,14 +1156,13 @@ sub is_valid if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; } if ($keyword eq "VMS" && $VMS) { return 1; } if ($keyword eq "WIN32" && $W32) { return 1; } - if ($keyword eq "WIN16" && $W16) { return 1; } if ($keyword eq "WINNT" && $NT) { return 1; } if ($keyword eq "OS2" && $OS2) { return 1; } # Special platforms: # EXPORT_VAR_AS_FUNCTION means that global variables # will be represented as functions. This currently # only happens on VMS-VAX. - if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32 || $W16)) { + if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32)) { return 1; } if ($keyword eq "OPENSSL_FIPSCAPABLE") { @@ -1191,19 +1186,19 @@ sub is_valid if ($keyword eq "MD4" && $no_md4) { return 0; } if ($keyword eq "MD5" && $no_md5) { return 0; } if ($keyword eq "SHA" && $no_sha) { return 0; } - if ($keyword eq "RIPEMD" && $no_ripemd) { return 0; } + if ($keyword eq "RMD160" && $no_ripemd) { return 0; } if ($keyword eq "MDC2" && $no_mdc2) { return 0; } if ($keyword eq "WHIRLPOOL" && $no_whirlpool) { return 0; } if ($keyword eq "RSA" && $no_rsa) { return 0; } if ($keyword eq "DSA" && $no_dsa) { return 0; } if ($keyword eq "DH" && $no_dh) { return 0; } if ($keyword eq "EC" && $no_ec) { return 0; } - if ($keyword eq "ECDSA" && $no_ecdsa) { return 0; } - if ($keyword eq "ECDH" && $no_ecdh) { return 0; } - if ($keyword eq "HMAC" && $no_hmac) { return 0; } if ($keyword eq "AES" && $no_aes) { return 0; } if ($keyword eq "CAMELLIA" && $no_camellia) { return 0; } if ($keyword eq "SEED" && $no_seed) { return 0; } + if ($keyword eq "SCRYPT" && $no_scrypt) { return 0; } + if ($keyword eq "CHACHA" && $no_chacha) { return 0; } + if ($keyword eq "POLY1305" && $no_poly1305) { return 0; } if ($keyword eq "EVP" && $no_evp) { return 0; } if ($keyword eq "LHASH" && $no_lhash) { return 0; } if ($keyword eq "STACK" && $no_stack) { return 0; } @@ -1212,14 +1207,12 @@ sub is_valid if ($keyword eq "BIO" && $no_bio) { return 0; } if ($keyword eq "COMP" && $no_comp) { return 0; } if ($keyword eq "DSO" && $no_dso) { return 0; } - if ($keyword eq "KRB5" && $no_krb5) { return 0; } if ($keyword eq "ENGINE" && $no_engine) { return 0; } if ($keyword eq "HW" && $no_hw) { return 0; } if ($keyword eq "FP_API" && $no_fp_api) { return 0; } if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; } - if ($keyword eq "GMP" && $no_gmp) { return 0; } + if ($keyword eq "SCT" && $no_sct) { return 0; } if ($keyword eq "RFC3779" && $no_rfc3779) { return 0; } - if ($keyword eq "TLSEXT" && $no_tlsext) { return 0; } if ($keyword eq "PSK" && $no_psk) { return 0; } if ($keyword eq "CMS" && $no_cms) { return 0; } if ($keyword eq "EC_NISTP_64_GCC_128" && $no_nistp_gcc) @@ -1235,6 +1228,7 @@ sub is_valid if ($keyword eq "SRTP" && $no_srtp) { return 0; } if ($keyword eq "UNIT_TEST" && $no_unit_test) { return 0; } if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; } + if ($keyword eq "OCB" && $no_ocb) { return 0; } # Nothing recognise as true return 1; @@ -1310,27 +1304,28 @@ sub print_def_file my $version = get_version(); my $what = "OpenSSL: implementation of Secure Socket Layer"; my $description = "$what $version, $name - http://$http_vendor"; + my $prevsymversion = "", $prevprevsymversion = ""; - if ($W32) - { $libname.="32"; } - elsif ($W16) - { $libname.="16"; } - elsif ($OS2) - { # DLL names should not clash on the whole system. - # However, they should not have any particular relationship - # to the name of the static library. Chose descriptive names - # (must be at most 8 chars). - my %translate = (ssl => 'open_ssl', crypto => 'cryptssl'); - $libname = $translate{$name} || $name; - $liboptions = < 'open_ssl', crypto => 'cryptssl'); + $libname = $translate{$name} || $name; + $liboptions = <) { chop; @@ -1428,7 +1448,13 @@ sub load_numbers $ret{$a[0]}=$a[1]; $num_noinfo++; } else { - $ret{$a[0]}=$a[1]."\\".$a[2]; # \\ is a special marker + #Sanity check the version number + if (defined $prevversion) { + check_version_lte($prevversion, $a[2]); + } + check_version_lte($a[2], $currversion); + $prevversion = $a[2]; + $ret{$a[0]}=$a[1]."\\".$a[2]."\\".$a[3]; # \\ is a special marker } $max_num = $a[1] if $a[1] > $max_num; $prev=$a[0]; @@ -1577,3 +1603,133 @@ sub count_parens return $open - $close; } +#Parse opensslv.h to get the current version number. Also work out the base +#version, i.e. the lowest version number that is binary compatible with this +#version +sub get_openssl_version() +{ + open (IN, "include/openssl/opensslv.h") || die "Can't open opensslv.h"; + + while() { + if (/OPENSSL_VERSION_TEXT\s+"OpenSSL (\d\.\d\.)(\d[a-z]*)(-| )/) { + my $suffix = $2; + my $baseversion = $1 =~ s/\./_/gr; + close IN; + return ($baseversion."0", $baseversion.$suffix); + } + } + die "Can't find OpenSSL version number\n"; +} + +#Given an OpenSSL version number, calculate the next version number. If the +#version number gets to a.b.czz then we go to a.b.(c+1) +sub get_next_version() +{ + my $thisversion = shift; + + my ($base, $letter) = $thisversion =~ /^(\d_\d_\d)([a-z]{0,2})$/; + + if ($letter eq "zz") { + my $lastnum = substr($base, -1); + return substr($base, 0, length($base)-1).(++$lastnum); + } + return $base.get_next_letter($letter); +} + +#Given the letters off the end of an OpenSSL version string, calculate what +#the letters for the next release would be. +sub get_next_letter() +{ + my $thisletter = shift; + my $baseletter = ""; + my $endletter; + + if ($thisletter eq "") { + return "a"; + } + if ((length $thisletter) > 1) { + ($baseletter, $endletter) = $thisletter =~ /([a-z]+)([a-z])/; + } else { + $endletter = $thisletter; + } + + if ($endletter eq "z") { + return $thisletter."a"; + } else { + return $baseletter.(++$endletter); + } +} + +#Check if a version is less than or equal to the current version. Its a fatal +#error if not. They must also only differ in letters, or the last number (i.e. +#the first two numbers must be the same) +sub check_version_lte() +{ + my ($testversion, $currversion) = @_; + my $lentv; + my $lencv; + my $cvbase; + + my ($cvnums) = $currversion =~ /^(\d_\d_\d)[a-z]*$/; + my ($tvnums) = $testversion =~ /^(\d_\d_\d)[a-z]*$/; + + #Die if we can't parse the version numbers or they don't look sane + die "Invalid version number: $testversion and $currversion\n" + if (!defined($cvnums) || !defined($tvnums) + || length($cvnums) != 5 + || length($tvnums) != 5); + + #If the base versions (without letters) don't match check they only differ + #in the last number + if ($cvnums ne $tvnums) { + die "Invalid version number: $testversion " + ."for current version $currversion\n" + if (substr($cvnums, -1) < substr($tvnums, -1) + || substr($cvnums, 0, 4) ne substr($tvnums, 0, 4)); + return; + } + #If we get here then the base version (i.e. the numbers) are the same - they + #only differ in the letters + + $lentv = length $testversion; + $lencv = length $currversion; + + #If the testversion has more letters than the current version then it must + #be later (or malformed) + if ($lentv > $lencv) { + die "Invalid version number: $testversion " + ."is greater than $currversion\n"; + } + + #Get the last letter from the current version + my ($cvletter) = $currversion =~ /([a-z])$/; + if (defined $cvletter) { + ($cvbase) = $currversion =~ /(\d_\d_\d[a-z]*)$cvletter$/; + } else { + $cvbase = $currversion; + } + die "Unable to parse version number $currversion" if (!defined $cvbase); + my $tvbase; + my ($tvletter) = $testversion =~ /([a-z])$/; + if (defined $tvletter) { + ($tvbase) = $testversion =~ /(\d_\d_\d[a-z]*)$tvletter$/; + } else { + $tvbase = $testversion; + } + die "Unable to parse version number $testversion" if (!defined $tvbase); + + if ($lencv > $lentv) { + #If current version has more letters than testversion then testversion + #minus the final letter must be a substring of the current version + die "Invalid version number $testversion " + ."is greater than $currversion or is invalid\n" + if (index($cvbase, $tvbase) != 0); + } else { + #If both versions have the same number of letters then they must be + #equal up to the last letter, and the last letter in testversion must + #be less than or equal to the last letter in current version. + die "Invalid version number $testversion " + ."is greater than $currversion\n" + if (($cvbase ne $tvbase) && ($tvletter gt $cvletter)); + } +}