Added feature to check and change private key password

master
Thomas Hooge 4 years ago
parent 1b49cf92c0
commit 1957b9f56c
  1. 3
      lib/CA.pm
  2. 117
      lib/GUI.pm
  3. 80
      lib/KEY.pm
  4. 43
      lib/OpenSSL.pm
  5. 1
      templates/tinyca.cnf

@ -132,6 +132,7 @@ sub open_ca {
main::printd("Request-Type: " . ($self->{'cfg'}->{global}{default_req_type} // 'none'));
main::printd("Default bits server: " . ($self->{'cfg'}->{server}{default_bits} // 'none'));
main::printd("Default bits user: " . ($self->{'cfg'}->{user}{default_bits} // 'none'));
main::printd("Default key cipher: " . ($self->{'cfg'}->{user}{default_cipher} // 'none'));
# update config (necessary for update from old tinyca)
$cnf = $self->{$opts->{'name'}}->{'cnf'};
@ -659,7 +660,7 @@ sub import_ca {
$opts->{'cakeydata'} = $main->{'KEY'}->key_change_passwd(
$main, $opts->{'cakeyfile'}, $opts->{'passwd'},
$opts->{'newpasswd'});
$opts->{'newpasswd'}, 'ca');
if($opts->{'cakeydata'} eq 1) {
return;

@ -1760,6 +1760,109 @@ sub show_key_import_dialog {
return;
}
#
# check key password
#
sub show_key_check_dialog {
my ($self, $keyfile) = @_;
my ($box, $button_close, $button_check, $table, $label_result);
my ($entry, $passwd, $result);
$passwd = '';
$button_close = Gtk2::Button->new_from_stock('gtk-close');
$button_close->signal_connect('clicked', sub { $box->destroy() });
$box = GUI::HELPERS::dialog_box(
_("Check password"), _("Check password on private key file"),
$button_close);
$table = Gtk2::Table->new(2, 3, 0);
$table->set_col_spacing(0, 10);
$box->vbox->add($table);
$entry = GUI::HELPERS::entry_to_table(
_("Password:"),
\$passwd, $table, 0, 0);
$entry->grab_focus();
$button_check = Gtk2::Button->new(_("Check"));
$button_check->signal_connect('clicked', sub {
$passwd =~ s/^\s+|\s+$//g;
if(length($passwd) == 0) {
$label_result->set_label(_("Enter password"));
return;
}
$result = $self->{'OpenSSL'}->checkpass($keyfile, $passwd);
$label_result->set_label($result == 0 ? _("OK") : _("ERROR"));
});
$table->attach_defaults($button_check, 2, 3, 0, 1);
$label_result = Gtk2::Label->new("");
$table->attach_defaults($label_result, 1, 2, 1, 2);
$box->show_all();
return;
}
#
# change password for key
#
sub show_key_passwd_dialog {
my ($self, $keyfile) = @_;
my ($box, $button_ok, $button_cancel, $pwtable);
my ($entry_old, $entry_new1, $entry_new2);
my ($passwd, $newpasswd, $newpasswd2, $result);
$button_ok = Gtk2::Button->new_from_stock('gtk-ok');
$button_ok->signal_connect('clicked', sub {
if($newpasswd eq $newpasswd2) {
$result = $self->{'KEY'}->key_change_passwd($self, $keyfile, $passwd, $newpasswd, 'key');
if($result == 0) {
main::printd("password changed");
$box->destroy();
} else {
GUI::HELPERS::print_error(_("Password change failed"));
}
} else {
GUI::HELPERS::print_warning(_("New password does not match"));
}
});
# $button_ok->grab_default();
$button_cancel = Gtk2::Button->new_from_stock('gtk-cancel');
$button_cancel->signal_connect('clicked', sub { $box->destroy() });
$box = GUI::HELPERS::dialog_box(
_("Change password"), _("Change password on private key file"),
$button_ok, $button_cancel);
$pwtable = Gtk2::Table->new(3, 2, 0);
$pwtable->set_col_spacing(0, 10);
$box->vbox->add($pwtable);
$entry_old = GUI::HELPERS::entry_to_table(
_("Old password:"),
\$passwd, $pwtable, 0, 0);
$entry_old->grab_focus();
$entry_new1 = GUI::HELPERS::entry_to_table(
_("New password:"),
\$newpasswd, $pwtable, 1, 0);
$entry_new2 = GUI::HELPERS::entry_to_table(
_("Confirm password:"),
\$newpasswd2, $pwtable, 2, 0);
$box->show_all();
return;
}
#
# get password for exporting keys
#
@ -3060,6 +3163,20 @@ sub _create_key_menu {
$self->{'keymenu'} = Gtk2::Menu->new();
$item = Gtk2::ImageMenuItem->new( _("Check password"));
$item->signal_connect(activate =>
sub { $self->{'KEY'}->check_passwd($self) });
$image = Gtk2::Image->new_from_stock('gtk-info', 'menu');
$item->set_image($image);
$self->{'keymenu'}->insert($item, -1);
$item = Gtk2::ImageMenuItem->new( _("Change password"));
$item->signal_connect(activate =>
sub { $self->{'KEY'}->set_password($self) });
$image = Gtk2::Image->new_from_stock('gtk-convert', 'menu');
$item->set_image($image);
$self->{'keymenu'}->insert($item, -1);
$item = Gtk2::ImageMenuItem->new( _("Export Key"));
$item->signal_connect(activate =>
sub { $self->{'KEY'}->get_export_key($self) });

@ -473,8 +473,65 @@ sub _check_key {
return($name);
}
#
# Check password
#
sub check_passwd {
my ($self, $main) = @_;
my ($keyname, $key, $keyfile);
$key = $main->{'keybrowser'}->selection_dn();
if(not defined $key) {
GUI::HELPERS::print_info(_("Please select a Key first"));
return;
}
$keyname = HELPERS::enc_base64($key);
$keyfile = $main->{'cadir'}."/keys/".$keyname.".pem";
if(not -s $keyfile) {
GUI::HELPERS::print_warning(_("Key file not found:".$keyfile));
return;
}
$main->show_key_check_dialog($keyfile);
return;
}
#
# Set new password for key
#
sub set_password {
my ($self, $main) = @_;
my ($keyname, $key, $keyfile);
$key = $main->{'keybrowser'}->selection_dn();
if(not defined $key) {
GUI::HELPERS::print_info(_("Please select a Key first"));
return;
}
$keyname = HELPERS::enc_base64($key);
$keyfile = $main->{'cadir'}."/keys/".$keyname.".pem";
if(not -s $keyfile) {
GUI::HELPERS::print_warning(_("Key file not found:".$keyfile));
return;
}
$main->show_key_passwd_dialog($keyfile);
return;
}
sub key_change_passwd {
my ($self, $main, $file, $oldpass, $newpass) = @_;
my ($self, $main, $file, $oldpass, $newpass, $mode) = @_;
my $opts = {};
my ($t, $ret, $ext);
@ -483,7 +540,7 @@ sub key_change_passwd {
my($type);
# ckeck file format
# check file format
open(KEY, "<$file") || do {
$t = sprintf(_("Can't open Key file:\n%s"),
$file);
@ -495,7 +552,7 @@ sub key_change_passwd {
$inform = "PEM";
$type = "RSA";
last;
} elsif(/BEGIN RSA PRIVATE KEY/){
} elsif(/BEGIN DSA PRIVATE KEY/){
$inform = "PEM";
$type = "DSA";
last;
@ -519,15 +576,28 @@ sub key_change_passwd {
GUI::HELPERS::set_cursor($main, 0);
if($ret eq 1) {
if($mode eq 'ca') {
$t = _("Generating key failed");
if($ext =~ /unable to load Private Key/) {
$t .= _("The password for your old CA Key is wrong");
}
} else {
$t = _("Change password failed");
}
GUI::HELPERS::print_warning(($t), $ext);
return($ret);
return(1);
}
if($mode eq 'key') {
# Write out key with new password
open(OUT, ">$file") || do {
GUI::HELPERS::print_warning(sprintf(_("Can't open output file: %s: %s"), $file, $!));
return(1);
};
print OUT $ret;
close(OUT);
return(0);
}
return($ret);
}

@ -989,6 +989,49 @@ sub convkey {
return($tmp);
}
sub checkpass {
my ($self, $keyfile, $passwd) = @_;
my ($cmd, $ext, $ret, $pid, $type);
# Check type: RSA or DSA
open(KEY, "<$keyfile") || do {
GUI::HELPERS::print_warning(sprintf(_("Can't open Key file:\n%s"), $keyfile));
return(1);
};
$type = "UNKNOWN";
while(<KEY>) {
if(/BEGIN RSA PRIVATE KEY/) {
$type = "rsa";
last;
} elsif(/BEGIN DSA PRIVATE KEY/){
$type = "dsa";
last;
}
}
if($type eq "UNKNOWN") {
GUI::HELPERS::print_warning(_("Invalid key encryption type"));
return(1);
}
$cmd = "$self->{'bin'} $type -noout";
$cmd .= " -in \"$keyfile\"";
$cmd .= " -passin env:SSLPASS";
$ENV{'SSLPASS'} = $passwd;
my($rdfh, $wtfh);
$ext = "$cmd\n\n";
$pid = open3($wtfh, $rdfh, $rdfh, $cmd);
while(<$rdfh>) {
$ext .= $_;
}
waitpid($pid, 0);
$ret = $? >> 8;
delete($ENV{'SSLPASS'});
return($ret);
}
sub genp12 {
my $self = shift;
my $opts = { @_ };

@ -2,6 +2,7 @@
use_metadb = no
default_req_type = user
default_domain = example.com
default_cipher = aes256
[server]
default_bits = 4096