generated from smedev/Template-for-SMEServer-Contribs-Package
phpki-0.82
This commit is contained in:
130
root/include/common.php
Normal file
130
root/include/common.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
umask(0007);
|
||||
|
||||
if ($HTTP_SERVER_VARS['PHP_AUTH_USER'])
|
||||
$PHPki_user = md5($HTTP_SERVER_VARS['PHP_AUTH_USER']);
|
||||
else
|
||||
$PHPki_user = md5('default');
|
||||
|
||||
$PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
|
||||
|
||||
|
||||
function printHeader($withmenu="default") {
|
||||
global $config;
|
||||
$title = ($config['header_title']?$config['header_title']:'PHPki Certificate Authority');
|
||||
|
||||
switch ($withmenu) {
|
||||
case 'public':
|
||||
case 'about':
|
||||
case 'setup':
|
||||
$style_css = './css/style.css';
|
||||
break;
|
||||
case 'ca':
|
||||
case 'admin':
|
||||
default:
|
||||
$style_css = '../css/style.css';
|
||||
break;
|
||||
}
|
||||
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
header("Expires: -1");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>PHPki: <?=$title?> </title>
|
||||
<link rel="stylesheet" type="text/css" href="<?=$style_css?>">
|
||||
</head>
|
||||
<body>
|
||||
<?
|
||||
|
||||
if (isKonq()) {
|
||||
$logoclass = 'logo-konq';
|
||||
$titleclass = 'title-konq';
|
||||
$menuclass = 'headermenu-konq';
|
||||
}
|
||||
else {
|
||||
$logoclass = 'logo-ie';
|
||||
$titleclass = 'title-ie';
|
||||
$menuclass = 'headermenu-ie';
|
||||
}
|
||||
|
||||
?>
|
||||
<div class=<?=$logoclass?>>PHPki</div>
|
||||
<div class=<?=$titleclass?>><?=$title?></div>
|
||||
<?
|
||||
|
||||
switch ($withmenu) {
|
||||
case false:
|
||||
case 'about':
|
||||
break;
|
||||
case 'setup':
|
||||
?>
|
||||
<div class=<?=$menuclass?>>
|
||||
<a class=<?=$menuclass?> href=readme.php>ReadMe</a>
|
||||
<a class=<?=$menuclass?> href=setup.php>Setup</a>
|
||||
<a class=<?=$menuclass?> href=about.php target=_about>About</a>
|
||||
</div>
|
||||
<?
|
||||
break;
|
||||
case 'public':
|
||||
print "<div class=$menuclass>";
|
||||
|
||||
if (DEMO) {
|
||||
print "<a class=$menuclass href=index.php>Public</a>";
|
||||
print "<a class=$menuclass href=ca/ >Manage</a>";
|
||||
}
|
||||
else {
|
||||
print "<a class=$menuclass href=index.php>Menu</a>";
|
||||
}
|
||||
|
||||
if (file_exists('policy.html')) {
|
||||
print '<a class='.$menuclass.' style="color: red" href=policy.html target=help>Policy</a>';
|
||||
}
|
||||
?>
|
||||
<a class=<?=$menuclass?> href=help.php target=_help>Help</a>
|
||||
<a class=<?=$menuclass?> href=about.php target=_about>About</a>
|
||||
</div>
|
||||
<?
|
||||
break;
|
||||
case 'ca':
|
||||
default:
|
||||
print "<div class=$menuclass>";
|
||||
|
||||
if (DEMO) {
|
||||
print "<a class=$menuclass href=../index.php>Public</a>";
|
||||
print "<a class=$menuclass href=../ca/index.php>Manage</a>";
|
||||
}
|
||||
else {
|
||||
print "<a class=$menuclass href=index.php>Menu</a>";
|
||||
}
|
||||
|
||||
if (file_exists('../policy.html')) {
|
||||
print '<a class='.$menuclass.' style="color: red" href=../policy.html target=help>Policy</a>';
|
||||
}
|
||||
?>
|
||||
<a class=<?=$menuclass?> href=../help.php target=_help>Help</a>
|
||||
<a class=<?=$menuclass?> href=../about.php target=_about>About</a>
|
||||
</div>
|
||||
<?
|
||||
}
|
||||
|
||||
?><hr width=99% align=left color=#99caff><?
|
||||
}
|
||||
|
||||
|
||||
function printFooter() {
|
||||
?>
|
||||
<br>
|
||||
<hr width=99% align=left color=#99caff>
|
||||
<center style='margin-top: -5px; font-size: 8pt'>PHPki v<?=PHPKI_VERSION?> - Copyright 2003 - William E. Roadcap</center><br>
|
||||
</body>
|
||||
</html>
|
||||
<?
|
||||
}
|
||||
|
||||
?>
|
207
root/include/my_functions.php
Normal file
207
root/include/my_functions.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
$PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
|
||||
|
||||
#
|
||||
# Returns TRUE if browser is Internet Explorer.
|
||||
#
|
||||
function isIE() {
|
||||
global $HTTP_SERVER_VARS;
|
||||
return strstr($HTTP_SERVER_VARS['HTTP_USER_AGENT'], 'MSIE');
|
||||
}
|
||||
|
||||
function isKonq() {
|
||||
global $HTTP_SERVER_VARS;
|
||||
return strstr($HTTP_SERVER_VARS['HTTP_USER_AGENT'], 'Konqueror');
|
||||
}
|
||||
|
||||
function isMoz() {
|
||||
global $HTTP_SERVER_VARS;
|
||||
return strstr($HTTP_SERVER_VARS['HTTP_USER_AGENT'], 'Gecko');
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Force upload of specified file to browser.
|
||||
#
|
||||
function upload($source, $destination, $content_type="application/octet-stream") {
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
header("Expires: -1");
|
||||
# header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
# header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
# header("Pragma: no-cache");
|
||||
header("Content-Type: $content_type");
|
||||
|
||||
if (is_array($source)) {
|
||||
$fsize = 0;
|
||||
foreach($source as $f) $fsize += filesize($f);
|
||||
}
|
||||
else {
|
||||
$fsize = filesize($source);
|
||||
}
|
||||
|
||||
header("Content-length: " . $fsize);
|
||||
# header("Content-Disposition: attachment; filename=\"" . $destination ."\"");
|
||||
header("Content-Disposition: filename=\"" . $destination ."\"");
|
||||
|
||||
if (is_array($source))
|
||||
foreach($source as $f) $ret = readfile($f);
|
||||
else
|
||||
$ret=readfile($source);
|
||||
|
||||
# $fd=fopen($source,'r');
|
||||
# fpassthru($fd);
|
||||
# fclose($fd);
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Returns a value from the GET/POST global array referenced
|
||||
# by field name. POST fields have precedence over GET fields.
|
||||
# Quoting/Slashes are stripped if magic quotes gpc is on.
|
||||
#
|
||||
function gpvar($v) {
|
||||
global $HTTP_GET_VARS, $HTTP_POST_VARS;
|
||||
$x = "";
|
||||
if ($HTTP_GET_VARS[$v]) $x = $HTTP_GET_VARS[$v];
|
||||
if ($HTTP_POST_VARS[$v]) $x = $HTTP_POST_VARS[$v];
|
||||
if (get_magic_quotes_gpc()) $x = stripslashes($x);
|
||||
return $x;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Sort a two multidimensional array by one of it's columns
|
||||
#
|
||||
function csort($array, $column, $ascdec=SORT_ASC){
|
||||
if (sizeof($array) == 0) return $array;
|
||||
|
||||
foreach($array as $x) $sortarr[]=$x[$column];
|
||||
array_multisort($sortarr, $ascdec, $array);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Returns a value suitable for display in the browser.
|
||||
# Strips slashes if second argument is true.
|
||||
#
|
||||
function htvar($v, $strip=false) {
|
||||
if ($strip)
|
||||
return htmlentities(stripslashes($v));
|
||||
else
|
||||
return htmlentities($v);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Returns a value suitable for use as a shell argument.
|
||||
# Strips slashes if magic quotes is on, surrounds
|
||||
# provided strings with single-quotes and quotes any
|
||||
# other dangerous characters.
|
||||
#
|
||||
function escshellarg($v, $strip=false) {
|
||||
if ($strip)
|
||||
return escapeshellarg(stripslashes($v));
|
||||
else
|
||||
return escapeshellarg($v);
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Similar to escshellarg(), but doesn't surround provided
|
||||
# string with single-quotes.
|
||||
#
|
||||
function escshellcmd($v, $strip=false) {
|
||||
if ($strip)
|
||||
return escapeshellcmd(stripslashes($v));
|
||||
else
|
||||
return escapeshellarg($v);
|
||||
}
|
||||
|
||||
#
|
||||
# Recursively strips slashes from a string or array.
|
||||
#
|
||||
function stripslashes_array(&$a) {
|
||||
if (is_array($a)) {
|
||||
foreach($a as $k => $v) {
|
||||
my_stripslashes($a[$k]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$a = stripslashes($a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Don't use this.
|
||||
#
|
||||
function undo_magic_quotes(&$a) {
|
||||
if(get_magic_quotes_gpc()) {
|
||||
global $HTTP_POST_VARS, $HTTP_GET_VARS;
|
||||
|
||||
foreach($HTTP_POST_VARS as $k => $v) {
|
||||
stripslashes_array($HTTP_POST_VARS[$k]);
|
||||
global $$k;
|
||||
stripslashes_array($$k);
|
||||
}
|
||||
foreach($HTTP_GET_VARS as $k => $v) {
|
||||
stripslashes_array($HTTP_GET_VARS[$k]);
|
||||
global $$k;
|
||||
stripslashes_array($$k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Returns TRUE if argument contains only alphabetic characters.
|
||||
#
|
||||
function is_alpha($v) {
|
||||
return (eregi('[^A-Z]',$v) ? false : true) ;
|
||||
}
|
||||
|
||||
#
|
||||
# Returns TRUE if argument contains only numeric characters.
|
||||
#
|
||||
function is_num($v) {
|
||||
return (eregi('[^0-9]',$v) ? false : true) ;
|
||||
}
|
||||
|
||||
#
|
||||
# Returns TRUE if argument contains only alphanumeric characters.
|
||||
#
|
||||
function is_alnum($v) {
|
||||
return (eregi('[^A-Z0-9]',$v) ? false : true) ;
|
||||
}
|
||||
|
||||
#
|
||||
# Returns TRUE if argument is in proper e-mail address format.
|
||||
#
|
||||
function is_email($v) {
|
||||
return (eregi('^[^@ ]+\@[^@ ]+\.[A-Z]{2,3}$',$v) ? true : false);
|
||||
}
|
||||
|
||||
#
|
||||
# Checks regexp in every element of an array, returns TRUE as soon
|
||||
# as a match is found.
|
||||
#
|
||||
function eregi_array($regexp, $a) {
|
||||
|
||||
foreach($a as $e) {
|
||||
if (eregi($regexp,$e)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#
|
||||
# Reads entire file into a string
|
||||
# Same as file_get_contents in php >= 4.3.0
|
||||
#
|
||||
function my_file_get_contents($f) {
|
||||
return implode('', file($f));
|
||||
}
|
||||
|
||||
?>
|
779
root/include/openssl_functions.php
Normal file
779
root/include/openssl_functions.php
Normal file
@@ -0,0 +1,779 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
// Creates a temporary openssl config file specific to given parameters.
|
||||
// File name is placed in ./tmp with a random name. It lingers unless
|
||||
// removed manually.
|
||||
//
|
||||
function CA_create_cnf($country='',$province='',$locality='',$organization='',$unit='',$common_name='',$email='',$keysize=1024) {
|
||||
global $config, $PHPki_user;
|
||||
|
||||
$issuer = $PHPki_user;
|
||||
|
||||
$cnf_contents = "
|
||||
HOME = $config[home_dir]
|
||||
RANDFILE = $config[random]
|
||||
dir = $config[ca_dir]
|
||||
certs = $config[cert_dir]
|
||||
crl_dir = $config[crl_dir]
|
||||
database = $config[index]
|
||||
new_certs_dir = $config[new_certs_dir]
|
||||
private_dir = $config[private_dir]
|
||||
serial = $config[serial]
|
||||
certificate = $config[cacert_pem]
|
||||
crl = $config[cacrl_pem]
|
||||
private_key = $config[cakey]
|
||||
crl_extentions = crl_ext
|
||||
default_days = 365
|
||||
default_crl_days = 30
|
||||
preserve = no
|
||||
default_md = md5
|
||||
|
||||
[ req ]
|
||||
default_bits = $keysize
|
||||
string_mask = nombstr
|
||||
prompt = no
|
||||
distinguished_name = req_name
|
||||
req_extensions = req_ext
|
||||
|
||||
[ req_name]
|
||||
C=$country
|
||||
ST=$province
|
||||
L=$locality
|
||||
0.O=$organization
|
||||
1.O='$issuer'
|
||||
OU=$unit
|
||||
CN=$common_name
|
||||
emailAddress=$email
|
||||
|
||||
[ ca ]
|
||||
default_ca = email_cert
|
||||
|
||||
[ root_cert ]
|
||||
x509_extensions = root_ext
|
||||
default_days = 3650
|
||||
policy = policy_supplied
|
||||
|
||||
[ email_cert ]
|
||||
x509_extensions = email_ext
|
||||
default_days = 365
|
||||
policy = policy_supplied
|
||||
|
||||
[ email_codesigning_cert ]
|
||||
x509_extensions = email_codesigning_ext
|
||||
default_days = 365
|
||||
policy = policy_supplied
|
||||
|
||||
[ server_cert ]
|
||||
x509_extensions = server_ext
|
||||
default_days = 365
|
||||
policy = policy_supplied
|
||||
|
||||
[ vpn_cert ]
|
||||
x509_extensions = vpn_client_server_ext
|
||||
default_days = 365
|
||||
policy = policy_supplied
|
||||
|
||||
[ time_stamping_cert ]
|
||||
x509_extensions = time_stamping_ext
|
||||
default_days = 365
|
||||
policy = policy_supplied
|
||||
|
||||
|
||||
[ policy_supplied ]
|
||||
countryName = supplied
|
||||
stateOrProvinceName = supplied
|
||||
localityName = supplied
|
||||
organizationName = supplied
|
||||
organizationalUnitName = supplied
|
||||
commonName = supplied
|
||||
emailAddress = supplied
|
||||
|
||||
[ req_ext]
|
||||
basicConstraints = CA:false
|
||||
|
||||
[ crl_ext ]
|
||||
issuerAltName=issuer:copy
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
|
||||
[ root_ext ]
|
||||
basicConstraints = CA:true
|
||||
keyUsage = cRLSign, keyCertSign
|
||||
nsCertType = sslCA, emailCA, objCA
|
||||
subjectKeyIdentifier = hash
|
||||
subjectAltName = email:copy
|
||||
crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
|
||||
nsComment = \"PHPki/OpenSSL Generated Root Certificate\"
|
||||
#nsCaRevocationUrl = ns_revoke_query.php?
|
||||
nsCaPolicyUrl = $config[base_url]policy.html
|
||||
|
||||
[ email_ext ]
|
||||
basicConstraints = critical, CA:false
|
||||
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = critical, emailProtection, clientAuth
|
||||
nsCertType = critical, client, email
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
subjectAltName = email:copy
|
||||
issuerAltName = issuer:copy
|
||||
crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
|
||||
nsComment = \"PHPki/OpenSSL Generated Personal Certificate\"
|
||||
nsBaseUrl = $config[base_url]
|
||||
nsRevocationUrl = ns_revoke_query.php?
|
||||
nsCaPolicyUrl = $config[base_url]policy.html
|
||||
|
||||
[ email_codesigning_ext ]
|
||||
basicConstraints = critical, CA:false
|
||||
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = critical, emailProtection, clientAuth, codeSigning
|
||||
nsCertType = critical, client, email
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
subjectAltName = email:copy
|
||||
issuerAltName = issuer:copy
|
||||
crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
|
||||
nsComment = \"PHPki/OpenSSL Generated Personal Certificate\"
|
||||
nsBaseUrl = $config[base_url]
|
||||
nsRevocationUrl = ns_revoke_query.php?
|
||||
nsCaPolicyUrl = $config[base_url]policy.html
|
||||
|
||||
[ server_ext ]
|
||||
basicConstraints = critical, CA:false
|
||||
keyUsage = critical, digitalSignature, keyEncipherment
|
||||
nsCertType = critical, server
|
||||
extendedKeyUsage = critical, serverAuth
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
subjectAltName = DNS:$common_name,email:copy
|
||||
issuerAltName = issuer:copy
|
||||
crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
|
||||
nsComment = \"PHPki/OpenSSL Generated Server Certificate\"
|
||||
nsBaseUrl = $config[base_url]
|
||||
nsRevocationUrl = ns_revoke_query.php?
|
||||
nsCaPolicyUrl = $config[base_url]policy.html
|
||||
|
||||
[ time_stamping_ext ]
|
||||
basicConstraints = CA:false
|
||||
keyUsage = critical, nonRepudiation, digitalSignature
|
||||
extendedKeyUsage = timeStamping
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
subjectAltName = DNS:$common_name,email:copy
|
||||
issuerAltName = issuer:copy
|
||||
crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
|
||||
nsComment = \"PHPki/OpenSSL Generated Time Stamping Certificate\"
|
||||
nsBaseUrl = $config[base_url]
|
||||
nsRevocationUrl = ns_revoke_query.php?
|
||||
|
||||
[ vpn_client_ext ]
|
||||
basicConstraints = critical, CA:false
|
||||
keyUsage = critical, digitalSignature
|
||||
extendedKeyUsage = critical, clientAuth
|
||||
nsCertType = critical, client
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
subjectAltName = DNS:$common_name,email:copy
|
||||
|
||||
[ vpn_server_ext ]
|
||||
basicConstraints = critical, CA:false
|
||||
keyUsage = critical, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = critical, serverAuth
|
||||
nsCertType = critical, server
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
subjectAltName = DNS:$common_name,email:copy
|
||||
|
||||
[ vpn_client_server_ext ]
|
||||
basicConstraints = critical, CA:false
|
||||
keyUsage = critical, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = critical, serverAuth, clientAuth
|
||||
nsCertType = critical, server, client
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always, issuer:always
|
||||
subjectAltName = DNS:$common_name,email:copy
|
||||
";
|
||||
|
||||
# Write out the config file.
|
||||
$cnf_file = tempnam('./tmp','cnf-');
|
||||
$handle = fopen($cnf_file,"w");
|
||||
fwrite($handle, $cnf_contents);
|
||||
fclose($handle);
|
||||
|
||||
return($cnf_file);
|
||||
}
|
||||
|
||||
//
|
||||
// Search the certificate index and return resulting
|
||||
// records in array[cert_serial_number][field_name].
|
||||
// Fields: serial, country, province, locality, organization,
|
||||
// issuer, unit, common_name, email
|
||||
//
|
||||
function CAdb_to_array($search = '.*') {
|
||||
global $config;
|
||||
|
||||
# Prepend a default status to search string if missing.
|
||||
if (! ereg('^\^\[.*\]', $search)) $search = '^[VRE].*'.$search;
|
||||
|
||||
# Include valid certs?
|
||||
if (ereg('^\^\[.*V.*\]',$search)) $inclval = true;
|
||||
# Include revoked certs?
|
||||
if (ereg('^\^\[.*R.*\]',$search)) $inclrev = true;
|
||||
# Include expired certs?
|
||||
if (ereg('^\^\[.*E.*\]',$search)) $inclexp = true;
|
||||
|
||||
# There isn't really a status of 'E' in the openssl index.
|
||||
# Change (E)xpired to (V)alid within the search string.
|
||||
$search = ereg_replace('^(\^\[.*)E(.*\])','\\1V\\2',$search);
|
||||
|
||||
$db = array();
|
||||
exec('egrep -i '.escshellarg($search).' '.$config['index'], $x);
|
||||
foreach($x as $y) {
|
||||
$i = CAdb_explode_entry($y);
|
||||
if (($i['status'] == "Valid" && $inclval) || ($i['status'] == "Revoked" && $inclrev) || ($i['status'] == "Expired" && $inclexp))
|
||||
$db[$i['serial']] = $i;
|
||||
}
|
||||
|
||||
return($db);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns an array containing the index record for
|
||||
// certificate $serial.
|
||||
//
|
||||
function CAdb_get_entry($serial) {
|
||||
global $config;
|
||||
$regexp = "^[VR]\t.*\t.*\t$serial\t.*\t.*$";
|
||||
$x = exec('egrep '.escshellarg($regexp).' '.$config['index']);
|
||||
if ($x)
|
||||
return CAdb_explode_entry($x);
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns the serial number of a VALID certificate matching
|
||||
// $email and/or $name. Returns FALSE if no match is found.
|
||||
//
|
||||
function CAdb_in($email="", $name="") {
|
||||
global $config;
|
||||
$email = escshellcmd($email);
|
||||
$name = escshellcmd($name);
|
||||
$regexp = "^[V].*CN=$name/(Email|emailAddress)=$email";
|
||||
$x =exec("egrep '$regexp' $config[index]");
|
||||
if ($x) {
|
||||
list($j,$j,$j,$serial,$j,$j) = explode("\t", $x);
|
||||
return "$serial";
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Alias for CAdb_in()
|
||||
//
|
||||
function CAdb_serial($email, $name='') {
|
||||
return CAdb_in($email, $name='');
|
||||
}
|
||||
|
||||
//
|
||||
// Alias for CAdb_in()
|
||||
//
|
||||
function CAdb_exists($email, $name='') {
|
||||
return CAdb_in($email, $name='');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns the certificate 'issuer'
|
||||
//
|
||||
function CAdb_issuer($serial) {
|
||||
global $config;
|
||||
$rec = CAdb_get_entry($serial);
|
||||
return $rec['issuer'];
|
||||
}
|
||||
|
||||
//
|
||||
// Returns an array containing the respective fields given a
|
||||
// a raw line ($dbentry) from the certificate index.
|
||||
// Fields: serial, country, province locality, organization,
|
||||
// issuer, unit, common_name, email
|
||||
//
|
||||
function CAdb_explode_entry($dbentry) {
|
||||
$a = explode("\t", $dbentry);
|
||||
$b = preg_split('/\/([A-Z]|[a-z])+=/', $a[5]);
|
||||
|
||||
switch ($a[0]) {
|
||||
case "V":
|
||||
$db['status'] = "Valid";
|
||||
break;
|
||||
case "R":
|
||||
$db['status'] = "Revoked";
|
||||
break;
|
||||
}
|
||||
|
||||
sscanf(CA_cert_startdate($a[3]),"%s %s %s %s", $mm,$dd,$tt,$yy);
|
||||
$db['issued'] = strftime("%y-%b-%d", strtotime("$dd $mm $yy"));
|
||||
|
||||
sscanf($a[1], "%2s%2s%2s",$yy,$mm,$dd);
|
||||
$db['expires'] = strftime("%y-%b-%d", strtotime("$mm/$dd/$yy"));
|
||||
|
||||
if (time() > strtotime("$mm/$dd/$yy"))
|
||||
$db['status'] = "Expired";
|
||||
|
||||
$db['serial'] = $a[3];
|
||||
$db['country'] = $b[1];
|
||||
$db['province'] = $b[2];
|
||||
$db['locality'] = $b[3];
|
||||
$db['organization'] = $b[4];
|
||||
$db['issuer'] = $b[5];
|
||||
$db['unit'] = $b[6];
|
||||
$db['common_name'] = $b[7];
|
||||
$db['email'] = $b[8];
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the date & time a specified certificate is revoked,
|
||||
// Returns FALSE if the certificate is not revoked.
|
||||
//
|
||||
function CAdb_is_revoked($serial) {
|
||||
global $config;
|
||||
$regexp = "^R\t.*\t.*\t$serial\t.*\t.*$";
|
||||
$x = exec('egrep '.escshellarg($regexp).' '.$config['index']);
|
||||
|
||||
if ($x) {
|
||||
list($j,$j,$revoke_date,$j,$j,$j) = explode("\t", $x);
|
||||
sscanf($revoke_date, "%2s%2s%2s",$yy,$mm,$dd);
|
||||
return strftime("%b %d, %Y", strtotime("$mm/$dd/$yy"));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns TRUE if a certificate is valid, otherwise FALSE.
|
||||
//
|
||||
function CAdb_is_valid($serial) {
|
||||
global $config;
|
||||
$regexp = "^V\t.*\t.*\t$serial\t.*\t.*$";
|
||||
|
||||
if (exec('egrep '.escshellarg($regexp).' '.$config['index']))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the long-form certificate description as output by
|
||||
// openssl x509 -in certificatefile -text -purpose
|
||||
//
|
||||
function CA_cert_text($serial) {
|
||||
global $config;
|
||||
$certfile = $config['new_certs_dir'] . '/' . $serial . '.pem';
|
||||
return(shell_exec(X509.' -in '.escshellarg($certfile).' -text -purpose 2>&1'));
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the long-form text of the Certificate Revocation List
|
||||
// openssl crl -in crlfile -text
|
||||
//
|
||||
function CA_crl_text() {
|
||||
global $config;
|
||||
$crlfile = $config['cacrl_pem'];
|
||||
return(shell_exec(CRL.' -in '.escshellarg($crlfile).' -text 2>&1'));
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the subject of a certificate.
|
||||
//
|
||||
function CA_cert_subject($serial) {
|
||||
global $config;
|
||||
$certfile = $config['new_certs_dir'] . '/' . $serial . '.pem';
|
||||
$x = exec(X509.' -in '.escshellarg($certfile).' -noout -subject 2>&1');
|
||||
return(str_replace('subject=', '', $x));
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the common name of a certificate.
|
||||
//
|
||||
function CA_cert_cname($serial) {
|
||||
global $config;
|
||||
return(ereg_replace('^.*/CN=(.*)/.*','\\1',CA_cert_subject($serial)));
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the email address of a certificate.
|
||||
//
|
||||
function CA_cert_email($serial) {
|
||||
global $config;
|
||||
$certfile = $config['new_certs_dir'] . '/' . $serial . '.pem';
|
||||
$x = exec(X509.' -in '.escshellarg($certfile).' -noout -email 2>&1');
|
||||
return($x);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the effective date of a certificate.
|
||||
//
|
||||
function CA_cert_startdate($serial) {
|
||||
global $config;
|
||||
$certfile = $config['new_certs_dir'] . '/' . $serial . '.pem';
|
||||
$x = exec(X509.' -in '.escshellarg($certfile).' -noout -startdate 2>&1');
|
||||
return(str_replace('notBefore=','',$x));
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the expiration date of a certificate.
|
||||
//
|
||||
function CA_cert_enddate($serial) {
|
||||
global $config;
|
||||
$certfile = $config['new_certs_dir'] . '/' . $serial . '.pem';
|
||||
$x = exec(X509.' -in '.escshellarg($certfile).' -noout -enddate 2>&1');
|
||||
return(str_replace('notAfter=','',$x));
|
||||
}
|
||||
|
||||
//
|
||||
// Revokes a specified certificate.
|
||||
//
|
||||
function CA_revoke_cert($serial) {
|
||||
global $config;
|
||||
|
||||
$fd = fopen($config['index'],'a');
|
||||
flock($fd, LOCK_EX);
|
||||
|
||||
$certfile = "$config[new_certs_dir]/$serial.pem";
|
||||
|
||||
$cmd_output[] = 'Revoking the certificate.';
|
||||
exec(CA." -config '$config[openssl_cnf]' -revoke ".escshellarg($certfile)." -passin pass:'$config[ca_pwd]' 2>&1", $cmd_output, $ret);
|
||||
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
list($ret, $cmd_output[]) = CA_generate_crl();
|
||||
}
|
||||
|
||||
fclose($fd);
|
||||
|
||||
return array(($ret == true || $ret == 0 ? true : false), implode('<br>',$cmd_output));
|
||||
}
|
||||
|
||||
//
|
||||
// Creates a new certificate request, and certificate in various formats
|
||||
// according to specified parameters. PKCS12 bundle files contain the
|
||||
// private key, certificate, and CA certificate.
|
||||
//
|
||||
// Returns an array containing the output of failed openssl commands.
|
||||
//
|
||||
function CA_create_cert($cert_type='email',$country,$province,$locality,$organization,$unit,$common_name,$email,$expiry,$passwd,$keysize=1024) {
|
||||
global $config;
|
||||
|
||||
# Wait here if another user has the database locked.
|
||||
$fd = fopen($config['index'],"a");
|
||||
flock($fd, LOCK_EX);
|
||||
|
||||
# Get the next available serial number
|
||||
$serial = trim(implode('',file($config['serial'])));
|
||||
|
||||
$userkey = $config['private_dir'].'/'.$serial.'-key.pem';
|
||||
$userreq = $config['req_dir'].'/'.$serial.'-req.pem';
|
||||
$usercert = $config['new_certs_dir'].'/'.$serial.'.pem';
|
||||
$userder = $config['cert_dir'].'/'.$serial.'.der';
|
||||
$userpfx = $config['pfx_dir'].'/'.$serial.'.pfx';
|
||||
|
||||
$expiry_days = round($expiry * 365.25, 0);
|
||||
|
||||
$cnf_file = CA_create_cnf($country,$province,$locality,$organization,$unit,$common_name,$email,$keysize);
|
||||
|
||||
# Escape certain dangerous characters in user input
|
||||
$email = escshellcmd($email);
|
||||
$passwd = escshellarg($passwd);
|
||||
$friendly_name = escshellarg($common_name);
|
||||
$extensions = escshellarg($cert_type.'_ext');
|
||||
|
||||
# Create the certificate request
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = 'Creating certifcate request.';
|
||||
|
||||
if ($passwd) {
|
||||
exec(REQ." -new -newkey rsa:$keysize -keyout '$userkey' -out '$userreq' -config '$cnf_file' -days '$expiry_days' -passout pass:$passwd 2>&1", $cmd_output, $ret);
|
||||
}
|
||||
else {
|
||||
exec(REQ." -new -newkey rsa:$keysize -keyout '$userkey' -out '$userreq' -config '$cnf_file' -days '$expiry_days' -nodes 2>&1", $cmd_output, $ret);
|
||||
}
|
||||
|
||||
# Sign the certificate request and create the certificate
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = "Signing $cert_type certifcate request.";
|
||||
exec(CA." -config '$cnf_file' -in '$userreq' -out /dev/null -notext -days '$expiry_days' -passin pass:'$config[ca_pwd]' -batch -extensions $extensions 2>&1", $cmd_output, $ret);
|
||||
};
|
||||
|
||||
# Create DER format certificate
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = "Creating DER format certifcate.";
|
||||
exec(X509." -in '$usercert' -out '$userder' -inform PEM -outform DER 2>&1", $cmd_output, $ret);
|
||||
};
|
||||
|
||||
# Create a PKCS12 certificate file for download to Windows
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = "Creating PKCS12 format certifcate.";
|
||||
if ($passwd) {
|
||||
$cmd_output[] = "infile: $usercert keyfile: $userkey outfile: $userpfx pass: $passwd";
|
||||
exec(PKCS12." -export -in '$usercert' -inkey '$userkey' -certfile '$config[cacert_pem]' -caname '$config[organization]' -out '$userpfx' -name $friendly_name -rand '$config[random]' -passin pass:$passwd -passout pass:$passwd 2>&1", $cmd_output, $ret);
|
||||
}
|
||||
else {
|
||||
$cmd_output[] = "infile: $usercert keyfile: $userkey outfile: $userpfx";
|
||||
exec(PKCS12." -export -in '$usercert' -inkey '$userkey' -certfile '$config[cacert_pem]' -caname '$config[organization]' -out '$userpfx' -name $friendly_name -passout pass: 2>&1", $cmd_output, $ret);
|
||||
}
|
||||
};
|
||||
|
||||
#Unlock the CA database
|
||||
fclose($fd);
|
||||
|
||||
#Remove temporary openssl config file.
|
||||
if (file_exists($cnf_file)) unlink($cnf_file);
|
||||
|
||||
if ($ret == 0) {
|
||||
# Successful!
|
||||
# Return status=true and serial number of issued certificate.
|
||||
return array(true, $serial);
|
||||
|
||||
}
|
||||
else {
|
||||
# Not successful. :-(
|
||||
# Clean up our loose ends.
|
||||
# Return status=false and openssl output/errors for debug.
|
||||
CA_remove_cert($serial);
|
||||
$cmd_output[] = 'Click on the "Help" link above for information on how to report this problem.';
|
||||
return array(false, implode("<br>",$cmd_output));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Renews a specified certificate, revoking any existing valid versions.
|
||||
// Uses old certificate request to Creates a new request, and certificate
|
||||
// in various formats.
|
||||
//
|
||||
// Returns an array containing the output of failed openssl commands.
|
||||
//
|
||||
// FIXME: Yes, I know... This functions contains much duplicative code
|
||||
// from CA_create_cert(). Bleh!
|
||||
//
|
||||
function CA_renew_cert($old_serial,$expiry,$passwd) {
|
||||
global $config;
|
||||
|
||||
# Don't renew a revoked certificate if a valid one exists for this
|
||||
# URL. Find and renew the valid certificate instead.
|
||||
if (CAdb_is_revoked($old_serial)) {
|
||||
$ret = CAdb_in(CA_cert_email($old_serial),CA_cert_cname($old_serial));
|
||||
if ($ret && $old_serial != $ret) $old_serial = $ret;
|
||||
}
|
||||
|
||||
# Valid certificates must be revoked prior to renewal.
|
||||
if (CAdb_is_valid($old_serial)) {
|
||||
$ret = CA_revoke_cert($old_serial);
|
||||
if (! $ret[0]) return $ret;
|
||||
}
|
||||
|
||||
$cert_type = CA_cert_type($old_serial);
|
||||
$extensions = $cert_type.'_ext';
|
||||
|
||||
# Get common_name from old certificate for use as the
|
||||
# "friendly name" of PKCS12 certificate.
|
||||
$rec = CAdb_get_entry($old_serial);
|
||||
$country = $rec['country'];
|
||||
$province = $rec['province'];
|
||||
$locality = $rec['locality'];
|
||||
$organization = $rec['organiztion'];
|
||||
$unit = $rec['unit'];
|
||||
$common_name = $rec['common_name'];
|
||||
$email = $rec['email'];
|
||||
|
||||
# Wait here if another user has the database locked.
|
||||
$fd = fopen($config['index'],"a");
|
||||
flock($fd, LOCK_EX);
|
||||
|
||||
# Get the next available serial number
|
||||
$serial = trim(implode('',file($config['serial'])));
|
||||
|
||||
$old_userkey = $config['private_dir'].'/'.$old_serial.'-key.pem';
|
||||
$old_userreq = $config['req_dir'].'/'.$old_serial.'-req.pem';
|
||||
$userkey = $config['private_dir'].'/'.$serial.'-key.pem';
|
||||
$userreq = $config['req_dir'].'/'.$serial.'-req.pem';
|
||||
$usercert = $config['new_certs_dir'].'/'.$serial.'.pem';
|
||||
$userder = $config['cert_dir'].'/'.$serial.'.der';
|
||||
$userpfx = $config['pfx_dir'].'/'.$serial.'.pfx';
|
||||
|
||||
$expiry_days = round($expiry * 365.25, 0);
|
||||
|
||||
$cmd_output = array();
|
||||
$ret = 0;
|
||||
|
||||
# Create a new certificate request by copying the old request.
|
||||
if (! file_exists($old_userreq) || ! copy($old_userreq,$userreq)) {
|
||||
$cmd_output[] = 'Could not create new certificate request file.';
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
# Copy private key to new file.
|
||||
if ($ret == 0 && (! file_exists($old_userkey) || ! copy($old_userkey,$userkey))) {
|
||||
$cmd_output[] = "Could not update private key file.";
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
$cnf_file = CA_create_cnf($country,$province,$locality,$organization,$unit,$common_name,$email);
|
||||
|
||||
# "friendly name" of PKCS12 certificate.
|
||||
$friendly_name = escshellarg($rec['common_name']);
|
||||
|
||||
# Escape dangerous characters in user input.
|
||||
$passwd = escshellarg($passwd);
|
||||
|
||||
# Sign the certificate request and create the certificate.
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = "Signing the $cert_type certificate request.";
|
||||
exec(CA." -config '$cnf_file' -in '$userreq' -out /dev/null -notext -days '$expiry_days' -passin pass:'$config[ca_pwd]' -batch -extensions $extensions 2>&1", $cmd_output, $ret);
|
||||
};
|
||||
|
||||
# Create DER format certificate
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = "Creating DER format certificate.";
|
||||
exec(X509." -in '$usercert' -out '$userder' -inform PEM -outform DER 2>&1", $cmd_output, $ret);
|
||||
};
|
||||
|
||||
# Create a PKCS12 certificate file for download to Windows
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = "Creating PKCS12 format certificate.";
|
||||
if ($passwd) {
|
||||
$cmd_output[] = "infile: $usercert keyfile: $userkey outfile: $userpfx pass: $passwd";
|
||||
exec(PKCS12." -export -in '$usercert' -inkey '$userkey' -certfile '$config[cacert_pem]' -caname '$config[organization]' -out '$userpfx' -name $friendly_name -rand '$config[random]' -passin pass:$passwd -passout pass:$passwd 2>&1", $cmd_output, $ret);
|
||||
}
|
||||
else {
|
||||
$cmd_output[] = "infile: $usercert keyfile: $userkey outfile: $userpfx";
|
||||
exec(PKCS12." -export -in '$usercert' -inkey '$userkey' -certfile '$config[cacert_pem]' -caname '$config[organization]' -out '$userpfx' -name $friendly_name -passout pass: 2>&1", $cmd_output, $ret);
|
||||
}
|
||||
};
|
||||
|
||||
#Unlock the CA database
|
||||
fclose($fd);
|
||||
|
||||
#Remove temporary openssl config file.
|
||||
if (file_exists($cnf_file)) unlink($cnf_file);
|
||||
|
||||
if ($ret == 0) {
|
||||
return array(true, $serial);
|
||||
}
|
||||
else {
|
||||
# Not successful, so clean up before exiting.
|
||||
CA_remove_cert($serial);
|
||||
|
||||
if (eregi_array('.*private key.*',$cmd_output))
|
||||
$cmd_output[] = '<strong>This was likely caused by entering the wrong certificate password.</strong>';
|
||||
else
|
||||
$cmd_output[] = '<strong>Click on the "Help" link above for information on how to report this problem.</strong>';
|
||||
|
||||
return array(false, implode('<br>',$cmd_output));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Creates a new Certificate Revocation List and copies it the the approriate
|
||||
// locations. Returns error messages from failed commands.
|
||||
//
|
||||
function CA_generate_crl() {
|
||||
global $config;
|
||||
|
||||
$ret = 0;
|
||||
|
||||
$cmd_output[] = "Generating Certificate Revocation List.";
|
||||
exec(CA. " -gencrl -config '$config[openssl_cnf]' -out '$config[cacrl_pem]' -passin pass:'$config[ca_pwd]' 2>&1", $cmd_output, $ret);
|
||||
|
||||
if ($ret == 0) {
|
||||
unset($cmd_output);
|
||||
$cmd_output[] = "Creating DER format Certificate Revocation List.";
|
||||
exec(CRL." -in '$config[cacrl_pem]' -out '$config[cacrl_der]' -inform PEM -outform DER 2>&1", $cmd_output, $ret);
|
||||
}
|
||||
|
||||
return array(($ret == 0 ? true : false), implode('<br>',$cmd_output));
|
||||
}
|
||||
|
||||
//
|
||||
// Removes a specified certificate from the certificate index,
|
||||
// and all traces of it from the file system.
|
||||
//
|
||||
function CA_remove_cert($serial) {
|
||||
global $config;
|
||||
|
||||
$userreq = $config['req_dir'].'/'.$serial.'-req.pem';
|
||||
$userkey = $config['private_dir'].'/'.$serial.'-key.pem';
|
||||
$usercert = $config['new_certs_dir'].'/'.$serial.'.pem';
|
||||
$userder = $config['cert_dir'].'/'.$serial.'.der';
|
||||
$userpfx = $config['pfx_dir'].'/'.$serial.'.pfx';
|
||||
|
||||
|
||||
# Wait here if another user has the database locked.
|
||||
$fd = fopen($config['index'],'a');
|
||||
flock($fd, LOCK_EX);
|
||||
|
||||
if( file_exists($userreq)) unlink($userreq);
|
||||
if( file_exists($userkey)) unlink($userkey);
|
||||
if( file_exists($usercert)) unlink($usercert);
|
||||
if( file_exists($userder)) unlink($userder);
|
||||
if( file_exists($userpfx)) unlink($userpfx);
|
||||
|
||||
$tmpfile = $config['index'].'.tmp';
|
||||
copy($config['index'], $tmpfile);
|
||||
|
||||
$regexp = "^[VR]\t.*\t.*\t".$serial."\t.*\t.*$";
|
||||
exec('egrep -v '.escshellarg($regexp)." $tmpfile > $config[index] 2>/dev/null");
|
||||
|
||||
unlink($tmpfile);
|
||||
fclose($fd);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the likely intended use for a specified certificate
|
||||
// (email, server, vpn).
|
||||
//
|
||||
function CA_cert_type($serial) {
|
||||
|
||||
$certtext = CA_cert_text($serial);
|
||||
|
||||
if (ereg('OpenSSL.* (E.?mail|Personal) .*Certificate', $certtext) && ereg('Code Signing', $certtest)) {
|
||||
$cert_type = 'email_codesigning';
|
||||
}
|
||||
if (ereg('OpenSSL.* (E.?mail|Personal) .*Certificate', $certtext)) {
|
||||
$cert_type = 'email';
|
||||
}
|
||||
elseif (ereg('OpenSSL.* Server .*Certificate', $certtext)) {
|
||||
$cert_type = 'server';
|
||||
}
|
||||
elseif (ereg('timeStamping|Time Stamping', $certtext)) {
|
||||
$cert_type = 'time_stamping';
|
||||
}
|
||||
elseif (ereg('TLS Web Client Authentication', $certtext) && ereg('TLS Web Server Authentication', $certtext)) {
|
||||
$cert_type = 'vpn_client_server';
|
||||
}
|
||||
elseif (ereg('TLS Web Client Authentication', $certtext)) {
|
||||
$cert_type = 'vpn_client';
|
||||
}
|
||||
elseif (ereg('TLS Web Server Authentication', $certtext)) {
|
||||
$cert_type = 'vpn_server';
|
||||
}
|
||||
else {
|
||||
$cert_type = 'vpn_client_server';
|
||||
}
|
||||
|
||||
return $cert_type;
|
||||
}
|
||||
|
||||
?>
|
Reference in New Issue
Block a user