mirror of
https://github.com/openssl/openssl.git
synced 2024-11-28 04:25:31 +08:00
Fix c_rehash script, add -fingerprint option to crl.
This commit is contained in:
parent
0d3b0afe9e
commit
439df5087f
6
CHANGES
6
CHANGES
@ -4,6 +4,12 @@
|
||||
|
||||
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
|
||||
|
||||
*) Enhance c_rehash script. Old version would mishandle certificates
|
||||
with the same subject name hash and wouldn't handle CRLs at all.
|
||||
Added -fingerprint option to crl utility, to support new c_rehash
|
||||
features.
|
||||
[Steve Henson]
|
||||
|
||||
*) Eliminate non-ANSI declarations in crypto.h and stack.h.
|
||||
[Ulf Möller]
|
||||
|
||||
|
@ -890,12 +890,13 @@ EOF
|
||||
### (system 'make depend') == 0 or exit $? if $depflags ne "";
|
||||
# Run "make depend" manually if you want to be able to delete
|
||||
# the source code files of ciphers you left out.
|
||||
&dofile("tools/c_rehash",$openssldir,'^DIR=', 'DIR=%s',);
|
||||
if ( $perl =~ m@^/@) {
|
||||
&dofile("tools/c_rehash",$perl,'^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";');
|
||||
&dofile("apps/der_chop",$perl,'^#!/', '#!%s');
|
||||
&dofile("apps/CA.pl",$perl,'^#!/', '#!%s');
|
||||
} else {
|
||||
# No path for Perl known ...
|
||||
&dofile("tools/c_rehash",'/usr/local/bin/perl','^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";');
|
||||
&dofile("apps/der_chop",'/usr/local/bin/perl','^#!/', '#!%s');
|
||||
&dofile("apps/CA.pl",'/usr/local/bin/perl','^#!/', '#!%s');
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ dclean:
|
||||
|
||||
rehash: rehash.time
|
||||
rehash.time: certs
|
||||
@(OPENSSL="`pwd`/apps/openssl"; export OPENSSL; sh tools/c_rehash certs)
|
||||
@(OPENSSL="`pwd`/apps/openssl"; export OPENSSL; $(PERL) tools/c_rehash certs)
|
||||
touch rehash.time
|
||||
|
||||
test: tests
|
||||
|
@ -135,7 +135,7 @@ $(DLIBCRYPTO):
|
||||
$(PROGRAM): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
|
||||
$(RM) $(PROGRAM)
|
||||
$(CC) -o $(PROGRAM) $(CFLAGS) $(PROGRAM).o $(E_OBJ) $(PEX_LIBS) $(LIBSSL) $(LIBCRYPTO) $(EX_LIBS)
|
||||
@(cd ..; OPENSSL="`pwd`/apps/openssl"; export OPENSSL; sh tools/c_rehash certs)
|
||||
@(cd ..; OPENSSL="`pwd`/apps/openssl"; export OPENSSL; $(PERL) tools/c_rehash certs)
|
||||
|
||||
progs.h: progs.pl
|
||||
$(PERL) progs.pl $(E_EXE) >progs.h
|
||||
|
29
apps/crl.c
29
apps/crl.c
@ -104,6 +104,7 @@ int MAIN(int argc, char **argv)
|
||||
int informat,outformat;
|
||||
char *infile=NULL,*outfile=NULL;
|
||||
int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
|
||||
int fingerprint = 0;
|
||||
char **pp,buf[256];
|
||||
X509_STORE *store = NULL;
|
||||
X509_STORE_CTX ctx;
|
||||
@ -111,6 +112,7 @@ int MAIN(int argc, char **argv)
|
||||
X509_OBJECT xobj;
|
||||
EVP_PKEY *pkey;
|
||||
int do_ver = 0;
|
||||
const EVP_MD *md_alg,*digest=EVP_md5();
|
||||
|
||||
apps_startup();
|
||||
|
||||
@ -183,6 +185,13 @@ int MAIN(int argc, char **argv)
|
||||
nextupdate= ++num;
|
||||
else if (strcmp(*argv,"-noout") == 0)
|
||||
noout= ++num;
|
||||
else if (strcmp(*argv,"-fingerprint") == 0)
|
||||
fingerprint= ++num;
|
||||
else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
|
||||
{
|
||||
/* ok */
|
||||
digest=md_alg;
|
||||
}
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err,"unknown option %s\n",*argv);
|
||||
@ -274,6 +283,26 @@ bad:
|
||||
BIO_printf(bio_out,"NONE");
|
||||
BIO_printf(bio_out,"\n");
|
||||
}
|
||||
if (fingerprint == i)
|
||||
{
|
||||
int j;
|
||||
unsigned int n;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
|
||||
if (!X509_CRL_digest(x,digest,md,&n))
|
||||
{
|
||||
BIO_printf(bio_err,"out of memory\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_out,"%s Fingerprint=",
|
||||
OBJ_nid2sn(EVP_MD_type(digest)));
|
||||
for (j=0; j<(int)n; j++)
|
||||
{
|
||||
BIO_printf(bio_out,"%02X%c",md[j],
|
||||
(j+1 == (int)n)
|
||||
?'\n':':');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -660,6 +660,8 @@ int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
|
||||
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
|
||||
|
||||
int X509_digest(X509 *data,const EVP_MD *type,unsigned char *md,unsigned int *len);
|
||||
int X509_CRL_digest(X509_CRL *data,const EVP_MD *type,unsigned char *md,unsigned int *len);
|
||||
int X509_REQ_digest(X509_REQ *data,const EVP_MD *type,unsigned char *md,unsigned int *len);
|
||||
int X509_NAME_digest(X509_NAME *data,const EVP_MD *type,
|
||||
unsigned char *md,unsigned int *len);
|
||||
#endif
|
||||
|
@ -417,6 +417,18 @@ int X509_digest(X509 *data, const EVP_MD *type, unsigned char *md,
|
||||
return(ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len));
|
||||
}
|
||||
|
||||
int X509_CRL_digest(X509_CRL *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
return(ASN1_digest((int (*)())i2d_X509_CRL,type,(char *)data,md,len));
|
||||
}
|
||||
|
||||
int X509_REQ_digest(X509_REQ *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
return(ASN1_digest((int (*)())i2d_X509_REQ,type,(char *)data,md,len));
|
||||
}
|
||||
|
||||
int X509_NAME_digest(X509_NAME *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
|
@ -1,61 +1,148 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# redo the hashes for the certificates in your cert path or the ones passed
|
||||
# on the command line.
|
||||
#
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
if [ "$OPENSSL"x = "x" -o ! -x "$OPENSSL" ]; then
|
||||
OPENSSL='openssl'
|
||||
export OPENSSL
|
||||
fi
|
||||
DIR=/usr/local/ssl
|
||||
PATH=$DIR/bin:$PATH
|
||||
|
||||
if [ ! -f "$OPENSSL" ]; then
|
||||
found=0
|
||||
for dir in . `echo $PATH | sed -e 's/:/ /g'`; do
|
||||
if [ -f "$dir/$OPENSSL" ]; then
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ $found = 0 ]; then
|
||||
echo "c_rehash: rehashing skipped ('openssl' program not available)" 1>&2
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
# Perl c_rehash script, scan all files in a directory
|
||||
# and add symbolic links to their hash values.
|
||||
|
||||
SSL_DIR=$DIR/certs
|
||||
my $openssl;
|
||||
|
||||
if [ "$*" = "" ]; then
|
||||
CERTS=${*:-${SSL_CERT_DIR:-$SSL_DIR}}
|
||||
else
|
||||
CERTS=$*
|
||||
fi
|
||||
my $dir;
|
||||
|
||||
if(defined $ENV{OPENSSL}) {
|
||||
$openssl = $ENV{OPENSSL};
|
||||
} else {
|
||||
$openssl = "openssl";
|
||||
$ENV{OPENSSL} = $openssl;
|
||||
}
|
||||
|
||||
$ENV{PATH} .= ":$dir/bin";
|
||||
|
||||
if(! -f $openssl) {
|
||||
my $found = 0;
|
||||
foreach (split /:/, $ENV{PATH}) {
|
||||
if(-f "$_/$openssl") {
|
||||
$found = 1;
|
||||
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 /:/, $ENV{SSL_CERT_DIR};
|
||||
} else {
|
||||
$dirlist[0] = "$dir/certs";
|
||||
}
|
||||
|
||||
|
||||
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$/} @flist) {
|
||||
# Check to see if certificates and/or CRLs present.
|
||||
my ($cert, $crl) = check_file($fname);
|
||||
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_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
|
||||
|
||||
sub link_hash_cert {
|
||||
my $fname = $_[0];
|
||||
my ($hash, $fprint) = `$openssl x509 -hash -fingerprint -noout -in $fname`;
|
||||
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";
|
||||
return;
|
||||
}
|
||||
$suffix++;
|
||||
}
|
||||
$hash .= ".$suffix";
|
||||
print "$fname => $hash\n";
|
||||
symlink $fname, $hash;
|
||||
$hashlist{$hash} = $fprint;
|
||||
}
|
||||
|
||||
# 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) = `$openssl crl -hash -fingerprint -noout -in $fname`;
|
||||
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 $fname, $hash;
|
||||
$hashlist{$hash} = $fprint;
|
||||
}
|
||||
|
||||
IFS=': '
|
||||
for i in $CERTS
|
||||
do
|
||||
(
|
||||
IFS=' '
|
||||
if [ -d $i -a -w $i ]; then
|
||||
cd $i
|
||||
echo "Doing $i"
|
||||
for i in *.pem
|
||||
do
|
||||
if [ $i != '*.pem' ]; then
|
||||
h=`$OPENSSL x509 -hash -noout -in $i`
|
||||
if [ "x$h" = "x" ]; then
|
||||
echo $i does not contain a certificate
|
||||
else
|
||||
if [ -f $h.0 ]; then
|
||||
/bin/rm -f $h.0
|
||||
fi
|
||||
echo "$i => $h.0"
|
||||
ln -s $i $h.0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
)
|
||||
done
|
||||
|
Loading…
Reference in New Issue
Block a user