source: src/router/openssl/tools/c_rehash.in @ 12238

Last change on this file since 12238 was 12238, checked in by BrainSlayer, 4 years ago

patches

File size: 3.5 KB
Line 
1#!/usr/bin/perl
2
3
4# Perl c_rehash script, scan all files in a directory
5# and add symbolic links to their hash values.
6
7my $openssl;
8
9my $dir;
10
11if(defined $ENV{OPENSSL}) {
12        $openssl = $ENV{OPENSSL};
13} else {
14        $openssl = "openssl";
15        $ENV{OPENSSL} = $openssl;
16}
17
18$ENV{PATH} .= ":$dir/bin";
19
20if(! -x $openssl) {
21        my $found = 0;
22        foreach (split /:/, $ENV{PATH}) {
23                if(-x "$_/$openssl") {
24                        $found = 1;
25                        last;
26                }       
27        }
28        if($found == 0) {
29                print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
30                exit 0;
31        }
32}
33
34if(@ARGV) {
35        @dirlist = @ARGV;
36} elsif($ENV{SSL_CERT_DIR}) {
37        @dirlist = split /:/, $ENV{SSL_CERT_DIR};
38} else {
39        $dirlist[0] = "$dir/certs";
40}
41
42
43foreach (@dirlist) {
44        if(-d $_ and -w $_) {
45                hash_dir($_);
46        }
47}
48
49sub hash_dir {
50        my %hashlist;
51        print "Doing $_[0]\n";
52        chdir $_[0];
53        opendir(DIR, ".");
54        my @flist = readdir(DIR);
55        # Delete any existing symbolic links
56        foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
57                if(-l $_) {
58                        unlink $_;
59                }
60        }
61        closedir DIR;
62        FILE: foreach $fname (grep {/\.pem$/} @flist) {
63                # Check to see if certificates and/or CRLs present.
64                my ($cert, $crl) = check_file($fname);
65                if(!$cert && !$crl) {
66                        print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
67                        next;
68                }
69                link_hash_cert($fname) if($cert);
70                link_hash_crl($fname) if($crl);
71        }
72}
73
74sub check_file {
75        my ($is_cert, $is_crl) = (0,0);
76        my $fname = $_[0];
77        open IN, $fname;
78        while(<IN>) {
79                if(/^-----BEGIN (.*)-----/) {
80                        my $hdr = $1;
81                        if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
82                                $is_cert = 1;
83                                last if($is_crl);
84                        } elsif($hdr eq "X509 CRL") {
85                                $is_crl = 1;
86                                last if($is_cert);
87                        }
88                }
89        }
90        close IN;
91        return ($is_cert, $is_crl);
92}
93
94
95# Link a certificate to its subject name hash value, each hash is of
96# the form <hash>.<n> where n is an integer. If the hash value already exists
97# then we need to up the value of n, unless its a duplicate in which
98# case we skip the link. We check for duplicates by comparing the
99# certificate fingerprints
100
101sub link_hash_cert {
102                my $fname = $_[0];
103                $fname =~ s/'/'\\''/g;
104                my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in '$fname'`;
105                chomp $hash;
106                chomp $fprint;
107                $fprint =~ s/^.*=//;
108                $fprint =~ tr/://d;
109                my $suffix = 0;
110                # Search for an unused hash filename
111                while(exists $hashlist{"$hash.$suffix"}) {
112                        # Hash matches: if fingerprint matches its a duplicate cert
113                        if($hashlist{"$hash.$suffix"} eq $fprint) {
114                                print STDERR "WARNING: Skipping duplicate certificate $fname\n";
115                                return;
116                        }
117                        $suffix++;
118                }
119                $hash .= ".$suffix";
120                print "$fname => $hash\n";
121                $symlink_exists=eval {symlink("",""); 1};
122                if ($symlink_exists) {
123                        symlink $fname, $hash;
124                } else {
125                        system ("cp", $fname, $hash);
126                }
127                $hashlist{$hash} = $fprint;
128}
129
130# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
131
132sub link_hash_crl {
133                my $fname = $_[0];
134                $fname =~ s/'/'\\''/g;
135                my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
136                chomp $hash;
137                chomp $fprint;
138                $fprint =~ s/^.*=//;
139                $fprint =~ tr/://d;
140                my $suffix = 0;
141                # Search for an unused hash filename
142                while(exists $hashlist{"$hash.r$suffix"}) {
143                        # Hash matches: if fingerprint matches its a duplicate cert
144                        if($hashlist{"$hash.r$suffix"} eq $fprint) {
145                                print STDERR "WARNING: Skipping duplicate CRL $fname\n";
146                                return;
147                        }
148                        $suffix++;
149                }
150                $hash .= ".r$suffix";
151                print "$fname => $hash\n";
152                $symlink_exists=eval {symlink("",""); 1};
153                if ($symlink_exists) {
154                        symlink $fname, $hash;
155                } else {
156                        system ("cp", $fname, $hash);
157                }
158                $hashlist{$hash} = $fprint;
159}
160
Note: See TracBrowser for help on using the repository browser.