<?php
include('./config.php');
include('./include/my_functions.php');
include('./include/common.php');

$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');
$crl_distrib  = gpvar('crl_distrib');
$revoke_url   = gpvar('revoke_url');
$policy_url   = gpvar('policy_url');
$comment_root = gpvar('comment_root');
$comment_email = gpvar('comment_email');
$comment_sign = gpvar('comment_sign');
$comment_srv  = gpvar('comment_srv');
$comment_stamp = gpvar('comment_stamp');
$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 = '
    <input type=hidden name=country value="' . htvar($country) . '">
    <input type=hidden name=province value="' . htvar($province) . '">
    <input type=hidden name=locality value="' . htvar($locality) . '">
    <input type=hidden name=organization value="' . htvar($organization) . '">
    <input type=hidden name=unit value="' . htvar($unit) . '">
    <input type=hidden name=contact value="' . htvar($contact) . '">
    <input type=hidden name=common_name value="' . htvar($common_name) . '">
    <input type=hidden name=passwd value="' . htvar($passwd) . '">
    <input type=hidden name=passwdv value="' . htvar($passwdv) . '">
    <input type=hidden name=expiry value="' . htvar($expiry) . '">
    <input type=hidden name=keysize value="' . htvar($keysize) . '">
    <input type=hidden name=base_url value="' . htvar($base_url) . '">
    <input type=hidden name=crl_distrib value="' . htvar($crl_distrib) . '">
    <input type=hidden name=revoke_url value="' . htvar($revoke_url) . '">
    <input type=hidden name=policy_url value="' . htvar($policy_url) . '">
    <input type=hidden name=comment_root value="' . htvar($comment_root) . '">
    <input type=hidden name=comment_email value="' . htvar($comment_email) . '">
    <input type=hidden name=comment_sign value="' . htvar($comment_sign) . '">
    <input type=hidden name=comment_srv value="' . htvar($comment_srv) . '">
    <input type=hidden name=comment_stamp value="' . htvar($comment_stamp) . '">
    <input type=hidden name=openssl_bin value="' . htvar($openssl_bin) . '">
    <input type=hidden name=getting_help value="' . htvar($getting_help) . '">
    <input type=hidden name=ca_prefix value="' . htvar($ca_prefix) . '">
    <input type=hidden name=header_title value="' . htvar($header_title) . '">
    <input type=hidden name=passwd_file value="' . htvar($passwd_file) . '">
    <input type=hidden name=store_dir value="' . htvar($store_dir) . '">
';

switch ($stage) {
    case 'validate':
        $er = '';

        if (! $country) {
            $er .= 'Missing Country<br>';
        }
        if (! $province) {
            $er .= 'Missing State/Province<br>';
        }
        if (! $locality) {
            $er .= 'Missing Locality<br>';
        }
        if (! $organization) {
            $er .= 'Missing Organization<br>';
        }
        if (! $unit) {
            $er .= 'Missing Unit/Department<br>';
        }
        if (! $contact) {
            $er .= 'Missing Contact E-mail Address<br>';
        }
        if (! $common_name) {
            $er .= 'Missing Common Name<br>';
        }
        if (! $passwd) {
            $er .= 'Missing Certificate Password<br>';
        }
        if (! $passwdv) {
            $er .= 'Missing Certificate Password Verification "Again"<br>';
        }
        if (! $header_title) {
            $er .= 'Missing Header Title<br>';
        }
        if (! $passwd_file) {
            $er .= 'Missing User Password File Location';
        }
        if (! $store_dir) {
            $er .= 'Missing Storage Directory<br>';
        }

        $countrycode = strtoupper($country);

        if (! preg_match("/\b[A-Z][A-Z]\b/", $countrycode, $match)) {
            $er .= 'Country Code must be ISO 3166 two letters <br>';
        }

        if ($passwd && strlen($passwd) < 8) {
            $er .= 'Certificate password is too short.<br>';
        }

        if ($passwd and $passwd != $passwdv) {
            $er .= 'Password and password verification do not match.<br>';
        }

        if ($contact && ! is_email($contact)) {
                $er .= 'E-mail address ('. htvar($contact) . ') may be invalid.<br>';
        }

        // reetp this was the wrong way round - swapped
        // strpos ($haystack, $needle)
        if (strpos($_SERVER['DOCUMENT_ROOT'], $store_dir) === 0) {
            $er .= 'Store directory ('.$store_dir.') must exist somewhere outside of DOCUMENT_ROOT ('.$_SERVER['DOCUMENT_ROOT'].').<br>';
        }

        // reetp this was the wrong way round - swapped
        // strpos ($haystack, $needle)
        if (strpos(dirname($_SERVER['SCRIPT_FILENAME']), $store_dir) === 0) {
            $er .= 'Store directory ('.$store_dir.') cannot exist within the PHPki installation directory ('.dirname($_SERVER['SCRIPT_FILENAME']).').<br>';
        }

        if (! $er) {
            if (! file_exists($store_dir)) {
                if (! mkdir("$store_dir", $store_perms)) {
                    $er .= "Could not create the store directory \"$store_dir\"<br>";
                }
            }

            if (file_exists($store_dir)) {
                if (! chmod($store_dir, $store_perms)) {
                    $er .= "Could not change permissions on the store directory \"$store_dir\"<br>";
                }
                if (! is_readable($store_dir)) {
                    $er .= "The store directory \"$store_dir\" is not readable by the web server user \"$uname\"<br>";
                }
                if (! is_writeable($store_dir)) {
                    $er .= "The store directory \"$store_dir\: is not writable by the web server user \"$uname\"<br>";
                }
            } else {
                $er .= "Store directory \"$store_dir\" does not exist.  You will have to manually create it as described in the setup form.<br>";
            }
        }

        if ($er) {
                $er = '<h2>ERROR(S) IN FORM:</h2><h4><blockquote>' . $er . '</blockquote></h4>';
        }

        if ($er) {
                printHeader('setup');
                ?>

                <form action='<?php echo $PHP_SELF?>' method=post>
                <input type=submit name=Submit value='Go Back'>
                <font color=#ff0000><?php echo $er?></font>
                <br><input type=submit name=Submit2 value='Go Back'>

                <?php
                print $hidden_fields;
                print "</form>";

                printFooter();
                break;
        }
  
        // Here we have "if (not $er)" then fall through to case 'write'
        // It's pretty crappy coding TBH

    case 'write':
        printHeader('about');

        #
        #Create the file store directory structure.
        #

        print '<strong>Creating PHPki file store...</strong><br>';
        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 '<strong>Writing configuration files...</strong><br>';
        flush();

        $config_main_txt = <<<EOS
<?php
# PHPki CONFIGURATION FILE
# Automatically generated by PHPki.  Edit at your own peril.
#
\$config['organization']  = '$organization';
\$config['unit']          = '$unit';
\$config['contact']       = '$contact';
\$config['locality']      = '$locality';
\$config['province']      = '$province';
\$config['country']       = '$country';
\$config['common_name']   = '$common_name';

# Store Directory
\$config['store_dir']     = '$store_dir';

# Location HTTP Password File
\$config['passwd_file']   = '$passwd_file';

# Password for CA root certificate.
\$config['ca_pwd']        = '$passwd';

# Number of years the root certificate is good.
\$config['expiry']        = '$expiry';

# CA certificate key size
\$config['keysize']       = '$keysize';

# This is superimposed over the PHPki logo on each page.
\$config['header_title']  = '$header_title';

# String to prefix cer and crl uploads
\$config['ca_prefix']     = '$ca_prefix';

# Location of your OpenSSL binary.
\$config['openssl_bin']   = '$openssl_bin';

# Base URL
\$config['base_url']      = '$base_url';

# CRL Distribution points path
\$config['crl_distrib']   = '$crl_distrib';

# Certificate Revocation URL
\$config['revoke_url']    = '$revoke_url';

# Certificate Authority Policy URL
\$config['policy_url']    = '$policy_url';

# Certificate Comment Fields
\$config['comment_root']  = '$comment_root';
\$config['comment_email'] = '$comment_email';
\$config['comment_sign']  = '$comment_sign';
\$config['comment_srv']   = '$comment_srv';
\$config['comment_stamp'] = '$comment_stamp';

# Who users should contact if they have technical difficulty with
# your certificate authority site.
\$config['getting_help']  = '$getting_help';

#
# You shouldn't change anything below this line.  If you do, don't
# ask for help!
#
\$config['home_dir']      = \$config['store_dir'];
\$config['ca_dir']        = \$config['home_dir'] . '/CA';
\$config['private_dir']   = \$config['ca_dir']   . '/private';
\$config['new_certs_dir'] = \$config['ca_dir']   . '/newcerts';
\$config['cert_dir']      = \$config['ca_dir']   . '/certs';
\$config['req_dir']       = \$config['ca_dir']   . '/requests';
\$config['crl_dir']       = \$config['ca_dir']   . '/crl';
\$config['pfx_dir']       = \$config['ca_dir']   . '/pfx';
\$config['index']         = \$config['ca_dir']   . '/index.txt';
\$config['serial']        = \$config['ca_dir']   . '/serial';
\$config['random']        = \$config['ca_dir']   . '/.rnd';
\$config['cacrl_pem']     = \$config['crl_dir']  . '/cacrl.pem';
\$config['cacrl_der']     = \$config['crl_dir']  . '/cacrl.crl';
\$config['cacert_pem']    = \$config['cert_dir'] . '/cacert.pem';
\$config['cakey']         = \$config['private_dir'] . '/cakey.pem';

# Default OpenSSL Config File.
\$config['openssl_cnf']   = \$config['home_dir'] . '/config/openssl.cnf';

# Define default md
\$config['default_md']    = 'sha512';

\$PHPki_admins = Array(md5('admin'));

define('OPENSSL',\$config['openssl_bin'].' ');
define('X509', OPENSSL . ' x509 ');
define('PKCS12', "RANDFILE='\$config[random]' " . OPENSSL . ' pkcs12 ');
define('CA', OPENSSL . ' ca ');
define('REQ', OPENSSL . ' req ');
define('CRL', OPENSSL . ' crl ');
define('DH', OPENSSL . ' dhparam ');
# define('DH', OPENSSL . ' dhparam ' . "RANDFILE='$config[random]' ");
?>
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
<?php
define('PHPKI_VERSION','$version');
define('STORE_DIR','$store_dir');
define('DEMO',FALSE);
define('BASE_URL','$base_url');
?>
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 '<strong>Creating root certificate... '. $keysize .' bits</strong><br>';
        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 '<strong>Generating certificate revocation list...</strong><br>';
        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 '<p><strong>Creating 1024 bit Diffie-Hellman parameters used by OpenVPN.<br>';
        #print "Saving to $config[private_dir]/dhparam1024.pem.</strong><br>";
        #$cmd = "openssl dhparam -rand '$config[random]' -out '$config[private_dir]/dhparam1024.pem' 1024";
        #print $cmd.'<br>';
        #flush();
        #flush_exec($cmd,100);

        #print "Please ignore warnings about \"unable to write 'random state\' <br><br>";

        // 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 '<p><strong>Creating 2048 bit Diffie-Hellman parameters used by OpenVPN.<br>';
        print "Saving to $store_dir/dhparam2048.pem.</strong><br>";
        $cmd = "openssl dhparam -rand '$configRandom' -out '$configPrivate_dir/dhparam2048.pem' 2048";
        print $cmd.'<br>';
        flush();
        flush_exec($cmd, 200);

        print "Please ignore warnings about \"unable to write 'random state' <br><br>";

        #
        # Create a TLS auth key for OpenVPN if openvpn is installed
        #
        $command = 'which openvpn';
        $command = escapeshellcmd($command);

        if (system($command) == '/usr/sbin/openvpn') {
            print '<p><strong>Creating a TLS authentication key used by OpenVPN.<br>';
            print "Saving to $store_dir/takey.pem.</strong><br>";
            $cmd = "openvpn --genkey --secret '$configPrivate_dir/takey.pem'";
            print $cmd.'<br>';
            flush();
            flush_exec($cmd);
        } else {
            echo "openvpn is required to generate a takey.pem<br>";
            echo "You can create one later like this:<br>";
            echo "openvpn --genkey --secret ". $configPrivate_dir . "/takey.pem<br>";
        }



        #
        # 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";
        }

        ?>
        <center>
        <h2>Setup is complete. Your CA root certificate as been created.</h2>
        <?php
        if (! getOSInformation()) {
            print '<h3><font color=red>SECURITY WARNING!&nbsp;&nbsp; Be sure to run the <cite>secure.sh</cite> shell script as the <strong>root</strong> user.</font></h3>';
        }
        ?>
        <p><br><br>
        <form action='<?php echo $PHP_SELF?>' method=post>
        <input type=submit name=submit value="Proceed To The PHPki Main Menu">
        <input type=hidden name=stage value=finished>
        </form>
        </center>
        <?php
        printFooter();
        break;

    case 'finished':
        // We get here if we complete the previous section
        // if OS = SME then go to server manager else, reload
        if (getOSInformation){
            $location = "/server-manager/cgi-bin/phpki";
        } else {
            $location = $PHP_SELF;
        }
        echo '<META HTTP-EQUIV="Refresh" Content="0; URL=' . $location . '">';
        exit; 

    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 = 2048;
        }
        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 = '
<b>Contact:</b><br>
First-Name Last-Name<br>
Company/Organization Name<br>
Address Line #1<br>
Address Line #2<br>
City, State, ZipCode<br>
<br>
Phone: (000) 000-0000<br>
E-mail: <a href=mailto:someone@somewhere.com>someone@somewhere.com</a>&nbsp;&nbsp;&nbsp;<i><b>E-mail is preferred.</b></i><br>';
        }

        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 = 'dl_crl.php';
        }
        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');
        ?>
        <form action="<?php echo $PHP_SELF?>" method="post">
    <center><h2>Certificate Authority Initial Setup</h2></center>
    <table width=99%>
    <tr>
    <th colspan=2><h3>Root Certificate Data</h3></th>
    </tr>
    <tr>
    <td/><h4><font color=red>* Required field</font></h4></td>
    <td>&nbsp;</td>
    </tr>
    <tr>
    <td width=35%><strong>Organization</strong> <font color=red>*</font></td>
    <td><input type=text name=organization value="<?php echo htvar($organization)?>" maxlength=60 size=50></td>
    </tr>

    <tr>
    <td><strong>Department/Unit</strong> <font color=red>*</font></td>
    <td><input type=text name=unit value="<?php echo htvar($unit)?>" maxlength=60 size=30></td>
    </tr>

    <tr>
    <td>
    <strong>Common Name</strong> <font color=red>*</font>
    This is embeded in certificates, and is most often displayed in
    e-mail clients as the <cite>Issued By:</cite> text.  This is usually
    the full name of your certificate authority (i.e. ACME Certificate Authority).
    </td>
    <td><input type=text name=common_name value="<?php echo htvar($common_name)?>" maxlength=60 size=60></td>
    </tr>

    <tr>
    <td>
    <strong>Technical Contact E-mail Address</strong> <font color=red>*</font><br>
    Enter an e-mail address where users should send correspondence
    regarding your certificate authority and the certificates you issue.
    </td>

    <td><input type=text name=contact value="<?php echo htvar($contact)?>" maxlength=60 size=30></td>
    </tr>

    <tr>
    <td><strong>Locality</strong> <font color=red>*</font></td>
    <td><input type=text name=locality value="<?php echo htvar($locality)?>" maxlength=60 size=30></td>
    </tr>

    <tr>
    <td><strong>State/Province</strong> <font color=red>*</font></td>
    <td><input type=text name=province value="<?php echo htvar($province)?>" maxlength=60 size=20></td>
    </tr>

    <tr>
    <td><strong>Country Code ISO 3166 - 2 Characters</strong> <font color=red>*</font></td>
    <td><input type=text name=country value="<?php echo htvar($country)?>" maxlength=2 size=2></td>
    </tr>

    <tr>
    <td>
    <strong>Password</strong> <font color=red>*</font><br>
    This password will be used to protect your root certificate private
    key.<br/>Can't contain single quote ! <strong><font color=red>Do not lose or forget this password.</font></strong>
    </td>
    <td><input type=password name=passwd value="<?php echo htvar($passwd)?>" size=30>&nbsp;&nbsp; Again <input type=password name=passwdv value="<?php echo htvar($passwdv)?>" size=30></td>
    </tr>

    <tr>
    <td>
    <strong>Certificate Life</strong> <font color=red>*</font><br>
    Enter the number of years you wish your root certificate to be valid.
    </td>
    <td><select name=expiry>

    <?php
    for ($i = 5; $i <= 15; $i+=5) {
        print "<option value=$i " . ($expiry == $i ? "selected='selected'" : "") . " >$i Years</option>\n" ;
    }
    ?>

    </select></td>
    </tr>

    <tr>
    <td>
    <strong>Key Size</strong> <font color=red>*</font><br>
    Enter the size of your certificate key. Recommend 2048+
    </td>
    <td><select name=keysize>

    <?php
    for ($i = 1024; $i <= 4096; $i+=512) {
        print "<option value=$i " . ($keysize == $i ? "selected='selected'" : "") . ">$i bits</option>\n" ;
    }
    ?>

    </select></td>
    </tr>

    <tr>
    <td>
    <strong>Certificate Authority Base URL</strong><br>
    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.
    </td>
    <td>
    <input type=text name=base_url value="<?php echo htvar($base_url)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Certificate Authority CRL Distribution Points</strong><br>
     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.
    </td>
    <td>
    <input type=text name=crl_distrib value="<?php echo htvar($crl_distrib)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Certificate Authority Revocation Check URL</strong><br>
     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.
    </td>
    <td>
    <input type=text name=revoke_url value="<?php echo htvar($revoke_url)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Certificate Authority Policy URL</strong><br>
     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.
    </td>
    <td>
    <input type=text name=policy_url value="<?php echo htvar($policy_url)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Root Certificate Comment</strong><br>
     Root certificate Comment attribute. You may change it to something
     or use the default value set by PHPki.
    </td>
    <td>
    <input type=text name=comment_root value="<?php echo htvar($comment_root)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Email Certificate Comment</strong><br>
     Email certificate Comment attribute. You may change it to something
     or use the default value set by PHPki.
    </td>
    <td>
    <input type=text name=comment_email value="<?php echo htvar($comment_email)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Email/Signing Certificate Comment</strong><br>
     Email and signing certificate Comment attribute. You may change it
     to something or use the default value set by PHPki.
    </td>
    <td>
    <input type=text name=comment_sign value="<?php echo htvar($comment_sign)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>SSL Server Certificate Comment</strong><br>
     SSL server certificate Comment attribute. You may change it to something
     or use the default value set by PHPki.
    </td>
    <td>
    <input type=text name=comment_srv value="<?php echo htvar($comment_srv)?>" size=50>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Time Stamping Certificate Comment</strong><br>
     Time stamping certificate Comment attribute. You may change it
     to something or use the default value set by PHPki.
    </td>
    <td>
    <input type=text name=comment_stamp value="<?php echo htvar($comment_stamp)?>" size=50>
    </td>
    </tr>

    </table>

    <p>
    <table width=99%>
    <tr>
    <th colspan=2><h3>Configuration Options</h3></th>
    </tr>

    <tr>
    <td width=35%>
    <strong>Storage Directory <font color=red>*</font></strong><br>
    Enter the location where PHPki will store its files.  This should be a directory where
    the web server has full read/write access (chown <?php echo $uname?> ; chmod 700), and is preferably
    outside of DOCUMENT_ROOT (<?php echo $_SERVER['DOCUMENT_ROOT']?>).  You may have to manually create the directory before completing this form.
    </td>
    <td>
    <input type=text name=store_dir value="<?php echo htvar($store_dir)?>" size=35>
    </td>
    </tr>

    <tr>
    <td width=35%>
    <strong>Location of OpenSSL Executable <font color=red>*</font></strong><br>
    Enter the location of your OpenSSL binary.  The default is usually ok.
    </td>
    <td>
    <input type=text name=openssl_bin value="<?php echo htvar($openssl_bin)?>" size=35>
    </td>
    </tr>

    <tr>
    <td width=35%>
    <strong>Location of HTTP password file <font color=red>*</font></strong><br>
    Enter the location of your PHPki user password file.  The default is usually ok.
    </td>
    <td>
    <input type=text name=passwd_file value="<?php echo htvar($passwd_file)?>" size=35>
    </td>
    </tr>

    <tr>
    <td>
    <strong>File Upload Prefix</strong><br>
    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
    <cite style="white-space: nowrap">"acme_"</cite>, the root certificate would be uploaded as
    <cite>"acme_caroot.crt"</cite>.
    </td>
    <td>
    <input type=text name=ca_prefix value="<?php echo htvar($ca_prefix)?>" maxlength=10 size=10>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Page Header Title</strong><br>
    This title will be displayed superimposed over the PHPki logo at the
    top of every page.
    </td>
    <td>
    <input type=text name=header_title value="<?php echo htvar($header_title)?>" maxlength=40 size=40>
    </td>
    </tr>

    <tr>
    <td>
    <strong>Help Document Contact Info</strong><br>
    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.
    </td>
    <td>
    <textarea name=getting_help cols=50 rows=15><?php echo htvar($getting_help)?></textarea>
    </td>
    </tr>
    </table>

    <font color=red>* Required field</font>
    <p><center><font color=red>Please click the Submit button ONCE and be patient.</font><br />
       This may take a few minutes. Please do not interrupt the process.....</center>
    </p>

    <p>
    <center><input style="border: 1px solid red; padding: 10px;" type=submit name=submit value=Submit></center>
    <input type=hidden name=stage value='validate'>
    </form>
    </p>

    <?php
    printFooter();
        break;
}

function create_ca_cnf($email, $expiry)
{
}
?>
