diff options
author | jim-p <jimp@pfsense.org> | 2014-10-21 14:42:43 -0400 |
---|---|---|
committer | jim-p <jimp@pfsense.org> | 2014-10-21 14:43:22 -0400 |
commit | a376c57de58765dbd469cb07ee3108da49a2657d (patch) | |
tree | a92cefa3ab93e3d1695afe4c1a3eada57d97b1cb | |
parent | 5b473705fac4e128070fcc009864b97624f38b03 (diff) | |
download | pfsense-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.inc | 37 | ||||
-rw-r--r-- | etc/inc/system.inc | 70 | ||||
-rw-r--r-- | etc/phpshellsessions/generateguicert | 8 |
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 |