Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix file operations in c_rehash.
CVE-2022-2068

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
  • Loading branch information
faramir-dev authored and mattcaswell committed Jun 20, 2022
1 parent abebcec commit 2c9c358
Showing 1 changed file with 52 additions and 54 deletions.
106 changes: 52 additions & 54 deletions tools/c_rehash.in
Expand Up @@ -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";
}
}
Expand All @@ -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(<IN>) {

open(my $in, "<", $fname);
while(<$in>) {
if (/^-----BEGIN (.*)-----/) {
my $hdr = $1;
if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
Expand All @@ -148,7 +174,7 @@ sub check_file {
}
}
}
close IN;
close $in;
return ($is_cert, $is_crl);
}

Expand Down Expand Up @@ -177,51 +203,22 @@ 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 <hash>.r<n>

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;
Expand All @@ -231,22 +228,23 @@ sub link_hash_crl {
$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;
}

0 comments on commit 2c9c358

Please sign in to comment.