c_rehash: Do not use shell to invoke openssl
authorTomas Mraz <tomas@openssl.org>
Tue, 26 Apr 2022 10:40:24 +0000 (12:40 +0200)
committerMatt Caswell <matt@openssl.org>
Tue, 3 May 2022 10:08:36 +0000 (11:08 +0100)
Except on VMS where it is safe.

This fixes CVE-2022-1292.

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
tools/c_rehash.in

index d51d8856d709cda39f939c1e04faeb0a31d599e6..a630773a0240834476e74a7eb049a0d22729c383 100644 (file)
@@ -152,6 +152,23 @@ sub check_file {
     return ($is_cert, $is_crl);
 }
 
     return ($is_cert, $is_crl);
 }
 
+sub compute_hash {
+    my $fh;
+    if ( $^O eq "VMS" ) {
+        # VMS uses the open through shell
+        # The file names are safe there and list form is unsupported
+        if (!open($fh, "-|", join(' ', @_))) {
+            print STDERR "Cannot compute hash on '$fname'\n";
+            return;
+        }
+    } else {
+        if (!open($fh, "-|", @_)) {
+            print STDERR "Cannot compute hash on '$fname'\n";
+            return;
+        }
+    }
+    return (<$fh>, <$fh>);
+}
 
 # Link a certificate to its subject name hash value, each hash is of
 # the form <hash>.<n> where n is an integer. If the hash value already exists
 
 # Link a certificate to its subject name hash value, each hash is of
 # the form <hash>.<n> where n is an integer. If the hash value already exists
@@ -161,10 +178,12 @@ sub check_file {
 
 sub link_hash_cert {
     my $fname = $_[0];
 
 sub link_hash_cert {
     my $fname = $_[0];
-    $fname =~ s/\"/\\\"/g;
-    my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
+    my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash,
+                                       "-fingerprint", "-noout",
+                                       "-in", $fname);
     chomp $hash;
     chomp $fprint;
     chomp $hash;
     chomp $fprint;
+    return if !$hash;
     $fprint =~ s/^.*=//;
     $fprint =~ tr/://d;
     my $suffix = 0;
     $fprint =~ s/^.*=//;
     $fprint =~ tr/://d;
     my $suffix = 0;
@@ -202,10 +221,12 @@ sub link_hash_cert {
 
 sub link_hash_crl {
     my $fname = $_[0];
 
 sub link_hash_crl {
     my $fname = $_[0];
-    $fname =~ s/'/'\\''/g;
-    my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`;
+    my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash,
+                                       "-fingerprint", "-noout",
+                                       "-in", $fname);
     chomp $hash;
     chomp $fprint;
     chomp $hash;
     chomp $fprint;
+    return if !$hash;
     $fprint =~ s/^.*=//;
     $fprint =~ tr/://d;
     my $suffix = 0;
     $fprint =~ s/^.*=//;
     $fprint =~ tr/://d;
     my $suffix = 0;