'; 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 ($contact && ! 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 writable by the web server user \"$uname\"
"; } } else { $er .= "Store directory \"$store_dir\" does not exist. You will have to manually create it as described 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_main_txt = << EOS; # # Write out the CA configuration file. # $fd = fopen("$store_dir/config/config.php", 'w'); fwrite($fd, $config_main_txt); fclose($fd); # # Create the bootstrap configuration # $config_boot_txt = << EOS; # # Write out the bootstrap config # $fd = fopen('./config.php', 'w'); fwrite($fd, $config_boot_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 # $configHOME = $config['home_dir']; $configRANDFILE = $config['random']; $configCa_dir = $config['ca_dir']; $configCert_dir = $config['cert_dir']; $configCrl_dir = $config['crl_dir']; $configDatabase = $config['index']; $configNew_certs_dir = $config['new_certs_dir']; $configPrivate_dir = $config['private_dir']; $configSerial = $config['serial']; $configCacert_pem = $config['cacert_pem']; $configCacrl_pem = $config['cacrl_pem']; $configCakey = $config['cakey']; $configDefault_md = $config['default_md']; $configBase_url = $config['base_url']; $configCrl_dist = $config['crl_distrib']; $configComment_root = $config['comment_root']; $configPolicy_url = $config['policy_url']; $configRevoke_url = $config['revoke_url']; $configComment_email = $config['comment_email']; $configComment_sign = $config['comment_sign']; $configComment_srv = $config['comment_srv']; $config_txt1 = " HOME = $configHOME RANDFILE = $configRANDFILE dir = $configCa_dir certs = $configCert_dir crl_dir = $configCrl_dir database = $configDatabase new_certs_dir = $configNew_certs_dir private_dir = $configPrivate_dir serial = $configSerial certificate = $configCacert_pem crl = $configCacrl_pem private_key = $configCakey crl_extentions = crl_ext default_days = 365 default_crl_days = 30 preserve = no default_md = $configDefault_md [ 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:$configBase_url$configCrl_dist nsComment = $configComment_root #nsCaRevocationUrl = nsCaPolicyUrl = $configBase_url$configPolicy_url [ 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:$configBase_url$configCrl_dist nsComment = $configComment_email nsBaseUrl = $configBase_url nsRevocationUrl = $configRevoke_url #nsRenewalUrl = nsCaPolicyUrl = $configBase_url$configPolicy_url #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:$configBase_url$configCrl_dist nsComment = $configComment_sign nsBaseUrl = $configBase_url nsRevocationUrl = $configRevoke_url #nsRenewalUrl = nsCaPolicyUrl = $configBase_url$configPolicy_url #nsSslServerName = [ server_ext ] basicConstraints = critical, CA:false keyUsage = critical, digitalSignature, keyEncipherment nsCertType = server extendedKeyUsage = critical, serverAuth subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always, issuer:always subjectAltName = $server_altnames issuerAltName = issuer:copy crlDistributionPoints = URI:$configBase_url$configCrl_dist nsComment = $configComment_srv nsBaseUrl = $configBase_url nsRevocationUrl = $configRevoke_url nsCaPolicyUrl = $configBase_url$configPolicy_url [ 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:$configBase_url$configCrl_dist nsComment = $config[comment_stamp] nsBaseUrl = $configBase_url nsRevocationUrl = $configRevoke_url nsCaPolicyUrl = $configBase_url$configPolicy_url [ 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 "; $config_txt2 = <<< EOS [ req ] default_bits = 2048 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; $configCountry = $config['country']; $configProvince = $config['province']; $configLocality = $config['locality']; $configOrganization = $config['organization']; $configUnit = $config['unit']; $configCommon_name = $config['common_name']; $configEmailaddress = $config['contact']; $config_txt3 = <<< EOS [ req ] default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_name string_mask = nombstr req_extensions = req_ext prompt = no [ req_name ] C = $configCountry ST = $configProvince L = $configLocality O = $configOrganization OU = $configUnit CN = $configCommon_name emailAddress = $configEmailaddress [ 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 # $configHome_dir = $config['home_dir']; $tmp_cnf = "$configHome_dir/tmp/openssl.cnf"; $fd = fopen($tmp_cnf, 'w'); fwrite($fd, $config_txt1 . $config_txt3); fclose($fd); # # Initialize 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... '. $keysize .' bits
'; flush(); $configOpenssl_cnf = $config['openssl_cnf']; $configPrivate_dir = $config['private_dir']; $configCacert_pem = $config['cacert_pem']; $configCa_pwd = $config['ca_pwd']; $configCakey = $config['cakey']; $configRandom = $config['random']; $configCacrl_der = $config['cacrl_der']; $configCacrl_pem = $config['cacrl_pem']; // .rnd created here exec(REQ . " -x509 -config $tmp_cnf -extensions root_ext -newkey rsa:$keysize -keyout $configCakey -out $configCacert_pem -passout pass:'$configCa_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 $configOpenssl_cnf -out $configCacrl_pem -passin pass:'$configCa_pwd'"); # Make a copy of the CRL in DER format. # exec(CRL . " -in $configCacrl_pem -out $configCarcrl_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 $config[private_dir]/dhparam1024.pem.

"; #$cmd = "openssl dhparam -rand '$config[random]' -out '$config[private_dir]/dhparam1024.pem' 1024"; #print $cmd.'
'; #flush(); #flush_exec($cmd,100); #print "Please ignore warnings about \"unable to write 'random state\'

"; // This method works but still errors in logs // exec(DH . "-rand '$config[random]' -out '$config[private_dir]/dhparam1024.pem' 1024"); // exec(DH . " -out '$config[private_dir]/dhparam1024.pem' 1024"); print '

Creating 2048 bit Diffie-Hellman parameters used by OpenVPN.
'; print "Saving to $store_dir/dhparam2048.pem.

"; $cmd = "openssl dhparam -rand '$configRandom' -out '$configPrivate_dir/dhparam2048.pem' 2048"; print $cmd.'
'; flush(); flush_exec($cmd, 200); print "Please ignore warnings about \"unable to write 'random state'

"; # # Create a TLS auth key for OpenVPN if openvpn is installed # $command = 'which openvpn'; $command = escapeshellcmd($command); if (system($command) == '/usr/sbin/openvpn') { print '

Creating a TLS authentication key used by OpenVPN.
'; print "Saving to $store_dir/takey.pem.

"; $cmd = "openvpn --genkey --secret '$configPrivate_dir/takey.pem'"; print $cmd.'
'; flush(); flush_exec($cmd); } else { echo "openvpn is required to generate a takey.pem
"; echo "You can create one later like this:
"; echo "openvpn --genkey --secret ". $configPrivate_dir . "/takey.pem
"; } # # 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.

SECURITY WARNING!   Be sure to run the secure.sh shell script as the root user.'; } ?>



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 (! $crl_distrib) { $crl_distrib = 'index.php?stage=dl_crl'; } if (! $revoke_url) { $revoke_url = 'ns_revoke_query.php?'; } if (! $policy_url) { $policy_url = 'policy.html'; } if (! $comment_root) { $comment_root = 'PHPki/OpenSSL Generated Root Certificate Authority'; } if (! $comment_email) { $comment_email = 'PHPki/OpenSSL Generated Personal Certificate'; } if (! $comment_sign) { $comment_sign = 'PHPki/OpenSSL Generated Personal Certificate'; } if (! $comment_srv) { $comment_srv = 'PHPki/OpenSSL Generated Secure Server Certificate'; } if (! $comment_stamp) { $comment_stamp = 'PHPki/OpenSSL Generated Time Stamping Certificate'; } 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'); ?>

Certificate Authority Initial Setup

Root Certificate Data

* Required field

 
Organization *
Department/Unit *
Common Name * This is embeded in certificates, and is most often displayed in e-mail clients as the Issued By: text. This is usually the full name of your certificate authority (i.e. ACME Certificate Authority).
Technical Contact E-mail Address *
Enter an e-mail address where users should send correspondence regarding your certificate authority and the certificates you issue.
Locality *
State/Province *
Country Code ISO 3166 - 2 Characters *
Password *
This password will be used to protect your root certificate private key.
Can't contain single quote ! Do not lose or forget this password.
   Again
Certificate Life *
Enter the number of years you wish your root certificate to be valid.
Key Size *
Enter the size of your certificate key. Recommend 2048+
Certificate Authority Base URL
Enter the public Web address where your Certificate Authority will reside. The address should end with a trailing slash (/) character. This address will be embeded in all certficates issued by your CA, for informational purposes.
Certificate Authority CRL Distribution Points
Provide the public URL where Certificate Revocation List (CRL) of your CA will reside. This path is relative to Base URL above. You may leave it by default if your clients have direct access to PHPki.
Certificate Authority Revocation Check URL
Provide the public URL where clients of your CA can check if the requested certificate has been revoked. This path is relative to Base URL above. You may leave it by default if your clients have direct access to PHPki.
Certificate Authority Policy URL
Provide the public URL where your CA policy will reside. This path is relative to Base URL above. You may leave it by default or adjust to your environment.
Root Certificate Comment
Root certificate Comment attribute. You may change it to something or use the default value set by PHPki.
Email Certificate Comment
Email certificate Comment attribute. You may change it to something or use the default value set by PHPki.
Email/Signing Certificate Comment
Email and signing certificate Comment attribute. You may change it to something or use the default value set by PHPki.
SSL Server Certificate Comment
SSL server certificate Comment attribute. You may change it to something or use the default value set by PHPki.
Time Stamping Certificate Comment
Time stamping certificate Comment attribute. You may change it to something or use the default value set by PHPki.

Configuration Options

Storage Directory *
Enter the location where PHPki will store its files. This should be a directory where the web server has full read/write access (chown ; chmod 700), and is preferably outside of DOCUMENT_ROOT (). You may have to manually create the directory before completing this form.
Location of OpenSSL Executable *
Enter the location of your OpenSSL binary. The default is usually ok.
Location of HTTP password file *
Enter the location of your PHPki user password file. The default is usually ok.
File Upload Prefix
This is an optional prefix which will be added to root certificate and certificate revocation list file uploads. Normally the root certificate is uploaded as caroot.crt. With a prefix like "acme_", the root certificate would be uploaded as "acme_caroot.crt".
Page Header Title
This title will be displayed superimposed over the PHPki logo at the top of every page.
Help Document Contact Info
This text will be inserted into the online help document under the "Getting Additional Help" section. Include full contact info for the convenience of your users. Use HTML tags to improve presentation.
* Required field

Please click the Submit button ONCE and be patient.
This may take a few minutes. Please do not interrupt the process.....