smeserver-base/root/etc/e-smith/templates/home/e-smith/ssl.crt

121 lines
4.6 KiB
Plaintext

{
use constant KEYLIFEINDAYS => $modSSL{KeyLifeInDays} || 365;
use esmith::ssl;
use Date::Parse;
use Cwd;
use Net::IP qw(ip_is_ipv4 ip_is_ipv6);
my $here = getcwd;
my $Country = $modSSL{Country} || "--";
my $State = $modSSL{State} || "----";
my $FQDN = "$SystemName.$DomainName";
my $commonName = $modSSL{CommonName} || $FQDN;
my $crt = "/home/e-smith/ssl.crt/$FQDN.crt";
my $key = "/home/e-smith/ssl.key/$FQDN.key";
my $defaultCity = $ldap{defaultCity};
my $defaultCompany = $ldap{defaultCompany};
my $defaultDepartment = $ldap{defaultDepartment};
my $email = "admin\@$DomainName";
my @subjectAlt = `/sbin/e-smith/generate-subjectaltnames`;
chomp @subjectAlt;
our $subjectAltName = "";
my $i=0;
for my $elem (@subjectAlt) {
$subjectAltName .= "," if $i>0;
$i++;
if (ip_is_ipv4($elem) || ip_is_ipv6($elem) ){
$subjectAltName .= "IP Address:$elem";
next;
}
$subjectAltName .= "DNS:$elem";
}
$subjectAltName = ( $subjectAltName eq "DNS: ")? "": $subjectAltName;
chomp $subjectAltName;
# crop fields that are too long for X509:
$Country = substr($Country, 0, 2);
$defaultCity = substr($defaultCity, 0, 128);
$defaultCompany = substr($defaultCompany, 0, 64);
$defaultDepartment = substr($defaultDepartment, 0, 64);
$email = substr($email, 0, 64);
$commonName = substr($commonName, 0, 64);
# if self-signed certificate files exists, is a certificate, and is still valid
if ( cert_exists_good_size )
{
# check expiry date, if less than 2 days from now we update it.
my $expire = `openssl x509 -enddate -noout -in $crt`;
$expire =~ s/^notAfter=//;
$expire = str2time($expire);
my $ttl_days = ($expire - time()) / 60 / 60 / 24;
# check the cert and the key are related, if key has been changed, then we need to change the cert
my $crt_md5 = `openssl x509 -noout -modulus -in $crt | openssl md5`;
my $key_md5 = `openssl rsa -noout -modulus -in $key | openssl md5`;
if ( ($ttl_days > 2) && ( "$crt_md5" eq "$key_md5" ) ) {
my $expected_issuer = '/C='.$Country .
'/ST='.$State;
$expected_issuer .= '/L=' . ($defaultCity ? $defaultCity : 'Default City');
$expected_issuer .= '/O=' . ($defaultCompany ? $defaultCompany : 'Default Company Ltd');
$expected_issuer .= "/OU=$defaultDepartment" if $defaultDepartment;
$expected_issuer .= "/CN=$commonName" .
"/emailAddress=$email";
my $issuer = `openssl x509 -issuer -noout -in $crt`;
chomp $issuer;
$issuer =~ s/^issuer= //;
my $signatureAlg = `openssl x509 -text -noout -in $crt | grep "Signature Algorithm" | head -1`;
chomp $signatureAlg;
$signatureAlg =~ s/^ *Signature Algorithm: //;
# Test for expected subjectAltName
# openssl x509 -text -noout -in /etc/dehydrated/certs/domain/cert.pem | sed -ne '/X509v3 Subject Alternative Name/{ N;s/^.*\n//;:a;s/^\( *\)\(.*\), /\2,\1/;ta;p;q; }'
$expected_subjectAltName = `openssl x509 -text -noout -in $crt | sed -ne '/X509v3 Subject Alternative Name/{ N;s/^.*\\n//;:a;s/^\\( *\\)\\(.*\\), /\\2,\\1/;ta;p;q; }'`;
chomp $expected_subjectAltName;
if (
($issuer eq $expected_issuer)
&& ($signatureAlg ne "sha1WithRSAEncryption")
&& ($subjectAltName eq $expected_subjectAltName)
)
{
# Old key file is still good. Read it out - processTemplate will work
# out that it hasn't changed, and leave the old one in place
open(C, "$crt") or die "Couldn't open crt file: $!";
my @crt = <C>;
chomp @crt;
$OUT = join "\n", @crt;
close(C);
return;
}
}
}
# go to somewhere private and safe where we can run programs
# as root
unless (-e "/tmp/ssl")
{
mkdir "/tmp/ssl", 0700;
}
chdir "/tmp/ssl" or die "Couldn't change to secure directory: $!";
$SIG{ALRM} = sub { die "whoops, $program pipe broke" };
unless (open(SSL,"-|"))
{
# child
exec("/usr/bin/openssl",
qw(req -new -key),
$key,
qw( -sha256 -x509 -days), KEYLIFEINDAYS,
qw(-set_serial), time(),
qw(-extensions v3_req),
qw(-config), "/etc/openssl.conf"
)
|| die "can't exec program: $!";
# NOTREACHED
}
while (<SSL>)
{
$OUT .= $_;
}
close(SSL) or die "Closing openssl pipe reported: $!";
chdir $here;
}