diff options
author | Evgeny Yurchenko <ey@tm-k.com> | 2011-06-23 19:02:34 -0400 |
---|---|---|
committer | Evgeny Yurchenko <ey@tm-k.com> | 2011-06-23 19:02:34 -0400 |
commit | 95c8cf48f9bd72da5371aa01a03a070885411dbf (patch) | |
tree | f2e31bd16778856299f6101028949e712b53198a | |
parent | ca4acbcdd84195c9917363fceabcd4b5294bf1d0 (diff) | |
download | pfsense-95c8cf48f9bd72da5371aa01a03a070885411dbf.zip pfsense-95c8cf48f9bd72da5371aa01a03a070885411dbf.tar.gz |
Intermediate CAs and openssl_xxx() error checking in CA management.
-rw-r--r-- | etc/inc/certs.inc | 42 | ||||
-rw-r--r-- | usr/local/www/system_camanager.php | 67 |
2 files changed, 105 insertions, 4 deletions
diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc index 3595f45..67a3540 100644 --- a/etc/inc/certs.inc +++ b/etc/inc/certs.inc @@ -186,6 +186,48 @@ function ca_create(& $ca, $keylen, $lifetime, $dn) { return true; } +function ca_inter_create(& $ca, $keylen, $lifetime, $dn, $caref) { + // Create Intermediate Certificate Authority + $signing_ca =& lookup_ca($caref); + if (!$signing_ca) + return false; + + $signing_ca_res_crt = openssl_x509_read(base64_decode($signing_ca['crt'])); + $signing_ca_res_key = openssl_pkey_get_private(array(0 => base64_decode($signing_ca['prv']) , 1 => "")); + if (!$signing_ca_res_crt || !$signing_ca_res_key) return false; + $signing_ca_serial = ++$signing_ca['serial']; + + $args = array( + "digest_alg" => "sha1", + "private_key_bits" => (int)$keylen, + "private_key_type" => OPENSSL_KEYTYPE_RSA, + "encrypt_key" => false); + + // generate a new key pair + $res_key = openssl_pkey_new($args); + if (!$res_key) return false; + + // generate a certificate signing request + $res_csr = openssl_csr_new($dn, $res_key, $args); + if (!$res_csr) return false; + + // Sign the certificate + $res_crt = openssl_csr_sign($res_csr, $signing_ca_res_crt, $signing_ca_res_key, $lifetime, $args, $signing_ca_serial); + if (!$res_crt) return false; + + // export our certificate data + if (!openssl_pkey_export($res_key, $str_key) || + !openssl_x509_export($res_crt, $str_crt)) + return false; + + // return our ca information + $ca['crt'] = base64_encode($str_crt); + $ca['prv'] = base64_encode($str_key); + $ca['serial'] = 0; + + return true; +} + function cert_import(& $cert, $crt_str, $key_str) { $cert['crt'] = base64_encode($crt_str); diff --git a/usr/local/www/system_camanager.php b/usr/local/www/system_camanager.php index a4b60af..92a129a 100644 --- a/usr/local/www/system_camanager.php +++ b/usr/local/www/system_camanager.php @@ -42,7 +42,8 @@ require_once("certs.inc"); $ca_methods = array( "existing" => gettext("Import an existing Certificate Authority"), - "internal" => gettext("Create an internal Certificate Authority")); + "internal" => gettext("Create an internal Certificate Authority"), + "intermediate" => gettext("Create an intermediate Certificate Authority")); $ca_keylens = array( "512", "1024", "2048", "4096"); @@ -154,7 +155,7 @@ if ($act == "expkey") { if ($_POST) { - $input_errors = array(); + unset($input_errors); $pconfig = $_POST; /* input validation */ @@ -183,6 +184,22 @@ if ($_POST) { gettext("Distinguished name Email Address"), gettext("Distinguished name Common Name")); } + if ($pconfig['method'] == "intermediate") { + $reqdfields = explode(" ", + "descr caref keylen lifetime dn_country dn_state dn_city ". + "dn_organization dn_email dn_commonname"); + $reqdfieldsn = array( + gettext("Descriptive name"), + gettext("Signing Certificate Authority"), + gettext("Key length"), + gettext("Lifetime"), + gettext("Distinguished name Country Code"), + gettext("Distinguished name State or Province"), + gettext("Distinguished name City"), + gettext("Distinguished name Organization"), + gettext("Distinguished name Email Address"), + gettext("Distinguished name Common Name")); + } do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); if ($pconfig['method'] != "existing") @@ -229,7 +246,7 @@ if ($_POST) { if ($pconfig['method'] == "existing") ca_import($ca, $pconfig['cert'], $pconfig['key'], $pconfig['serial']); - if ($pconfig['method'] == "internal") { + else if ($pconfig['method'] == "internal") { $dn = array( 'countryName' => $pconfig['dn_country'], 'stateOrProvinceName' => $pconfig['dn_state'], @@ -239,6 +256,23 @@ if ($_POST) { 'commonName' => $pconfig['dn_commonname']); ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn); } + else if ($pconfig['method'] == "intermediate") { + $dn = array( + 'countryName' => $pconfig['dn_country'], + 'stateOrProvinceName' => $pconfig['dn_state'], + 'localityName' => $pconfig['dn_city'], + 'organizationName' => $pconfig['dn_organization'], + 'emailAddress' => $pconfig['dn_email'], + 'commonName' => $pconfig['dn_commonname']); + $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warings directly to a page screwing menu tab */ + if (!ca_inter_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['caref'])){ + while($ssl_err = openssl_error_string()){ + $input_errors = array(); + array_push($input_errors, "openssl library returns: " . $ssl_err); + } + } + error_reporting($old_err_level); + } } if (isset($id) && $a_ca[$id]) @@ -246,7 +280,8 @@ if ($_POST) { else $a_ca[] = $ca; - write_config(); + if (!$input_errors) + write_config(); // pfSenseHeader("system_camanager.php"); } @@ -268,10 +303,17 @@ function method_change() { case 0: document.getElementById("existing").style.display=""; document.getElementById("internal").style.display="none"; + document.getElementById("intermediate").style.display="none"; break; case 1: document.getElementById("existing").style.display="none"; document.getElementById("internal").style.display=""; + document.getElementById("intermediate").style.display="none"; + break; + case 2: + document.getElementById("existing").style.display="none"; + document.getElementById("internal").style.display=""; + document.getElementById("intermediate").style.display=""; break; } } @@ -385,6 +427,23 @@ function method_change() { <tr> <td colspan="2" valign="top" class="listtopic"><?=gettext("Internal Certificate Authority");?></td> </tr> + <tr id='intermediate'> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Signing Certificate Authority");?></td> + <td width="78%" class="vtable"> + <select name='caref' id='caref' class="formselect" onChange='internalca_change()'> + <?php + foreach( $a_ca as $ca): + if (!$ca['prv']) + continue; + $selected = ""; + if ($pconfig['caref'] == $ca['refid']) + $selected = "selected"; + ?> + <option value="<?=$ca['refid'];?>"<?=$selected;?>><?=$ca['descr'];?></option> + <?php endforeach; ?> + </select> + </td> + </tr> <tr> <td width="22%" valign="top" class="vncellreq"><?=gettext("Key length");?></td> <td width="78%" class="vtable"> |