RSA: more verbose RSA key handling

This commit is contained in:
terrafrost 2013-12-24 18:37:43 -06:00
parent 4bd9a546ab
commit 3a0193875a

View File

@ -992,8 +992,9 @@ class Crypt_RSA
$iv = pack('H*', trim($matches[2])); $iv = pack('H*', trim($matches[2]));
$symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
$symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8))); $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8)));
$ciphertext = preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-| #s', '', $key); // remove the Proc-Type / DEK-Info sections as they're no longer needed
$ciphertext = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false; $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
$ciphertext = $this->_extractBER($key);
if ($ciphertext === false) { if ($ciphertext === false) {
$ciphertext = $key; $ciphertext = $key;
} }
@ -1037,8 +1038,7 @@ class Crypt_RSA
$crypto->setIV($iv); $crypto->setIV($iv);
$decoded = $crypto->decrypt($ciphertext); $decoded = $crypto->decrypt($ciphertext);
} else { } else {
$decoded = preg_replace('#-.+-|[\r\n]| #', '', $key); $decoded = $this->_extractBER($key);
$decoded = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $decoded) ? base64_decode($decoded) : false;
} }
if ($decoded !== false) { if ($decoded !== false) {
@ -2781,4 +2781,31 @@ class Crypt_RSA
return $this->_rsassa_pss_verify($message, $signature); return $this->_rsassa_pss_verify($message, $signature);
} }
} }
/**
* Extract raw BER from Base64 encoding
*
* @access private
* @param String $str
* @return String
*/
function _extractBER($str)
{
/*
X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them above and beyond the ceritificate. ie.
some may have the following preceding the -----BEGIN CERTIFICATE----- line:
Bag Attributes
localKeyID: 01 00 00 00
subject=/O=organization/OU=org unit/CN=common name
issuer=/O=organization/CN=common name
*/
$temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
$temp = preg_replace('#-+[^-]+-+#', '', $temp);
// remove new lines
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
return $temp != false ? $temp : $str;
}
} }