From 0a5e26a648d187c1568fa2bcee0ffff134000489 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 12 Jun 2014 22:03:00 -0500 Subject: [PATCH 1/9] RSA: add support for saving to PKCS8 (unencrypted) --- phpseclib/Crypt/RSA.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 82ec4c35..8d96c132 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -191,6 +191,10 @@ define('CRYPT_RSA_PRIVATE_FORMAT_PUTTY', 1); * XML formatted private key */ define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2); +/** + * PKCS#8 formatted private key + */ +define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 3); /**#@-*/ /**#@+ @@ -846,6 +850,17 @@ class Crypt_RSA $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + if ($this->privateKeyFormat == CRYPT_RSA_PRIVATE_FORMAT_PKCS8) { + $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $RSAPrivateKey = pack('Ca*a*Ca*a*', + CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($RSAPrivateKey), 64) . + '-----END PRIVATE KEY-----'; + return $RSAPrivateKey; + } + if (!empty($this->password) || is_string($this->password)) { $iv = crypt_random_string(8); $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key @@ -993,6 +1008,7 @@ class Crypt_RSA } return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false; case CRYPT_RSA_PRIVATE_FORMAT_PKCS1: + case CRYPT_RSA_PRIVATE_FORMAT_PKCS8: case CRYPT_RSA_PUBLIC_FORMAT_PKCS1: /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to @@ -1083,7 +1099,9 @@ class Crypt_RSA 7:d=1 hl=2 l= 13 cons: SEQUENCE 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption 20:d=2 hl=2 l= 0 prim: NULL - 22:d=1 hl=4 l= 609 prim: OCTET STRING */ + 22:d=1 hl=4 l= 609 prim: OCTET STRING + + ie. PKCS8 keys*/ if ($tag == CRYPT_RSA_ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") { $this->_string_shift($key, 3); From 21c6a15df37b852e711f4179f000c5f8fc10e109 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 13 Jun 2014 08:54:30 -0500 Subject: [PATCH 2/9] Crypt/Base: add support for pbkdf1 --- phpseclib/Crypt/Base.php | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 83f46e3e..198c5424 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -541,7 +541,7 @@ class Crypt_Base * Sets the password. * * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: - * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}: + * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: * $hash, $salt, $count, $dkLen * * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php @@ -551,6 +551,7 @@ class Crypt_Base * @see Crypt/Hash.php * @param String $password * @param optional String $method + * @return Boolean * @access public */ function setPassword($password, $method = 'pbkdf2') @@ -558,7 +559,7 @@ class Crypt_Base $key = ''; switch ($method) { - default: // 'pbkdf2' + default: // 'pbkdf2' or 'pbkdf1' $func_args = func_get_args(); // Hash function @@ -574,8 +575,28 @@ class Crypt_Base // Keylength $dkLen = isset($func_args[5]) ? $func_args[5] : $this->password_key_size; - // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable switch (true) { + case $method == 'pbkdf1': + if (!class_exists('Crypt_Hash')) { + include_once 'Crypt/Hash.php'; + } + $hashObj = new Crypt_Hash(); + $hashObj->setHash($hash); + if ($dkLen > $hashObj->getLength()) { + user_error('Derived key too long'); + return false; + } + $t = $password . $salt; + for ($i = 0; $i < $count; ++$i) { + $t = $hashObj->hash($t); + } + $key = substr($t, 0, $dkLen); + + $this->setKey(substr($key, 0, $dkLen >> 1)); + $this->setIV(substr($key, $dkLen >> 1)); + + return true; + // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable case !function_exists('hash_pbkdf2'): case !function_exists('hash_algos'): case !in_array($hash, hash_algos()): @@ -602,6 +623,8 @@ class Crypt_Base } $this->setKey($key); + + return true; } /** From abae026264b983267cd82be9b90c818ef85ebea8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 13 Jun 2014 08:56:00 -0500 Subject: [PATCH 3/9] RSA: add support for loading PKCS8 encrypted private keys --- phpseclib/Crypt/RSA.php | 51 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 8d96c132..48378dec 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -145,6 +145,10 @@ define('CRYPT_RSA_ASN1_INTEGER', 2); * ASN1 Bit String */ define('CRYPT_RSA_ASN1_BITSTRING', 3); +/** + * ASN1 Object Identifier + */ +define('CRYPT_RSA_ASN1_OBJECT', 6); /** * ASN1 Sequence (with the constucted bit set) */ @@ -1109,6 +1113,52 @@ class Crypt_RSA } if ($tag == CRYPT_RSA_ASN1_SEQUENCE) { + $temp = $this->_string_shift($key, $this->_decodeLength($key)); + if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_OBJECT) { + return false; + } + $length = $this->_decodeLength($temp); + switch ($this->_string_shift($temp, $length)) { + case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption + break; + case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC + /* + PBEParameter ::= SEQUENCE { + salt OCTET STRING (SIZE(8)), + iterationCount INTEGER } + */ + if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_SEQUENCE) { + return false; + } + if ($this->_decodeLength($temp) != strlen($temp)) { + return false; + } + $this->_string_shift($temp); // assume it's an octet string + $salt = $this->_string_shift($temp, $this->_decodeLength($temp)); + if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_INTEGER) { + return false; + } + $this->_decodeLength($temp); + list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT)); + $this->_string_shift($key); // assume it's an octet string + $length = $this->_decodeLength($key); + if (strlen($key) != $length) { + return false; + } + + if (!class_exists('Crypt_DES')) { + include_once 'Crypt/DES.php'; + } + $crypto = new Crypt_DES(); + $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount, 16); + $key = $crypto->decrypt($key); + if ($key === false) { + return false; + } + return $this->_parseKey($key, CRYPT_RSA_PRIVATE_FORMAT_PKCS1); + default: + return false; + } /* intended for keys for which OpenSSL's asn1parse returns the following: 0:d=0 hl=4 l= 290 cons: SEQUENCE @@ -1116,7 +1166,6 @@ class Crypt_RSA 6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption 17:d=2 hl=2 l= 0 prim: NULL 19:d=1 hl=4 l= 271 prim: BIT STRING */ - $this->_string_shift($key, $this->_decodeLength($key)); $tag = ord($this->_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag $this->_decodeLength($key); // skip over the BIT STRING / OCTET STRING length // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of From d474f56f60bdfa696afbf755f039080b39ec67ef Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 13 Jun 2014 10:39:57 -0500 Subject: [PATCH 4/9] Crypt/Base: adjust default key size for pbkdf1 --- phpseclib/Crypt/Base.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 198c5424..8572d235 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -573,7 +573,11 @@ class Crypt_Base $count = isset($func_args[4]) ? $func_args[4] : 1000; // Keylength - $dkLen = isset($func_args[5]) ? $func_args[5] : $this->password_key_size; + if (!isset($func_args[5])) { + $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size; + } else { + $dkLen = $func_args[5]; + } switch (true) { case $method == 'pbkdf1': From 4434d91f25d69f3050d5e6ac9a3494939ee5d2b4 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 13 Jun 2014 11:43:32 -0500 Subject: [PATCH 5/9] RSA: add support for saving encrypted PKCS8 keys --- phpseclib/Crypt/RSA.php | 54 +++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 48378dec..d6bad9ec 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -140,19 +140,23 @@ define('CRYPT_RSA_SIGNATURE_PKCS1', 2); /** * ASN1 Integer */ -define('CRYPT_RSA_ASN1_INTEGER', 2); +define('CRYPT_RSA_ASN1_INTEGER', 2); /** * ASN1 Bit String */ -define('CRYPT_RSA_ASN1_BITSTRING', 3); +define('CRYPT_RSA_ASN1_BITSTRING', 3); +/** + * ASN1 Octet String + */ +define('CRYPT_RSA_ASN1_OCTETSTRING', 4); /** * ASN1 Object Identifier */ -define('CRYPT_RSA_ASN1_OBJECT', 6); +define('CRYPT_RSA_ASN1_OBJECT', 6); /** * ASN1 Sequence (with the constucted bit set) */ -define('CRYPT_RSA_ASN1_SEQUENCE', 48); +define('CRYPT_RSA_ASN1_SEQUENCE', 48); /**#@-*/ /**#@+ @@ -859,9 +863,43 @@ class Crypt_RSA $RSAPrivateKey = pack('Ca*a*Ca*a*', CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); - $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . - chunk_split(base64_encode($RSAPrivateKey), 64) . - '-----END PRIVATE KEY-----'; + if (!empty($this->password) || is_string($this->password)) { + $salt = crypt_random_string(8); + $iterationCount = 2048; + + if (!class_exists('Crypt_DES')) { + include_once 'Crypt/DES.php'; + } + $crypto = new Crypt_DES(); + $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount); + $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey); + + $parameters = pack('Ca*a*Ca*N', + CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($salt)), $salt, + CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(4), $iterationCount + ); + $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03"; + + $encryptionAlgorithm = pack('Ca*a*Ca*a*', + CRYPT_RSA_ASN1_OBJECT, $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), $pbeWithMD5AndDES_CBC, + CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($parameters)), $parameters + ); + + $RSAPrivateKey = pack('Ca*a*Ca*a*', + CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($encryptionAlgorithm)), $encryptionAlgorithm, + CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey + ); + + $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + + $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($RSAPrivateKey), 64) . + '-----END ENCRYPTED PRIVATE KEY-----'; + } else { + $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($RSAPrivateKey), 64) . + '-----END PRIVATE KEY-----'; + } return $RSAPrivateKey; } @@ -1150,7 +1188,7 @@ class Crypt_RSA include_once 'Crypt/DES.php'; } $crypto = new Crypt_DES(); - $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount, 16); + $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount); $key = $crypto->decrypt($key); if ($key === false) { return false; From 4878f2a99bb0c4a253ce34f5f9b4b8ae74254e0f Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 13 Jun 2014 12:39:12 -0500 Subject: [PATCH 6/9] RSA: add PKCS8 unit tests --- tests/Unit/Crypt/RSA/LoadKeyTest.php | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index cf80d82e..9402ab42 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -124,6 +124,72 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $this->assertInternalType('string', $rsa->getPrivateKey()); } + public function testLoadPKCS8PrivateKey() + { + $rsa = new Crypt_RSA(); + $rsa->setPassword('password'); + + $key = '-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIE6TAbBgkqhkiG9w0BBQMwDgQIcWWgZeQYPTcCAggABIIEyLoa5b3ktcPmy4VB +hHkpHzVSEsKJPmQTUaQvUwIp6+hYZeuOk78EPehrYJ/QezwJRdyBoD51oOxqWCE2 +fZ5Wf6Mi/9NIuPyqQccP2ouErcMAcDLaAx9C0Ot37yoG0S6hOZgaxqwnCdGYKHgS +7cYUv40kLOJmTOJlHJbatfXHocrHcHkCBJ1q8wApA1KVQIZsqmyBUBuwbrfFwpC9 +d/R674XxCWJpXvU63VNZRFYUvd7YEWCrdSeleb99p0Vn1kxI5463PXurgs/7GPiO +SLSdX44DESP9l7lXenC4gbuT8P0xQRDzGrB5l9HHoV3KMXFODWTMnLcp1nuhA0OT +fPS2yzT9zJgqHiVKWgcUUJ5uDelVfnsmDhnh428p0GBFbniH07qREC9kq78UqQNI +Kybp4jQ4sPs64zdYm/VyLWtAYz8QNAKHLcnPwmTPr/XlJmox8rlQhuSQTK8E+lDr +TOKpydrijN3lF+pgyUuUj6Ha8TLMcOOwqcrpBig4SGYoB56gjAO0yTE9uCPdBakj +yxi3ksn51ErigGM2pGMNcVdwkpJ/x+DEBBO0auy3t9xqM6LK8pwNcOT1EWO+16zY +79LVSavc49t+XxMc3Xasz/G5xQgD1FBp6pEnsg5JhTTG/ih6Y/DQD8z3prjC3qKc +rpL4NA9KBI/IF1iIXlrfmN/zCKbBuEOEGqwcHBDHPySZbhL2XLSpGcK/NBl1bo1Z +G+2nUTauoC67Qb0+fnzTcvOiMNAbHMiqkirs4anHX33MKL2gR/3dp8ca9hhWWXZz +Mkk2FK9sC/ord9F6mTtvTiOSDzpiEhb94uTxXqBhIbsrGXCUUd0QQN5s2dmW2MfS +M35KeSv2rwDGzC1+Qf3MhHGIZDqoQwuZEzM5yHHafCatAbZd2sjaFWegg0r2ca7a +eZkZFj3ZuDYXJFnL82guOASh7rElWO2Ys7ncXAKnaV3WkkF+JDv/CUHr+Q/h6Ae5 +qEvgubTCVSYHzRP37XJItlcdywTIcTY+t6jymmyEBJ66LmUoD47gt/vDUSbhT6Oa +GlcZ+MZGlUnPOSq4YknOgwKH8izboY4UgVCrmXvlaZYQhZemNDkVbpYVDf+s6cPf +tJwVoZf+qf2SsRTUsI10isoIzCyGw2ie8kmipdP434Z/99uVU3zxD6raNDlyp33q +FWMgpr2JU6NVAla7N51g7Jk8VjIIn7SvCYyWkmvv4kLB1UHl3NFqYb9YuIZUaDyt +j/NMcKMLLOaEorRZ2N2mDNoihMxMf8J3J9APnzUigAtaalGKNOrd2Fom5OVADePv +Tb5sg1uVQzfcpFrjIlLVh+2cekX0JM84phbMpHmm5vCjjfYvUvcMy0clCf0x3jz6 +LZf5Fzc8xbZmpse5OnOrsDLCNh+SlcYOzsagSZq4TgvSeI9Tr4lv48dLJHCCcYKL +eymS9nhlCFuuHbi7zI7edcI49wKUW1Sj+kvKq3LMIEkMlgzqGKA6JqSVxHP51VH5 +FqV4aKq70H6dNJ43bLVRPhtF5Bip5P7k/6KIsGTPUd54PHey+DuWRjitfheL0G2w +GF/qoZyC1mbqdtyyeWgHtVbJVUORmpbNnXOII9duEqBUNDiO9VSZNn/8h/VsYeAB +xryZaRDVmtMuf/OZBQ== +-----END ENCRYPTED PRIVATE KEY-----'; + + $this->assertTrue($rsa->loadKey($key)); + $this->assertInternalType('string', $rsa->getPrivateKey()); + } + + public function testSavePKCS8PrivateKey() + { + $rsa = new Crypt_RSA(); + + $key = '-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp +wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5 +1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh +3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2 +pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX +GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il +AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF +L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k +X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl +U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ +37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0= +-----END RSA PRIVATE KEY-----'; + $rsa->setPassword('password'); + + $this->assertTrue($rsa->loadKey($key)); + + $key = $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PKCS8); + $this->assertInternalType('string', $key); + + $this->assertTrue($rsa->loadKey($key)); + } + public function testPubKey1() { $rsa = new Crypt_RSA(); From 83301097eaa68a15faad63a8d2b64dfebc7fc589 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 13 Jun 2014 13:11:59 -0500 Subject: [PATCH 7/9] RSA: rename PUBLIC_FORMAT_PKCS1_RAW -> PUBLIC_FORMAT_PKCS8 also make CRYPT_RSA_PUBLIC_FORMAT_PKCS8 the default format --- phpseclib/Crypt/RSA.php | 15 ++++++++------- phpseclib/File/X509.php | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index d6bad9ec..c295e0df 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -235,6 +235,7 @@ define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 3); * * Analogous to ssh-keygen's pem format (as specified by -m) */ +define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 4); define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW', 4); /** * XML formatted public key @@ -255,11 +256,11 @@ define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 6); * * -----BEGIN PUBLIC KEY----- * - * Analogous to ssh-keygen's pkcs8 format (as specified by -m) - * (the applicability of PKCS8 is dubious since PKCS8 is talking about - * private keys but whatever) + * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8 + * is specific to private keys it's basically creating a DER-encoded wrapper + * for keys. This just extends that same concept to public keys (much like ssh-keygen) */ -define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 7); +define('CRYPT_RSA_PUBLIC_FORMAT_PKCS8', 7); /**#@-*/ /** @@ -301,7 +302,7 @@ class Crypt_RSA * @var Integer * @access public */ - var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS1; + var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS8; /** * Modulus (ie. n) @@ -1748,7 +1749,7 @@ class Crypt_RSA * @param String $key * @param Integer $type optional */ - function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1) + function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS8) { if (empty($this->modulus) || empty($this->publicExponent)) { return false; @@ -1795,7 +1796,7 @@ class Crypt_RSA * @param String $key * @param Integer $type optional */ - function _getPrivatePublicKey($mode = CRYPT_RSA_PUBLIC_FORMAT_PKCS1) + function _getPrivatePublicKey($mode = CRYPT_RSA_PUBLIC_FORMAT_PKCS8) { if (empty($this->modulus) || empty($this->exponent)) { return false; diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index b69dae1b..0f8f4bb8 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -4235,7 +4235,7 @@ class File_X509 } return false; default: // Should be a key object (i.e.: Crypt_RSA). - $key = $key->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW); + $key = $key->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1); break; } @@ -4276,7 +4276,7 @@ class File_X509 //return new File_ASN1_Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey()))); return array( 'algorithm' => array('algorithm' => 'rsaEncryption'), - 'subjectPublicKey' => $this->publicKey->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW) + 'subjectPublicKey' => $this->publicKey->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1) ); default: return false; From d8b235141eeaea59428fe97613ee801e6069deec Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 13 Jun 2014 13:17:37 -0500 Subject: [PATCH 8/9] RSA: CS adjustments --- phpseclib/Crypt/RSA.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index c295e0df..9a4a600d 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -862,7 +862,8 @@ class Crypt_RSA if ($this->privateKeyFormat == CRYPT_RSA_PRIVATE_FORMAT_PKCS8) { $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $RSAPrivateKey = pack('Ca*a*Ca*a*', - CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey + ); $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); if (!empty($this->password) || is_string($this->password)) { $salt = crypt_random_string(8); From 0bafe1e6c63ed1715a3f4b1221a2a587fa2c129c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 16 Jun 2014 09:57:04 -0500 Subject: [PATCH 9/9] Crypt/Base: readability improvement --- phpseclib/Crypt/Base.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 8572d235..2248ed4f 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -573,10 +573,10 @@ class Crypt_Base $count = isset($func_args[4]) ? $func_args[4] : 1000; // Keylength - if (!isset($func_args[5])) { - $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size; - } else { + if (isset($func_args[5])) { $dkLen = $func_args[5]; + } else { + $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size; } switch (true) {