diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index d2c6c7cbe..72be6eeb1 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -2762,7 +2762,7 @@ function _emsa_pss_verify($m, $em, $emBits) // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error // be output. - $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8); + $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; $mHash = $this->hash->hash($m); @@ -2840,7 +2840,7 @@ function _rsassa_pss_verify($m, $s) // RSA verification - $modBits = 8 * $this->k; + $modBits = strlen($this->modulus->toBits()); $s2 = $this->_os2ip($s); $m2 = $this->_rsavp1($s2); @@ -2848,7 +2848,7 @@ function _rsassa_pss_verify($m, $s) user_error('Invalid signature'); return false; } - $em = $this->_i2osp($m2, $modBits >> 3); + $em = $this->_i2osp($m2, $this->k); if ($em === false) { user_error('Invalid signature'); return false; diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index c3a3f2283..97af5c45d 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -94,4 +94,25 @@ public function testZeroLengthSalt() $rsa->loadKey($rsa->getPublicKey()); $this->assertTrue($rsa->verify($plaintext, $sig)); } + + /** + * @group github1423 + */ + public function testPSSSigsWithNonPowerOf2Key() + { + $pub = '-----BEGIN PUBLIC KEY----- +MF0wDQYJKoZIhvcNAQEBBQADTAAwSQJCAmdYuOvii3I6ya3q/zSeZFoJprgF9fIq +k12yS6pCS3c+1wZ9cYFVtgfpSL4XpylLe9EnRT2GRVYCqUkR4AUeTuvnAgMBAAE= +-----END PUBLIC KEY-----'; + + $rsa = new Crypt_RSA(); + $rsa->loadKey($pub); + $rsa->setHash('sha256'); + $rsa->setSaltLength(32); + $rsa->setMGFHash('sha256'); + + $sig = base64_decode(strtr('Ad022bD-UCmWpBNMtsYJjG0FVxML-FFlN4IKrByP8rwjVzV_D-YqSjc_oW6LrooV7jbtEF5803YLn8lllyzDnw00', '-_', '+/')); + $payload = 'eyJraWQiOiJ0RkMyVUloRnBUTV9FYTNxY09kX01xUVQxY0JCbTlrRkxTRGZlSmhzUkc4IiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJhY2NvdW50cG9ydGFsIiwic3ViIjoiNTliOGM4YzA5NTVhNDA5MDg2MGRmYmM3ZGQwMjVjZWEiLCJjbGlkIjoiZTQ5ZTA2N2JiMTFjNDcyMmEzNGIyYjNiOGE2YTYzNTUiLCJhbSI6InBhc3N3b3JkIiwicCI6ImVOcDFrRUZQd3pBTWhmXC9QdEVOYU5kQkc2bUZDNHNpbENNNXU0aTNXMHFSS0hFVDU5V1JzcXpZRUp4XC84M3ZQbkIxcUg3Rm5CZVNabEtNME9saGVZVUVWTXlHOEVUOEZnWDI4dkdqWG4wWkcrV2hSK01rWVBicGZacHI2U3E0N0RFYjBLYkRFT21CSUZuOTZKN1ZDaWg1Q2p4dWNRZDJmdHJlMCt2cSthZFFObUluK0poWEl0UlBvQ0xya1wvZ05VV3N3T09vSVwva0Q5ZVk4c05jRHFPUzNkanFWb3RPU21oRUo5b0hZZmFqZmpSRzFGSWpGRFwvOExtT2pKbVF3d0tBMnQ0aXJBQ2NncHo0dzBuN3BtXC84YXV2T0dFM2twVFZ2d0IzdzlQZk1YZnJJUTBhejRsaEtIdVBUMU42XC9sb1FJPSIsImlhaSI6IjU5YjhjOGMwOTU1YTQwOTA4NjBkZmJjN2RkMDI1Y2VhIiwiY2xzdmMiOiJhY2NvdW50cG9ydGFsIiwibHB2IjoxNTQ3Njc1NDM4LCJ0IjoicyIsImljIjp0cnVlLCJleHAiOjE1NDc3MDQyMzgsImlhdCI6MTU0NzY3NTQzOCwianRpIjoiZTE0N2UzM2UzNzVhNDkyNWJjMzdjZTRjMDIwMmJjNDYifQ'; + $this->assertTrue($rsa->verify($payload, $sig)); + } }