diff -up openssl-3.0.1/tools/c_rehash.in.cve20222068 openssl-3.0.1/tools/c_rehash.in --- openssl-3.0.1/tools/c_rehash.in.cve20222068 2022-06-22 13:15:57.347421765 +0200 +++ openssl-3.0.1/tools/c_rehash.in 2022-06-22 13:16:14.797576250 +0200 @@ -104,18 +104,41 @@ foreach (@dirlist) { } exit($errorcount); +sub copy_file { + my ($src_fname, $dst_fname) = @_; + + if (open(my $in, "<", $src_fname)) { + if (open(my $out, ">", $dst_fname)) { + print $out $_ while (<$in>); + close $out; + } else { + warn "Cannot open $dst_fname for write, $!"; + } + close $in; + } else { + warn "Cannot open $src_fname for read, $!"; + } +} + sub hash_dir { + my $dir = shift; my %hashlist; - print "Doing $_[0]\n"; - chdir $_[0]; - opendir(DIR, "."); + + print "Doing $dir\n"; + + if (!chdir $dir) { + print STDERR "WARNING: Cannot chdir to '$dir', $!\n"; + return; + } + + opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n"; my @flist = sort readdir(DIR); closedir DIR; if ( $removelinks ) { # Delete any existing symbolic links foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) { if (-l $_) { - print "unlink $_" if $verbose; + print "unlink $_\n" if $verbose; unlink $_ || warn "Can't unlink $_, $!\n"; } } @@ -130,13 +153,16 @@ sub hash_dir { link_hash_cert($fname) if ($cert); link_hash_crl($fname) if ($crl); } + + chdir $pwd; } sub check_file { my ($is_cert, $is_crl) = (0,0); my $fname = $_[0]; - open IN, $fname; - while() { + + open(my $in, "<", $fname); + while(<$in>) { if (/^-----BEGIN (.*)-----/) { my $hdr = $1; if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) { @@ -148,7 +174,7 @@ sub check_file { } } } - close IN; + close $in; return ($is_cert, $is_crl); } @@ -177,76 +203,49 @@ sub compute_hash { # certificate fingerprints sub link_hash_cert { - my $fname = $_[0]; - my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash, - "-fingerprint", "-noout", - "-in", $fname); - chomp $hash; - chomp $fprint; - return if !$hash; - $fprint =~ s/^.*=//; - $fprint =~ tr/://d; - my $suffix = 0; - # Search for an unused hash filename - while(exists $hashlist{"$hash.$suffix"}) { - # Hash matches: if fingerprint matches its a duplicate cert - if ($hashlist{"$hash.$suffix"} eq $fprint) { - print STDERR "WARNING: Skipping duplicate certificate $fname\n"; - return; - } - $suffix++; - } - $hash .= ".$suffix"; - if ($symlink_exists) { - print "link $fname -> $hash\n" if $verbose; - symlink $fname, $hash || warn "Can't symlink, $!"; - } else { - print "copy $fname -> $hash\n" if $verbose; - if (open($in, "<", $fname)) { - if (open($out,">", $hash)) { - print $out $_ while (<$in>); - close $out; - } else { - warn "can't open $hash for write, $!"; - } - close $in; - } else { - warn "can't open $fname for read, $!"; - } - } - $hashlist{$hash} = $fprint; + link_hash($_[0], 'cert'); } # Same as above except for a CRL. CRL links are of the form .r sub link_hash_crl { - my $fname = $_[0]; - my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash, + link_hash($_[0], 'crl'); +} + +sub link_hash { + my ($fname, $type) = @_; + my $is_cert = $type eq 'cert'; + + my ($hash, $fprint) = compute_hash($openssl, + $is_cert ? "x509" : "crl", + $is_cert ? $x509hash : $crlhash, "-fingerprint", "-noout", "-in", $fname); chomp $hash; + $hash =~ s/^.*=// if !$is_cert; chomp $fprint; return if !$hash; $fprint =~ s/^.*=//; $fprint =~ tr/://d; my $suffix = 0; # Search for an unused hash filename - while(exists $hashlist{"$hash.r$suffix"}) { + my $crlmark = $is_cert ? "" : "r"; + while(exists $hashlist{"$hash.$crlmark$suffix"}) { # Hash matches: if fingerprint matches its a duplicate cert - if ($hashlist{"$hash.r$suffix"} eq $fprint) { - print STDERR "WARNING: Skipping duplicate CRL $fname\n"; + if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) { + my $what = $is_cert ? 'certificate' : 'CRL'; + print STDERR "WARNING: Skipping duplicate $what $fname\n"; return; } $suffix++; } - $hash .= ".r$suffix"; + $hash .= ".$crlmark$suffix"; if ($symlink_exists) { print "link $fname -> $hash\n" if $verbose; symlink $fname, $hash || warn "Can't symlink, $!"; } else { - print "cp $fname -> $hash\n" if $verbose; - system ("cp", $fname, $hash); - warn "Can't copy, $!" if ($? >> 8) != 0; + print "copy $fname -> $hash\n" if $verbose; + copy_file($fname, $hash); } $hashlist{$hash} = $fprint; }