diff options
author | jim-p <jimp@pfsense.org> | 2017-07-06 13:30:36 -0400 |
---|---|---|
committer | jim-p <jimp@pfsense.org> | 2017-07-06 13:30:36 -0400 |
commit | 0c82b8c2a77bba6b2b3ab42a880c0e478ebc70f6 (patch) | |
tree | 202884e55d78441c461a9f80c2eaa459980723f5 /src/etc | |
parent | eb3435be701d59e2147ee0263692cc0a3291514a (diff) | |
download | pfsense-0c82b8c2a77bba6b2b3ab42a880c0e478ebc70f6.zip pfsense-0c82b8c2a77bba6b2b3ab42a880c0e478ebc70f6.tar.gz |
Restructure how certificate types and SANs are handled in the cert manager when making a Cert/CSR/Signing, so each section can properly use the controls without duplicating. It is now possible to add SANs and EKUs to certificates when signing using the certificate manager. Fixes #7527 and also Fixes #7677
NOTE: Attributes such as SANs and KU/EKU cannot be copied from a CSR when signing due to a deficiency in OpenSSL's x509 functions (they do not support "copy_extensions" at this time). They must be specified manually.
Diffstat (limited to 'src/etc')
-rw-r--r-- | src/etc/inc/certs.inc | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index d568fa9..9d71199 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -332,18 +332,7 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type = "user", $ $ca_serial = ++$ca['serial']; } - switch ($type) { - case "ca": - $cert_type = "v3_ca"; - break; - case "server": - case "self-signed": - $cert_type = "server"; - break; - default: - $cert_type = "usr_cert"; - break; - } + $cert_type = cert_type_config_section($type); // in case of using Subject Alternative Names use other sections (with postfix '_san') // pass subjectAltName over environment variable 'SAN' @@ -403,18 +392,7 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type = "user", $ function csr_generate(& $cert, $keylen, $dn, $type = "user", $digest_alg = "sha256") { - switch ($type) { - case "ca": - $cert_type = "v3_ca"; - break; - case "server": - case "self-signed": - $cert_type = "server"; - break; - default: - $cert_type = "usr_cert"; - break; - } + $cert_type = cert_type_config_section($type); // in case of using Subject Alternative Names use other sections (with postfix '_san') // pass subjectAltName over environment variable 'SAN' @@ -457,6 +435,41 @@ function csr_generate(& $cert, $keylen, $dn, $type = "user", $digest_alg = "sha2 return true; } +function csr_sign($csr, $ca, $duration, $copyattributes = true, $type = "user", $altnames) { + global $config; + $old_err_level = error_reporting(0); + + // Gather the information required for signed cert + $ca_str_crt = base64_decode($ca['crt']); + $ca_str_key = base64_decode($ca['prv']); + $ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => "")); + if (!$ca_res_key) { + return false; + } + if (empty($ca['serial'])) { + $ca['serial'] = 0; + } + $ca_serial = ++$ca['serial']; + + $cert_type = cert_type_config_section($type); + + if (!empty($altnames)) { + putenv("SAN={$altnames}"); // subjectAltName can be set _only_ via configuration file + $cert_type .= '_san'; + } + + $args = array( + "x509_extensions" => $cert_type, + "req_extensions" => "req_{$cert_type}" + ); + + // Sign the new cert and export it in x509 format + openssl_x509_export(openssl_csr_sign($csr, $ca_str_crt, $ca_str_key, $duration, $args, $ca_serial), $n509); + error_reporting($old_err_level); + + return $n509; +} + function csr_complete(& $cert, $str_crt) { $str_key = base64_decode($cert['prv']); cert_import($cert, $str_crt, $str_key); @@ -1060,4 +1073,20 @@ function cert_add_altname_type($str) { } } +function cert_type_config_section($type) { + switch ($type) { + case "ca": + $cert_type = "v3_ca"; + break; + case "server": + case "self-signed": + $cert_type = "server"; + break; + default: + $cert_type = "usr_cert"; + break; + } + return $cert_type; +} + ?> |