&1",'r');
$line = '';
while (! feof($handle)) {
$chr = fread($handle, 1);
$line .= $chr;
if ($chr == "\n") {
print str_replace("\n", "
\n", $line);
$line = '';
flush();
}
elseif (strlen($line) > $line_length) {
print $line."
\n";
$line = '';
flush();
}
}
print $line."
\n";
flush;
return;
}
$version = PHPKI_VERSION;
# Who does the webserver run as (apache,www-data,etc)?
$uid = posix_getuid();
$pwdinfo = posix_getpwuid($uid);
$uname = $pwdinfo['name'];
# Permissions on the file store.
$store_perms=0770;
# Where are we?
$here = dirname($_SERVER['SCRIPT_FILENAME']);
$submit = gpvar('submit');
$stage = gpvar('stage');
$organization = gpvar('organization');
$unit = gpvar('unit');
$contact = gpvar('contact');
$locality = gpvar('locality');
$province = gpvar('province');
$country = gpvar('country');
$common_name = gpvar('common_name');
$passwd = gpvar('passwd');
$passwdv = gpvar('passwdv');
$expiry = gpvar('expiry');
$keysize = gpvar('keysize');
$base_url = gpvar('base_url');
$openssl_bin = gpvar('openssl_bin');
$passwd_file = gpvar('passwd_file');
$getting_help = gpvar('getting_help');
$ca_prefix = gpvar('ca_prefix');
$header_title = gpvar('header_title');
$store_dir = gpvar('store_dir');
if ($base_url && substr($base_url,-1) != '/') $base_url .= '/';
$hidden_fields = '
';
switch ($stage) {
case 'validate':
$er = '';
if (! $country) $er .= 'Missing Country
';
if (! $province) $er .= 'Missing State/Province
';
if (! $locality) $er .= 'Missing Locality
';
if (! $organization) $er .= 'Missing Organization
';
if (! $unit) $er .= 'Missing Unit/Department
';
if (! $contact) $er .= 'Missing Contact E-mail Address
';
if (! $common_name) $er .= 'Missing Common Name
';
if (! $passwd) $er .= 'Missing Certificate Password
';
if (! $passwdv) $er .= 'Missing Certificate Password Verification "Again"
';
if (! $header_title) $er .= 'Missing Header Title
';
if (! $passwd_file) $er .= 'Missing User Password File Location';
if (! $store_dir) $er .= 'Missing Storage Directory
';
$countrycode = strtoupper($country);
if (! preg_match("/\b[A-Z][A-Z]\b/", $countrycode, $match) ) {
$er .= 'Country Code must be ISO 3166 two letters
';
}
if ( $passwd && strlen($passwd) < 8 )
$er .= 'Certificate password is too short.
';
if ( $passwd and $passwd != $passwdv )
$er .= 'Password and password verification do not match.
';
if ( $email && ! is_email($contact) )
$er .= 'E-mail address ('. htvar($contact) . ') may be invalid.
';
if (strpos($store_dir,$_SERVER['DOCUMENT_ROOT']) === 0)
$er .= 'Store directory must exist somewhere outside of DOCUMENT_ROOT ('.$_SERVER['DOCUMENT_ROOT'].').
';
if (strpos($store_dir,dirname($_SERVER['SCRIPT_FILENAME'])) === 0)
$er .= 'Store directory cannot exist within the PHPki installation directory ('.dirname($_SERVER['SCRIPT_FILENAME']).').
';
if (! $er) {
if (! file_exists($store_dir) ) {
if ( ! mkdir("$store_dir",$store_perms)) $er .= "Could not create the store directory \"$store_dir\"
";
}
if (file_exists($store_dir)) {
if (! chmod($store_dir, $store_perms)) $er .= "Could not change permissions on the store directory \"$store_dir\"
";
if (! is_readable($store_dir)) $er .= "The store directory \"$store_dir\" is not readable by the web server user \"$uname\"
";
if (! is_writeable($store_dir)) $er .= "The store directory \"$store_dir\: is not writeable by the web server user \"$uname\"
";
}
else {
$er .= "Store directory \"$store_dir\" does not exist. You will have to manually create it as desribed in the setup form.
";
}
}
if ( $er )
$er = '
ERROR(S) IN FORM:
' . $er . '
';
if ($er) {
printHeader('setup');
?>
";
printFooter();
break;
}
case 'write':
printHeader('about');
#
#Create the file store directory structure.
#
print 'Creating PHPki file store...
';
flush();
if (! file_exists("$store_dir/config")) mkdir("$store_dir/config",$store_perms);
if (! file_exists("$store_dir/tmp")) mkdir("$store_dir/tmp",$store_perms);
if (! file_exists("$store_dir/CA")) mkdir("$store_dir/CA",$store_perms);
if (! file_exists("$store_dir/CA/certs")) mkdir("$store_dir/CA/certs",$store_perms);
if (! file_exists("$store_dir/CA/private")) mkdir("$store_dir/CA/private",$store_perms);
if (! file_exists("$store_dir/CA/newcerts")) mkdir("$store_dir/CA/newcerts",$store_perms);
if (! file_exists("$store_dir/CA/requests")) mkdir("$store_dir/CA/requests",$store_perms);
if (! file_exists("$store_dir/CA/crl")) mkdir("$store_dir/CA/crl",$store_perms);
if (! file_exists("$store_dir/CA/pfx")) mkdir("$store_dir/CA/pfx",$store_perms);
#
# Create the PHPki CA configuration.
#
print 'Writing configuration files...
';
flush();
$config_txt = <<
EOS;
#
# Write out the CA configuration file.
#
$fd = fopen("$store_dir/config/config.php",'w');
fwrite($fd, $config_txt);
fclose($fd);
#
# Create the bootstrap configuration
#
$config_txt = <<
EOS;
#
# Write out the bootstrap config
#
$fd = fopen('./config.php','w');
fwrite($fd, $config_txt);
fclose($fd);
# Re-read the CA config file so the openssl_functions
# can be used to create a CA root certificate.
include("$store_dir/config/config.php");
#
# Now create a temporary openssl.cnf for creating a self-signed
# CA root certificate, and create a generic openssl.cnf file
# in the CA home
#
$config_txt1 = <<< EOS
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_extensions = crl_ext
default_days = 365
default_crl_days = 30
preserve = no
default_md = sha1
[ 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_signing_cert ]
x509_extensions = email_signing_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
[ 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 Authority"
#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?
#nsRenewalUrl =
nsCaPolicyUrl = $config[base_url]policy.html
#nsSslServerName =
[ email_signing_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?
#nsRenewalUrl =
nsCaPolicyUrl = $config[base_url]policy.html
#nsSslServerName =
[ server_ext ]
basicConstraints = CA:false
keyUsage = critical, digitalSignature, keyEncipherment
nsCertType = critical, server
extendedKeyUsage = critical, serverAuth, 1.3.6.1.5.5.7.3.1
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 Secure 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?
nsCaPolicyUrl = $config[base_url]policy.html
[ 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
[ crl_ext ]
issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
EOS;
$config_txt2 = <<< EOS
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_name
string_mask = nombstr
req_extensions = req_ext
[ req_name]
countryName = Country Name (2 letter code)
countryName_default = US
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default =
localityName = Locality Name (eg, city)
localityName_default =
0.organizationName = Organization Name (eg, company)
0.organizationName_default =
1.organizationName = Second Organization Name (eg, company)
1.organizationName_default =
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default =
commonName = Common Name (eg, YOUR name)
emailAddress = Email Address or Web URL
[ req_ext ]
basicConstraints = critical, CA:false
EOS;
$config_txt3 = <<< EOS
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_name
string_mask = nombstr
req_extensions = req_ext
prompt = no
[ req_name ]
C = $config[country]
ST = $config[province]
L = $config[locality]
O = $config[organization]
OU = $config[unit]
CN = $config[common_name]
emailAddress = $config[contact]
[ req_ext ]
basicConstraints = critical, CA:true
EOS;
#
# Write the permanent OpenSSL config
#
$fd = fopen($config['openssl_cnf'],'w');
fwrite($fd, $config_txt1 . $config_txt2);
fclose($fd);
#
# Write the temporary OpenSSL config
#
$tmp_cnf = "$config[home_dir]/tmp/openssl.cnf";
$fd = fopen($tmp_cnf,'w');
fwrite($fd, $config_txt1 . $config_txt3);
fclose($fd);
#
# Intialize index.txt and serial files
#
$fd = fopen($config['index'],'w');
fwrite($fd, "");
fclose($fd);
#
$fd = fopen($config['serial'],'w');
fwrite($fd, "100001");
fclose($fd);
#
# Convert expiry years to approximate days.
#
$days = $config['expiry'] * 365.25;
#
# Create a new self-signed CA certificate in PEM format.
#
print 'Creating root certificate...
';
flush();
exec(REQ . " -x509 -config $tmp_cnf -extensions root_ext -newkey rsa:$keysize -keyout $config[cakey] -out $config[cacert_pem] -passout pass:'$config[ca_pwd]' -days $days 2>&1");
# **** DISABLED *****
# It appears that both IE and Netscape accept PEM formatted root certificates
#
# Create a copy of the CA certificate in DER format.
#
#exec(X509 . " -in ca/$config[cacert_pem] -inform PEM -out ca/$config[cacert_der] -outform DER 2>&1");
#
# Generate the initial CRL.
#
print 'Generating certificate revocation list...
';
flush();
exec(CA . " -gencrl -config $config[openssl_cnf] -out $config[cacrl_pem] -passin pass:'$config[ca_pwd]'");
# Make a copy of the CRL in DER format.
#
exec(CRL . " -in $config[cacrl_pem] -out $config[cacrl_der] -inform PEM -outform DER");
#
# Clean up.
#
if (! unlink("$store_dir/tmp/openssl.cnf")) print "Can't unlink $store_dir/tmp/openssl.cnf";
#
# Create dhparam files for OpenVPN and others.
#
print 'Creating 1024 bit Diffie-Hellman parameters used by OpenVPN.
';
print "Saving to $store_dir/dhparam1024.pem.
";
$cmd = "openssl dhparam -rand '$config[random]' -out '$config[private_dir]/dhparam1024.pem' 1024";
print $cmd.'
';
flush();
flush_exec($cmd,100);
#
# Create a TLS auth key for OpenVPN.
#
print '
Creating a TLS authentication key used by OpenVPN.
';
print "Saving to $store_dir/takey.pem.
";
$cmd = "openvpn --genkey --secret '$config[private_dir]/takey.pem'";
print $cmd.'
';
flush();
flush_exec($cmd);
#print '
Creating 2048 bit Diffie-Hellman parameters used by OpenVPN.
';
#print "Saving to $store_dir/dhparam2048.pem.
";
#$cmd = "openssl dhparam -rand '$config[random]' -out '$config[private_dir]/dhparam2048.pem' 2048";
#print $cmd.'
';
#flush();
#flush_exec($cmd,200);
#
# Step aside and let the users in (create index.php files).
#
if (! unlink('index.php')) print "Can't unlink index.php";
if (! unlink('setup.php')) print "Can't unlink setup.php";;
if (! unlink('ca/index.php')) print "Can't unlink ca/index.php";
if (! symlink('main.php','index.php')) print "Can't symlink main.php";
if (! symlink('main.php','ca/index.php')) print "Can't symlink ca/main.php";;
?>
Setup is complete. Your CA root certificate as been created.
printFooter();
break;
default:
if (! $country) $country = $config['country'];
if (! $province) $province = $config['province'];
if (! $locality) $locality = $config['locality'];
if (! $organization) $organization = $config['organization'];
if (! $contact) $contact = $config['contact'];
if (! $expiry) $expiry = $config['expiry'];
if (! $expiry) $expiry = 10;
if (! $keysize) $keysize = $config['keysize'];
if (! $keysize) $keysize = 1024;
if (! $passwd) $passwd = $config['ca_pwd'];
if (! $passwdv) $passwdv = $passwd;
if (! $unit) $unit = $config['unit'];
if (! $unit) $unit = "Certificate Authority";
if (! $common_name) $common_name = $config['common_name'];
if (! $common_name) $common_name = "PHPki Certificate Authority";
if (! $getting_help) $getting_help = $config['getting_help'];
if (! $getting_help) $getting_help = '
Contact:
First-Name Last-Name
Company/Organization Name
Address Line #1
Address Line #2
City, State, ZipCode
Phone: (000) 000-0000
E-mail: someone@somewhere.com E-mail is preferred.
';
if (! $store_dir) $store_dir = dirname($_SERVER['DOCUMENT_ROOT']).'/phpki-store';
if (! $base_url) $base_url = $config['base_url'];
if (! $base_url) $base_url = 'http://www.somewhere.com/phpki/';
if (! $ca_prefix) $ca_prefix = $config['ca_prefix'];
if (! $openssl_bin) $openssl_bin = $config['openssl_bin'];
if (! $openssl_bin) $openssl_bin = '/usr/bin/openssl';
if (! $passwd_file) $passwd_file = $config['passwd_file'];
if (! $passwd_file) $passwd_file = dirname($_SERVER['DOCUMENT_ROOT']).'/phpkipasswd';
if (! $header_title) $header_title = $config['header_title'];
if (! $header_title) $header_title = 'Certificate Authority';
printHeader('setup');
?>
printFooter();
break;
}
function create_ca_cnf($email, $expiry) {
}
?>