Thread [LWP] validiert Zertifikat nicht (Strawberry Win32) (10 answers)
Opened by GwenDragon at 2014-04-14 14:34

GwenDragon
 2014-05-25 12:33
#175731 #175731
User since
2005-01-17
14532 Artikel
Admin1
[Homepage]
user image
Peim Parameter SSL_ca_file wird üblicherweise ein Zertifikatsbündel (Datei, die mehrere PEM-koderte CA-Zertifikate, jedes durch eine Leerzeile getrennt, beinhaltet) angegeben, das alle zu überprüfenden Zertifikate beinhaltet.

Wenn ein durch SSL_ca_path angegebenes Verzeichnis verwendet wird, müssen die Zertifikate als einzelne Dateien (PEM-kodiert) vorliegen, es muss für jede eine Hashdatei existieren, welche durch das Programm c_rehash erzeugt wurde.

Syntax: c_rehash ~/.cert/www.example.com/

Siehe auch https://www.openssl.org/docs/ssl/SSL_CTX_load_veri...

c_rehash:
more (50.8kb):
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!perl

# Perl c_rehash script, scan all files in a directory
# and add symbolic links to their hash values.

my $openssl;

my $dir = "/usr/lib/ssl";
my $prefix = "/usr";

if(defined $ENV{OPENSSL}) {
        $openssl = $ENV{OPENSSL};
} else {
        $openssl = "openssl";
        $ENV{OPENSSL} = $openssl;
}

my $pwd;
eval "require Cwd";
if (defined(&Cwd::getcwd)) {
        $pwd=Cwd::getcwd();
} else {
        $pwd=`pwd`; chomp($pwd);
}
my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':'; # DOS/Win32 or Unix delimiter?

$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); # prefix our path

if(! -x $openssl) {
        my $found = 0;
        foreach (split /$path_delim/, $ENV{PATH}) {
                if(-x "$_/$openssl") {
                        $found = 1;
                        $openssl = "$_/$openssl";
                        last;
                }       
        }
        if($found == 0) {
                print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
                exit 0;
        }
}

if(@ARGV) {
        @dirlist = @ARGV;
} elsif($ENV{SSL_CERT_DIR}) {
        @dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
} else {
        $dirlist[0] = "$dir/certs";
}

if (-d $dirlist[0]) {
        chdir $dirlist[0];
        $openssl="$pwd/$openssl" if (!-x $openssl);
        chdir $pwd;
}

foreach (@dirlist) {
        if(-d $_ and -w $_) {
                hash_dir($_);
        }
}

sub hash_dir {
        my %hashlist;
        print "Doing $_[0]\n";
        chdir $_[0];
        opendir(DIR, ".");
        my @flist = readdir(DIR);
        # Delete any existing symbolic links
        foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
                if(-l $_) {
                        unlink $_;
                }
        }
        closedir DIR;
        FILE: foreach $fname (grep {/\.pem$|\.crt$/} @flist) {
                # Check to see if certificates and/or CRLs present.
                my ($cert, $crl) = check_file($fname);
                if(!$cert && !$crl) {
                        ($cert, $crl) = check_file("$openssl x509 -in \"$fname\" -inform der  -outform pem | ");
                        if(!$cert && !$crl) {
                                print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
                                next;
                        }
                }
                link_hash_cert($fname) if($cert);
                link_hash_cert_old($fname) if($cert);
                link_hash_crl($fname) if($crl);
        }
}

sub check_file {
        my ($is_cert, $is_crl) = (0,0);
        my $fname = $_[0];
        open IN, $fname;
        while(<IN>) {
                if(/^-----BEGIN (.*)-----/) {
                        my $hdr = $1;
                        if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
                                $is_cert = 1;
                                last if($is_crl);
                        } elsif($hdr eq "X509 CRL") {
                                $is_crl = 1;
                                last if($is_cert);
                        }
                }
        }
        close IN;
        return ($is_cert, $is_crl);
}


# 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
# then we need to up the value of n, unless its a duplicate in which
# case we skip the link. We check for duplicates by comparing the
# certificate fingerprints

use File::Temp qw/ tempfile /;
sub link_hash_cert {
                my $fname = $_[0];
                my $hashopt = $_[1] || '-subject_hash';
                $fname =~ s/'/'\\''/g;
                open my $in_fh, '<', $fname or die "can't open $fname for read";
                my $cert = eval {local $/ = undef; <$in_fh>};
                close $in_fh;
                OUTERLOOP:
                while ($cert =~ /^(-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)$/gms)
                {
                   my $part = $1;
                   my (undef, $tfile) = tempfile();
                   #my $tfile = `tempfile`;
                   chomp $tfile;
                   open my $tfile_fh, '>', $tfile or die "can't open $tfile for write";
                   print {$tfile_fh} "$part\n";
                   close $tfile_fh;

                   my ($hash, $fprint) = `"$openssl" x509 $hashopt -fingerprint -noout -in "$tfile"`;
                   chomp $hash;
                   chomp $fprint;
                   $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";
                                   unlink $tfile;
                                   next OUTERLOOP;
                           }
                           $suffix++;
                   }
                   $hash .= ".$suffix";
                   print "$fname => $hash\n";
                   $symlink_exists=eval {symlink("",""); 1};
                   if ($symlink_exists) {
                           symlink $fname, $hash;
                   } else {
                           open IN,"<$tfile" or die "can't open $tfile for read";
                           open OUT,">$hash" or die "can't open $hash for write";
                           print OUT <IN>;      # does the job for small text files
                           close OUT;
                           close IN;
                   }
                   $hashlist{$hash} = $fprint;
                   unlink $tfile;
                } ## end while ($cert =~ /^(-----BEGIN ...
}

sub link_hash_cert_old {
                link_hash_cert($_[0], '-subject_hash_old');
}

# Same as above except for a CRL. CRL links are of the form <hash>.r<n>

sub link_hash_crl {
                my $fname = $_[0];
                $fname =~ s/'/'\\''/g;
                my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
                if(!$hash || !$fprint) {
                        ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname' -inform der`;
                }
                chomp $hash;
                chomp $fprint;
                $fprint =~ s/^.*=//;
                $fprint =~ tr/://d;
                my $suffix = 0;
                # Search for an unused hash filename
                while(exists $hashlist{"$hash.r$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";
                                return;
                        }
                        $suffix++;
                }
                $hash .= ".r$suffix";
                print "$fname => $hash\n";
                $symlink_exists=eval {symlink("",""); 1};
                if ($symlink_exists) {
                        symlink $fname, $hash;
                } else {
                        system ("cp", $fname, $hash);
                }
                $hashlist{$hash} = $fprint;
}


c_rehash in OpenSSL source.

Einfach fragen, wenns wissen fehlt ;)

Editiert von GwenDragon: c_rehash hinzu, für Windows wg. tempfile angepasst
Last edited: 2014-05-25 13:25:58 +0200 (CEST)
die Drachin, Gwendolyn


Unterschiedliche Perl-Versionen auf Windows (fast wie perlbrew) • Meine Perl-Artikel

View full thread [LWP] validiert Zertifikat nicht (Strawberry Win32)