<?PHP		#index.php of VIVOS (Tabelio), maybe authentrus

require_once(".htfolder.inc.php");
if (isset($_REQUEST["command"])) $command=$_REQUEST["command"];
if (isset($_REQUEST["display"])) $display=$_REQUEST["display"];
define ('ENROLL',"Enroll");
define ('NEWSIGNER',"New Signer");
define ('UPLOAD',"C:\Uploads");
define ('TOOMANYTOLIST',22);
$self=$_SERVER["SERVER_NAME"].$_SERVER["PHP_SELF"];
$openssldir="/usr/bin";
$biofiles_dir=HARDTOGET."webvivos/bio";
$namefiles_dir=HARDTOGET."names";
$certs_dir=HARDTOGET."webvivos";

# The configuration file made on the fly for vivos cheapo certificates.

# This one is adapted for the valID certificates
function cnf_make($filename,$count,$dir)

{

	#$certs_dir="$dir/certs";

	$certs_dir=$dir;

	$cnfp=fopen($filename,"w");

	if (!$cnfp)
	{
		loggywoggy("Failed to open configuration file $filename.");
		return $cnfp;
	}
	fwrite($cnfp,"[ ca ]\n");

	fwrite($cnfp,"default_ca	= $count"."ca\n\n");


	fwrite($cnfp,"[ $count"."ca ]\n");

	fwrite($cnfp,"certificate      = $dir/root.pem\n");

	fwrite($cnfp,"new_certs_dir    = $certs_dir\n");

	$databasefile="$certs_dir/$count.txt";
	fwrite($cnfp,"database		= $databasefile\n");
	touch($databasefile);

	fwrite($cnfp,"private_key      = $dir/rootkey.pem\n");

	$serialfile="$certs_dir/$count.srl";
	fwrite($cnfp,"serial           = $serialfile\n");
	$serp=fopen($serialfile,"w");
	fwrite($serp,sprintf("%04x",$count));
	fclose($serp);


	fwrite($cnfp,"default_crl_days = 7\n");

	fwrite($cnfp,"default_days     = 365\n");

	fwrite($cnfp,"default_md       = sha1\n");


	fwrite($cnfp,"policy           = $count"."_policy\n");

	fwrite($cnfp,"x509_extensions  = certificate_extensions\n");


	fwrite($cnfp,"[ $count"."_policy ]\n");

	fwrite($cnfp,"countryName            = optional\n");

	fwrite($cnfp,"stateOrProvinceName    = optional\n");

	fwrite($cnfp,"localityName           = optional\n");

	fwrite($cnfp,"organizationName       = optional\n");

	fwrite($cnfp,"organizationalUnitName = optional\n");

	fwrite($cnfp,"commonName             = supplied\n");

	fwrite($cnfp,"emailAddress           = optional\n");


	fwrite($cnfp,"[ req ]\n");
	fwrite($cnfp,"default_bits		= 2048\n");

	fwrite($cnfp,"default_keyfile 	= privkey.pem\n");

	fwrite($cnfp,"default_md              = sha1\n");


	fwrite($cnfp,"prompt                  = no\n");

	fwrite($cnfp,"distinguished_name	= req_distinguished_name\n");

	fwrite($cnfp,"x509_extensions		= req_extensions\n");


# the following sections are specific to the request we're building


	fwrite($cnfp,"[ certificate_extensions ]\n");

	fwrite($cnfp,"basicConstraints = CA:false\n");


	fwrite($cnfp,"[ req_distinguished_name ]\n");

	fwrite($cnfp,"countryName         	= US\n");

	fwrite($cnfp,"stateOrProvinceName 	= New York\n");

	fwrite($cnfp,"localityName        	= Wantagh\n");

	fwrite($cnfp,"organizationName    	= Suffolk County\n");

	fwrite($cnfp,"organizationalUnitName	= Birth Certificates\n");

	fwrite($cnfp,"commonName          	= William F. Schmitt\n");


	fwrite($cnfp,"[ req_extensions ]\n");

	fwrite($cnfp,"basicConstraints = CA:true\n");

	fwrite($cnfp,"subjectAltName = DNS:Bill Schmitt\n");

#subjectAltName = DNS:splat.zork.org,DNS:localhost\n");

	fclose($cnfp);

	return TRUE;

}

if (!function_exists('dberrors'))
{
function dberrors($res)		#$res is an error object found by pearcheak.
{
	$a=print_r($res->getDebugInfo(),TRUE);
	if ($res->getDebugInfo() != ($res->getUserInfo()))
		$a.="\n".print_r($res->getUserInfo(),TRUE);
	return $a;
}
}


if (!function_exists('show_cert'))
{
function show_cert($cert)
{
	
			$lusk=openssl_x509_parse($cert);
			$a="<PRE>";
			$a.=print_r($lusk,TRUE);
			$a.="</PRE>";
	return $a;
}
}
####################################END OF UPPER STUFF, NOW LETS DO SOMETHING.


if (isset($command)) switch($command)
{
	case ENROLL:
		##	Record the subject in the database.
		$subjectid=DBnextId($db,"subject","subjectid");
		$query=DBinsertQuery($db,"","insert into subject(subjectid,status,officerid,",
					")values($subjectid,'gd',$surferid,",
					")",
			"first,middle,surname,email,country,state,employer,division,title");
		if (strlen($query) > 0)
		{
			$biofile="$biofiles_dir/$subjectid.bio";
			$msgs.=addMessage("The biometrics file is at $biofile.");
			if (move_uploaded_file($_FILES["biofile"]["tmp_name"],$biofile))
			{
				$msgs.=addMessage("Biometrics file is properly stored.");
				chmod($biofile,0444);
				loggywoggy("The biometrics file is stored at $biofile.");
			}
			else
			{
				$errors.=addError("The biometrics file got lost.");
				$display="enroll";
			}
			if (pearcheck($res=$db->query($query)))
			{
				loggywoggy("Could not add subject with\n$query");
				loggywoggy(dberrors($res));
			}
		}
		else
		{
			$errors.=adderror("We could not record the subject's information.");
			$display="enroll";
			break;
		}


		##	Make the certificate
		$signerid=((isset($_REQUEST["signerid"]))?($_REQUEST["signerid"]):(0));
		$serial=DBnextId($db,"signer",$signerid);
		if (!(serial > 0))
		{
			loggywoggy("Failed to get a serial number from sequence for signer $signerid.");
		}
		$signer=DBrowById($db,"signer",$signerid);
		$CAFILE="$certs_dir/$signerid/certs/root.pem";
		$CACERT="-cert $CAFILE ";
		$CAKEYFILE="-keyfile $certs_dir/$signerid/certs/rootkey.pem";
		$CAKEY="-key ".$signer["password"];
		$DAYS="-days ".$signer["days"];
		$ERRORFILE="$certs_dir/$signerid/certs/errors";

		$req_names = array('common_name'=>'commonName', 'email'=>'emailAddress', 'employer'=>'organizationName',
                 'division'=>'organizationalUnitName', 'city'=>'localityName', 'state'=>'stateOrProvinceName',
                 'country'=>'countryName',
			'first'=>'givenName','middle'=>'initials','surname'=>'surname','title'=>'title');
		$req_file=HARDTOGET."webvivos/$signerid/names/$serial.names";
		$msgs.=addMessage("The names and request are in $req_file.");
	
		$reqp=fopen($req_file,"w");
		while (list($key, $val) = each($req_names))
		{
			if (isset($_REQUEST[$key]))
			{
				$value=str_replace("\r\n","",$_REQUEST[$key]);
				fwrite($reqp,sprintf("%s = %s\n",$val,$value));
			}
		}
		fwrite($reqp,sprintf("SPKAC = %s\n",str_replace("\r\n","",$_REQUEST["SPKAC"])));
		fclose($reqp);
		chmod($req_file,0644);
		$req=file_get_contents($req_file);
		$cnffile="$certs_dir/$signerid/certs/$serial.cnf";
		if (!cnf_make($cnffile,$serial,"$certs_dir/$signerid/certs"))
		{
			loggywoggy("Could not create a configuration file for subject $subjectid.");
			$errors.=addError("We could not create a configuration file, the whole thing fails.");
			break;
		}
		$cmd="$openssldir/openssl ca -batch -config $cnffile "
			."-extensions certificate_extensions "
			."$CACERT "
			."$CAKEYFILE "
			."$CAKEY "
			."-spkac $req_file "
			."$DAYS "
			."-verbose "
			."2>$ERRORFILE";
		$cert = shell_exec ($cmd);
		if (strlen($cert) == 0)
		{
			$errors.=addError("Our attempt to sign your certificate was unsuccessful.");
			loggywoggy("Failed to create a certificate for officer $surferid with this request:\n$req");
			$display="enroll";
			break;
		}
		#loggywoggy("Request\n$req\nsubjected to command\n$cmd\ngot a certificate\n$cert");
		loggywoggy("Just generated certificate for $subjectid on authority of officer $surferid.");
		header("Content-Type: application/x-x509-user-cert");
		#	header("Content-Length: ".strlen($cert));
		#	header("Location: $PHP_SELF?command=info");
		echo $cert;
		$certificateid=DBnextId($db,"certificate","certificateid");
		$query="insert into certificate (certificateid,signerid,officerid,serial_number,common_name,"
			."request,certificate,private_key,subjectid,ip,granted"
			.") values ($certificateid,$signerid,$surferid,$serial"
			.",'".$_REQUEST["common_name"]."'"
			.",'$req'"
			.",'".strstr($cert,"-----BEGIN CERTIFICATE-----")."'"
			.",NULL"
			.",$subjectid"
			.",".ip2long($_SERVER["REMOTE_ADDR"])
			.",now())";
		if (pearcheck($res=$db->query($query)))
		{
			$errors.=addError("Your certificate was not properly recorded.");
			loggywoggy("Unable to record the certificate in the database with:\n$query");
			loggywoggy(dberrors($res));
		}
		else
		{
			loggywoggy("Certificate $certificateid for subject $subjectid and authorized by $surferid was granted and recorded.");
		}
		$display="done";
		break;

	case NEWSIGNER:
		$signerid=DBnextId($db,"signer","signerid");
		$query=DBinsertQuery($db,"","insert into signer(signerid,officerid,",
					") values ($signerid,$surferid,
					",")",
			"certificate,private_key,common_name,password","days");
		if (strlen($query) == 0)
		{
			$errors.=addError("I'm sorry but we could not figure out how to add your certificate to our system.");
			$display="newsigner";
			loggywoggy("Could not add a certificate for officer $signerid.");
			break;
		}
		if (pearcheck($res=$db->query($query)))
		{
			$errors.=addError("I'm sorry but we tried to add your certificate to our records but it failed.");
			$display="newsigner";
			loggywoggy("Could not add certificate of officer $surferid with\n$query");
			loggywoggy(dberrors($res));
			break;
		}
		$msgs.=addMessage("Your certificate is probably in the database now.");
		$seq_name="signer_".$signerid."_seq";
		$query="create sequence $seq_name";
		if (isset($_REQUEST["serialstart"])) $query.=" start with ".$_REQUEST["serialstart"];
		if (isset($_REQUEST["increment"])) $query.=" increment by ".$_REQUEST["increment"];
		if (pearcheck($res=$db->query($query)))
		{
			$errors.=addError("We recorded your certificate but for some reason we couldn't create a serial number generator.  "
				."This means that you can't use it until we straighted this out.");
			loggywoggy("Failed to create signer sequence $signerid for officer $surferid.");
				loggywoggy(dberrors($res));
		}
		else
		{
			if (pearcheck($res=$db->query("grant all on $seq_name to authentrusmaster")))
			{
				loggywoggy("Could not give authentrusmaster permission on $seq_name.\n".dberrors($res));
			}
		}
		$certsdir="$certs_dir/$signerid";
		if (!mkdir($certsdir))
		{
			$errors.=addError("We could not create the new directory for your signing certificate.");
			$display="newsigner";
			loggywoggy("Could not create directory $certsdir for officer $surferid.");
			break;
		}
/*						biometrics can be stored in $certs_dir/bio/$subjectid
		if (!mkdir("$certsdir/bio"))
		{
			$errors.=addError("We messed up our directory structure.  Please call us so we can fix it right away.");
			loggywoggy("Unable to make the bio directory for signer $signerid.");
		}
*/
		if (!mkdir("$certsdir/names"))
		{
			$errors.=addError("We messed up our directory structure.  Please call us so we can fix it right away.");
			loggywoggy("Unable to make the names directory for signer $signerid.");
		}
		if (!mkdir("$certsdir/certs"))
		{
			$errors.=addError("We messed up our directory structure.  Please call us so we can fix it right away.");
			loggywoggy("Unable to make the certs directory for signer $signerid.");
			break;
		}
		$rootfile="$certsdir/certs/root.pem";
		if (file_put_contents($rootfile,$_REQUEST["certificate"]) == 0)
		{
			$errors.=addError("I'm sorry, but we were unable to put your certificate in its new folder.");
			$display="newsigner";
			loggywoggy("Could not spill signing certificate $signerid to $rootfile.");
			break;
		}
		$rootkeyfile="$certsdir/certs/rootkey.pem";
		if (file_put_contents($rootkeyfile,$_REQUEST["private_key"],0400) == 0)
		{
			$errors.=addError("I'm sorry, but we were unable to put your file in its new folder.");
			$display="newsigner";
			loggywoggy("Could not spill private key $signerid to $rootkeyfile.");
			break;
		}
		loggywoggy("We have added signing certificate $signerid with all its directories and probably the serial number sequence.");
		break;
/*	case "TESTTHIS":
		if (pearcheck($res=$db->query("select s.signerid from signer s,certificate c wher s.officerid=c.officerid or c.subjectid=33")))
		{
			$errors.=addError(dberrors($res));
				loggywoggy(dberrors($res));
			break;
			$errors.=addError("getMessage gets<BR>".print_r($res->getMessage(),TRUE));
			$errors.=addError("getDebugInfo gets<BR>".print_r($res->getDebugInfo(),TRUE));
			if ($res->getDebugInfo() != ($res->getUserInfo()))
			$errors.=addError("getUserInfo gets<BR>".print_r($res->getUserInfo(),TRUE));
		}
		else
		{
			$n=nrows($res);
			$msgs.=addMessage("The query got $n rows.");
			if ($n>0)
			{
				$row=$res->fetchRow();
				$msgs.=addMessage("The first signerid is ".$row["signerid"]);
			}	
		}
		break;
*/
	default:
		loggywoggy("We did not process the command $command.");
}

if (isset($display))
{
	echo page_top($site_name,$display);
	if (strlen($errors) > 0) echo "<FONT color=red size=+3>$errors</FONT>";
	if (strlen($msgs) > 0) echo "$msgs";
	#if (isset($_POST)) echo "<BR>The variables posted are:<PRE>".print_r($_POST,TRUE)."</PRE>";
	#if (isset($_FILES)) echo "<BR>The files uploaded are:<PRE>".print_r($_FILES,TRUE)."</PRE>";
	echo "<BR>";
switch($display)
{
	case "correct":
		echo "You should have done it right the first time.";
		break;
	case "me":
		echo "Did you know that vanity is one of the seven deadly sins?";
		break;
	case "download":
		break;
	case "viewsigner":
		$certid=$_REQUEST["id"];
		$cert=DBrowById($db,"signer",$certid);
		echo "<H2>Signing Certificate ".$cert["certificateid"]."-".$cert["common_name"]."</H2>";
		echo show_cert($cert["certificate"]);
		break;
	case "viewsubject":
		$subjectid=$_REQUEST["id"];
		$row=DBrowById($db,"subject",$subjectid,"subjectid");
		echo "\n<H2>Subject $subjectid--".make_name($row)."</H2>";
		echo "\n<TABLE>"
			."\n<TR><TD>First name</TD><TD>".$row["first"]."</TD></TR>"
			."\n<TR><TD>Middle name</TD><TD>".$row["middle"]."</TD></TR>"
			."\n<TR><TD>Surname</TD><TD>".$row["surname"]."</TD></TR>"
			."\n<TR><TD>Status</TD><TD>".$db->getOne("select meaning from subject_status where status='".$row["status"]."'")."</TD></TR>"
			."\n<TR><TD>Supporting Documents</TD><TD>"."</TD></TR>";
		echo "\n</TABLE>\n";
		if (pearcheck($certs=$db->query("select * from certificate where subjectid=$subjectid")))
		{
			echo "We were unable to find certificates for this subject.";
				loggywoggy(dberrors($res));
		}
		else
		{
			$n=nrows($certs);
			if ($n == 0)
			{
				echo "We have not issued any certificates to this subject.";
			}
			else
			{
				echo (($n == 1)?("This certificate was"):("These $n certificates were"))." issued to this subject:<UL>";
				
				while ($cert=$certs->fetchRow())
				{
					$certid=$cert["certificateid"];
					echo "<LI>Certificate $certid was issued to this subject";
					echo "<BR>on ".$cert["granted"];
					echo "<BR>signed by certificate ".$cert["signerid"];
					echo "<BR>on the authority of officer ".$cert["officerid"];
					echo "<BR><A href=https://$self?display=viewcert&id=$certid>View this certificate</A>";
					echo "</LI>";
				}
				echo "</UL>";
			}
		}
		break;
	case "viewcert":
		$certid=$_REQUEST["id"];
		$cert=DBrowById($db,"certificate",$certid);
		echo "<H2>Certificate ".$cert["certificateid"]."-".$cert["common_name"]."</H2>";
		echo show_cert($cert["certificate"]);
		break;
	case "enroll":
		echo "<FORM method='post' enctype='multipart/form-data' action='https://$self' onSubmit=\"if(!check()){return false;}\">";
		echo "\n<TABLE>";
		echo "\n<TR>".formTag("Honorific")."<TD><INPUT name=title id=title></TD></TR>";
		echo "\n<TR>".formTag("First Name")."<TD><INPUT name=first id=first></TD></TR>";
		echo "\n<TR>".formTag("Middle Name(s)/Initial(s)")."<TD><INPUT name=middle id=middle></TD></TR>";
		echo "\n<TR>".formTag("Surname")."<TD><INPUT name=surname id=surname></TD></TR>";
		echo "\n<TR>".formTag("Common Name")."<TD><INPUT name=common_name id=common_name></TD><TD>What name do you go by.</TD></TR>";

		echo "\n<TR>".formTag("Email Address")."<TD><INPUT name=email id=email></TD></TR>";
		echo "\n<TR>".formTag("Country")."<TD>".DBformSelect($db,"country","select * from country order by englishname","inet_code","name")."</TD></TR>";
		echo "\n<TR>".formTag("State")."<TD><INPUT name=state id=state></TD></TR>";
		echo "\n<TR>".formTag("City")."<TD><INPUT name=city id=city></TD></TR>";
		echo "\n<TR>".formTag("Employer")."<TD><INPUT name=employer id=employer></TD></TR>";
		echo "\n<TR>".formTag("Division")."<TD><INPUT name=division id=division></TD></TR>";
		
		echo "\n<TR>".formTag("Biometrics File")."<TD><INPUT type=file name=biofile value='".UPLOAD."' id=biofile></TD></TR>";
		
		echo "\n<TR>".formTag("Key size")."<TD><KEYGEN NAME=\"SPKAC\" CHALLENGE=\"challengePassword\" id=keygen></TD><TD>For the Authentrus Smart Card, choose 1024</TD></TR>";
		echo "\n<TR>".formTag("Signing Certificate")."<TD>".DBformSelect($db,"signerid","select * from signer where (officerid=$surferid or signerid=0) order by signerid","signerid","common_name")."</TD></TR>";
		echo "\n<TR><TD></TD><TD><INPUT type=submit name=command value='".ENROLL."'></TD></TR>";

		echo "\n</TABLE>";
		echo "</FORM>";
		break;
	case "done":
		echo "We did it.";
		break;
	case "newsigner":
		echo "<FORM method=post action='https://$self'>";
		echo "\n<TABLE>";
		echo "\n<TR>".formTag("Common Name")."<TD><INPUT name='common_name' id='common_name'></TD></TR>";
		echo "\n<TR>".formTag("Certificate")."<TD><TEXTAREA name='certificate' id='certificate'></TEXTAREA></TD><TD>The actual certificate</TD></TR>";
		echo "\n<TR>".formTag("Private Key")."<TD><TEXTAREA name='private_key' id='private_key'></TEXTAREA></TD></TR>";
		echo "\n<TR>".formTag("Password")."<TD><INPUT name='password' id='password'></TD></TR>";
		echo "\n<TR>".formTag("Valid Period")."<TD><INPUT name='days' id='days'></TD><TD>Number of days until a new certificate expires</TD></TR>";
		echo "\n<TR>".formTag("Starting Serial Number")."<TD><INPUT name='serialstart' id='serialstart'></TD><TD>The first serial number we should use for this certificate.</TD></TR>";
		echo "\n<TR>".formTag("Serial Number Increment")."<TD><INPUT name='increment' id='increment'></TD><TD>Should we stripe the serial number generation?</TD></TR>";
		echo "\n<TR><TD></TD><TD><INPUT type=submit name=command value='".NEWSIGNER."'></TD></TR>";
		echo "\n</TABLE></FORM>";
		break;
	default:
		echo "<H2>Welcome ".make_name($surfer)."</H2>";
		echo "What would you like to do, today?";
		echo "<BR>Just click the appropriate menu item above or below.";
		loggywoggy("We did not process the display $display.");
}
}
else	##No requested display
{
	echo page_top($site_name);
	if (strlen($errors) > 0) echo "<FONT color=red size=+3>$errors</FONT>";
	if (strlen($msgs) > 0) echo "$msgs";
	echo "<H2>$site_name for $name</H2>";
	#if (isset($_POST)) echo "<BR>The variables posted are:<PRE>".print_r($_POST,TRUE)."</PRE>";
	#if (isset($_FILES)) echo "<BR>The files uploaded are:<PRE>".print_r($_FILES,TRUE)."</PRE>";
	$signers=$db->query("select * from signer where officerid=$surferid");
	if (($n=$signers->numRows()) > 0)
	{
		echo "\n<BR>You have ".if_s($n>1,"these certificates","this certificate").":<UL>";
		while ($row=$signers->fetchRow())
		{
			$signerid=$row["signerid"];
			echo "\n<LI><A href=https://$self?display=viewsigner&id=$signerid>$signerid-".$row["common_name"]."</A></LI>";
		}
		echo "\n</UL>";
	}
	unset($signers);
	$subjects=$db->query("select * from subject where officerid=$surferid");
	if (($n=nrows($subjects)) > 0)
	{
		if ($n>TOOMANYTOLIST)
		{
			echo "<BR>You have enrolled $n subjects so far.";
		}
		else
		{
			echo "\n<BR>You have enrolled ".if_s($n>1,"these subjects","this subject").":<UL>";
			while ($row=$subjects->fetchRow())
			{
				$subjectid=$row["subjectid"];
				echo "\n<LI><A href=https://$self?display=viewsubject&id=$subjectid>$subjectid-".make_name($row)."</A></LI>";
			}
			echo "\n</UL>";
		}
	}
	$certs=$db->query("select * from certificate where officerid=$surferid");
	if (($n=nrows($certs)) > 0)
	{
		if ($n>TOOMANYTOLIST)
		{
			echo "<BR>You have authorized $n certificates so far.";
		}
		else
		{
			echo "\n<BR>You have authorized ".if_s($n>1,"these certificates","this certificate").":<UL>";
			while ($row=$certs->fetchRow())
			{
				$certid=$row["certificateid"];
				echo "\n<LI><A href=https://$self?display=viewcert&id=$certid>$certid-".make_name($row)."</A></LI>";
			}
			echo "\n</UL>";
		}
	}
	echo "";
}
#echo phpinfo();
?>