From: terrafrost <terrafrost@php.net>
Date: Tue, 21 Nov 2023 19:10:46 -0600
Subject: Math/BinaryField: fix for excessively large degrees

Origin: backport, https://github.com/phpseclib/phpseclib/commit/964d78101a70305df33f442f5490f0adb3b7e77f
Bug-Debian: https://bugs.debian.org/1057008
---
 phpseclib/Math/BinaryField.php  |  9 +++++++++
 tests/Unit/Crypt/EC/KeyTest.php | 16 ++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/phpseclib/Math/BinaryField.php b/phpseclib/Math/BinaryField.php
index 3e21a67..5da8c93 100644
--- a/phpseclib/Math/BinaryField.php
+++ b/phpseclib/Math/BinaryField.php
@@ -48,6 +48,15 @@ class BinaryField extends FiniteField
     public function __construct(...$indices)
     {
         $m = array_shift($indices);
+        if ($m > 571) {
+            /* sect571r1 and sect571k1 are the largest binary curves that https://www.secg.org/sec2-v2.pdf defines
+               altho theoretically there may be legit reasons to use binary finite fields with larger degrees
+               imposing a limit on the maximum size is both reasonable and precedented. in particular,
+               http://tools.ietf.org/html/rfc4253#section-6.1 (The Secure Shell (SSH) Transport Layer Protocol) says
+               "implementations SHOULD check that the packet length is reasonable in order for the implementation to
+                avoid denial of service and/or buffer overflow attacks" */
+            throw new \OutOfBoundsException('Degrees larger than 571 are not supported');
+        }
         $val = str_repeat('0', $m) . '1';
         foreach ($indices as $index) {
             $val[$index] = '1';
diff --git a/tests/Unit/Crypt/EC/KeyTest.php b/tests/Unit/Crypt/EC/KeyTest.php
index f0069a3..f423845 100644
--- a/tests/Unit/Crypt/EC/KeyTest.php
+++ b/tests/Unit/Crypt/EC/KeyTest.php
@@ -690,4 +690,20 @@ cN6W+k8UvGf+Y/lDWNbFitQocabsDUvSN0edHH3UKP5QPTz4cOlyIPMrXQ==
         $key = PublicKeyLoader::load($key);
         $this->assertInstanceOf(PublicKey::class, $key);
     }
+
+    public function testExcessivelyLargeBinaryField()
+    {
+        $this->expectException('\OutOfBoundsException');
+
+        $key = '-----BEGIN PUBLIC KEY-----
+MIIBDDCB0wYHKoZIzj0CATCBxwIBATAgBgcqhkjOPQECMBUCBH////8GCSqGSM49
+AQIDAgICAMEwTQQZABeFj+t6mJdRaeFx93tAh94JisipEd97AQQZAP37Sb/mw6if
+rK2qeh5bvHzBwuXYMUeIFAMVABA/rsdNaW5naHVhUXV3f8Wxke8wBDMEAfSBvF8P
++Ep0rWzfb970v2F5YlNy2MDF4QAl45nykDcSzPPqnjoa0X+wsyAbavfOGwUCGQEA
+AAAAAAAAAAAAAADH80p3j0Q6zJIOukkCAQIDNAAEAE2mUTAwdPK952h3G8ZinK8B
+z9DYTLdGkQDqox3AtEs9nn6kE1O/vHE4bqMegjj4gbA=
+-----END PUBLIC KEY-----';
+        $key = EC::loadFormat('PKCS8', $key);
+        $this->assertInstanceOf(PublicKey::class, $key);
+    }
 }
