version 1.3, 2019/07/08 23:00:16
|
version 1.7, 2023/05/14 19:14:39
|
Line 72 Term::ReadKey
|
Line 72 Term::ReadKey
|
Sys::Hostname::FQDN |
Sys::Hostname::FQDN |
Locale::Country |
Locale::Country |
Crypt::OpenSSL::X509 |
Crypt::OpenSSL::X509 |
|
Crypt::X509::CRL |
|
MIME::Base64 |
DateTime::Format::x509 |
DateTime::Format::x509 |
File::Slurp |
File::Slurp |
|
|
Line 96 END
|
Line 98 END
|
exit; |
exit; |
} |
} |
|
|
require Sys::Hostname::FQDN; |
eval { require Sys::Hostname::FQDN; }; |
require Term::ReadKey; |
if ($@) { |
require Locale::Country; |
print "Could not find required perl module: Sys::Hostname::FQDN. Exiting.\n"; |
require Crypt::OpenSSL::X509; |
exit; |
require DateTime::Format::x509; |
} |
require File::Slurp; |
eval { require Term::ReadKey; }; |
require Cwd; |
if ($@) { |
|
print "Could not find required perl module: Term::ReadKey. Exiting\n"; |
|
exit; |
|
} |
|
eval { require Locale::Country; }; |
|
if ($@) { |
|
print "Could not find required perl module: Locale::Country. Exiting\n"; |
|
exit; |
|
} |
|
eval { require Crypt::OpenSSL::X509; }; |
|
if ($@) { |
|
print "Could not find required perl module: Crypt::OpenSSL::X509. Exiting\n"; |
|
exit; |
|
} |
|
eval { require Crypt::X509::CRL; }; |
|
if ($@) { |
|
print "Could not find required perl module: Crypt::X509::CRL. Exiting\n"; |
|
exit; |
|
} |
|
eval { require DateTime::Format::x509; }; |
|
if ($@) { |
|
print "Could not find required perl module: DateTime::Format::x509. Exiting\n"; |
|
exit; |
|
} |
|
eval { require File::Slurp; }; |
|
if ($@) { |
|
print "Could not find required perl module: File::Slurp. Exiting\n"; |
|
exit; |
|
} |
|
eval { require MIME::Base64; }; |
|
if ($@) { |
|
print "Could not find required perl core module: MIME::Base64\n"; |
|
exit; |
|
} |
|
eval { require Cwd; }; |
|
if ($@) { |
|
print "Could not find required perl core module: Cwd\n"; |
|
exit; |
|
} |
|
|
my ($dir,$hostname,%data); |
my ($dir,$hostname,%data); |
|
|
Line 136 END
|
Line 176 END
|
} else { |
} else { |
print "A lonca directory is required, but no directory exists\n"; |
print "A lonca directory is required, but no directory exists\n"; |
exit; |
exit; |
} |
} |
if (-e "$dir/lonca/opensslca.conf") { |
if (-e "$dir/lonca/opensslca.conf") { |
# retrieve existing config file and verify that if contains the required fields. |
# retrieve existing config file and verify that if contains the required fields. |
%data = &parse_config("$dir/lonca/opensslca.conf"); |
%data = &parse_config("$dir/lonca/opensslca.conf"); |
Line 156 END
|
Line 196 END
|
|
|
A configuration file: $dir/lonca/opensslca.conf will be created. |
A configuration file: $dir/lonca/opensslca.conf will be created. |
|
|
The following information will be included: |
The following information will be included: |
Country, State/Province, City, Cluster Name, Organizational Name, E-mail address, Default certificate lifetime (days), CRL re-creation interval (days) |
Country, State/Province, City, Cluster Name, Organizational Name, E-mail address, Default certificate lifetime (days), CRL re-creation interval (days) |
|
|
END |
END |
Line 218 x509_extensions = certificate_extension
|
Line 258 x509_extensions = certificate_extension
|
[ loncapa_policy ] |
[ loncapa_policy ] |
|
|
commonName = supplied |
commonName = supplied |
|
localityName = supplied |
stateOrProvinceName = supplied |
stateOrProvinceName = supplied |
countryName = supplied |
countryName = supplied |
emailAddress = supplied |
emailAddress = supplied |
Line 232 crlDistributionPoints = URI:http://$clus
|
Line 273 crlDistributionPoints = URI:http://$clus
|
[ req ] |
[ req ] |
|
|
default_bits = 2048 |
default_bits = 2048 |
|
default_md = sha256 |
|
default_keyfile = $dir/lonca/private/cakey.pem |
|
|
|
prompt = no |
distinguished_name = loncapa_ca |
distinguished_name = loncapa_ca |
|
|
x509_extensions = loncapa_ca_extensions |
x509_extensions = loncapa_ca_extensions |
Line 254 authorityKeyIdentifier=keyid:always,issu
|
Line 299 authorityKeyIdentifier=keyid:always,issu
|
|
|
|
|
END |
END |
|
close($fh); |
} else { |
} else { |
print 'Error: failed to wtite to '."$dir/lonca/opensslca.conf. Exiting.\n"; |
print 'Error: failed to wtite to '."$dir/lonca/opensslca.conf. Exiting.\n"; |
exit; |
exit; |
Line 307 END
|
Line 352 END
|
} else { |
} else { |
exit; |
exit; |
} |
} |
} |
} |
} else { |
} else { |
$sslkeypass = &get_new_sslkeypass(); |
$sslkeypass = &get_new_sslkeypass(); |
# generate SSL key |
# generate SSL key |
Line 388 END
|
Line 433 END
|
print "Enter the lifetime (in days) for the CA root certificate distributed to all nodes, e.g., 3650\n"; |
print "Enter the lifetime (in days) for the CA root certificate distributed to all nodes, e.g., 3650\n"; |
my $cadays = &get_days(); |
my $cadays = &get_days(); |
unless (&make_ca_cert("$dir/lonca/private","$dir/lonca",$sslkeypass,$cadays)) { |
unless (&make_ca_cert("$dir/lonca/private","$dir/lonca",$sslkeypass,$cadays)) { |
print "Failed to create CA cert\n"; |
print "Failed to create CA certificate\n"; |
exit; |
exit; |
} |
} |
} |
} |
Line 401 END
|
Line 446 END
|
chmod $mode, "$dir/lonca/index.txt"; |
chmod $mode, "$dir/lonca/index.txt"; |
} else { |
} else { |
print "lonca/index.txt file is missing\n"; |
print "lonca/index.txt file is missing\n"; |
exit; |
exit; |
} |
} |
# echo 1000 > serial |
|
|
|
|
|
unless (-e "$dir/lonca/crl/loncapaCAcrl.pem") { |
my $defcrlsel = 1; |
open(PIPE,"openssl ca -gencrl -keyfile $dir/lonca/private/cakey.pem -cert $dir/lonca/cacert.pem -out $dir". |
if (!-e "$dir/lonca/crl/loncapaCAcrl.pem") { |
"/lonca/crl/loncapaCAcrl.pem -config $dir/lonca/opensslca.conf -passin pass:$sslkeypass |"); |
print "No Revocation Certificate List found.\n"; |
close(PIPE); |
print 'Create Certificate Revocation List [Y/n]'; |
if (-e "$dir/lonca/crl/loncapaCAcrl.pem") { |
} else { |
print "Certificate Revocation List created\n"; |
if (open(PIPE,"openssl crl -in $dir/lonca/crl/loncapaCAcrl.pem -inform pem -CAfile $dir/lonca/cacert.pem -noout 2>&1 |")) { |
|
my $crlstatus = <PIPE>; |
|
close(PIPE); |
|
chomp($crlstatus); |
|
my $failmsg = "Could not determine 'valid from' and 'valid to' dates for Certificate Revocation List.\n"; |
|
if ($crlstatus =~ /OK/) { |
|
print "Current Certficate Revocation List is consistent with current CA certificate.\n"; |
|
if (open(my $fh,'<',"$dir/lonca/crl/loncapaCAcrl.pem")) { |
|
my $pem_crl = ''; |
|
while (my $line=<$fh>) { |
|
chomp($line); |
|
next if ($line eq '-----BEGIN X509 CRL-----'); |
|
next if ($line eq '-----END X509 CRL-----'); |
|
$pem_crl .= $line; |
|
} |
|
close($fh); |
|
my $der_crl = MIME::Base64::decode_base64($pem_crl); |
|
if ($der_crl ne '') { |
|
my $decoded = Crypt::X509::CRL->new( crl => $der_crl ); |
|
if (ref($decoded)) { |
|
if ($decoded->error) { |
|
print $failmsg; |
|
} else { |
|
my $starttime = $decoded->this_update; |
|
my $endtime = $decoded->next_update; |
|
if (($endtime ne '') && ($endtime < time)) { |
|
print "Certificate Revocation List is no longer valid.\n"; |
|
} elsif ($starttime > time) { |
|
print "Certificate Revocation List will become valid in the future.\n"; |
|
} elsif (($starttime ne '') && ($endtime ne '')) { |
|
my $showstart = localtime($starttime); |
|
my $showend = localtime($endtime); |
|
print "Certificate Revocation List valid from: $showstart to: $showend\n"; |
|
$defcrlsel = 0; |
|
} else { |
|
print $failmsg; |
|
} |
|
} |
|
} else { |
|
print $failmsg; |
|
} |
|
} else { |
|
print $failmsg; |
|
} |
|
} else { |
|
print $failmsg; |
|
} |
|
} else { |
|
print "Current Certificate Revocation List is not consistent with current CA certificate.\n"; |
|
} |
|
if ($defcrlsel) { |
|
print 'Create Certificate Revocation List [Y/n]'; |
|
} else { |
|
print 'Create Certificate Revocation List [y/N]'; |
|
} |
|
} else { |
|
print "Could not check Certificate Revocation List status.\n"; |
|
print 'Create Certificate Revocation List [Y/n]'; |
} |
} |
} |
} |
if (-e "$dir/lonca/crl/loncapaCAcrl.pem") { |
if (&get_user_selection($defcrlsel)) { |
open(PIPE,"openssl crl -in $dir/lonca/crl/loncapaCAcrl.pem -inform pem -CAfile $dir/lonca/cacert.pem -noout 2>&1 |"); |
if (open(PIPE,"openssl ca -gencrl -keyfile $dir/lonca/private/cakey.pem -cert $dir/lonca/cacert.pem -out $dir". |
my $revoked = <PIPE>; |
"/lonca/crl/loncapaCAcrl.pem -config $dir/lonca/opensslca.conf -passin pass:$sslkeypass |")) { |
close(PIPE); |
close(PIPE); |
chomp($revoked); |
if (-e "$dir/lonca/crl/loncapaCAcrl.pem") { |
print "Revocation certificate status: $revoked\n"; |
if (open(PIPE,"openssl crl -in $dir/lonca/crl/loncapaCAcrl.pem -inform pem -CAfile $dir/lonca/cacert.pem -noout 2>&1 |")) { |
# Create a new one? |
my $revoked = <PIPE>; |
|
close(PIPE); |
|
chomp($revoked); |
|
if ($revoked eq 'verify OK') { |
|
print "Certificate Revocation List created\n"; |
|
} else { |
|
print "Certificate Revocation List status: $revoked\n"; |
|
} |
|
} else { |
|
print "Could not check Certificate Revocation List status\n"; |
|
} |
|
} else { |
|
print "Failed to create Certificate Revocation List\n"; |
|
} |
|
} else { |
|
print "Failed to create Certificate Revocation List\n"; |
|
} |
} |
} |
|
exit(0); |
|
|
|
|
sub cafield_to_key { |
sub cafield_to_key { |
my %mapping = ( |
my %mapping = ( |
Line 818 sub confirm_config {
|
Line 936 sub confirm_config {
|
print(<<END); |
print(<<END); |
|
|
The cluster name, organization name, country, state and city will be |
The cluster name, organization name, country, state and city will be |
included in the CA certificate |
included in the CA certificate, and in signed certificate(s) issued to |
|
node(s) in the cluster (which will receive the default certficate lifetime). |
|
|
1) Cluster Name: $data{'clustername'} |
1) Cluster Name: $data{'clustername'} |
2) Organization Name: $data{'organization'} |
2) Organization Name: $data{'organization'} |
Line 830 included in the CA certificate
|
Line 949 included in the CA certificate
|
8) CRL recreation interval (days): $data{'crldays'} |
8) CRL recreation interval (days): $data{'crldays'} |
9) Everything is correct up above |
9) Everything is correct up above |
|
|
Enter a choice of 1-8 to change, otherwise enter 9: |
Enter a choice of 1-8 to change, otherwise enter 9: |
END |
END |
my $choice=<STDIN>; |
my $choice=<STDIN>; |
chomp($choice); |
chomp($choice); |