Checkin of certificate manager module
authorJamie Cameron <jcameron@webmin.com>
Thu, 26 Jul 2007 21:23:50 +0000 (21:23 +0000)
committerJamie Cameron <jcameron@webmin.com>
Thu, 26 Jul 2007 21:23:50 +0000 (21:23 +0000)
37 files changed:
certmgr/CHANGELOG [new file with mode: 0644]
certmgr/acl_security.pl [new file with mode: 0755]
certmgr/certmgr-lib.pl [new file with mode: 0755]
certmgr/config-*-linux [new file with mode: 0755]
certmgr/config-freebsd [new file with mode: 0755]
certmgr/config-macos [new file with mode: 0755]
certmgr/config-openbsd [new file with mode: 0755]
certmgr/config-redhat-linux [new file with mode: 0755]
certmgr/config-solaris [new file with mode: 0755]
certmgr/config.info [new file with mode: 0755]
certmgr/config_info.pl [new file with mode: 0755]
certmgr/defaultacl [new file with mode: 0755]
certmgr/gencert.cgi [new file with mode: 0755]
certmgr/gencsr.cgi [new file with mode: 0755]
certmgr/help/intro.html [new file with mode: 0755]
certmgr/help/signcsr_ca_pass.html [new file with mode: 0644]
certmgr/images/decrypt.gif [new file with mode: 0755]
certmgr/images/delete.gif [new file with mode: 0755]
certmgr/images/encrypt.gif [new file with mode: 0755]
certmgr/images/export.gif [new file with mode: 0755]
certmgr/images/gencert.gif [new file with mode: 0755]
certmgr/images/gencsr.gif [new file with mode: 0755]
certmgr/images/icon.gif [new file with mode: 0755]
certmgr/images/import.gif [new file with mode: 0755]
certmgr/images/manual.gif [new file with mode: 0755]
certmgr/images/signcsr.gif [new file with mode: 0755]
certmgr/images/smallicon.gif [new file with mode: 0755]
certmgr/images/view.gif [new file with mode: 0755]
certmgr/import.cgi [new file with mode: 0755]
certmgr/index.cgi [new file with mode: 0755]
certmgr/lang/en [new file with mode: 0755]
certmgr/lang/es [new file with mode: 0755]
certmgr/manual.cgi [new file with mode: 0755]
certmgr/module.info [new file with mode: 0755]
certmgr/save_manual.cgi [new file with mode: 0755]
certmgr/signcsr.cgi [new file with mode: 0755]
certmgr/view.cgi [new file with mode: 0755]

diff --git a/certmgr/CHANGELOG b/certmgr/CHANGELOG
new file mode 100644 (file)
index 0000000..1f2eb0a
--- /dev/null
@@ -0,0 +1,9 @@
+---- Changes since 1.501 ----
+Added config-redhat-linux
+Modified config-* to include: ssl_cnf_file=/usr/share/ssl/openssl.cnf ssl_sign_ca_private_key= ssl_sign_ca_certificate= (JBB8)
+---- Changes since 1.502 ----
+Added edit capablity to ssl_cnf_file in config.info. Scripts edit_file.cgi and edit_cmd.cgi added to module (JBB8)
+---- Changes since 1.503 ----
+Added defaults for email and other cert attributes
+---- Changes since 1.504 ----
+Added a page for manually editing the OpenSSL config file
diff --git a/certmgr/acl_security.pl b/certmgr/acl_security.pl
new file mode 100755 (executable)
index 0000000..a11911e
--- /dev/null
@@ -0,0 +1,24 @@
+
+do 'certmgr-lib.pl';
+
+# acl_security_form(&options)
+# Output HTML for editing security options for the acl module
+sub acl_security_form
+{
+print "<tr> <td valign=top><b>$text{'acl_pages'}</b></td> <td colspan=3>\n";
+foreach $p (@pages) {
+       printf "<input type=checkbox name=%s value=1 %s> %s<br>\n",
+               $p, $_[0]->{$p} ? "checked" : "", $text{'index_'.$p};
+       }
+print "</td> </tr>\n";
+}
+
+# acl_security_save(&options)
+# Parse the form for security options for the acl module
+sub acl_security_save
+{
+foreach $p (@pages) {
+       $_[0]->{$p} = $in{$p};
+       }
+}
+
diff --git a/certmgr/certmgr-lib.pl b/certmgr/certmgr-lib.pl
new file mode 100755 (executable)
index 0000000..570e12c
--- /dev/null
@@ -0,0 +1,231 @@
+# certmgr-lib.pl
+
+do '../web-lib.pl';
+&init_config();
+%access = &get_module_acl();
+
+@pages = ( "gencert", "gencsr", "signcsr", "import", "view", "manual" );
+
+sub my_urlize{
+       my $temp=$_[0];
+       $temp=~s~([^/:.a-zA-Z0-9])~sprintf("%%%2x",ord($1))~eg;
+       return($temp);
+}
+
+sub print_cert_form{
+       my $form=$_[0];
+       my $certfield;
+       if ($form=~/^gen(.*)$/) {$certfield=$1."file";}
+       print <<EOF;
+$text{'gencert_password_notice'}
+<hr>
+<form action=$form.cgi method=post>
+<input type=hidden name=submitted value=generate>
+<table border>
+<tr $tb> <td align=center><b>$text{$form.'_header'}</b></td> </tr>
+<tr $cb> <td><table>
+<tr><td>$text{$form.'_'.$certfield}</td><td><input name=$certfield size=40 value="$in{$certfield}"></td></tr>
+<tr><td>$text{'keyfile'}</td><td><input name=keyfile size=40 value="$in{'keyfile'}"></td></tr>
+EOF
+       if ($form eq "gencert"){
+               print "<tr><td>$text{'keycertfile'}</td><td><input name=keycertfile size=40 value=\"$in{'keycertfile'}\"></td></tr>";
+       }
+print <<EOF;
+<tr><td>$text{'password'}</td><td><input name=password size=40 type=password value="$in{'password'}"></td></tr>
+<tr><td>$text{'confirm_password'}</td><td><input name=confirm_password size=40 type=password value="$in{'confirm_password'}"></td></tr>
+<tr><td>$text{'keysize'}</td><td>
+<table width=100%><tr>
+<td width=33%><input name=keysize type=radio value=512$checked[0]> 512</td>
+<td width=33%><input name=keysize type=radio value=1024$checked[1]> 1024</td>
+<td width=33%><input name=keysize type=radio value=2048$checked[2]> 2048</td>
+</tr></table>
+</td></tr>
+EOF
+       if ($form eq "gencert"){
+               print <<EOF;
+<tr><td>$text{$form.'_days'}</td><td><input name=days size=40 value="$in{'days'}"></td></tr>
+EOF
+       }
+       print <<EOF;
+<tr><td>$text{'cn'}</td><td><input name=cn size=40 value="$in{'cn'}"></td></tr>
+<tr><td>$text{'o'}</td><td><input name=o size=40 value="$in{'o'}"></td></tr>
+<tr><td>$text{'ou'}</td><td><input name=ou size=40 value="$in{'ou'}"></td></tr>
+<tr><td>$text{'l'}</td><td><input name=l size=40 value="$in{'l'}"></td></tr>
+<tr><td>$text{'st'}</td><td><input name=st size=40 value="$in{'st'}"></td></tr>
+<tr><td>$text{'c'}</td><td><input name=c size=2 maxlength=2 value="$in{'c'}"></td></tr>
+<tr><td>$text{'emailAddress'}</td><td><input name=emailAddress size=40 value="$in{'emailAddress'}"></td></tr>
+<tr> <td colspan=2 align=right>
+<input type=reset value="$text{'reset'}">
+<input type=submit value="$text{$form.'_generate'}"></td> </tr>
+
+</table></td></tr></table>
+</form>
+EOF
+}
+
+sub print_sign_form {
+       my $form=$_[0];
+       my $certfield;
+       print <<EOF;
+$text{'signcsr_desc'}
+<hr>
+<form action=$form.cgi method=post>
+<input type=hidden name=submitted value=sign>
+<table border>
+<tr $tb> <td align=center><b>$text{'signcsr_header'}</b></td> </tr>
+<tr $cb> <td><table>
+<tr><td>$text{'signcsr_csrfile'}</td><td><input name=csrfile size=40 value="$in{'csrfile'}"></td></tr>
+<tr><td>$text{'signcsr_signfile'}</td><td><input name=signfile size=40 value="$in{'signfile'}"></td></tr>
+<tr><td>$text{'signcsr_keyfile'}</td><td><input name=keyfile size=40 value="$in{'keyfile'}"></td></tr>
+<tr><td>$text{'signcsr_keycertfile'}</td><td><input name=keycertfile size=40 value="$in{'keycertfile'}"></td></tr>
+<tr><td><a onClick='window.open("/help.cgi/certmgr/signcsr_ca_pass", "help", "toolbar=no,menubar=no,scrollbars=yes,width=400,height=300,resizable=yes"); return false' href="/help.cgi/certmgr/signcsr_ca_pass"><b>$text{'signcsr_ca_passphrase'}</b></a></td><td> <input name=password size=40 type=password value="$in{'password'}"> </td></tr>
+<tr><td>$text{'signcsr_days'}</td><td><input name=days size=40 value="$in{'days'}"></td></tr>
+<tr> <td colspan=2 align=right>
+<input type=reset value="$text{'reset'}">
+<input type=submit value="$text{'signcsr_generate'}"></td> </tr>
+
+</table></td></tr></table>
+</form>
+EOF
+}
+
+sub print_cert_info{
+       my $full=$_[0];
+       my $certdata=$_[1];
+       my %issuer;
+       my %subject;
+       my @fields=('CN','O','OU','L','ST','C');
+       my $field;
+       foreach $field (@fields){
+               if ($certdata=~/^\s*Issuer:.*?\s+$field=(.*?)(, [A-Z]{1,2}|\/\w+=|$)/m) { $issuer{$field}=$1; }
+               if ($certdata=~/^\s*Subject:.*?\s+$field=(.*?)(, [A-Z]{1,2}|\/\w+=|$)/m) { $subject{$field}=$1; }
+       }
+       if (!($certdata=~/^\s*Issuer:/m)) { $text{'certmgrlib_issuer'}=""; }
+       if ($certdata=~/^\s*Issuer:.*?\/Email=(\S*?)(,\s*|$)/m) { $issuer{'emailAddress'}=$1;}
+       if ($certdata=~/^\s*Subject:.*?\/Email=(\S*?)(,\s*|$)/m) { $subject{'emailAddress'}=$1;}
+       if ($certdata=~/^\s*Not\s*After\s*:\s*(.*?)\s*$/m) { $subject{'expires'}=$1;}
+       if ($certdata=~/^\s*Not\s*Before\s*:\s*(.*?)\s*$/m) { $subject{'issued'}=$1;}
+       if ($certdata=~/^\s*MD5\s*Fingerprint=(.*?)\s*$/m) { $subject{'md5fingerprint'}=$1;}
+       if ($certdata=~/^\s*(\S*)\s*Public\s*Key:\s*\((.*?)\s*bit\)\s*$/m) { $subject{'keytype'}=$1; $subject{'keysize'}=$2;}
+       if ($certdata=~/^\s*Modulus\s*\(\d*\s*bit\):\s*((([0-9a-fA-F]{2}:)*\s*)*[0-9a-fA-F]{2})/ms) { $subject{'modulus'}=$1; }
+       if ($certdata=~/^\s*Exponent:\s*(.*?)\s*?$/m) { $subject{'exponent'}=$1; }
+       if ($subject{'L'} && ($subject{'ST'} || $subject{'C'})) {$subject{'L'}.=',';} #Append commas
+       if ($subject{'ST'} && $subject{'C'}) {$subject{'ST'}.=',';}                   #Append commas
+       if ($issuer{'L'} && ($issuer{'ST'} || $issuer{'C'})) {$issuer{'L'}.=',';}     #Append commas
+       if ($issuer{'ST'} && $issuer{'C'}) {$issuer{'ST'}.=',';}                      #Append commas
+       $subject{'modulus'}=~s/$/<\/code><br>/msg;
+       $subject{'modulus'}=~s/^/<code>/msg;
+       $subject{'modulus'}=~s/\s+//msg;
+       print "<table width=100%>\n";
+       print "<tr><td width=50%><b>$text{'certmgrlib_subject'}</b></td><td width=50%><b>$text{'certmgrlib_issuer'}</b></td></tr>\n";
+       print "<tr><td>$subject{'CN'}</td><td>$issuer{'CN'}</td></tr>\n";
+       print "<tr><td>$subject{'O'}</td><td>$issuer{'O'}</td></tr>\n";
+       print "<tr><td>$subject{'OU'}</td><td>$issuer{'OU'}</td></tr>\n";
+       print "<tr><td>$subject{'L'} $subject{'ST'} $subject{'C'}</td><td>$issuer{'L'} $issuer{'ST'} $issuer{'C'}</td></tr>\n";
+       print "<tr><td>$subject{'emailAddress'}</td><td>$issuer{'emailAddress'}</td></tr>\n";
+       if ($subject{'issued'}){
+               print "<tr><td colspan=2>$text{'issued_on'} $subject{'issued'}</td></tr>\n";
+               print "<tr><td colspan=2>$text{'expires_on'} $subject{'expires'}</td></tr>\n";
+       }
+       if ($full){
+               print "<tr><td>$text{'keysize'}</td><td>$subject{'keysize'}</td></tr>\n";
+               print "<tr><td>$text{'keytype'}</td><td>$subject{'keytype'}</td></tr>\n";
+       }
+       if ($full){
+               print "<tr><td>$text{'publicExponent'}</td><td>$subject{'exponent'}</td></tr>\n";
+               print "<tr><td colspan=2>$text{'modulus'}:<br>$subject{'modulus'}</td></tr>\n";
+       }
+       if ($subject{'md5fingerprint'}){
+               print "<tr><td colspan=2>$text{'md5fingerprint'}:<br>$subject{'md5fingerprint'}</td></tr>\n";
+       }
+       print "</table>\n";
+}
+
+sub print_key_info{
+       my $full=$_[0];
+       my $keydata=$_[1];
+       my %key;
+       my @fields=('modulus','privateExponent','prime1','prime2','exponent1','exponent2','coefficient');
+       my $field;
+       $keydata=~/^publicExponent:\s*(.*?)\s*?$/ms;
+       $key{'publicExponent'}=$1;
+       $keydata=~/^Private-Key:\s*\((\d*)\s*bit\)\s*?$/ms;
+       $key{'keysize'}=$1;
+       foreach $field (@fields){
+               if ($keydata=~/^$field:\s*((([0-9a-fA-F]{2}:)*\s*)*[0-9a-fA-F]{2})/ms) { $key{$field}=$1; }
+       }
+       print "<table width=100%>\n";
+       print "<tr><td ";
+       if ($full) { print "valign=top align=right"; }
+       print ">$text{'keysize'}:</td><td>$key{'keysize'}</td></tr>\n";
+       splice(@fields,1,0,'publicExponent');
+       if ($full) { foreach $field (@fields){
+               $key{$field}=~s/$/<\/code><br>/msg;
+               $key{$field}=~s/^/<code>/msg;
+               $key{$field}=~s/\s+//msg;
+               print "<tr><td valign=top align=right>$text{$field}:</td><td>$key{$field}</td></tr>\n";
+       } }
+       print "</table>\n";
+}
+
+sub pem_or_der{
+       my $filename=$_[0];
+       my $filetype=$_[1];
+       my $format;
+       my $cipher;
+       my $flag;
+       if ($filetype=~/^cert(ificate)?$/i){
+               open(PEM_OR_DER,$filename)||return("$text{'certmgrlib_e_file_open'} $filename");
+               while(<PEM_OR_DER>){ if (/^\s*-+BEGIN\s*CERTIFICATE-*\s*$/i) { $format="PEM" } }
+               close(PEM_OR_DER);
+               if (!$format) {$format="DER";}
+               open(PEM_OR_DER,"$config{'openssl_cmd'} x509 -in $filename -inform $format -text|")||return($text{'certmgrlib_e_exec'});
+               while (<PEM_OR_DER>){
+                       if (/^\s*Certificate:\s$/) { 
+                               close(PEM_OR_DER);
+                               return($format);
+                       }
+               }
+               close(PEM_OR_DER);
+               return($text{'certmgrlib_e_cert'});
+       }
+       if ($filetype=~/^key$/i){
+               open(PEM_OR_DER,$filename)||return("$text{'certmgrlib_e_file_open'} $filename");
+               while(<PEM_OR_DER>){
+                       if (/^\s*-+BEGIN\s*RSA\s*PRIVATE\s*KEY-*\s*$/i) { $format="PEM" }
+                       if (/^\s*Proc-Type:\s*\d*,ENCRYPTED\s*$/) { $flag=1; }
+                       if (($flag)&&(/^DEK-Info:\s*(.*?),.*$/i)) { $cipher=$1 }
+               }
+               close(PEM_OR_DER);
+               if ($cipher) { if (wantarray) {return(($format,$cipher));} return($format); }
+               else {$cipher="none";}
+               if (!$format) {$format="DER";}
+               open(PEM_OR_DER,"$config{'openssl_cmd'} rsa -in $filename -inform $format -text|")||return($text{'certmgrlib_e_exec'});
+               while (<PEM_OR_DER>){
+                       if (/^\s*Private-Key:\s(\d*\sbit)\s*$/) { 
+                               close(PEM_OR_DER);
+                               if (wantarray) {return(($format,$cipher));}
+                               return($format);
+                       }
+               }
+               close(PEM_OR_DER);
+               return($text{'certmgrlib_e_key'});
+       }
+}
+
+sub getfiles {
+       my(@dirs,@files,$thisdir,$dir);
+       $thisdir=$_[0];
+       opendir(DIR, $thisdir);
+       @dirs= sort grep { !/^[.]{1,2}$/ && -d "$thisdir/$_" } readdir(DIR);
+       closedir(DIR);
+       opendir(DIR,$thisdir);
+       @files= sort grep { -f "$thisdir/$_" } readdir(DIR);
+       closedir(DIR);
+       foreach $dir (@dirs) {
+               push(@files, grep { $_=$dir.'/'.$_ } &getfiles($thisdir."/".$dir));
+       }
+       return(@files);
+}
+
+1;
diff --git a/certmgr/config-*-linux b/certmgr/config-*-linux
new file mode 100755 (executable)
index 0000000..37df573
--- /dev/null
@@ -0,0 +1,24 @@
+openssl_cmd=/usr/bin/openssl
+ssl_dir=/etc/ssl
+ssl_cert_dir=/etc/ssl/certs
+ssl_key_dir=/etc/ssl/private
+ssl_csr_dir=/etc/ssl/csr
+ssl_cnf_file=/etc/webmin/acl/openssl.cnf
+ssl_sign_ca_private_key=
+ssl_sign_ca_certificate=
+key_filename=hostkey.pem
+cert_filename=hostcert.pem
+key_cert_filename=hostkey+cert.pem
+csr_filename=hostcsr.pem
+default_days=730
+default_wildcard=*.pem
+sign_filename=signedcsr.pem
+incsr_filename=csr.pem
+default_o=Organization
+default_ou=Unit
+default_l=City
+default_c=US
+default_st=State
+default_email=user@example.com
+cacert_path=/etc/ssl/cacert.pem
+cakey_path=/etc/ssl/private/cakey.pem
diff --git a/certmgr/config-freebsd b/certmgr/config-freebsd
new file mode 100755 (executable)
index 0000000..37df573
--- /dev/null
@@ -0,0 +1,24 @@
+openssl_cmd=/usr/bin/openssl
+ssl_dir=/etc/ssl
+ssl_cert_dir=/etc/ssl/certs
+ssl_key_dir=/etc/ssl/private
+ssl_csr_dir=/etc/ssl/csr
+ssl_cnf_file=/etc/webmin/acl/openssl.cnf
+ssl_sign_ca_private_key=
+ssl_sign_ca_certificate=
+key_filename=hostkey.pem
+cert_filename=hostcert.pem
+key_cert_filename=hostkey+cert.pem
+csr_filename=hostcsr.pem
+default_days=730
+default_wildcard=*.pem
+sign_filename=signedcsr.pem
+incsr_filename=csr.pem
+default_o=Organization
+default_ou=Unit
+default_l=City
+default_c=US
+default_st=State
+default_email=user@example.com
+cacert_path=/etc/ssl/cacert.pem
+cakey_path=/etc/ssl/private/cakey.pem
diff --git a/certmgr/config-macos b/certmgr/config-macos
new file mode 100755 (executable)
index 0000000..37df573
--- /dev/null
@@ -0,0 +1,24 @@
+openssl_cmd=/usr/bin/openssl
+ssl_dir=/etc/ssl
+ssl_cert_dir=/etc/ssl/certs
+ssl_key_dir=/etc/ssl/private
+ssl_csr_dir=/etc/ssl/csr
+ssl_cnf_file=/etc/webmin/acl/openssl.cnf
+ssl_sign_ca_private_key=
+ssl_sign_ca_certificate=
+key_filename=hostkey.pem
+cert_filename=hostcert.pem
+key_cert_filename=hostkey+cert.pem
+csr_filename=hostcsr.pem
+default_days=730
+default_wildcard=*.pem
+sign_filename=signedcsr.pem
+incsr_filename=csr.pem
+default_o=Organization
+default_ou=Unit
+default_l=City
+default_c=US
+default_st=State
+default_email=user@example.com
+cacert_path=/etc/ssl/cacert.pem
+cakey_path=/etc/ssl/private/cakey.pem
diff --git a/certmgr/config-openbsd b/certmgr/config-openbsd
new file mode 100755 (executable)
index 0000000..37df573
--- /dev/null
@@ -0,0 +1,24 @@
+openssl_cmd=/usr/bin/openssl
+ssl_dir=/etc/ssl
+ssl_cert_dir=/etc/ssl/certs
+ssl_key_dir=/etc/ssl/private
+ssl_csr_dir=/etc/ssl/csr
+ssl_cnf_file=/etc/webmin/acl/openssl.cnf
+ssl_sign_ca_private_key=
+ssl_sign_ca_certificate=
+key_filename=hostkey.pem
+cert_filename=hostcert.pem
+key_cert_filename=hostkey+cert.pem
+csr_filename=hostcsr.pem
+default_days=730
+default_wildcard=*.pem
+sign_filename=signedcsr.pem
+incsr_filename=csr.pem
+default_o=Organization
+default_ou=Unit
+default_l=City
+default_c=US
+default_st=State
+default_email=user@example.com
+cacert_path=/etc/ssl/cacert.pem
+cakey_path=/etc/ssl/private/cakey.pem
diff --git a/certmgr/config-redhat-linux b/certmgr/config-redhat-linux
new file mode 100755 (executable)
index 0000000..49277d9
--- /dev/null
@@ -0,0 +1,16 @@
+openssl_cmd=/usr/bin/openssl
+ssl_dir=/usr/share/ssl
+ssl_cert_dir=/usr/share/ssl/certs
+ssl_key_dir=/usr/share/ssl/private
+ssl_csr_dir=/usr/share/ssl/csr
+ssl_cnf_file=/usr/share/ssl/openssl.cnf
+ssl_sign_ca_private_key=
+ssl_sign_ca_certificate=
+key_filename=hostkey.pem
+cert_filename=hostcert.pem
+key_cert_filename=hostkey+cert.pem
+csr_filename=hostcsr.pem
+default_days=730
+default_wildcard=*.pem
+sign_filename=signedcsr.pem
+incsr_filename=csr.pem
diff --git a/certmgr/config-solaris b/certmgr/config-solaris
new file mode 100755 (executable)
index 0000000..37df573
--- /dev/null
@@ -0,0 +1,24 @@
+openssl_cmd=/usr/bin/openssl
+ssl_dir=/etc/ssl
+ssl_cert_dir=/etc/ssl/certs
+ssl_key_dir=/etc/ssl/private
+ssl_csr_dir=/etc/ssl/csr
+ssl_cnf_file=/etc/webmin/acl/openssl.cnf
+ssl_sign_ca_private_key=
+ssl_sign_ca_certificate=
+key_filename=hostkey.pem
+cert_filename=hostcert.pem
+key_cert_filename=hostkey+cert.pem
+csr_filename=hostcsr.pem
+default_days=730
+default_wildcard=*.pem
+sign_filename=signedcsr.pem
+incsr_filename=csr.pem
+default_o=Organization
+default_ou=Unit
+default_l=City
+default_c=US
+default_st=State
+default_email=user@example.com
+cacert_path=/etc/ssl/cacert.pem
+cakey_path=/etc/ssl/private/cakey.pem
diff --git a/certmgr/config.info b/certmgr/config.info
new file mode 100755 (executable)
index 0000000..58ecc9c
--- /dev/null
@@ -0,0 +1,24 @@
+openssl_cmd=Path to openssl binary,8
+ssl_dir=OpenSSL data directory,7
+ssl_cert_dir=OpenSSL certificate directory,7
+ssl_key_dir=OpenSSL key directory,7
+ssl_csr_dir=OpenSSL CSR directory,7
+ssl_cnf_file=OpenSSL configuration file,8
+ssl_sign_ca_private_key=Signing CA private key,8
+ssl_sign_ca_certificate=Signing CA Certificate,8
+key_filename=Default filename for host key,0
+cert_filename=Default filename for host certificate,0
+key_cert_filename=Default filename for host key/certificate pair,0
+csr_filename=Default filename for host CSR,0
+sign_filename=Default filename for signed certificate,0
+incsr_filename=Default filename for someone else's CSR,0
+default_days=Default certificate validity (in days),0
+default_wildcard=Default key/certificate filename wildcard,0
+default_o=Default Organization,0
+default_ou=Default Organizational Unit,0
+default_l=Default Locality,0
+default_c=Default Country Code,0
+default_st=Default State or Province,0
+default_email=Default E-mail Address,0
+cacert_path=Path to CA certificate file,0
+cakey_path=Path to CA private key file,0
diff --git a/certmgr/config_info.pl b/certmgr/config_info.pl
new file mode 100755 (executable)
index 0000000..508997e
--- /dev/null
@@ -0,0 +1,15 @@
+# config_info.pl for certmgr
+# do 'certmgr-lib.pl';
+require 'certmgr-lib.pl';
+
+sub show_cfile
+{
+local ($value) = @_;
+return "<input name=cfile size=30 value='$value'> ". &file_chooser_button("cfile")." "."<a href='/certmgr/edit_file.cgi?file=$value'>Edit..</a>";
+}
+
+sub parse_cfile
+{
+return $in{'cfile'};
+}
+
diff --git a/certmgr/defaultacl b/certmgr/defaultacl
new file mode 100755 (executable)
index 0000000..c4a870a
--- /dev/null
@@ -0,0 +1,6 @@
+gencert=1
+gencsr=1
+signcsr=1
+import=1
+view=1
+manual=1
diff --git a/certmgr/gencert.cgi b/certmgr/gencert.cgi
new file mode 100755 (executable)
index 0000000..21dfab3
--- /dev/null
@@ -0,0 +1,177 @@
+#!/usr/local/bin/perl
+# gencert.cgi
+# Generates self-signed certificates
+
+require './certmgr-lib.pl';
+&ReadParse();
+$access{'gencert'} || &error($text{'ecannot'});
+&header($text{'gencert_title'}, "");
+
+if ($in{'keysize'}==512){$checked[0]=" checked";}
+elsif ($in{'keysize'}==2048){$checked[2]=" checked";}
+else {$checked[1]=" checked";}  # Default keysize 1024
+$in{'c'}=~tr/[a-z]/[A-Z]/;
+if ($in{'submitted'} eq "generate") {
+       if (!$in{'cn'}) { $error.=$text{'gencert_e_nocn'}."<br>\n"; }
+       if (!$in{'days'}) { $error.=$text{'gencert_e_nodays'}."<br>\n"; }
+       if ($in{'password'} ne $in{'confirm_password'}) {
+               $error.=$text{'gencert_e_badpw'}."<br>\n";
+               $in{'password'}="";
+               $in{'confirm_password'}="";
+       }
+       if (!($in{'certfile'} && $in{'keyfile'})){
+               $error.=$text{'gencert_e_nofilename'}."<br>\n";
+       }
+       if (!$error) {
+               &process();
+               exit;
+       }
+} else {
+       if (!$in{'certfile'}) { $in{'certfile'}=$config{'ssl_cert_dir'}."/".
+               $config{'cert_filename'}; }
+       if (!$in{'keyfile'}) { $in{'keyfile'}=$config{'ssl_key_dir'}."/".
+               $config{'key_filename'}; }
+       if (!$in{'keycertfile'}) { $in{'keycertfile'}=
+               $config{'ssl_key_dir'}."/".$config{'key_cert_filename'};}
+} 
+if (!$in{'cn'}) { $in{'cn'}=&get_system_hostname(); }
+if (!$in{'days'}) { $in{'days'}=$config{'default_days'}; }
+
+if ($error) {
+        print "<hr> <b>$text{'gencert_error'}</b>\n<ul>\n";
+        print "$error</ul>\n$text{'gencert_pleasefix'}\n";
+}
+
+print "<hr>\n";
+&print_cert_form("gencert");
+print "<hr>\n";
+&footer("", $text{'index_return'});
+
+sub process{
+       $conffilename=&tempname();
+       $outfile=&tempname();
+       if (((-e $in{'certfile'})||(-e $in{'keyfile'})||(-e $in{'keycertfile'}))&&($in{'overwrite'} ne "yes")) {
+               &overwriteprompt();
+               print "<hr>\n";
+               &footer("", $text{'index_return'});
+               exit;
+       }
+       open(CONF,">$conffilename");
+       print CONF <<EOF;
+[ req ]
+ distinguished_name = req_dn
+ prompt = no
+[ req_dn ]
+ CN = $in{'cn'}
+EOF
+        if ($in{'o'}) {print CONF " O = $in{'o'}\n";}
+        if ($in{'ou'}) {print CONF " OU = $in{'ou'}\n";}
+        if ($in{'l'}) {print CONF " L = $in{'l'}\n";}
+        if ($in{'st'}) {print CONF " ST = $in{'st'}\n";}
+        if ($in{'c'}) {print CONF " C = $in{'c'}\n";}
+        if ($in{'emailAddress'}) {print CONF " emailAddress = $in{'emailAddress'}\n";}
+        close(CONF);
+       if ($in{'password'}){ $des="-passout pass:".quotemeta($in{'password'}); }
+       else { $des="-nodes"; }
+       if (!(open(OPENSSL,"|$config{'openssl_cmd'} req $des -newkey rsa:$in{'keysize'} -keyout $in{'keyfile'} -new \\
+                               -out $in{'certfile'} -config $conffilename -x509 -days $in{'days'} \\
+                               -outform pem >$outfile 2>&1"))) {
+               $error="$text{'e_genfailed'}: $!";
+       } else {
+               close(OPENSSL);
+               open(ERROR,"<$outfile");
+               while(<ERROR>){$out.=$_;}
+               close(ERROR);
+               if (!((-e $in{'certfile'})&&(-e $in{'keyfile'}))) { 
+                       $error=$out;
+               } else{
+                       $error=0;
+                       chmod(0400,$in{'keyfile'});
+                       if ($in{'keycertfile'}) {
+                               open(OUTFILE,">$in{'keycertfile'}");
+                               open(INFILE,"$in{'keyfile'}");
+                               while(<INFILE>) { print OUTFILE; }
+                               close(INFILE);
+                               open(INFILE,"$in{'certfile'}");
+                               while(<INFILE>) { print OUTFILE; }
+                               close(INFILE);
+                               close(OUTFILE);
+                               chmod(0400,$in{'keycertfile'});
+                       }
+               }
+       }
+       unlink($outfile);
+       unlink($conffilename);
+       print "<hr>\n";
+       if ($error){ print "<b>$text{'gencert_e_genfailed'}</b>\n<pre>$error</pre>\n<hr>\n";}
+       else {
+               print "<b>$text{'gencert_genworked'}</b>\n<pre>$out</pre>\n";
+               $url="\"view.cgi?certfile=".&my_urlize($in{'certfile'}).'"';
+               print "<b>$text{'gencert_saved_cert'} <a href=$url>$in{'certfile'}</a></b><br>\n";
+               $url="\"view.cgi?keyfile=".&my_urlize($in{'keyfile'}).'"';
+               print "<b>$text{'gencert_saved_key'} <a href=$url>$in{'keyfile'}</a></b><br>\n";
+               $url="\"view.cgi?keycertfile=".&my_urlize($in{'keycertfile'}).'"';
+               if (-e $in{'keycertfile'}) {
+                       print "<b>$text{'gencert_saved_keycert'} <a href=$url>$in{'keyfile'}</a></b><br>\n";
+               }
+               print "<hr>\n";
+       }
+       print "<hr>\n";
+       &footer("", $text{'index_return'});
+}
+
+sub overwriteprompt{
+       my($buffer1,$buffer2,$buffer,$key,$temp_pem,$url);
+       
+       print "<table>\n<tr valign=top>";
+       if (-e $in{'certfile'}) {
+               open(OPENSSL,"$config{'openssl_cmd'} x509 -in $in{'certfile'} -text -fingerprint -noout|");
+               while(<OPENSSL>){ $buffer1.=$_; }
+               close(OPENSSL);
+               $url="\"view.cgi?certfile=".&my_urlize($in{'certfile'}).'"';
+               print "<td><table border><tr $tb><td align=center><b><a href=$url>$in{'certfile'}</a></b></td> </tr>\n<tr $cb> <td>\n";
+               if (!$buffer1) { print $text{'e_file'};}
+               else { &print_cert_info(0,$buffer1); }
+               print "</td></tr></table></td>\n";
+       }
+       if (-e $in{'keyfile'}) {
+               open(OPENSSL,"$config{'openssl_cmd'} rsa -in $in{'keyfile'} -text -noout|");
+               while(<OPENSSL>){ $buffer.=$_; }
+               close(OPENSSL);
+               $url="\"view.cgi?keyfile=".&my_urlize($in{'keyfile'}).'"';
+               print "<td><table border><tr $tb> <td align=center><b><a href=$url>$in{'keyfile'}</a></b></td> </tr>\n<tr $cb> <td>\n";
+               if (!$buffer) { print $text{'e_file'};}
+               else { &print_key_info(0,$buffer); }
+               print "</td></tr></table></td>\n";
+       }
+       if (-e $in{'keycertfile'}) {
+               undef($buffer);
+               open(OPENSSL,"$config{'openssl_cmd'} x509 -in $in{'keycertfile'} -text -fingerprint -noout|");
+               while(<OPENSSL>){ $buffer2.=$_; }
+               close(OPENSSL);
+               open(OPENSSL,"$config{'openssl_cmd'} rsa -in $in{'keycertfile'} -text -noout|");
+               while(<OPENSSL>){ $buffer.=$_; }
+               close(OPENSSL);
+               if ($buffer1 ne $buffer2) {
+                       $url="\"view.cgi?keycertfile=".&my_urlize($in{'keycertfile'}).'"';
+                       print "<td><table border><tr $tb> <td align=center colspan=2><b><a href=$url>$in{'keycertfile'}</a></b></td> </tr>\n";
+                       print "<tr $cb><td><b>$text{'certificate'}</b></td><td><b>$text{'key'}</b></td></tr>\n<tr $cb valign=top> <td>\n";
+                       if (!$buffer2) { print $text{'e_file'};}
+                       else {&print_cert_info(0,$buffer2); }
+                       print "</td><td>\n";
+                       if (!$buffer) { print $text{'e_file'};}
+                       else {&print_key_info(0,$buffer); }
+                       print "</td></tr></table></td>\n";
+               }
+       }
+       print "</tr></table>\n";
+       print "$text{'gencert_moreinfo'}";
+       print "<hr>\n$text{'gencert_overwrite'}\n<p>\n";
+       
+       print "<form action=gencert.cgi method=post>\n";
+       foreach $key (keys %in) {
+               print "<input name=\"$key\" type=hidden value=\"$in{$key}\">\n";
+       }
+       print "<input name=overwrite value=\"yes\" type=hidden>\n";
+       print "<input type=submit value=\"$text{'continue'}\"></form>\n";
+}
diff --git a/certmgr/gencsr.cgi b/certmgr/gencsr.cgi
new file mode 100755 (executable)
index 0000000..48e6007
--- /dev/null
@@ -0,0 +1,143 @@
+#!/usr/local/bin/perl
+# gencsr.cgi
+# Generates certificates signing requests (CSRs)
+
+require './certmgr-lib.pl';
+&ReadParse();
+$access{'gencsr'} || &error($text{'ecannot'});
+&header($text{'gencsr_title'}, "");
+
+if ($in{'keysize'}==512){$checked[0]=" checked";}
+elsif ($in{'keysize'}==2048){$checked[2]=" checked";}
+else {$checked[1]=" checked";}  # Default keysize 1024
+$in{'c'}=~tr/[a-z]/[A-Z]/;
+if ($in{'submitted'} eq "generate") {
+       if (!$in{'cn'}) { $error.=$text{'gencert_e_nocn'}."<br>\n"; }
+       if ($in{'password'} ne $in{'confirm_password'}) {
+               $error.=$text{'gencert_e_badpw'}."<br>\n";
+               $in{'password'}="";
+               $in{'confirm_password'}="";
+       }
+       if (!($in{'csrfile'} && $in{'keyfile'} )){
+               $error.=$text{'gencsr_e_nofilename'}."<br>\n";
+       }
+       if (!$error) {
+               &process();
+               exit;
+       }
+}
+
+if ($error) {
+        print "<hr> <b>$text{'gencsr_error'}</b>\n<ul>\n";
+        print "$error</ul>\n$text{'gencsr_pleasefix'}\n";
+} else {
+       if (!$in{'csrfile'}) { $in{'csrfile'}=$config{'ssl_csr_dir'}."/".
+               $config{'csr_filename'}; }
+       if (!$in{'keyfile'}) { $in{'keyfile'}=$config{'ssl_key_dir'}."/".
+               $config{'key_filename'}; }
+       if (!$in{'cn'}) { $in{'cn'}=&get_system_hostname(); }
+       if (!$in{'o'}) { $in{'o'}=$config{'default_o'}; }
+       if (!$in{'ou'}) { $in{'ou'}=$config{'default_ou'}; }
+       if (!$in{'l'}) { $in{'l'}=$config{'default_l'}; }
+       if (!$in{'st'}) { $in{'st'}=$config{'default_st'}; }
+       if (!$in{'c'}) { $in{'c'}=$config{'default_c'}; }
+       $in{'c'}=~tr/[a-z]/[A-Z]/;
+       if (!$in{'emailAddress'}) { $in{'emailAddress'}=$config{'default_email'}; }
+}
+
+print "<hr>\n";
+&print_cert_form("gencsr");
+print "<hr>\n";
+&footer("", $text{'index_return'});
+
+sub process{
+       $conffilename=&tempname();
+       $outfile=&tempname();
+       if (((-e $in{'csrfile'})||(-e $in{'keyfile'}))&&($in{'overwrite'} ne "yes")) {
+               &overwriteprompt();
+               print "<hr>\n";
+               &footer("", $text{'index_return'});
+               exit;
+       }
+       open(CONF,">$conffilename");
+       print CONF <<EOF;
+[ req ]
+ distinguished_name = req_dn
+ prompt = no
+[ req_dn ]
+ CN = $in{'cn'}
+EOF
+       if ($in{'o'}) {print CONF " O = $in{'o'}\n";}
+       if ($in{'ou'}) {print CONF " OU = $in{'ou'}\n";}
+       if ($in{'l'}) {print CONF " L = $in{'l'}\n";}
+       if ($in{'st'}) {print CONF " ST = $in{'st'}\n";}
+       if ($in{'c'}) {print CONF " C = $in{'c'}\n";}
+       if ($in{'emailAddress'}) {print CONF " emailAddress = $in{'emailAddress'}\n";}
+       close(CONF);
+       if ($in{'password'}){ $des="-passout pass:".quotemeta($in{'password'}); }
+       else { $des="-nodes"; }
+       if (!(open(OPENSSL,"|$config{'openssl_cmd'} req $des -newkey rsa:$in{'keysize'} -keyout $in{'keyfile'} -new \\
+                               -out $in{'csrfile'} -config $conffilename >$outfile 2>&1"))) {
+               $error="$e_genfailed: $!";
+       } else {
+               close(OPENSSL);
+               open(ERROR,"<$outfile");
+               while(<ERROR>){$out.=$_;}
+               close(ERROR);
+               if (!((-e $in{'csrfile'})&&(-e $in{'keyfile'}))) { 
+                       $error=$out;
+               } else {
+                       $error=0;
+                       chmod(0400,$in{'keyfile'});
+               }
+       }
+       unlink($outfile);
+       unlink($conffilename);
+       print "<hr>\n";
+       if ($error){ print "<b>$text{'gencsr_e_genfailed'}</b>\n<pre>$error</pre>\n<hr>\n";}
+       else {
+               print "<b>$text{'gencsr_genworked'}</b>\n<pre>$out</pre>\n";
+               $url="\"view.cgi?csrfile=".&my_urlize($in{'csrfile'}).'"';
+               print "<b>$text{'gencsr_saved_csr'} <a href=$url>$in{'csrfile'}</a></b><br>\n";
+               $url="\"view.cgi?keyfile=".&my_urlize($in{'keyfile'}).'"';
+               print "<b>$text{'gencert_saved_key'} <a href=$url>$in{'keyfile'}</a></b><br>\n";
+       }
+       print "<hr>\n";
+       &footer("", $text{'index_return'});
+}
+
+sub overwriteprompt{
+       my($buffer1,$buffer2,$buffer,$key,$temp_pem,$url);
+       
+       print "<table>\n<tr valign=top>";
+       if (-e $in{'csrfile'}) {
+               open(OPENSSL,"$config{'openssl_cmd'} req -in $in{'csrfile'} -text -noout|");
+               while(<OPENSSL>){ $buffer1.=$_; }
+               close(OPENSSL);
+               $url="\"view.cgi?csrfile=".&my_urlize($in{'csrfile'}).'"';
+               print "<td><table border><tr $tb><td align=center><b><a href=$url>$in{'csrfile'}</a></b></td> </tr>\n<tr $cb> <td>\n";
+               if (!$buffer1) { print $text{'e_file'};}
+               else { &print_cert_info(0,$buffer1); }
+               print "</td></tr></table></td>\n";
+       }
+       if (-e $in{'keyfile'}) {
+               open(OPENSSL,"$config{'openssl_cmd'} rsa -in $in{'keyfile'} -text -noout|");
+               while(<OPENSSL>){ $buffer.=$_; }
+               close(OPENSSL);
+               $url="\"view.cgi?keyfile=".&my_urlize($in{'keyfile'}).'"';
+               print "<td><table border><tr $tb> <td align=center><b><a href=$url>$in{'keyfile'}</a></b></td> </tr>\n<tr $cb> <td>\n";
+               if (!$buffer) { print $text{'e_file'};}
+               else { &print_key_info(0,$buffer); }
+               print "</td></tr></table></td>\n";
+       }
+       print "</tr></table>\n";
+       print "$text{'gencsr_moreinfo'}";
+       print "<hr>\n$text{'gencsr_overwrite'}\n<p>\n";
+       
+       print "<form action=gencsr.cgi method=post>\n";
+       foreach $key (keys %in) {
+               print "<input name=\"$key\" type=hidden value=\"$in{$key}\">\n";
+       }
+       print "<input name=overwrite value=\"yes\" type=hidden>\n";
+       print "<input type=submit value=\"$text{'continue'}\"></form>\n";
+}
diff --git a/certmgr/help/intro.html b/certmgr/help/intro.html
new file mode 100755 (executable)
index 0000000..627687d
--- /dev/null
@@ -0,0 +1,7 @@
+<header>Certificate and Key Management</header>
+
+This module allows you to manage SSL certificates installed on the system.
+With this module, self-signed certificates and certificate signing requests (CSR)
+can be generated.  Certificates can be imported, exported, deleted and viewed.
+<hr>
+
diff --git a/certmgr/help/signcsr_ca_pass.html b/certmgr/help/signcsr_ca_pass.html
new file mode 100644 (file)
index 0000000..bffa779
--- /dev/null
@@ -0,0 +1,9 @@
+<header>CA Pass Phrase </header>
+
+<P>The CA root certificate is usually protected by a pass phrase that must
+be input in this field in order that it may be used to sign the new
+certificate.  If the root certificate is protected by a pass phrase and
+no phrase is entered then the openssl binary may hang and the system 
+response times  may be seriously impacted.</P>
+<hr>
+
diff --git a/certmgr/images/decrypt.gif b/certmgr/images/decrypt.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/decrypt.gif differ
diff --git a/certmgr/images/delete.gif b/certmgr/images/delete.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/delete.gif differ
diff --git a/certmgr/images/encrypt.gif b/certmgr/images/encrypt.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/encrypt.gif differ
diff --git a/certmgr/images/export.gif b/certmgr/images/export.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/export.gif differ
diff --git a/certmgr/images/gencert.gif b/certmgr/images/gencert.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/gencert.gif differ
diff --git a/certmgr/images/gencsr.gif b/certmgr/images/gencsr.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/gencsr.gif differ
diff --git a/certmgr/images/icon.gif b/certmgr/images/icon.gif
new file mode 100755 (executable)
index 0000000..4058b74
Binary files /dev/null and b/certmgr/images/icon.gif differ
diff --git a/certmgr/images/import.gif b/certmgr/images/import.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/import.gif differ
diff --git a/certmgr/images/manual.gif b/certmgr/images/manual.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/manual.gif differ
diff --git a/certmgr/images/signcsr.gif b/certmgr/images/signcsr.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/signcsr.gif differ
diff --git a/certmgr/images/smallicon.gif b/certmgr/images/smallicon.gif
new file mode 100755 (executable)
index 0000000..8e7c3b9
Binary files /dev/null and b/certmgr/images/smallicon.gif differ
diff --git a/certmgr/images/view.gif b/certmgr/images/view.gif
new file mode 100755 (executable)
index 0000000..4df5b8c
Binary files /dev/null and b/certmgr/images/view.gif differ
diff --git a/certmgr/import.cgi b/certmgr/import.cgi
new file mode 100755 (executable)
index 0000000..56468cc
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/local/bin/perl
+# import.cgi
+# Import Signed Certificates and Keys
+
+require './certmgr-lib.pl';
+$access{'import'} || &error($text{'ecannot'});
+if ($ENV{'REQUEST_METHOD'} eq 'POST') {
+       &ReadParseMime();
+       }
+&header($text{'import_title'}, "");
+
+if ($in{'submitted'} eq "import") {
+       if ($in{'import'} eq $text{'import_upload_cert'}){
+               $type="cert";
+       } elsif ($in{'import'} eq $text{'import_upload_key'}){
+               $type="key";
+       }
+       $filename="$in{$type.'_directory'}/$in{$type.'_file_filename'}";
+       $filename=~s#//#/#g;
+       if (!$in{$type.'_directory'}) { 
+               $error.="<li> $text{'import_e_nodir'}<br>\n";
+       }
+       if (!$in{$type.'_file_filename'}) {
+               $error.="<li> $text{'import_e_nofilename'}<br>\n";
+       } 
+       if (!$in{$type.'_file_upload'}) {
+               $error.="<li> $text{'import_e_nofile'}<br>\n";
+       }
+       if (!$error) {
+               if ((-e $filename)&&(!$in{'overwrite'})) {
+                       &overwriteprompt($type);
+               }
+               &receive($type);
+               exit;
+       }
+}
+
+if ($error) {
+       print "<hr> <b>$text{'import_error'}</b>\n<ul>\n";
+       print "$error</ul>\n$text{'import_pleasefix'}\n";
+}
+if (!$in{'cert_directory'}) { $in{'cert_directory'}=$config{'ssl_cert_dir'}; }
+if (!$in{'key_directory'}) { $in{'key_directory'}=$config{'ssl_key_dir'}; }
+if (!$in{'cert_file_filename'}) { $in{'cert_file_filename'}=$config{'cert_filename'}; }
+if (!$in{'key_file_filename'}) { $in{'key_file_filename'}=$config{'key_filename'}; }
+       
+print <<EOF;
+<hr>
+<form action="import.cgi" enctype=multipart/form-data method=post>
+<input type=hidden name="submitted" value="import">
+<table border>
+<tr $tb> <td><center><b>$text{'import_header'}</b></center></td> </tr>
+<tr $cb> <td>
+ <table width=100%>
+ <tr> <td width=35%><b>$text{'import_cert_file'}</b></td>
+ <td width=65%><input name="cert_file_upload" type="file" size="48" value="$in{'cert_file_upload_filename'}"></td></tr>
+ <tr> <td><b>$text{'import_cert_destination'}</b></td>
+ <td><select name=cert_directory>
+EOF
+print "  <option value='' ";
+if (!$in{'cert_directory'}) {print "selected";}
+print ">$text{'import_choose'}";
+foreach $f ( &getdirs($config{'ssl_dir'})) {
+        if ($config{'ssl_dir'}."/".$f eq $in{'cert_directory'}) {print "  <option selected>$config{'ssl_dir'}/$f\n";}
+        else {print "  <option>$config{'ssl_dir'}/$f\n";}
+        }
+print <<EOF;
+ </select></td> </tr>
+ <tr><td><b>$text{'import_cert_filename'}</b></td><td><input name="cert_file_filename" size="48" value="$in{'cert_file_filename'}"></td></tr>
+ <tr> <td colspan=2 align=right>
+ <input type=reset value="$text{'import_reset'}">
+ <input type=submit name=import value="$text{'import_upload_cert'}"></td> </tr>
+ </table>
+</td></tr>
+<tr $cb><td>
+ <table width=100%>
+ <tr> <td width=35%><b>$text{'import_key_file'}</b></td>
+ <td width=65%><input name="key_file_upload" type="file" size="48" value="$in{'key_file_upload_filename'}"></td></tr>
+ <tr> <td><b>$text{'import_key_destination'}</b></td>
+ <td><select name=key_directory>
+EOF
+print "  <option value='' ";
+if (!$in{'key_directory'}) {print "selected";}
+print ">$text{'import_choose'}";
+foreach $f ( &getdirs($config{'ssl_dir'})) {
+        if ($config{'ssl_dir'}."/".$f eq $in{'key_directory'}) {print "  <option selected>$config{'ssl_dir'}/$f\n";}
+        else {print "  <option>$config{'ssl_dir'}/$f\n";}
+        }
+print <<EOF;
+ </select></td> </tr>
+ <tr> <td><b>$text{'import_key_filename'}</b></td><td><input name="key_file_filename" size="48" value="$in{'key_file_filename'}"></td></tr>
+ <tr> <td colspan=2 align=right>
+ <input type=reset value="$text{'import_reset'}">
+ <input type=submit name="import" value="$text{'import_upload_key'}"></td> </tr>
+ </table>
+</td></tr></table></form>
+<hr>
+EOF
+&footer("", $text{'import_return'});
+
+sub getdirs {
+       my(@dirs,@subdirs,$thisdir);
+       $thisdir=$_[0];
+       opendir(DIR, $thisdir);
+       @dirs= sort grep { !/^[.]{1,2}$/ && -d "$thisdir/$_" } readdir(DIR);
+       closedir(DIR);
+       foreach $dir (@dirs) {
+               push(@subdirs, $dir);
+               push(@subdirs, grep { $_=$dir.'/'.$_ } &getdirs($thisdir."/".$dir));
+       }
+       return(@subdirs);
+}
+
+sub receive {
+       my $type=$_[0];
+       open(FILE,">$filename");
+       print FILE $in{$type.'_file_upload'};
+       close(FILE);
+       if ($type eq "cert") { chmod(0644,$filename); }
+       elsif ($type eq "key") { chmod(0400,$filename); }
+       print "<hr>\n";
+       print "<h4>File $filename uploaded successfully</h4>\n";
+       print "<hr>\n";
+       &footer("", $text{'import_return'});
+}
+
+sub overwriteprompt{
+       my $type=$_[0];
+       my($buffer1,$buffer2,$buffer,$key,$temp_pem,$url);
+       
+       print "<table>\n<tr valign=top>";
+       if ($type eq "cert") {
+               open(OPENSSL,"$config{'openssl_cmd'} x509 -in $filename -text -fingerprint -noout|");
+               while(<OPENSSL>){ $buffer1.=$_; }
+               close(OPENSSL);
+               $url="\"view.cgi?certfile=".&my_urlize($filename).'"';
+               print "<td><table border><tr $tb><td align=center><b><a href=$url>$filename</a></b></td> </tr>\n<tr $cb> <td>\n";
+               if (!$buffer1) { print $text{'e_file'};}
+               else { &print_cert_info(0,$buffer1); }
+               print "</td></tr></table></td>\n";
+       }
+       if ($type eq "key") {
+               open(OPENSSL,"$config{'openssl_cmd'} rsa -in $filename -text -noout|");
+               while(<OPENSSL>){ $buffer.=$_; }
+               close(OPENSSL);
+               $url="\"view.cgi?keyfile=".&my_urlize($filename).'"';
+               print "<td><table border><tr $tb> <td align=center><b><a href=$url>$filename</a></b></td> </tr>\n<tr $cb> <td>\n";
+               if (!$buffer) { print $text{'e_file'};}
+               else { &print_key_info(0,$buffer); }
+               print "</td></tr></table></td>\n";
+       }
+       print "</tr></table>\n";
+       print "$text{'gencert_moreinfo'}";
+       print "<hr>\n$text{'gencert_overwrite'}\n<p>\n";
+       
+       print "<form action=import.cgi enctype=multipart/form-data method=post>\n";
+       foreach $key (keys %in) {
+               print "<input name=\"$key\" type=hidden value=\"$in{$key}\">\n";
+       }
+       print "<input name=overwrite value=\"yes\" type=hidden>\n";
+       print "<input type=submit value=\"$text{'continue'}\"></form>\n";
+}
diff --git a/certmgr/index.cgi b/certmgr/index.cgi
new file mode 100755 (executable)
index 0000000..71585db
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/local/bin/perl
+# index.cgi
+# Upload and load kernel modules
+
+require './certmgr-lib.pl';
+
+if (! -d $config{'ssl_cert_dir'} ) { system("mkdir -p -m 0755 $config{'ssl_cert_dir'}"); }
+if (! -d $config{'ssl_csr_dir'} ) { system("mkdir -p -m 0755 $config{'ssl_csr_dir'}"); }
+if (! -d $config{'ssl_key_dir'} ) { system("mkdir -p -m 0700 $config{'ssl_key_dir'}"); }
+
+&header($text{'index_title'}, "", "intro", 1, 1);
+
+print <<EOF;
+<hr>
+<table border>
+<tr $tb> <td align=center><b>$text{'index_header'}</b></td> </tr>
+<tr $cb> <td><table width=100%><tr>
+EOF
+foreach $p (@pages) {
+       next if (!$access{$p});
+       $txt = $text{'index_'.$p};
+       print "<tr> <td><a href=$p.cgi><img src=images/$p.gif border=0></a>\n";
+       print "</td><td><a href=$p.cgi>$txt</a></td></tr>\n";
+       }
+print "</table></td></tr></table>\n";
+print "<hr>\n";
+
+&footer("/", $text{'index_index'});
diff --git a/certmgr/lang/en b/certmgr/lang/en
new file mode 100755 (executable)
index 0000000..3d2bab1
--- /dev/null
@@ -0,0 +1,149 @@
+certificate=Certificate
+key=Key
+csr=CSR
+
+e_file=An error occured while trying to get information from this file
+e_notcert=Perhaps this file is not PEM encoded or not a valid certificate or key
+e_genfailed=Generation not successful
+
+cn=Common Name (eg. host name)
+o=Organization Name (eg. company)
+ou=Organization Unit Name (eg. division)
+l=Locality (eg. city)
+st=State or Province (full name)
+c=Country (2 letter code)
+emailAddress=email Address (eg. webmaster@company.com)
+password=Password
+confirm_password=Confirm Password
+keysize=Key size (in bits)
+keytype=Key Type
+issued_on=Issued on
+expires_on=Expires on
+md5fingerprint=MD5 Fingerprint
+
+modulus=Modulus (from public key)
+publicExponent=Public Exponent
+privateExponent=Private Exponent
+prime1=Prime 1
+prime2=Prime 2
+exponent1=Exponent 1
+exponent2=Exponent 2
+coefficient=Coefficient
+
+keyfile=Key file name
+keycertfile=Key/Certificate pair file name
+continue=Continue
+
+certmgrlib_issuer=Issuer
+certmgrlib_subject=Subject
+certmgrlib_e_file_open=Unable to open file
+certmgrlib_e_exec=Unable to determine file type: couldn't execute openssl
+certmgrlib_e_cert=Unable to determine file type: invalid certificate
+certmgrlib_e_cert2=Unable to determine file type: invalid key
+
+index_title=Certificate Manager
+index_header=Certificate Manager Main Index
+index_gencert=Generate Self Signed Certificate and Key
+index_gencsr=Generate Key and Certificate Signing Request (CSR)
+index_signcsr=Sign Certificate Signing Request
+index_import=Import Key or Signed Certificate
+index_view=Manage/View Installed Certificates and Keys
+index_return=module index
+index_manual=Edit OpenSSL Configuration File
+
+index_index=index
+
+gencert_title=Generate Certificate & Key
+gencert_header=Certificate Manager: Generate Self Signed Certificate and Key
+gencert_generate=Generate Key
+gencert_password_notice=Note:  If this key will be used as a server SSL key, any password entered here must be entered each time that an SSL service which uses this key is started.  If you don't want to be required to provide the password each time, you may leave the password blank.  However, anyone with root access to this machine can potentially take the key and decrypt any SSL traffic which uses this key.
+gencert_certfile=Certificate file name
+gencert_days=Certificate valid for (days)
+gencert_overwrite=The above certificate(s) and/or key(s) will be replaced if you continue.  Are you sure you wish to continue?
+gencert_moreinfo=To download or view more information about a certificate or key, follow the link from its filename.
+gencert_error=Your submission had the following error(s):
+gencert_pleasefix=Please correct any issues and resubmit.
+gencert_e_nocn=No common name (CN) given
+gencert_e_badpw=Passwords do not match
+gencert_e_nodays=No certificate validity length specified
+gencert_e_nofilename=At least one certificate and one key must be generated
+gencert_e_genfailed=Error, certificate and key not generated
+gencert_genworked=Certificate and key generated
+gencert_saved_key=The key was saved as
+gencert_saved_cert=The certificate was saved as
+gencert_saved_keycert=The certificate+key file was saved as
+
+gencsr_title=Generate CSR
+gencsr_header=Certificate Manager : Generate Certificate Signing Request
+gencsr_csrfile=CSR filename
+gencsr_generate=Generate CSR
+gencsr_overwrite=The above CSR and/or key will be replaced if you continue.  Are you sure you wish to continue?
+gencsr_moreinfo=To download or view more information about a CSR or key, follow the link from its filename.
+gencsr_error=Your submission had the following error(s):
+gencsr_e_genfailed=Error, CSR and key not generated
+gencsr_e_nofilename=One CSR and one key filename must be specified
+gencsr_genworked=CSR and key generated
+gencsr_saved_csr=The CSR was saved as
+
+manage_encrypt=Encrypt Private Key
+manage_decrypt=Decrypt Private Key
+manage_changepw=Change Password of Private Key
+manage_delete=Delete Certificate
+
+view_title=View Certificate/CSR/Key
+view_view=View
+view_update=Update
+view_download=Download
+view_pkcs12=As PKCS12, With Password:
+view_delete=Delete
+view_select=Please select a file to view
+view_choose=Choose
+view_deleted=File deleted sucessfully
+view_e_not_deleted=Error: Problem deleting file
+view_e_nofile=File not found or not a regular file
+view_wildcard=File Wildcard
+
+import_title=Import Key or Signed Certificate
+import_e_nodir=No directory selected
+import_e_nofilename=Filename not received with file
+import_e_nofile=File not received
+import_e_fileexists=File exists
+import_error=Your upload had the following errors
+import_pleasefix=Please fix any problems and re-upload your file
+import_header=Choose a certificate or key to upload
+import_choose=Choose a directory
+import_reset=Reset
+import_cert_file=Certificate file to upload
+import_cert_destination=Destination directory of certificate
+import_cert_filename=Destination filename of certificate
+import_upload_cert=Upload Certificate
+import_key_file=Key file to upload
+import_key_destination=Destination directory of key
+import_key_filename=Destination filename of key
+import_upload_key=Upload Key
+
+signcsr_header=Certificate Manager : Sign Certificate Signing Request
+signcsr_desc=This page allows you to sign a CSR generated by someone else with one of your own private keys.
+signcsr_title=Sign Certificate Signing Request
+signcsr_csrfile=CSR filename
+signcsr_signfile=Signed certificate filename
+signcsr_keyfile=CA private key file
+signcsr_keycertfile=CA certificate file
+signcsr_ca_passphrase=CA pass phrase
+signcsr_days=Number of days to certify for
+signcsr_generate=Sign Certificate
+signcsr_e_nocsrfile=No CSR filename entered
+signcsr_e_nosignfile=No signed certificate filename entered
+signcsr_e_nokeyfile=No CA private key file or certificate file entered
+signcsr_e_signfailed=Error, signed certificate not generated
+signcsr_worked=Signed certificate generated
+signcsr_saved_cert=The certificate was saved as
+
+acl_pages=Allowed pages
+
+ecannot=You are not allowed to use this page
+
+manual_title=Edit Config File
+manual_desc=Editing OpenSSL configuration file $1 ..
+manual_err=Failed to save config file
+manual_edata=Nothing entered!
diff --git a/certmgr/lang/es b/certmgr/lang/es
new file mode 100755 (executable)
index 0000000..0f82f44
--- /dev/null
@@ -0,0 +1,116 @@
+certificate=Certificado
+key=Llave
+csr=CSR (Requisito de firmar certificado)
+
+e_file=Un error ocurrio mientras se trataba de obtener informacion de este archivo
+e_notcert=Quiza este archive no esta encoded en forma PEM o no es un certificado o llave valido
+e_genfailed=Generacion no fue exitoso
+
+cn=Nombre Común (por ejemplo, nombre de este host)
+o=Nombre de Organización (por ejemplo, nombre de empresa)
+ou=Nombre de Unidad de Organización (por ejemplo, división)
+l=Localidad (eg. ciudad)
+st=Estado o Provincia (name completo)
+c=País (codigo de 2 letras)
+emailAddress=dirección de email (por ejemplo, webmaster@company.com)
+password=Seña
+confirm_password=Confirmar seña
+keysize=Temaño de llave (bits)
+keytype=Tipo de llave
+issued_on=Fecha de certificación
+expires_on=Fecha de vencimiento
+md5fingerprint=Huella dactilar MD5
+
+modulus=Modulus (del llave publico)
+publicExponent=Exponente Publico
+privateExponent=Exponente Privado
+prime1=Número Primo (uno)
+prime2=Número Primo (dos)
+exponent1=Exponente (uno)
+exponent2=Exponente (dos)
+coefficient=Coeficiente
+
+keyfile=Nombre del archivo de la llave
+keycertfile=Nombre del archivo del par de la llave y el certificado
+continue=Continuar
+
+certmgrlib_issuer=Emisor
+certmgrlib_subject=Sujecto
+certmgrlib_e_file_open=Unable to open file
+certmgrlib_e_exec=Unable to determine file type: couldn't execute openssl
+certmgrlib_e_cert=Unable to determine file type: invalid certificate
+certmgrlib_e_cert=Unable to determine file type: invalid key
+
+index_title=Certificate Manager
+index_header=Certificate Manager Main Index
+index_gencert=Generate Self Signed Certificate and Key
+index_gencsr=Generate Key and Certificate Signing Request (CSR)
+index_import=Import Key or Signed Certificate
+index_view=Manage/View Installed Certificates and Keys
+
+index_index=index
+
+gencert_title=Generate Certificate & Key
+gencert_header=Certificate Manager: Generate Self Signed Certificate and Key
+gencert_generate=Generate Key
+gencert_password_notice=Note:  If this key will be used as a server SSL key, any password entered here must be entered each time that an SSL service which uses this key is started.  If you don't want to be required to provide the password each time, you may leave the password blank.  However, anyone with root access to this machine can potentially take the key and decrypt any SSL traffic which uses this key.
+gencert_certfile=Certificate file name
+gencert_days=Certificate valid for (days)
+gencert_overwrite=The above certificate(s) and/or key(s) will be replaced if you continue.  Are you sure you wish to continue?
+gencert_moreinfo=To download or view more information about a certificate or key, follow the link from its filename.
+gencert_error=Your submission had the following error(s):
+gencert_pleasefix=Please correct any issues and resubmit.
+gencert_e_nocn=No common name (CN) given
+gencert_e_badpw=Passwords do not match
+gencert_e_nodays=No certificate validity length specified
+gencert_e_nofilename=At least one certificate and one key must be generated
+gencert_e_genfailed=Error, certificate and key not generated
+gencert_genworked=Certificate and key generated
+gencert_saved_key=The key was saved as
+gencert_saved_cert=The certificate was saved as
+gencert_saved_keycert=The certificate+key file was saved as
+
+gencsr_title=Generate CSR
+gencsr_csrfile=CSR filename
+gencsr_generate=Generate CSR
+gencsr_overwrite=The above CSR and/or key will be replaced if you continue.  Are you sure you wish to continue?
+gencsr_moreinfo=To download or view more information about a CSR or key, follow the link from its filename.
+gencsr_error=Your submission had the following error(s):
+gencsr_e_genfailed=Error, CSR and key not generated
+gencsr_e_nofilename=One CSR and one key filename must be specified
+gencsr_genworked=CSR and key generated
+gencsr_saved_csr=The CSR was saved as
+
+manage_encrypt=Encrypt Private Key
+manage_decrypt=Decrypt Private Key
+manage_changepw=Change Password of Private Key
+manage_delete=Delete Certificate
+
+view_title=View Certificate/CSR/Key
+view_view=View
+view_update=Update
+view_download=Download
+view_delete=Delete
+view_select=Please select a file to view
+view_choose=Choose
+view_deleted=File deleted sucessfully
+view_e_not_deleted=Error: Problem deleting file
+view_e_nofile=File not found or not a regular file
+view_wildcard=File Wildcard
+
+import_title=Import Key or Signed Certificate
+import_e_nodir=No directory selected
+import_e_nofilename=Filename not received with file
+import_e_nofile=File not received
+import_e_fileexists=File exists
+import_error=Your upload had the following errors
+import_pleasefix=Please fix any problems and re-upload your file
+import_header=Choose a certificate or key to upload
+import_choose=Choose a directory
+import_reset=Reset
+import_cert_file=Certificate file to upload
+import_cert_destination=Destination directory of certificate
+import_upload_cert=Upload Certificate
+import_key_file=Key file to upload
+import_key_destination=Destination directory of key
+import_upload_key=Upload Key
diff --git a/certmgr/manual.cgi b/certmgr/manual.cgi
new file mode 100755 (executable)
index 0000000..c45411e
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/local/bin/perl
+# Show a page for manually editing openssl.conf
+
+require './certmgr-lib.pl';
+do '../ui-lib.pl';
+&ReadParse();
+&ui_print_header(undef, $text{'manual_title'}, "");
+
+# Show the file contents
+print &text('manual_desc', "<tt>$config{'ssl_cnf_file'}</tt>"),"<p>\n";
+print &ui_form_start("save_manual.cgi", "form-data");
+$data = &read_file_contents($config{'ssl_cnf_file'});
+print &ui_textarea("data", $data, 20, 80),"\n";
+print &ui_form_end([ [ "save", $text{'save'} ] ]);
+
+&ui_print_footer("", $text{'index_return'});
+
diff --git a/certmgr/module.info b/certmgr/module.info
new file mode 100755 (executable)
index 0000000..f986156
--- /dev/null
@@ -0,0 +1,5 @@
+category=system
+os_support=*-linux freebsd macos solaris openbsd
+desc=PKI Certificate and Key Management
+name=certmgr
+version=1.505
diff --git a/certmgr/save_manual.cgi b/certmgr/save_manual.cgi
new file mode 100755 (executable)
index 0000000..ad19c24
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/local/bin/perl
+# Update the manually edited config file
+
+require './certmgr-lib.pl';
+&ReadParseMime();
+&error_setup($text{'manual_err'});
+
+$in{'data'} =~ s/\r//g;
+$in{'data'} =~ /\S/ || &error($text{'manual_edata'});
+
+&open_lock_tempfile(DATA, ">$config{'ssl_cnf_file'}");
+&print_tempfile(DATA, $in{'data'});
+&close_tempfile(DATA);
+
+&redirect("");
+
diff --git a/certmgr/signcsr.cgi b/certmgr/signcsr.cgi
new file mode 100755 (executable)
index 0000000..3255102
--- /dev/null
@@ -0,0 +1,101 @@
+#!/usr/local/bin/perl
+# signcsr.cgi
+# Signs CSRs with a cert
+
+require './certmgr-lib.pl';
+$access{'signcsr'} || &error($text{'ecannot'});
+&ReadParse();
+&header($text{'signcsr_title'}, "");
+
+if ($in{'submitted'} eq "sign") {
+       if (!$in{'days'}) { $error.=$text{'gencert_e_nodays'}."<br>\n"; }
+       if (!$in{'csrfile'}) {
+               $error.=$text{'signcsr_e_nocsrfile'}."<br>\n";
+       }
+       if (!$in{'signfile'}) {
+               $error.=$text{'signcsr_e_nosignfile'}."<br>\n";
+       }
+       if (!$in{'keyfile'} || !$in{'keycertfile'}) {
+               $error.=$text{'signcsr_e_nokeyfile'}."<br>\n";
+       }
+       if (!$error) {
+               &process();
+               exit;
+       }
+} else {
+       if (!$in{'csrfile'}) { $in{'csrfile'}=$config{'ssl_csr_dir'}."/".
+               $config{'incsr_filename'}; }
+       if (!$in{'signfile'}) { $in{'signfile'}=$config{'ssl_cert_dir'}."/".
+               $config{'sign_filename'}; }
+       if (!$in{'keyfile'}) { $in{'keyfile'}=$config{'cakey_path'}; }
+       if (!$in{'keycertfile'}) { $in{'keycertfile'}=$config{'cacert_path'};}
+       if (!$in{'days'}) { $in{'days'}=$config{'default_days'}; }
+}
+
+if ($error) {
+        print "<hr> <b>$text{'signcsr_error'}</b>\n<ul>\n";
+        print "$error</ul>\n$text{'gencert_pleasefix'}\n";
+}
+
+print "<hr>\n";
+&print_sign_form("signcsr");
+print "<hr>\n";
+&footer("", $text{'index_return'});
+
+sub process{
+       &foreign_require("webmin", "webmin-lib.pl");
+       &webmin::setup_ca();
+       if ((-e $in{'signfile'})&&($in{'overwrite'} ne "yes")) {
+               &overwriteprompt();
+               print "<hr>\n";
+               &footer("", $text{'index_return'});
+               exit;
+       }
+       $tempdir = &tempname();
+       mkdir($tempdir, 0700);
+       if ($in{'password'}){ $des="-passin pass:".quotemeta($in{'password'}); }
+       $out = `yes | $config{'openssl_cmd'} ca -in $in{'csrfile'} -out $in{'signfile'} -cert $in{'keycertfile'} -keyfile $in{'keyfile'} -outdir $tempdir -days $in{'days'} -config $config_directory/acl/openssl.cnf $des 2>&1`;
+
+       system("rm -rf $tempdir");
+       if (!-e $in{'csrfile'}) { 
+               $error=$out;
+       } else{
+               $error=0;
+               chmod(0400,$in{'signfile'});
+       }
+       print "<hr>\n";
+       if ($error){ print "<b>$text{'signcsr_e_signfailed'}</b>\n<pre>$error</pre>\n<hr>\n";}
+       else {
+               print "<b>$text{'signcsr_worked'}</b>\n<pre>$out</pre>\n";
+               $url="\"view.cgi?certfile=".&my_urlize($in{'signfile'}).'"';
+               print "<b>$text{'signcsr_saved_cert'} <a href=$url>$in{'signfile'}</a></b><br>\n";
+               print "<hr>\n";
+       }
+       &footer("", $text{'index_return'});
+}
+
+sub overwriteprompt{
+       my($buffer1,$buffer2,$buffer,$key,$temp_pem,$url);
+       
+       print "<table>\n<tr valign=top>";
+       if (-e $in{'signfile'}) {
+               open(OPENSSL,"$config{'openssl_cmd'} x509 -in $in{'signfile'} -text -fingerprint -noout|");
+               while(<OPENSSL>){ $buffer1.=$_; }
+               close(OPENSSL);
+               $url="\"view.cgi?certfile=".&my_urlize($in{'signfile'}).'"';
+               print "<td><table border><tr $tb><td align=center><b><a href=$url>$in{'signfile'}</a></b></td> </tr>\n<tr $cb> <td>\n";
+               if (!$buffer1) { print $text{'e_file'};}
+               else { &print_cert_info(0,$buffer1); }
+               print "</td></tr></table></td>\n";
+       }
+       print "</tr></table>\n";
+       print "$text{'gencert_moreinfo'}";
+       print "<hr>\n$text{'gencert_overwrite'}\n<p>\n";
+       
+       print "<form action=signcsr.cgi method=post>\n";
+       foreach $key (keys %in) {
+               print "<input name=\"$key\" type=hidden value=\"$in{$key}\">\n";
+       }
+       print "<input name=overwrite value=\"yes\" type=hidden>\n";
+       print "<input type=submit value=\"$text{'continue'}\"></form>\n";
+}
diff --git a/certmgr/view.cgi b/certmgr/view.cgi
new file mode 100755 (executable)
index 0000000..adbe733
--- /dev/null
@@ -0,0 +1,209 @@
+#!/usr/local/bin/perl
+# view.cgi
+# Views certificates and keys in detail
+
+require './certmgr-lib.pl';
+$access{'view'} || &error($text{'ecannot'});
+&ReadParse();
+
+if (!$in{'wildcard'}){$in{'wildcard'}=$config{'default_wildcard'}}
+$wildcard_pattern=$in{'wildcard'};
+$wildcard_pattern=~s/\./\\./g;
+$wildcard_pattern=~s/\*/[^\/]*?/g;
+$wildcard_pattern=~s/\?/./g;
+
+
+if ($in{'dl'} ne "yes" && $in{'pkcs12'} ne "yes") {
+       &header($text{'view_title'}, "");
+       print "<hr>\n";
+}
+if ($in{'delete'} eq "yes"){
+       if ($in{'keyfile'}) { $file=$in{'keyfile'} }
+       elsif ($in{'certfile'}) { $file=$in{'certfile'} }
+       elsif ($in{'csrfile'}) { $file=$in{'csrfile'} }
+       elsif ($in{'keycertfile'}) { $file=$in{'keycertfile'} }
+       if (!($file)&&((-f $file)||(-s $file))){ print "<b>$file</b>: $text{'view_e_nofile'}\n<p>\n"; }
+       if (unlink($file)) { print "<b>$file</b>: $text{'view_deleted'}\n<p>\n"; }
+       else { print "<b>$file</b>: $text{'view_e_not_deleted'}\n<p>\n"; }
+       &footer("", $text{'index_return'});
+       exit;
+}
+
+if (($in{'filename'}) && ($in{'view'} eq $text{'view_view'})) {
+       $in{'filename'}=$config{'ssl_dir'}."/".$in{'filename'};
+       if (!open(FILE,$in{'filename'})) {
+               print "$text{'e_file'}\n<p>\n";
+               &footer("", $text{'index_return'});
+               exit;
+       }
+       while(<FILE>){ $buffer.=$_;}
+       if ($buffer=~/^\s*-+BEGIN\s*RSA\s*PRIVATE\s*KEY-*\s*$/mi) { $key=1; }
+       if ($buffer=~/^\s*-+BEGIN\s*CERTIFICATE-*\s*$/mi) { $cert=1; }
+       if ($buffer=~/^\s*-+BEGIN\s*CERTIFICATE\s*REQUEST-*\s*$/mi) { $csr=1; }
+       if (($key)&&($cert)) {$in{'keycertfile'}=$in{'filename'};}
+       elsif ($key) {$in{'keyfile'}=$in{'filename'};}
+       elsif ($cert) {$in{'certfile'}=$in{'filename'};}
+       elsif ($csr) {$in{'csrfile'}=$in{'filename'};}
+       else {
+               print "$text{'e_file'}<br>\n$text{'e_notcert'}\n<p>\n";
+               &footer("", $text{'index_return'});
+               exit;
+       }
+       undef($buffer);
+       undef($key);
+       undef($cert);
+               
+}
+
+if ($in{'keyfile'}) {
+       if ($in{'dl'} eq 'yes') {
+               # Just output in PEM format
+               &output_cert($in{'keyfile'});
+       } elsif ($in{'pkcs12'} eq 'yes') {
+               # Just output in PKCS8 format
+               &output_pkcs12($in{'keyfile'});
+       }
+
+       open(OPENSSL,"$config{'openssl_cmd'} rsa -in $in{'keyfile'} -text -noout|");
+       while(<OPENSSL>){ $buffer.=$_; }
+       close(OPENSSL);
+       print "<table border><tr $tb> <td align=center><b>$in{'keyfile'}</b></td> </tr>\n<tr $cb> <td>\n";
+       if (!$buffer) { print $text{'e_file'};}
+       else {&print_key_info(1,$buffer);}
+       print "</td></tr></table>\n";
+       &download_form("keyfile", $in{'keyfile'}, $text{'key'});
+       print "<hr>\n";
+       &footer("", $text{'index_return'});
+       exit;
+}
+if ($in{'certfile'}||$in{'csrfile'}) {
+       if ($in{'csrfile'}){
+               $in{'certfile'}=$in{'csrfile'};
+               $text{'certificate'}=$text{'csr'};
+       }
+       if ($in{'dl'} eq 'yes') {
+               # Just output in PEM format
+               &output_cert($in{'certfile'});
+       } elsif ($in{'pkcs12'} eq 'yes') {
+               # Just output in PKCS8 format
+               &output_pkcs12($in{'certfile'});
+       }
+
+       if ($in{'csrfile'}) {
+               open(OPENSSL,"$config{'openssl_cmd'} req -in $in{'certfile'} -text -noout|");
+       } else {
+               open(OPENSSL,"$config{'openssl_cmd'} x509 -in $in{'certfile'} -text -fingerprint -noout|");
+       }
+       while(<OPENSSL>){ $buffer.=$_; }
+       close(OPENSSL);
+       print "<table border><tr $tb> <td align=center><b>$in{'certfile'}</b></td> </tr>\n<tr $cb> <td>\n";
+       if (!$buffer) { print $text{'e_file'};}
+       else {&print_cert_info(1,$buffer);}
+       print "</td></tr></table>\n";
+       &download_form("certfile", $in{'certfile'}, $text{'certificate'});
+       print "<hr>\n";
+       &footer("", $text{'index_return'});
+       exit;
+}
+if ($in{'keycertfile'}) {
+       if ($in{'dl'} eq 'yes') {
+               # Just output in PEM format
+               &output_cert($in{'keycertfile'});
+       } elsif ($in{'pkcs12'} eq 'yes') {
+               # Just output in PKCS8 format
+               &output_pkcs12($in{'keycertfile'});
+       }
+
+       open(OPENSSL,"$config{'openssl_cmd'} x509 -in $in{'keycertfile'} -text -fingerprint -noout|");
+       while(<OPENSSL>){ $buffer.=$_; }
+       close(OPENSSL);
+       print "<table border><tr $tb> <td align=center colspan=2><b>$in{'keycertfile'}</b></td> </tr>\n";
+                       print "<tr $cb><td align=center><b>$text{'certificate'}</b></td><td align=center><b>$text{'key'}</b></td></tr>\n<tr $cb valign=top> <td>\n";
+       if (!$buffer) { print $text{'e_file'};}
+       else {&print_cert_info(1,$buffer);}
+       print "</td><td>\n";
+       undef($buffer);
+       open(OPENSSL,"$config{'openssl_cmd'} rsa -in $in{'keycertfile'} -text -noout|");
+       while(<OPENSSL>){ $buffer.=$_; }
+       close(OPENSSL);
+       if (!$buffer) { print $text{'e_file'};}
+       else {&print_key_info(1,$buffer);}
+       print "</td></tr></table>\n";
+       &download_form("keycertfile", $in{'keycertfile'},
+                      "$text{'certificate'} / $text{'key'}");
+       print "<hr>\n";
+       &footer("", $text{'index_return'});
+       exit;
+}
+
+
+print "<form action=view.cgi method=post>\n";
+print "<table border>\n<tr $tb> <td><center><b>$text{'view_select'}</b></center></td> </tr>\n";
+print "<tr $cb><td><table border=0><td>$text{'view_wildcard'}:</td><td><input name=wildcard value=\"$in{'wildcard'}\"></td>";
+print "<td><input type=submit name=update value=\"$text{'view_update'}\"></td></tr>\n";
+print "<tr><td colspan=2><select name=filename>\n";
+print "<option value='' selected>$text{'view_choose'}\n";
+foreach $f ( grep { /^(.*\/)*$wildcard_pattern$/ && -f "$config{'ssl_dir'}/$_" } &getfiles($config{'ssl_dir'})) { print "<option value=\"$f\">$config{'ssl_dir'}/$f\n"; }
+print "</select>\n";
+print "</td><td><input type=submit name=view value=\"$text{'view_view'}\"></td></tr></table></td></tr></table>\n";
+print "</form>\n";
+print "<hr>\n";
+&footer("", $text{'index_return'});
+
+sub output_cert
+{
+print "Content-type: text/plain\n\n";
+open(OPENSSL, $_[0]);
+while(<OPENSSL>){ print; }
+close(OPENSSL);
+exit;
+}
+
+sub output_pkcs12
+{
+print "Content-type: application/pkcs12\n\n";
+local $qp = quotemeta($in{'pass'});
+open(OPENSSL, "$config{'openssl_cmd'} pkcs12 -in $_[0] -export -passout pass:$qp |");
+while(<OPENSSL>){ print; }
+close(OPENSSL);
+exit;
+}
+
+sub pkcs12_filename
+{
+local $fn = &my_urlize($_[0]);
+$fn =~ s/\.pem$/\.p12/i;
+return $fn;
+}
+
+# download_form(mode, file, suffix)
+sub download_form
+{
+local ($mode, $keyfile, $suffix) = @_;
+$suffix = "";
+$keyfile =~ /\/([^\/]*)$/;
+local $filename = &my_urlize($1);
+local $p12filename = &pkcs12_filename($1);
+
+print "<table border=0><tr><td>\n";
+print "<form action=view.cgi/$filename method=post>\n";
+print "<input type=hidden name=dl value=yes>\n";
+print "<input type=hidden name=$mode value=\"$keyfile\">\n";
+print "<input type=submit value=\"$text{'view_download'} $suffix\"></form>\n";
+print "</td><td>\n";
+
+print "<form action=view.cgi/$p12filename method=post>\n";
+print "<input type=hidden name=pkcs12 value=yes>\n";
+print "<input type=hidden name=$mode value=\"$keyfile\">\n";
+print "<input type=submit value=\"$text{'view_download'} $suffix $text{'view_pkcs12'}\">\n";
+print "<input type=password name=pass size=20>\n";
+print "</form>\n";
+print "</td><td>\n";
+
+print "<form action=view.cgi method=post>\n";
+print "<input type=hidden name=delete value=yes>\n";
+print "<input type=hidden name=$mode value=\"$keyfile\">\n";
+print "<input type=submit value=\"$text{'view_delete'} $suffix\"></form>\n";
+print "</td></tr></table>\n";
+}
+