aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2000-05-18 00:33:00 +0000
committerDr. Stephen Henson <steve@openssl.org>2000-05-18 00:33:00 +0000
commit439df5087f012e65b80c13ade8953778cc0b4704 (patch)
treeed0aa5c1d53f8b9b24b7c3923624a64067d68c7f
parent0d3b0afe9e59962f92b0cc6c63fc65a8e8dbc0de (diff)
downloadopenssl-439df5087f012e65b80c13ade8953778cc0b4704.tar.gz
Fix c_rehash script, add -fingerprint option to crl.
-rw-r--r--CHANGES6
-rwxr-xr-xConfigure3
-rw-r--r--Makefile.org2
-rw-r--r--apps/Makefile.ssl2
-rw-r--r--apps/crl.c29
-rw-r--r--crypto/x509/x509.h2
-rw-r--r--crypto/x509/x_all.c12
-rw-r--r--tools/c_rehash.in209
8 files changed, 201 insertions, 64 deletions
diff --git a/CHANGES b/CHANGES
index ab8f8531fa..bb2e353d59 100644
--- a/CHANGES
+++ b/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]
diff --git a/Configure b/Configure
index 1de6c3fb10..3e86c05a87 100755
--- a/Configure
+++ b/Configure
@@ -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');
}
diff --git a/Makefile.org b/Makefile.org
index 5ca1493925..cf98fb515e 100644
--- a/Makefile.org
+++ b/Makefile.org
@@ -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
diff --git a/apps/Makefile.ssl b/apps/Makefile.ssl
index fef670db23..0d0cd888b4 100644
--- a/apps/Makefile.ssl
+++ b/apps/Makefile.ssl
@@ -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
diff --git a/apps/crl.c b/apps/crl.c
index 338f46d97c..b1c3325f21 100644
--- a/apps/crl.c
+++ b/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':':');
+ }
+ }
}
}
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index d2ad77815e..a0aaad8366 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -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
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index d2bf3c8e1c..b67ca243dc 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -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)
{
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
index cc3b65871f..baec7c14ff 100644
--- a/tools/c_rehash.in
+++ b/tools/c_rehash.in
@@ -1,61 +1,148 @@
-#!/bin/sh
-#
-# redo the hashes for the certificates in your cert path or the ones passed
-# on the command line.
-#
-
-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
-
-SSL_DIR=$DIR/certs
-
-if [ "$*" = "" ]; then
- CERTS=${*:-${SSL_CERT_DIR:-$SSL_DIR}}
-else
- CERTS=$*
-fi
-
-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
+#!/usr/local/bin/perl
+
+
+# Perl c_rehash script, scan all files in a directory
+# and add symbolic links to their hash values.
+
+my $openssl;
+
+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;
+}
+