<?PHP
	#wiie.inc.php-The things that IE on Windows will understand as a certificate request
	#Things which should change in osbr file:
	#		osbrcertform--$action default should change . --> .$_SERVER["PHP_SELF"]
	#		osbrcertheader--should be added but do nothing
	
	#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");
	
	if (!defined("ALLSITES")) define ("ALLSITES","/var/www/sites/allsites");
	include_once(ALLSITES."/.htreportingerrors.inc.php");
	
define("USINGMAFF",false);	#Switch to straighten out some things before checking it out on a Windows machine.
	
	##############################################################################################
	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\" onSubmit='GenReq(this)'>";
			$a.="\n<input type=hidden name=\"cmd\" value=\"$command\">";
			$a.="\n<INPUT type=hidden name='sessionid'>";
			$a.="\n<INPUT type=hidden name='reqEntry'>";
			return $a;
		}	#	end of osbrcertform
	}
	
	##############################################################################################
	if (!function_exists("osbrcertheader"))
	{
		function osbrcertheader()
		{
			$a=<<<ENDHEADER
			
<OBJECT classid="clsid:127698E4-E730-4E5C-A2b1-21490A70C8A1"
codebase="xenroll.dll"
id=Enroll >
</OBJECT>
<OBJECT classid="clsid:98AFF3F0-5524-11D0-8812-00A0C903B83C"
codebase="certcli.dll"
id=Request >
</OBJECT>
<SCRIPT LANGUAGE="JavaScript">
<!---

// this is from JavaScript: The Definitive Guide, since
// Microsoft implementation of Math.random() is broken
//
function random() {
	random.seed = (random.seed*random.a + random.c) % random.m;
	return random.seed/random.m;
}
random.m = 714025; random.a = 4096; random.c = 150889;
random.seed = (new Date()).getTime()%random.m;

function GenReq (formid)
{
	var sessionid               = "a_unique_session_id";
	var reqHardware             = 0;
	var szName                  = "";
	var szPurpose               = "ClientAuth";
	var doOnline                = 1;
	var keySpec = 1;
	var comma = "";
	
	alert("We are in GenReq.");
	
	szName = "";
	var reqForm=formid;
	
	if (reqForm.commonName.value == "")
		reqForm.commonName.value=reqForm.first.value+" "+reqForm.surname.value;
	
	szName = szName + comma+"CN=" + reqForm.commonName.value;
	comma=";";
	
	alert ("Your distinguished name is " + szName);
	
	
	
	if (reqForm.countryName.value != "")
	{
		szName = szName + comma+"C=" + reqForm.countryName.value;
		comma=";";
		
		alert ("Your distinguished name is " + szName);
		
	}
	
	if (reqForm.stateOrProvinceName.value != "")
	{
		szName = szName + comma+"S=" + reqForm.stateOrProvinceName.value;
		comma=";";
	}
	
	if (reqForm.localityName.value != "")
	{
		szName = szName + comma+"L=" + reqForm.localityName.value;
		comma=";";
	}
	
	if (reqForm.organizationName.value != "")
	{
		szName = szName + comma+ "O=" + reqForm.organizationName.value;
		comma=";";
	}
	
	if (reqForm.organizationalUnitName.value != "")
	{
		szName = szName + comma+"OU=" + reqForm.organizationalUnitName.value;
		comma=";";
		alert ("Your distinguished name is " + szName);
	}
	
	alert ("Your distinguished name is " + szName);
	
	/* make session id unique */
	sessionid = "xx" + Math.round(random() * 1000);
	
	alert ("Your session id is " + sessionid );
ENDHEADER;
if (USINGMAFF)
	$a.="sz10=23\n;";
else
	$a.="sz10 = Enroll.createPKCS10( szName, \"1.3.6.1.4.1.311.2.1.21\");";
	$a.=<<< ENDHEADER
	alert ("Your session ID is " + sessionid);
	
    /*
     *
     * The condition sz10 being empty occurs on any condition in which the
     * credential was not successfully generated. In particular, it occurs
     * when the operation was cancelled by the user, as well as additional
     * errors. A cancel is distinguished from other unsuccessful
     * generations by an empty sz10 and an error value of zero.
     *
     */
	
	if (sz10 != "")
	{
		reqForm.reqEntry.value = sz10;
		reqForm.sessionid.value = sessionid;
	}
	else
	{
		alert("Somehow, Internet Explorer was unable to generate a key pair and certificate request.  You might try again or change some name parts in the form but we can't really help you with an internal problem.");
		return false;
	}

}
</SCRIPT>
ENDHEADER;
			$a.="\n";
			return $a;
}	##	end of osbrcertheader
}

if (!function_exists("osbrcertkeysize"))
{
	function osbrcertkeysize()
	{
		return;
	}
}
	
	##############################################################################################
#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;
	}
}
	
	##############################################################################################
#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)
	{
		$req=fromREQUEST("reqEntry");
		if (strlen($req) == 0)
		{
			die("Your browser did not send a certificate request.");
		}
		$a="-----BEGIN CERTIFICATE REQUEST-----\n";
		$a.=$req;
		$a.="-----END CERTIFICATE REQUEST-----\n";
		return file_put_contents($filename,$a);
	}
}
	
	##############################################################################################
#osbrmakecert
if (!function_exists("osbrmakecert"))
{
	function osbrmakecert($count=4,$CAFILE=CAFILE,$KEYFILE=CAKEYFILE,$certs_dir=CERTSDIR,$days=731,$CApassword=CAPASSWORD)
	{
		$CA=OPENSSLDIR." openssl ca";
		$CRL2PKCS7=OPENSSLDIR." openssl crl2pkcs7";
		
		if (defined("CNFFILE"))
			$cnffile=CNFFILE;
		else
			$cnffile=$certs_dir."/$count.cnf";
		$req_file = "$certs_dir/$count.req"; # certificate request filename
		$result_file = "$certs_dir/$count.result"; # certificate filename	?????
		$ERRORFILE = "$certs_dir/errors";
		$pkcs7_file = "$certs_dir/$count.pkcs";								#????

		certprogress("About to make certificate $count (".UDECHEX($count).").",$ERRORFILE,__LINE__,__FILE__);
	$cmd = "$CA -batch -config $cnffile -extensions certificate_extensions "
	."-cert $CAFILE -key $CApassword -in $req_file -out $result_file -days $days 2>>$ERRORFILE";
	$crcmd = "$CRL2PKCS7 -cert $CAFILE -certfile $result_file "
	."-in $crlfile -out $pkcs7_file 2>>$ERRORFILE";
	
	system ($cmd,$rc);
	if ($rc != 0)
	{
		loggywoggy("Failure to make certificate with command\n$cmd.");
		die("Our certificate making process failed us.  We are sorry.  Try again?");
		die("Return code was $rc from our first command<BR>$cmd");
	}
		system ($crcmd,$rc);
		return $count;
	}		##end of osbrmakecert
}
	
	
##############################################################################################
	#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="wiie",$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.="</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=<<<ENDSCRIPT
			<script type=text/javascript>
			var keygen=document.getElementById("$id");
			keygen.submit();
			</script>;
ENDSCRIPT;
			return $a;
		}
	}
?>