summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjim-p <jimp@pfsense.org>2014-10-21 14:42:43 -0400
committerjim-p <jimp@pfsense.org>2014-10-21 14:43:22 -0400
commita376c57de58765dbd469cb07ee3108da49a2657d (patch)
treea92cefa3ab93e3d1695afe4c1a3eada57d97b1cb
parent5b473705fac4e128070fcc009864b97624f38b03 (diff)
downloadpfsense-a376c57de58765dbd469cb07ee3108da49a2657d.zip
pfsense-a376c57de58765dbd469cb07ee3108da49a2657d.tar.gz
Teach the certificate generation code how to make a self-signed certificate, and
change the GUI cert generation code to use it. Also, move the GUI cert generation code to its own function so we can add a GUI option to regenerate it later. Also use some more sane defaults for the contents of the default self- signed certificate's fields so it will be more unique and less likely to trigger problems in browser certificate storage handling. Also add a CLI script to regenerate a new GUI certificate. Several master commits rolled into one patch for 2.1.x.
-rw-r--r--etc/inc/certs.inc37
-rw-r--r--etc/inc/system.inc70
-rw-r--r--etc/phpshellsessions/generateguicert8
3 files changed, 77 insertions, 38 deletions
diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc
index 518bc59..2043ca3 100644
--- a/etc/inc/certs.inc
+++ b/etc/inc/certs.inc
@@ -270,22 +270,28 @@ function cert_import(& $cert, $crt_str, $key_str) {
function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type="user", $digest_alg = "sha256") {
- $ca =& lookup_ca($caref);
- if (!$ca)
- return false;
+ $cert['type'] = $type;
- $ca_str_crt = base64_decode($ca['crt']);
- $ca_str_key = base64_decode($ca['prv']);
- $ca_res_crt = openssl_x509_read($ca_str_crt);
- $ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => ""));
- if(!$ca_res_key) return false;
- $ca_serial = ++$ca['serial'];
+ if ($type != "self-signed") {
+ $cert['caref'] = $caref;
+ $ca =& lookup_ca($caref);
+ if (!$ca)
+ return false;
+
+ $ca_str_crt = base64_decode($ca['crt']);
+ $ca_str_key = base64_decode($ca['prv']);
+ $ca_res_crt = openssl_x509_read($ca_str_crt);
+ $ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => ""));
+ if(!$ca_res_key) return false;
+ $ca_serial = ++$ca['serial'];
+ }
switch ($type) {
case "ca":
$cert_type = "v3_ca";
break;
case "server":
+ case "self-signed":
$cert_type = "server";
break;
default:
@@ -304,11 +310,20 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type="user", $di
$res_key = openssl_pkey_new($args);
if(!$res_key) return false;
+ // If this is a self-signed cert, blank out the CA and sign with the cert's key
+ if ($type == "self-signed") {
+ $ca = null;
+ $ca_res_crt = null;
+ $ca_res_key = $res_key;
+ $ca_serial = 0;
+ $cert['type'] = "server";
+ }
+
// generate a certificate signing request
$res_csr = openssl_csr_new($dn, $res_key, $args);
if(!$res_csr) return false;
- // self sign the certificate
+ // sign the certificate using an internal CA
$res_crt = openssl_csr_sign($res_csr, $ca_res_crt, $ca_res_key, $lifetime,
$args, $ca_serial);
if(!$res_crt) return false;
@@ -319,10 +334,8 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type="user", $di
return false;
// return our certificate information
- $cert['caref'] = $caref;
$cert['crt'] = base64_encode($str_crt);
$cert['prv'] = base64_encode($str_key);
- $cert['type'] = $type;
return true;
}
diff --git a/etc/inc/system.inc b/etc/inc/system.inc
index a1ea489..328e1d7 100644
--- a/etc/inc/system.inc
+++ b/etc/inc/system.inc
@@ -767,6 +767,43 @@ function system_pccard_start() {
return $res;
}
+function system_webgui_create_certificate() {
+ global $config, $g;
+
+ if (!is_array($config['ca']))
+ $config['ca'] = array();
+ $a_ca =& $config['ca'];
+ if (!is_array($config['cert']))
+ $config['cert'] = array();
+ $a_cert =& $config['cert'];
+ log_error("Creating SSL Certificate for this host");
+
+ $cert = array();
+ $cert['refid'] = uniqid();
+ $cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
+
+ $dn = array(
+ 'countryName' => "US",
+ 'stateOrProvinceName' => "State",
+ 'localityName' => "Locality",
+ 'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
+ 'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
+ 'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
+ $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warings directly to a page screwing menu tab */
+ if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")){
+ while($ssl_err = openssl_error_string()){
+ log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
+ }
+ error_reporting($old_err_level);
+ return null;
+ }
+ error_reporting($old_err_level);
+
+ $a_cert[] = $cert;
+ $config['system']['webgui']['ssl-certref'] = $cert['refid'];
+ write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
+ return $cert;
+}
function system_webgui_start() {
global $config, $g;
@@ -790,36 +827,17 @@ function system_webgui_start() {
// Ensure that we have a webConfigurator CERT
$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
if(!is_array($cert) && !$cert['crt'] && !$cert['prv']) {
- if (!is_array($config['ca']))
- $config['ca'] = array();
- $a_ca =& $config['ca'];
- if (!is_array($config['cert']))
- $config['cert'] = array();
- $a_cert =& $config['cert'];
- log_error("Creating SSL Certificate for this host");
- $cert = array();
- $cert['refid'] = uniqid();
- $cert['descr'] = gettext("webConfigurator default");
- mwexec("/usr/local/bin/openssl genrsa 1024 > {$g['tmp_path']}/ssl.key");
- mwexec("/usr/local/bin/openssl req -new -x509 -nodes -sha256 -days 2000 -key {$g['tmp_path']}/ssl.key > {$g['tmp_path']}/ssl.crt");
- $crt = file_get_contents("{$g['tmp_path']}/ssl.crt");
- $key = file_get_contents("{$g['tmp_path']}/ssl.key");
- unlink("{$g['tmp_path']}/ssl.key");
- unlink("{$g['tmp_path']}/ssl.crt");
- cert_import($cert, $crt, $key);
- $a_cert[] = $cert;
- $config['system']['webgui']['ssl-certref'] = $cert['refid'];
- write_config(gettext("Importing HTTPS certificate"));
- if(!$config['system']['webgui']['port'])
- $portarg = "443";
- $ca = ca_chain($cert);
+ $cert = system_webgui_create_certificate();
+ $crt = $cert['crt'];
+ $key = $cert['prv'];
} else {
$crt = base64_decode($cert['crt']);
$key = base64_decode($cert['prv']);
- if(!$config['system']['webgui']['port'])
- $portarg = "443";
- $ca = ca_chain($cert);
}
+
+ if(!$config['system']['webgui']['port'])
+ $portarg = "443";
+ $ca = ca_chain($cert);
}
/* generate lighttpd configuration */
diff --git a/etc/phpshellsessions/generateguicert b/etc/phpshellsessions/generateguicert
new file mode 100644
index 0000000..925ab60
--- /dev/null
+++ b/etc/phpshellsessions/generateguicert
@@ -0,0 +1,8 @@
+require_once("system.inc");
+
+echo gettext("Generating a new self-signed SSL certificate for the GUI...");
+$cert = system_webgui_create_certificate();
+echo gettext("Done.\n");
+echo gettext("Restarting webConfigurator...");
+send_event("service restart webgui");
+echo gettext("Done.\n"); \ No newline at end of file
OpenPOWER on IntegriCloud