summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorParagon Initiative Enterprises <security@paragonie.com>2016-06-12 21:06:53 -0400
committerParagon Initiative Enterprises <security@paragonie.com>2016-06-12 21:06:53 -0400
commit802a31079090bcfb8dfc88a5704bef3a761a39ec (patch)
treeb3656ab457ed5afa0305c43ef75af15e7834d3b9
parent83f4c006f9d20db6e5d70a7d01ef125cadebfaec (diff)
downloadconstant_time_encoding-802a31079090bcfb8dfc88a5704bef3a761a39ec.zip
constant_time_encoding-802a31079090bcfb8dfc88a5704bef3a761a39ec.tar.gz
constant_time_encoding-802a31079090bcfb8dfc88a5704bef3a761a39ec.tar.bz2
Handle edge-case reported in #4v2.0.2
-rw-r--r--src/Base32.php24
-rw-r--r--src/Base64.php31
-rw-r--r--tests/Base64Test.php43
3 files changed, 74 insertions, 24 deletions
diff --git a/src/Base32.php b/src/Base32.php
index c5ee3de..a65c1c7 100644
--- a/src/Base32.php
+++ b/src/Base32.php
@@ -176,24 +176,24 @@ abstract class Base32 implements EncoderInterface
if ($srcLen === 0) {
return '';
}
- if (($srcLen & 7) === 0) {
- for ($j = 0; $j < 7; ++$j) {
- if ($src[$srcLen - 1] === '=') {
- $srcLen--;
- } else {
- break;
+ if ($strictPadding) {
+ if (($srcLen & 7) === 0) {
+ for ($j = 0; $j < 7; ++$j) {
+ if ($src[$srcLen - 1] === '=') {
+ $srcLen--;
+ } else {
+ break;
+ }
}
}
- }
- if (($srcLen & 7) === 1) {
- if ($strictPadding) {
+ if (($srcLen & 7) === 1) {
throw new \RangeException(
'Incorrect padding'
);
- } else {
- $src = \rtrim($src, '=');
- $srcLen = Binary::safeStrlen($src);
}
+ } else {
+ $src = \rtrim($src, '=');
+ $srcLen = Binary::safeStrlen($src);
}
$err = 0;
diff --git a/src/Base64.php b/src/Base64.php
index 89289a9..df801cc 100644
--- a/src/Base64.php
+++ b/src/Base64.php
@@ -94,23 +94,29 @@ abstract class Base64 implements EncoderInterface
if ($srcLen === 0) {
return '';
}
- if (($srcLen & 3) === 0) {
- if ($src[$srcLen - 1] === '=') {
- $srcLen--;
+
+ if ($strictPadding) {
+ if (($srcLen & 3) === 0) {
if ($src[$srcLen - 1] === '=') {
$srcLen--;
+ if ($src[$srcLen - 1] === '=') {
+ $srcLen--;
+ }
}
}
- }
- if (($srcLen & 3) === 1) {
- if ($strictPadding) {
+ if (($srcLen & 3) === 1) {
+ throw new \RangeException(
+ 'Incorrect padding'
+ );
+ }
+ if ($src[$srcLen - 1] === '=') {
throw new \RangeException(
'Incorrect padding'
);
- } else {
- $src = \rtrim($src, '=');
- $srcLen = Binary::safeStrlen($src);
}
+ } else {
+ $src = \rtrim($src, '=');
+ $srcLen = Binary::safeStrlen($src);
}
$err = 0;
@@ -135,9 +141,9 @@ abstract class Base64 implements EncoderInterface
if ($i < $srcLen) {
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
$c0 = static::decode6Bits($chunk[1]);
- $c1 = static::decode6Bits($chunk[2]);
if ($i + 2 < $srcLen) {
+ $c1 = static::decode6Bits($chunk[2]);
$c2 = static::decode6Bits($chunk[3]);
$dest .= \pack(
'CC',
@@ -145,12 +151,15 @@ abstract class Base64 implements EncoderInterface
((($c1 << 4) | ($c2 >> 2)) & 0xff)
);
$err |= ($c0 | $c1 | $c2) >> 8;
- } elseif($i + 1 < $srcLen) {
+ } elseif ($i + 1 < $srcLen) {
+ $c1 = static::decode6Bits($chunk[2]);
$dest .= \pack(
'C',
((($c0 << 2) | ($c1 >> 4)) & 0xff)
);
$err |= ($c0 | $c1) >> 8;
+ } elseif ($i < $srcLen && $strictPadding) {
+ $err |= 1;
}
}
if ($err !== 0) {
diff --git a/tests/Base64Test.php b/tests/Base64Test.php
index 2fca82a..6ac3a66 100644
--- a/tests/Base64Test.php
+++ b/tests/Base64Test.php
@@ -26,9 +26,50 @@ class Base64Test extends PHPUnit_Framework_TestCase
$unpadded = \rtrim($enc, '=');
$this->assertSame(
$random,
- Base64::decode($unpadded, true)
+ Base64::decode($unpadded)
);
}
}
+ $str = 'MIIFzzCCBLegAwIBAgIDAfdlMA0GCSqGSIb3DQEBBQUAMHMxCzAJBgNVBAYTAlBM' .
+ 'MSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQ' .
+ 'DDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1Oi' .
+ 'A2MB4XDTExMTEwOTA2MDAwMFoXDTEzMTEwOTA2MDAwMFowgdkxCzAJBgNVBAYTAlBMM' .
+ 'RwwGgYDVQQKDBNVcnrEhWQgTWlhc3RhIEdkeW5pMRswGQYDVQQFExJQRVNFTDogNjEw' .
+ 'NjA2MDMxMTgxGTAXBgNVBAMMEEplcnp5IFByemV3b3Jza2kxTzBNBgNVBBAwRgwiQWw' .
+ 'uIE1hcnN6YcWCa2EgUGnFgnN1ZHNraWVnbyA1Mi81NAwNODEtMzgyIEdkeW5pYQwGUG' .
+ '9sc2thDAlwb21vcnNraWUxDjAMBgNVBCoMBUplcnp5MRMwEQYDVQQEDApQcnpld29yc' .
+ '2tpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMm5vjGqHPthJCMqKpqssSISRo' .
+ 's0PYDTcEQzyyurfX67EJWKtZj6HNwuDMEGJ02iBNZfjUl7r8dIi28bSKhNlsfycXZKY' .
+ 'RcIjp0+r5RqtR2auo9GQ6veKb61DEAGIqaR+uLLcJVTHCu0w9oXLGbRlGth5eNoj03C' .
+ 'xXVAH2IfhbNwIDAQABo4IChzCCAoMwDAYDVR0TAQH/BAIwADCCAUgGA1UdIAEB/wSCA' .
+ 'TwwggE4MIIBNAYJKoRoAYb3IwEBMIIBJTCB3QYIKwYBBQUHAgIwgdAMgc1EZWtsYXJh' .
+ 'Y2phIHRhIGplc3Qgb8Wbd2lhZGN6ZW5pZW0gd3lkYXdjeSwgxbxlIHRlbiBjZXJ0eWZ' .
+ 'pa2F0IHpvc3RhxYIgd3lkYW55IGpha28gY2VydHlmaWthdCBrd2FsaWZpa293YW55IH' .
+ 'pnb2RuaWUgeiB3eW1hZ2FuaWFtaSB1c3Rhd3kgbyBwb2RwaXNpZSBlbGVrdHJvbmlje' .
+ 'm55bSBvcmF6IHRvd2FyenlzesSFY3ltaSBqZWogcm96cG9yesSFZHplbmlhbWkuMEMG' .
+ 'CCsGAQUFBwIBFjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN' .
+ '6eS9wb2xpdHlrYS5odG1sMAkGA1UdCQQCMAAwIQYDVR0RBBowGIEWai5wcnpld29yc2' .
+ 'tpQGdkeW5pYS5wbDAOBgNVHQ8BAf8EBAMCBkAwgZ4GA1UdIwSBljCBk4AU3TGldJXip' .
+ 'N4oGS3ZYmnBDMFs8gKhd6R1MHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dh' .
+ 'IEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt' .
+ '3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2ggJb9jBIBgNVHR8EQTA/MD' .
+ '2gO6A5hjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9DU' .
+ 'kxfT1pLMzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBYPIqnAreyeql7/opJjcar/qWZ' .
+ 'y9ruhB2q0lZFsJOhwgMnbQXzp/4vv93YJqcHGAXdHP6EO8FQX47mjo2ZKQmi+cIHJHL' .
+ 'ONdX/3Im+M17V0iNAh7Z1lOSfTRT+iiwe/F8phcEaD5q2RmvYusR7zXZq/cLL0If0hX' .
+ 'oPZ/EHQxjN8pxzxiUx6bJAgturnIMEfRNesxwghdr1dkUjOhGLf3kHVzgM6j3VAM7oF' .
+ 'mMUb5y5s96Bzl10DodWitjOEH0vvnIcsppSxH1C1dCAi0o9f/1y2XuLNhBNHMAyTqpY' .
+ 'PX8Yvav1c+Z50OMaSXHAnTa20zv8UtiHbaAhwlifCelUMj93S';
+
+ try {
+ Base64::decode($str, true);
+ $this->fail('Strict padding not enforced');
+ } catch (\Exception $ex) {
+
+ $this->assertSame(
+ Base64::decode($str),
+ \base64_decode($str)
+ );
+ }
}
}