diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 84d1d773..a62fec9f 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -218,8 +218,10 @@ define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2); define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 3); /** * PKCS#1 formatted public key + * + * Used by X.509 certificates */ -define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 4); +define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW', 4); /** * XML formatted public key */ @@ -230,6 +232,12 @@ define('CRYPT_RSA_PUBLIC_FORMAT_XML', 5); * Place in $HOME/.ssh/authorized_keys */ define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 6); +/** + * PKCS#1 formatted public key (encapsulated) + * + * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set) + */ +define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 7); /**#@-*/ /** @@ -833,7 +841,7 @@ class Crypt_RSA { $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . CRYPT_RSA_COMMENT; return $RSAPublicKey; - default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1 + default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW or CRYPT_RSA_PUBLIC_FORMAT_PKCS1 // from : // RSAPublicKey ::= SEQUENCE { // modulus INTEGER, -- n @@ -849,16 +857,18 @@ class Crypt_RSA { $components['modulus'], $components['publicExponent'] ); - $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA - $RSAPublicKey = chr(0) . $RSAPublicKey; - $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey; + if ($this->publicKeyFormat == CRYPT_RSA_PUBLIC_FORMAT_PKCS1) { + $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $RSAPublicKey = chr(0) . $RSAPublicKey; + $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey; - $encapsulated = pack('Ca*a*', - CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey - ); + $RSAPublicKey = pack('Ca*a*', + CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey + ); + } $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($encapsulated)) . + chunk_split(base64_encode($RSAPublicKey)) . '-----END PUBLIC KEY-----'; return $RSAPublicKey; diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 47729b83..8fb931e5 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1279,10 +1279,12 @@ class File_X509 { return false; } - switch ($cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm']) { - case 'rsaEncryption': - $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = - base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); + if (is_array($cert['tbsCertificate']['subjectPublicKeyInfo'])) { + switch ($cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm']) { + case 'rsaEncryption': + $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = + base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); + } } $asn1 = new File_ASN1(); @@ -2614,9 +2616,12 @@ class File_X509 { switch (strtolower(get_class($this->publicKey))) { case 'crypt_rsa': + // the following two return statements do the same thing. i dunno.. i just prefer the later for some reason. + // the former is a good example of how to do fuzzing on the public key + //return new File_ASN1_Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey()))); return array( 'algorithm' => array('algorithm' => 'rsaEncryption'), - 'subjectPublicKey' => $this->publicKey->getPublicKey() + 'subjectPublicKey' => $this->publicKey->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW) ); default: return false;