<?PHP
	#.htmaff.inc.php
	#This is a set of routines for generating certificates.
	#Their general form will be osbrfunction() where os and br are the operating system and browser
	#which the surfer is using as returned by the osbr function in .htclient.inc.php.
	
	#These functions are probably best used in this wise:
	#	Determin eligibility of applicant(surfer)
	#	Display the certificate request page with
	#		osbrcertform to start the form
	#		other data like DN parts, things are easier later on if the input names match the distinguished name parts.
	#		osbrcertkeysize to place the key generator and get the SPKAC item back
	#		osbrcertsubmit to place the submit button at the bottom of the form
	#		echo </form>
	#	The other data above can be things like the distinguished name of the subject.  For each input tag
	#	the name should be the same as is expected for distinguished names as that is used later to construct
	#	the request file.
	#	More on each of the functions is below with the functions.
	
	#define constants for the openssl stuff.  Apparently, none of this is in opensslwrap.
	if (!defined("OPENSSLDIR")) define ("OPENSSLDIR","/usr/bin");	#Location of openssl binary
	if (!defined("CERTSDIR")) define ("CERTSDIR","/home/phadley/websites/certs/1");	#directory for certificates and probably req files, serial number file, error file, and other neat stuff.
	if (!defined("CNFFILE")) define ("CNFFILE",CERTSDIR."/config.cnf");	#the configuration file which could also be written specifically for each certificate with the osbrconfig function (far from complete and beautiful)
	if (!defined("CAFILE")) define ("CAFILE",CERTSDIR."/root.pem");	#Location of the signing certificate and I know that Wes doesn't want us to talk that way.
	if (!defined("KEYFILE")) define ("KEYFILE",CERTSDIR."/rootkey.pem");	#?Location of the key to the rootl
	if (!defined("CAPASSWORD")) define("CAPASSWORD","1273!Main");			#The actul passwot
	if (!defined("REQPARTS")) define ("REQPARTS","commonName,emailAddress,organizationName,organizationalUnitName,localityName,stateOrProvinceName,countryName");
	
	#osbrcertform returns HTML for the start of a form which generates the key pair and sends it in.
	#It outputs a <form> tag.  If you give no argumetns to the function it uses these defaults:
	#	action=. so it comes back to index.php in the same folder/directory
	#	Command ($cmd) = makecert so that the switch statement goes to making a certificte
	#	method=post
	#	name=genRecForm in case you need a name.  I forget where genRecForm comes from.
	#	id = keygen which is used if you want to use automatic submission (means the user doesn't even have to click)
	
	if (!function_exists("osbrcertform"))
	{
		function osbrcertform($action=".",$command="makecert",$method="post",$name="genRecForm",$id="keygen")
		{
			$a="<form action=\"$action\" method=\"$method\" name=\"$name\" id=\"$id\">";
			$a.="\n<input type=hidden name=\"cmd\" value=\"$command\">";
			return $a;
		}	#end of osbrcertform
	}
	
	################################################################################################
	if (!function_exists("osbrcertheader"))
	{
		function osbrcertheader()
		{
			return "";
		}	#end of osbrcertheader
	}

	
	#osbrcertkeysize returns HTML for the submit button (KEYGEN for FF)
	#It outputs a <keygen> tag which Firefox (and only Firefox?) uses to ask for a key pair (legacy of Netscape)
	#keygen also displays a dropdown with which the user can choose the size of the private key.
	#I have it default to SPKAC because that makes the construction of the request file easier.
	#I suspect that the challenge is how the certificate finds its private key.  I'm not sure.
	if (!function_exists ("osbrcertkeysize"))
	{
		function osbrcertkeysize($name="SPKAC",$challenge="challengePassword")
		{
			$a="<KEYGEN NAME=\"$name\" CHALLENGE=\"$challenge\">";
			return $a;
		}	#end of osbrcertkeysize
	}
	
	#osbrcertsubmit returns HTML for the submit button
	#It outputs the submit button.  I suppose that this could be done quite easily by an echo command but there it is.
	if (!function_exists ("osbrcertsubmit"))
	{
		function osbrcertsubmit($name="command",$value="Request a Certificate")
		{
			$a="<input type=submit name=\"$name\" value=\"$value\">";
			return $a;
		}	#end of osbrcertsubmit
	}
	
	$certsdir="/home/phadley/websites/certs/1";
	$req_file = "$certsdir/$count.req"; # certificate request filename
	
	#osbrmakereqfile makes the request out of the SPKAC and name parts
	#This constructs the request file used in making the certificate.  It looks like it's name parts and the SPKAC.
	#$parts is a comma separated string of name parts.  If these are the same as the part names openssl recognizes
	#and the same as the input item name from the form, they find their way into the file by themselves.
	#You can limit what goes into the DN on the certificate by limiting this list.
	#As yet I have no idea what happens if you use a noncanonical name and I'm not sure what should be
	#the name for first, middle, surname, and all those other real name parts.
	if (!function_exists("osbrmakereqfile"))
	{
		function osbrmakereqfile($filename,$parts=REQPARTS)
		{
			$a="";
			$partses=explode(",",$parts);
			foreach ($partses as $key)
			{
				$value=fromREQUESt($key);
				if (!is_null($value) && (strlen($value) > 0)) $a.="$key	=	$value\n";
			}
			$a.="SPKAC	=	".str_replace("\r\n","",fromREQUEST("SPKAC"))."\n";
			return file_put_contents($filename,$a);
		}
	}
	
	#osbrmakecert actualy generates a certificate by assembling a command line and then executing it.
	#It constructs an openssl command line and then executes it.
	if (!function_exists("osbrmakecert"))
	{
		function osbrmakecert($count=4,$CAFILE=CAFILE,$KEYFILE=CAKEYFILE,$certs_dir=CERTSDIR,$days=731,$CApassword=CAPASSWORD)
		{
			$openssldir=OPENSSLDIR;
			#$os="ma";$br="ff";$osbr="osbr";
			
			if (defined("CNFFILE"))
				$cnffile=CNFFILE;
			else
				$cnffile=$certs_dir."/$count.cnf";
			
			$email=fromREQUEST("email");
			if (is_null($email)) $email="unknown  $count";
			
			/*
			 #	header("Content-Length: ".strlen($cert));
			 #	header("Location: $PHP_SELF?command=info");
			 */
			
			$CA="$openssldir/openssl ca";
			$CRL2PKCS7 = "$openssldir/openssl crl2pkcs7";
			$ERRORFILE = "$certs_dir/errors";
			###$srlfile="$certs_dir/$count.srl";
			$srlfile="$certs_dir/serial";
			#$cnffile="$certs_dir/$count.cnf";
			$cnffile="$certs_dir/config.cnf";
			$crlfile="$certs_dir/crl.pem";
			$req_file = "$certs_dir/$count.req"; # certificate request filename
			$result_file = "$certs_dir/$count.result"; # certificate filename	?????
			$pkcs7_file = "$certs_dir/$count.pkcs";								#????
			###$dbfile="$certs_dir/$count.txt";
			
			file_put_contents($srlfile,dechex($count));
			###shell_exec("touch $dbfile");
			#	config should be a static file and I think I've achieved that with config.cnf and that
			#	makes the function for creating a config file superfluous.
			#osbrconfig($cnffile,$count,$certs_dir,$email);
			
			$CRL = "$certs_dir/crl.pem";
			##$CACERT = "-cert $CAFILE";
			##$CAKEY = "-key $CApassword";
			##$part="makecert";
			
			##$req=file_get_contents($req_file);
			$cmd="$CA -batch -config $cnffile -extensions certificate_extensions "
			."-cert $CAFILE "
			."-key $CApassword "
			."-verbose -spkac $req_file -days $days "
			."2>>$ERRORFILE";
			$cert = shell_exec ($cmd);
			return $count;
			#header("Content-Type: application/x-x509-user-cert");
			#echo $cert;
		}
	}
	
	#This picks up the certificate and sends it out with a proper header
	if (!function_exists('osbrcertsend'))
	{
		function osbrcertsend($serial)
		{
			header("Content-Type: application/x-x509-user-cert");
			$fred=sprintf("%08X",$serial);
			while (substr($fred,0,2) == "00") $fred=substr($fred,2);
			$filename=CERTSDIR."/$fred.pem";
			$n=readfile($filename);
			if ($n > 0)
				return true;
			else
				return false;
		}
	}
	
	if (!function_exists('osbrautocertsend'))
	{
		function osbrautocertsend($serial,$osbr="maff",$formid="grabit")
		{
			$a="<form action=. method=post id=\"$formid\">";
			$a.="<input type=hidden name=cmd value=certsend>";
			$a.="<input type=hidden name=id value=$serial";
			$a.="<input type=hidden name=osbr value=$osbr>";
			$a.="</form>";
			$a.="\n<script type=text/javascript>";
			$a.="\nvar keygen=document.getElementById(\"$formid\");";
			$a.="\nkeygen.submit();";
			$a.="\n</script>";
			return $a;
		}
	}
	
	#This goes up after certsubmit but is down here to make indentation work properly.
	#osbrcertautosubmit will submit the certificate request without the user clicking anything.
	if (!function_exists("osbrcertautosubmit"))
	{
		function osbrcertautosubmit($id="keygen")
		{
			$a="<script type=text/javascript>
			var keygen=document.getElementById(\"$id\");
											   keygen.submit();
											   </script>";
											   return $a;
											   }
											   }
											   
	?>