|
|
4418f4 |
#!%INSTDIR%/bin/perl
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# This program is free software; you can redistribute it and/or
|
|
|
4418f4 |
# modify it under the terms of the GNU General Public License
|
|
|
4418f4 |
# as published by the Free Software Foundation; either version 2
|
|
|
4418f4 |
# of the License, or (at your option) any later version.
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# This program is distributed in the hope that it will be useful,
|
|
|
4418f4 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
4418f4 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
4418f4 |
# GNU General Public License for more details.
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# You should have received a copy of the GNU General Public License
|
|
|
4418f4 |
# along with this program; if not, write to the Free Software
|
|
|
4418f4 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
4418f4 |
# 02110-1301, US
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# Generate a keypair. Get a keysize from the user, generate
|
|
|
4418f4 |
# some useful random data, generate a key, produce a CSR if
|
|
|
4418f4 |
# required and add a passphrase if required.
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# genkey.pl -- based on genkey and genkey.aux from Stronghold
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# Mark J Cox, mjc@redhat.com and Joe Orton, jorton@redhat.com
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# 200103 Initial version
|
|
|
4418f4 |
# 200106 Converted to Newt
|
|
|
4418f4 |
# 200106 Added gencert/genreq functionality
|
|
|
4418f4 |
# 200106 Added some state
|
|
|
4418f4 |
# 200111 Added makeca functionality
|
|
|
4418f4 |
# 200305 Hide passwords entered for private key
|
|
|
4418f4 |
# 200308 Adapted for Taroon
|
|
|
4418f4 |
# 200308 Fix warnings in UTF-8 locale
|
|
|
4418f4 |
# 200409 Added --days support
|
|
|
4418f4 |
# 200804 Use NSS library for cryptography [Bug 346731]
|
|
|
4418f4 |
#
|
|
|
4418f4 |
#
|
|
|
4418f4 |
$bindir = "%INSTDIR%/bin";
|
|
|
4418f4 |
$ssltop = "%INSTDIR%/conf/ssl";
|
|
|
4418f4 |
$nssconf = "/etc/httpd/conf.d/nss.conf";
|
|
|
4418f4 |
$cadir = "$ssltop/CA";
|
|
|
4418f4 |
|
|
|
4418f4 |
use Crypt::Makerand;
|
|
|
4418f4 |
use Newt;
|
|
|
4418f4 |
use Getopt::Long;
|
|
|
4418f4 |
use File::Temp qw/ tempfile /;
|
|
|
4418f4 |
|
|
|
4418f4 |
sub InitRoot
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my $help = shift;
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Cls();
|
|
|
4418f4 |
Newt::DrawRootText(0, 0,
|
|
|
4418f4 |
"Red Hat Keypair Generation (c) 2008 Red Hat, Inc.");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($help == 1) {
|
|
|
4418f4 |
Newt::PushHelpLine(" <Tab>/<Alt-Tab> between elements |" .
|
|
|
4418f4 |
" <Space> selects |" .
|
|
|
4418f4 |
" <Escape> to quit");
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub FinishRoot
|
|
|
4418f4 |
{
|
|
|
4418f4 |
Newt::PopHelpLine();
|
|
|
4418f4 |
Newt::Cls();
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub usage
|
|
|
4418f4 |
{
|
|
|
4418f4 |
print STDERR <
|
|
|
4418f4 |
Usage: genkey [options] servername
|
|
|
4418f4 |
--test Test mode, faster seeding, overwrite existing key
|
|
|
4418f4 |
--genreq Generate a Certificate Signing Request (CSR)
|
|
|
4418f4 |
--makeca Generate a self-signed certificate for a CA
|
|
|
4418f4 |
--days Days until expiry of self-signed certificate (default 30)
|
|
|
4418f4 |
--renew CSR is for cert renewal, reusing existing key pair, openssl certs only
|
|
|
4418f4 |
--cacert Renewal is for a CA certificate, needed for openssl certs only
|
|
|
4418f4 |
--nss Use the nss database for keys and certificates
|
|
|
4418f4 |
--gdb For package maintainers, to trace into the nss utilities
|
|
|
4418f4 |
EOH
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Run a form with support for pressing escape and enter.
|
|
|
4418f4 |
sub RunForm
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($panel, $onenter, $onescape) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
# set defaults
|
|
|
4418f4 |
$onenter = "Next" if (!defined($onenter));
|
|
|
4418f4 |
$onescape = "Cancel" if (!defined($onescape));
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->AddHotKey(Newt::NEWT_KEY_ESCAPE());
|
|
|
4418f4 |
$panel->AddHotKey(Newt::NEWT_KEY_ENTER()) unless $onenter eq "Ignore";
|
|
|
4418f4 |
|
|
|
4418f4 |
($reason, $data) = $panel->Run();
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($reason eq Newt::NEWT_EXIT_HOTKEY) {
|
|
|
4418f4 |
if ($data == Newt::NEWT_KEY_ESCAPE()) {
|
|
|
4418f4 |
# They pressed ESCAPE; pretend they pressed "Cancel" or "No"
|
|
|
4418f4 |
return $onescape;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
elsif ($data == Newt::NEWT_KEY_ENTER()) {
|
|
|
4418f4 |
my $current = $panel->GetCurrent();
|
|
|
4418f4 |
if ($panel->{refs}{$$current}->Tag()) {
|
|
|
4418f4 |
# They pressed ENTER over a button; pretend they pressed it.
|
|
|
4418f4 |
return $panel->{refs}{$$current}->Tag();
|
|
|
4418f4 |
}
|
|
|
4418f4 |
return $onenter;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
elsif ($reason eq Newt::NEWT_EXIT_COMPONENT) {
|
|
|
4418f4 |
return $data->Tag();
|
|
|
4418f4 |
}
|
|
|
4418f4 |
die "unhandled event ", $reason, " ", $data, "\n";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# main
|
|
|
4418f4 |
#
|
|
|
4418f4 |
|
|
|
4418f4 |
my $test_mode = '';
|
|
|
4418f4 |
my $genreq_mode = '';
|
|
|
4418f4 |
my $ca_mode = '';
|
|
|
4418f4 |
my $cert_days = 30;
|
|
|
4418f4 |
my $nss ='';
|
|
|
4418f4 |
my $renew = '';
|
|
|
4418f4 |
my $cacert = '';
|
|
|
4418f4 |
my $modNssDbDir = '';
|
|
|
4418f4 |
my $nssNickname = '';
|
|
|
4418f4 |
my $nssDBPrefix = '';
|
|
|
4418f4 |
my $gdb = '';
|
|
|
4418f4 |
GetOptions('test|t' => \$test_mode,
|
|
|
4418f4 |
'genreq' => \$genreq_mode,
|
|
|
4418f4 |
'days=i' => \$cert_days,
|
|
|
4418f4 |
'renew' => \$renew,
|
|
|
4418f4 |
'cacert' => \$cacert,
|
|
|
4418f4 |
'nss|n' => \$nss,
|
|
|
4418f4 |
'gdb' => \$gdb,
|
|
|
4418f4 |
'makeca' => \$ca_mode) or usage();
|
|
|
4418f4 |
usage() unless @ARGV != 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($genreq_mode && $renew && !$nss) {
|
|
|
4418f4 |
print STDERR <
|
|
|
4418f4 |
Certificate renewal from PEM files is not yet supported.
|
|
|
4418f4 |
EOH
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$skip_random = $test_mode;
|
|
|
4418f4 |
$overwrite_key = $test_mode;
|
|
|
4418f4 |
$servername = $ARGV[0];
|
|
|
4418f4 |
$randfile = $ssltop."/.rand.".$$;
|
|
|
4418f4 |
$keyEncPassword = ''; # for the one we write
|
|
|
4418f4 |
$tmpPasswordFile = ''; # none has been created yet
|
|
|
4418f4 |
$keyfile = $ssltop."/private/".$servername.".key";
|
|
|
4418f4 |
if ($ca_mode) {
|
|
|
4418f4 |
$keyfile = $cadir."/private/".$servername.".key";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
### State variables
|
|
|
4418f4 |
my $bits = 0;
|
|
|
4418f4 |
my $myca = "Other";
|
|
|
4418f4 |
my $useca = 0;
|
|
|
4418f4 |
my $subject;
|
|
|
4418f4 |
#
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Init();
|
|
|
4418f4 |
InitRoot(1);
|
|
|
4418f4 |
|
|
|
4418f4 |
local $SIG{__DIE__} = sub { @err=@_; Newt::Finished(); die @err;};
|
|
|
4418f4 |
|
|
|
4418f4 |
# Either mod_nss or mod_ssl is required
|
|
|
4418f4 |
requireModule();
|
|
|
4418f4 |
|
|
|
4418f4 |
# For mod_nss we need these variables set
|
|
|
4418f4 |
if ($nss) {
|
|
|
4418f4 |
# the configuration file is required
|
|
|
4418f4 |
if (!nssconfigFound()) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Could not find mod_nss's nss.conf file".
|
|
|
4418f4 |
"for this host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$modNssDbDir = getModNSSDatabase();
|
|
|
4418f4 |
$nssNickname = $servername ? $servername : getNSSNickname();
|
|
|
4418f4 |
$nssDBPrefix = getNSSDBPrefix();
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# Does the key already exist? don't overwrite
|
|
|
4418f4 |
#
|
|
|
4418f4 |
|
|
|
4418f4 |
if (!$nss) {
|
|
|
4418f4 |
if (!$genreq_mode && -f $keyfile && !$overwrite_key) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"You already have a key file for this host in file:\n\n" .
|
|
|
4418f4 |
$keyfile . "\n\n" .
|
|
|
4418f4 |
"This script will not overwrite an existing key.\n" .
|
|
|
4418f4 |
"You will need to remove or rename this file in order to" .
|
|
|
4418f4 |
"generate a new key for this host, then rerun the command");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
# check for the key in the database
|
|
|
4418f4 |
if (!$genreq_mode && keyInDatabase($nssNickname,$modNssDbDir) &&
|
|
|
4418f4 |
!$renew && !$overwrite_key) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"You already have a key file for this host in the datatabase:\n\n" .
|
|
|
4418f4 |
"$modNssDbDir" ." with nickname ". "$nssNickname" . "\n\n" .
|
|
|
4418f4 |
"This script will not overwrite an existing key.\n" .
|
|
|
4418f4 |
"You will need to remove or rename the database in order to" .
|
|
|
4418f4 |
"generate a new key for this host, then rerun the command");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
######################################################################
|
|
|
4418f4 |
# Main
|
|
|
4418f4 |
#
|
|
|
4418f4 |
|
|
|
4418f4 |
# Array of windows which we cycle through. Each window function should
|
|
|
4418f4 |
# return:
|
|
|
4418f4 |
# "Next" or "Skip" -> go on to the next window
|
|
|
4418f4 |
# "Back" -> go back to the last window which returned "Next"
|
|
|
4418f4 |
# "Cancel" -> cancelled: quit and return failure.
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# "Skip" is to allow for windows which don't display anything (due
|
|
|
4418f4 |
# to choices made in previous windows, for instance).
|
|
|
4418f4 |
#
|
|
|
4418f4 |
my @windows;
|
|
|
4418f4 |
if ($genreq_mode) {
|
|
|
4418f4 |
$useca = 1;
|
|
|
4418f4 |
@windows = $renew
|
|
|
4418f4 |
? (passwordWindow,genReqWindow,)
|
|
|
4418f4 |
: (getkeysizeWindow,
|
|
|
4418f4 |
customKeySizeWindow,
|
|
|
4418f4 |
getRandomDataWindow,
|
|
|
4418f4 |
passwordWindow,
|
|
|
4418f4 |
genReqWindow,
|
|
|
4418f4 |
);
|
|
|
4418f4 |
$doingwhat="CSR generation";
|
|
|
4418f4 |
} elsif ($ca_mode) {
|
|
|
4418f4 |
@windows = (CAwelcomeWindow,
|
|
|
4418f4 |
getkeysizeWindow,
|
|
|
4418f4 |
customKeySizeWindow,
|
|
|
4418f4 |
getRandomDataWindow,
|
|
|
4418f4 |
passwordWindow,
|
|
|
4418f4 |
genCACertWindow,
|
|
|
4418f4 |
);
|
|
|
4418f4 |
$doingwhat="CA cert generation";
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
@windows = (welcomeWindow,
|
|
|
4418f4 |
getkeysizeWindow,
|
|
|
4418f4 |
customKeySizeWindow,
|
|
|
4418f4 |
getRandomDataWindow,
|
|
|
4418f4 |
wantCAWindow,
|
|
|
4418f4 |
passwordWindow,
|
|
|
4418f4 |
genReqWindow,
|
|
|
4418f4 |
genCertWindow,
|
|
|
4418f4 |
### @EXTRA@ ### Leave this comment here.
|
|
|
4418f4 |
);
|
|
|
4418f4 |
$doingwhat="testing CSR and cert generation";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
my $screen = 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
my @screenstack;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $result;
|
|
|
4418f4 |
|
|
|
4418f4 |
while ($screen <= $#windows) {
|
|
|
4418f4 |
$result = $windows[$screen]->();
|
|
|
4418f4 |
print STDERR "undef from window #" .$screen . "\n" if (!$result);
|
|
|
4418f4 |
if ($result eq "Cancel") {
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 2, "Confirm");
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0,
|
|
|
4418f4 |
Newt::TextboxReflowed(60, 10, 10, 0,
|
|
|
4418f4 |
"Do you want to cancel ".$doingwhat.
|
|
|
4418f4 |
"?"));
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 1, DoubleButton("Yes", "No"));
|
|
|
4418f4 |
# Default to NOT cancel if escape is pressed (again)
|
|
|
4418f4 |
$ret = &RunForm($panel, "No", "No");
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
last if $ret eq "Yes";
|
|
|
4418f4 |
next;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$nextscreen = $screen + 1 if ($result eq "Next" or $result eq "Skip"
|
|
|
4418f4 |
or !$result);
|
|
|
4418f4 |
$nextscreen = pop @screenstack if ($result eq "Back" and scalar(@screenstack));
|
|
|
4418f4 |
push @screenstack, $screen if ($result eq "Next");
|
|
|
4418f4 |
$screen = $nextscreen;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Exit
|
|
|
4418f4 |
clearSensitiveData();
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1 if ($result eq "Cancel");
|
|
|
4418f4 |
exit 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# end main
|
|
|
4418f4 |
#
|
|
|
4418f4 |
|
|
|
4418f4 |
######################################################################
|
|
|
4418f4 |
# Handy functions
|
|
|
4418f4 |
|
|
|
4418f4 |
# Returns a panel containing two buttons of given names.
|
|
|
4418f4 |
sub DoubleButton {
|
|
|
4418f4 |
my ($left, $right) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $leftb = Newt::Button($left)->Tag($left);
|
|
|
4418f4 |
my $rightb = Newt::Button($right)->Tag($right);
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Panel(2, 1)
|
|
|
4418f4 |
->Add(0, 0, $leftb, Newt::NEWT_ANCHOR_RIGHT(), 0, 1, 0, 0)
|
|
|
4418f4 |
->Add(1, 0, $rightb, Newt::NEWT_ANCHOR_LEFT(), 1, 1, 0, 0);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Returns a panel containing next/back/cancel buttons.
|
|
|
4418f4 |
sub NextBackCancelButton {
|
|
|
4418f4 |
|
|
|
4418f4 |
my $nextb = Newt::Button('Next')->Tag('Next');
|
|
|
4418f4 |
my $backb = Newt::Button('Back')->Tag('Back');
|
|
|
4418f4 |
my $cancelb = Newt::Button('Cancel')->Tag('Cancel');
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Panel(3, 1)
|
|
|
4418f4 |
->Add(0, 0, $nextb, Newt::NEWT_ANCHOR_RIGHT(), 0, 1, 0, 0)
|
|
|
4418f4 |
->Add(1, 0, $backb, Newt::NEWT_ANCHOR_RIGHT(), 1, 1, 0, 0)
|
|
|
4418f4 |
->Add(2, 0, $cancelb, Newt::NEWT_ANCHOR_LEFT(), 1, 1, 0, 0);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Require that this Apache module (mod_nss or mod_ssl) be installed
|
|
|
4418f4 |
sub requireModule {
|
|
|
4418f4 |
|
|
|
4418f4 |
my $module = $nss ? "mod_nss" : "mod_ssl";
|
|
|
4418f4 |
my $not_installed_msg = `rpm -q $module | grep "not installed"`;
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($not_installed_msg) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"$not_installed_msg".
|
|
|
4418f4 |
"\nIt is required to generate this type of CSRs or certs".
|
|
|
4418f4 |
"for this host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Check that nss.conf exists
|
|
|
4418f4 |
sub nssconfigFound {
|
|
|
4418f4 |
# if it isn't in its usual place
|
|
|
4418f4 |
if (!$nssconf || !(-f $nssconf)) {
|
|
|
4418f4 |
# do an rpm query
|
|
|
4418f4 |
my $cmd = 'rpm -ql mod_nss';
|
|
|
4418f4 |
($fh, $tmplist) = tempfile("list.XXXXXX");
|
|
|
4418f4 |
system("$cmd > $tmplist");
|
|
|
4418f4 |
$nssconf = `grep nss.conf $tmplist`;
|
|
|
4418f4 |
unlink($tmplist);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
return ($nssconf && (-f $nssconf));
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Returns the mod_nss database directory path.
|
|
|
4418f4 |
sub getModNSSDatabase {
|
|
|
4418f4 |
|
|
|
4418f4 |
# Extract the value from the mod_nss configuration file.
|
|
|
4418f4 |
my $cmd ='/usr/bin/gawk \'/^NSSCertificateDatabase/ { print $2 }\'' . " $nssconf";
|
|
|
4418f4 |
($fh, $dbfile) = tempfile("dbdirectory.XXXXXX");
|
|
|
4418f4 |
system("$cmd > $dbfile");
|
|
|
4418f4 |
open(DIR, "<$dbfile");
|
|
|
4418f4 |
my $dbdir = '';
|
|
|
4418f4 |
chomp($dbdir = <DIR>);
|
|
|
4418f4 |
|
|
|
4418f4 |
unlink($dbfile);
|
|
|
4418f4 |
|
|
|
4418f4 |
return $dbdir;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Returns the rsa server name.
|
|
|
4418f4 |
sub getNSSNickname {
|
|
|
4418f4 |
|
|
|
4418f4 |
# Extract the value from the mod_nss configuration file.
|
|
|
4418f4 |
my $cmd ='/usr/bin/gawk \'/^NSSNickname/ { print $2 }\'' . " $nssconf";
|
|
|
4418f4 |
($fh, $nicknamefile) = tempfile("nssnickname.XXXXXX");
|
|
|
4418f4 |
system("$cmd > $nicknamefile");
|
|
|
4418f4 |
open(NICK, "<$nicknamefile");
|
|
|
4418f4 |
my $nickname = '';
|
|
|
4418f4 |
chomp($nickname = <NICK>);
|
|
|
4418f4 |
unlink($nicknamefile);
|
|
|
4418f4 |
return $nickname;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Returns the nss database prefix
|
|
|
4418f4 |
sub getNSSDBPrefix {
|
|
|
4418f4 |
|
|
|
4418f4 |
# Extract the value from the mod_nss configuration file.
|
|
|
4418f4 |
my $cmd ='/usr/bin/gawk \'/^NSSDBPrefix/ { print $2 }\'' . " $nssconf";
|
|
|
4418f4 |
($fh, $prefixfile) = tempfile("dbprefix.XXXXXX");
|
|
|
4418f4 |
system("$cmd > $prefixfile");
|
|
|
4418f4 |
open(PREFIX, "<$prefixfile");
|
|
|
4418f4 |
my $prefix = '';
|
|
|
4418f4 |
chomp($prefix = <PREFIX>);
|
|
|
4418f4 |
unlink($prefixfile);
|
|
|
4418f4 |
|
|
|
4418f4 |
return $prefix;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Erases and deletes the password file
|
|
|
4418f4 |
sub clearSensitiveData {
|
|
|
4418f4 |
if (-f $tmpPasswordFile) {
|
|
|
4418f4 |
open(DOOMED,$tmpPasswordFile);
|
|
|
4418f4 |
truncate(DOOMED,0);
|
|
|
4418f4 |
close(DOOMED);
|
|
|
4418f4 |
unlink($tmpPasswordFile);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Remove a directory and its contents
|
|
|
4418f4 |
sub removeDirectory {
|
|
|
4418f4 |
my ($dir) = @_;
|
|
|
4418f4 |
if (-f $dir) {
|
|
|
4418f4 |
opendir(DOOMED, $dir) || die("Cannot open directory");
|
|
|
4418f4 |
my @thefiles= readdir(DOOMED);
|
|
|
4418f4 |
foreach my $file (@thefiles) {
|
|
|
4418f4 |
unlink @file;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
closedir(DOOMED);
|
|
|
4418f4 |
rmdir $dir;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Print error message
|
|
|
4418f4 |
sub printError {
|
|
|
4418f4 |
my ($msg) = @_;
|
|
|
4418f4 |
Newt::Suspend();
|
|
|
4418f4 |
print STDERR "$msg\n";
|
|
|
4418f4 |
Newt::Resume();
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Is the given key in the database?
|
|
|
4418f4 |
sub keyInDatabase {
|
|
|
4418f4 |
my ($nickname, $dbdir) = @_;
|
|
|
4418f4 |
my $tmp = "tmp";
|
|
|
4418f4 |
my $answer = `$bindir/certutil -L -d $dbdir | grep $nickname`;
|
|
|
4418f4 |
return $answer;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
######################################################################
|
|
|
4418f4 |
# The window functions
|
|
|
4418f4 |
|
|
|
4418f4 |
sub makerand
|
|
|
4418f4 |
{
|
|
|
4418f4 |
require Fcntl;
|
|
|
4418f4 |
|
|
|
4418f4 |
my ($bits,$filename) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $count = 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
my @credits = ("This software contains the truerand library",
|
|
|
4418f4 |
"developed by Matt Blaze, Jim Reeds, and Jack",
|
|
|
4418f4 |
"Lacy. Copyright (c) 1992, 1994 AT&T.");
|
|
|
4418f4 |
my ($cols, $rows) = Newt::GetScreenSize();
|
|
|
4418f4 |
|
|
|
4418f4 |
foreach (@credits) {
|
|
|
4418f4 |
$count++;
|
|
|
4418f4 |
Newt::DrawRootText($cols-45, $rows-5 + $count, $_);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$count = 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 2, "Generating random bits");
|
|
|
4418f4 |
my $scale = Newt::Scale(40, $bits);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, Newt::Label("(this may take some time)"));
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 1, $scale, 0, 0, 1);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Draw();
|
|
|
4418f4 |
|
|
|
4418f4 |
if (!sysopen($randfh,$filename,Fcntl::O_WRONLY()|Fcntl::O_CREAT()
|
|
|
4418f4 |
|Fcntl::O_TRUNC()|Fcntl::O_EXCL(),0600)) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Can't create random data file");
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
return "Cancel";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Refresh();
|
|
|
4418f4 |
while ($count++ < $bits/32) {
|
|
|
4418f4 |
use bytes; # random data is not UTF-8, prevent warnings
|
|
|
4418f4 |
# decode as an "native-length" unsigned long
|
|
|
4418f4 |
syswrite($randfh,pack("L!",Crypt::Makerand::trand32()));
|
|
|
4418f4 |
$scale->Set($count*32);
|
|
|
4418f4 |
Newt::Refresh();
|
|
|
4418f4 |
}
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
close $randfh;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub getkeysizeWindow()
|
|
|
4418f4 |
{
|
|
|
4418f4 |
$minbits = 512;
|
|
|
4418f4 |
$maxbits = 8192;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $title= <
|
|
|
4418f4 |
Choose the size of your key. The smaller the key you choose the faster
|
|
|
4418f4 |
your server response will be, but you'll have less security. Keys of
|
|
|
4418f4 |
less than 1024 bits are easily cracked.
|
|
|
4418f4 |
|
|
|
4418f4 |
We suggest you select the default, 2048 bits.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 3, "Choose key size");
|
|
|
4418f4 |
my $listbox = Newt::Listbox(5, 0);
|
|
|
4418f4 |
my $text = Newt::Textbox(70, 6, 0, $title);
|
|
|
4418f4 |
my @listitems = ("512 (insecure)",
|
|
|
4418f4 |
"1024 (low-grade, fast speed)",
|
|
|
4418f4 |
"2048 (medium-security, medium speed) [RECOMMENDED]",
|
|
|
4418f4 |
"4096 (high-security, slow speed)",
|
|
|
4418f4 |
"Choose your own");
|
|
|
4418f4 |
|
|
|
4418f4 |
$listbox->Append(@listitems);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, $text);
|
|
|
4418f4 |
$panel->Add(0, 1, $listbox, 0, 0, 1);
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton());
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::newtListboxSetCurrent($listbox->{co}, 2);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Draw();
|
|
|
4418f4 |
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($ret eq "Cancel" or $ret eq "Back") {
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$bits = 256;
|
|
|
4418f4 |
|
|
|
4418f4 |
foreach $item(@listitems) {
|
|
|
4418f4 |
$bits = $bits * 2;
|
|
|
4418f4 |
if ($item eq $listbox->Get()) {
|
|
|
4418f4 |
last;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub customKeySizeWindow()
|
|
|
4418f4 |
{
|
|
|
4418f4 |
return "Next" if $bits < 8192; # else, choose custom size.
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Refresh();
|
|
|
4418f4 |
|
|
|
4418f4 |
$bits = 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
$title = <
|
|
|
4418f4 |
Select the exact key size you want to use. Note that some browsers do
|
|
|
4418f4 |
not work correctly with arbitrary key sizes. For a reasonable level
|
|
|
4418f4 |
of security you should use 2048.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel = Newt::Panel(1, 3, "Select exact key size");
|
|
|
4418f4 |
my $entry = Newt::Entry(10, 0, "");
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, Newt::Textbox(70, 4, 0, $title));
|
|
|
4418f4 |
$panel->Add(0, 1, $entry);
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton());
|
|
|
4418f4 |
|
|
|
4418f4 |
do {
|
|
|
4418f4 |
$panel->Focus($entry);
|
|
|
4418f4 |
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($ret eq "Cancel" or $ret eq "Back") {
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($entry->Get() ne "") {
|
|
|
4418f4 |
$bits = int($entry->Get());
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
$bits = 0;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
} while ($bits < $minbits || $bits > $maxbits);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub welcomeWindow()
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my $name = $servername;
|
|
|
4418f4 |
my $where_key = $nss
|
|
|
4418f4 |
? $modNssDbDir."/$nssDBPrefix"."key3.db" : "$ssltop/private/$name.key";
|
|
|
4418f4 |
my $where_cert = $nss
|
|
|
4418f4 |
? $modNssDbDir."/$nssDBPrefix"."cert8.db" : "$ssltop/certs/$name.crt";
|
|
|
4418f4 |
my $what = $nss ? "directory" : "file";
|
|
|
4418f4 |
my $message = <
|
|
|
4418f4 |
You are now generating a new keypair which will be used to encrypt all
|
|
|
4418f4 |
SSL traffic to the server named $name.
|
|
|
4418f4 |
Optionally you can also create a certificate request and send it to a
|
|
|
4418f4 |
certificate authority (CA) for signing.
|
|
|
4418f4 |
|
|
|
4418f4 |
The key will be stored in
|
|
|
4418f4 |
$where_key
|
|
|
4418f4 |
The certificate stored in
|
|
|
4418f4 |
$where_cert
|
|
|
4418f4 |
|
|
|
4418f4 |
If the key generation fails, move the $what
|
|
|
4418f4 |
$where_key
|
|
|
4418f4 |
to a backup location and try again.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 2, "Keypair generation");
|
|
|
4418f4 |
my $text = Newt::Textbox(70, 10, Newt::NEWT_TEXTBOX_SCROLL(), $message);
|
|
|
4418f4 |
my $ret;
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, $text);
|
|
|
4418f4 |
$panel->Add(0, 1, DoubleButton("Next","Cancel"));
|
|
|
4418f4 |
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub CAwelcomeWindow()
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my $name = $servername;
|
|
|
4418f4 |
my $where = $nss ? $modNssDbDir."/$nssDBPrefix"."key3.db" : "$cadir/private/$name";
|
|
|
4418f4 |
my $message = <
|
|
|
4418f4 |
You are now generating a new keypair which will be used for your
|
|
|
4418f4 |
private CA
|
|
|
4418f4 |
|
|
|
4418f4 |
The key will be stored in
|
|
|
4418f4 |
$where
|
|
|
4418f4 |
|
|
|
4418f4 |
If the key generation fails, move the file
|
|
|
4418f4 |
$where
|
|
|
4418f4 |
to a backup location and try again.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 2, "CA Key generation");
|
|
|
4418f4 |
my $text = Newt::Textbox(70, 10, Newt::NEWT_TEXTBOX_SCROLL(), $message);
|
|
|
4418f4 |
my $ret;
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, $text);
|
|
|
4418f4 |
$panel->Add(0, 1, DoubleButton("Next","Cancel"));
|
|
|
4418f4 |
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub wantCAWindow
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 2, "Generate CSR");
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0,
|
|
|
4418f4 |
Newt::TextboxReflowed(60, 10, 10, 0,
|
|
|
4418f4 |
"Would you like to send a Certificate Request (CSR) " .
|
|
|
4418f4 |
"to a Certificate Authority (CA)?"));
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 1, DoubleButton("Yes", "No"));
|
|
|
4418f4 |
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($ret eq "Cancel") {
|
|
|
4418f4 |
return "Cancel";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$useca = ($ret eq "Yes") ? 1 : 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Save the passphrase to a temporary file.
|
|
|
4418f4 |
sub savePassword
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($passwd) = @_;
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# Write password to a file with lines formatted as:
|
|
|
4418f4 |
# NSS Certificate DB:access_passphrase
|
|
|
4418f4 |
# PEM Token #0:ca_key_access_passphrase
|
|
|
4418f4 |
# PEM Token #1:server_key_access_passphrase
|
|
|
4418f4 |
#
|
|
|
4418f4 |
my $passwordLine = $nss
|
|
|
4418f4 |
? "NSS Certificate DB" : $cacert ? "PEM Token #0:" : "PEM Token #1:";
|
|
|
4418f4 |
$passwordLine .= "$passwd\n";
|
|
|
4418f4 |
if ($tmpPasswordFile) {
|
|
|
4418f4 |
# append to existing file
|
|
|
4418f4 |
if (!open(SESAME, ">>$tmpPasswordFile")) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Unable to append passphrase to $tmpPasswordFile".
|
|
|
4418f4 |
"\n\nPress return to continue");
|
|
|
4418f4 |
return "Back";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
# write to a new file
|
|
|
4418f4 |
$tmpPasswordFile = ".passwordfile.".$$;
|
|
|
4418f4 |
if (!open (SESAME, ">$tmpPasswordFile")) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Unable to save passphrase to $tmpPasswordFile".
|
|
|
4418f4 |
"\n\nPress return to continue");
|
|
|
4418f4 |
$tmpPasswordFile = ''; # mark it as never created
|
|
|
4418f4 |
return "Back";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
print SESAME $passwordLine;
|
|
|
4418f4 |
close(SESAME);
|
|
|
4418f4 |
# This file will be deleted on program exit.
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Prompts for a module or key access password.
|
|
|
4418f4 |
# The argument indicates wheter the password is to
|
|
|
4418f4 |
# access the nss module access or for access to the key
|
|
|
4418f4 |
# to be loaded from a pem file into a PEM module token.
|
|
|
4418f4 |
sub moduleAccesPasswordWindow
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($what) = @_;
|
|
|
4418f4 |
# either "module" or "key"
|
|
|
4418f4 |
|
|
|
4418f4 |
my $message = <
|
|
|
4418f4 |
At this stage you can provide the $what acess passphrase.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
$panel = Newt::Panel(1, 3, $what." access");
|
|
|
4418f4 |
$panel->Add(0, 0, Newt::Textbox(70, 5, 0, $message));
|
|
|
4418f4 |
|
|
|
4418f4 |
my $checkbox = Newt::Checkbox($what." access password if any");
|
|
|
4418f4 |
$panel->Add(0, 1, $checkbox);
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton());
|
|
|
4418f4 |
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
my $plain = 1;
|
|
|
4418f4 |
$plain = 0 if $checkbox->Checked();
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return $ret if ($ret eq "Back" or $ret eq "Cancel" or $plain == 1);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel = Newt::Panel(1, 3, "Enter the $what passphrase");
|
|
|
4418f4 |
|
|
|
4418f4 |
$message = <
|
|
|
4418f4 |
This is the passphrase to your $what.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
$panel->Add(0, 0, Newt::Textbox(70, 5, 0, $message));
|
|
|
4418f4 |
$subp = Newt::Panel(2,2);
|
|
|
4418f4 |
$entp1 = AddField($subp,0,"Passphrase","",30,0,
|
|
|
4418f4 |
Newt::NEWT_FLAG_HIDDEN());
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 1, $subp, 0, 0, 1);
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton());
|
|
|
4418f4 |
|
|
|
4418f4 |
while (1) {
|
|
|
4418f4 |
# Clear the password entry box to avoid confusion on looping
|
|
|
4418f4 |
$entp1->Set("");
|
|
|
4418f4 |
$panel->Focus($entp1);
|
|
|
4418f4 |
|
|
|
4418f4 |
# Pass "Ignore" to make enter go to next widget.
|
|
|
4418f4 |
$ret = &RunForm($panel, "Ignore");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($ret eq "Cancel" or $ret eq "Back") {
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $subp;
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
$pass1 = $entp1->Get();
|
|
|
4418f4 |
|
|
|
4418f4 |
last;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return $ret if ($ret eq "Back" or $ret eq "Cancel");
|
|
|
4418f4 |
|
|
|
4418f4 |
# Save it to a temporary file to supply to the nss utilities,
|
|
|
4418f4 |
# the file will be erased upon exit
|
|
|
4418f4 |
savePassword($pass1);
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Prompts for key encryption password
|
|
|
4418f4 |
# When using NSS it prompts for the
|
|
|
4418f4 |
# module acces password instead.
|
|
|
4418f4 |
sub passwordWindow
|
|
|
4418f4 |
{
|
|
|
4418f4 |
if ($nss || $renew) {
|
|
|
4418f4 |
# nss module access password or key password
|
|
|
4418f4 |
return moduleAccesPasswordWindow($nss ? "module" : "key");
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
my $message = <
|
|
|
4418f4 |
At this stage you can set the passphrase on your private key. If you
|
|
|
4418f4 |
set the passphrase you will have to enter it every time the server
|
|
|
4418f4 |
starts. The passphrase you use to encrypt your key must be the same
|
|
|
4418f4 |
for all the keys used by the same server installation.
|
|
|
4418f4 |
|
|
|
4418f4 |
If you do not encrypt your key, then if someone breaks into your
|
|
|
4418f4 |
server and grabs the file containing your key, they will be able to
|
|
|
4418f4 |
decrypt all communications to and from the server that were negotiated
|
|
|
4418f4 |
using that key. If your key is encrypted it would be much more
|
|
|
4418f4 |
work for someone to retrieve the private key.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
$panel = Newt::Panel(1, 3, "Protecting your private key");
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, Newt::Textbox(70, 11, 0, $message));
|
|
|
4418f4 |
|
|
|
4418f4 |
my $checkbox = Newt::Checkbox("Encrypt the private key");
|
|
|
4418f4 |
$panel->Add(0, 1, $checkbox);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton());
|
|
|
4418f4 |
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
my $plain = 1;
|
|
|
4418f4 |
$plain = 0 if $checkbox->Checked();
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return $ret if ($ret eq "Back" or $ret eq "Cancel" or $plain == 1);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel = Newt::Panel(1, 3, "Set private key passphrase");
|
|
|
4418f4 |
|
|
|
4418f4 |
$message = <
|
|
|
4418f4 |
Now we are going to set the passphrase on the private key. This
|
|
|
4418f4 |
passphrase is used to encrypt your private key when it is stored
|
|
|
4418f4 |
on disk. You will have to type this passphrase when the server
|
|
|
4418f4 |
starts.
|
|
|
4418f4 |
|
|
|
4418f4 |
-- DO NOT LOSE THIS PASS PHRASE --
|
|
|
4418f4 |
|
|
|
4418f4 |
If you lose the pass phrase you will not be able to run the server
|
|
|
4418f4 |
with this private key. You will need to generate a new private/public
|
|
|
4418f4 |
key pair and request a new certificate from your certificate authority.
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
$panel->Add(0, 0, Newt::Textbox(70, 11, 0, $message));
|
|
|
4418f4 |
$subp = Newt::Panel(2,2);
|
|
|
4418f4 |
$entp1 = AddField($subp,0,"Passphrase (>4 characters)","",30,0,
|
|
|
4418f4 |
Newt::NEWT_FLAG_HIDDEN());
|
|
|
4418f4 |
$entp2 = AddField($subp,1,"Passphrase (again) ","",30,0,
|
|
|
4418f4 |
Newt::NEWT_FLAG_HIDDEN());
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 1, $subp, 0, 0, 1);
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton());
|
|
|
4418f4 |
|
|
|
4418f4 |
while (1) {
|
|
|
4418f4 |
# Clear the password entry boxes to avoid confusion on looping
|
|
|
4418f4 |
$entp1->Set("");
|
|
|
4418f4 |
$entp2->Set("");
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Focus($entp1);
|
|
|
4418f4 |
|
|
|
4418f4 |
# Pass "Ignore" to make enter go to next widget.
|
|
|
4418f4 |
$ret = &RunForm($panel, "Ignore");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($ret eq "Cancel" or $ret eq "Back") {
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $subp;
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
$pass1 = $entp1->Get();
|
|
|
4418f4 |
$pass2 = $entp2->Get();
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($pass1 ne $pass2) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"The passphrases you entered do not match.");
|
|
|
4418f4 |
next;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
if (length($pass1)<4) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"The passphrase must be at least 4 characters".
|
|
|
4418f4 |
"\n\nPress return to try again");
|
|
|
4418f4 |
next;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
last;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return $ret if ($ret eq "Back" or $ret eq "Cancel");
|
|
|
4418f4 |
|
|
|
4418f4 |
# FIXME: Ugly, should use perl system() correctly.
|
|
|
4418f4 |
$pass1 =~ s/"/\\\"/g;
|
|
|
4418f4 |
$keyEncPassword = "\"". $pass1. "\"";
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# Bottleneck routine to call the nss utilities.
|
|
|
4418f4 |
# Calls are bracketed by newt suspend and resume
|
|
|
4418f4 |
# enabling user interaction from the nss utilities
|
|
|
4418f4 |
# and trace messages to the console.
|
|
|
4418f4 |
#
|
|
|
4418f4 |
sub nssUtilCmd {
|
|
|
4418f4 |
|
|
|
4418f4 |
my ($cmd, $args) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Suspend();
|
|
|
4418f4 |
print STDOUT "$cmd $args"."\n";
|
|
|
4418f4 |
$! = '';
|
|
|
4418f4 |
if ($gdb) {
|
|
|
4418f4 |
system("gdb $cmd");
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
system("$cmd $args");
|
|
|
4418f4 |
print STDERR "$cmd returned $!"."\n" if $!;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
Newt::Resume();
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
#
|
|
|
4418f4 |
# make a certificate using the database
|
|
|
4418f4 |
#
|
|
|
4418f4 |
sub makeCertNSS
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($certfile, # output
|
|
|
4418f4 |
$subject, $days, $nickname,
|
|
|
4418f4 |
$noisefile, $pwdfile) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
# If no days specified it's a ca so use 2 years
|
|
|
4418f4 |
use integer;
|
|
|
4418f4 |
my $months = $days / 30;
|
|
|
4418f4 |
my $trustargs = $ca_mode ? "CT,," : "u,,";
|
|
|
4418f4 |
$trustargs = "\"" . $trustargs. "\"";
|
|
|
4418f4 |
|
|
|
4418f4 |
my $args = "-S ";
|
|
|
4418f4 |
$args .= "-n $nickname ";
|
|
|
4418f4 |
$args .= "-s $subject ";
|
|
|
4418f4 |
$args .= "-x "; ## self-signed
|
|
|
4418f4 |
$args .= "-t $trustargs ";
|
|
|
4418f4 |
$args .= "-k rsa ";
|
|
|
4418f4 |
$args .= "-g $bits ";
|
|
|
4418f4 |
$args .= "-v $months ";
|
|
|
4418f4 |
$args .= "-a ";
|
|
|
4418f4 |
$args .= "-f $pwdfile " if $pwdfile;
|
|
|
4418f4 |
$args .= "-z $noisefile " if $noisefile;
|
|
|
4418f4 |
$args .= "-d $modNssDbDir ";
|
|
|
4418f4 |
$args .= "-p $nssDBPrefix " if $nssDBPrefix;
|
|
|
4418f4 |
$args .= "-o $certfile " if $certfile;
|
|
|
4418f4 |
|
|
|
4418f4 |
nssUtilCmd("$bindir/certutil", $args);
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($noisefile) {
|
|
|
4418f4 |
unlink($noisefile);
|
|
|
4418f4 |
$noisefile = '';
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($certfile && !-f $certfile) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Was not able to create a certificate for this ".
|
|
|
4418f4 |
"host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Create a certificate-signing request file that can be submitted to
|
|
|
4418f4 |
# a Certificate Authority for processing into a finished certificate.
|
|
|
4418f4 |
sub genRequestNSS
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($csrfile, # output
|
|
|
4418f4 |
$subject, $days, $noisefile, $pwdfile) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
use integer;
|
|
|
4418f4 |
my $months = $days / 30;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $args = "-R ";
|
|
|
4418f4 |
|
|
|
4418f4 |
$args .= "-s $subject ";
|
|
|
4418f4 |
$args .= "-d $modNssDbDir ";
|
|
|
4418f4 |
$args .= "-p $nssDBPrefix " if $nssDDPrefix;
|
|
|
4418f4 |
$args .= "-a "; ## using ascii
|
|
|
4418f4 |
$args .= "-k rsa ";
|
|
|
4418f4 |
$args .= "-g $bits ";
|
|
|
4418f4 |
$args .= "-f $pwdfile " if $pwdfile;
|
|
|
4418f4 |
$args .= "-v $months ";
|
|
|
4418f4 |
$args .= "-z $noisefile " if $noisefile;
|
|
|
4418f4 |
$args .= "-o $csrfile ";
|
|
|
4418f4 |
|
|
|
4418f4 |
nssUtilCmd("$bindir/certutil", $args);
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($noisefile) {
|
|
|
4418f4 |
unlink($noisefile);
|
|
|
4418f4 |
$noisefile = '';
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
if (!-f $csrfile) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Was not able to create a CSR for this ".
|
|
|
4418f4 |
"host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Generate a CA certificate file.
|
|
|
4418f4 |
# Use keyutil which supports exporting the key.
|
|
|
4418f4 |
sub makeCertOpenSSL
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($keyfile, $certfile, # output
|
|
|
4418f4 |
$subject, $days, $noisefile, $pwdfile) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
use integer;
|
|
|
4418f4 |
my $months = $days ? $days / 30 : 24;
|
|
|
4418f4 |
|
|
|
4418f4 |
# build the arguments for a gen cert call, self-signed
|
|
|
4418f4 |
my $args = "-c makecert ";
|
|
|
4418f4 |
$args .= "-g $bits ";
|
|
|
4418f4 |
$args .= "-s $subject ";
|
|
|
4418f4 |
$args .= "-v $months ";
|
|
|
4418f4 |
$args .= "-a "; ## using ascii
|
|
|
4418f4 |
$args .= "-z $noisefile " if $noisefile;
|
|
|
4418f4 |
$args .= "-e $keyEncPassword " if $keyEncPassword;
|
|
|
4418f4 |
# there is no password when the
|
|
|
4418f4 |
# user wants the key in the clear
|
|
|
4418f4 |
$args .= "-o $certfile ";
|
|
|
4418f4 |
$args .= "-k $keyfile";
|
|
|
4418f4 |
|
|
|
4418f4 |
nssUtilCmd("$bindir/keyutil", $args);
|
|
|
4418f4 |
|
|
|
4418f4 |
if (!-f $certfile) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Was not able to create a certificate for this ".
|
|
|
4418f4 |
"host:\n\nPress return to exit");
|
|
|
4418f4 |
unlink($noisefile) if $noisefile;
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
if ($keyfile && (-f $keyfile)) {
|
|
|
4418f4 |
if (chmod(0400, $keyfile) != 1) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Could not set permissions of private key file.\n".
|
|
|
4418f4 |
"$keyfile");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
unlink($noisefile) if $noisefile;
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
if ($noisefile) {
|
|
|
4418f4 |
unlink($noisefile);
|
|
|
4418f4 |
$noisefile = '';
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Create a certificate-signing request file that can be submitted to a
|
|
|
4418f4 |
# Certificate Authority (CA) for processing into a finished certificate.
|
|
|
4418f4 |
# Use keyutil which exports key.
|
|
|
4418f4 |
sub genRequestOpenSSL
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($keyfile,$csrfile, # output
|
|
|
4418f4 |
$subject,$days,$noisefile,$pwdfile) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
use integer;
|
|
|
4418f4 |
my $months = $days ? $days / 30 : 24;
|
|
|
4418f4 |
|
|
|
4418f4 |
# build the arguments for a gen request call
|
|
|
4418f4 |
my $args = "-c genreq ";
|
|
|
4418f4 |
$args .= "-g $bits ";
|
|
|
4418f4 |
$args .= "-s $subject ";
|
|
|
4418f4 |
$args .= "-v $months ";
|
|
|
4418f4 |
$args .= "-a "; ## using ascii
|
|
|
4418f4 |
$args .= "-o $csrfile ";
|
|
|
4418f4 |
$args .= "-k $keyfile ";
|
|
|
4418f4 |
$args .= "-e $keyEncPassword " if $keyEncPassword;
|
|
|
4418f4 |
# there is no password when the
|
|
|
4418f4 |
# user wants the key in the clear
|
|
|
4418f4 |
$args .= "-z $noisefile " if $noisefile;
|
|
|
4418f4 |
|
|
|
4418f4 |
nssUtilCmd("$bindir/keyutil", $args);
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($noisefile) {
|
|
|
4418f4 |
unlink($noisefile);
|
|
|
4418f4 |
$noisefile = '';
|
|
|
4418f4 |
}
|
|
|
4418f4 |
Newt::Resume();
|
|
|
4418f4 |
|
|
|
4418f4 |
if (!-f $csrfile) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Unable to create a cert signing request for this ".
|
|
|
4418f4 |
"host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
if ($keyfile && !(-f $keyfile)) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Unable to create a key for this ".
|
|
|
4418f4 |
"host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
if (chmod(0400, $keyfile) != 1) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Could not set permissions of private key file.\n".
|
|
|
4418f4 |
"$keyfile");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Renew a certificate which is stored in the nss database
|
|
|
4418f4 |
sub renewCertNSS
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($csrfile, $dbdir, $dbprefix, $nickname, $days, $pwdfile) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
use integer;
|
|
|
4418f4 |
my $months = $days ? $days / 30 : 24;
|
|
|
4418f4 |
|
|
|
4418f4 |
# Build the arguments for a certificate renewal request
|
|
|
4418f4 |
# This is a request where we reuse the existing key pair
|
|
|
4418f4 |
|
|
|
4418f4 |
my $args = "-R ";
|
|
|
4418f4 |
$args .= "-d $dbdir ";
|
|
|
4418f4 |
$args .= "-p $dbprefix " if $dbprefix;
|
|
|
4418f4 |
$args .= "-a "; ## using ascii
|
|
|
4418f4 |
$args .= "-k $nickname "; ## pass cert nickname as key id
|
|
|
4418f4 |
$args .= "-f $pwdfile " if $pwdfile;
|
|
|
4418f4 |
$args .= "-v $months ";
|
|
|
4418f4 |
$args .= "-o $csrfile ";
|
|
|
4418f4 |
|
|
|
4418f4 |
nssUtilCmd("$bindir/certutil", $args);
|
|
|
4418f4 |
|
|
|
4418f4 |
if (!-f $csrfile) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Was not able to create a CSR for this ".
|
|
|
4418f4 |
"host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Renew a certificate which is stored in a PEM file
|
|
|
4418f4 |
sub renewCertOpenSSL
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($csrfile, # output
|
|
|
4418f4 |
$certfile,$keyfile,$cacert,$days) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
use integer;
|
|
|
4418f4 |
my $months = $days ? $days / 30 : 24;
|
|
|
4418f4 |
|
|
|
4418f4 |
# Build the arguments for a certificate renewal request
|
|
|
4418f4 |
# This is a request where we reuse the existing key pair
|
|
|
4418f4 |
|
|
|
4418f4 |
my $args = "--command genreq ";
|
|
|
4418f4 |
$args .= "--ascii "; ## using ascii
|
|
|
4418f4 |
$args .= "--renew $certfile ";
|
|
|
4418f4 |
$args .= "--input $keyfile ";
|
|
|
4418f4 |
$args .= "--cacert " if $cacert;
|
|
|
4418f4 |
$args .= "--filepwdnss $pwdfile " if $pwdfile;
|
|
|
4418f4 |
$args .= "--validity $months ";
|
|
|
4418f4 |
$args .= "--out $csrfile ";
|
|
|
4418f4 |
### pass $noisefile?
|
|
|
4418f4 |
|
|
|
4418f4 |
nssUtilCmd("$bindir/keyutil", $args);
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Resume();
|
|
|
4418f4 |
|
|
|
4418f4 |
if (!-f $csrfile) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Close",
|
|
|
4418f4 |
"Unable to create a cert signing request for this ".
|
|
|
4418f4 |
"host:\n\nPress return to exit");
|
|
|
4418f4 |
Newt::Finished();
|
|
|
4418f4 |
exit 1;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub AddField
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($panel, $row, $msg, $default, $width, $topspace, $flags) = (@_, 0, 0);
|
|
|
4418f4 |
my $entry;
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, $row, Newt::Label($msg), Newt::NEWT_ANCHOR_RIGHT(), 0, $topspace);
|
|
|
4418f4 |
$entry = Newt::Entry($width, $flags, $default);
|
|
|
4418f4 |
$panel->Add(1, $row, $entry, Newt::NEWT_ANCHOR_LEFT(), 1, $topspace);
|
|
|
4418f4 |
|
|
|
4418f4 |
$entry;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub getCertDetails
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($fqdn, $msg, $iscsr) = (@_, 0);
|
|
|
4418f4 |
my $cert;
|
|
|
4418f4 |
my $panel;
|
|
|
4418f4 |
my $subp;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $ents = {}, $cert = {};
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel = Newt::Panel(1, 3, "Enter details for your certificate");
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, Newt::TextboxReflowed(65, 10, 10, 0, $msg));
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($iscsr) {
|
|
|
4418f4 |
$subp = Newt::Panel(2, 9);
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
$subp = Newt::Panel(2, 6);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$ents{'C'} = AddField($subp, 0, "Country Name (ISO 2 letter code)", "GB", 3);
|
|
|
4418f4 |
$ents{'ST'} = AddField($subp, 1,
|
|
|
4418f4 |
"State or Province Name (full name)", "Berkshire", 20, 0,
|
|
|
4418f4 |
Newt::NEWT_ENTRY_SCROLL());
|
|
|
4418f4 |
$ents{'L'} = AddField($subp, 2, "Locality Name (e.g. city)", "Newbury", 20, 0,
|
|
|
4418f4 |
Newt::NEWT_ENTRY_SCROLL());
|
|
|
4418f4 |
$ents{'O'} = AddField($subp, 3,
|
|
|
4418f4 |
"Organization Name (eg, company)", "My Company Ltd", 30, 0,
|
|
|
4418f4 |
Newt::NEWT_ENTRY_SCROLL());
|
|
|
4418f4 |
$ents{'OU'} = AddField($subp, 4, "Organizational Unit Name (eg, section)", "", 30, 0,
|
|
|
4418f4 |
Newt::NEWT_ENTRY_SCROLL());
|
|
|
4418f4 |
$ents{'CN'} = AddField($subp, 5,
|
|
|
4418f4 |
"Common Name (fully qualified domain name)", $fqdn, 30, 1,
|
|
|
4418f4 |
Newt::NEWT_ENTRY_SCROLL());
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($iscsr) {
|
|
|
4418f4 |
|
|
|
4418f4 |
my $msg = "Extra attributes for certificate request:";
|
|
|
4418f4 |
|
|
|
4418f4 |
$subp->Add(0, 6, Newt::Textbox(length($msg), 1, 0, $msg),
|
|
|
4418f4 |
Newt::NEWT_ANCHOR_RIGHT());
|
|
|
4418f4 |
|
|
|
4418f4 |
$ents{'Challenge'} = AddField($subp, 7, "Optional challenge password",
|
|
|
4418f4 |
"", 20, 0);
|
|
|
4418f4 |
$ents{'CompanyName'} = AddField($subp, 8, "Optional company name", "", 30, 0,
|
|
|
4418f4 |
Newt::NEWT_ENTRY_SCROLL());
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 1, $subp, 0, 0, 1);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton(), 0, 0, 0, 0, -1);
|
|
|
4418f4 |
|
|
|
4418f4 |
while (1) {
|
|
|
4418f4 |
|
|
|
4418f4 |
# Pass "Ignore" to make enter go to next widget.
|
|
|
4418f4 |
$ret = &RunForm($panel, "Ignore");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($ret eq "Next" && $iscsr) {
|
|
|
4418f4 |
my $pass = $ents{'Challenge'}->Get();
|
|
|
4418f4 |
if (length($pass) > 0 && length($pass) < 4) {
|
|
|
4418f4 |
Newt::newtWinMessage("Error", "Retry",
|
|
|
4418f4 |
"The challenge password must be at least four characters in length");
|
|
|
4418f4 |
# Move focus to challenge password field
|
|
|
4418f4 |
$panel->Focus($ents{'Challenge'});
|
|
|
4418f4 |
# and go again.
|
|
|
4418f4 |
next;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
last;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($ret eq "Cancel" or $ret eq "Back") {
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $subp;
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$cert{'C'} = $ents{'C'}->Get();
|
|
|
4418f4 |
$cert{'ST'} = $ents{'ST'}->Get();
|
|
|
4418f4 |
$cert{'L'} = $ents{'L'}->Get();
|
|
|
4418f4 |
$cert{'O'} = $ents{'O'}->Get();
|
|
|
4418f4 |
$cert{'OU'} = $ents{'OU'}->Get();
|
|
|
4418f4 |
$cert{'CN'} = $ents{'CN'}->Get();
|
|
|
4418f4 |
|
|
|
4418f4 |
# Escape commas
|
|
|
4418f4 |
foreach my $part (keys %cert) {
|
|
|
4418f4 |
$cert{$part} =~ s/,/\\\\,/g;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Build the subject from the details
|
|
|
4418f4 |
|
|
|
4418f4 |
$SEP = ", ";
|
|
|
4418f4 |
$subject = 'CN' . "=" . $cert{'CN'};
|
|
|
4418f4 |
$subject = $subject . $SEP . 'OU' . "=" . $cert{'OU'} if $cert{'OU'};
|
|
|
4418f4 |
$subject = $subject . $SEP . 'O' . "=" . $cert{'O'} if $cert{'O'};
|
|
|
4418f4 |
$subject = $subject . $SEP . 'L' . "=" . $cert{'L'} if $cert{'L'};
|
|
|
4418f4 |
$subject = $subject . $SEP . 'ST' . "=" . $cert{'ST'} if $cert{'ST'};
|
|
|
4418f4 |
$subject = $subject . $SEP . 'C' . "=" . $cert{'C'} if $cert{'C'};
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($iscsr) {
|
|
|
4418f4 |
$cert{'CompanyName'} = $ents{'CompanyName'}->Get();
|
|
|
4418f4 |
$cert{'Challenge'} = $ents{'Challenge'}->Get();
|
|
|
4418f4 |
$subject = $subject . $SEP . 'CompanyName' ."=" . $cert{'CompanyName'} if $cert{'CompanyName'};
|
|
|
4418f4 |
$subject = $subject . $SEP . 'Challenge' ."=" . $cert{'Challenge'} if $cert{'Challenge'};
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
|
|
|
4418f4 |
undef $subp;
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
# must escape the double quotes because
|
|
|
4418f4 |
# it will be embedded in another string
|
|
|
4418f4 |
$subject = "\"" . "$subject" . "\"";
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub whichCAWindow {
|
|
|
4418f4 |
return "Skip" unless $useca;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $title = <
|
|
|
4418f4 |
Please choose the Certificate Authority you wish to send
|
|
|
4418f4 |
your certificate request to
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 3, "Choose Certificate Authority");
|
|
|
4418f4 |
my $listbox = Newt::Listbox(4, 0);
|
|
|
4418f4 |
my $text = Newt::Textbox(60, 2, 0, $title);
|
|
|
4418f4 |
my @listitems = ("Equifax","Thawte","VeriSign","Other");
|
|
|
4418f4 |
undef $myca;
|
|
|
4418f4 |
|
|
|
4418f4 |
$listbox->Append(@listitems);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 0, $text);
|
|
|
4418f4 |
$panel->Add(0, 1, $listbox, 0, 0, 1);
|
|
|
4418f4 |
if ($genreq_mode) {
|
|
|
4418f4 |
$panel->Add(0, 2, DoubleButton("Next","Cancel"));
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
$panel->Add(0, 2, NextBackCancelButton());
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::newtListboxSetCurrent($listbox->{co}, 0);
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Draw();
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
|
|
|
4418f4 |
$myca = $listbox->Get();
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
Newt::Refresh();
|
|
|
4418f4 |
return $ret;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Cert signing request generation for renewal
|
|
|
4418f4 |
sub renewCert
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my ($csrfile) = @_;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $tempDbDir = "/tmp/nss.".$$;
|
|
|
4418f4 |
|
|
|
4418f4 |
# Get a comfirmation
|
|
|
4418f4 |
my $msg = "You are about to issue a certificate renewal";
|
|
|
4418f4 |
my $panel = Newt::Panel(1, 2, "Certificate Renewal");
|
|
|
4418f4 |
$panel->Add(0, 0,
|
|
|
4418f4 |
Newt::TextboxReflowed(60, 10, 10, 0,
|
|
|
4418f4 |
"Would you like to send a Certificate Request" .
|
|
|
4418f4 |
"for\n\n$servername".
|
|
|
4418f4 |
"\nto a Certificate Authority (CA)?"));
|
|
|
4418f4 |
|
|
|
4418f4 |
$panel->Add(0, 1, DoubleButton("Yes", "No"));
|
|
|
4418f4 |
$ret = &RunForm($panel);
|
|
|
4418f4 |
$panel->Hide();
|
|
|
4418f4 |
undef $panel;
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Cancel" if $ret eq "Cancel";
|
|
|
4418f4 |
|
|
|
4418f4 |
# Cert to renew could be in the nss database or in a pem file
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($nss) {
|
|
|
4418f4 |
# Renew cert in the nss database
|
|
|
4418f4 |
renewCertNSS($csrfile, $modNssDbDir, $nssDBPrefix,
|
|
|
4418f4 |
$nssNickname, $days, $tmpPasswordFile);
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
# Renew cert in a PEM file
|
|
|
4418f4 |
renewCertOpenSSL($csrfile, $certfile, $keyfile, $cacert, $days);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub genReqWindow
|
|
|
4418f4 |
{
|
|
|
4418f4 |
return "Skip" unless $useca;
|
|
|
4418f4 |
|
|
|
4418f4 |
$keyfile = $ssltop."/private/".$servername.".key";
|
|
|
4418f4 |
$certfile = $ssltop."/certs/".$servername.".crt";
|
|
|
4418f4 |
|
|
|
4418f4 |
$num = 0;
|
|
|
4418f4 |
while (-f $ssltop."/certs/".$servername.".$num.csr") {
|
|
|
4418f4 |
$num++;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
$csrfile = $ssltop."/certs/".$servername.".$num.csr";
|
|
|
4418f4 |
|
|
|
4418f4 |
return renewCert($csrfile) if $renew;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $msg = "You are about to be asked to enter information that will be ".
|
|
|
4418f4 |
"incorporated into your certificate request to a CA. What you are about to ".
|
|
|
4418f4 |
"enter is what is called a Distinguished Name or a DN. There are ".
|
|
|
4418f4 |
"quite a few fields but you can leave some blank.";
|
|
|
4418f4 |
|
|
|
4418f4 |
my $ret = getCertDetails($servername,$msg, 1);
|
|
|
4418f4 |
return $ret unless ($ret eq "Next");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($nss) {
|
|
|
4418f4 |
genRequestNSS($csrfile, $subject, 730, $randfile, $tmpPasswordFile);
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
genRequestOpenSSL($keyfile, $csrfile,
|
|
|
4418f4 |
$subject, 730, $randfile, $tmpPasswordFile);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
# Now make a temporary cert; skip for OpenSSL since it would
|
|
|
4418f4 |
# overwrite the existing key.
|
|
|
4418f4 |
if (!$genreq_mode && !-f $certfile && $nss) {
|
|
|
4418f4 |
makeCertNSS($certfile,
|
|
|
4418f4 |
$subject, $cert_days, $nssNickname,
|
|
|
4418f4 |
$randfile, $tmpPasswordFile);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
undef $csrtext;
|
|
|
4418f4 |
open(CSR,"<$csrfile");
|
|
|
4418f4 |
while(<CSR>) {
|
|
|
4418f4 |
$csrtext .= $_;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
close(CSR);
|
|
|
4418f4 |
|
|
|
4418f4 |
# Fixme: Disabling csr display, not recognized as PEM base 64 encoded
|
|
|
4418f4 |
$csrtext = "" if $renew && !$nss;
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Suspend();
|
|
|
4418f4 |
|
|
|
4418f4 |
# Clear the screen
|
|
|
4418f4 |
system("clear");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($myca eq "VeriSign") {
|
|
|
4418f4 |
|
|
|
4418f4 |
print <
|
|
|
4418f4 |
You now need to connect to the VeriSign site and submit your CSR. The
|
|
|
4418f4 |
page at https://digitalid.verisign.com/server/help/hlpEnrollServer.htm
|
|
|
4418f4 |
explains how to do this, and what additional documention will be
|
|
|
4418f4 |
required before VeriSign can sign your certificate.
|
|
|
4418f4 |
|
|
|
4418f4 |
Your CSR is given below. To submit it to VeriSign, go through the
|
|
|
4418f4 |
enrollment process starting at
|
|
|
4418f4 |
https://digitalid.verisign.com/server/enrollIntro.htm. Paste the CSR,
|
|
|
4418f4 |
including the BEGIN and END lines, when prompted in step 4.
|
|
|
4418f4 |
|
|
|
4418f4 |
$csrtext
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($myca eq "Thawte") {
|
|
|
4418f4 |
print <
|
|
|
4418f4 |
You now need to connect to the Thawte site and submit your CSR. The
|
|
|
4418f4 |
page at https://www.thawte.com/certs/server/request.html explains how
|
|
|
4418f4 |
to do this, and what additional documention will be required before
|
|
|
4418f4 |
Thawte can sign your certificate.
|
|
|
4418f4 |
|
|
|
4418f4 |
Your CSR is given below. To submit it to Thawte, go to
|
|
|
4418f4 |
https://www.thawte.com/cgi/server/step1.exe and select "Web Server
|
|
|
4418f4 |
Certificate". Paste the CSR, including the BEGIN and END lines, when
|
|
|
4418f4 |
prompted.
|
|
|
4418f4 |
|
|
|
4418f4 |
$csrtext
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($myca eq "Equifax") {
|
|
|
4418f4 |
print <
|
|
|
4418f4 |
You now need to connect to the Equifax site and submit your CSR. The
|
|
|
4418f4 |
page at http://www.equifaxsecure.com/ebusinessid/c2net/ explains how
|
|
|
4418f4 |
to do this, and what additional documention will be required before
|
|
|
4418f4 |
Equifax can sign your certificate.
|
|
|
4418f4 |
|
|
|
4418f4 |
Your CSR is given below. To submit it to Equifax, go to
|
|
|
4418f4 |
http://www.equifaxsecure.com/ebusinessid/c2net/
|
|
|
4418f4 |
Paste the CSR, including the BEGIN and END lines, when prompted.
|
|
|
4418f4 |
|
|
|
4418f4 |
$csrtext
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($myca eq "Other") {
|
|
|
4418f4 |
print <
|
|
|
4418f4 |
You now need to submit your CSR and documentation to your certificate
|
|
|
4418f4 |
authority. Submitting your CSR may involve pasting it into an online
|
|
|
4418f4 |
web form, or mailing it to a specific address. In either case, you
|
|
|
4418f4 |
should include the BEGIN and END lines.
|
|
|
4418f4 |
|
|
|
4418f4 |
$csrtext
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
print <
|
|
|
4418f4 |
|
|
|
4418f4 |
A copy of this CSR has been saved in the file
|
|
|
4418f4 |
$csrfile
|
|
|
4418f4 |
|
|
|
4418f4 |
Press return when ready to continue
|
|
|
4418f4 |
EOT
|
|
|
4418f4 |
$_=<STDIN>;
|
|
|
4418f4 |
Newt::Resume();
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
|
|
|
4418f4 |
sub genCertWindow
|
|
|
4418f4 |
{
|
|
|
4418f4 |
return "Skip" if $useca;
|
|
|
4418f4 |
|
|
|
4418f4 |
$keyfile = $ssltop."/private/".$servername.".key";
|
|
|
4418f4 |
$certfile = $ssltop."/certs/".$servername.".crt";
|
|
|
4418f4 |
|
|
|
4418f4 |
my $msg = "You are about to be asked to enter information that will be ".
|
|
|
4418f4 |
"made into a self-signed certificate for your server. What you are ".
|
|
|
4418f4 |
"about to ".
|
|
|
4418f4 |
"enter is what is called a Distinguished Name or a DN. There are ".
|
|
|
4418f4 |
"quite a few fields but you can leave some blank";
|
|
|
4418f4 |
|
|
|
4418f4 |
my $ret = getCertDetails($servername,$msg, 0);
|
|
|
4418f4 |
return $ret unless ($ret eq "Next");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($nss) {
|
|
|
4418f4 |
makeCertNSS($certfile, # output
|
|
|
4418f4 |
$subject,$cert_days,$nssNickname,
|
|
|
4418f4 |
$randfile,$tmpPasswordFile);
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
makeCertOpenSSL($keyfile,$certfile, # output
|
|
|
4418f4 |
$subject,$cert_days,
|
|
|
4418f4 |
$randfile,$tmpPasswordFile);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub genCACertWindow
|
|
|
4418f4 |
{
|
|
|
4418f4 |
return "Skip" if $useca;
|
|
|
4418f4 |
|
|
|
4418f4 |
$keyfile = $cadir."/private/".$servername;
|
|
|
4418f4 |
$certfile = $cadir."/".$servername;
|
|
|
4418f4 |
|
|
|
4418f4 |
my $msg = "You are about to be asked to enter information that will be ".
|
|
|
4418f4 |
"made into a certificate for your CA key. What you are ".
|
|
|
4418f4 |
"about to ".
|
|
|
4418f4 |
"enter is what is called a Distinguished Name or a DN. There are ".
|
|
|
4418f4 |
"quite a few fields but you can leave some blank";
|
|
|
4418f4 |
|
|
|
4418f4 |
my $ret = getCertDetails("",$msg, 0);
|
|
|
4418f4 |
return $ret unless ($ret eq "Next");
|
|
|
4418f4 |
|
|
|
4418f4 |
if ($nss) {
|
|
|
4418f4 |
makeCertNSS('',$subject,730,$nssNickname,
|
|
|
4418f4 |
$randfile,$tmpPasswordFile);
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
makeCertOpenSSL($keyfile,$certfile,$subject,730,
|
|
|
4418f4 |
$randfile,$tmpPasswordFile);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
sub getRandomDataWindow()
|
|
|
4418f4 |
{
|
|
|
4418f4 |
my $randbits = $bits * 2;
|
|
|
4418f4 |
|
|
|
4418f4 |
# Get some random data from truerand library
|
|
|
4418f4 |
#
|
|
|
4418f4 |
if (!$skip_random) {
|
|
|
4418f4 |
FinishRoot();
|
|
|
4418f4 |
InitRoot(0);
|
|
|
4418f4 |
makerand($randbits,$randfile);
|
|
|
4418f4 |
FinishRoot();
|
|
|
4418f4 |
|
|
|
4418f4 |
# Get some random data from keystrokes
|
|
|
4418f4 |
#
|
|
|
4418f4 |
Newt::Suspend();
|
|
|
4418f4 |
|
|
|
4418f4 |
system("$bindir/keyrand $randbits $randfile");
|
|
|
4418f4 |
|
|
|
4418f4 |
Newt::Resume();
|
|
|
4418f4 |
} else {
|
|
|
4418f4 |
# No extra random seed is being provided to nss. Rely
|
|
|
4418f4 |
# on nss faster autoseeding process. The nss utilities
|
|
|
4418f4 |
# will prompt the user for some keystrokes.
|
|
|
4418f4 |
$randfile = '';
|
|
|
4418f4 |
}
|
|
|
4418f4 |
return "Next";
|
|
|
4418f4 |
}
|