Now here we are going to write some stuff and it is going to be about the what it is like supporting PHP.
// this function makes up for the fact that openssl doesn't
// currently support direct use of modulus and exponent except
// when PEM encoded in publicKeyInfo or Certificate ASN.1
// So, believe it or not, I convert it into a publicKeyInfo ASN
// structure and then turn it into PEM - then it works fine.
function kimssl_pkey_get_public ($modulus, $exponent)
{
// decode to binary
$modulus = base64_decode($modulus);
$exponent = base64_decode($exponent);
// make an ASN publicKeyInfo
$exponentEncoding = makeAsnSegment(0x02, $exponent);
$modulusEncoding = makeAsnSegment(0x02, $modulus);
$sequenceEncoding = makeAsnSegment(0x30,
$modulusEncoding.$exponentEncoding);
$bitstringEncoding = makeAsnSegment(0x03, $sequenceEncoding);
$rsaAlgorithmIdentifier = pack("H*", "300D06092A864886F70D0101010500");
$publicKeyInfo = makeAsnSegment (0x30,
$rsaAlgorithmIdentifier.$bitstringEncoding);
// encode the publicKeyInfo in base64 and add PEM brackets
$publicKeyInfoBase64 = base64_encode($publicKeyInfo);
$encoding = "-----BEGIN PUBLIC KEY-----\n";
$offset = 0;
while ($segment=substr($publicKeyInfoBase64, $offset, 64)){
$encoding = $encoding.$segment."\n";
$offset += 64;
}
$encoding = $encoding."-----END PUBLIC KEY-----\n";
// use the PEM version of the key to get a key handle
$publicKey = openssl_pkey_get_public ($encoding);
return ($publicKey);
}
// this helper function is necessary because PHP's openssl
// currently requires that the public key be in PEM format
// This does the ASN.1 type and length encoding
function makeAsnSegment($type, $string)
{
// fix up integers and bitstrings
switch ($type){
case 0x02:
if (ord($string) > 0x7f)
$string = chr(0).$string;
break;
case 0x03:
$string = chr(0).$string;
break;
}
$length = strlen($string);
if ($length < 128){
$output = sprintf("%c%c%s", $type, $length, $string);
}
else if ($length < 0x0100){
$output = sprintf("%c%c%c%s", $type, 0x81, $length, $string);
}
else if ($length < 0x010000) {
$output = sprintf("%c%c%c%c%s", $type, 0x82, $length/0x0100, $length%0x0100, $string);
}
else {
$output = NULL;
}
return($output);
}
Truth is stranger than fiction.
