diff options
Diffstat (limited to 'src/etc/inc/certs.inc')
-rw-r--r-- | src/etc/inc/certs.inc | 106 |
1 files changed, 92 insertions, 14 deletions
diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index b30a607..1ed1b6e 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -39,6 +39,15 @@ $openssl_crl_status = array( OCSP_REVOKED_STATUS_CERTIFICATEHOLD => "Certificate Hold" ); +global $cert_altname_types; +$cert_altname_types = array( + 'DNS' => gettext('FQDN or Hostname'), + 'IP' => gettext('IP address'), + 'URI' => gettext('URI'), + 'email' => gettext('email address'), +); + + function & lookup_ca($refid) { global $config; @@ -323,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' @@ -392,10 +390,21 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type = "user", $ return true; } -function csr_generate(& $cert, $keylen, $dn, $digest_alg = "sha256") { +function csr_generate(& $cert, $keylen, $dn, $type = "user", $digest_alg = "sha256") { + + $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' + if ($dn['subjectAltName']) { + putenv("SAN={$dn['subjectAltName']}"); // subjectAltName can be set _only_ via configuration file + $cert_type .= '_san'; + unset($dn['subjectAltName']); + } $args = array( - "x509_extensions" => "v3_req", + "x509_extensions" => $cert_type, + "req_extensions" => "req_{$cert_type}", "digest_alg" => $digest_alg, "private_key_bits" => (int)$keylen, "private_key_type" => OPENSSL_KEYTYPE_RSA, @@ -426,6 +435,41 @@ function csr_generate(& $cert, $keylen, $dn, $digest_alg = "sha256") { return true; } +function csr_sign($csr, & $ca, $duration, $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); @@ -1011,4 +1055,38 @@ function cert_escape_x509_chars($str, $reverse = false) { } } +function cert_add_altname_type($str) { + $type = ""; + if (is_ipaddr($str)) { + $type = "IP"; + } elseif (is_hostname($str)) { + $type = "DNS"; + } elseif (is_URL($str)) { + $type = "URI"; + } elseif (filter_var($str, FILTER_VALIDATE_EMAIL)) { + $type = "email"; + } + if (!empty($type)) { + return "{$type}:" . cert_escape_x509_chars($str); + } else { + return ""; + } +} + +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; +} + ?> |