3 # WARNING: do not edit!
\r
4 # Generated by makefile from tools\c_rehash.in
\r
5 # Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
\r
7 # Licensed under the OpenSSL license (the "License"). You may not use
\r
8 # this file except in compliance with the License. You can obtain a copy
\r
9 # in the file LICENSE in the source distribution or at
\r
10 # https://www.openssl.org/source/license.html
\r
12 # Perl c_rehash script, scan all files in a directory
\r
13 # and add symbolic links to their hash values.
\r
19 my $openssl = $ENV{OPENSSL} || "openssl";
\r
21 my $x509hash = "-subject_hash";
\r
22 my $crlhash = "-hash";
\r
24 my $symlink_exists=eval {symlink("",""); 1};
\r
25 my $removelinks = 1;
\r
28 while ( $ARGV[0] =~ /^-/ ) {
\r
29 my $flag = shift @ARGV;
\r
30 last if ( $flag eq '--');
\r
31 if ( $flag eq '-old') {
\r
32 $x509hash = "-subject_hash_old";
\r
33 $crlhash = "-hash_old";
\r
34 } elsif ( $flag eq '-h' || $flag eq '-help' ) {
\r
36 } elsif ( $flag eq '-n' ) {
\r
38 } elsif ( $flag eq '-v' ) {
\r
42 print STDERR "Usage error; try -h.\n";
\r
48 print "Usage: c_rehash [-old] [-h] [-help] [-v] [dirs...]\n";
\r
49 print " -old use old-style digest\n";
\r
50 print " -h or -help print this help text\n";
\r
51 print " -v print files removed and linked\n";
\r
56 if (defined(&Cwd::getcwd)) {
\r
63 # DOS/Win32 or Unix delimiter? Prefix our installdir, then search.
\r
64 my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':';
\r
65 $ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : "");
\r
67 if (! -x $openssl) {
\r
69 foreach (split /$path_delim/, $ENV{PATH}) {
\r
70 if (-x "$_/$openssl") {
\r
72 $openssl = "$_/$openssl";
\r
77 print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
\r
84 } elsif ($ENV{SSL_CERT_DIR}) {
\r
85 @dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
\r
87 $dirlist[0] = "$dir/certs";
\r
90 if (-d $dirlist[0]) {
\r
92 $openssl="$pwd/$openssl" if (!-x $openssl);
\r
96 foreach (@dirlist) {
\r
101 print "Skipping $_, can't write\n";
\r
110 print "Doing $_[0]\n";
\r
113 my @flist = sort readdir(DIR);
\r
115 if ( $removelinks ) {
\r
116 # Delete any existing symbolic links
\r
117 foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
\r
119 print "unlink $_" if $verbose;
\r
120 unlink $_ || warn "Can't unlink $_, $!\n";
\r
124 FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
\r
125 # Check to see if certificates and/or CRLs present.
\r
126 my ($cert, $crl) = check_file($fname);
\r
127 if (!$cert && !$crl) {
\r
128 print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
\r
131 link_hash_cert($fname) if ($cert);
\r
132 link_hash_crl($fname) if ($crl);
\r
137 my ($is_cert, $is_crl) = (0,0);
\r
141 if (/^-----BEGIN (.*)-----/) {
\r
143 if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
\r
146 } elsif ($hdr eq "X509 CRL") {
\r
148 last if ($is_cert);
\r
153 return ($is_cert, $is_crl);
\r
157 # Link a certificate to its subject name hash value, each hash is of
\r
158 # the form <hash>.<n> where n is an integer. If the hash value already exists
\r
159 # then we need to up the value of n, unless its a duplicate in which
\r
160 # case we skip the link. We check for duplicates by comparing the
\r
161 # certificate fingerprints
\r
163 sub link_hash_cert {
\r
165 $fname =~ s/'/'\\''/g;
\r
166 my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
\r
169 $fprint =~ s/^.*=//;
\r
170 $fprint =~ tr/://d;
\r
172 # Search for an unused hash filename
\r
173 while(exists $hashlist{"$hash.$suffix"}) {
\r
174 # Hash matches: if fingerprint matches its a duplicate cert
\r
175 if ($hashlist{"$hash.$suffix"} eq $fprint) {
\r
176 print STDERR "WARNING: Skipping duplicate certificate $fname\n";
\r
181 $hash .= ".$suffix";
\r
182 if ($symlink_exists) {
\r
183 print "link $fname -> $hash\n" if $verbose;
\r
184 symlink $fname, $hash || warn "Can't symlink, $!";
\r
186 print "copy $fname -> $hash\n" if $verbose;
\r
187 if (open($in, "<", $fname)) {
\r
188 if (open($out,">", $hash)) {
\r
189 print $out $_ while (<$in>);
\r
192 warn "can't open $hash for write, $!";
\r
196 warn "can't open $fname for read, $!";
\r
199 $hashlist{$hash} = $fprint;
\r
202 # Same as above except for a CRL. CRL links are of the form <hash>.r<n>
\r
204 sub link_hash_crl {
\r
206 $fname =~ s/'/'\\''/g;
\r
207 my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`;
\r
210 $fprint =~ s/^.*=//;
\r
211 $fprint =~ tr/://d;
\r
213 # Search for an unused hash filename
\r
214 while(exists $hashlist{"$hash.r$suffix"}) {
\r
215 # Hash matches: if fingerprint matches its a duplicate cert
\r
216 if ($hashlist{"$hash.r$suffix"} eq $fprint) {
\r
217 print STDERR "WARNING: Skipping duplicate CRL $fname\n";
\r
222 $hash .= ".r$suffix";
\r
223 if ($symlink_exists) {
\r
224 print "link $fname -> $hash\n" if $verbose;
\r
225 symlink $fname, $hash || warn "Can't symlink, $!";
\r
227 print "cp $fname -> $hash\n" if $verbose;
\r
228 system ("cp", $fname, $hash);
\r
229 warn "Can't copy, $!" if ($? >> 8) != 0;
\r
231 $hashlist{$hash} = $fprint;
\r