I'm trying to create a simple PKI infrastucture for internal use, and I want to use the html <keygen>
tag.
I know this tag sends an SPKAK to server, wich will have to sign it. Since I can't use exec
to launch openssl, and have php 5.5, the only way to process SPKAK is with phpseclib.
This is my code:
<?PHP
if(isset($_POST['key'])){
header('Content-type: application/x-x509-user-cert');
header('Content-disposition: attachment; filename=user.crt');
include('File/X509.php');
$capem = file_get_contents('root-ca.crt');
$subject = new File_X509();
$subject->loadCA($capem);
$subject->loadSPKAC($_POST['key']);
$subject->setDN('CN=Username');
$issuer = new File_X509();
$issuer->loadX509($capem);
$cakey = new Crypt_RSA();
$cakey->setPassword('SECRETPASSWORD');
$cakey->loadKey(file_get_contents('root-ca.key'));
$issuer->setPrivateKey($cakey);
$x509 = new File_X509();
$cert = $x509->sign($issuer, $subject);
$x509->loadX509($cert);
$x509->setExtension('id-ce-keyUsage', array('digitalSignature', 'keyEncipherment'));
$x509->setStartDate('-1 day');
$x509->setEndDate('+ 3 year');
$x509->setSerialNumber('1235', 10);
$cert = $x509->sign($issuer, $x509);
echo $x509->saveX509($cert);
}else{
?>
<form method="POST">
<keygen name="key" keytype="RSA" challenge="ucert">
<button>SEND</button>
</form>
<?PHP
}
?>
The strange thing is that the generated certificate is valid (windows recognises it) but the browser (both Chrome and Firefox in my testings) doesn't recognise it, giving error 201 INVALID CERT, so it's not associated with the private key stored on browser.
What's the correct way to do this?
I was able to import the resultant file.pfx file into Google Chrome. It shows up now as a "Personal Certificate".