Move _encodeLength and _decodeLength to Common\Functions\ASN1.php

This commit is contained in:
terrafrost 2016-07-31 08:54:57 -05:00
parent c509909004
commit d64599f799
13 changed files with 142 additions and 165 deletions

View File

@ -0,0 +1,66 @@
<?php
/**
* Common ASN1 Functions
*
* PHP version 5
*
* @category Common
* @package Functions\ASN1
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2016 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Common\Functions;
/**
* Common ASN1 Functions
*
* @package Functions\ASN1
* @author Jim Wigginton <terrafrost@php.net>
*/
class ASN1
{
/**
* DER-decode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access public
* @param string $string
* @return int
*/
static function decodeLength(&$string)
{
$length = ord(Strings::shift($string));
if ($length & 0x80) { // definite length, long form
$length&= 0x7F;
$temp = Strings::shift($string, $length);
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
}
return $length;
}
/**
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access public
* @param int $length
* @return string
*/
static function encodeLength($length)
{
if ($length <= 0x7F) {
return chr($length);
}
$temp = ltrim(pack('N', $length), chr(0));
return pack('Ca*', 0x80 | strlen($temp), $temp);
}
}

View File

@ -30,7 +30,7 @@ class Strings
*
* @param string $string
* @param int $index
* @access private
* @access public
* @return string
*/
static function shift(&$string, $index = 1)

View File

@ -1093,47 +1093,6 @@ class RSA
);
}
/**
* DER-decode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param string $string
* @return int
*/
function _decodeLength(&$string)
{
$length = ord(Strings::shift($string));
if ($length & 0x80) { // definite length, long form
$length&= 0x7F;
$temp = Strings::shift($string, $length);
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
}
return $length;
}
/**
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param int $length
* @return string
*/
function _encodeLength($length)
{
if ($length <= 0x7F) {
return chr($length);
}
$temp = ltrim(pack('N', $length), chr(0));
return pack('Ca*', 0x80 | strlen($temp), $temp);
}
/**
* Determines the private key format
*

View File

@ -1,4 +1,5 @@
<?php
/**
* Miccrosoft BLOB Formatted RSA Key Handler
*

View File

@ -1,4 +1,5 @@
<?php
/**
* OpenSSH Formatted RSA Key Handler
*

View File

@ -1,4 +1,5 @@
<?php
/**
* PKCS Formatted RSA Key Handler
*
@ -23,6 +24,7 @@ use phpseclib\Crypt\DES;
use phpseclib\Crypt\TripleDES;
use phpseclib\Math\BigInteger;
use phpseclib\Common\Functions\Strings;
use phpseclib\Common\Functions\ASN1;
/**
* PKCS Formatted RSA Key Handler
@ -213,7 +215,7 @@ abstract class PKCS
if (ord(Strings::shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
if (self::_decodeLength($key) != strlen($key)) {
if (ASN1::decodeLength($key) != strlen($key)) {
return false;
}
@ -235,11 +237,11 @@ abstract class PKCS
}
if ($tag == self::ASN1_SEQUENCE) {
$temp = Strings::shift($key, self::_decodeLength($key));
$temp = Strings::shift($key, ASN1::decodeLength($key));
if (ord(Strings::shift($temp)) != self::ASN1_OBJECT) {
return false;
}
$length = self::_decodeLength($temp);
$length = ASN1::decodeLength($temp);
switch (Strings::shift($temp, $length)) {
case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
break;
@ -252,18 +254,18 @@ abstract class PKCS
if (ord(Strings::shift($temp)) != self::ASN1_SEQUENCE) {
return false;
}
if (self::_decodeLength($temp) != strlen($temp)) {
if (ASN1::decodeLength($temp) != strlen($temp)) {
return false;
}
Strings::shift($temp); // assume it's an octet string
$salt = Strings::shift($temp, self::_decodeLength($temp));
$salt = Strings::shift($temp, ASN1::decodeLength($temp));
if (ord(Strings::shift($temp)) != self::ASN1_INTEGER) {
return false;
}
self::_decodeLength($temp);
ASN1::decodeLength($temp);
list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
Strings::shift($key); // assume it's an octet string
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
if (strlen($key) != $length) {
return false;
}
@ -286,7 +288,7 @@ abstract class PKCS
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING */
$tag = ord(Strings::shift($key)); // skip over the BIT STRING / OCTET STRING tag
self::_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
ASN1::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
// unused bits in the final subsequent octet. The number shall be in the range zero to seven."
// -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
@ -296,7 +298,7 @@ abstract class PKCS
if (ord(Strings::shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
if (self::_decodeLength($key) != strlen($key)) {
if (ASN1::decodeLength($key) != strlen($key)) {
return false;
}
$tag = ord(Strings::shift($key));
@ -305,12 +307,12 @@ abstract class PKCS
return false;
}
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$temp = Strings::shift($key, $length);
if (strlen($temp) != 1 || ord($temp) > 2) {
$components['modulus'] = new BigInteger($temp, 256);
Strings::shift($key); // skip over self::ASN1_INTEGER
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(Strings::shift($key, $length), 256);
return $components;
@ -318,48 +320,48 @@ abstract class PKCS
if (ord(Strings::shift($key)) != self::ASN1_INTEGER) {
return false;
}
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['modulus'] = new BigInteger(Strings::shift($key, $length), 256);
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['publicExponent'] = new BigInteger(Strings::shift($key, $length), 256);
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['privateExponent'] = new BigInteger(Strings::shift($key, $length), 256);
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['primes'] = array(1 => new BigInteger(Strings::shift($key, $length), 256));
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['primes'][] = new BigInteger(Strings::shift($key, $length), 256);
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['exponents'] = array(1 => new BigInteger(Strings::shift($key, $length), 256));
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['exponents'][] = new BigInteger(Strings::shift($key, $length), 256);
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['coefficients'] = array(2 => new BigInteger(Strings::shift($key, $length), 256));
if (!empty($key)) {
if (ord(Strings::shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
self::_decodeLength($key);
ASN1::decodeLength($key);
while (!empty($key)) {
if (ord(Strings::shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
self::_decodeLength($key);
ASN1::decodeLength($key);
$key = substr($key, 1);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['primes'][] = new BigInteger(Strings::shift($key, $length), 256);
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['exponents'][] = new BigInteger(Strings::shift($key, $length), 256);
Strings::shift($key);
$length = self::_decodeLength($key);
$length = ASN1::decodeLength($key);
$components['coefficients'][] = new BigInteger(Strings::shift($key, $length), 256);
}
}
@ -402,47 +404,6 @@ abstract class PKCS
self::$format = self::MODE_ANY;
}
/**
* DER-decode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param string $string
* @return int
*/
static function _decodeLength(&$string)
{
$length = ord(Strings::shift($string));
if ($length & 0x80) { // definite length, long form
$length&= 0x7F;
$temp = Strings::shift($string, $length);
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
}
return $length;
}
/**
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param int $length
* @return string
*/
static function _encodeLength($length)
{
if ($length <= 0x7F) {
return chr($length);
}
$temp = ltrim(pack('N', $length), chr(0));
return pack('Ca*', 0x80 | strlen($temp), $temp);
}
/**
* Extract raw BER from Base64 encoding
*

View File

@ -1,4 +1,5 @@
<?php
/**
* PKCS#1 Formatted RSA Key Handler
*
@ -29,6 +30,7 @@ use phpseclib\Crypt\DES;
use phpseclib\Crypt\Random;
use phpseclib\Crypt\TripleDES;
use phpseclib\Math\BigInteger;
use phpseclib\Common\Functions\ASN1;
/**
* PKCS#1 Formatted RSA Key Handler
@ -88,7 +90,7 @@ class PKCS1 extends PKCS
$components = array();
foreach ($raw as $name => $value) {
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($value)), $value);
}
$RSAPrivateKey = implode('', $components);
@ -103,15 +105,15 @@ class PKCS1 extends PKCS
// exponent INTEGER, -- di
// coefficient INTEGER -- ti
// }
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
}
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
}
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
if (!empty($password) || is_string($password)) {
$cipher = self::getEncryptionObject(self::$defaultEncryptionAlgorithm);
@ -153,14 +155,14 @@ class PKCS1 extends PKCS
// publicExponent INTEGER -- e
// }
$components = array(
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($modulus)), $modulus),
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($publicExponent)), $publicExponent)
);
$RSAPublicKey = pack(
'Ca*a*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
ASN1::encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
$components['modulus'],
$components['publicExponent']
);

View File

@ -1,4 +1,5 @@
<?php
/**
* PKCS#8 Formatted RSA Key Handler
*
@ -28,6 +29,7 @@ use ParagonIE\ConstantTime\Base64;
use phpseclib\Crypt\DES;
use phpseclib\Crypt\Random;
use phpseclib\Math\BigInteger;
use phpseclib\Common\Functions\ASN1;
/**
* PKCS#8 Formatted RSA Key Handler
@ -68,7 +70,7 @@ class PKCS8 extends PKCS
$components = array();
foreach ($raw as $name => $value) {
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($value)), $value);
}
$RSAPrivateKey = implode('', $components);
@ -83,15 +85,15 @@ class PKCS8 extends PKCS
// exponent INTEGER, -- di
// coefficient INTEGER -- ti
// }
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
}
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
}
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
$RSAPrivateKey = pack(
@ -100,10 +102,10 @@ class PKCS8 extends PKCS
"\01\00",
$rsaOID,
4,
self::_encodeLength(strlen($RSAPrivateKey)),
ASN1::encodeLength(strlen($RSAPrivateKey)),
$RSAPrivateKey
);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
if (!empty($password) || is_string($password)) {
$salt = Random::string(8);
$iterationCount = 2048;
@ -115,10 +117,10 @@ class PKCS8 extends PKCS
$parameters = pack(
'Ca*a*Ca*N',
self::ASN1_OCTETSTRING,
self::_encodeLength(strlen($salt)),
ASN1::encodeLength(strlen($salt)),
$salt,
self::ASN1_INTEGER,
self::_encodeLength(4),
ASN1::encodeLength(4),
$iterationCount
);
$pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
@ -126,24 +128,24 @@ class PKCS8 extends PKCS
$encryptionAlgorithm = pack(
'Ca*a*Ca*a*',
self::ASN1_OBJECT,
self::_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
ASN1::encodeLength(strlen($pbeWithMD5AndDES_CBC)),
$pbeWithMD5AndDES_CBC,
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($parameters)),
ASN1::encodeLength(strlen($parameters)),
$parameters
);
$RSAPrivateKey = pack(
'Ca*a*Ca*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($encryptionAlgorithm)),
ASN1::encodeLength(strlen($encryptionAlgorithm)),
$encryptionAlgorithm,
self::ASN1_OCTETSTRING,
self::_encodeLength(strlen($RSAPrivateKey)),
ASN1::encodeLength(strlen($RSAPrivateKey)),
$RSAPrivateKey
);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, ASN1::encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
$RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
chunk_split(Base64::encode($RSAPrivateKey), 64) .
@ -176,14 +178,14 @@ class PKCS8 extends PKCS
// publicExponent INTEGER -- e
// }
$components = array(
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($modulus)), $modulus),
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, ASN1::encodeLength(strlen($publicExponent)), $publicExponent)
);
$RSAPublicKey = pack(
'Ca*a*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
ASN1::encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
$components['modulus'],
$components['publicExponent']
);
@ -191,12 +193,12 @@ class PKCS8 extends PKCS
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
$RSAPublicKey = chr(0) . $RSAPublicKey;
$RSAPublicKey = chr(3) . self::_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
$RSAPublicKey = chr(3) . ASN1::encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
$RSAPublicKey = pack(
'Ca*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($rsaOID . $RSAPublicKey)),
ASN1::encodeLength(strlen($rsaOID . $RSAPublicKey)),
$rsaOID . $RSAPublicKey
);

View File

@ -1,4 +1,5 @@
<?php
/**
* PuTTY Formatted RSA Key Handler
*

View File

@ -1,4 +1,5 @@
<?php
/**
* Raw RSA Key Handler
*

View File

@ -1,4 +1,5 @@
<?php
/**
* XML Formatted RSA Key Handler
*

View File

@ -26,6 +26,7 @@ namespace phpseclib\File;
use ParagonIE\ConstantTime\Base64;
use phpseclib\File\ASN1\Element;
use phpseclib\Math\BigInteger;
use phpseclib\Common\Functions\ASN1 as Functions;
/**
* Pure-PHP ASN.1 Parser
@ -884,7 +885,7 @@ class ASN1
*/
if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) {
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
$temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp;
$temp = $subtag . Functions::encodeLength(strlen($temp)) . $temp;
} else {
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']);
$temp = $subtag . substr($temp, 1);
@ -918,7 +919,7 @@ class ASN1
if (isset($child['constant'])) {
if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) {
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
$temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp;
$temp = $subtag . Functions::encodeLength(strlen($temp)) . $temp;
} else {
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']);
$temp = $subtag . substr($temp, 1);
@ -1089,34 +1090,14 @@ class ASN1
if (isset($mapping['cast'])) {
if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) {
$value = chr($tag) . $this->_encodeLength(strlen($value)) . $value;
$value = chr($tag) . Functions::encodeLength(strlen($value)) . $value;
$tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast'];
} else {
$tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast'];
}
}
return chr($tag) . $this->_encodeLength(strlen($value)) . $value;
}
/**
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param int $length
* @return string
*/
function _encodeLength($length)
{
if ($length <= 0x7F) {
return chr($length);
}
$temp = ltrim(pack('N', $length), chr(0));
return pack('Ca*', 0x80 | strlen($temp), $temp);
return chr($tag) . Functions::encodeLength(strlen($value)) . $value;
}
/**

View File

@ -9,6 +9,7 @@ use phpseclib\File\ASN1;
use phpseclib\File\ASN1\Element;
use phpseclib\File\X509;
use phpseclib\Crypt\RSA;
use phpseclib\Common\Functions\ASN1 as Functions;
class Unit_File_X509_X509Test extends PhpseclibTestCase
{
@ -136,10 +137,10 @@ IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
$asn1 = new ASN1();
$value = $this->_encodeOID('1.2.3.4');
$ext = chr(ASN1::TYPE_OBJECT_IDENTIFIER) . $asn1->_encodeLength(strlen($value)) . $value;
$ext = chr(ASN1::TYPE_OBJECT_IDENTIFIER) . Functions::encodeLength(strlen($value)) . $value;
$value = 'zzzzzzzzz';
$ext.= chr(ASN1::TYPE_OCTET_STRING) . $asn1->_encodeLength(strlen($value)) . $value;
$ext = chr(ASN1::TYPE_SEQUENCE | 0x20) . $asn1->_encodeLength(strlen($ext)) . $ext;
$ext.= chr(ASN1::TYPE_OCTET_STRING) . Functions::encodeLength(strlen($value)) . $value;
$ext = chr(ASN1::TYPE_SEQUENCE | 0x20) . Functions::encodeLength(strlen($ext)) . $ext;
$cert['tbsCertificate']['extensions'][4] = new Element($ext);