<?php
$csr ='-----BEGIN CERTIFICATE REQUEST-----
MIICaDCCAVACAQAwIzELMAkGA1UEBhMCVVMxFDASBgNVBAMTC2V4YW1wbGUuY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp3oXxBdyjls2NgWPVxCl
ufJLBZ6IYryLpa3DakG1MSXMhnyZa/R/dKEBk5W5PrfctLRZPP8ijNWHdUSTnBne
CEKy/YjrcWuLIUoGZpxtKxC79eh8ojquUYZROtGWApPx3jpoBm02IEG0CdjtdF7/
rromhKxNajBqtAHsOqD5XAhcbF4f8hEsEaE9RBd5MwqXoE64w4HkWNcQs1BDr55L
uQXnXdp4sYXENqfVsoJ6GqtMbJihtWwamQQYK42ALxEjHUFTehU5K4Qjvy2wMlp9
DdA/rNNmnJ+i30BLDZyY5GREt1gdVHUHR7kD5VcQ0xqshcbxGRzfpjMSJQvumvty
kwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAEisLgiTlezDEquIMx9/N8Nam2qa
s+o1yvAdQEfwMY/zNrQ9Xe50SP4bQ0t415fV1XePulHbNXXEidy2SYZOTELnAePL
ctqblNHtt1m+9utEaFTlEAy/ep9IGIby8oTKoTtIvtFKQCISe8BCpaDOD0MXROLP
6CcdcdWS2N69gsIR8nOMw6teoWR4r6YQGbHtsvtMu2Yg/ho0r0OfTU5tovDQ3zOT
5afV3C9H41Yx/VDSLoMv0rL7qH3OSh+hFPxFksochTrnMuSoE/5Umu4lAibTteGW
CPPINlnv9UYcYuZY6tSGqD/tknfX69OSoZGOLBxOwhKwyYs7F5kyA+Oepd0=
-----END CERTIFICATE REQUEST-----
';
$verified = ASN1Simple::verifySig($csr,$alg=OPENSSL_ALGO_SHA256);
echo $verified ? 'verified' : 'notverified';
echo "\n";
class ASN1Simple
{
public function verifySig($csr,$alg)
{
$str = $csr;
$str = preg_replace('/\-+BEGIN [A-Z_ ]+\-+/','',$str);
$str = preg_replace('/\-+END[A-Z_ ]+\-+/','',$str);
$str = preg_replace('/[^A-Za-z0-9=+\/]/m','',$str);//strip off non base64
$bytes = base64_decode($str);
$pos=0;
//parent node
list($startpos,$cstart,$endpos) = self::readNode($bytes,$pos);
$pos = $cstart;//move to children
{//read signed body
list($startpos,$cstart,$endpos) = self::readNode($bytes,$pos);
$data = substr($bytes, $startpos,$endpos-$startpos);
$pos = $endpos;//move to next sibling node
}
{//skip signature algorthing info
list($startpos,$cstart,$endpos) = self::readNode($bytes,$pos);
$pos = $endpos;//move to next sibling node
}
{//read signature
list($startpos,$cstart,$endpos) = self::readNode($bytes,$pos);
$sig = substr($bytes, $cstart,$endpos-$cstart);
$sig = $sig[0]=="\x0" ? substr($sig,1) : $sig;
}
$pkey_resource = openssl_csr_get_public_key($csr);
return openssl_verify($data,$sig,$pkey_resource,$alg) ? true : false;
}
public function readNode(&$bytes,&$pos)
{
$startpos = $pos;
$tag = self::readByte($bytes,$pos);
$clength = self::readLength($bytes,$pos);
$cstart = $pos;
$end = $cstart + $clength;
return array($startpos,$cstart,$end);
}
public function readByte($bytes,&$pos)
{
$byte = isset($bytes[$pos]) ? $bytes[$pos] : null;
$pos++;
return ord($byte);
}
public function readLength($bytes,&$pos)
{
$buf = self::readByte($bytes, $pos);
$len = $buf & 0x7F;
if ($len == $buf)
return $len;
if ($len > 3)
throw new Exception("Length over 24 bits not supported");
if ($len == 0)
return -1; // undefined
$buf = 0;
for ($i = 0; $i < $len; ++$i)
$buf = ($buf << 8) | self::readByte($bytes, $pos);
return $buf;
}
}
?>