diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 099e1ec0..dba99de7 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -1176,6 +1176,11 @@ class ASN1 $oid = array(); $pos = 0; $len = strlen($content); + // see https://github.com/openjdk/jdk/blob/2deb318c9f047ec5a4b160d66a4b52f93688ec42/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java#L55 + if ($len > 4096) { + //user_error('Object Identifier size is limited to 4096 bytes'); + return false; + } if (ord($content[$len - 1]) & 0x80) { return false; diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index 81b69ace..fd9cd578 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -729,6 +729,33 @@ class BigInteger return $result; } + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + function getLength() + { + if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL) { + return strlen($this->toBits()); + } + + $max = count($this->value) - 1; + return $max != -1 ? + $max * MATH_BIGINTEGER_BASE + ceil(log($a->value[$max] + 1, 2)) : + 0; + } + + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + function getLengthInBytes() + { + return ceil($this->getLength() / 8); + } + /** * Copy an object * @@ -3237,6 +3264,11 @@ class BigInteger $min = $temp; } + $length = $max->getLength(); + if ($length > 8196) { + user_error('Generation of random prime numbers larger than 8196 has been disabled'); + } + static $one, $two; if (!isset($one)) { $one = new static(1); @@ -3344,7 +3376,14 @@ class BigInteger */ function isPrime($t = false) { - $length = strlen($this->toBytes()); + $length = $this->getLength(); + // OpenSSL limits RSA keys to 16384 bits. The length of an RSA key is equal to the length of the modulo, which is + // produced by multiplying the primes p and q by one another. The largest number two 8196 bit primes can produce is + // a 16384 bit number so, basically, 8196 bit primes are the largest OpenSSL will generate and if that's the largest + // that it'll generate it also stands to reason that that's the largest you'll be able to test primality on + if ($length > 8196) { + user_error('Primality testing is not supported for numbers larger than 8196 bits'); + } if (!$t) { // see HAC 4.49 "Note (controlling the error probability)" diff --git a/tests/Unit/File/ASN1/mal-cert-02.der b/tests/Unit/File/ASN1/mal-cert-02.der new file mode 100644 index 00000000..981c3557 Binary files /dev/null and b/tests/Unit/File/ASN1/mal-cert-02.der differ diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index d371154e..486809a2 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -448,4 +448,17 @@ class Unit_File_ASN1Test extends PhpseclibTestCase $decoded = $asn1->decodeBER($em); $this->assertFalse($decoded[0]); } + + public function testLongOID() + { + $cert = file_get_contents(dirname(__FILE__) . '/ASN1/mal-cert-02.der'); + + $asn1 = new File_ASN1(); + //$this->setExpectedException('PHPUnit_Framework_Error_Notice'); + $decoded = $asn1->decodeBER($cert); + $this->assertFalse($decoded[0]); + + //$x509 = new X509(); + //$x509->loadX509($cert); + } }