1
0
mirror of https://github.com/danog/phpseclib.git synced 2024-12-06 05:58:53 +01:00

Merge branch 'openssl-support-2.0'

This commit is contained in:
terrafrost 2015-04-10 23:08:29 -05:00
commit 5304afd5c1
43 changed files with 3102 additions and 1088 deletions

View File

@ -3,5 +3,5 @@ imports:
tools:
external_code_coverage:
runs: 5 # No Code Coverage on PHP 5.2 and HHVM
runs: 5 # No Code Coverage and HHVM
timeout: 2700 # 45 minutes

View File

@ -23,7 +23,7 @@ install:
- eval `ssh-agent -s`
- travis/setup-secure-shell.sh
- sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/install-php-extensions.sh; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then travis/setup-composer.sh; fi"
- travis/setup-composer.sh
script:
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' ]; then vendor/bin/phing -f build/build.xml sniff; fi"
@ -31,4 +31,4 @@ script:
after_success:
- sh -c "if $TRAVIS_SECURE_ENV_VARS; then travis/upload-code-coverage-html.sh; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' -a '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/upload-code-coverage-scrutinizer.sh; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/upload-code-coverage-scrutinizer.sh; fi"

View File

@ -1,5 +1,11 @@
# Changelog
## 0.3.10 - 2015-02-04
- simplify SSH2 window size handling ([#538](https://github.com/phpseclib/phpseclib/pull/538))
- slightly relax the conditions under which OpenSSL is used ([#598](https://github.com/phpseclib/phpseclib/pull/598))
- fix issue with empty constructed context-specific tags in ASN1 ([#606](https://github.com/phpseclib/phpseclib/pull/606))
## 0.3.9 - 2014-11-09
- PHP 5.6 improvements ([#482](https://github.com/phpseclib/phpseclib/pull/482), [#491](https://github.com/phpseclib/phpseclib/issues/491))

View File

@ -63,10 +63,5 @@
"psr-4": {
"phpseclib\\": "phpseclib/"
}
},
"extra": {
"branch-alias": {
"dev-php5": "2.0-dev"
}
}
}

394
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "8bfef4eaee8f139a70e6250eb9175fd6",
"hash": "1973a3fc1c8f678a9cd0ff646f7a8bee",
"packages": [],
"packages-dev": [
{
@ -159,16 +159,16 @@
},
{
"name": "phing/phing",
"version": "2.9.0",
"version": "2.9.1",
"source": {
"type": "git",
"url": "https://github.com/phingofficial/phing.git",
"reference": "12af1264dd4c5b88e28ee787e829de13c5ec172e"
"reference": "393edeffa8a85d43636ce0c9b4deb1ff9ac60a5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phingofficial/phing/zipball/12af1264dd4c5b88e28ee787e829de13c5ec172e",
"reference": "12af1264dd4c5b88e28ee787e829de13c5ec172e",
"url": "https://api.github.com/repos/phingofficial/phing/zipball/393edeffa8a85d43636ce0c9b4deb1ff9ac60a5c",
"reference": "393edeffa8a85d43636ce0c9b4deb1ff9ac60a5c",
"shasum": ""
},
"require": {
@ -244,20 +244,128 @@
"task",
"tool"
],
"time": "2014-11-25 14:58:59"
"time": "2014-12-03 09:18:46"
},
{
"name": "phpunit/php-code-coverage",
"version": "2.0.12",
"name": "phpdocumentor/reflection-docblock",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "7ce9da20f96964bb7a4033f53834df13328dbeab"
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7ce9da20f96964bb7a4033f53834df13328dbeab",
"reference": "7ce9da20f96964bb7a4033f53834df13328dbeab",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"suggest": {
"dflydev/markdown": "~1.0",
"erusev/parsedown": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-0": {
"phpDocumentor": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "mike.vanriel@naenius.com"
}
],
"time": "2015-02-03 12:10:50"
},
{
"name": "phpspec/prophecy",
"version": "v1.3.1",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9",
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9",
"shasum": ""
},
"require": {
"doctrine/instantiator": "~1.0,>=1.0.2",
"phpdocumentor/reflection-docblock": "~2.0"
},
"require-dev": {
"phpspec/phpspec": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"psr-0": {
"Prophecy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
},
{
"name": "Marcello Duarte",
"email": "marcello.duarte@gmail.com"
}
],
"description": "Highly opinionated mocking framework for PHP 5.3+",
"homepage": "http://phpspec.org",
"keywords": [
"Double",
"Dummy",
"fake",
"mock",
"spy",
"stub"
],
"time": "2014-11-17 16:23:49"
},
{
"name": "phpunit/php-code-coverage",
"version": "2.0.15",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
"shasum": ""
},
"require": {
@ -270,7 +378,7 @@
},
"require-dev": {
"ext-xdebug": ">=2.1.4",
"phpunit/phpunit": "~4.1"
"phpunit/phpunit": "~4"
},
"suggest": {
"ext-dom": "*",
@ -289,9 +397,6 @@
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
@ -309,7 +414,7 @@
"testing",
"xunit"
],
"time": "2014-12-02 13:17:01"
"time": "2015-01-24 10:06:35"
},
{
"name": "phpunit/php-file-iterator",
@ -446,16 +551,16 @@
},
{
"name": "phpunit/php-token-stream",
"version": "1.3.0",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876"
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876",
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74",
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74",
"shasum": ""
},
"require": {
@ -468,7 +573,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
"dev-master": "1.4-dev"
}
},
"autoload": {
@ -491,20 +596,20 @@
"keywords": [
"tokenizer"
],
"time": "2014-08-31 06:12:13"
"time": "2015-01-17 09:51:32"
},
{
"name": "phpunit/phpunit",
"version": "4.3.5",
"version": "4.5.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "2dab9d593997db4abcf58d0daf798eb4e9cecfe1"
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2dab9d593997db4abcf58d0daf798eb4e9cecfe1",
"reference": "2dab9d593997db4abcf58d0daf798eb4e9cecfe1",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5",
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5",
"shasum": ""
},
"require": {
@ -514,15 +619,17 @@
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpspec/prophecy": "~1.3.1",
"phpunit/php-code-coverage": "~2.0",
"phpunit/php-file-iterator": "~1.3.2",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "~1.0.2",
"phpunit/phpunit-mock-objects": "~2.3",
"sebastian/comparator": "~1.0",
"sebastian/comparator": "~1.1",
"sebastian/diff": "~1.1",
"sebastian/environment": "~1.0",
"sebastian/exporter": "~1.0",
"sebastian/environment": "~1.2",
"sebastian/exporter": "~1.2",
"sebastian/global-state": "~1.0",
"sebastian/version": "~1.0",
"symfony/yaml": "~2.0"
},
@ -535,7 +642,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3.x-dev"
"dev-master": "4.5.x-dev"
}
},
"autoload": {
@ -544,10 +651,6 @@
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"",
"../../symfony/yaml/"
],
"license": [
"BSD-3-Clause"
],
@ -559,13 +662,13 @@
}
],
"description": "The PHP Unit Testing framework.",
"homepage": "http://www.phpunit.de/",
"homepage": "https://phpunit.de/",
"keywords": [
"phpunit",
"testing",
"xunit"
],
"time": "2014-11-11 10:11:09"
"time": "2015-02-05 15:51:19"
},
{
"name": "phpunit/phpunit-mock-objects",
@ -727,30 +830,30 @@
},
{
"name": "sebastian/comparator",
"version": "1.0.1",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef"
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e54a01c0da1b87db3c5a3c4c5277ddf331da4aef",
"reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e",
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.1",
"sebastian/exporter": "~1.0"
"sebastian/diff": "~1.2",
"sebastian/exporter": "~1.2"
},
"require-dev": {
"phpunit/phpunit": "~4.1"
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.1.x-dev"
}
},
"autoload": {
@ -787,7 +890,7 @@
"compare",
"equality"
],
"time": "2014-05-11 23:00:21"
"time": "2015-01-29 16:28:08"
},
{
"name": "sebastian/diff",
@ -893,28 +996,29 @@
},
{
"name": "sebastian/exporter",
"version": "1.0.2",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0"
"reference": "84839970d05254c73cde183a721c7af13aede943"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943",
"reference": "84839970d05254c73cde183a721c7af13aede943",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": ">=5.3.3",
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.2.x-dev"
}
},
"autoload": {
@ -954,20 +1058,124 @@
"export",
"exporter"
],
"time": "2014-09-10 00:51:36"
"time": "2015-01-27 07:23:06"
},
{
"name": "sebastian/version",
"version": "1.0.3",
"name": "sebastian/global-state",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
"reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43"
"url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
"reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
"reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"suggest": {
"ext-uopz": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Snapshotting of global state",
"homepage": "http://www.github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
"time": "2014-10-06 09:23:50"
},
{
"name": "sebastian/recursion-context",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "3989662bbb30a29d20d9faa04a846af79b276252"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252",
"reference": "3989662bbb30a29d20d9faa04a846af79b276252",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2015-01-24 09:48:32"
},
{
"name": "sebastian/version",
"version": "1.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
"reference": "a77d9123f8e809db3fbdea15038c27a95da4058b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b",
"reference": "a77d9123f8e809db3fbdea15038c27a95da4058b",
"shasum": ""
},
"type": "library",
@ -989,7 +1197,7 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2014-03-07 15:35:33"
"time": "2014-12-15 14:25:24"
},
{
"name": "squizlabs/php_codesniffer",
@ -1068,17 +1276,17 @@
},
{
"name": "symfony/console",
"version": "v2.6.0",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "d3bac228fd7a2aac9193e241b239880b3ba39a10"
"reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/d3bac228fd7a2aac9193e241b239880b3ba39a10",
"reference": "d3bac228fd7a2aac9193e241b239880b3ba39a10",
"url": "https://api.github.com/repos/symfony/Console/zipball/e44154bfe3e41e8267d7a3794cd9da9a51cfac34",
"reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34",
"shasum": ""
},
"require": {
@ -1121,21 +1329,21 @@
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
"time": "2014-11-20 13:24:23"
"time": "2015-01-25 04:39:26"
},
{
"name": "symfony/filesystem",
"version": "v2.6.0",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
"reference": "6f7c7e42f20ee200d8ac5d2ec1d2a524138305e0"
"reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/6f7c7e42f20ee200d8ac5d2ec1d2a524138305e0",
"reference": "6f7c7e42f20ee200d8ac5d2ec1d2a524138305e0",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/a1f566d1f92e142fa1593f4555d6d89e3044a9b7",
"reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7",
"shasum": ""
},
"require": {
@ -1168,21 +1376,21 @@
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com",
"time": "2014-11-16 17:28:09"
"time": "2015-01-03 21:13:09"
},
{
"name": "symfony/finder",
"version": "v2.6.0",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",
"url": "https://github.com/symfony/Finder.git",
"reference": "d574347c652a14cfee0349f744c7880e1d9029fd"
"reference": "16513333bca64186c01609961a2bb1b95b5e1355"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Finder/zipball/d574347c652a14cfee0349f744c7880e1d9029fd",
"reference": "d574347c652a14cfee0349f744c7880e1d9029fd",
"url": "https://api.github.com/repos/symfony/Finder/zipball/16513333bca64186c01609961a2bb1b95b5e1355",
"reference": "16513333bca64186c01609961a2bb1b95b5e1355",
"shasum": ""
},
"require": {
@ -1215,21 +1423,21 @@
],
"description": "Symfony Finder Component",
"homepage": "http://symfony.com",
"time": "2014-11-28 10:00:40"
"time": "2015-01-03 08:01:59"
},
{
"name": "symfony/process",
"version": "v2.6.0",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Process",
"source": {
"type": "git",
"url": "https://github.com/symfony/Process.git",
"reference": "dc88f75d1c07791e5733f90be747961dce26cf05"
"reference": "ecfc23e89d9967999fa5f60a1e9af7384396e9ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Process/zipball/dc88f75d1c07791e5733f90be747961dce26cf05",
"reference": "dc88f75d1c07791e5733f90be747961dce26cf05",
"url": "https://api.github.com/repos/symfony/Process/zipball/ecfc23e89d9967999fa5f60a1e9af7384396e9ae",
"reference": "ecfc23e89d9967999fa5f60a1e9af7384396e9ae",
"shasum": ""
},
"require": {
@ -1262,21 +1470,21 @@
],
"description": "Symfony Process Component",
"homepage": "http://symfony.com",
"time": "2014-11-04 14:29:39"
"time": "2015-01-25 04:39:26"
},
{
"name": "symfony/yaml",
"version": "v2.6.0",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "51c845cf3e4bfc182d1d5c05ed1c7338361d86f8"
"reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/51c845cf3e4bfc182d1d5c05ed1c7338361d86f8",
"reference": "51c845cf3e4bfc182d1d5c05ed1c7338361d86f8",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8",
"reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8",
"shasum": ""
},
"require": {
@ -1309,20 +1517,20 @@
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"time": "2014-11-20 13:24:23"
"time": "2015-01-25 04:39:26"
},
{
"name": "twig/twig",
"version": "v1.16.2",
"version": "v1.18.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "42f758d9fe2146d1f0470604fc05ee43580873fc"
"reference": "4cf7464348e7f9893a93f7096a90b73722be99cf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/42f758d9fe2146d1f0470604fc05ee43580873fc",
"reference": "42f758d9fe2146d1f0470604fc05ee43580873fc",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/4cf7464348e7f9893a93f7096a90b73722be99cf",
"reference": "4cf7464348e7f9893a93f7096a90b73722be99cf",
"shasum": ""
},
"require": {
@ -1331,7 +1539,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.16-dev"
"dev-master": "1.18-dev"
}
},
"autoload": {
@ -1357,7 +1565,7 @@
},
{
"name": "Twig Team",
"homepage": "https://github.com/fabpot/Twig/graphs/contributors",
"homepage": "http://twig.sensiolabs.org/contributors",
"role": "Contributors"
}
],
@ -1366,7 +1574,7 @@
"keywords": [
"templating"
],
"time": "2014-10-17 12:53:44"
"time": "2015-01-25 17:32:08"
}
],
"aliases": [],

View File

@ -5,7 +5,11 @@
*
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
* PHP version 5
*
* NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
* to save one include_once().
*
* If {@link \phpseclib\Crypt\AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
* {@link \phpseclib\Crypt\AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
@ -56,15 +60,6 @@ use phpseclib\Crypt\Rijndael;
*/
class AES extends Rijndael
{
/**
* The namespace used by the cipher for its constants.
*
* @see \phpseclib\Crypt\Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'AES';
/**
* Dummy function
*
@ -127,7 +122,7 @@ class AES extends Rijndael
default:
$this->key_size = 32;
}
$this->_setupEngine();
$this->_setEngine();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
* PHP version 5
*
* Useful resources are as follows:
*
@ -68,15 +68,6 @@ class Blowfish extends Base
*/
var $password_key_size = 56;
/**
* The namespace used by the cipher for its constants.
*
* @see \phpseclib\Crypt\Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'BLOWFISH';
/**
* The mcrypt specific name of the cipher
*
@ -98,7 +89,7 @@ class Blowfish extends Base
/**
* The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
*
* S-Box 1
* S-Box 0
*
* @access private
* @var array
@ -319,6 +310,29 @@ class Blowfish extends Base
parent::setKey($key);
}
/**
* Test for engine validity
*
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
*
* @see \phpseclib\Crypt\Base::isValidEngine()
* @param Integer $engine
* @access public
* @return Boolean
*/
function isValidEngine($engine)
{
if ($engine == self::ENGINE_OPENSSL) {
if (strlen($this->key) != 16) {
return false;
}
$this->cipher_name_openssl_ecb = 'bf-ecb';
$this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
}
return parent::isValidEngine($engine);
}
/**
* Setup the key (expansion)
*
@ -396,17 +410,17 @@ class Blowfish extends Base
$r = $in[2];
for ($i = 0; $i < 16; $i+= 2) {
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= $p[$i + 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
$r^= $p[$i + 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
}
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
}
@ -443,7 +457,6 @@ class Blowfish extends Base
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
}
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
}
@ -458,15 +471,14 @@ class Blowfish extends Base
$lambda_functions =& self::_getLambdaFunctions();
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10);
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
switch (true) {
case $gen_hi_opt_code:
$code_hash = md5(str_pad("Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
$code_hash = "Blowfish, {$this->mode}";
// Generation of a unique hash for our generated code
$code_hash = "Crypt_Blowfish, {$this->mode}";
if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
if (!isset($lambda_functions[$code_hash])) {

View File

@ -5,7 +5,7 @@
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
* PHP version 5
*
* Useful resources are as follows:
*
@ -97,15 +97,6 @@ class DES extends Base
*/
var $password_key_size = 8;
/**
* The namespace used by the cipher for its constants.
*
* @see \phpseclib\Crypt\Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'DES';
/**
* The mcrypt specific name of the cipher
*
@ -115,6 +106,21 @@ class DES extends Base
*/
var $cipher_name_mcrypt = 'des';
/**
* The OpenSSL names of the cipher / modes
*
* @see \phpseclib\Crypt\Base::openssl_mode_names
* @var Array
* @access private
*/
var $openssl_mode_names = array(
self::MODE_ECB => 'des-ecb',
self::MODE_CBC => 'des-cbc',
self::MODE_CFB => 'des-cfb',
self::MODE_OFB => 'des-ofb'
// self::MODE_CTR is undefined for DES
);
/**
* Optimizing value while CFB-encrypting
*
@ -585,6 +591,28 @@ class DES extends Base
0x00000820, 0x00020020, 0x08000000, 0x08020800
);
/**
* Test for engine validity
*
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
*
* @see \phpseclib\Crypt\Base::isValidEngine()
* @param Integer $engine
* @access public
* @return Boolean
*/
function isValidEngine($engine)
{
if ($this->key_size_max == 8) {
if ($engine == self::ENGINE_OPENSSL) {
$this->cipher_name_openssl_ecb = 'des-ecb';
$this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
}
}
return parent::isValidEngine($engine);
}
/**
* Sets the key.
*
@ -1282,21 +1310,20 @@ class DES extends Base
$des_rounds = $this->des_rounds;
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// (Currently, for Crypt_DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
// (Currently, for Crypt_TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
// Generation of a uniqe hash for our generated code
switch (true) {
case $gen_hi_opt_code:
// For hi-optimized code, we create for each combination of
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
$code_hash = md5(str_pad("DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
// After max 10 hi-optimized functions, we create generic
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
// Currently 2 * 5 generic functions will be then max. possible.
$code_hash = "DES, $des_rounds, {$this->mode}";
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
if ($gen_hi_opt_code) {
// For hi-optimized code, we create for each combination of
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
// After max 10 hi-optimized functions, we create generic
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
// Currently 2 * 5 generic functions will be then max. possible.
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
// Is there a re-usable $lambda_functions in there? If not, we have to create it.

View File

@ -10,7 +10,7 @@
* If {@link \phpseclib\Crypt\Hash::setKey() setKey()} is called, {@link \phpseclib\Crypt\Hash::hash() hash()} will return the HMAC as opposed to
* the hash. If no valid algorithm is provided, sha1 will be used.
*
* PHP versions 4 and 5
* PHP version 5
*
* {@internal The variable names are the same as those in
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}

View File

@ -5,7 +5,7 @@
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
* PHP version 5
*
* Useful resources are as follows:
*
@ -62,7 +62,19 @@ class RC2 extends Base
* @var String
* @access private
*/
var $key = "\0";
var $key;
/**
* The Original (unpadded) Key
*
* @see \phpseclib\Crypt\Base::key
* @see setKey()
* @see encrypt()
* @see decrypt()
* @var String
* @access private
*/
var $orig_key;
/**
* The default password key_size used by setPassword()
@ -74,15 +86,6 @@ class RC2 extends Base
*/
var $password_key_size = 16; // = 128 bits
/**
* The namespace used by the cipher for its constants.
*
* @see \phpseclib\Crypt\Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'RC2';
/**
* The mcrypt specific name of the cipher
*
@ -113,6 +116,17 @@ class RC2 extends Base
*/
var $default_key_length = 1024;
/**
* The key length in bits.
*
* @see \phpseclib\Crypt\RC2::isValidEnine()
* @see \phpseclib\Crypt\RC2::setKey()
* @var Integer
* @access private
* @internal Should be in range [1..1024].
*/
var $current_key_length;
/**
* The Key Schedule
*
@ -240,32 +254,27 @@ class RC2 extends Base
);
/**
* Default Constructor.
* Test for engine validity
*
* Determines whether or not the mcrypt extension should be used.
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
*
* $mode could be:
*
* - \phpseclib\Crypt\Base::MODE_ECB
*
* - \phpseclib\Crypt\Base::MODE_CBC
*
* - \phpseclib\Crypt\Base::MODE_CTR
*
* - \phpseclib\Crypt\Base::MODE_CFB
*
* - \phpseclib\Crypt\Base::MODE_OFB
*
* If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
*
* @see \phpseclib\Crypt\Base::__construct()
* @param optional Integer $mode
* @see \phpseclib\Crypt\Base::Crypt_Base()
* @param Integer $engine
* @access public
* @return Boolean
*/
function __construct($mode = Base::MODE_CBC)
function isValidEngine($engine)
{
parent::__construct($mode);
$this->setKey('');
switch ($engine) {
case self::ENGINE_OPENSSL:
if ($this->current_key_length != 128 || strlen($this->orig_key) != 16) {
return false;
}
$this->cipher_name_openssl_ecb = 'rc2-ecb';
$this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode();
}
return parent::isValidEngine($engine);
}
/**
@ -299,15 +308,18 @@ class RC2 extends Base
* @see \phpseclib\Crypt\Base::setKey()
* @access public
* @param String $key
* @param Integer $t1 optional Effective key length in bits.
* @param Integer $t1 optional Effective key length in bits.
*/
function setKey($key, $t1 = 0)
{
$this->orig_key = $key;
if ($t1 <= 0) {
$t1 = $this->default_key_length;
} else if ($t1 > 1024) {
$t1 = 1024;
}
$this->current_key_length = $t1;
// Key byte count should be 1..128.
$key = strlen($key) ? substr($key, 0, 128) : "\x00";
$t = strlen($key);
@ -340,6 +352,52 @@ class RC2 extends Base
parent::setKey(call_user_func_array('pack', $l));
}
/**
* Encrypts a message.
*
* Mostly a wrapper for Crypt_Base::encrypt, with some additional OpenSSL handling code
*
* @see decrypt()
* @access public
* @param String $plaintext
* @return String $ciphertext
*/
function encrypt($plaintext)
{
if ($this->engine == self::ENGINE_OPENSSL) {
$temp = $this->key;
$this->key = $this->orig_key;
$result = parent::encrypt($plaintext);
$this->key = $temp;
return $result;
}
return parent::encrypt($plaintext);
}
/**
* Decrypts a message.
*
* Mostly a wrapper for Crypt_Base::decrypt, with some additional OpenSSL handling code
*
* @see encrypt()
* @access public
* @param String $ciphertext
* @return String $plaintext
*/
function decrypt($ciphertext)
{
if ($this->engine == self::ENGINE_OPENSSL) {
$temp = $this->key;
$this->key = $this->orig_key;
$result = parent::decrypt($ciphertext);
$this->key = $temp;
return $result;
}
return parent::encrypt($ciphertext);
}
/**
* Encrypts a block
*
@ -430,6 +488,21 @@ class RC2 extends Base
return pack('vvvv', $r0, $r1, $r2, $r3);
}
/**
* Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine
*
* @see \phpseclib\Crypt\Base::_setupMcrypt()
* @access private
*/
function _setupMcrypt()
{
if (!isset($this->key)) {
$this->setKey('');
}
parent::_setupMcrypt();
}
/**
* Creates the key schedule
*
@ -438,6 +511,10 @@ class RC2 extends Base
*/
function _setupKey()
{
if (!isset($this->key)) {
$this->setKey('');
}
// Key has already been expanded in \phpseclib\Crypt\RC2::setKey():
// Only the first value must be altered.
$l = unpack('Ca/Cb/v*', $this->key);
@ -460,14 +537,14 @@ class RC2 extends Base
// The first 10 generated $lambda_functions will use the $keys hardcoded as integers
// for the mixing rounds, for better inline crypt performance [~20% faster].
// But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
$keys = $this->keys;
if (count($lambda_functions) >= 10) {
foreach ($this->keys as $k => $v) {
$keys[$k] = '$keys[' . $k . ']';
}
}
// (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
$code_hash = md5(str_pad("RC2, {$this->mode}, ", 32, "\0") . implode(',', $keys));
// Generation of a uniqe hash for our generated code
$code_hash = "Crypt_RC2, {$this->mode}";
if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
// Is there a re-usable $lambda_functions in there?
// If not, we have to create it.
@ -475,6 +552,16 @@ class RC2 extends Base
// Init code for both, encrypt and decrypt.
$init_crypt = '$keys = $self->keys;';
switch (true) {
case $gen_hi_opt_code:
$keys = $this->keys;
default:
$keys = array();
foreach ($this->keys as $k => $v) {
$keys[$k] = '$keys[' . $k . ']';
}
}
// $in is the current 8 bytes block which has to be en/decrypt
$encrypt_block = $decrypt_block = '
$in = unpack("v4", $in);

View File

@ -5,7 +5,7 @@
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
* PHP version 5
*
* Useful resources are as follows:
*
@ -85,15 +85,6 @@ class RC4 extends Base
*/
var $password_key_size = 128; // = 1024 bits
/**
* The namespace used by the cipher for its constants.
*
* @see \phpseclib\Crypt\Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'RC4';
/**
* The mcrypt specific name of the cipher
*
@ -193,7 +184,7 @@ class RC4 extends Base
*/
function encrypt($plaintext)
{
if ($this->engine == Base::ENGINE_MCRYPT) {
if ($this->engine != Base::ENGINE_INTERNAL) {
return parent::encrypt($plaintext);
}
return $this->_crypt($plaintext, self::ENCRYPT);
@ -213,7 +204,7 @@ class RC4 extends Base
*/
function decrypt($ciphertext)
{
if ($this->engine == Base::ENGINE_MCRYPT) {
if ($this->engine != Base::ENGINE_INTERNAL) {
return parent::decrypt($ciphertext);
}
return $this->_crypt($ciphertext, self::DECRYPT);

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
*
* PHP versions 4 and 5
* PHP version 5
*
* Here's an example of how to encrypt and decrypt text with this library:
* <code>

View File

@ -3,7 +3,7 @@
/**
* Random Number Generator
*
* PHP versions 4 and 5
* PHP version 5
*
* Here's a short example of how to use this library:
* <code>

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
*
* Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
*
* PHP versions 4 and 5
* PHP version 5
*
* Here's a short example of how to use this library:
* <code>
@ -84,16 +84,6 @@ class TripleDES extends DES
*/
var $password_default_salt = 'phpseclib';
/**
* The namespace used by the cipher for its constants.
*
* @see \phpseclib\Crypt\DES::const_namespace
* @see \phpseclib\Crypt\Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'DES';
/**
* The mcrypt specific name of the cipher
*
@ -194,6 +184,27 @@ class TripleDES extends DES
}
}
/**
* Test for engine validity
*
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
*
* @see \phpseclib\Crypt\Base::Crypt_Base()
* @param Integer $engine
* @access public
* @return Boolean
*/
function isValidEngine($engine)
{
if ($engine == self::ENGINE_OPENSSL) {
$this->cipher_name_openssl_ecb = 'des-ede3';
$mode = $this->_openssl_translate_mode();
$this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
}
return parent::isValidEngine($engine);
}
/**
* Sets the initialization vector. (optional)
*
@ -236,7 +247,7 @@ class TripleDES extends DES
$key = str_pad(substr($key, 0, 24), 24, chr(0));
// if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
// http://php.net/function.mcrypt-encrypt#47973
//$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
} else {
$key = str_pad($key, 8, chr(0));
}
@ -406,4 +417,24 @@ class TripleDES extends DES
// setup our key
parent::_setupKey();
}
/**
* Sets the internal crypt engine
*
* @see \phpseclib\Crypt\Base::Crypt_Base()
* @see \phpseclib\Crypt\Base::setPreferredEngine()
* @param Integer $engine
* @access public
* @return Integer
*/
function setPreferredEngine($engine)
{
if ($this->mode_3cbc) {
$this->des[0]->setPreferredEngine($engine);
$this->des[1]->setPreferredEngine($engine);
$this->des[2]->setPreferredEngine($engine);
}
return parent::setPreferredEngine($engine);
}
}

View File

@ -5,7 +5,7 @@
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
* PHP version 5
*
* Useful resources are as follows:
*
@ -49,15 +49,6 @@ use phpseclib\Crypt\Base;
*/
class Twofish extends Base
{
/**
* The namespace used by the cipher for its constants.
*
* @see \phpseclib\Crypt\Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'TWOFISH';
/**
* The mcrypt specific name of the cipher
*
@ -678,21 +669,19 @@ class Twofish extends Base
$lambda_functions =& self::_getLambdaFunctions();
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
// (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
switch (true) {
case $gen_hi_opt_code:
$code_hash = md5(str_pad("Twofish, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
$code_hash = "Twofish, {$this->mode}";
// Generation of a uniqe hash for our generated code
$code_hash = "Crypt_Twofish, {$this->mode}";
if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
if (!isset($lambda_functions[$code_hash])) {
switch (true) {
case $gen_hi_opt_code:
$K = $this->K;
$init_crypt = '
static $S0, $S1, $S2, $S3;
if (!$S0) {
@ -710,7 +699,6 @@ class Twofish extends Base
for ($i = 0; $i < 40; ++$i) {
$K[] = '$K_' . $i;
}
$init_crypt = '
$S0 = $self->S0;
$S1 = $self->S1;

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP ANSI Decoder
*
* PHP versions 4 and 5
* PHP version 5
*
* If you call read() in \phpseclib\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
* They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP ASN.1 Parser
*
* PHP versions 4 and 5
* PHP version 5
*
* ASN.1 provides the semantics for data encoded using various schemes. The most commonly
* utilized scheme is DER or the "Distinguished Encoding Rules". PEM's are base64 encoded

View File

@ -2,7 +2,7 @@
/**
* Pure-PHP ASN.1 Parser
*
* PHP versions 4 and 5
* PHP version 5
*
* @category File
* @package ASN1

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP X.509 Parser
*
* PHP versions 4 and 5
* PHP version 5
*
* Encode and decode X.509 certificates.
*
@ -1568,7 +1568,7 @@ class X509
}
}
}
} elseif ($map) {
} else {
$value = base64_encode($value);
}
}
@ -1591,6 +1591,10 @@ class X509
if (is_array($extensions)) {
$size = count($extensions);
for ($i = 0; $i < $size; $i++) {
if ($extensions[$i] instanceof Element) {
continue;
}
$id = $extensions[$i]['extnId'];
$value = &$extensions[$i]['extnValue'];

View File

@ -6,7 +6,7 @@
* Supports base-2, base-10, base-16, and base-256 numbers. Uses the GMP or BCMath extensions, if available,
* and an internal implementation, otherwise.
*
* PHP versions 4 and 5
* PHP version 5
*
* {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the
* {@link self::MODE_INTERNAL self::MODE_INTERNAL} mode)

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP implementation of SCP.
*
* PHP versions 4 and 5
* PHP version 5
*
* The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
*

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP implementation of SFTP.
*
* PHP versions 4 and 5
* PHP version 5
*
* Currently only supports SFTPv2 and v3, which, according to wikipedia.org, "is the most widely used version,
* implemented by the popular OpenSSH SFTP server". If you want SFTPv4/5/6 support, provide me with access

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP implementation of SSHv1.
*
* PHP versions 4 and 5
* PHP version 5
*
* Here's a short example of how to use this library:
* <code>

View File

@ -3,7 +3,7 @@
/**
* Pure-PHP implementation of SSHv2.
*
* PHP versions 4 and 5
* PHP version 5
*
* Here are some examples of how to use this library:
* <code>
@ -100,9 +100,10 @@ class SSH2
* @see \phpseclib\Net\SSH2::_get_channel_packet()
* @access private
*/
const CHANNEL_EXEC = 0; // PuTTy uses 0x100
const CHANNEL_SHELL = 1;
const CHANNEL_SUBSYSTEM = 2;
const CHANNEL_EXEC = 0; // PuTTy uses 0x100
const CHANNEL_SHELL = 1;
const CHANNEL_SUBSYSTEM = 2;
const CHANNEL_AGENT_FORWARD = 3;
/**#@-*/
/**#@+
@ -798,21 +799,6 @@ class SSH2
*/
var $port;
/**
* Timeout for initial connection
*
* Set by the constructor call. Calling setTimeout() is optional. If it's not called functions like
* exec() won't timeout unless some PHP setting forces it too. The timeout specified in the constructor,
* however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be
* 10 seconds. It is used by fsockopen() and the initial stream_select in that function.
*
* @see \phpseclib\Net\SSH2::__construct()
* @see \phpseclib\Net\SSH2::_connect()
* @var Integer
* @access private
*/
var $connectionTimeout;
/**
* Number of columns for terminal window size
*
@ -835,6 +821,24 @@ class SSH2
*/
var $windowRows = 24;
/**
* Crypto Engine
*
* @see Net_SSH2::setCryptoEngine()
* @see Net_SSH2::_key_exchange()
* @var Integer
* @access private
*/
var $crypto_engine = false;
/**
* A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
*
* @var System_SSH_Agent
* @access private
*/
var $agent;
/**
* Default Constructor.
*
@ -919,7 +923,21 @@ class SSH2
$this->host = $host;
$this->port = $port;
$this->connectionTimeout = $timeout;
$this->timeout = $timeout;
}
/**
* Set Crypto Engine Mode
*
* Possible $engine values:
* CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
*
* @param Integer $engine
* @access private
*/
function setCryptoEngine($engine)
{
$this->crypto_engine = $engine;
}
/**
@ -936,36 +954,24 @@ class SSH2
$this->bitmap |= self::MASK_CONSTRUCTOR;
$timeout = $this->connectionTimeout;
$this->curTimeout = $this->timeout;
$host = $this->host . ':' . $this->port;
$this->last_packet = microtime(true);
$start = microtime(true);
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $timeout);
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
if (!$this->fsock) {
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
return false;
}
$elapsed = microtime(true) - $start;
$timeout-= $elapsed;
$this->curTimeout-= $elapsed;
if ($timeout <= 0) {
user_error("Cannot connect to $host. Timeout error");
return false;
}
$read = array($this->fsock);
$write = $except = null;
$sec = floor($timeout);
$usec = 1000000 * ($timeout - $sec);
// on windows this returns a "Warning: Invalid CRT parameters detected" error
// the !count() is done as a workaround for <https://bugs.php.net/42682>
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
user_error("Cannot connect to $host. Banner timeout");
if ($this->curTimeout <= 0) {
$this->is_timeout = true;
return false;
}
@ -983,6 +989,27 @@ class SSH2
$extra.= $temp;
$temp = '';
}
if ($this->curTimeout) {
if ($this->curTimeout < 0) {
$this->is_timeout = true;
return false;
}
$read = array($this->fsock);
$write = $except = null;
$start = microtime(true);
$sec = floor($this->curTimeout);
$usec = 1000000 * ($this->curTimeout - $sec);
// on windows this returns a "Warning: Invalid CRT parameters detected" error
// the !count() is done as a workaround for <https://bugs.php.net/42682>
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
$this->is_timeout = true;
return false;
}
$elapsed = microtime(true) - $start;
$this->curTimeout-= $elapsed;
}
$temp.= fgets($this->fsock, 255);
}
@ -1043,7 +1070,9 @@ class SSH2
$identifier = 'SSH-2.0-phpseclib_0.3';
$ext = array();
if (extension_loaded('mcrypt')) {
if (extension_loaded('openssl')) {
$ext[] = 'openssl';
} elseif (extension_loaded('mcrypt')) {
$ext[] = 'mcrypt';
}
@ -1085,7 +1114,7 @@ class SSH2
'arcfour256',
'arcfour128',
//'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
//'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
// CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
@ -1113,9 +1142,18 @@ class SSH2
'3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
'3des-cbc', // REQUIRED three-key 3DES in CBC mode
//'none' // OPTIONAL no encryption; NOT RECOMMENDED
//'none' // OPTIONAL no encryption; NOT RECOMMENDED
);
if (extension_loaded('openssl') && !extension_loaded('mcrypt')) {
// OpenSSL does not support arcfour256 in any capacity and arcfour128 / arcfour support is limited to
// instances that do not use continuous buffers
$encryption_algorithms = array_diff(
$encryption_algorithms,
array('arcfour256', 'arcfour128', 'arcfour')
);
}
if (class_exists('\phpseclib\Crypt\RC4') === false) {
$encryption_algorithms = array_diff(
$encryption_algorithms,
@ -1573,6 +1611,9 @@ class SSH2
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
if ($this->encrypt) {
if ($this->crypto_engine) {
$this->encrypt->setEngine($this->crypto_engine);
}
$this->encrypt->enableContinuousBuffer();
$this->encrypt->disablePadding();
@ -1590,6 +1631,9 @@ class SSH2
}
if ($this->decrypt) {
if ($this->crypto_engine) {
$this->decrypt->setEngine($this->crypto_engine);
}
$this->decrypt->enableContinuousBuffer();
$this->decrypt->disablePadding();
@ -2055,6 +2099,7 @@ class SSH2
*/
function _ssh_agent_login($username, $agent)
{
$this->agent = $agent;
$keys = $agent->requestIdentities();
foreach ($keys as $key) {
if ($this->_privatekey_login($username, $key)) {
@ -2234,6 +2279,7 @@ class SSH2
if (!$this->_send_binary_packet($packet)) {
return false;
}
$response = $this->_get_binary_packet();
if ($response === false) {
user_error('Connection closed by server');
@ -2400,6 +2446,24 @@ class SSH2
}
}
/**
* Return an available open channel
*
* @return Integer
* @access public
*/
function _get_open_channel()
{
$channel = self::CHANNEL_EXEC;
do {
if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) {
return $channel;
}
} while ($channel++ < self::CHANNEL_SUBSYSTEM);
return false;
}
/**
* Returns the output of an interactive shell
*
@ -2758,18 +2822,41 @@ class SSH2
case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
$this->_string_shift($payload, 1);
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
$this->errors[] = 'SSH_MSG_CHANNEL_OPEN: ' . utf8_decode($this->_string_shift($payload, $length));
$this->_string_shift($payload, 4); // skip over client channel
$data = $this->_string_shift($payload, $length);
extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
switch($data) {
case 'auth-agent':
case 'auth-agent@openssh.com':
if (isset($this->agent)) {
$new_channel = self::CHANNEL_AGENT_FORWARD;
$packet = pack('CN3a*Na*',
NET_SSH2_MSG_REQUEST_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, 0, '', 0, '');
extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4)));
extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4)));
if (!$this->_send_binary_packet($packet)) {
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
$this->packet_size_client_to_server[$new_channel] = $remote_window_size;
$this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size;
$this->window_size_client_to_server[$new_channel] = $this->window_size;
$packet_size = 0x4000;
$packet = pack('CN4',
NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, $server_channel, $new_channel, $packet_size, $packet_size);
$this->server_channels[$new_channel] = $server_channel;
$this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION;
if (!$this->_send_binary_packet($packet)) {
return false;
}
}
break;
default:
$packet = pack('CN3a*Na*',
NET_SSH2_MSG_REQUEST_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, 0, '', 0, '');
if (!$this->_send_binary_packet($packet)) {
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
}
$payload = $this->_get_binary_packet();
break;
case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
@ -2906,48 +2993,59 @@ class SSH2
return '';
}
extract(unpack('Ctype/Nchannel', $this->_string_shift($response, 5)));
extract(unpack('Ctype', $this->_string_shift($response, 1)));
$this->window_size_server_to_client[$channel]-= strlen($response);
// resize the window, if appropriate
if ($this->window_size_server_to_client[$channel] < 0) {
$packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_size);
if (!$this->_send_binary_packet($packet)) {
return false;
}
$this->window_size_server_to_client[$channel]+= $this->window_size;
if ($type == NET_SSH2_MSG_CHANNEL_OPEN) {
extract(unpack('Nlength', $this->_string_shift($response, 4)));
} else {
extract(unpack('Nchannel', $this->_string_shift($response, 4)));
}
switch ($this->channel_status[$channel]) {
case NET_SSH2_MSG_CHANNEL_OPEN:
switch ($type) {
case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));
$this->server_channels[$channel] = $server_channel;
extract(unpack('Nwindow_size', $this->_string_shift($response, 4)));
$this->window_size_client_to_server[$channel] = $window_size;
$temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));
$this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
return $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
default:
user_error('Unable to open channel');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
// will not be setup yet on incoming channel open request
if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) {
$this->window_size_server_to_client[$channel]-= strlen($response);
// resize the window, if appropriate
if ($this->window_size_server_to_client[$channel] < 0) {
$packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_size);
if (!$this->_send_binary_packet($packet)) {
return false;
}
break;
case NET_SSH2_MSG_CHANNEL_REQUEST:
switch ($type) {
case NET_SSH2_MSG_CHANNEL_SUCCESS:
return true;
case NET_SSH2_MSG_CHANNEL_FAILURE:
return false;
default:
user_error('Unable to fulfill channel request');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
case NET_SSH2_MSG_CHANNEL_CLOSE:
return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
$this->window_size_server_to_client[$channel]+= $this->window_size;
}
switch ($this->channel_status[$channel]) {
case NET_SSH2_MSG_CHANNEL_OPEN:
switch ($type) {
case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));
$this->server_channels[$channel] = $server_channel;
extract(unpack('Nwindow_size', $this->_string_shift($response, 4)));
$this->window_size_client_to_server[$channel] = $window_size;
$temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));
$this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
$result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
$this->_on_channel_open();
return $result;
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
default:
user_error('Unable to open channel');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
break;
case NET_SSH2_MSG_CHANNEL_REQUEST:
switch ($type) {
case NET_SSH2_MSG_CHANNEL_SUCCESS:
return true;
case NET_SSH2_MSG_CHANNEL_FAILURE:
return false;
default:
user_error('Unable to fulfill channel request');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
case NET_SSH2_MSG_CHANNEL_CLOSE:
return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
}
}
// ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA
@ -2965,6 +3063,15 @@ class SSH2
*/
extract(unpack('Nlength', $this->_string_shift($response, 4)));
$data = $this->_string_shift($response, $length);
if ($channel == self::CHANNEL_AGENT_FORWARD) {
$agent_response = $this->agent->_forward_data($data);
if (!is_bool($agent_response)) {
$this->_send_channel_packet($channel, $agent_response);
}
break;
}
if ($client_channel == $channel) {
return $data;
}
@ -3203,7 +3310,7 @@ class SSH2
$this->bitmap^= self::MASK_WINDOW_ADJUST;
// using an invalid channel will let the buffers be built up for the valid channels
$this->_get_channel_packet(-1);
$this->bitmap^= NET_SSH2_MASK_WINDOW_ADJUST;
$this->bitmap^= self::MASK_WINDOW_ADJUST;
}
/* The maximum amount of data allowed is determined by the maximum
@ -3401,6 +3508,22 @@ class SSH2
return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT);
}
/**
* Helper function for agent->_on_channel_open()
*
* Used when channels are created to inform agent
* of said channel opening. Must be called after
* channel open confirmation received
*
* @access private
*/
function _on_channel_open()
{
if (isset($this->agent)) {
$this->agent->_on_channel_open($this);
}
}
/**
* Returns all errors
*

View File

@ -1,8 +1,9 @@
<?php
/**
* Pure-PHP ssh-agent client.
*
* PHP versions 4 and 5
* PHP version 5
*
* Here are some examples of how to use this library:
* <code>
@ -61,6 +62,19 @@ class Agent
const SSH_AGENT_SIGN_RESPONSE = 14;
/**#@-*/
/**@+
* Agent forwarding status
*
* @access private
*/
// no forwarding requested and not active
const FORWARD_NONE = 0;
// request agent forwarding when opportune
const FORWARD_REQUEST = 1;
// forwarding has been request and is active
const FORWARD_ACTIVE = 2;
/**#@-*/
/**
* Unused
*/
@ -74,6 +88,29 @@ class Agent
*/
var $fsock;
/**
* Agent forwarding status
*
* @access private
*/
var $forward_status = self::FORWARD_NONE;
/**
* Buffer for accumulating forwarded authentication
* agent data arriving on SSH data channel destined
* for agent unix socket
*
* @access private
*/
var $socket_buffer = '';
/**
* Tracking the number of bytes we are expecting
* to arrive for the agent socket on the SSH data
* channel
*/
var $expected_bytes = 0;
/**
* Default Constructor
*
@ -156,4 +193,107 @@ class Agent
return $identities;
}
/**
* Signal that agent forwarding should
* be requested when a channel is opened
*
* @param Net_SSH2 $ssh
* @return Boolean
* @access public
*/
function startSSHForwarding($ssh)
{
if ($this->forward_status == self::FORWARD_NONE) {
$this->forward_status = self::FORWARD_REQUEST;
}
}
/**
* Request agent forwarding of remote server
*
* @param Net_SSH2 $ssh
* @return Boolean
* @access private
*/
function _request_forwarding($ssh)
{
$request_channel = $ssh->_get_open_channel();
if ($request_channel === false) {
return false;
}
$packet = pack('CNNa*C',
NET_SSH2_MSG_CHANNEL_REQUEST, $ssh->server_channels[$request_channel], strlen('auth-agent-req@openssh.com'), 'auth-agent-req@openssh.com', 1);
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST;
if (!$ssh->_send_binary_packet($packet)) {
return false;
}
$response = $ssh->_get_channel_packet($request_channel);
if ($response === false) {
return false;
}
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN;
$this->forward_status = self::FORWARD_ACTIVE;
return true;
}
/**
* On successful channel open
*
* This method is called upon successful channel
* open to give the SSH Agent an opportunity
* to take further action. i.e. request agent forwarding
*
* @param Net_SSH2 $ssh
* @access private
*/
function _on_channel_open($ssh)
{
if ($this->forward_status == self::FORWARD_REQUEST) {
$this->_request_forwarding($ssh);
}
}
/**
* Forward data to SSH Agent and return data reply
*
* @param String $data
* @return data from SSH Agent
* @access private
*/
function _forward_data($data)
{
if ($this->expected_bytes > 0) {
$this->socket_buffer.= $data;
$this->expected_bytes -= strlen($data);
} else {
$agent_data_bytes = current(unpack('N', $data));
$current_data_bytes = strlen($data);
$this->socket_buffer = $data;
if ($current_data_bytes != $agent_data_bytes + 4) {
$this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes;
return false;
}
}
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
user_error('Connection closed attempting to forward data to SSH agent');
}
$this->socket_buffer = '';
$this->expected_bytes = 0;
$agent_reply_bytes = current(unpack('N', fread($this->fsock, 4)));
$agent_reply_data = fread($this->fsock, $agent_reply_bytes);
$agent_reply_data = current(unpack('a*', $agent_reply_data));
return pack('Na*', $agent_reply_bytes, $agent_reply_data);
}
}

View File

@ -2,7 +2,7 @@
/**
* Pure-PHP ssh-agent client.
*
* PHP versions 4 and 5
* PHP version 5
*
* @category System
* @package SSH\Agent

View File

@ -16,17 +16,10 @@ class Functional_Net_SFTPLargeFileTest extends PhpseclibFunctionalTestCase
static public function setUpBeforeClass()
{
if (!extension_loaded('mcrypt')) {
self::markTestSkipped('This test depends on mcrypt for performance.');
if (!extension_loaded('mcrypt') && !extension_loaded('openssl')) {
self::markTestSkipped('This test depends on mcrypt or openssl for performance.');
}
parent::setUpBeforeClass();
self::ensureConstant('CRYPT_AES_MODE', Base::ENGINE_MCRYPT);
self::ensureConstant('CRYPT_BLOWFISH_MODE', Base::ENGINE_MCRYPT);
self::ensureConstant('CRYPT_DES_MODE', Base::ENGINE_MCRYPT);
self::ensureConstant('CRYPT_RC2_MODE', Base::ENGINE_MCRYPT);
self::ensureConstant('CRYPT_RC4_MODE', Base::ENGINE_MCRYPT);
self::ensureConstant('CRYPT_RIJNDAEL_MODE', Base::ENGINE_MCRYPT);
self::ensureConstant('CRYPT_TWOFISH_MODE', Base::ENGINE_MCRYPT);
}
public function setUp()

View File

@ -30,5 +30,26 @@ class Functional_Net_SSH2AgentTest extends PhpseclibFunctionalTestCase
$ssh->login($this->getEnv('SSH_USERNAME'), $agent),
'SSH2 login using Agent failed.'
);
return array('ssh' => $ssh, 'ssh-agent' => $agent);
}
/**
* @depends testAgentLogin
*/
public function testAgentForward($args)
{
$ssh = $args['ssh'];
$agent = $args['ssh-agent'];
$hostname = $this->getEnv('SSH_HOSTNAME');
$username = $this->getEnv('SSH_USERNAME');
$this->assertEquals($username, trim($ssh->exec('whoami')));
$agent->startSSHForwarding($ssh);
$this->assertEquals($username, trim($ssh->exec("ssh " . $username . "@" . $hostname . ' \'whoami\'')));
return $args;
}
}

View File

@ -9,11 +9,8 @@ use phpseclib\Crypt\Base;
class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase
{
static public function setUpBeforeClass()
protected function setUp()
{
parent::setUpBeforeClass();
self::ensureConstant('CRYPT_AES_MODE', Base::ENGINE_INTERNAL);
self::ensureConstant('CRYPT_RIJNDAEL_MODE', Base::ENGINE_INTERNAL);
$this->engine = Base::ENGINE_INTERNAL;
}
}

View File

@ -9,15 +9,8 @@ use phpseclib\Crypt\Base;
class Unit_Crypt_AES_McryptTest extends Unit_Crypt_AES_TestCase
{
static public function setUpBeforeClass()
protected function setUp()
{
if (!extension_loaded('mcrypt')) {
self::markTestSkipped('mcrypt extension is not available.');
}
parent::setUpBeforeClass();
self::ensureConstant('CRYPT_AES_MODE', Base::ENGINE_MCRYPT);
self::ensureConstant('CRYPT_RIJNDAEL_MODE', Base::ENGINE_MCRYPT);
$this->engine = Base::ENGINE_MCRYPT;
}
}

View File

@ -0,0 +1,16 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
class Unit_Crypt_AES_OpenSSLTest extends Unit_Crypt_AES_TestCase
{
protected function setUp()
{
$this->engine = Base::ENGINE_OPENSSL;
}
}

View File

@ -11,14 +11,21 @@ use phpseclib\Crypt\Rijndael;
abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
{
static public function setUpBeforeClass()
protected $engine;
private function _checkEngine($aes)
{
include_once 'Crypt/AES.php';
parent::setUpBeforeClass();
self::reRequireFile('Crypt/Rijndael.php');
self::reRequireFile('Crypt/AES.php');
if ($aes->getEngine() != $this->engine) {
$engine = 'internal';
switch ($this->engine) {
case Base::ENGINE_OPENSSL:
$engine = 'OpenSSL';
break;
case Base::ENGINE_MCRYPT:
$engine = 'mcrypt';
}
self::markTestSkipped('Unable to initialize ' . $engine . ' engine');
}
}
/**
@ -68,10 +75,13 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
public function testEncryptDecryptWithContinuousBuffer($mode, $plaintext, $iv, $key)
{
$aes = new AES($mode);
$aes->setPreferredEngine($this->engine);
$aes->enableContinuousBuffer();
$aes->setIV($iv);
$aes->setKey($key);
$this->_checkEngine($aes);
$actual = '';
for ($i = 0, $strlen = strlen($plaintext); $i < $strlen; ++$i) {
$actual .= $aes->decrypt($aes->encrypt($plaintext[$i]));
@ -89,8 +99,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
// https://web.archive.org/web/20070209120224/http://fp.gladman.plus.com/cryptography_technology/rijndael/aesdvec.zip
$aes = new Rijndael();
$aes->setPreferredEngine($this->engine);
$aes->disablePadding();
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael.
//$this->_checkEngine($aes); // should only work in internal mode
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
$this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880'));
}
@ -103,9 +115,221 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
// same as the above - just with a different ciphertext
$aes = new AES();
$aes->setPreferredEngine($this->engine);
$aes->disablePadding();
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits
$this->_checkEngine($aes);
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
$this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0'));
}
/**
* Produces all combinations of test values.
*
* @return array
*/
public function continuousBufferBatteryCombos()
{
$modes = array(
Base::MODE_CTR,
Base::MODE_OFB,
Base::MODE_CFB,
);
$combos = array(
array(16),
array(17),
array(1, 16),
array(3, 6, 7), // (3 to test the openssl_encrypt call and the buffer creation, 6 to test the exclusive use of the buffer and 7 to test the buffer's exhaustion and recreation)
array(15, 4), // (15 to test openssl_encrypt call and buffer creation and 4 to test something that spans multpile bloc
array(3, 6, 10, 16), // this is why the strlen check in the buffer-only code was needed
array(16, 16), // two full size blocks
array(3, 6, 7, 16), // partial block + full size block
array(16, 3, 6, 7),
// a few others just for fun
array(32,32),
array(31,31),
array(17,17),
array(99, 99)
);
$result = array();
// @codingStandardsIgnoreStart
foreach ($modes as $mode)
foreach ($combos as $combo)
foreach (array('encrypt', 'decrypt') as $op)
$result[] = array($op, $mode, $combo);
// @codingStandardsIgnoreEnd
return $result;
}
/**
* @dataProvider continuousBufferBatteryCombos
*/
public function testContinuousBufferBattery($op, $mode, $test)
{
$iv = str_repeat('x', 16);
$key = str_repeat('a', 16);
$aes = new AES($mode);
$aes->setPreferredEngine($this->engine);
$aes->setKey($key);
$aes->setIV($iv);
$this->_checkEngine($aes);
$str = '';
$result = '';
foreach ($test as $len) {
$temp = str_repeat('d', $len);
$str.= $temp;
}
$c1 = $aes->$op($str);
$aes = new AES($mode);
$aes->setPreferredEngine($this->engine);
$aes->enableContinuousBuffer();
$aes->setKey($key);
$aes->setIV($iv);
if (!$this->_checkEngine($aes)) {
return;
}
foreach ($test as $len) {
$temp = str_repeat('d', $len);
$output = $aes->$op($temp);
$result.= $output;
}
$c2 = $result;
$this->assertSame(bin2hex($c1), bin2hex($c2));
}
/**
* @dataProvider continuousBufferBatteryCombos
*/
// pretty much the same as testContinuousBufferBattery with the caveat that continuous mode is not enabled
public function testNonContinuousBufferBattery($op, $mode, $test)
{
if (count($test) == 1) {
return;
}
$iv = str_repeat('x', 16);
$key = str_repeat('a', 16);
$aes = new AES($mode);
$aes->setPreferredEngine($this->engine);
$aes->setKey($key);
$aes->setIV($iv);
$this->_checkEngine($aes);
$str = '';
$result = '';
foreach ($test as $len) {
$temp = str_repeat('d', $len);
$str.= $temp;
}
$c1 = $aes->$op($str);
$aes = new AES($mode);
$aes->setPreferredEngine($this->engine);
$aes->setKey($key);
$aes->setIV($iv);
$this->_checkEngine($aes);
foreach ($test as $len) {
$temp = str_repeat('d', $len);
$output = $aes->$op($temp);
$result.= $output;
}
$c2 = $result;
$this->assertNotSame(bin2hex($c1), bin2hex($c2));
}
// from http://csrc.nist.gov/groups/STM/cavp/documents/aes/AESAVS.pdf#page=16
public function testGFSBox128()
{
$aes = new AES();
$aes->setKey(pack('H*', '00000000000000000000000000000000'));
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
$aes->disablePadding();
$aes->setPreferredEngine($this->engine);
$this->_checkEngine($aes);
$result = bin2hex($aes->encrypt(pack('H*', 'f34481ec3cc627bacd5dc3fb08f273e6')));
$this->assertSame($result, '0336763e966d92595a567cc9ce537f5e');
$result = bin2hex($aes->encrypt(pack('H*', '9798c4640bad75c7c3227db910174e72')));
$this->assertSame($result, 'a9a1631bf4996954ebc093957b234589');
$result = bin2hex($aes->encrypt(pack('H*', '96ab5c2ff612d9dfaae8c31f30c42168')));
$this->assertSame($result, 'ff4f8391a6a40ca5b25d23bedd44a597');
$result = bin2hex($aes->encrypt(pack('H*', '6a118a874519e64e9963798a503f1d35')));
$this->assertSame($result, 'dc43be40be0e53712f7e2bf5ca707209');
$result = bin2hex($aes->encrypt(pack('H*', 'cb9fceec81286ca3e989bd979b0cb284')));
$this->assertSame($result, '92beedab1895a94faa69b632e5cc47ce');
$result = bin2hex($aes->encrypt(pack('H*', 'b26aeb1874e47ca8358ff22378f09144')));
$this->assertSame($result, '459264f4798f6a78bacb89c15ed3d601');
$result = bin2hex($aes->encrypt(pack('H*', '58c8e00b2631686d54eab84b91f0aca1')));
$this->assertSame($result, '08a4e2efec8a8e3312ca7460b9040bbf');
}
public function testGFSBox192()
{
$aes = new AES();
$aes->setKey(pack('H*', '000000000000000000000000000000000000000000000000'));
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
$aes->disablePadding();
$aes->setPreferredEngine($this->engine);
$this->_checkEngine($aes);
$result = bin2hex($aes->encrypt(pack('H*', '1b077a6af4b7f98229de786d7516b639')));
$this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72');
$result = bin2hex($aes->encrypt(pack('H*', '9c2d8842e5f48f57648205d39a239af1')));
$this->assertSame($result, 'c9b8135ff1b5adc413dfd053b21bd96d');
$result = bin2hex($aes->encrypt(pack('H*', 'bff52510095f518ecca60af4205444bb')));
$this->assertSame($result, '4a3650c3371ce2eb35e389a171427440');
$result = bin2hex($aes->encrypt(pack('H*', '51719783d3185a535bd75adc65071ce1')));
$this->assertSame($result, '4f354592ff7c8847d2d0870ca9481b7c');
$result = bin2hex($aes->encrypt(pack('H*', '26aa49dcfe7629a8901a69a9914e6dfd')));
$this->assertSame($result, 'd5e08bf9a182e857cf40b3a36ee248cc');
$result = bin2hex($aes->encrypt(pack('H*', '941a4773058224e1ef66d10e0a6ee782')));
$this->assertSame($result, '067cd9d3749207791841562507fa9626');
}
public function testGFSBox256()
{
$aes = new AES();
$aes->setKey(pack('H*', '00000000000000000000000000000000' . '00000000000000000000000000000000'));
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
$aes->disablePadding();
$aes->setPreferredEngine($this->engine);
$this->_checkEngine($aes);
$result = bin2hex($aes->encrypt(pack('H*', '014730f80ac625fe84f026c60bfd547d')));
$this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7');
$result = bin2hex($aes->encrypt(pack('H*', '0b24af36193ce4665f2825d7b4749c98')));
$this->assertSame($result, 'a9ff75bd7cf6613d3731c77c3b6d0c04');
$result = bin2hex($aes->encrypt(pack('H*', '761c1fe41a18acf20d241650611d90f1')));
$this->assertSame($result, '623a52fcea5d443e48d9181ab32c7421');
$result = bin2hex($aes->encrypt(pack('H*', '8a560769d605868ad80d819bdba03771')));
$this->assertSame($result, '38f2c7ae10612415d27ca190d27da8b4');
$result = bin2hex($aes->encrypt(pack('H*', '91fbef2d15a97816060bee1feaa49afe')));
$this->assertSame($result, '1bc704f1bce135ceb810341b216d7abe');
}
}

View File

@ -0,0 +1,84 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright MMXIII Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
use phpseclib\Crypt\Blowfish;
class Unit_Crypt_BlowfishTest extends PhpseclibTestCase
{
public function engineVectors()
{
$engines = array(
Base::ENGINE_INTERNAL => 'internal',
Base::ENGINE_MCRYPT => 'mcrypt',
Base::ENGINE_OPENSSL => 'OpenSSL',
);
// tests from https://www.schneier.com/code/vectors.txt
$tests = array(
// key, plaintext, ciphertext
array(pack('H*', '0000000000000000'), pack('H*', '0000000000000000'), pack('H*', '4EF997456198DD78')),
array(pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '51866FD5B85ECB8A')),
array(pack('H*', '3000000000000000'), pack('H*', '1000000000000001'), pack('H*', '7D856F9A613063F2')),
array(pack('H*', '1111111111111111'), pack('H*', '1111111111111111'), pack('H*', '2466DD878B963C9D')),
array(pack('H*', '0123456789ABCDEF'), pack('H*', '1111111111111111'), pack('H*', '61F9C3802281B096')),
array(pack('H*', '1111111111111111'), pack('H*', '0123456789ABCDEF'), pack('H*', '7D0CC630AFDA1EC7')),
array(pack('H*', '0000000000000000'), pack('H*', '0000000000000000'), pack('H*', '4EF997456198DD78')),
array(pack('H*', 'FEDCBA9876543210'), pack('H*', '0123456789ABCDEF'), pack('H*', '0ACEAB0FC6A0A28D')),
array(pack('H*', '7CA110454A1A6E57'), pack('H*', '01A1D6D039776742'), pack('H*', '59C68245EB05282B')),
array(pack('H*', '0131D9619DC1376E'), pack('H*', '5CD54CA83DEF57DA'), pack('H*', 'B1B8CC0B250F09A0')),
array(pack('H*', '07A1133E4A0B2686'), pack('H*', '0248D43806F67172'), pack('H*', '1730E5778BEA1DA4')),
array(pack('H*', '3849674C2602319E'), pack('H*', '51454B582DDF440A'), pack('H*', 'A25E7856CF2651EB')),
array(pack('H*', '04B915BA43FEB5B6'), pack('H*', '42FD443059577FA2'), pack('H*', '353882B109CE8F1A')),
array(pack('H*', '0113B970FD34F2CE'), pack('H*', '059B5E0851CF143A'), pack('H*', '48F4D0884C379918')),
array(pack('H*', '0170F175468FB5E6'), pack('H*', '0756D8E0774761D2'), pack('H*', '432193B78951FC98')),
array(pack('H*', '43297FAD38E373FE'), pack('H*', '762514B829BF486A'), pack('H*', '13F04154D69D1AE5')),
array(pack('H*', '07A7137045DA2A16'), pack('H*', '3BDD119049372802'), pack('H*', '2EEDDA93FFD39C79')),
array(pack('H*', '04689104C2FD3B2F'), pack('H*', '26955F6835AF609A'), pack('H*', 'D887E0393C2DA6E3')),
array(pack('H*', '37D06BB516CB7546'), pack('H*', '164D5E404F275232'), pack('H*', '5F99D04F5B163969')),
array(pack('H*', '1F08260D1AC2465E'), pack('H*', '6B056E18759F5CCA'), pack('H*', '4A057A3B24D3977B')),
array(pack('H*', '584023641ABA6176'), pack('H*', '004BD6EF09176062'), pack('H*', '452031C1E4FADA8E')),
array(pack('H*', '025816164629B007'), pack('H*', '480D39006EE762F2'), pack('H*', '7555AE39F59B87BD')),
array(pack('H*', '49793EBC79B3258F'), pack('H*', '437540C8698F3CFA'), pack('H*', '53C55F9CB49FC019')),
array(pack('H*', '4FB05E1515AB73A7'), pack('H*', '072D43A077075292'), pack('H*', '7A8E7BFA937E89A3')),
array(pack('H*', '49E95D6D4CA229BF'), pack('H*', '02FE55778117F12A'), pack('H*', 'CF9C5D7A4986ADB5')),
array(pack('H*', '018310DC409B26D6'), pack('H*', '1D9D5C5018F728C2'), pack('H*', 'D1ABB290658BC778')),
array(pack('H*', '1C587F1C13924FEF'), pack('H*', '305532286D6F295A'), pack('H*', '55CB3774D13EF201')),
array(pack('H*', '0101010101010101'), pack('H*', '0123456789ABCDEF'), pack('H*', 'FA34EC4847B268B2')),
array(pack('H*', '1F1F1F1F0E0E0E0E'), pack('H*', '0123456789ABCDEF'), pack('H*', 'A790795108EA3CAE')),
array(pack('H*', 'E0FEE0FEF1FEF1FE'), pack('H*', '0123456789ABCDEF'), pack('H*', 'C39E072D9FAC631D')),
array(pack('H*', '0000000000000000'), pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '014933E0CDAFF6E4')),
array(pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '0000000000000000'), pack('H*', 'F21E9A77B71C49BC')),
array(pack('H*', '0123456789ABCDEF'), pack('H*', '0000000000000000'), pack('H*', '245946885754369A')),
array(pack('H*', 'FEDCBA9876543210'), pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '6B5C5A9C5D9E0A5A'))
);
$result = array();
// @codingStandardsIgnoreStart
foreach ($engines as $engine => $engineName)
foreach ($tests as $test)
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
// @codingStandardsIgnoreEnd
return $result;
}
/**
* @dataProvider engineVectors
*/
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
{
$bf = new Blowfish();
$bf->setKey($key);
if (!$bf->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
$bf->setPreferredEngine($engine);
$bf->disablePadding();
$result = $bf->encrypt($plaintext);
$plaintext = bin2hex($plaintext);
$this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine");
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright MMXIII Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
use phpseclib\Crypt\DES;
// the AES tests establish the correctness of the modes of operation. this test is inteded to establish the consistency of
// key and iv padding between the multiple engines
class Unit_Crypt_DESTest extends PhpseclibTestCase
{
public function testEncryptPadding()
{
$des = new DES(Base::MODE_CBC);
$des->setKey('d');
$des->setIV('d');
$des->setPreferredEngine(Base::ENGINE_INTERNAL);
$result = pack('H*', '3e7613642049af1e');
$internal = $des->encrypt('d');
$this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result');
$des->setPreferredEngine(Base::ENGINE_MCRYPT);
if ($des->getEngine() == Base::ENGINE_MCRYPT) {
$mcrypt = $des->encrypt('d');
$this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize mcrypt engine');
}
$des->setPreferredEngine(Base::ENGINE_OPENSSL);
if ($des->getEngine() == Base::ENGINE_OPENSSL) {
$openssl = $des->encrypt('d');
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize OpenSSL engine');
}
}
// phpseclib null pads ciphertext's if they're not long enough and you're in ecb / cbc mode. this silent failure mode is consistent
// with mcrypt's behavior. maybe throwing an exception would be better but whatever. this test is more intended to establish consistent
// behavior between the various engine's
public function testDecryptPadding()
{
$des = new DES(Base::MODE_CBC);
$des->disablePadding();
// when the key and iv are not specified they should be null padded
//$des->setKey();
//$des->setIV();
$des->setPreferredEngine(Base::ENGINE_INTERNAL);
$internal = $des->decrypt('d');
$result = pack('H*', '79b305d1ce555221');
$this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result');
$des->setPreferredEngine(Base::ENGINE_MCRYPT);
if ($des->getEngine() == Base::ENGINE_MCRYPT) {
$mcrypt = $des->decrypt('d');
$this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize mcrypt engine');
}
$des->setPreferredEngine(Base::ENGINE_OPENSSL);
if ($des->getEngine() == Base::ENGINE_OPENSSL) {
$openssl = $des->decrypt('d');
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize OpenSSL engine');
}
}
}

View File

@ -0,0 +1,122 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright MMXIII Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
use phpseclib\Crypt\RC2;
class Unit_Crypt_RC2Test extends PhpseclibTestCase
{
var $engines = array(
Base::ENGINE_INTERNAL => 'internal',
Base::ENGINE_MCRYPT => 'mcrypt',
Base::ENGINE_OPENSSL => 'OpenSSL',
);
public function engineVectors()
{
// tests from https://tools.ietf.org/html/rfc2268#page-8
$tests = array(
// key, effective key length, plaintext, ciphertext
array('0000000000000000', 63, '0000000000000000', 'ebb773f993278eff'),
array('ffffffffffffffff', 64, 'ffffffffffffffff', '278b27e42e2f0d49'),
array('3000000000000000', 64, '1000000000000001', '30649edf9be7d2c2'),
array('88', 64, '0000000000000000', '61a8a244adacccf0'),
array('88bca90e90875a', 64, '0000000000000000', '6ccf4308974c267f'),
array('88bca90e90875a7f0f79c384627bafb2', 64, '0000000000000000', '1a807d272bbe5db1'),
array('88bca90e90875a7f0f79c384627bafb2', 128, '0000000000000000', '2269552ab0f85ca6'),
array('88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e', 129, '0000000000000000', '5b78d3a43dfff1f1')
);
$result = array();
// @codingStandardsIgnoreStart
foreach ($this->engines as $engine => $engineName)
foreach ($tests as $test)
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
// @codingStandardsIgnoreEnd
return $result;
}
// this test is just confirming RC2's key expansion
public function testEncryptPadding()
{
$rc2 = new RC2(Base::MODE_ECB);
// unlike Crypt_AES / Crypt_Rijndael, when you tell Crypt_RC2 that the key length is 128-bits the key isn't null padded to that length.
// instead, RC2 key expansion is used to extend it out to that length. this isn't done for AES / Rijndael since that doesn't define any
// sort of key expansion algorithm.
// admittedly, phpseclib is inconsistent in this regard. RC4 and Blowfish support arbitrary key lengths between a certain range, as well,
// and they don't have any way to set the key length. but then again, neither do those algorithms have their own key expansion algorithm,
// whereas RC2 does. and technically, AES / Rijndael (and even Twofish) don't support arbitrary key lengths - they support variable key
// lengths. so in some ways, i suppose this inconsistency somewhat makes sense, although the fact that Crypt_Twofish doesn't have a
// setKeyLength() function whereas Crypt_AES / Crypt_Rijndael do not is, itself, an inconsistency.
// but that said, Crypt_RC2 is inconsistent in other ways: if you pass a 128-bit (16-byte) key to it via setKey() the key is not treated
// as a 128-bit key but rather as a 1024-bit key and is expanded accordingly, not via null padding, but via RC2's key expansion algorithm.
// this behavior is in contrast to mcrypt, which extends keys via null padding to 1024 bits. it is also in contrast to OpenSSL, which
// extends keys, via null padding, to 128 bits. mcrypt's approach seems preferable as one can simulate 128 bit keys by using RC2's
// key expansion algorithm to extend the key to 1024 bits and then changing the first byte of the new key with an inverse pitable mapping.
// in contrast, to my knowledge, there is no technique for expanding a key less than 128 bits to 128 bits, via RC2 key expansion. the only
// scenario in that regard is null padding.
// simple truncation is insufficient, since, quoting RFC2268, "the purpose of the key-expansion algorithm [in RC2] is to modify the key buffer
// so that each bit of the expanded key depends in a complicated way on every bit of the supplied input key".
// now, to OpenSSL's credit, null padding is internally consistent with OpenSSL. OpenSSL only supports fixed length keys. For rc2, rc4 and
// bf (blowfish), all keys are 128 bits (or are null padded / truncated accordingly). to use 40-bit or 64-bit keys with RC4 with OpenSSL you
// don't use the rc4 algorithm - you use the rc4-40 or rc4-64 algorithm. and similarily, it's not aes-cbc that you use - it's either aes-128-cbc
// or aes-192-cbc or aes-256-cbc. this is in contrast to mcrypt, which (with the exception of RC2) actually supports variable and arbitrary
// length keys.
// superficially, it seens like Rijndael would be another exception to mcrypt's key length handling, but it in fact is not. the reason being that,
// with mcrypt, when you specify MCRYPT_RIJNDAEL_128 or MCRYPT_RIJNDAEL_192 or MCRYPT_RIJNDAEL_256 the numbers at the end aren't referring to the
// key length, but rather, the block length. ie. Rijndael, unlike most block ciphers, doesn't just have a variable (but not arbitrary) key length -
// it also has a variable block length. AES's block length, however, is not variable, so technically, only MCRYPT_RIJNDAEL_128 is AES.
$rc2->setKey(str_repeat('d', 16), 128);
$rc2->setPreferredEngine(Base::ENGINE_INTERNAL);
$internal = $rc2->encrypt('d');
$result = pack('H*', 'e3b36057f4821346');
$this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result');
$rc2->setPreferredEngine(Base::ENGINE_MCRYPT);
if ($rc2->getEngine() == Base::ENGINE_MCRYPT) {
$mcrypt = $rc2->encrypt('d');
$this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize mcrypt engine');
}
$rc2->setPreferredEngine(Base::ENGINE_OPENSSL);
if ($rc2->getEngine() == Base::ENGINE_OPENSSL) {
$openssl = $rc2->encrypt('d');
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize OpenSSL engine');
}
}
/**
* @dataProvider engineVectors
*/
public function testVectors($engine, $engineName, $key, $keyLen, $plaintext, $ciphertext)
{
$rc2 = new RC2();
$rc2->disablePadding();
$rc2->setKeyLength($keyLen);
$rc2->setKey(pack('H*', $key)); // could also do $rc2->setKey(pack('H*', $key), $keyLen)
if (!$rc2->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
$rc2->setPreferredEngine($engine);
$result = bin2hex($rc2->encrypt(pack('H*', $plaintext)));
$this->assertEquals($result, $ciphertext, "Failed asserting that $plaintext yielded expected output in $engineName engine");
}
}

View File

@ -0,0 +1,208 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
use phpseclib\Crypt\RC4;
class Unit_Crypt_RC4Test extends PhpseclibTestCase
{
public function engineVectors()
{
$engines = array(
Base::ENGINE_INTERNAL => 'internal',
Base::ENGINE_MCRYPT => 'mcrypt',
Base::ENGINE_OPENSSL => 'OpenSSL',
);
// tests from https://tools.ietf.org/html/rfc6229
$tests = array(
array(
'key' => pack('H*', '0102030405'), // 40-bit key
'output' => array(
array('offset' => 0, 'result' => 'b2396305f03dc027ccc3524a0a1118a8'),
array('offset' => 16, 'result' => '6982944f18fc82d589c403a47a0d0919'),
array('offset' => 240, 'result' => '28cb1132c96ce286421dcaadb8b69eae'),
array('offset' => 256, 'result' => '1cfcf62b03eddb641d77dfcf7f8d8c93'),
array('offset' => 496, 'result' => '42b7d0cdd918a8a33dd51781c81f4041'),
array('offset' => 512, 'result' => '6459844432a7da923cfb3eb4980661f6'),
array('offset' => 752, 'result' => 'ec10327bde2beefd18f9277680457e22'),
array('offset' => 768, 'result' => 'eb62638d4f0ba1fe9fca20e05bf8ff2b'),
array('offset' => 1008, 'result' => '45129048e6a0ed0b56b490338f078da5'),
array('offset' => 1024, 'result' => '30abbcc7c20b01609f23ee2d5f6bb7df'),
array('offset' => 1520, 'result' => '3294f744d8f9790507e70f62e5bbceea'),
array('offset' => 1536, 'result' => 'd8729db41882259bee4f825325f5a130'),
array('offset' => 2032, 'result' => '1eb14a0c13b3bf47fa2a0ba93ad45b8b'),
array('offset' => 2048, 'result' => 'cc582f8ba9f265e2b1be9112e975d2d7'),
array('offset' => 3056, 'result' => 'f2e30f9bd102ecbf75aaade9bc35c43c'),
array('offset' => 3072, 'result' => 'ec0e11c479dc329dc8da7968fe965681'),
array('offset' => 4080, 'result' => '068326a2118416d21f9d04b2cd1ca050'),
array('offset' => 4096, 'result' => 'ff25b58995996707e51fbdf08b34d875')
)
),
array(
'key' => pack('H*', '01020304050607'), // 56-bit key
'output' => array(
array('offset' => 0, 'result' => '293f02d47f37c9b633f2af5285feb46b'),
array('offset' => 16, 'result' => 'e620f1390d19bd84e2e0fd752031afc1'),
array('offset' => 240, 'result' => '914f02531c9218810df60f67e338154c'),
array('offset' => 256, 'result' => 'd0fdb583073ce85ab83917740ec011d5'),
array('offset' => 496, 'result' => '75f81411e871cffa70b90c74c592e454'),
array('offset' => 512, 'result' => '0bb87202938dad609e87a5a1b079e5e4'),
array('offset' => 752, 'result' => 'c2911246b612e7e7b903dfeda1dad866'),
array('offset' => 768, 'result' => '32828f91502b6291368de8081de36fc2'),
array('offset' => 1008, 'result' => 'f3b9a7e3b297bf9ad804512f9063eff1'),
array('offset' => 1024, 'result' => '8ecb67a9ba1f55a5a067e2b026a3676f'),
array('offset' => 1520, 'result' => 'd2aa902bd42d0d7cfd340cd45810529f'),
array('offset' => 1536, 'result' => '78b272c96e42eab4c60bd914e39d06e3'),
array('offset' => 2032, 'result' => 'f4332fd31a079396ee3cee3f2a4ff049'),
array('offset' => 2048, 'result' => '05459781d41fda7f30c1be7e1246c623'),
array('offset' => 3056, 'result' => 'adfd3868b8e51485d5e610017e3dd609'),
array('offset' => 3072, 'result' => 'ad26581c0c5be45f4cea01db2f3805d5'),
array('offset' => 4080, 'result' => 'f3172ceffc3b3d997c85ccd5af1a950c'),
array('offset' => 4096, 'result' => 'e74b0b9731227fd37c0ec08a47ddd8b8')
)
),
array(
'key' => pack('H*', '0102030405060708'), // 64-bit key
'output' => array(
array('offset' => 0, 'result' => '97ab8a1bf0afb96132f2f67258da15a8'),
array('offset' => 16, 'result' => '8263efdb45c4a18684ef87e6b19e5b09'),
array('offset' => 240, 'result' => '9636ebc9841926f4f7d1f362bddf6e18'),
array('offset' => 256, 'result' => 'd0a990ff2c05fef5b90373c9ff4b870a'),
array('offset' => 496, 'result' => '73239f1db7f41d80b643c0c52518ec63'),
array('offset' => 512, 'result' => '163b319923a6bdb4527c626126703c0f'),
array('offset' => 752, 'result' => '49d6c8af0f97144a87df21d91472f966'),
array('offset' => 768, 'result' => '44173a103b6616c5d5ad1cee40c863d0'),
array('offset' => 1008, 'result' => '273c9c4b27f322e4e716ef53a47de7a4'),
array('offset' => 1024, 'result' => 'c6d0e7b226259fa9023490b26167ad1d'),
array('offset' => 1520, 'result' => '1fe8986713f07c3d9ae1c163ff8cf9d3'),
array('offset' => 1536, 'result' => '8369e1a965610be887fbd0c79162aafb'),
array('offset' => 2032, 'result' => '0a0127abb44484b9fbef5abcae1b579f'),
array('offset' => 2048, 'result' => 'c2cdadc6402e8ee866e1f37bdb47e42c'),
array('offset' => 3056, 'result' => '26b51ea37df8e1d6f76fc3b66a7429b3'),
array('offset' => 3072, 'result' => 'bc7683205d4f443dc1f29dda3315c87b'),
array('offset' => 4080, 'result' => 'd5fa5a3469d29aaaf83d23589db8c85b'),
array('offset' => 4096, 'result' => '3fb46e2c8f0f068edce8cdcd7dfc5862')
)
),
array(
'key' => pack('H*', '0102030405060708090a'), // 80-bit key
'output' => array(
array('offset' => 0, 'result' => 'ede3b04643e586cc907dc21851709902'),
array('offset' => 16, 'result' => '03516ba78f413beb223aa5d4d2df6711'),
array('offset' => 240, 'result' => '3cfd6cb58ee0fdde640176ad0000044d'),
array('offset' => 256, 'result' => '48532b21fb6079c9114c0ffd9c04a1ad'),
array('offset' => 496, 'result' => '3e8cea98017109979084b1ef92f99d86'),
array('offset' => 512, 'result' => 'e20fb49bdb337ee48b8d8dc0f4afeffe'),
array('offset' => 752, 'result' => '5c2521eacd7966f15e056544bea0d315'),
array('offset' => 768, 'result' => 'e067a7031931a246a6c3875d2f678acb'),
array('offset' => 1008, 'result' => 'a64f70af88ae56b6f87581c0e23e6b08'),
array('offset' => 1024, 'result' => 'f449031de312814ec6f319291f4a0516'),
array('offset' => 1520, 'result' => 'bdae85924b3cb1d0a2e33a30c6d79599'),
array('offset' => 1536, 'result' => '8a0feddbac865a09bcd127fb562ed60a'),
array('offset' => 2032, 'result' => 'b55a0a5b51a12a8be34899c3e047511a'),
array('offset' => 2048, 'result' => 'd9a09cea3ce75fe39698070317a71339'),
array('offset' => 3056, 'result' => '552225ed1177f44584ac8cfa6c4eb5fc'),
array('offset' => 3072, 'result' => '7e82cbabfc95381b080998442129c2f8'),
array('offset' => 4080, 'result' => '1f135ed14ce60a91369d2322bef25e3c'),
array('offset' => 4096, 'result' => '08b6be45124a43e2eb77953f84dc8553')
)
),
array(
'key' => pack('H*', '0102030405060708090a0b0c0d0e0f10'), // 128-bit key
'output' => array(
array('offset' => 0, 'result' => '9ac7cc9a609d1ef7b2932899cde41b97'),
array('offset' => 16, 'result' => '5248c4959014126a6e8a84f11d1a9e1c'),
array('offset' => 240, 'result' => '065902e4b620f6cc36c8589f66432f2b'),
array('offset' => 256, 'result' => 'd39d566bc6bce3010768151549f3873f'),
array('offset' => 496, 'result' => 'b6d1e6c4a5e4771cad79538df295fb11'),
array('offset' => 512, 'result' => 'c68c1d5c559a974123df1dbc52a43b89'),
array('offset' => 752, 'result' => 'c5ecf88de897fd57fed301701b82a259'),
array('offset' => 768, 'result' => 'eccbe13de1fcc91c11a0b26c0bc8fa4d'),
array('offset' => 1008, 'result' => 'e7a72574f8782ae26aabcf9ebcd66065'),
array('offset' => 1024, 'result' => 'bdf0324e6083dcc6d3cedd3ca8c53c16'),
array('offset' => 1520, 'result' => 'b40110c4190b5622a96116b0017ed297'),
array('offset' => 1536, 'result' => 'ffa0b514647ec04f6306b892ae661181'),
array('offset' => 2032, 'result' => 'd03d1bc03cd33d70dff9fa5d71963ebd'),
array('offset' => 2048, 'result' => '8a44126411eaa78bd51e8d87a8879bf5'),
array('offset' => 3056, 'result' => 'fabeb76028ade2d0e48722e46c4615a3'),
array('offset' => 3072, 'result' => 'c05d88abd50357f935a63c59ee537623'),
array('offset' => 4080, 'result' => 'ff38265c1642c1abe8d3c2fe5e572bf8'),
array('offset' => 4096, 'result' => 'a36a4c301ae8ac13610ccbc12256cacc')
)
),
array(
'key' => pack('H*', '0102030405060708090a0b0c0d0e0f101112131415161718'), // 192-bit key
'output' => array(
array('offset' => 0, 'result' => '0595e57fe5f0bb3c706edac8a4b2db11'),
array('offset' => 16, 'result' => 'dfde31344a1af769c74f070aee9e2326'),
array('offset' => 240, 'result' => 'b06b9b1e195d13d8f4a7995c4553ac05'),
array('offset' => 256, 'result' => '6bd2378ec341c9a42f37ba79f88a32ff'),
array('offset' => 496, 'result' => 'e70bce1df7645adb5d2c4130215c3522'),
array('offset' => 512, 'result' => '9a5730c7fcb4c9af51ffda89c7f1ad22'),
array('offset' => 752, 'result' => '0485055fd4f6f0d963ef5ab9a5476982'),
array('offset' => 768, 'result' => '591fc66bcda10e452b03d4551f6b62ac'),
array('offset' => 1008, 'result' => '2753cc83988afa3e1688a1d3b42c9a02'),
array('offset' => 1024, 'result' => '93610d523d1d3f0062b3c2a3bbc7c7f0'),
array('offset' => 1520, 'result' => '96c248610aadedfeaf8978c03de8205a'),
array('offset' => 1536, 'result' => '0e317b3d1c73b9e9a4688f296d133a19'),
array('offset' => 2032, 'result' => 'bdf0e6c3cca5b5b9d533b69c56ada120'),
array('offset' => 2048, 'result' => '88a218b6e2ece1e6246d44c759d19b10'),
array('offset' => 3056, 'result' => '6866397e95c140534f94263421006e40'),
array('offset' => 3072, 'result' => '32cb0a1e9542c6b3b8b398abc3b0f1d5'),
array('offset' => 4080, 'result' => '29a0b8aed54a132324c62e423f54b4c8'),
array('offset' => 4096, 'result' => '3cb0f3b5020a98b82af9fe154484a168')
)
),
array(
'key' => pack('H*', '0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20'), // 256-bit key
'output' => array(
array('offset' => 0, 'result' => 'eaa6bd25880bf93d3f5d1e4ca2611d91'),
array('offset' => 16, 'result' => 'cfa45c9f7e714b54bdfa80027cb14380'),
array('offset' => 240, 'result' => '114ae344ded71b35f2e60febad727fd8'),
array('offset' => 256, 'result' => '02e1e7056b0f623900496422943e97b6'),
array('offset' => 496, 'result' => '91cb93c787964e10d9527d999c6f936b'),
array('offset' => 512, 'result' => '49b18b42f8e8367cbeb5ef104ba1c7cd'),
array('offset' => 752, 'result' => '87084b3ba700bade955610672745b374'),
array('offset' => 768, 'result' => 'e7a7b9e9ec540d5ff43bdb12792d1b35'),
array('offset' => 1008, 'result' => 'c799b596738f6b018c76c74b1759bd90'),
array('offset' => 1024, 'result' => '7fec5bfd9f9b89ce6548309092d7e958'),
array('offset' => 1520, 'result' => '40f250b26d1f096a4afd4c340a588815'),
array('offset' => 1536, 'result' => '3e34135c79db010200767651cf263073'),
array('offset' => 2032, 'result' => 'f656abccf88dd827027b2ce917d464ec'),
array('offset' => 2048, 'result' => '18b62503bfbc077fbabb98f20d98ab34'),
array('offset' => 3056, 'result' => '8aed95ee5b0dcbfbef4eb21d3a3f52f9'),
array('offset' => 3072, 'result' => '625a1ab00ee39a5327346bddb01a9c18'),
array('offset' => 4080, 'result' => 'a13a7c79c7e119b5ab0296ab28c300b9'),
array('offset' => 4096, 'result' => 'f3e4c0a2e02d1d01f7f0a74618af2b48')
)
)
);
$result = array();
// @codingStandardsIgnoreStart
foreach ($engines as $engine => $engineName)
foreach ($tests as $test)
foreach ($test['output'] as $output)
$result[] = array($engine, $engineName, $test['key'], $output['offset'], $output['result']);
// @codingStandardsIgnoreEnd
return $result;
}
/**
* @dataProvider engineVectors
*/
public function testVectors($engine, $engineName, $key, $offset, $expected)
{
$rc4 = new RC4();
$rc4->setPreferredEngine($engine);
$rc4->setKey($key);
if ($rc4->getEngine() != $engine) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine for ' . (strlen($key) * 8) . '-bit key');
}
$result = $rc4->encrypt(str_repeat("\0", $offset + 16));
$this->assertEquals(bin2hex(substr($result, -16)), $expected, "Failed asserting that key $key yielded expected output at offset $offset in $engineName engine");
}
}

View File

@ -0,0 +1,183 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
use phpseclib\Crypt\TripleDES;
class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
{
var $engines = array(
Base::ENGINE_INTERNAL => 'internal',
Base::ENGINE_MCRYPT => 'mcrypt',
Base::ENGINE_OPENSSL => 'OpenSSL',
);
public function engineVectors()
{
// tests from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf#page=273
$tests = array(
// Table A.1
// key, plaintext, ciphertext
array(str_repeat("\x01", 24), pack('H*', '8000000000000000'), pack('H*', '95F8A5E5DD31D900')),
array(str_repeat("\x01", 24), pack('H*', '4000000000000000'), pack('H*', 'DD7F121CA5015619')),
array(str_repeat("\x01", 24), pack('H*', '2000000000000000'), pack('H*', '2E8653104F3834EA')),
array(str_repeat("\x01", 24), pack('H*', '1000000000000000'), pack('H*', '4BD388FF6CD81D4F')),
array(str_repeat("\x01", 24), pack('H*', '0800000000000000'), pack('H*', '20B9E767B2FB1456')),
array(str_repeat("\x01", 24), pack('H*', '0400000000000000'), pack('H*', '55579380D77138EF')),
array(str_repeat("\x01", 24), pack('H*', '0200000000000000'), pack('H*', '6CC5DEFAAF04512F')),
array(str_repeat("\x01", 24), pack('H*', '0100000000000000'), pack('H*', '0D9F279BA5D87260')),
array(str_repeat("\x01", 24), pack('H*', '0080000000000000'), pack('H*', 'D9031B0271BD5A0A')),
array(str_repeat("\x01", 24), pack('H*', '0040000000000000'), pack('H*', '424250B37C3DD951')),
array(str_repeat("\x01", 24), pack('H*', '0020000000000000'), pack('H*', 'B8061B7ECD9A21E5')),
array(str_repeat("\x01", 24), pack('H*', '0010000000000000'), pack('H*', 'F15D0F286B65BD28')),
array(str_repeat("\x01", 24), pack('H*', '0008000000000000'), pack('H*', 'ADD0CC8D6E5DEBA1')),
array(str_repeat("\x01", 24), pack('H*', '0004000000000000'), pack('H*', 'E6D5F82752AD63D1')),
array(str_repeat("\x01", 24), pack('H*', '0002000000000000'), pack('H*', 'ECBFE3BD3F591A5E')),
array(str_repeat("\x01", 24), pack('H*', '0001000000000000'), pack('H*', 'F356834379D165CD')),
array(str_repeat("\x01", 24), pack('H*', '0000800000000000'), pack('H*', '2B9F982F20037FA9')),
array(str_repeat("\x01", 24), pack('H*', '0000400000000000'), pack('H*', '889DE068A16F0BE6')),
array(str_repeat("\x01", 24), pack('H*', '0000200000000000'), pack('H*', 'E19E275D846A1298')),
array(str_repeat("\x01", 24), pack('H*', '0000100000000000'), pack('H*', '329A8ED523D71AEC')),
array(str_repeat("\x01", 24), pack('H*', '0000080000000000'), pack('H*', 'E7FCE22557D23C97')),
array(str_repeat("\x01", 24), pack('H*', '0000040000000000'), pack('H*', '12A9F5817FF2D65D')),
array(str_repeat("\x01", 24), pack('H*', '0000020000000000'), pack('H*', 'A484C3AD38DC9C19')),
array(str_repeat("\x01", 24), pack('H*', '0000010000000000'), pack('H*', 'FBE00A8A1EF8AD72')),
array(str_repeat("\x01", 24), pack('H*', '0000008000000000'), pack('H*', '750D079407521363')),
array(str_repeat("\x01", 24), pack('H*', '0000004000000000'), pack('H*', '64FEED9C724C2FAF')),
array(str_repeat("\x01", 24), pack('H*', '0000002000000000'), pack('H*', 'F02B263B328E2B60')),
array(str_repeat("\x01", 24), pack('H*', '0000001000000000'), pack('H*', '9D64555A9A10B852')),
array(str_repeat("\x01", 24), pack('H*', '0000000800000000'), pack('H*', 'D106FF0BED5255D7')),
array(str_repeat("\x01", 24), pack('H*', '0000000400000000'), pack('H*', 'E1652C6B138C64A5')),
array(str_repeat("\x01", 24), pack('H*', '0000000200000000'), pack('H*', 'E428581186EC8F46')),
array(str_repeat("\x01", 24), pack('H*', '0000000100000000'), pack('H*', 'AEB5F5EDE22D1A36')),
array(str_repeat("\x01", 24), pack('H*', '0000000080000000'), pack('H*', 'E943D7568AEC0C5C')),
array(str_repeat("\x01", 24), pack('H*', '0000000040000000'), pack('H*', 'DF98C8276F54B04B')),
array(str_repeat("\x01", 24), pack('H*', '0000000020000000'), pack('H*', 'B160E4680F6C696F')),
array(str_repeat("\x01", 24), pack('H*', '0000000010000000'), pack('H*', 'FA0752B07D9C4AB8')),
array(str_repeat("\x01", 24), pack('H*', '0000000008000000'), pack('H*', 'CA3A2B036DBC8502')),
array(str_repeat("\x01", 24), pack('H*', '0000000004000000'), pack('H*', '5E0905517BB59BCF')),
array(str_repeat("\x01", 24), pack('H*', '0000000002000000'), pack('H*', '814EEB3B91D90726')),
array(str_repeat("\x01", 24), pack('H*', '0000000001000000'), pack('H*', '4D49DB1532919C9F')),
array(str_repeat("\x01", 24), pack('H*', '0000000000800000'), pack('H*', '25EB5FC3F8CF0621')),
array(str_repeat("\x01", 24), pack('H*', '0000000000400000'), pack('H*', 'AB6A20C0620D1C6F')),
array(str_repeat("\x01", 24), pack('H*', '0000000000200000'), pack('H*', '79E90DBC98F92CCA')),
array(str_repeat("\x01", 24), pack('H*', '0000000000100000'), pack('H*', '866ECEDD8072BB0E')),
array(str_repeat("\x01", 24), pack('H*', '0000000000080000'), pack('H*', '8B54536F2F3E64A8')),
array(str_repeat("\x01", 24), pack('H*', '0000000000040000'), pack('H*', 'EA51D3975595B86B')),
array(str_repeat("\x01", 24), pack('H*', '0000000000020000'), pack('H*', 'CAFFC6AC4542DE31')),
array(str_repeat("\x01", 24), pack('H*', '0000000000010000'), pack('H*', '8DD45A2DDF90796C')),
array(str_repeat("\x01", 24), pack('H*', '0000000000008000'), pack('H*', '1029D55E880EC2D0')),
array(str_repeat("\x01", 24), pack('H*', '0000000000004000'), pack('H*', '5D86CB23639DBEA9')),
array(str_repeat("\x01", 24), pack('H*', '0000000000002000'), pack('H*', '1D1CA853AE7C0C5F')),
array(str_repeat("\x01", 24), pack('H*', '0000000000001000'), pack('H*', 'CE332329248F3228')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000800'), pack('H*', '8405D1ABE24FB942')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000400'), pack('H*', 'E643D78090CA4207')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000200'), pack('H*', '48221B9937748A23')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000100'), pack('H*', 'DD7C0BBD61FAFD54')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000080'), pack('H*', '2FBC291A570DB5C4')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000040'), pack('H*', 'E07C30D7E4E26E12')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000020'), pack('H*', '0953E2258E8E90A1')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000010'), pack('H*', '5B711BC4CEEBF2EE')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000008'), pack('H*', 'CC083F1E6D9E85F6')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000004'), pack('H*', 'D2FD8867D50D2DFE')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000002'), pack('H*', '06E7EA22CE92708F')),
array(str_repeat("\x01", 24), pack('H*', '0000000000000001'), pack('H*', '166B40B44ABA4BD6'))
);
$result = array();
// @codingStandardsIgnoreStart
foreach ($this->engines as $engine => $engineName)
foreach ($tests as $test)
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
// @codingStandardsIgnoreEnd
return $result;
}
/**
* @dataProvider engineVectors
*/
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
{
$des = new TripleDES();
if (!$des->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
$des->setPreferredEngine($engine);
$des->setKey($key);
$des->disablePadding();
$result = $des->encrypt($plaintext);
$plaintext = bin2hex($plaintext);
$this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine");
}
public function engineIVVectors()
{
$engines = array(
Base::ENGINE_INTERNAL => 'internal',
Base::ENGINE_MCRYPT => 'mcrypt',
Base::ENGINE_OPENSSL => 'OpenSSL',
);
// tests from http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf
$tests = array(
// key, iv, plaintext, ciphertext
array(
pack('H*', '627f460e08104a10' . '43cd265d5840eaf1' . '313edf97df2a8a8c'),
pack('H*', '8e29f75ea77e5475'),
pack('H*', '326a494cd33fe756'),
pack('H*', 'b22b8d66de970692')),
array(
pack('H*', '37ae5ebf46dff2dc' . '0754b94f31cbb385' . '5e7fd36dc870bfae'),
pack('H*', '3d1de3cc132e3b65'),
pack('H*', '84401f78fe6c10876d8ea23094ea5309'),
pack('H*', '7b1f7c7e3b1c948ebd04a75ffba7d2f5'))
);
$result = array();
// @codingStandardsIgnoreStart
foreach ($engines as $engine => $engineName)
foreach ($tests as $test)
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
// @codingStandardsIgnoreEnd
return $result;
}
/**
* @dataProvider engineIVVectors
*/
public function testVectorsWithIV($engine, $engineName, $key, $iv, $plaintext, $expected)
{
$des = new TripleDES();
if (!$des->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
$des->setPreferredEngine($engine);
$des->setKey($key);
$des->setIV($iv);
$des->disablePadding();
$result = $des->encrypt($plaintext);
$plaintext = bin2hex($plaintext);
$this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine");
}
public function testInnerChaining()
{
// regular CBC returns
// e089b6d84708c6bc80be6c2da82bd19a79ffe11f02933ac1
$expected = 'e089b6d84708c6bc6f04c8971121603d7be2861efae0f3f5';
$des = new TripleDES(TripleDES::MODE_3CBC);
$des->setKey('abcdefghijklmnopqrstuvwx');
foreach ($this->engines as $engine => $engineName) {
$des->setPreferredEngine($engine);
if (!$des->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
$result = bin2hex($des->encrypt(str_repeat('a', 16)));
$this->assertEquals($result, $expected, "Failed asserting inner chainin worked correctly in $engineName engine");
}
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright MMXIII Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
use phpseclib\Crypt\Twofish;
class Unit_Crypt_TwofishTest extends PhpseclibTestCase
{
public function testVectors()
{
$engines = array(
Base::ENGINE_INTERNAL => 'internal',
Base::ENGINE_MCRYPT => 'mcrypt',
Base::ENGINE_OPENSSL => 'OpenSSL',
);
foreach ($engines as $engine=>$name) {
$tf = new Twofish();
$tf->disablePadding();
// tests from https://www.schneier.com/code/ecb_ival.txt
// key size = 128
$key = pack('H*', '00000000000000000000000000000000');
$tf->setKey($key);
if (!$tf->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $name . ' engine');
}
$plaintext = pack('H*', '00000000000000000000000000000000');
$ciphertext = $tf->encrypt($plaintext);
$expected = strtolower('9F589F5CF6122C32B6BFEC2F2AE8C35A');
$this->assertEquals(bin2hex($ciphertext), $expected, "Failed asserting that $plaintext yielded expected output in $name engine");
$expected = bin2hex($plaintext);
$plaintext = bin2hex($tf->decrypt($ciphertext));
$this->assertEquals($plaintext, $expected, "Failed asserting that $plaintext yielded expected output in $name engine");
// key size = 192
$key = pack('H*', '0123456789ABCDEFFEDCBA98765432100011223344556677');
$tf->setKey($key);
if (!$tf->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $name . ' engine');
}
$plaintext = pack('H*', '00000000000000000000000000000000');
$ciphertext = $tf->encrypt($plaintext);
$expected = strtolower('CFD1D2E5A9BE9CDF501F13B892BD2248');
$this->assertEquals(bin2hex($ciphertext), $expected, "Failed asserting that $plaintext yielded expected output in $name engine");
$expected = bin2hex($plaintext);
$plaintext = bin2hex($tf->decrypt($ciphertext));
$this->assertEquals($plaintext, $expected, "Failed asserting that $plaintext yielded expected output in $name engine");
// key size = 256
$key = pack('H*', '0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF');
$tf->setKey($key);
if (!$tf->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $name . ' engine');
}
$plaintext = pack('H*', '00000000000000000000000000000000');
$ciphertext = $tf->encrypt($plaintext);
$expected = strtolower('37527BE0052334B89F0CFCCAE87CFA20');
$this->assertEquals(bin2hex($ciphertext), $expected, "Failed asserting that $plaintext yielded expected output in $name engine");
$expected = bin2hex($plaintext);
$plaintext = bin2hex($tf->decrypt($ciphertext));
$this->assertEquals($plaintext, $expected, "Failed asserting that $plaintext yielded expected output in $name engine");
}
}
}

View File

@ -0,0 +1,125 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\File\ASN1;
use phpseclib\File\ASN1\Element;
use phpseclib\File\X509;
class Unit_File_X509_X509Test extends PhpseclibTestCase
{
public function testLoadUnsupportedExtension()
{
$test = '-----BEGIN CERTIFICATE-----
MIIG1jCCBL6gAwIBAgITUAAAAA0qg8bE6DhrLAAAAAAADTANBgkqhkiG9w0BAQsF
ADAiMSAwHgYDVQQDExcuU2VjdXJlIEVudGVycHJpc2UgQ0EgMTAeFw0xNTAyMjMx
NTE1MDdaFw0xNjAyMjMxNTE1MDdaMD8xFjAUBgoJkiaJk/IsZAEZFgZzZWN1cmUx
DjAMBgNVBAMTBVVzZXJzMRUwEwYDVQQDEwxtZXRhY2xhc3NpbmcwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMdG1CzR/gTalbLN9J+2cvMGeD7wsR7S78
HU5hdwE+kECROjRAcjFBOR57ezSDrkmhkTzo28tj0oAHjOh8N9vuXtASfZSCXugx
H+ImJ+E7PA4aXBp+0H2hohW9sXNNCFiVNmJLX66O4bxIeKtVRq/+eSNijV4OOEkC
zMyTHAUbOFP0t6KoJtM1syNoQ1+fKdfcjz5XtiEzSVcp2zf0MwNFSeZSgGQ0jh8A
Kd6YVKA8ZnrqOWZxKETT+bBNTjIT0ggjQfzcE4zW2RzrN7zWabUowoU92+DAp4s3
sAEywX9ISSge62DEzTnZZSf9bpoScAfT8raRFA3BkoJ/s4c4CgfPAgMBAAGjggLm
MIIC4jAdBgNVHQ4EFgQULlIyJL9+ZwAI/SkVdsJMxFOVp+EwHwYDVR0jBBgwFoAU
5nEIMEUT5mMd1WepmviwgK7dIzwwggEKBgNVHR8EggEBMIH+MIH7oIH4oIH1hoG5
bGRhcDovLy9DTj0uU2VjdXJlJTIwRW50ZXJwcmlzZSUyMENBJTIwMSxDTj1hdXRo
LENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxD
Tj1Db25maWd1cmF0aW9uLERDPXNlY3VyZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25M
aXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGN2h0dHA6
Ly9jcmwuc2VjdXJlb2JzY3VyZS5jb20vP2FjdGlvbj1jcmwmY2E9ZW50ZXJwcmlz
ZTEwgccGCCsGAQUFBwEBBIG6MIG3MIG0BggrBgEFBQcwAoaBp2xkYXA6Ly8vQ049
LlNlY3VyZSUyMEVudGVycHJpc2UlMjBDQSUyMDEsQ049QUlBLENOPVB1YmxpYyUy
MEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9
c2VjdXJlP2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0
aW9uQXV0aG9yaXR5MBcGCSsGAQQBgjcUAgQKHggAVQBzAGUAcjAOBgNVHQ8BAf8E
BAMCBaAwKQYDVR0lBCIwIAYKKwYBBAGCNwoDBAYIKwYBBQUHAwQGCCsGAQUFBwMC
MC4GA1UdEQQnMCWgIwYKKwYBBAGCNxQCA6AVDBNtZXRhY2xhc3NpbmdAc2VjdXJl
MEQGCSqGSIb3DQEJDwQ3MDUwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3DQMEAgIA
gDAHBgUrDgMCBzAKBggqhkiG9w0DBzANBgkqhkiG9w0BAQsFAAOCAgEAKNmjYh+h
cObJEM0CWgz50jOYKZ4M5iIxoAWgrYY9Pv+0O9aPjvPLzjd5bY322L8lxh5wy5my
DKmip+irzjdVdxzQfoyy+ceODmCbX9L6MfEDn0RBzdwjLe1/eOxE1na0sZztrVCc
yt5nI91NNGZJUcVqVQsIA/25FWlkvo/FTfuqTuXdQiEVM5MCKJI915anmTdugy+G
0CmBJALIxtyz5P7sZhaHZFNdpKnx82QsauErqjP9H0RXc6VXX5qt+tEDvYfSlFcc
0lv3aQnV/eIdfm7APJkQ3lmNWWQwdkVf7adXJ7KAAPHSt1yvSbVxThJR/jmIkyeQ
XW/TOP5m7JI/GrmvdlzI1AgwJ+zO8fOmCDuif99pDb1CvkzQ65RZ8p5J1ZV6hzlb
VvOhn4LDnT1jnTcEqigmx1gxM/5ifvMorXn/ItMjKPlb72vHpeF7OeKE8GHsvZAm
osHcKyJXbTIcXchmpZX1efbmCMJBqHgJ/qBTBMl9BX0+YqbTZyabRJSs9ezbTRn0
oRYl21Q8EnvS71CemxEUkSsKJmfJKkQNCsOjc8AbX/V/X9R7LJkH3UEx6K2zQQKK
k6m17mi63YW/+iPCGOWZ2qXmY5HPEyyF2L4L4IDryFJ+8xLyw3pH9/yp5aHZDtp6
833K6qyjgHJT+fUzSEYpiwF5rSBJIGClOCY=
-----END CERTIFICATE-----';
$x509 = new X509();
$cert = $x509->loadX509($test);
$this->assertEquals('MDUwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3DQMEAgIAgDAHBgUrDgMCBzAKBggqhkiG9w0DBw==', $cert['tbsCertificate']['extensions'][8]['extnValue']);
}
public function testSaveUnsupportedExtension()
{
$x509 = new X509();
$cert = $x509->loadX509('-----BEGIN CERTIFICATE-----
MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x
MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy
wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B
d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM
BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp
ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le
IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
-----END CERTIFICATE-----');
$asn1 = new ASN1();
$value = $this->encodeOID('1.2.3.4');
$ext = chr(ASN1::TYPE_OBJECT_IDENTIFIER) . $asn1->_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;
$cert['tbsCertificate']['extensions'][4] = new Element($ext);
$result = $x509->loadX509($x509->saveX509($cert));
$this->assertCount(5, $result['tbsCertificate']['extensions']);
}
function encodeOID($oid)
{
if ($oid === false) {
user_error('Invalid OID');
return false;
}
$value = '';
$parts = explode('.', $oid);
$value = chr(40 * $parts[0] + $parts[1]);
for ($i = 2; $i < count($parts); $i++) {
$temp = '';
if (!$parts[$i]) {
$temp = "\0";
} else {
while ($parts[$i]) {
$temp = chr(0x80 | ($parts[$i] & 0x7F)) . $temp;
$parts[$i] >>= 7;
}
$temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
}
$value.= $temp;
}
return $value;
}
}

View File

@ -41,9 +41,14 @@ class Unit_Net_SSH2Test extends PhpseclibTestCase
$identifier = $this->createSSHMock()->_generate_identifier();
$this->assertStringStartsWith('SSH-2.0-phpseclib_0.3', $identifier);
if (extension_loaded('mcrypt')) {
if (extension_loaded('openssl')) {
$this->assertContains('openssl', $identifier);
$this->assertNotContains('mcrypt', $identifier);
} else if (extension_loaded('mcrypt')) {
$this->assertNotContains('openssl', $identifier);
$this->assertContains('mcrypt', $identifier);
} else {
$this->assertNotContains('openssl', $identifier);
$this->assertNotContains('mcrypt', $identifier);
}

View File

@ -28,4 +28,6 @@ ssh-add "$HOME/.ssh/id_rsa"
# Allow the private key of the travis user to log in as phpseclib user
sudo mkdir -p "/home/$USERNAME/.ssh/"
sudo cp "$HOME/.ssh/id_rsa.pub" "/home/$USERNAME/.ssh/authorized_keys"
sudo ssh-keyscan -t rsa localhost > "/tmp/known_hosts"
sudo cp "/tmp/known_hosts" "/home/$USERNAME/.ssh/known_hosts"
sudo chown "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh/" -R