Fixed prime module, removed dependencies from repository, adapted for hhvm.
This commit is contained in:
parent
a505017c45
commit
e7487ab60c
1
.gitignore
vendored
1
.gitignore
vendored
@ -60,3 +60,4 @@ target/
|
||||
\#*#
|
||||
.#*#
|
||||
*.swp
|
||||
vendor
|
||||
|
@ -12,5 +12,7 @@ addons:
|
||||
packages:
|
||||
- python3
|
||||
|
||||
before_script:
|
||||
- composer update --dev
|
||||
script:
|
||||
- ./testing.php
|
||||
|
@ -9,7 +9,7 @@
|
||||
"require": {
|
||||
"danog/phpstruct": "^1.1",
|
||||
"phpseclib/phpseclib": "^2.0",
|
||||
"paragonie/constant_time_encoding": "^2.0",
|
||||
"paragonie/constant_time_encoding": "^1|^2",
|
||||
"paragonie/random_compat": "^2.0",
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
|
4
composer.lock
generated
4
composer.lock
generated
@ -4,8 +4,8 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "07a6861cc0286953f658e0d61d03c238",
|
||||
"content-hash": "0637dff4a75ae6826badf8fae267a55b",
|
||||
"hash": "8d6fcaae1bc321e5d42b8b4749ea4266",
|
||||
"content-hash": "d004c37ebd93efd29d86d09824fdd71b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "danog/phpstruct",
|
||||
|
@ -131,50 +131,42 @@ class PrimeModule
|
||||
|
||||
public function pollard_brent($n)
|
||||
{
|
||||
$zero = new \phpseclib\Math\BigInteger(0);
|
||||
$one = new \phpseclib\Math\BigInteger(1);
|
||||
$two = new \phpseclib\Math\BigInteger(2);
|
||||
$three = new \phpseclib\Math\BigInteger(3);
|
||||
if ($n->powMod($one, $two)->toString() == '0') {
|
||||
$zero = new \phpseclib\Math\BigInteger(1);
|
||||
if (Tools::posmod($n, 2) == 0) {
|
||||
return 2;
|
||||
}
|
||||
if ($n->powMod($one, $three)->toString() == '0') {
|
||||
if (Tools::posmod($n, 3) == 0) {
|
||||
return 3;
|
||||
}
|
||||
$max = new \phpseclib\Math\BigInteger($n - 1);
|
||||
$big = new \phpseclib\Math\BigInteger();
|
||||
$max = $n->subtract($one);
|
||||
list($y, $c, $m) = [new \phpseclib\Math\BigInteger(87552211475113995), new \phpseclib\Math\BigInteger(330422027228888537), new \phpseclib\Math\BigInteger(226866727920975483)];
|
||||
//[$big->random($one, $max), $big->random($one, $max), $big->random($one, $max)];
|
||||
list($g, $r, $q) = [$one, $one, $one];
|
||||
while ($g->equals($one)) {
|
||||
list($y, $c, $m) = [(int)$big->random($zero, $max)->toString(), (int)$big->random($zero, $max)->toString(), (int)$big->random($zero, $max)->toString()];
|
||||
list($g, $r, $q) = [1, 1, 1];
|
||||
do {
|
||||
$x = $y;
|
||||
$params = ['y' => $y, 'two' => $two, 'c' => $c, 'one' => $one, 'n' => $n];
|
||||
$r->loopforeach(function ($i, $params) {
|
||||
$params['y'] = $params['y']->powMod($params['two'], $params['n'])->add($params['c'])->powMod($params['one'], $params['n']);
|
||||
}, $params);
|
||||
each($params);
|
||||
$k = $zero;
|
||||
while ($k->compare($r) == -1 && $g->equals($one)) {
|
||||
$i = 0;
|
||||
do {
|
||||
$i++;
|
||||
$y = Tools::posmod(Tools::posmod(pow($y, 2), $n) + $c, $n);
|
||||
} while ($i < $r);
|
||||
$k = 0;
|
||||
do {
|
||||
$ys = $y;
|
||||
$params = ['x' => $x, 'y' => $y, 'two' => $two, 'c' => $c, 'one' => $one, 'n' => $n, 'q' => $q];
|
||||
$m->min($r->subtract($k))->loopforeach(function ($i, $params) {
|
||||
$params['y'] = $params['y']->powMod($params['two'], $params['n'])->add($params['c'])->powMod($params['one'], $params['n']);
|
||||
$params['q'] = $params['q']->multiply($params['x']->subtract($params['y'])->abs())->powMod($params['one'], $params['n']);
|
||||
}, $params);
|
||||
each($params);
|
||||
$g = $q->gcd($n);
|
||||
$k = $k->add($m);
|
||||
}
|
||||
$r = $r->multiply($two);
|
||||
}
|
||||
die;
|
||||
if ($g->equals($n)) {
|
||||
do {
|
||||
$y = Tools::posmod(Tools::posmod(pow($y, 2), $n) + $c, $n);
|
||||
$q = Tools::posmod($q * abs($x - $y), $n);
|
||||
} while(min($m, $r - $k));
|
||||
$g = $this->gcd($q, $n);
|
||||
$k += $m;
|
||||
} while ($k < $r and $g == 1);
|
||||
$r *= 2;
|
||||
} while ($g == 1);
|
||||
|
||||
if ($g == $n) {
|
||||
while (true) {
|
||||
$ys = $ys->powMod($two, $n)->add($c)->powMod($one, $n);
|
||||
$g = $x->subtract($ys)->abs()->gcd($n);
|
||||
if ($g->compare($one) == 1) {
|
||||
break;
|
||||
}
|
||||
$ys = Tools::posmod(Tools::posmod(pow($ys, 2), $n) + $c, $n);
|
||||
$g = $this->gcd(abs($x - $ys), $n);
|
||||
if ($g > 1) break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,11 +178,11 @@ class PrimeModule
|
||||
if (function_exists('shell_exec')) {
|
||||
try {
|
||||
// Use the python version.
|
||||
$res = explode(' ', shell_exec('python '.__DIR__.'/getpq.py '.$pq));
|
||||
$res = json_decode(shell_exec('python '.__DIR__.'/getpq.py '.(string)$pq));
|
||||
if (count($res) == 2) {
|
||||
return $res;
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
// Else do factorization with wolfram alpha :)))))
|
||||
@ -221,7 +213,10 @@ class PrimeModule
|
||||
if (count($res) == 2) {
|
||||
return $res;
|
||||
}
|
||||
$n = (int) $n->toString();
|
||||
if(is_object($pq)) {
|
||||
$n = $pq->toString();
|
||||
} else $n = $pq;
|
||||
$n = (int) $n;
|
||||
$factors = [];
|
||||
$limit = sqrt($n) + 1;
|
||||
foreach ($this->smallprimes as $checker) {
|
||||
|
@ -23,7 +23,7 @@ class RSA extends TL\TL
|
||||
public function __construct($key)
|
||||
{
|
||||
$this->key = new \phpseclib\Crypt\RSA();
|
||||
$this->key->load($key);
|
||||
$this->key->loadKey($key);
|
||||
$this->n = $this->key->modulus;
|
||||
$this->e = $this->key->exponent;
|
||||
|
||||
|
@ -262,7 +262,8 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
||||
if ($p->compare($q) > 0) {
|
||||
list($p, $q) = [$q, $p];
|
||||
}
|
||||
if (!(($pq->equals($p->multiply($q))) && ($p < $q))) {
|
||||
var_dump($p, $q);
|
||||
if (!($pq->equals($p->multiply($q)) && $p->compare($q) < 0)) {
|
||||
throw new Exception("Handshake: couldn't compute p and q.");
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
import prime
|
||||
import sys
|
||||
pq = prime.primefactors(int(sys.argv[1]))
|
||||
sys.stdout.write(str(pq[0]) + " " + str(pq[1]))
|
||||
import json
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
pq = prime.primefactors(long(sys.argv[1]))
|
||||
|
||||
sys.stdout.write(json.dumps(pq))
|
||||
sys.stdout.flush()
|
||||
|
@ -54,8 +54,7 @@ def pollard_brent(n):
|
||||
if n % 2 == 0: return 2
|
||||
if n % 3 == 0: return 3
|
||||
|
||||
y, c, m = 87552211475113995, 330422027228888537, 226866727920975483
|
||||
#random.randint(1, n-1), random.randint(1, n-1), random.randint(1, n-1)
|
||||
y, c, m = random.randint(1, n-1), random.randint(1, n-1), random.randint(1, n-1)
|
||||
|
||||
g, r, q = 1, 1, 1
|
||||
while g == 1:
|
||||
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@ -4,4 +4,4 @@
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitbd69ed7fd0aebb6b1ba64b36dad1b458::getLoader();
|
||||
return ComposerAutoloaderInit5d4506c3f77f3e7aec8a380bfc1c8cd6::getLoader();
|
||||
|
14
vendor/composer/autoload_real.php
vendored
14
vendor/composer/autoload_real.php
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitbd69ed7fd0aebb6b1ba64b36dad1b458
|
||||
class ComposerAutoloaderInit5d4506c3f77f3e7aec8a380bfc1c8cd6
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
@ -19,15 +19,15 @@ class ComposerAutoloaderInitbd69ed7fd0aebb6b1ba64b36dad1b458
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitbd69ed7fd0aebb6b1ba64b36dad1b458', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit5d4506c3f77f3e7aec8a380bfc1c8cd6', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitbd69ed7fd0aebb6b1ba64b36dad1b458', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit5d4506c3f77f3e7aec8a380bfc1c8cd6', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitbd69ed7fd0aebb6b1ba64b36dad1b458::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit5d4506c3f77f3e7aec8a380bfc1c8cd6::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
@ -48,19 +48,19 @@ class ComposerAutoloaderInitbd69ed7fd0aebb6b1ba64b36dad1b458
|
||||
$loader->register(true);
|
||||
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInitbd69ed7fd0aebb6b1ba64b36dad1b458::$files;
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit5d4506c3f77f3e7aec8a380bfc1c8cd6::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequirebd69ed7fd0aebb6b1ba64b36dad1b458($fileIdentifier, $file);
|
||||
composerRequire5d4506c3f77f3e7aec8a380bfc1c8cd6($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequirebd69ed7fd0aebb6b1ba64b36dad1b458($fileIdentifier, $file)
|
||||
function composerRequire5d4506c3f77f3e7aec8a380bfc1c8cd6($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
8
vendor/composer/autoload_static.php
vendored
8
vendor/composer/autoload_static.php
vendored
@ -4,7 +4,7 @@
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInitbd69ed7fd0aebb6b1ba64b36dad1b458
|
||||
class ComposerStaticInit5d4506c3f77f3e7aec8a380bfc1c8cd6
|
||||
{
|
||||
public static $files = array (
|
||||
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
||||
@ -50,9 +50,9 @@ class ComposerStaticInitbd69ed7fd0aebb6b1ba64b36dad1b458
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitbd69ed7fd0aebb6b1ba64b36dad1b458::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitbd69ed7fd0aebb6b1ba64b36dad1b458::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInitbd69ed7fd0aebb6b1ba64b36dad1b458::$prefixesPsr0;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit5d4506c3f77f3e7aec8a380bfc1c8cd6::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit5d4506c3f77f3e7aec8a380bfc1c8cd6::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInit5d4506c3f77f3e7aec8a380bfc1c8cd6::$prefixesPsr0;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
100
vendor/composer/installed.json
vendored
100
vendor/composer/installed.json
vendored
@ -1,4 +1,54 @@
|
||||
[
|
||||
{
|
||||
"name": "danog/phpstruct",
|
||||
"version": "1.1",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/danog/PHPStruct.git",
|
||||
"reference": "ac1d7a0b1eb54d5b10dca553be816c8fb0881e47"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/danog/PHPStruct/zipball/ac1d7a0b1eb54d5b10dca553be816c8fb0881e47",
|
||||
"reference": "ac1d7a0b1eb54d5b10dca553be816c8fb0881e47",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.4.*"
|
||||
},
|
||||
"time": "2016-07-29 15:13:54",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"danog\\PHP\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "danog",
|
||||
"email": "daniil@daniil.it"
|
||||
}
|
||||
],
|
||||
"description": "PHP implementation of python's struct module.",
|
||||
"homepage": "https://daniil.it/phpstruct",
|
||||
"keywords": [
|
||||
"byte",
|
||||
"bytes",
|
||||
"pack",
|
||||
"python",
|
||||
"struct",
|
||||
"unpack"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "2.0.2",
|
||||
@ -93,56 +143,6 @@
|
||||
"x509"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "danog/phpstruct",
|
||||
"version": "1.1",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/danog/PHPStruct.git",
|
||||
"reference": "ac1d7a0b1eb54d5b10dca553be816c8fb0881e47"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/danog/PHPStruct/zipball/ac1d7a0b1eb54d5b10dca553be816c8fb0881e47",
|
||||
"reference": "ac1d7a0b1eb54d5b10dca553be816c8fb0881e47",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.4.*"
|
||||
},
|
||||
"time": "2016-07-29 15:13:54",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"danog\\PHP\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "danog",
|
||||
"email": "daniil@daniil.it"
|
||||
}
|
||||
],
|
||||
"description": "PHP implementation of python's struct module.",
|
||||
"homepage": "https://daniil.it/phpstruct",
|
||||
"keywords": [
|
||||
"byte",
|
||||
"bytes",
|
||||
"pack",
|
||||
"python",
|
||||
"struct",
|
||||
"unpack"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v2.0.3",
|
||||
|
160
vendor/phpseclib/phpseclib/CHANGELOG.md
vendored
160
vendor/phpseclib/phpseclib/CHANGELOG.md
vendored
@ -1,160 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## 2.0.2 - 2016-06-04
|
||||
|
||||
- All Ciphers: fix issue with CBC mode / OpenSSL / continuous buffers / decryption (#938)
|
||||
- Random: fix issues with serialize() (#932)
|
||||
- RC2: fix issue with decrypting
|
||||
- RC4: fix issue with key not being truncated correctly
|
||||
- SFTP: nlist() on a non-existant directory resulted in error
|
||||
- SFTP: add is_writable, is_writeable, is_readable
|
||||
- X509: add IPv6 support for subjectaltname extension (#936)
|
||||
|
||||
## 2.0.1 - 2016-01-18
|
||||
|
||||
- RSA: fix regression in PSS mode ([#769](https://github.com/phpseclib/phpseclib/pull/769))
|
||||
- RSA: fix issue loading PKCS8 specific keys ([#861](https://github.com/phpseclib/phpseclib/pull/861))
|
||||
- X509: add getOID() method ([#789](https://github.com/phpseclib/phpseclib/pull/789))
|
||||
- X509: improve base64-encoded detection rules ([#855](https://github.com/phpseclib/phpseclib/pull/855))
|
||||
- SFTP: fix quirky behavior with put() ([#830](https://github.com/phpseclib/phpseclib/pull/830))
|
||||
- SFTP: fix E_NOTICE ([#883](https://github.com/phpseclib/phpseclib/pull/883))
|
||||
- SFTP/Stream: fix issue with filenames with hashes ([#901](https://github.com/phpseclib/phpseclib/pull/901))
|
||||
- SSH2: add isAuthenticated() method ([#897](https://github.com/phpseclib/phpseclib/pull/897))
|
||||
- SSH/Agent: fix possible PHP warning ([#923](https://github.com/phpseclib/phpseclib/issues/923))
|
||||
- BigInteger: add __debugInfo() magic method ([#881](https://github.com/phpseclib/phpseclib/pull/881))
|
||||
- BigInteger: fix issue with doing bitwise not on 0
|
||||
- add getBlockLength() method to symmetric ciphers
|
||||
|
||||
## 2.0.0 - 2015-08-04
|
||||
|
||||
- Classes were renamed and namespaced ([#243](https://github.com/phpseclib/phpseclib/issues/243))
|
||||
- The use of an autoloader is now required (e.g. Composer)
|
||||
|
||||
## 1.0.2 - 2016-05-07
|
||||
|
||||
- All Ciphers: fix issue with CBC mode / OpenSSL / continuous buffers / decryption (#938)
|
||||
- Random: fix issues with serialize() (#932)
|
||||
- RC2: fix issue with decrypting
|
||||
- RC4: fix issue with key not being truncated correctly
|
||||
- SFTP: nlist() on a non-existant directory resulted in error
|
||||
- SFTP: add is_writable, is_writeable, is_readable
|
||||
- RSA: fix PHP4 compatability issue
|
||||
|
||||
## 1.0.1 - 2016-01-18
|
||||
|
||||
- RSA: fix regression in PSS mode ([#769](https://github.com/phpseclib/phpseclib/pull/769))
|
||||
- RSA: fix issue loading PKCS8 specific keys ([#861](https://github.com/phpseclib/phpseclib/pull/861))
|
||||
- X509: add getOID() method ([#789](https://github.com/phpseclib/phpseclib/pull/789))
|
||||
- X509: improve base64-encoded detection rules ([#855](https://github.com/phpseclib/phpseclib/pull/855))
|
||||
- SFTP: fix quirky behavior with put() ([#830](https://github.com/phpseclib/phpseclib/pull/830))
|
||||
- SFTP: fix E_NOTICE ([#883](https://github.com/phpseclib/phpseclib/pull/883))
|
||||
- SFTP/Stream: fix issue with filenames with hashes ([#901](https://github.com/phpseclib/phpseclib/pull/901))
|
||||
- SSH2: add isAuthenticated() method ([#897](https://github.com/phpseclib/phpseclib/pull/897))
|
||||
- SSH/Agent: fix possible PHP warning ([#923](https://github.com/phpseclib/phpseclib/issues/923))
|
||||
- BigInteger: add __debugInfo() magic method ([#881](https://github.com/phpseclib/phpseclib/pull/881))
|
||||
- BigInteger: fix issue with doing bitwise not on 0
|
||||
- add getBlockLength() method to symmetric ciphers
|
||||
|
||||
## 1.0.0 - 2015-08-02
|
||||
|
||||
- OpenSSL support for symmetric ciphers ([#507](https://github.com/phpseclib/phpseclib/pull/507))
|
||||
- rewritten vt100 terminal emulator (File_ANSI) ([#689](https://github.com/phpseclib/phpseclib/pull/689))
|
||||
- agent-forwarding support (System_SSH_Agent) ([#592](https://github.com/phpseclib/phpseclib/pull/592))
|
||||
- Net_SSH2 improvements
|
||||
- diffie-hellman-group-exchange-sha1/sha256 support ([#714](https://github.com/phpseclib/phpseclib/pull/714))
|
||||
- window size handling updates ([#717](https://github.com/phpseclib/phpseclib/pull/717))
|
||||
- Net_SFTP improvements
|
||||
- add callback support to put() ([#655](https://github.com/phpseclib/phpseclib/pull/655))
|
||||
- stat cache fixes ([#743](https://github.com/phpseclib/phpseclib/issues/743), [#730](https://github.com/phpseclib/phpseclib/issues/730), [#709](https://github.com/phpseclib/phpseclib/issues/709), [#726](https://github.com/phpseclib/phpseclib/issues/726))
|
||||
- add "none" encryption mode to Crypt_RSA ([#692](https://github.com/phpseclib/phpseclib/pull/692))
|
||||
- misc ASN.1 / X.509 parsing fixes ([#721](https://github.com/phpseclib/phpseclib/pull/721), [#627](https://github.com/phpseclib/phpseclib/pull/627))
|
||||
- use a random serial number for new X509 certs ([#740](https://github.com/phpseclib/phpseclib/pull/740))
|
||||
- add getPublicKeyFingerprint() to Crypt_RSA ([#677](https://github.com/phpseclib/phpseclib/pull/677))
|
||||
|
||||
## 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))
|
||||
|
||||
## 0.3.8 - 2014-09-12
|
||||
|
||||
- improve support for indef lengths in File_ASN1
|
||||
- add hmac-sha2-256 support to Net_SSH2
|
||||
- make it so negotiated algorithms can be seen before Net_SSH2 login
|
||||
- add sha256-96 and sha512-96 to Crypt_Hash
|
||||
- window size handling adjustments in Net_SSH2
|
||||
|
||||
## 0.3.7 - 2014-07-05
|
||||
|
||||
- auto-detect public vs private keys
|
||||
- add file_exists, is_dir, is_file, readlink and symlink to Net_SFTP
|
||||
- add support for recursive nlist and rawlist
|
||||
- make it so nlist and rawlist can return pre-sorted output
|
||||
- make it so callback functions can make exec() return early
|
||||
- add signSPKAC and saveSPKAC methods to File_X509
|
||||
- add support for PKCS8 keys in Crypt_RSA
|
||||
- add pbkdf1 support to setPassword() in Crypt_Base
|
||||
- add getWindowColumns, getWindowRows, setWindowColumns, setWindowRows to Net_SSH2
|
||||
- add support for filenames with spaces in them to Net_SCP
|
||||
|
||||
## 0.3.6 - 2014-02-23
|
||||
|
||||
- add preliminary support for custom SSH subsystems
|
||||
- add ssh-agent support
|
||||
|
||||
## 0.3.5 - 2013-07-11
|
||||
|
||||
- numerous SFTP changes:
|
||||
- chown
|
||||
- chgrp
|
||||
- truncate
|
||||
- improved file type detection
|
||||
- put() can write to te middle of a file
|
||||
- mkdir accepts the same paramters that PHP's mkdir does
|
||||
- the ability to upload/download 2GB files
|
||||
- across-the-board speedups for the various encryption algorithms
|
||||
- multi-factor authentication support for Net_SSH2
|
||||
- a $callback parameter for Net_SSH2::exec
|
||||
- new classes:
|
||||
- Net_SFTP_StreamWrapper
|
||||
- Net_SCP
|
||||
- Crypt_Twofish
|
||||
- Crypt_Blowfish
|
||||
|
||||
## 0.3.1 - 2012-11-20
|
||||
|
||||
- add Net_SSH2::enableQuietMode() for suppressing stderr
|
||||
- add Crypt_RSA::__toString() and Crypt_RSA::getSize()
|
||||
- fix problems with File_X509::validateDate(), File_X509::sign() and Crypt_RSA::verify()
|
||||
- use OpenSSL to speed up modular exponention in Math_BigInteger
|
||||
- improved timeout functionality in Net_SSH2
|
||||
- add support for SFTPv2
|
||||
- add support for CRLs in File_X509
|
||||
- SSH-2.0-SSH doesn't implement hmac-*-96 correctly
|
||||
|
||||
## 0.3.0 - 2012-07-08
|
||||
|
||||
- add support for reuming Net_SFTP::put()
|
||||
- add support for recursive deletes and recursive chmods to Net_SFTP
|
||||
- add setTimeout() to Net_SSH2
|
||||
- add support for PBKDF2 to the various Crypt_* classes via setPassword()
|
||||
- add File_X509 and File_ASN1
|
||||
- add the ability to decode various formats in Crypt_RSA
|
||||
- make Net_SSH2::getServerPublicHostKey() return a printer-friendly version of the public key
|
||||
|
||||
## 0.2.2 - 2011-05-09
|
||||
|
||||
- CFB and OFB modes were added to all block ciphers
|
||||
- support for interactive mode was added to Net_SSH2
|
||||
- Net_SSH2 now has limited keyboard_interactive authentication support
|
||||
- support was added for PuTTY formatted RSA private keys and XML formatted RSA private keys
|
||||
- Crypt_RSA::loadKey() will now try all key types automatically
|
||||
= add support for AES-128-CBC and DES-EDE3-CFB encrypted RSA private keys
|
||||
- add Net_SFTP::stat(), Net_SFTP::lstat() and Net_SFTP::rawlist()
|
||||
- logging was added to Net_SSH1
|
||||
- the license was changed to the less restrictive MIT license
|
6
vendor/phpseclib/phpseclib/README.md
vendored
6
vendor/phpseclib/phpseclib/README.md
vendored
@ -1,6 +1,6 @@
|
||||
# phpseclib - PHP Secure Communications Library
|
||||
|
||||
[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=master)](https://travis-ci.org/phpseclib/phpseclib)
|
||||
[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.org/phpseclib/phpseclib)
|
||||
|
||||
MIT-licensed pure-PHP implementations of an arbitrary-precision integer
|
||||
arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
|
||||
@ -8,7 +8,7 @@ AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
|
||||
|
||||
* [Download (1.0.2)](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.2.zip/download)
|
||||
* [Browse Git](https://github.com/phpseclib/phpseclib)
|
||||
* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/master/latest/)
|
||||
* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/2.0/latest/)
|
||||
|
||||
<img src="http://phpseclib.sourceforge.net/pear-icon.png" alt="PEAR Channel" width="16" height="16">
|
||||
PEAR Channel: [phpseclib.sourceforge.net](http://phpseclib.sourceforge.net/pear.htm)
|
||||
@ -16,7 +16,7 @@ PEAR Channel: [phpseclib.sourceforge.net](http://phpseclib.sourceforge.net/pear.
|
||||
## Documentation
|
||||
|
||||
* [Documentation / Manual](http://phpseclib.sourceforge.net/)
|
||||
* [API Documentation](http://phpseclib.bantux.org/api/master/) (generated by Sami)
|
||||
* [API Documentation](http://phpseclib.bantux.org/api/2.0/) (generated by Sami)
|
||||
|
||||
## Support
|
||||
|
||||
|
2
vendor/phpseclib/phpseclib/composer.json
vendored
2
vendor/phpseclib/phpseclib/composer.json
vendored
@ -51,8 +51,6 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"paragonie/constant_time_encoding": "^1|^2",
|
||||
"paragonie/random_compat": "^1.4|^2.0",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
|
441
vendor/phpseclib/phpseclib/composer.lock
generated
vendored
441
vendor/phpseclib/phpseclib/composer.lock
generated
vendored
@ -4,120 +4,9 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "422b05a6ce122760976256ff21e9381b",
|
||||
"content-hash": "3bd75e9c1741d7c0c0930855e5b96abb",
|
||||
"packages": [
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||
"reference": "d96e63b79a7135a65659ba5b1cb02826172bfedd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d96e63b79a7135a65659ba5b1cb02826172bfedd",
|
||||
"reference": "d96e63b79a7135a65659ba5b1cb02826172bfedd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3|^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"paragonie/random_compat": "^1.4|^2.0",
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ParagonIE\\ConstantTime\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com",
|
||||
"role": "Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "Steve 'Sc00bz' Thomas",
|
||||
"email": "steve@tobtu.com",
|
||||
"homepage": "https://www.tobtu.com",
|
||||
"role": "Original Developer"
|
||||
}
|
||||
],
|
||||
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
|
||||
"keywords": [
|
||||
"base16",
|
||||
"base32",
|
||||
"base32_decode",
|
||||
"base32_encode",
|
||||
"base64",
|
||||
"base64_decode",
|
||||
"base64_encode",
|
||||
"bin2hex",
|
||||
"encoding",
|
||||
"hex",
|
||||
"hex2bin",
|
||||
"rfc4648"
|
||||
],
|
||||
"time": "2016-06-13 01:00:24"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
|
||||
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2016-04-03 06:00:07"
|
||||
}
|
||||
],
|
||||
"hash": "8599992bf6058a9da82372eb8bcae2c2",
|
||||
"content-hash": "fde47c84178c55c06de858a2128e3d07",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
@ -360,136 +249,39 @@
|
||||
],
|
||||
"time": "2016-03-10 21:39:23"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
"version": "1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
|
||||
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
|
||||
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jaap van Otterdijk",
|
||||
"email": "opensource@ijaap.nl"
|
||||
}
|
||||
],
|
||||
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
|
||||
"homepage": "http://www.phpdoc.org",
|
||||
"keywords": [
|
||||
"FQSEN",
|
||||
"phpDocumentor",
|
||||
"phpdoc",
|
||||
"reflection",
|
||||
"static analysis"
|
||||
],
|
||||
"time": "2015-12-27 11:43:31"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "3.1.0",
|
||||
"version": "2.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||
"reference": "9270140b940ff02e58ec577c237274e92cd40cdd"
|
||||
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd",
|
||||
"reference": "9270140b940ff02e58ec577c237274e92cd40cdd",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"phpdocumentor/reflection-common": "^1.0@dev",
|
||||
"phpdocumentor/type-resolver": "^0.2.0",
|
||||
"webmozart/assert": "^1.0"
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.4",
|
||||
"phpunit/phpunit": "^4.4"
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike van Riel",
|
||||
"email": "me@mikevanriel.com"
|
||||
}
|
||||
],
|
||||
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||
"time": "2016-06-10 09:48:41"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
"version": "0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443",
|
||||
"reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"phpdocumentor/reflection-common": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.4",
|
||||
"phpunit/phpunit": "^5.2||^4.8.24"
|
||||
"suggest": {
|
||||
"dflydev/markdown": "~1.0",
|
||||
"erusev/parsedown": "~1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": [
|
||||
"psr-0": {
|
||||
"phpDocumentor": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
@ -501,39 +293,39 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike van Riel",
|
||||
"email": "me@mikevanriel.com"
|
||||
"email": "mike.vanriel@naenius.com"
|
||||
}
|
||||
],
|
||||
"time": "2016-06-10 07:14:17"
|
||||
"time": "2015-02-03 12:10:50"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.6.1",
|
||||
"version": "v1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "58a8137754bc24b25740d4281399a4a3596058e0"
|
||||
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
|
||||
"reference": "58a8137754bc24b25740d4281399a4a3596058e0",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
|
||||
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.0.2",
|
||||
"php": "^5.3|^7.0",
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
|
||||
"sebastian/comparator": "^1.1",
|
||||
"sebastian/recursion-context": "^1.0"
|
||||
"phpdocumentor/reflection-docblock": "~2.0",
|
||||
"sebastian/comparator": "~1.1",
|
||||
"sebastian/recursion-context": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.0"
|
||||
"phpspec/phpspec": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.6.x-dev"
|
||||
"dev-master": "1.5.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -566,7 +358,7 @@
|
||||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2016-06-07 08:13:47"
|
||||
"time": "2016-02-15 07:46:21"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@ -720,24 +512,21 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-timer",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
||||
"reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
|
||||
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
|
||||
"reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
|
||||
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4|~5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
@ -760,7 +549,7 @@
|
||||
"keywords": [
|
||||
"timer"
|
||||
],
|
||||
"time": "2016-05-12 18:03:57"
|
||||
"time": "2015-06-21 08:01:12"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
@ -813,16 +602,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "4.8.26",
|
||||
"version": "4.8.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "fc1d8cd5b5de11625979125c5639347896ac2c74"
|
||||
"reference": "a1066c562c52900a142a0e2bbf0582994671385e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc1d8cd5b5de11625979125c5639347896ac2c74",
|
||||
"reference": "fc1d8cd5b5de11625979125c5639347896ac2c74",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
|
||||
"reference": "a1066c562c52900a142a0e2bbf0582994671385e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -836,7 +625,7 @@
|
||||
"phpunit/php-code-coverage": "~2.1",
|
||||
"phpunit/php-file-iterator": "~1.4",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
"phpunit/php-timer": "^1.0.6",
|
||||
"phpunit/php-timer": ">=1.0.6",
|
||||
"phpunit/phpunit-mock-objects": "~2.3",
|
||||
"sebastian/comparator": "~1.1",
|
||||
"sebastian/diff": "~1.2",
|
||||
@ -881,7 +670,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2016-05-17 03:09:28"
|
||||
"time": "2016-03-14 06:16:08"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
@ -1160,16 +949,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
"version": "1.3.7",
|
||||
"version": "1.3.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716"
|
||||
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716",
|
||||
"reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
|
||||
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1206,20 +995,20 @@
|
||||
"environment",
|
||||
"hhvm"
|
||||
],
|
||||
"time": "2016-05-17 03:18:57"
|
||||
"time": "2016-02-26 18:40:46"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
|
||||
"reference": "7ae5513327cb536431847bcc0c10edba2701064e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
|
||||
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
|
||||
"reference": "7ae5513327cb536431847bcc0c10edba2701064e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1227,13 +1016,12 @@
|
||||
"sebastian/recursion-context": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-mbstring": "*",
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3.x-dev"
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1273,7 +1061,7 @@
|
||||
"export",
|
||||
"exporter"
|
||||
],
|
||||
"time": "2016-06-17 09:04:28"
|
||||
"time": "2015-06-21 07:55:53"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
@ -1416,16 +1204,16 @@
|
||||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||
"reference": "fb72ed32f8418db5e7770be1653e62e0d6f5dd3d"
|
||||
"reference": "1bcdf03b068a530ac1962ce671dead356eeba43b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/fb72ed32f8418db5e7770be1653e62e0d6f5dd3d",
|
||||
"reference": "fb72ed32f8418db5e7770be1653e62e0d6f5dd3d",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1bcdf03b068a530ac1962ce671dead356eeba43b",
|
||||
"reference": "1bcdf03b068a530ac1962ce671dead356eeba43b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1490,20 +1278,20 @@
|
||||
"phpcs",
|
||||
"standards"
|
||||
],
|
||||
"time": "2016-05-30 22:24:32"
|
||||
"time": "2016-04-03 22:58:34"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.8.7",
|
||||
"version": "v2.8.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3"
|
||||
"reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3",
|
||||
"reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154",
|
||||
"reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1550,20 +1338,20 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-06-06 15:06:25"
|
||||
"time": "2016-03-17 09:19:04"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v2.8.7",
|
||||
"version": "v2.8.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "dee379131dceed90a429e951546b33edfe7dccbb"
|
||||
"reference": "f08ffdf229252cd2745558cb2112df43903bcae4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/dee379131dceed90a429e951546b33edfe7dccbb",
|
||||
"reference": "dee379131dceed90a429e951546b33edfe7dccbb",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4",
|
||||
"reference": "f08ffdf229252cd2745558cb2112df43903bcae4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1599,20 +1387,20 @@
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-04-12 18:01:21"
|
||||
"time": "2016-03-27 10:20:16"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v2.8.7",
|
||||
"version": "v2.8.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "3ec095fab1800222732ca522a95dce8fa124007b"
|
||||
"reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/3ec095fab1800222732ca522a95dce8fa124007b",
|
||||
"reference": "3ec095fab1800222732ca522a95dce8fa124007b",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/ca24cf2cd4e3826f571e0067e535758e73807aa1",
|
||||
"reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1648,20 +1436,20 @@
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-06-06 11:11:27"
|
||||
"time": "2016-03-10 10:53:53"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.2.0",
|
||||
"version": "v1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "dff51f72b0706335131b00a7f49606168c582594"
|
||||
"reference": "1289d16209491b584839022f29257ad859b8532d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
|
||||
"reference": "dff51f72b0706335131b00a7f49606168c582594",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
|
||||
"reference": "1289d16209491b584839022f29257ad859b8532d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1673,7 +1461,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2-dev"
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1707,20 +1495,20 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-05-18 14:26:46"
|
||||
"time": "2016-01-20 09:13:37"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.8.7",
|
||||
"version": "v2.8.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "115347d00c342198cdc52a7bd8bc15b5ab43500c"
|
||||
"reference": "fb467471952ef5cf8497c029980e556b47545333"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/115347d00c342198cdc52a7bd8bc15b5ab43500c",
|
||||
"reference": "115347d00c342198cdc52a7bd8bc15b5ab43500c",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333",
|
||||
"reference": "fb467471952ef5cf8497c029980e556b47545333",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1756,20 +1544,20 @@
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-06-06 11:11:27"
|
||||
"time": "2016-03-23 13:11:46"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.8.7",
|
||||
"version": "v2.8.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "815fabf3f48c7d1df345a69d1ad1a88f59757b34"
|
||||
"reference": "584e52cb8f788a887553ba82db6caacb1d6260bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/815fabf3f48c7d1df345a69d1ad1a88f59757b34",
|
||||
"reference": "815fabf3f48c7d1df345a69d1ad1a88f59757b34",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb",
|
||||
"reference": "584e52cb8f788a887553ba82db6caacb1d6260bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1805,20 +1593,20 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-06-06 11:11:27"
|
||||
"time": "2016-03-04 07:54:35"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.24.1",
|
||||
"version": "v1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "3566d311a92aae4deec6e48682dc5a4528c4a512"
|
||||
"reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512",
|
||||
"reference": "3566d311a92aae4deec6e48682dc5a4528c4a512",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
|
||||
"reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1866,56 +1654,7 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2016-05-30 09:11:59"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/assert.git",
|
||||
"reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
|
||||
"reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\Assert\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Assertions to validate method input/output with nice error messages.",
|
||||
"keywords": [
|
||||
"assert",
|
||||
"check",
|
||||
"validate"
|
||||
],
|
||||
"time": "2015-08-24 13:29:44"
|
||||
"time": "2016-01-25 21:22:18"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
@ -66,32 +66,30 @@ class AES extends Rijndael
|
||||
* @see \phpseclib\Crypt\Rijndael::setBlockLength()
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \BadMethodCallException anytime it's called
|
||||
*/
|
||||
function setBlockLength($length)
|
||||
{
|
||||
throw new \BadMethodCallException('The block length cannot be set for AES.');
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length
|
||||
* Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
|
||||
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael:setKeyLength()
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
case 160:
|
||||
$length = 192;
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported');
|
||||
case 224:
|
||||
$length = 256;
|
||||
}
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
@ -105,19 +103,24 @@ class AES extends Rijndael
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
|
||||
if (!$this->explicit_key_length) {
|
||||
$length = strlen($key);
|
||||
switch (true) {
|
||||
case $length <= 16:
|
||||
$this->key_length = 16;
|
||||
break;
|
||||
case $length <= 24:
|
||||
$this->key_length = 24;
|
||||
break;
|
||||
default:
|
||||
$this->key_length = 32;
|
||||
}
|
||||
$this->_setEngine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
154
vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
vendored
154
vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
vendored
@ -139,7 +139,7 @@ abstract class Base
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = false;
|
||||
var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
|
||||
/**
|
||||
* The Initialization Vector
|
||||
@ -148,7 +148,7 @@ abstract class Base
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $iv = false;
|
||||
var $iv;
|
||||
|
||||
/**
|
||||
* A "sliding" Initialization Vector
|
||||
@ -429,15 +429,6 @@ abstract class Base
|
||||
*/
|
||||
var $openssl_options;
|
||||
|
||||
/**
|
||||
* Don't truncate / null pad key
|
||||
*
|
||||
* @see self::_clearBuffers()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $skip_key_adjustment = false;
|
||||
|
||||
/**
|
||||
* Has the key length explicitly been set or should it be derived from the key, itself?
|
||||
*
|
||||
@ -447,9 +438,20 @@ abstract class Base
|
||||
*/
|
||||
var $explicit_key_length = false;
|
||||
|
||||
/**
|
||||
* Don't truncate / null pad key
|
||||
*
|
||||
* @see self::_clearBuffers()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $skip_key_adjustment = false;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - self::MODE_ECB
|
||||
@ -462,29 +464,32 @@ abstract class Base
|
||||
*
|
||||
* - self::MODE_OFB
|
||||
*
|
||||
* If not explicitly set, self::MODE_CBC will be used.
|
||||
*
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function __construct($mode)
|
||||
function __construct($mode = self::MODE_CBC)
|
||||
{
|
||||
// $mode dependent settings
|
||||
switch ($mode) {
|
||||
case self::MODE_ECB:
|
||||
case self::MODE_CBC:
|
||||
$this->paddable = true;
|
||||
$this->mode = self::MODE_ECB;
|
||||
break;
|
||||
case self::MODE_CTR:
|
||||
case self::MODE_CFB:
|
||||
case self::MODE_OFB:
|
||||
case self::MODE_STREAM:
|
||||
$this->paddable = false;
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
case self::MODE_CBC:
|
||||
default:
|
||||
throw new \InvalidArgumentException('No valid mode has been specified');
|
||||
$this->paddable = true;
|
||||
$this->mode = self::MODE_CBC;
|
||||
}
|
||||
|
||||
$this->mode = $mode;
|
||||
$this->_setEngine();
|
||||
|
||||
// Determining whether inline crypting can be used by the cipher
|
||||
if ($this->use_inline_crypt !== false && function_exists('create_function')) {
|
||||
@ -493,28 +498,19 @@ abstract class Base
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector.
|
||||
* Sets the initialization vector. (optional)
|
||||
*
|
||||
* setIV() is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used.
|
||||
* SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used. If not explicitly set, it'll be assumed
|
||||
* to be all zero's.
|
||||
*
|
||||
* @access public
|
||||
* @param string $iv
|
||||
* @throws \LengthException if the IV length isn't equal to the block size
|
||||
* @throws \InvalidArgumentException if an IV is provided when one shouldn't be
|
||||
* @internal Can be overwritten by a sub class, but does not have to be
|
||||
*/
|
||||
function setIV($iv)
|
||||
{
|
||||
if ($this->mode == self::MODE_ECB) {
|
||||
throw new \InvalidArgumentException('This mode does not require an IV.');
|
||||
}
|
||||
|
||||
if ($this->mode == self::MODE_STREAM && $this->usesIV()) {
|
||||
throw new \InvalidArgumentException('This algorithm does not use an IV.');
|
||||
}
|
||||
|
||||
if (strlen($iv) != $this->block_size) {
|
||||
throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->iv = $iv;
|
||||
@ -522,14 +518,18 @@ abstract class Base
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the algorithm uses an IV
|
||||
* Sets the key length.
|
||||
*
|
||||
* Keys with explicitly set lengths need to be treated accordingly
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
* @param int $length
|
||||
*/
|
||||
function usesIV()
|
||||
function setKeyLength($length)
|
||||
{
|
||||
return true;
|
||||
$this->explicit_key_length = true;
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -554,24 +554,6 @@ abstract class Base
|
||||
return $this->block_size << 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Keys with explicitly set lengths need to be treated accordingly
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
$this->explicit_key_length = $length >> 3;
|
||||
|
||||
if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) {
|
||||
$this->key = false;
|
||||
throw new \LengthException('Key has already been set and is not ' .$this->explicit_key_length . ' bytes long');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
@ -588,12 +570,12 @@ abstract class Base
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
|
||||
throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
|
||||
if (!$this->explicit_key_length) {
|
||||
$this->setKeyLength(strlen($key) << 3);
|
||||
$this->explicit_key_length = false;
|
||||
}
|
||||
|
||||
$this->key = $key;
|
||||
$this->key_length = strlen($key);
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
}
|
||||
@ -610,7 +592,6 @@ abstract class Base
|
||||
* @see Crypt/Hash.php
|
||||
* @param string $password
|
||||
* @param string $method
|
||||
* @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length
|
||||
* @return bool
|
||||
* @access public
|
||||
* @internal Could, but not must, extend by the child Crypt_* class
|
||||
@ -637,8 +618,7 @@ abstract class Base
|
||||
if (isset($func_args[5])) {
|
||||
$dkLen = $func_args[5];
|
||||
} else {
|
||||
$key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length;
|
||||
$dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length;
|
||||
$dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
@ -646,7 +626,8 @@ abstract class Base
|
||||
$hashObj = new Hash();
|
||||
$hashObj->setHash($hash);
|
||||
if ($dkLen > $hashObj->getLength()) {
|
||||
throw new \LengthException('Derived key length cannot be longer than the hash length');
|
||||
user_error('Derived key too long');
|
||||
return false;
|
||||
}
|
||||
$t = $password . $salt;
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
@ -793,7 +774,7 @@ abstract class Base
|
||||
$this->changed = false;
|
||||
}
|
||||
if ($this->enchanged) {
|
||||
mcrypt_generic_init($this->enmcrypt, $this->key, $this->_getIV($this->encryptIV));
|
||||
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
||||
$this->enchanged = false;
|
||||
}
|
||||
|
||||
@ -856,7 +837,7 @@ abstract class Base
|
||||
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
||||
|
||||
if (!$this->continuousBuffer) {
|
||||
mcrypt_generic_init($this->enmcrypt, $this->key, $this->_getIV($this->encryptIV));
|
||||
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
||||
}
|
||||
|
||||
return $ciphertext;
|
||||
@ -1005,13 +986,14 @@ abstract class Base
|
||||
* @access public
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
* @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size
|
||||
* @internal Could, but not must, extend by the child Crypt_* class
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->paddable && strlen($ciphertext) % $this->block_size) {
|
||||
throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')');
|
||||
if ($this->paddable) {
|
||||
// we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}:
|
||||
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
||||
$ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
|
||||
}
|
||||
|
||||
if ($this->engine === self::ENGINE_OPENSSL) {
|
||||
@ -1104,7 +1086,7 @@ abstract class Base
|
||||
$this->changed = false;
|
||||
}
|
||||
if ($this->dechanged) {
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->_getIV($this->decryptIV));
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
||||
$this->dechanged = false;
|
||||
}
|
||||
|
||||
@ -1149,7 +1131,7 @@ abstract class Base
|
||||
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
||||
|
||||
if (!$this->continuousBuffer) {
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->_getIV($this->decryptIV));
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
||||
}
|
||||
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
@ -1286,22 +1268,6 @@ abstract class Base
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IV
|
||||
*
|
||||
* mcrypt requires an IV even if ECB is used
|
||||
*
|
||||
* @see self::encrypt()
|
||||
* @see self::decrypt()
|
||||
* @param string $iv
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _getIV($iv)
|
||||
{
|
||||
return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv;
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenSSL CTR Processor
|
||||
*
|
||||
@ -1854,7 +1820,6 @@ abstract class Base
|
||||
*
|
||||
* @see self::_unpad()
|
||||
* @param string $text
|
||||
* @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
@ -1866,7 +1831,8 @@ abstract class Base
|
||||
if ($length % $this->block_size == 0) {
|
||||
return $text;
|
||||
} else {
|
||||
throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding.");
|
||||
user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
|
||||
$this->padding = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1883,7 +1849,6 @@ abstract class Base
|
||||
*
|
||||
* @see self::_pad()
|
||||
* @param string $text
|
||||
* @throws \LengthException if the ciphertext's length is not a multiple of the block size
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
@ -1896,7 +1861,7 @@ abstract class Base
|
||||
$length = ord($text[strlen($text) - 1]);
|
||||
|
||||
if (!$length || $length > $this->block_size) {
|
||||
throw new \LengthException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})");
|
||||
return false;
|
||||
}
|
||||
|
||||
return substr($text, 0, -$length);
|
||||
@ -1909,19 +1874,20 @@ abstract class Base
|
||||
* after disableContinuousBuffer() or on cipher $engine (re)init
|
||||
* ie after setKey() or setIV()
|
||||
*
|
||||
* @access private
|
||||
* @access public
|
||||
* @internal Could, but not must, extend by the child Crypt_* class
|
||||
* @throws \UnexpectedValueException when an IV is required but not defined
|
||||
*/
|
||||
function _clearBuffers()
|
||||
{
|
||||
$this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
|
||||
|
||||
if ($this->iv === false && !in_array($this->mode, array(self::MODE_STREAM, self::MODE_ECB))) {
|
||||
throw new \UnexpectedValueException('No IV has been defined');
|
||||
}
|
||||
// mcrypt's handling of invalid's $iv:
|
||||
// $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
|
||||
$this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
|
||||
|
||||
$this->encryptIV = $this->decryptIV = $this->iv;
|
||||
if (!$this->skip_key_adjustment) {
|
||||
$this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2578,10 +2544,10 @@ abstract class Base
|
||||
$len = strlen($bytes);
|
||||
for ($i = 0; $i < $len; $i+=20) {
|
||||
$t = substr($bytes, $i, 20);
|
||||
$hash = sha1($hash, true);
|
||||
$hash = pack('H*', sha1($hash));
|
||||
$result .= $t ^ $hash;
|
||||
}
|
||||
return $result . sha1($hash, true);
|
||||
return $result . pack('H*', sha1($hash));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,22 +283,6 @@ class Blowfish extends Base
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function __construct($mode)
|
||||
{
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
@ -309,12 +293,14 @@ class Blowfish extends Base
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length < 32 || $length > 448) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported');
|
||||
if ($length < 32) {
|
||||
$this->key_length = 7;
|
||||
} elseif ($length > 448) {
|
||||
$this->key_length = 56;
|
||||
} else {
|
||||
$this->key_length = $length >> 3;
|
||||
}
|
||||
|
||||
$this->key_length = $length >> 3;
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
|
@ -578,22 +578,6 @@ class DES extends Base
|
||||
0x00000820, 0x00020020, 0x08000000, 0x08020800
|
||||
);
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function __construct($mode)
|
||||
{
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
@ -619,18 +603,24 @@ class DES extends Base
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys must be 64-bits long or 8 bytes long.
|
||||
* Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
|
||||
* only use the first eight, if $key has more then eight characters in it, and pad $key with the
|
||||
* null byte if it is less then eight characters long.
|
||||
*
|
||||
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed to be all zero's.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @access public
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
if (!($this instanceof TripleDES) && strlen($key) != 8) {
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported');
|
||||
// We check/cut here only up to max length of the key.
|
||||
// Key padding to the proper length will be done in _setupKey()
|
||||
if (strlen($key) > $this->key_length_max) {
|
||||
$key = substr($key, 0, $this->key_length_max);
|
||||
}
|
||||
|
||||
// Sets the key
|
||||
|
603
vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
vendored
603
vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
vendored
@ -1,19 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper around hash() and hash_hmac() functions supporting truncated hashes
|
||||
* such as sha256-96. Any hash algorithm returned by hash_algos() (and
|
||||
* truncated versions thereof) are supported.
|
||||
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
||||
*
|
||||
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will
|
||||
* return the HMAC as opposed to the hash.
|
||||
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
|
||||
*
|
||||
* md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
|
||||
*
|
||||
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
|
||||
* the hash. If no valid algorithm is provided, sha1 will be used.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* {@internal The variable names are the same as those in
|
||||
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $hash = new \phpseclib\Crypt\Hash('sha512');
|
||||
* $hash = new \phpseclib\Crypt\Hash('sha1');
|
||||
*
|
||||
* $hash->setKey('abcdefg');
|
||||
*
|
||||
@ -24,9 +31,7 @@
|
||||
* @category Crypt
|
||||
* @package Hash
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2015 Andreas Fischer
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
@ -34,16 +39,34 @@
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Math\BigInteger;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
||||
*
|
||||
* @package Hash
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @access public
|
||||
*/
|
||||
class Hash
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\Hash::__construct()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
const MODE_INTERNAL = 1;
|
||||
/**
|
||||
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
|
||||
*/
|
||||
const MODE_MHASH = 2;
|
||||
/**
|
||||
* Toggles the hash() implementation, which works on PHP 5.1.2+.
|
||||
*/
|
||||
const MODE_HASH = 3;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Hash Parameter
|
||||
*
|
||||
@ -53,6 +76,15 @@ class Hash
|
||||
*/
|
||||
var $hashParam;
|
||||
|
||||
/**
|
||||
* Byte-length of compression blocks / key (Internal HMAC)
|
||||
*
|
||||
* @see self::setAlgorithm()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $b;
|
||||
|
||||
/**
|
||||
* Byte-length of hash output (Internal HMAC)
|
||||
*
|
||||
@ -60,7 +92,7 @@ class Hash
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $length;
|
||||
var $l = false;
|
||||
|
||||
/**
|
||||
* Hash Algorithm
|
||||
@ -80,23 +112,10 @@ class Hash
|
||||
*/
|
||||
var $key = false;
|
||||
|
||||
/**
|
||||
* Initial Hash
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::_sha512()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $initial = false;
|
||||
|
||||
/**
|
||||
* Outer XOR (Internal HMAC)
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
@ -105,9 +124,7 @@ class Hash
|
||||
/**
|
||||
* Inner XOR (Internal HMAC)
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
@ -117,14 +134,25 @@ class Hash
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param string $hash
|
||||
* @return \phpseclib\Crypt\Hash
|
||||
* @access public
|
||||
*/
|
||||
function __construct($hash = 'sha256')
|
||||
function __construct($hash = 'sha1')
|
||||
{
|
||||
$this->setHash($hash);
|
||||
if (!defined('CRYPT_HASH_MODE')) {
|
||||
switch (true) {
|
||||
case extension_loaded('hash'):
|
||||
define('CRYPT_HASH_MODE', self::MODE_HASH);
|
||||
break;
|
||||
case extension_loaded('mhash'):
|
||||
define('CRYPT_HASH_MODE', self::MODE_MHASH);
|
||||
break;
|
||||
default:
|
||||
define('CRYPT_HASH_MODE', self::MODE_INTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
$this->ipad = str_repeat(chr(0x36), 128);
|
||||
$this->opad = str_repeat(chr(0x5C), 128);
|
||||
$this->setHash($hash);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,63 +191,101 @@ class Hash
|
||||
{
|
||||
$this->hashParam = $hash = strtolower($hash);
|
||||
switch ($hash) {
|
||||
case 'md2-96':
|
||||
case 'md5-96':
|
||||
case 'sha1-96':
|
||||
case 'sha224-96':
|
||||
case 'sha256-96':
|
||||
case 'sha384-96':
|
||||
case 'sha512-96':
|
||||
case 'sha512/224-96':
|
||||
case 'sha512/256-96':
|
||||
$hash = substr($hash, 0, -3);
|
||||
$this->length = 12; // 96 / 8 = 12
|
||||
$this->l = 12; // 96 / 8 = 12
|
||||
break;
|
||||
case 'md2':
|
||||
case 'md5':
|
||||
$this->length = 16;
|
||||
$this->l = 16;
|
||||
break;
|
||||
case 'sha1':
|
||||
$this->length = 20;
|
||||
break;
|
||||
case 'sha224':
|
||||
case 'sha512/224':
|
||||
$this->length = 28;
|
||||
$this->l = 20;
|
||||
break;
|
||||
case 'sha256':
|
||||
case 'sha512/256':
|
||||
$this->length = 32;
|
||||
$this->l = 32;
|
||||
break;
|
||||
case 'sha384':
|
||||
$this->length = 48;
|
||||
$this->l = 48;
|
||||
break;
|
||||
case 'sha512':
|
||||
$this->length = 64;
|
||||
$this->l = 64;
|
||||
}
|
||||
|
||||
switch ($hash) {
|
||||
case 'md2':
|
||||
$mode = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
|
||||
self::MODE_HASH : self::MODE_INTERNAL;
|
||||
break;
|
||||
case 'sha384':
|
||||
case 'sha512':
|
||||
$mode = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedAlgorithmException(
|
||||
"$hash is not a supported algorithm"
|
||||
);
|
||||
$mode = CRYPT_HASH_MODE;
|
||||
}
|
||||
|
||||
if ($hash == 'sha512/224' || $hash == 'sha512/256') {
|
||||
// from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24
|
||||
$this->initial = $hash == 'sha512/256' ?
|
||||
array(
|
||||
'22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD',
|
||||
'96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2'
|
||||
) :
|
||||
array(
|
||||
'8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF',
|
||||
'0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1'
|
||||
);
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$this->initial[$i] = new BigInteger($this->initial[$i], 16);
|
||||
$this->initial[$i]->setPrecision(64);
|
||||
}
|
||||
switch ($mode) {
|
||||
case self::MODE_MHASH:
|
||||
switch ($hash) {
|
||||
case 'md5':
|
||||
$this->hash = MHASH_MD5;
|
||||
break;
|
||||
case 'sha256':
|
||||
$this->hash = MHASH_SHA256;
|
||||
break;
|
||||
case 'sha1':
|
||||
default:
|
||||
$this->hash = MHASH_SHA1;
|
||||
}
|
||||
return;
|
||||
case self::MODE_HASH:
|
||||
switch ($hash) {
|
||||
case 'md5':
|
||||
$this->hash = 'md5';
|
||||
return;
|
||||
case 'md2':
|
||||
case 'sha256':
|
||||
case 'sha384':
|
||||
case 'sha512':
|
||||
$this->hash = $hash;
|
||||
return;
|
||||
case 'sha1':
|
||||
default:
|
||||
$this->hash = 'sha1';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->hash = $hash;
|
||||
switch ($hash) {
|
||||
case 'md2':
|
||||
$this->b = 16;
|
||||
$this->hash = array($this, '_md2');
|
||||
break;
|
||||
case 'md5':
|
||||
$this->b = 64;
|
||||
$this->hash = array($this, '_md5');
|
||||
break;
|
||||
case 'sha256':
|
||||
$this->b = 64;
|
||||
$this->hash = array($this, '_sha256');
|
||||
break;
|
||||
case 'sha384':
|
||||
case 'sha512':
|
||||
$this->b = 128;
|
||||
$this->hash = array($this, '_sha512');
|
||||
break;
|
||||
case 'sha1':
|
||||
default:
|
||||
$this->b = 64;
|
||||
$this->hash = array($this, '_sha1');
|
||||
}
|
||||
|
||||
$this->ipad = str_repeat(chr(0x36), $this->b);
|
||||
$this->opad = str_repeat(chr(0x5C), $this->b);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,35 +297,45 @@ class Hash
|
||||
*/
|
||||
function hash($text)
|
||||
{
|
||||
switch ($this->hash) {
|
||||
case 'sha512/224':
|
||||
case 'sha512/256':
|
||||
if (empty($this->key) || !is_string($this->key)) {
|
||||
return substr(self::_sha512($text, $this->initial), 0, $this->length);
|
||||
}
|
||||
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
||||
resultant L byte string as the actual key to HMAC."
|
||||
$mode = is_array($this->hash) ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
|
||||
|
||||
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
||||
$key = strlen($this->key) > $this->b ? self::_sha512($this->key, $this->initial) : $this->key;
|
||||
if (!empty($this->key) || is_string($this->key)) {
|
||||
switch ($mode) {
|
||||
case self::MODE_MHASH:
|
||||
$output = mhash($this->hash, $text, $this->key);
|
||||
break;
|
||||
case self::MODE_HASH:
|
||||
$output = hash_hmac($this->hash, $text, $this->key, true);
|
||||
break;
|
||||
case self::MODE_INTERNAL:
|
||||
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
||||
resultant L byte string as the actual key to HMAC."
|
||||
|
||||
$key = str_pad($this->key, 128, chr(0)); // step 1
|
||||
$temp = $this->ipad ^ $this->key; // step 2
|
||||
$temp .= $text; // step 3
|
||||
$temp = self::_sha512($temp, $this->initial); // step 4
|
||||
$output = $this->opad ^ $this->key; // step 5
|
||||
$output.= $temp; // step 6
|
||||
$output = self::_sha512($output, $this->initial); // step 7
|
||||
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
||||
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
||||
|
||||
return substr($output, 0, $this->length);
|
||||
$key = str_pad($key, $this->b, chr(0)); // step 1
|
||||
$temp = $this->ipad ^ $key; // step 2
|
||||
$temp .= $text; // step 3
|
||||
$temp = call_user_func($this->hash, $temp); // step 4
|
||||
$output = $this->opad ^ $key; // step 5
|
||||
$output.= $temp; // step 6
|
||||
$output = call_user_func($this->hash, $output); // step 7
|
||||
}
|
||||
} else {
|
||||
switch ($mode) {
|
||||
case self::MODE_MHASH:
|
||||
$output = mhash($this->hash, $text);
|
||||
break;
|
||||
case self::MODE_HASH:
|
||||
$output = hash($this->hash, $text, true);
|
||||
break;
|
||||
case self::MODE_INTERNAL:
|
||||
$output = call_user_func($this->hash, $text);
|
||||
}
|
||||
}
|
||||
$output = !empty($this->key) || is_string($this->key) ?
|
||||
hash_hmac($this->hash, $text, $this->key, true) :
|
||||
hash($this->hash, $text, true);
|
||||
|
||||
return strlen($output) > $this->length
|
||||
? substr($output, 0, $this->length)
|
||||
: $output;
|
||||
return substr($output, 0, $this->l);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,20 +346,243 @@ class Hash
|
||||
*/
|
||||
function getLength()
|
||||
{
|
||||
return $this->length;
|
||||
return $this->l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of SHA512
|
||||
* Wrapper for MD5
|
||||
*
|
||||
* @access private
|
||||
* @param string $m
|
||||
*/
|
||||
static function _sha512($m, $hash)
|
||||
function _md5($m)
|
||||
{
|
||||
static $k;
|
||||
return pack('H*', md5($m));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for SHA1
|
||||
*
|
||||
* @access private
|
||||
* @param string $m
|
||||
*/
|
||||
function _sha1($m)
|
||||
{
|
||||
return pack('H*', sha1($m));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of MD2
|
||||
*
|
||||
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
|
||||
*
|
||||
* @access private
|
||||
* @param string $m
|
||||
*/
|
||||
function _md2($m)
|
||||
{
|
||||
static $s = array(
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
||||
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
||||
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
||||
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
||||
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
||||
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
||||
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
||||
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
||||
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
||||
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
||||
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
||||
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
||||
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
||||
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
||||
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
||||
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
||||
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
||||
);
|
||||
|
||||
// Step 1. Append Padding Bytes
|
||||
$pad = 16 - (strlen($m) & 0xF);
|
||||
$m.= str_repeat(chr($pad), $pad);
|
||||
|
||||
$length = strlen($m);
|
||||
|
||||
// Step 2. Append Checksum
|
||||
$c = str_repeat(chr(0), 16);
|
||||
$l = chr(0);
|
||||
for ($i = 0; $i < $length; $i+= 16) {
|
||||
for ($j = 0; $j < 16; $j++) {
|
||||
// RFC1319 incorrectly states that C[j] should be set to S[c xor L]
|
||||
//$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
|
||||
// per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
|
||||
$c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
|
||||
$l = $c[$j];
|
||||
}
|
||||
}
|
||||
$m.= $c;
|
||||
|
||||
$length+= 16;
|
||||
|
||||
// Step 3. Initialize MD Buffer
|
||||
$x = str_repeat(chr(0), 48);
|
||||
|
||||
// Step 4. Process Message in 16-Byte Blocks
|
||||
for ($i = 0; $i < $length; $i+= 16) {
|
||||
for ($j = 0; $j < 16; $j++) {
|
||||
$x[$j + 16] = $m[$i + $j];
|
||||
$x[$j + 32] = $x[$j + 16] ^ $x[$j];
|
||||
}
|
||||
$t = chr(0);
|
||||
for ($j = 0; $j < 18; $j++) {
|
||||
for ($k = 0; $k < 48; $k++) {
|
||||
$x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
|
||||
//$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
|
||||
}
|
||||
$t = chr(ord($t) + $j);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5. Output
|
||||
return substr($x, 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of SHA256
|
||||
*
|
||||
* See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
|
||||
*
|
||||
* @access private
|
||||
* @param string $m
|
||||
*/
|
||||
function _sha256($m)
|
||||
{
|
||||
if (extension_loaded('suhosin')) {
|
||||
return pack('H*', sha256($m));
|
||||
}
|
||||
|
||||
// Initialize variables
|
||||
$hash = array(
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
);
|
||||
// Initialize table of round constants
|
||||
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
|
||||
static $k = array(
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
);
|
||||
|
||||
// Pre-processing
|
||||
$length = strlen($m);
|
||||
// to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
|
||||
$m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
|
||||
$m[$length] = chr(0x80);
|
||||
// we don't support hashing strings 512MB long
|
||||
$m.= pack('N2', 0, $length << 3);
|
||||
|
||||
// Process the message in successive 512-bit chunks
|
||||
$chunks = str_split($m, 64);
|
||||
foreach ($chunks as $chunk) {
|
||||
$w = array();
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
|
||||
$w[] = $temp;
|
||||
}
|
||||
|
||||
// Extend the sixteen 32-bit words into sixty-four 32-bit words
|
||||
for ($i = 16; $i < 64; $i++) {
|
||||
// @codingStandardsIgnoreStart
|
||||
$s0 = $this->_rightRotate($w[$i - 15], 7) ^
|
||||
$this->_rightRotate($w[$i - 15], 18) ^
|
||||
$this->_rightShift( $w[$i - 15], 3);
|
||||
$s1 = $this->_rightRotate($w[$i - 2], 17) ^
|
||||
$this->_rightRotate($w[$i - 2], 19) ^
|
||||
$this->_rightShift( $w[$i - 2], 10);
|
||||
// @codingStandardsIgnoreEnd
|
||||
$w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
|
||||
}
|
||||
|
||||
// Initialize hash value for this chunk
|
||||
list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
|
||||
|
||||
// Main loop
|
||||
for ($i = 0; $i < 64; $i++) {
|
||||
$s0 = $this->_rightRotate($a, 2) ^
|
||||
$this->_rightRotate($a, 13) ^
|
||||
$this->_rightRotate($a, 22);
|
||||
$maj = ($a & $b) ^
|
||||
($a & $c) ^
|
||||
($b & $c);
|
||||
$t2 = $this->_add($s0, $maj);
|
||||
|
||||
$s1 = $this->_rightRotate($e, 6) ^
|
||||
$this->_rightRotate($e, 11) ^
|
||||
$this->_rightRotate($e, 25);
|
||||
$ch = ($e & $f) ^
|
||||
($this->_not($e) & $g);
|
||||
$t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
|
||||
|
||||
$h = $g;
|
||||
$g = $f;
|
||||
$f = $e;
|
||||
$e = $this->_add($d, $t1);
|
||||
$d = $c;
|
||||
$c = $b;
|
||||
$b = $a;
|
||||
$a = $this->_add($t1, $t2);
|
||||
}
|
||||
|
||||
// Add this chunk's hash to result so far
|
||||
$hash = array(
|
||||
$this->_add($hash[0], $a),
|
||||
$this->_add($hash[1], $b),
|
||||
$this->_add($hash[2], $c),
|
||||
$this->_add($hash[3], $d),
|
||||
$this->_add($hash[4], $e),
|
||||
$this->_add($hash[5], $f),
|
||||
$this->_add($hash[6], $g),
|
||||
$this->_add($hash[7], $h)
|
||||
);
|
||||
}
|
||||
|
||||
// Produce the final hash value (big-endian)
|
||||
return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of SHA384 and SHA512
|
||||
*
|
||||
* @access private
|
||||
* @param string $m
|
||||
*/
|
||||
function _sha512($m)
|
||||
{
|
||||
static $init384, $init512, $k;
|
||||
|
||||
if (!isset($k)) {
|
||||
// Initialize variables
|
||||
$init384 = array( // initial values for SHA384
|
||||
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
|
||||
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
|
||||
);
|
||||
$init512 = array( // initial values for SHA512
|
||||
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
|
||||
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
|
||||
);
|
||||
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$init384[$i] = new BigInteger($init384[$i], 16);
|
||||
$init384[$i]->setPrecision(64);
|
||||
$init512[$i] = new BigInteger($init512[$i], 16);
|
||||
$init512[$i]->setPrecision(64);
|
||||
}
|
||||
|
||||
// Initialize table of round constants
|
||||
// (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
|
||||
$k = array(
|
||||
@ -314,6 +613,8 @@ class Hash
|
||||
}
|
||||
}
|
||||
|
||||
$hash = $this->l == 48 ? $init384 : $init512;
|
||||
|
||||
// Pre-processing
|
||||
$length = strlen($m);
|
||||
// to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
|
||||
@ -327,7 +628,7 @@ class Hash
|
||||
foreach ($chunks as $chunk) {
|
||||
$w = array();
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$temp = new BigInteger(self::_string_shift($chunk, 8), 256);
|
||||
$temp = new BigInteger($this->_string_shift($chunk, 8), 256);
|
||||
$temp->setPrecision(64);
|
||||
$w[] = $temp;
|
||||
}
|
||||
@ -348,21 +649,21 @@ class Hash
|
||||
);
|
||||
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
||||
$s1 = $s1->bitwise_xor($temp[2]);
|
||||
$w[$i] = clone $w[$i - 16];
|
||||
$w[$i] = $w[$i - 16]->copy();
|
||||
$w[$i] = $w[$i]->add($s0);
|
||||
$w[$i] = $w[$i]->add($w[$i - 7]);
|
||||
$w[$i] = $w[$i]->add($s1);
|
||||
}
|
||||
|
||||
// Initialize hash value for this chunk
|
||||
$a = clone $hash[0];
|
||||
$b = clone $hash[1];
|
||||
$c = clone $hash[2];
|
||||
$d = clone $hash[3];
|
||||
$e = clone $hash[4];
|
||||
$f = clone $hash[5];
|
||||
$g = clone $hash[6];
|
||||
$h = clone $hash[7];
|
||||
$a = $hash[0]->copy();
|
||||
$b = $hash[1]->copy();
|
||||
$c = $hash[2]->copy();
|
||||
$d = $hash[3]->copy();
|
||||
$e = $hash[4]->copy();
|
||||
$f = $hash[5]->copy();
|
||||
$g = $hash[6]->copy();
|
||||
$h = $hash[7]->copy();
|
||||
|
||||
// Main loop
|
||||
for ($i = 0; $i < 80; $i++) {
|
||||
@ -399,13 +700,13 @@ class Hash
|
||||
$t1 = $t1->add($k[$i]);
|
||||
$t1 = $t1->add($w[$i]);
|
||||
|
||||
$h = clone $g;
|
||||
$g = clone $f;
|
||||
$f = clone $e;
|
||||
$h = $g->copy();
|
||||
$g = $f->copy();
|
||||
$f = $e->copy();
|
||||
$e = $d->add($t1);
|
||||
$d = clone $c;
|
||||
$c = clone $b;
|
||||
$b = clone $a;
|
||||
$d = $c->copy();
|
||||
$c = $b->copy();
|
||||
$b = $a->copy();
|
||||
$a = $t1->add($t2);
|
||||
}
|
||||
|
||||
@ -425,11 +726,85 @@ class Hash
|
||||
// Produce the final hash value (big-endian)
|
||||
// (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
|
||||
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
|
||||
$hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes();
|
||||
$hash[4]->toBytes() . $hash[5]->toBytes();
|
||||
if ($this->l != 48) {
|
||||
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
|
||||
}
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Right Rotate
|
||||
*
|
||||
* @access private
|
||||
* @param int $int
|
||||
* @param int $amt
|
||||
* @see self::_sha256()
|
||||
* @return int
|
||||
*/
|
||||
function _rightRotate($int, $amt)
|
||||
{
|
||||
$invamt = 32 - $amt;
|
||||
$mask = (1 << $invamt) - 1;
|
||||
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Right Shift
|
||||
*
|
||||
* @access private
|
||||
* @param int $int
|
||||
* @param int $amt
|
||||
* @see self::_sha256()
|
||||
* @return int
|
||||
*/
|
||||
function _rightShift($int, $amt)
|
||||
{
|
||||
$mask = (1 << (32 - $amt)) - 1;
|
||||
return ($int >> $amt) & $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not
|
||||
*
|
||||
* @access private
|
||||
* @param int $int
|
||||
* @see self::_sha256()
|
||||
* @return int
|
||||
*/
|
||||
function _not($int)
|
||||
{
|
||||
return ~$int & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add
|
||||
*
|
||||
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
|
||||
* possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster.
|
||||
*
|
||||
* @param int $...
|
||||
* @return int
|
||||
* @see self::_sha256()
|
||||
* @access private
|
||||
*/
|
||||
function _add()
|
||||
{
|
||||
static $mod;
|
||||
if (!isset($mod)) {
|
||||
$mod = pow(2, 32);
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
$arguments = func_get_args();
|
||||
foreach ($arguments as $argument) {
|
||||
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
||||
}
|
||||
|
||||
return fmod($result, $mod);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
@ -440,7 +815,7 @@ class Hash
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
|
@ -259,22 +259,6 @@ class RC2 extends Base
|
||||
0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
|
||||
);
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function __construct($mode)
|
||||
{
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
@ -308,15 +292,19 @@ class RC2 extends Base
|
||||
*
|
||||
* @access public
|
||||
* @param int $length in bits
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length < 8 || $length > 1024) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
|
||||
if ($length < 8) {
|
||||
$this->default_key_length = 8;
|
||||
} elseif ($length > 1024) {
|
||||
$this->default_key_length = 128;
|
||||
} else {
|
||||
$this->default_key_length = $length;
|
||||
}
|
||||
$this->current_key_length = $this->default_key_length;
|
||||
|
||||
$this->default_key_length = $this->current_key_length = $length;
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -345,20 +333,16 @@ class RC2 extends Base
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param int $t1 optional Effective key length in bits.
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key, $t1 = false)
|
||||
function setKey($key, $t1 = 0)
|
||||
{
|
||||
$this->orig_key = $key;
|
||||
|
||||
if ($t1 === false) {
|
||||
if ($t1 <= 0) {
|
||||
$t1 = $this->default_key_length;
|
||||
} elseif ($t1 > 1024) {
|
||||
$t1 = 1024;
|
||||
}
|
||||
|
||||
if ($t1 < 1 || $t1 > 1024) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
|
||||
}
|
||||
|
||||
$this->current_key_length = $t1;
|
||||
// Key byte count should be 1..128.
|
||||
$key = strlen($key) ? substr($key, 0, 128) : "\x00";
|
||||
|
@ -121,6 +121,8 @@ class RC4 extends Base
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @return \phpseclib\Crypt\RC4
|
||||
* @access public
|
||||
@ -163,14 +165,26 @@ class RC4 extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* RC4 does not use an IV
|
||||
* Dummy function.
|
||||
*
|
||||
* Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
|
||||
* If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
|
||||
* calling setKey().
|
||||
*
|
||||
* [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
|
||||
* the IV's are relatively easy to predict, an attack described by
|
||||
* {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
|
||||
* can be used to quickly guess at the rest of the key. The following links elaborate:
|
||||
*
|
||||
* {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
|
||||
* {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
|
||||
*
|
||||
* @param string $iv
|
||||
* @see self::setKey()
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function usesIV()
|
||||
function setIV($iv)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,38 +194,20 @@ class RC4 extends Base
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length is invalid
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length < 8 || $length > 2048) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported');
|
||||
if ($length < 8) {
|
||||
$this->key_length = 1;
|
||||
} elseif ($length > 2048) {
|
||||
$this->key_length = 256;
|
||||
} else {
|
||||
$this->key_length = $length >> 3;
|
||||
}
|
||||
|
||||
$this->key_length = $length >> 3;
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Keys can be between 1 and 256 bytes long.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length is invalid
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
$length = strlen($key);
|
||||
if ($length < 1 || $length > 256) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
|
2037
vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
vendored
2037
vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
vendored
File diff suppressed because it is too large
Load Diff
@ -1,224 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Miccrosoft BLOB Formatted RSA Key Handler
|
||||
*
|
||||
* More info:
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375601(v=vs.85).aspx
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Microsoft BLOB Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class MSBLOB
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Public/Private Key Pair
|
||||
*/
|
||||
const PRIVATEKEYBLOB = 0x7;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const PUBLICKEYBLOB = 0x6;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const PUBLICKEYBLOBEX = 0xA;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
const CALG_RSA_KEYX = 0x0000A400;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
const CALG_RSA_SIGN = 0x00002400;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const RSA1 = 0x31415352;
|
||||
/**
|
||||
* Private Key
|
||||
*/
|
||||
const RSA2 = 0x32415352;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$key = Base64::decode($key);
|
||||
|
||||
if (!is_string($key) || strlen($key) < 20) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PUBLICKEYSTRUC publickeystruc
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
|
||||
extract(unpack('atype/aversion/vreserved/Valgo', self::_string_shift($key, 8)));
|
||||
switch (ord($type)) {
|
||||
case self::PUBLICKEYBLOB:
|
||||
case self::PUBLICKEYBLOBEX:
|
||||
$publickey = true;
|
||||
break;
|
||||
case self::PRIVATEKEYBLOB:
|
||||
$publickey = false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => $publickey);
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
|
||||
switch ($algo) {
|
||||
case self::CALG_RSA_KEYX:
|
||||
case self::CALG_RSA_SIGN:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// RSAPUBKEY rsapubkey
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx
|
||||
// could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit
|
||||
extract(unpack('Vmagic/Vbitlen/a4pubexp', self::_string_shift($key, 12)));
|
||||
switch ($magic) {
|
||||
case self::RSA2:
|
||||
$components['isPublicKey'] = false;
|
||||
case self::RSA1:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$baseLength = $bitlen / 16;
|
||||
if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
|
||||
// BYTE modulus[rsapubkey.bitlen/8]
|
||||
$components['modulus'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
|
||||
|
||||
if ($publickey) {
|
||||
return $components;
|
||||
}
|
||||
|
||||
$components['isPublicKey'] = false;
|
||||
|
||||
// BYTE prime1[rsapubkey.bitlen/16]
|
||||
$components['primes'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
// BYTE prime2[rsapubkey.bitlen/16]
|
||||
$components['primes'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
|
||||
// BYTE exponent1[rsapubkey.bitlen/16]
|
||||
$components['exponents'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
// BYTE exponent2[rsapubkey.bitlen/16]
|
||||
$components['exponents'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
|
||||
// BYTE coefficient[rsapubkey.bitlen/16]
|
||||
$components['coefficients'] = array(2 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
if (isset($components['privateExponent'])) {
|
||||
$components['publicExponent'] = $components['privateExponent'];
|
||||
}
|
||||
// BYTE privateExponent[rsapubkey.bitlen/8]
|
||||
$components['privateExponent'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$n = strrev($n->toBytes());
|
||||
$e = str_pad(strrev($e->toBytes()), 4, "\0");
|
||||
$key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
|
||||
$key.= pack('VVa*', self::RSA2, 8 * strlen($n), $e);
|
||||
$key.= $n;
|
||||
$key.= strrev($primes[1]->toBytes());
|
||||
$key.= strrev($primes[2]->toBytes());
|
||||
$key.= strrev($exponents[1]->toBytes());
|
||||
$key.= strrev($exponents[2]->toBytes());
|
||||
$key.= strrev($coefficients[1]->toBytes());
|
||||
$key.= strrev($d->toBytes());
|
||||
|
||||
return Base64::encode($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$n = strrev($n->toBytes());
|
||||
$e = str_pad(strrev($e->toBytes()), 4, "\0");
|
||||
$key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
|
||||
$key.= pack('VVa*', self::RSA1, 8 * strlen($n), $e);
|
||||
$key.= $n;
|
||||
|
||||
return Base64::encode($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Place in $HOME/.ssh/authorized_keys
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class OpenSSH
|
||||
{
|
||||
/**
|
||||
* Default comment
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $comment = 'phpseclib-generated-key';
|
||||
|
||||
/**
|
||||
* Sets the default comment
|
||||
*
|
||||
* @access public
|
||||
* @param string $comment
|
||||
*/
|
||||
static function setComment($comment)
|
||||
{
|
||||
self::$comment = str_replace(array("\r", "\n"), '', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts = explode(' ', $key, 3);
|
||||
|
||||
$key = isset($parts[1]) ? Base64::decode($parts[1]) : Base64::decode($parts[0]);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$comment = isset($parts[2]) ? $parts[2] : false;
|
||||
|
||||
if (substr($key, 0, 11) != "\0\0\0\7ssh-rsa") {
|
||||
return false;
|
||||
}
|
||||
self::_string_shift($key, 11);
|
||||
if (strlen($key) <= 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', self::_string_shift($key, 4)));
|
||||
if (strlen($key) <= $length) {
|
||||
return false;
|
||||
}
|
||||
$publicExponent = new BigInteger(self::_string_shift($key, $length), -256);
|
||||
if (strlen($key) <= 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', self::_string_shift($key, 4)));
|
||||
if (strlen($key) != $length) {
|
||||
return false;
|
||||
}
|
||||
$modulus = new BigInteger(self::_string_shift($key, $length), -256);
|
||||
|
||||
return array(
|
||||
'isPublicKey' => true,
|
||||
'modulus' => $modulus,
|
||||
'publicExponent' => $publicExponent,
|
||||
'comment' => $comment
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$publicExponent = $e->toBytes(true);
|
||||
$modulus = $n->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc4253#page-15>:
|
||||
// string "ssh-rsa"
|
||||
// mpint e
|
||||
// mpint n
|
||||
$RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
|
||||
$RSAPublicKey = 'ssh-rsa ' . Base64::encode($RSAPublicKey) . ' ' . self::$comment;
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
@ -1,487 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\Base;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\TripleDES;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
abstract class PKCS
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\RSA::createKey()
|
||||
*/
|
||||
/**
|
||||
* ASN1 Integer
|
||||
*/
|
||||
const ASN1_INTEGER = 2;
|
||||
/**
|
||||
* ASN1 Bit String
|
||||
*/
|
||||
const ASN1_BITSTRING = 3;
|
||||
/**
|
||||
* ASN1 Octet String
|
||||
*/
|
||||
const ASN1_OCTETSTRING = 4;
|
||||
/**
|
||||
* ASN1 Object Identifier
|
||||
*/
|
||||
const ASN1_OBJECT = 6;
|
||||
/**
|
||||
* ASN1 Sequence (with the constucted bit set)
|
||||
*/
|
||||
const ASN1_SEQUENCE = 48;
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Auto-detect the format
|
||||
*/
|
||||
const MODE_ANY = 0;
|
||||
/**
|
||||
* Require base64-encoded PEM's be supplied
|
||||
*/
|
||||
const MODE_PEM = 1;
|
||||
/**
|
||||
* Require raw DER's be supplied
|
||||
*/
|
||||
const MODE_DER = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Is the key a base-64 encoded PEM, DER or should it be auto-detected?
|
||||
*
|
||||
* @access private
|
||||
* @param int
|
||||
*/
|
||||
static $format = self::MODE_ANY;
|
||||
|
||||
/**
|
||||
* Returns the mode constant corresponding to the mode string
|
||||
*
|
||||
* @access public
|
||||
* @param string $mode
|
||||
* @return int
|
||||
* @throws \UnexpectedValueException if the block cipher mode is unsupported
|
||||
*/
|
||||
static function getEncryptionMode($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
case 'CBC':
|
||||
return Base::MODE_CBC;
|
||||
case 'ECB':
|
||||
return Base::MODE_ECB;
|
||||
case 'CFB':
|
||||
return Base::MODE_CFB;
|
||||
case 'OFB':
|
||||
return Base::MODE_OFB;
|
||||
case 'CTR':
|
||||
return Base::MODE_CTR;
|
||||
}
|
||||
throw new \UnexpectedValueException('Unsupported block cipher mode of operation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cipher object corresponding to a string
|
||||
*
|
||||
* @access public
|
||||
* @param string $algo
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException if the encryption algorithm is unsupported
|
||||
*/
|
||||
static function getEncryptionObject($algo)
|
||||
{
|
||||
$modes = '(CBC|ECB|CFB|OFB|CTR)';
|
||||
switch (true) {
|
||||
case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches):
|
||||
$cipher = new AES(self::getEncryptionMode($matches[2]));
|
||||
$cipher->setKeyLength($matches[1]);
|
||||
return $cipher;
|
||||
case preg_match("#^DES-EDE3-$modes$#", $algo, $matches):
|
||||
return new TripleDES(self::getEncryptionMode($matches[1]));
|
||||
case preg_match("#^DES-$modes$#", $algo, $matches):
|
||||
return new DES(self::getEncryptionMode($matches[1]));
|
||||
default:
|
||||
throw new \UnexpectedValueException('Unsupported encryption algorithmn');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a symmetric key for PKCS#1 keys
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @param string $iv
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function generateSymmetricKey($password, $iv, $length)
|
||||
{
|
||||
$symkey = '';
|
||||
$iv = substr($iv, 0, 8);
|
||||
while (strlen($symkey) < $length) {
|
||||
$symkey.= md5($symkey . $password . $iv, true);
|
||||
}
|
||||
return substr($symkey, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => strpos($key, 'PUBLIC') !== false);
|
||||
|
||||
/* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
|
||||
"outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
|
||||
protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
|
||||
two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
|
||||
|
||||
http://tools.ietf.org/html/rfc1421#section-4.6.1.1
|
||||
http://tools.ietf.org/html/rfc1421#section-4.6.1.3
|
||||
|
||||
DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
|
||||
DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
|
||||
function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
|
||||
own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
|
||||
implementation are part of the standard, as well.
|
||||
|
||||
* OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
|
||||
if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
|
||||
$iv = Hex::decode(trim($matches[2]));
|
||||
// remove the Proc-Type / DEK-Info sections as they're no longer needed
|
||||
$key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
|
||||
$ciphertext = self::_extractBER($key);
|
||||
if ($ciphertext === false) {
|
||||
$ciphertext = $key;
|
||||
}
|
||||
$crypto = self::getEncryptionObject($matches[1]);
|
||||
$crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3));
|
||||
$crypto->setIV($iv);
|
||||
$key = $crypto->decrypt($ciphertext);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (self::$format != self::MODE_DER) {
|
||||
$decoded = self::_extractBER($key);
|
||||
if ($decoded !== false) {
|
||||
$key = $decoded;
|
||||
} elseif (self::$format == self::MODE_PEM) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tag = ord(self::_string_shift($key));
|
||||
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
||||
|
||||
0:d=0 hl=4 l= 631 cons: SEQUENCE
|
||||
4:d=1 hl=2 l= 1 prim: INTEGER :00
|
||||
7:d=1 hl=2 l= 13 cons: SEQUENCE
|
||||
9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
||||
20:d=2 hl=2 l= 0 prim: NULL
|
||||
22:d=1 hl=4 l= 609 prim: OCTET STRING
|
||||
|
||||
ie. PKCS8 keys */
|
||||
|
||||
if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
|
||||
self::_string_shift($key, 3);
|
||||
$tag = self::ASN1_SEQUENCE;
|
||||
}
|
||||
|
||||
if ($tag == self::ASN1_SEQUENCE) {
|
||||
$temp = self::_string_shift($key, self::_decodeLength($key));
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_OBJECT) {
|
||||
return false;
|
||||
}
|
||||
$length = self::_decodeLength($temp);
|
||||
switch (self::_string_shift($temp, $length)) {
|
||||
case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
|
||||
break;
|
||||
case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
|
||||
/*
|
||||
PBEParameter ::= SEQUENCE {
|
||||
salt OCTET STRING (SIZE(8)),
|
||||
iterationCount INTEGER }
|
||||
*/
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($temp) != strlen($temp)) {
|
||||
return false;
|
||||
}
|
||||
self::_string_shift($temp); // assume it's an octet string
|
||||
$salt = self::_string_shift($temp, self::_decodeLength($temp));
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($temp);
|
||||
list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
|
||||
self::_string_shift($key); // assume it's an octet string
|
||||
$length = self::_decodeLength($key);
|
||||
if (strlen($key) != $length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$crypto = new DES(DES::MODE_CBC);
|
||||
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
|
||||
$key = $crypto->decrypt($key);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
return self::load($key);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
||||
|
||||
0:d=0 hl=4 l= 290 cons: SEQUENCE
|
||||
4:d=1 hl=2 l= 13 cons: SEQUENCE
|
||||
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
||||
17:d=2 hl=2 l= 0 prim: NULL
|
||||
19:d=1 hl=4 l= 271 prim: BIT STRING */
|
||||
$tag = ord(self::_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
|
||||
self::_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
|
||||
// "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
|
||||
// unused bits in the final subsequent octet. The number shall be in the range zero to seven."
|
||||
// -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
|
||||
if ($tag == self::ASN1_BITSTRING) {
|
||||
self::_string_shift($key);
|
||||
}
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
$tag = ord(self::_string_shift($key));
|
||||
}
|
||||
if ($tag != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = self::_decodeLength($key);
|
||||
$temp = self::_string_shift($key, $length);
|
||||
if (strlen($temp) != 1 || ord($temp) > 2) {
|
||||
$components['modulus'] = new BigInteger($temp, 256);
|
||||
self::_string_shift($key); // skip over self::ASN1_INTEGER
|
||||
$length = self::_decodeLength($key);
|
||||
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
|
||||
return $components;
|
||||
}
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
$length = self::_decodeLength($key);
|
||||
$components['modulus'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['publicExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
|
||||
if (!empty($key)) {
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($key);
|
||||
while (!empty($key)) {
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($key);
|
||||
$key = substr($key, 1);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['coefficients'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require base64-encoded PEM's be supplied
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requirePEM()
|
||||
{
|
||||
self::$format = self::MODE_PEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require raw DER's be supplied
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requireDER()
|
||||
{
|
||||
self::$format = self::MODE_DER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept any format and auto detect the format
|
||||
*
|
||||
* This is the default setting
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requireAny()
|
||||
{
|
||||
self::$format = self::MODE_ANY;
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-decode the length
|
||||
*
|
||||
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
||||
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
|
||||
*
|
||||
* @access private
|
||||
* @param string $string
|
||||
* @return int
|
||||
*/
|
||||
static function _decodeLength(&$string)
|
||||
{
|
||||
$length = ord(self::_string_shift($string));
|
||||
if ($length & 0x80) { // definite length, long form
|
||||
$length&= 0x7F;
|
||||
$temp = self::_string_shift($string, $length);
|
||||
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-encode the length
|
||||
*
|
||||
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
||||
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
|
||||
*
|
||||
* @access private
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function _encodeLength($length)
|
||||
{
|
||||
if ($length <= 0x7F) {
|
||||
return chr($length);
|
||||
}
|
||||
|
||||
$temp = ltrim(pack('N', $length), chr(0));
|
||||
return pack('Ca*', 0x80 | strlen($temp), $temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract raw BER from Base64 encoding
|
||||
*
|
||||
* @access private
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
static function _extractBER($str)
|
||||
{
|
||||
/* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
|
||||
* above and beyond the ceritificate.
|
||||
* ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
|
||||
*
|
||||
* Bag Attributes
|
||||
* localKeyID: 01 00 00 00
|
||||
* subject=/O=organization/OU=org unit/CN=common name
|
||||
* issuer=/O=organization/CN=common name
|
||||
*/
|
||||
$temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
|
||||
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
|
||||
$temp = preg_replace('#-+[^-]+-+#', '', $temp);
|
||||
// remove new lines
|
||||
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false;
|
||||
return $temp != false ? $temp : $str;
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by File/X509.php
|
||||
*
|
||||
* Has the following header:
|
||||
*
|
||||
* -----BEGIN RSA PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to ssh-keygen's pem format (as specified by -m)
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Crypt\TripleDES;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PKCS1 extends PKCS
|
||||
{
|
||||
/**
|
||||
* Default encryption algorithm
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $defaultEncryptionAlgorithm = 'DES-EDE3-CBC';
|
||||
|
||||
/**
|
||||
* Sets the default encryption algorithm
|
||||
*
|
||||
* @access public
|
||||
* @param string $algo
|
||||
*/
|
||||
static function setEncryptionAlgorithm($algo)
|
||||
{
|
||||
self::$defaultEncryptionAlgorithm = $algo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$num_primes = count($primes);
|
||||
$raw = array(
|
||||
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$components = array();
|
||||
foreach ($raw as $name => $value) {
|
||||
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = implode('', $components);
|
||||
|
||||
if ($num_primes > 2) {
|
||||
$OtherPrimeInfos = '';
|
||||
for ($i = 3; $i <= $num_primes; $i++) {
|
||||
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
|
||||
//
|
||||
// OtherPrimeInfo ::= SEQUENCE {
|
||||
// prime INTEGER, -- ri
|
||||
// exponent INTEGER, -- di
|
||||
// coefficient INTEGER -- ti
|
||||
// }
|
||||
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
|
||||
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
|
||||
}
|
||||
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
if (!empty($password) || is_string($password)) {
|
||||
$cipher = self::getEncryptionObject(self::$defaultEncryptionAlgorithm);
|
||||
$iv = Random::string($cipher->getBlockLength() >> 3);
|
||||
$cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3));
|
||||
$cipher->setIV($iv);
|
||||
$iv = strtoupper(Hex::encode($iv));
|
||||
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
||||
"Proc-Type: 4,ENCRYPTED\r\n" .
|
||||
"DEK-Info: " . self::$defaultEncryptionAlgorithm . ",$iv\r\n" .
|
||||
"\r\n" .
|
||||
chunk_split(Base64::encode($cipher->encrypt($RSAPrivateKey)), 64) .
|
||||
'-----END RSA PRIVATE KEY-----';
|
||||
} else {
|
||||
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END RSA PRIVATE KEY-----';
|
||||
}
|
||||
|
||||
return $RSAPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$modulus = $n->toBytes(true);
|
||||
$publicExponent = $e->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
|
||||
// RSAPublicKey ::= SEQUENCE {
|
||||
// modulus INTEGER, -- n
|
||||
// publicExponent INTEGER -- e
|
||||
// }
|
||||
$components = array(
|
||||
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
|
||||
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
|
||||
);
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
||||
$components['modulus'],
|
||||
$components['publicExponent']
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPublicKey), 64) .
|
||||
'-----END RSA PUBLIC KEY-----';
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
}
|
@ -1,209 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS#8 Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
|
||||
*
|
||||
* Has the following header:
|
||||
*
|
||||
* -----BEGIN PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
|
||||
* is specific to private keys it's basically creating a DER-encoded wrapper
|
||||
* for keys. This just extends that same concept to public keys (much like ssh-keygen)
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#8 Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PKCS8 extends PKCS
|
||||
{
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$num_primes = count($primes);
|
||||
$raw = array(
|
||||
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$components = array();
|
||||
foreach ($raw as $name => $value) {
|
||||
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = implode('', $components);
|
||||
|
||||
if ($num_primes > 2) {
|
||||
$OtherPrimeInfos = '';
|
||||
for ($i = 3; $i <= $num_primes; $i++) {
|
||||
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
|
||||
//
|
||||
// OtherPrimeInfo ::= SEQUENCE {
|
||||
// prime INTEGER, -- ri
|
||||
// exponent INTEGER, -- di
|
||||
// coefficient INTEGER -- ti
|
||||
// }
|
||||
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
|
||||
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
|
||||
}
|
||||
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPrivateKey = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_INTEGER,
|
||||
"\01\00",
|
||||
$rsaOID,
|
||||
4,
|
||||
self::_encodeLength(strlen($RSAPrivateKey)),
|
||||
$RSAPrivateKey
|
||||
);
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
if (!empty($password) || is_string($password)) {
|
||||
$salt = Random::string(8);
|
||||
$iterationCount = 2048;
|
||||
|
||||
$crypto = new DES(DES::MODE_CBC);
|
||||
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
|
||||
$RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
|
||||
|
||||
$parameters = pack(
|
||||
'Ca*a*Ca*N',
|
||||
self::ASN1_OCTETSTRING,
|
||||
self::_encodeLength(strlen($salt)),
|
||||
$salt,
|
||||
self::ASN1_INTEGER,
|
||||
self::_encodeLength(4),
|
||||
$iterationCount
|
||||
);
|
||||
$pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
|
||||
|
||||
$encryptionAlgorithm = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_OBJECT,
|
||||
self::_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
|
||||
$pbeWithMD5AndDES_CBC,
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($parameters)),
|
||||
$parameters
|
||||
);
|
||||
|
||||
$RSAPrivateKey = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($encryptionAlgorithm)),
|
||||
$encryptionAlgorithm,
|
||||
self::ASN1_OCTETSTRING,
|
||||
self::_encodeLength(strlen($RSAPrivateKey)),
|
||||
$RSAPrivateKey
|
||||
);
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
$RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END ENCRYPTED PRIVATE KEY-----';
|
||||
} else {
|
||||
$RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END PRIVATE KEY-----';
|
||||
}
|
||||
|
||||
return $RSAPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$modulus = $n->toBytes(true);
|
||||
$publicExponent = $e->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
|
||||
// RSAPublicKey ::= SEQUENCE {
|
||||
// modulus INTEGER, -- n
|
||||
// publicExponent INTEGER -- e
|
||||
// }
|
||||
$components = array(
|
||||
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
|
||||
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
|
||||
);
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
||||
$components['modulus'],
|
||||
$components['publicExponent']
|
||||
);
|
||||
|
||||
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
|
||||
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPublicKey = chr(0) . $RSAPublicKey;
|
||||
$RSAPublicKey = chr(3) . self::_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($rsaOID . $RSAPublicKey)),
|
||||
$rsaOID . $RSAPublicKey
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPublicKey), 64) .
|
||||
'-----END PUBLIC KEY-----';
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\Hash;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PuTTY
|
||||
{
|
||||
/**
|
||||
* Default comment
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $comment = 'phpseclib-generated-key';
|
||||
|
||||
/**
|
||||
* Sets the default comment
|
||||
*
|
||||
* @access public
|
||||
* @param string $comment
|
||||
*/
|
||||
static function setComment($comment)
|
||||
{
|
||||
self::$comment = str_replace(array("\r", "\n"), '', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a symmetric key for PuTTY keys
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @param string $iv
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function generateSymmetricKey($password, $length)
|
||||
{
|
||||
$symkey = '';
|
||||
$sequence = 0;
|
||||
while (strlen($symkey) < $length) {
|
||||
$temp = pack('Na*', $sequence++, $password);
|
||||
$symkey.= Hex::decode(sha1($temp));
|
||||
}
|
||||
return substr($symkey, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static $one;
|
||||
if (!isset($one)) {
|
||||
$one = new BigInteger(1);
|
||||
}
|
||||
|
||||
if (strpos($key, 'BEGIN SSH2 PUBLIC KEY')) {
|
||||
$data = preg_split('#[\r\n]+#', $key);
|
||||
$data = array_splice($data, 2, -1);
|
||||
$data = implode('', $data);
|
||||
|
||||
$components = OpenSSH::load($data);
|
||||
if ($components === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!preg_match('#Comment: "(.+)"#', $key, $matches)) {
|
||||
return false;
|
||||
}
|
||||
$components['comment'] = str_replace(array('\\\\', '\"'), array('\\', '"'), $matches[1]);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => false);
|
||||
$key = preg_split('#\r\n|\r|\n#', $key);
|
||||
$type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
|
||||
if ($type != 'ssh-rsa') {
|
||||
return false;
|
||||
}
|
||||
$encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
|
||||
$components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
|
||||
|
||||
$publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
|
||||
$public = Base64::decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
|
||||
$public = substr($public, 11);
|
||||
extract(unpack('Nlength', self::_string_shift($public, 4)));
|
||||
$components['publicExponent'] = new BigInteger(self::_string_shift($public, $length), -256);
|
||||
extract(unpack('Nlength', self::_string_shift($public, 4)));
|
||||
$components['modulus'] = new BigInteger(self::_string_shift($public, $length), -256);
|
||||
|
||||
$privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4]));
|
||||
$private = Base64::decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
|
||||
|
||||
switch ($encryption) {
|
||||
case 'aes256-cbc':
|
||||
$symkey = static::generateSymmetricKey($password, 32);
|
||||
$crypto = new AES(AES::MODE_CBC);
|
||||
}
|
||||
|
||||
if ($encryption != 'none') {
|
||||
$crypto->setKey($symkey);
|
||||
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||
$crypto->disablePadding();
|
||||
$private = $crypto->decrypt($private);
|
||||
if ($private === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['privateExponent'] = new BigInteger(self::_string_shift($private, $length), -256);
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['primes'] = array(1 => new BigInteger(self::_string_shift($private, $length), -256));
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($private, $length), -256);
|
||||
|
||||
$temp = $components['primes'][1]->subtract($one);
|
||||
$components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
|
||||
$temp = $components['primes'][2]->subtract($one);
|
||||
$components['exponents'][] = $components['publicExponent']->modInverse($temp);
|
||||
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($private, $length), -256));
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$raw = array(
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
|
||||
$encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none';
|
||||
$key.= $encryption;
|
||||
$key.= "\r\nComment: " . self::$comment . "\r\n";
|
||||
$public = pack(
|
||||
'Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($raw['publicExponent']),
|
||||
$raw['publicExponent'],
|
||||
strlen($raw['modulus']),
|
||||
$raw['modulus']
|
||||
);
|
||||
$source = pack(
|
||||
'Na*Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($encryption),
|
||||
$encryption,
|
||||
strlen(self::$comment),
|
||||
self::$comment,
|
||||
strlen($public),
|
||||
$public
|
||||
);
|
||||
$public = Base64::encode($public);
|
||||
$key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
|
||||
$key.= chunk_split($public, 64);
|
||||
$private = pack(
|
||||
'Na*Na*Na*Na*',
|
||||
strlen($raw['privateExponent']),
|
||||
$raw['privateExponent'],
|
||||
strlen($raw['prime1']),
|
||||
$raw['prime1'],
|
||||
strlen($raw['prime2']),
|
||||
$raw['prime2'],
|
||||
strlen($raw['coefficient']),
|
||||
$raw['coefficient']
|
||||
);
|
||||
if (empty($password) && !is_string($password)) {
|
||||
$source.= pack('Na*', strlen($private), $private);
|
||||
$hashkey = 'putty-private-key-file-mac-key';
|
||||
} else {
|
||||
$private.= Random::string(16 - (strlen($private) & 15));
|
||||
$source.= pack('Na*', strlen($private), $private);
|
||||
$crypto = new AES();
|
||||
|
||||
$crypto->setKey(static::generateSymmetricKey($password, 32));
|
||||
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||
$crypto->disablePadding();
|
||||
$private = $crypto->encrypt($private);
|
||||
$hashkey = 'putty-private-key-file-mac-key' . $password;
|
||||
}
|
||||
|
||||
$private = Base64::encode($private);
|
||||
$key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
|
||||
$key.= chunk_split($private, 64);
|
||||
$hash = new Hash('sha1');
|
||||
$hash->setKey(sha1($hashkey, true));
|
||||
$key.= 'Private-MAC: ' . Hex::encode($hash->hash($source)) . "\r\n";
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$n = $n->toBytes(true);
|
||||
$e = $e->toBytes(true);
|
||||
|
||||
$key = pack(
|
||||
'Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($e),
|
||||
$e,
|
||||
strlen($n),
|
||||
$n
|
||||
);
|
||||
$key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" .
|
||||
'Comment: "' . str_replace(array('\\', '"'), array('\\\\', '\"'), self::$comment) . "\"\r\n";
|
||||
chunk_split(Base64::encode($key), 64) .
|
||||
'---- END SSH2 PUBLIC KEY ----';
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* An array containing two \phpseclib\Math\BigInteger objects.
|
||||
*
|
||||
* The exponent can be indexed with any of the following:
|
||||
*
|
||||
* 0, e, exponent, publicExponent
|
||||
*
|
||||
* The modulus can be indexed with any of the following:
|
||||
*
|
||||
* 1, n, modulo, modulus
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class Raw
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_array($key)) {
|
||||
return false;
|
||||
}
|
||||
if (isset($key['isPublicKey']) && isset($key['modulus'])) {
|
||||
if (isset($key['privateExponent']) || isset($key['publicExponent'])) {
|
||||
if (!isset($key['primes'])) {
|
||||
return $key;
|
||||
}
|
||||
if (isset($key['exponents']) && isset($key['coefficients']) && isset($key['publicExponent']) && isset($key['privateExponent'])) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
$components = array('isPublicKey' => true);
|
||||
switch (true) {
|
||||
case isset($key['e']):
|
||||
$components['publicExponent'] = $key['e'];
|
||||
break;
|
||||
case isset($key['exponent']):
|
||||
$components['publicExponent'] = $key['exponent'];
|
||||
break;
|
||||
case isset($key['publicExponent']):
|
||||
$components['publicExponent'] = $key['publicExponent'];
|
||||
break;
|
||||
case isset($key[0]):
|
||||
$components['publicExponent'] = $key[0];
|
||||
}
|
||||
switch (true) {
|
||||
case isset($key['n']):
|
||||
$components['modulus'] = $key['n'];
|
||||
break;
|
||||
case isset($key['modulo']):
|
||||
$components['modulus'] = $key['modulo'];
|
||||
break;
|
||||
case isset($key['modulus']):
|
||||
$components['modulus'] = $key['modulus'];
|
||||
break;
|
||||
case isset($key[1]):
|
||||
$components['modulus'] = $key[1];
|
||||
}
|
||||
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
return array('e' => clone $e, 'n' => clone $n);
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* More info:
|
||||
*
|
||||
* http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
|
||||
* http://en.wikipedia.org/wiki/XML_Signature
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class XML
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array(
|
||||
'isPublicKey' => false,
|
||||
'primes' => array(),
|
||||
'exponents' => array(),
|
||||
'coefficients' => array()
|
||||
);
|
||||
|
||||
$use_errors = libxml_use_internal_errors(true);
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
if (!$dom->loadXML('<xml>' . $key . '</xml>')) {
|
||||
return false;
|
||||
}
|
||||
$xpath = new \DOMXPath($dom);
|
||||
$keys = array('modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd');
|
||||
foreach ($keys as $key) {
|
||||
// $dom->getElementsByTagName($key) is case-sensitive
|
||||
$temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']");
|
||||
if (!$temp->length) {
|
||||
continue;
|
||||
}
|
||||
$value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256);
|
||||
switch ($key) {
|
||||
case 'modulus':
|
||||
$components['modulus'] = $value;
|
||||
break;
|
||||
case 'exponent':
|
||||
$components['publicExponent'] = $value;
|
||||
break;
|
||||
case 'p':
|
||||
$components['primes'][1] = $value;
|
||||
break;
|
||||
case 'q':
|
||||
$components['primes'][2] = $value;
|
||||
break;
|
||||
case 'dp':
|
||||
$components['exponents'][1] = $value;
|
||||
break;
|
||||
case 'dq':
|
||||
$components['exponents'][2] = $value;
|
||||
break;
|
||||
case 'inverseq':
|
||||
$components['coefficients'][2] = $value;
|
||||
break;
|
||||
case 'd':
|
||||
$components['privateExponent'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
libxml_use_internal_errors($use_errors);
|
||||
|
||||
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
return false;
|
||||
}
|
||||
return "<RSAKeyValue>\r\n" .
|
||||
' <Modulus>' . Base64::encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Base64::encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
' <P>' . Base64::encode($primes[1]->toBytes()) . "</P>\r\n" .
|
||||
' <Q>' . Base64::encode($primes[2]->toBytes()) . "</Q>\r\n" .
|
||||
' <DP>' . Base64::encode($exponents[1]->toBytes()) . "</DP>\r\n" .
|
||||
' <DQ>' . Base64::encode($exponents[2]->toBytes()) . "</DQ>\r\n" .
|
||||
' <InverseQ>' . Base64::encode($coefficients[2]->toBytes()) . "</InverseQ>\r\n" .
|
||||
' <D>' . Base64::encode($d->toBytes()) . "</D>\r\n" .
|
||||
'</RSAKeyValue>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
return "<RSAKeyValue>\r\n" .
|
||||
' <Modulus>' . Base64::encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Base64::encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
'</RSAKeyValue>';
|
||||
}
|
||||
}
|
@ -41,22 +41,68 @@ class Random
|
||||
* eg. for RSA key generation.
|
||||
*
|
||||
* @param int $length
|
||||
* @throws \RuntimeException if a symmetric cipher is needed but not loaded
|
||||
* @return string
|
||||
*/
|
||||
static function string($length)
|
||||
{
|
||||
try {
|
||||
return \random_bytes($length);
|
||||
} catch (\Exception $e) {
|
||||
// random_compat will throw an Exception, which in PHP 5 does not implement Throwable
|
||||
} catch (\Throwable $e) {
|
||||
// If a sufficient source of randomness is unavailable, random_bytes() will throw an
|
||||
// object that implements the Throwable interface (Exception, TypeError, Error).
|
||||
// We don't actually need to do anything here. The string() method should just continue
|
||||
// as normal. Note, however, that if we don't have a sufficient source of randomness for
|
||||
// random_bytes(), most of the other calls here will fail too, so we'll end up using
|
||||
// the PHP implementation.
|
||||
if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
|
||||
try {
|
||||
return \random_bytes($length);
|
||||
} catch (\Throwable $e) {
|
||||
// If a sufficient source of randomness is unavailable, random_bytes() will throw an
|
||||
// object that implements the Throwable interface (Exception, TypeError, Error).
|
||||
// We don't actually need to do anything here. The string() method should just continue
|
||||
// as normal. Note, however, that if we don't have a sufficient source of randomness for
|
||||
// random_bytes(), most of the other calls here will fail too, so we'll end up using
|
||||
// the PHP implementation.
|
||||
}
|
||||
}
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
// method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
|
||||
// ie. class_alias is a function that was introduced in PHP 5.3
|
||||
if (extension_loaded('mcrypt') && function_exists('class_alias')) {
|
||||
return mcrypt_create_iv($length);
|
||||
}
|
||||
// method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
|
||||
// to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
|
||||
// openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
|
||||
// call php_win32_get_random_bytes():
|
||||
//
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
|
||||
//
|
||||
// php_win32_get_random_bytes() is defined thusly:
|
||||
//
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
|
||||
//
|
||||
// we're calling it, all the same, in the off chance that the mcrypt extension is not available
|
||||
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
} else {
|
||||
// method 1. the fastest
|
||||
if (extension_loaded('openssl')) {
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
// method 2
|
||||
static $fp = true;
|
||||
if ($fp === true) {
|
||||
// warning's will be output unles the error suppression operator is used. errors such as
|
||||
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
|
||||
$fp = @fopen('/dev/urandom', 'rb');
|
||||
}
|
||||
if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
|
||||
return fread($fp, $length);
|
||||
}
|
||||
// method 3. pretty much does the same thing as method 2 per the following url:
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
|
||||
// surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
|
||||
// not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
|
||||
// restrictions or some such
|
||||
if (extension_loaded('mcrypt')) {
|
||||
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||
}
|
||||
}
|
||||
// at this point we have no choice but to use a pure-PHP CSPRNG
|
||||
|
||||
@ -93,14 +139,15 @@ class Random
|
||||
session_cache_limiter('');
|
||||
session_start();
|
||||
|
||||
$v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') .
|
||||
(isset($_POST) ? self::safe_serialize($_POST) : '') .
|
||||
(isset($_GET) ? self::safe_serialize($_GET) : '') .
|
||||
(isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') .
|
||||
self::safe_serialize($GLOBALS) .
|
||||
self::safe_serialize($_SESSION) .
|
||||
self::safe_serialize($_OLD_SESSION);
|
||||
$v = $seed = $_SESSION['seed'] = sha1($v, true);
|
||||
$v = $seed = $_SESSION['seed'] = pack('H*', sha1(
|
||||
(isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') .
|
||||
(isset($_POST) ? phpseclib_safe_serialize($_POST) : '') .
|
||||
(isset($_GET) ? phpseclib_safe_serialize($_GET) : '') .
|
||||
(isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') .
|
||||
phpseclib_safe_serialize($GLOBALS) .
|
||||
phpseclib_safe_serialize($_SESSION) .
|
||||
phpseclib_safe_serialize($_OLD_SESSION)
|
||||
));
|
||||
if (!isset($_SESSION['count'])) {
|
||||
$_SESSION['count'] = 0;
|
||||
}
|
||||
@ -131,8 +178,8 @@ class Random
|
||||
// http://tools.ietf.org/html/rfc4253#section-7.2
|
||||
//
|
||||
// see the is_string($crypto) part for an example of how to expand the keys
|
||||
$key = sha1($seed . 'A', true);
|
||||
$iv = sha1($seed . 'C', true);
|
||||
$key = pack('H*', sha1($seed . 'A'));
|
||||
$iv = pack('H*', sha1($seed . 'C'));
|
||||
|
||||
// ciphers are used as per the nist.gov link below. also, see this link:
|
||||
//
|
||||
@ -157,11 +204,12 @@ class Random
|
||||
$crypto = new RC4();
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
||||
user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
||||
return false;
|
||||
}
|
||||
|
||||
$crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3));
|
||||
$crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3));
|
||||
$crypto->setKey($key);
|
||||
$crypto->setIV($iv);
|
||||
$crypto->enableContinuousBuffer();
|
||||
}
|
||||
|
||||
@ -184,16 +232,19 @@ class Random
|
||||
}
|
||||
return substr($result, 0, $length);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('phpseclib_safe_serialize')) {
|
||||
/**
|
||||
* Safely serialize variables
|
||||
*
|
||||
* If a class has a private __sleep() it'll emit a warning
|
||||
* If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier.
|
||||
* PHP 5.3 will emit a warning.
|
||||
*
|
||||
* @param mixed $arr
|
||||
* @access public
|
||||
*/
|
||||
static function safe_serialize(&$arr)
|
||||
function phpseclib_safe_serialize(&$arr)
|
||||
{
|
||||
if (is_object($arr)) {
|
||||
return '';
|
||||
@ -210,7 +261,7 @@ class Random
|
||||
foreach (array_keys($arr) as $key) {
|
||||
// do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
|
||||
if ($key !== '__phpseclib_marker') {
|
||||
$safearr[$key] = self::safe_serialize($arr[$key]);
|
||||
$safearr[$key] = phpseclib_safe_serialize($arr[$key]);
|
||||
}
|
||||
}
|
||||
unset($arr['__phpseclib_marker']);
|
||||
|
@ -168,26 +168,11 @@ class Rijndael extends Base
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function __construct($mode)
|
||||
{
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 128, 160, 192, 224, and 256.
|
||||
* Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
||||
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
|
||||
*
|
||||
* Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
|
||||
* and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
|
||||
@ -201,75 +186,49 @@ class Rijndael extends Base
|
||||
* This results then in slower encryption.
|
||||
*
|
||||
* @access public
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 160:
|
||||
case 192:
|
||||
case 224:
|
||||
case 256:
|
||||
$this->key_length = $length >> 3;
|
||||
switch (true) {
|
||||
case $length <= 128:
|
||||
$this->key_length = 16;
|
||||
break;
|
||||
case $length <= 160:
|
||||
$this->key_length = 20;
|
||||
break;
|
||||
case $length <= 192:
|
||||
$this->key_length = 24;
|
||||
break;
|
||||
case $length <= 224:
|
||||
$this->key_length = 28;
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
|
||||
$this->key_length = 32;
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Rijndael supports five different key lengths
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 20:
|
||||
case 24:
|
||||
case 28:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block length
|
||||
*
|
||||
* Valid block lengths are 128, 160, 192, 224, and 256.
|
||||
* Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
||||
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
*/
|
||||
function setBlockLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 160:
|
||||
case 192:
|
||||
case 224:
|
||||
case 256:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
|
||||
$length >>= 5;
|
||||
if ($length > 8) {
|
||||
$length = 8;
|
||||
} elseif ($length < 4) {
|
||||
$length = 4;
|
||||
}
|
||||
|
||||
$this->Nb = $length >> 5;
|
||||
$this->block_size = $length >> 3;
|
||||
$this->Nb = $length;
|
||||
$this->block_size = $length << 2;
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ class TripleDES extends DES
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt or OpenSSL extensions should be used.
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
@ -142,14 +142,16 @@ class TripleDES extends DES
|
||||
*
|
||||
* - \phpseclib\Crypt\Base::MODE_OFB
|
||||
*
|
||||
* - \phpseclib\Crypt\TripleDES::MODE_3CB
|
||||
* - \phpseclib\Crypt\TripleDES::MODE_3CBC
|
||||
*
|
||||
* If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::__construct()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $mode
|
||||
* @access public
|
||||
*/
|
||||
function __construct($mode)
|
||||
function __construct($mode = Base::MODE_CBC)
|
||||
{
|
||||
switch ($mode) {
|
||||
// In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
|
||||
@ -198,9 +200,10 @@ class TripleDES extends DES
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector.
|
||||
* Sets the initialization vector. (optional)
|
||||
*
|
||||
* SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used.
|
||||
* SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used. If not explicitly set, it'll be assumed
|
||||
* to be all zero's.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setIV()
|
||||
* @access public
|
||||
@ -219,23 +222,24 @@ class TripleDES extends DES
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 128 and 192 bits.
|
||||
*
|
||||
* If you want to use a 64-bit key use DES.php
|
||||
* Valid key lengths are 64, 128 and 192
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base:setKeyLength()
|
||||
* @access public
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
$length >>= 3;
|
||||
switch (true) {
|
||||
case $length <= 8:
|
||||
$this->key_length = 8;
|
||||
break;
|
||||
case $length <= 16:
|
||||
$this->key_length = 16;
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported');
|
||||
$this->key_length = 24;
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
@ -244,38 +248,36 @@ class TripleDES extends DES
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys.
|
||||
* Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
|
||||
* 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
|
||||
*
|
||||
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
||||
*
|
||||
* @access public
|
||||
* @see \phpseclib\Crypt\DES::setKey()
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
|
||||
throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
|
||||
$length = $this->explicit_key_length ? $this->key_length : strlen($key);
|
||||
if ($length > 8) {
|
||||
$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);
|
||||
} else {
|
||||
$key = str_pad($key, 8, chr(0));
|
||||
}
|
||||
parent::setKey($key);
|
||||
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
$key.= substr($key, 0, 8);
|
||||
case 24:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported');
|
||||
}
|
||||
|
||||
// copied from Base::setKey()
|
||||
$this->key = $key;
|
||||
$this->key_length = strlen($key);
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
|
||||
if ($this->mode_3cbc) {
|
||||
// And in case of self::MODE_3CBC:
|
||||
// if key <= 64bits we not need the 3 $des to work,
|
||||
// because we will then act as regular DES-CBC with just a <= 64bit key.
|
||||
// So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
|
||||
if ($this->mode_3cbc && $length > 8) {
|
||||
$this->des[0]->setKey(substr($key, 0, 8));
|
||||
$this->des[1]->setKey(substr($key, 8, 8));
|
||||
$this->des[2]->setKey(substr($key, 16, 8));
|
||||
|
@ -368,22 +368,6 @@ class Twofish extends Base
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function __construct($mode)
|
||||
{
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
@ -394,42 +378,20 @@ class Twofish extends Base
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
switch (true) {
|
||||
case $length <= 128:
|
||||
$this->key_length = 16;
|
||||
break;
|
||||
case $length <= 192:
|
||||
$this->key_length = 24;
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
$this->key_length = 32;
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Rijndael supports five different key lengths
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BadConfigurationException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package BadConfigurationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* BadConfigurationException
|
||||
*
|
||||
* @package BadConfigurationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class BadConfigurationException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FileNotFoundException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package FileNotFoundException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* FileNotFoundException
|
||||
*
|
||||
* @package FileNotFoundException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class FileNotFoundException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NoSupportedAlgorithmsException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package NoSupportedAlgorithmsException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* NoSupportedAlgorithmsException
|
||||
*
|
||||
* @package NoSupportedAlgorithmsException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class NoSupportedAlgorithmsException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UnsupportedAlgorithmException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package UnsupportedAlgorithmException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* UnsupportedAlgorithmException
|
||||
*
|
||||
* @package UnsupportedAlgorithmException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class UnsupportedAlgorithmException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -23,7 +23,6 @@
|
||||
|
||||
namespace phpseclib\File;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\File\ASN1\Element;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
@ -225,15 +224,14 @@ class ASN1
|
||||
*
|
||||
* @param string $encoded
|
||||
* @param int $start
|
||||
* @param int $encoded_pos
|
||||
* @return array
|
||||
* @access private
|
||||
*/
|
||||
function _decode_ber($encoded, $start = 0, $encoded_pos = 0)
|
||||
function _decode_ber($encoded, $start = 0)
|
||||
{
|
||||
$current = array('start' => $start);
|
||||
|
||||
$type = ord($encoded[$encoded_pos++]);
|
||||
$type = ord($this->_string_shift($encoded));
|
||||
$start++;
|
||||
|
||||
$constructed = ($type >> 5) & 1;
|
||||
@ -245,24 +243,23 @@ class ASN1
|
||||
do {
|
||||
$loop = ord($encoded[0]) >> 7;
|
||||
$tag <<= 7;
|
||||
$tag |= ord($encoded[$encoded_pos++]) & 0x7F;
|
||||
$tag |= ord($this->_string_shift($encoded)) & 0x7F;
|
||||
$start++;
|
||||
} while ($loop);
|
||||
}
|
||||
|
||||
// Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13
|
||||
$length = ord($encoded[$encoded_pos++]);
|
||||
$length = ord($this->_string_shift($encoded));
|
||||
$start++;
|
||||
if ($length == 0x80) { // indefinite length
|
||||
// "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all
|
||||
// immediately available." -- paragraph 8.1.3.2.c
|
||||
$length = strlen($encoded) - $encoded_pos;
|
||||
$length = strlen($encoded);
|
||||
} elseif ($length & 0x80) { // definite length, long form
|
||||
// technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only
|
||||
// support it up to four.
|
||||
$length&= 0x7F;
|
||||
$temp = substr($encoded, $encoded_pos, $length);
|
||||
$encoded_pos += $length;
|
||||
$temp = $this->_string_shift($encoded, $length);
|
||||
// tags of indefinte length don't really have a header length; this length includes the tag
|
||||
$current+= array('headerlength' => $length + 2);
|
||||
$start+= $length;
|
||||
@ -271,12 +268,11 @@ class ASN1
|
||||
$current+= array('headerlength' => 2);
|
||||
}
|
||||
|
||||
if ($length > (strlen($encoded) - $encoded_pos)) {
|
||||
if ($length > strlen($encoded)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$content = substr($encoded, $encoded_pos, $length);
|
||||
$content_pos = 0;
|
||||
$content = $this->_string_shift($encoded, $length);
|
||||
|
||||
// at this point $length can be overwritten. it's only accurate for definite length things as is
|
||||
|
||||
@ -309,7 +305,7 @@ class ASN1
|
||||
$temp = $this->_decode_ber($content, $start);
|
||||
$length = $temp['length'];
|
||||
// end-of-content octets - see paragraph 8.1.5
|
||||
if (substr($content, $content_pos + $length, 2) == "\0\0") {
|
||||
if (substr($content, $length, 2) == "\0\0") {
|
||||
$length+= 2;
|
||||
$start+= $length;
|
||||
$newcontent[] = $temp;
|
||||
@ -318,7 +314,7 @@ class ASN1
|
||||
$start+= $length;
|
||||
$remainingLength-= $length;
|
||||
$newcontent[] = $temp;
|
||||
$content_pos += $length;
|
||||
$this->_string_shift($content, $length);
|
||||
}
|
||||
|
||||
return array(
|
||||
@ -342,11 +338,11 @@ class ASN1
|
||||
//if (strlen($content) != 1) {
|
||||
// return false;
|
||||
//}
|
||||
$current['content'] = (bool) ord($content[$content_pos]);
|
||||
$current['content'] = (bool) ord($content[0]);
|
||||
break;
|
||||
case self::TYPE_INTEGER:
|
||||
case self::TYPE_ENUMERATED:
|
||||
$current['content'] = new BigInteger(substr($content, $content_pos), -256);
|
||||
$current['content'] = new BigInteger($content, -256);
|
||||
break;
|
||||
case self::TYPE_REAL: // not currently supported
|
||||
return false;
|
||||
@ -355,10 +351,10 @@ class ASN1
|
||||
// the number of unused bits in the final subsequent octet. The number shall be in the range zero to
|
||||
// seven.
|
||||
if (!$constructed) {
|
||||
$current['content'] = substr($content, $content_pos);
|
||||
$current['content'] = $content;
|
||||
} else {
|
||||
$temp = $this->_decode_ber($content, $start, $content_pos);
|
||||
$length-= (strlen($content) - $content_pos);
|
||||
$temp = $this->_decode_ber($content, $start);
|
||||
$length-= strlen($content);
|
||||
$last = count($temp) - 1;
|
||||
for ($i = 0; $i < $last; $i++) {
|
||||
// all subtags should be bit strings
|
||||
@ -376,13 +372,13 @@ class ASN1
|
||||
break;
|
||||
case self::TYPE_OCTET_STRING:
|
||||
if (!$constructed) {
|
||||
$current['content'] = substr($content, $content_pos);
|
||||
$current['content'] = $content;
|
||||
} else {
|
||||
$current['content'] = '';
|
||||
$length = 0;
|
||||
while (substr($content, $content_pos, 2) != "\0\0") {
|
||||
$temp = $this->_decode_ber($content, $length + $start, $content_pos);
|
||||
$content_pos += $temp['length'];
|
||||
while (substr($content, 0, 2) != "\0\0") {
|
||||
$temp = $this->_decode_ber($content, $length + $start);
|
||||
$this->_string_shift($content, $temp['length']);
|
||||
// all subtags should be octet strings
|
||||
//if ($temp['type'] != self::TYPE_OCTET_STRING) {
|
||||
// return false;
|
||||
@ -390,7 +386,7 @@ class ASN1
|
||||
$current['content'].= $temp['content'];
|
||||
$length+= $temp['length'];
|
||||
}
|
||||
if (substr($content, $content_pos, 2) == "\0\0") {
|
||||
if (substr($content, 0, 2) == "\0\0") {
|
||||
$length+= 2; // +2 for the EOC
|
||||
}
|
||||
}
|
||||
@ -405,28 +401,26 @@ class ASN1
|
||||
case self::TYPE_SET:
|
||||
$offset = 0;
|
||||
$current['content'] = array();
|
||||
$content_len = strlen($content);
|
||||
while ($content_pos < $content_len) {
|
||||
while (strlen($content)) {
|
||||
// if indefinite length construction was used and we have an end-of-content string next
|
||||
// see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2
|
||||
if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") {
|
||||
if (!isset($current['headerlength']) && substr($content, 0, 2) == "\0\0") {
|
||||
$length = $offset + 2; // +2 for the EOC
|
||||
break 2;
|
||||
}
|
||||
$temp = $this->_decode_ber($content, $start + $offset, $content_pos);
|
||||
$content_pos += $temp['length'];
|
||||
$temp = $this->_decode_ber($content, $start + $offset);
|
||||
$this->_string_shift($content, $temp['length']);
|
||||
$current['content'][] = $temp;
|
||||
$offset+= $temp['length'];
|
||||
}
|
||||
break;
|
||||
case self::TYPE_OBJECT_IDENTIFIER:
|
||||
$temp = ord($content[$content_pos++]);
|
||||
$temp = ord($this->_string_shift($content));
|
||||
$current['content'] = sprintf('%d.%d', floor($temp / 40), $temp % 40);
|
||||
$valuen = 0;
|
||||
// process septets
|
||||
$content_len = strlen($content);
|
||||
while ($content_pos < $content_len) {
|
||||
$temp = ord($content[$content_pos++]);
|
||||
while (strlen($content)) {
|
||||
$temp = ord($this->_string_shift($content));
|
||||
$valuen <<= 7;
|
||||
$valuen |= $temp & 0x7F;
|
||||
if (~$temp & 0x80) {
|
||||
@ -467,11 +461,11 @@ class ASN1
|
||||
case self::TYPE_UTF8_STRING:
|
||||
// ????
|
||||
case self::TYPE_BMP_STRING:
|
||||
$current['content'] = substr($content, $content_pos);
|
||||
$current['content'] = $content;
|
||||
break;
|
||||
case self::TYPE_UTC_TIME:
|
||||
case self::TYPE_GENERALIZED_TIME:
|
||||
$current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag);
|
||||
$current['content'] = $this->_decodeTime($content, $tag);
|
||||
default:
|
||||
}
|
||||
|
||||
@ -503,7 +497,7 @@ class ASN1
|
||||
switch (true) {
|
||||
case $mapping['type'] == self::TYPE_ANY:
|
||||
$intype = $decoded['type'];
|
||||
if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || (ord($this->encoded[$decoded['start']]) & 0x20)) {
|
||||
if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || ($this->encoded[$decoded['start']] & 0x20)) {
|
||||
return new Element(substr($this->encoded, $decoded['start'], $decoded['length']));
|
||||
}
|
||||
$inmap = $this->ANYmap[$intype];
|
||||
@ -739,7 +733,7 @@ class ASN1
|
||||
return $values;
|
||||
}
|
||||
case self::TYPE_OCTET_STRING:
|
||||
return Base64::encode($decoded['content']);
|
||||
return base64_encode($decoded['content']);
|
||||
case self::TYPE_NULL:
|
||||
return '';
|
||||
case self::TYPE_BOOLEAN:
|
||||
@ -799,7 +793,6 @@ class ASN1
|
||||
* @param string $mapping
|
||||
* @param int $idx
|
||||
* @return string
|
||||
* @throws \RuntimeException if the input has an error in it
|
||||
* @access private
|
||||
*/
|
||||
function _encode_der($source, $mapping, $idx = null, $special = array())
|
||||
@ -826,10 +819,10 @@ class ASN1
|
||||
case self::TYPE_SET: // Children order is not important, thus process in sequence.
|
||||
case self::TYPE_SEQUENCE:
|
||||
$tag|= 0x20; // set the constructed bit
|
||||
$value = '';
|
||||
|
||||
// ignore the min and max
|
||||
if (isset($mapping['min']) && isset($mapping['max'])) {
|
||||
$value = array();
|
||||
$child = $mapping['children'];
|
||||
|
||||
foreach ($source as $content) {
|
||||
@ -837,21 +830,11 @@ class ASN1
|
||||
if ($temp === false) {
|
||||
return false;
|
||||
}
|
||||
$value[]= $temp;
|
||||
$value.= $temp;
|
||||
}
|
||||
/* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared
|
||||
as octet strings with the shorter components being padded at their trailing end with 0-octets.
|
||||
NOTE - The padding octets are for comparison purposes only and do not appear in the encodings."
|
||||
|
||||
-- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */
|
||||
if ($mapping['type'] == self::TYPE_SET) {
|
||||
sort($value);
|
||||
}
|
||||
$value = implode($value, '');
|
||||
break;
|
||||
}
|
||||
|
||||
$value = '';
|
||||
foreach ($mapping['children'] as $key => $child) {
|
||||
if (!array_key_exists($key, $source)) {
|
||||
if (!isset($child['optional'])) {
|
||||
@ -997,12 +980,12 @@ class ASN1
|
||||
the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven.
|
||||
|
||||
-- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */
|
||||
$value = Base64::decode($source);
|
||||
$value = base64_decode($source);
|
||||
break;
|
||||
case self::TYPE_OBJECT_IDENTIFIER:
|
||||
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
|
||||
if ($oid === false) {
|
||||
throw new \RuntimeException('Invalid OID');
|
||||
user_error('Invalid OID');
|
||||
return false;
|
||||
}
|
||||
$value = '';
|
||||
@ -1055,7 +1038,7 @@ class ASN1
|
||||
$filters = $filters[$part];
|
||||
}
|
||||
if ($filters === false) {
|
||||
throw new \RuntimeException('No filters defined for ' . implode('/', $loc));
|
||||
user_error('No filters defined for ' . implode('/', $loc));
|
||||
return false;
|
||||
}
|
||||
return $this->_encode_der($source, $filters + $mapping, null, $special);
|
||||
@ -1079,7 +1062,7 @@ class ASN1
|
||||
$value = $source ? "\xFF" : "\x00";
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', $this->location));
|
||||
user_error('Mapping provides no type definition for ' . implode('/', $this->location));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
460
vendor/phpseclib/phpseclib/phpseclib/File/X509.php
vendored
460
vendor/phpseclib/phpseclib/phpseclib/File/X509.php
vendored
@ -26,12 +26,9 @@
|
||||
|
||||
namespace phpseclib\File;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\Hash;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
use phpseclib\File\ASN1\Element;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
@ -147,7 +144,6 @@ class X509
|
||||
var $CertificatePolicies;
|
||||
var $AuthorityInfoAccessSyntax;
|
||||
var $SubjectAltName;
|
||||
var $SubjectDirectoryAttributes;
|
||||
var $PrivateKeyUsagePeriod;
|
||||
var $IssuerAltName;
|
||||
var $PolicyMappings;
|
||||
@ -171,14 +167,6 @@ class X509
|
||||
var $SignedPublicKeyAndChallenge;
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* ASN.1 syntax for various DN attributes
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $PostalAddress;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* ASN.1 syntax for Certificate Signing Requests (RFC2986)
|
||||
*
|
||||
@ -1081,13 +1069,6 @@ class X509
|
||||
)
|
||||
);
|
||||
|
||||
$this->SubjectDirectoryAttributes = array(
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'min' => 1,
|
||||
'max' => -1,
|
||||
'children' => $Attribute
|
||||
);
|
||||
|
||||
// adapted from <http://tools.ietf.org/html/rfc2986>
|
||||
|
||||
$Attributes = array(
|
||||
@ -1255,14 +1236,6 @@ class X509
|
||||
)
|
||||
);
|
||||
|
||||
$this->PostalAddress = array(
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'optional' => true,
|
||||
'min' => 1,
|
||||
'max' => -1,
|
||||
'children' => $this->DirectoryString
|
||||
);
|
||||
|
||||
// OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2
|
||||
$this->oids = array(
|
||||
'1.3.6.1.5.5.7' => 'id-pkix',
|
||||
@ -1297,7 +1270,6 @@ class X509
|
||||
'2.5.4.9' => 'id-at-streetAddress',
|
||||
'2.5.4.45' => 'id-at-uniqueIdentifier',
|
||||
'2.5.4.72' => 'id-at-role',
|
||||
'2.5.4.16' => 'id-at-postalAddress',
|
||||
|
||||
'0.9.2342.19200300.100.1.25' => 'id-domainComponent',
|
||||
'1.2.840.113549.1.9' => 'pkcs-9',
|
||||
@ -1487,11 +1459,7 @@ class X509
|
||||
|
||||
$this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
||||
|
||||
if ($this->_isSubArrayValid($x509, 'tbsCertificate/extensions')) {
|
||||
$this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
|
||||
}
|
||||
$this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1);
|
||||
$this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1);
|
||||
$this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
|
||||
|
||||
$key = &$x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'];
|
||||
$key = $this->_reformatKey($x509['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $key);
|
||||
@ -1528,7 +1496,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']
|
||||
= Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
|
||||
= base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
|
||||
/* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier."
|
||||
-- https://tools.ietf.org/html/rfc3279#section-2.3.1
|
||||
|
||||
@ -1568,8 +1536,6 @@ class X509
|
||||
$asn1->loadFilters($filters);
|
||||
|
||||
$this->_mapOutExtensions($cert, 'tbsCertificate/extensions', $asn1);
|
||||
$this->_mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence', $asn1);
|
||||
$this->_mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence', $asn1);
|
||||
|
||||
$cert = $asn1->encodeDER($cert, $this->Certificate);
|
||||
|
||||
@ -1578,7 +1544,7 @@ class X509
|
||||
return $cert;
|
||||
// case self::FORMAT_PEM:
|
||||
default:
|
||||
return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Base64::encode($cert), 64) . '-----END CERTIFICATE-----';
|
||||
return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert), 64) . '-----END CERTIFICATE-----';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1593,13 +1559,13 @@ class X509
|
||||
*/
|
||||
function _mapInExtensions(&$root, $path, $asn1)
|
||||
{
|
||||
$extensions = &$this->_subArrayUnchecked($root, $path);
|
||||
$extensions = &$this->_subArray($root, $path);
|
||||
|
||||
if ($extensions) {
|
||||
if (is_array($extensions)) {
|
||||
for ($i = 0; $i < count($extensions); $i++) {
|
||||
$id = $extensions[$i]['extnId'];
|
||||
$value = &$extensions[$i]['extnValue'];
|
||||
$value = Base64::decode($value);
|
||||
$value = base64_decode($value);
|
||||
$decoded = $asn1->decodeBER($value);
|
||||
/* [extnValue] contains the DER encoding of an ASN.1 value
|
||||
corresponding to the extension type identified by extnID */
|
||||
@ -1626,7 +1592,7 @@ class X509
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$value = Base64::encode($value);
|
||||
$value = base64_encode($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1687,12 +1653,12 @@ class X509
|
||||
$map = $this->_getMapping($id);
|
||||
if (is_bool($map)) {
|
||||
if (!$map) {
|
||||
//user_error($id . ' is not a currently supported extension');
|
||||
user_error($id . ' is not a currently supported extension');
|
||||
unset($extensions[$i]);
|
||||
}
|
||||
} else {
|
||||
$temp = $asn1->encodeDER($value, $map, array('iPAddress' => array($this, '_encodeIP')));
|
||||
$value = Base64::encode($temp);
|
||||
$value = base64_encode($temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1727,11 +1693,11 @@ class X509
|
||||
if ($mapped !== false) {
|
||||
$values[$j] = $mapped;
|
||||
}
|
||||
if ($id == 'pkcs-9-at-extensionRequest' && $this->_isSubArrayValid($values, $j)) {
|
||||
if ($id == 'pkcs-9-at-extensionRequest') {
|
||||
$this->_mapInExtensions($values, $j, $asn1);
|
||||
}
|
||||
} elseif ($map) {
|
||||
$values[$j] = Base64::encode($value);
|
||||
$values[$j] = base64_encode($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1760,7 +1726,7 @@ class X509
|
||||
$id = $attributes[$i]['type'];
|
||||
$map = $this->_getMapping($id);
|
||||
if ($map === false) {
|
||||
//user_error($id . ' is not a currently supported attribute', E_USER_NOTICE);
|
||||
user_error($id . ' is not a currently supported attribute', E_USER_NOTICE);
|
||||
unset($attributes[$i]);
|
||||
} elseif (is_array($attributes[$i]['value'])) {
|
||||
$values = &$attributes[$i]['value'];
|
||||
@ -1782,68 +1748,6 @@ class X509
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map DN values from ANY type to DN-specific internal
|
||||
* format.
|
||||
*
|
||||
* @param array ref $root
|
||||
* @param string $path
|
||||
* @param object $asn1
|
||||
* @access private
|
||||
*/
|
||||
function _mapInDNs(&$root, $path, $asn1)
|
||||
{
|
||||
$dns = &$this->_subArray($root, $path);
|
||||
|
||||
if (is_array($dns)) {
|
||||
for ($i = 0; $i < count($dns); $i++) {
|
||||
for ($j = 0; $j < count($dns[$i]); $j++) {
|
||||
$type = $dns[$i][$j]['type'];
|
||||
$value = &$dns[$i][$j]['value'];
|
||||
if (is_object($value) && $value instanceof Element) {
|
||||
$map = $this->_getMapping($type);
|
||||
if (!is_bool($map)) {
|
||||
$decoded = $asn1->decodeBER($value);
|
||||
$value = $asn1->asn1map($decoded[0], $map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map DN values from DN-specific internal format to
|
||||
* ANY type.
|
||||
*
|
||||
* @param array ref $root
|
||||
* @param string $path
|
||||
* @param object $asn1
|
||||
* @access private
|
||||
*/
|
||||
function _mapOutDNs(&$root, $path, $asn1)
|
||||
{
|
||||
$dns = &$this->_subArray($root, $path);
|
||||
|
||||
if (is_array($dns)) {
|
||||
$size = count($dns);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
for ($j = 0; $j < count($dns[$i]); $j++) {
|
||||
$type = $dns[$i][$j]['type'];
|
||||
$value = &$dns[$i][$j]['value'];
|
||||
if (is_object($value) && $value instanceof Element) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$map = $this->_getMapping($type);
|
||||
if (!is_bool($map)) {
|
||||
$value = new Element($asn1->encodeDER($value, $map));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate an extension ID to an extension mapping
|
||||
*
|
||||
@ -1876,8 +1780,6 @@ class X509
|
||||
return $this->AuthorityInfoAccessSyntax;
|
||||
case 'id-ce-subjectAltName':
|
||||
return $this->SubjectAltName;
|
||||
case 'id-ce-subjectDirectoryAttributes':
|
||||
return $this->SubjectDirectoryAttributes;
|
||||
case 'id-ce-privateKeyUsagePeriod':
|
||||
return $this->PrivateKeyUsagePeriod;
|
||||
case 'id-ce-issuerAltName':
|
||||
@ -1937,8 +1839,6 @@ class X509
|
||||
return $this->CertificateIssuer;
|
||||
case 'id-ce-holdInstructionCode':
|
||||
return $this->HoldInstructionCode;
|
||||
case 'id-at-postalAddress':
|
||||
return $this->PostalAddress;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -2130,16 +2030,14 @@ class X509
|
||||
switch (true) {
|
||||
case isset($this->currentCert['tbsCertificate']):
|
||||
// self-signed cert
|
||||
switch (true) {
|
||||
case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']:
|
||||
case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(self::DN_STRING) === $this->getDN(self::DN_STRING):
|
||||
$authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
$signingCert = $this->currentCert; // working cert
|
||||
}
|
||||
if ($this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']) {
|
||||
$authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
$signingCert = $this->currentCert; // working cert
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->CAs)) {
|
||||
@ -2147,17 +2045,15 @@ class X509
|
||||
// even if the cert is a self-signed one we still want to see if it's a CA;
|
||||
// if not, we'll conditionally return an error
|
||||
$ca = $this->CAs[$i];
|
||||
switch (true) {
|
||||
case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']:
|
||||
case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']):
|
||||
$authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
$signingCert = $ca; // working cert
|
||||
break 3;
|
||||
}
|
||||
if ($this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) {
|
||||
$authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
$signingCert = $ca; // working cert
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($this->CAs) == $i && $caonly) {
|
||||
@ -2170,7 +2066,7 @@ class X509
|
||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'],
|
||||
$this->currentCert['signatureAlgorithm']['algorithm'],
|
||||
substr(Base64::decode($this->currentCert['signature']), 1),
|
||||
substr(base64_decode($this->currentCert['signature']), 1),
|
||||
$this->signatureSubject
|
||||
);
|
||||
case isset($this->currentCert['certificationRequestInfo']):
|
||||
@ -2178,7 +2074,7 @@ class X509
|
||||
$this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'],
|
||||
$this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'],
|
||||
$this->currentCert['signatureAlgorithm']['algorithm'],
|
||||
substr(Base64::decode($this->currentCert['signature']), 1),
|
||||
substr(base64_decode($this->currentCert['signature']), 1),
|
||||
$this->signatureSubject
|
||||
);
|
||||
case isset($this->currentCert['publicKeyAndChallenge']):
|
||||
@ -2186,24 +2082,22 @@ class X509
|
||||
$this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'],
|
||||
$this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'],
|
||||
$this->currentCert['signatureAlgorithm']['algorithm'],
|
||||
substr(Base64::decode($this->currentCert['signature']), 1),
|
||||
substr(base64_decode($this->currentCert['signature']), 1),
|
||||
$this->signatureSubject
|
||||
);
|
||||
case isset($this->currentCert['tbsCertList']):
|
||||
if (!empty($this->CAs)) {
|
||||
for ($i = 0; $i < count($this->CAs); $i++) {
|
||||
$ca = $this->CAs[$i];
|
||||
switch (true) {
|
||||
case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']:
|
||||
case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']):
|
||||
$authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
$signingCert = $ca; // working cert
|
||||
break 3;
|
||||
}
|
||||
if ($this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']) {
|
||||
$authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
$signingCert = $ca; // working cert
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2214,7 +2108,7 @@ class X509
|
||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'],
|
||||
$this->currentCert['signatureAlgorithm']['algorithm'],
|
||||
substr(Base64::decode($this->currentCert['signature']), 1),
|
||||
substr(base64_decode($this->currentCert['signature']), 1),
|
||||
$this->signatureSubject
|
||||
);
|
||||
default:
|
||||
@ -2225,8 +2119,7 @@ class X509
|
||||
/**
|
||||
* Validates a signature
|
||||
*
|
||||
* Returns true if the signature is verified and false if it is not correct.
|
||||
* If the algorithms are unsupposed an exception is thrown.
|
||||
* Returns true if the signature is verified, false if it is not correct or null on error
|
||||
*
|
||||
* @param string $publicKeyAlgorithm
|
||||
* @param string $publicKey
|
||||
@ -2234,15 +2127,14 @@ class X509
|
||||
* @param string $signature
|
||||
* @param string $signatureSubject
|
||||
* @access private
|
||||
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||
* @return bool
|
||||
* @return int
|
||||
*/
|
||||
function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
|
||||
{
|
||||
switch ($publicKeyAlgorithm) {
|
||||
case 'rsaEncryption':
|
||||
$rsa = new RSA();
|
||||
$rsa->load($publicKey);
|
||||
$rsa->loadKey($publicKey);
|
||||
|
||||
switch ($signatureAlgorithm) {
|
||||
case 'md2WithRSAEncryption':
|
||||
@ -2253,16 +2145,17 @@ class X509
|
||||
case 'sha384WithRSAEncryption':
|
||||
case 'sha512WithRSAEncryption':
|
||||
$rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
|
||||
if (!@$rsa->verify($signatureSubject, $signature, RSA::PADDING_PKCS1)) {
|
||||
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
|
||||
if (!@$rsa->verify($signatureSubject, $signature)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedAlgorithmException('Signature algorithm unsupported');
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedAlgorithmException('Public key algorithm unsupported');
|
||||
return null;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2287,7 +2180,7 @@ class X509
|
||||
// subjectPublicKey is stored as a bit string in X.509 certs. the first byte of a bit string represents how many bits
|
||||
// in the last byte should be ignored. the following only supports non-zero stuff but as none of the X.509 certs Firefox
|
||||
// uses as a cert authority actually use a non-zero bit I think it's safe to assume that none do.
|
||||
chunk_split(Base64::encode(substr(Base64::decode($key), 1)), 64) .
|
||||
chunk_split(base64_encode(substr(base64_decode($key), 1)), 64) .
|
||||
'-----END RSA PUBLIC KEY-----';
|
||||
default:
|
||||
return $key;
|
||||
@ -2305,7 +2198,7 @@ class X509
|
||||
*/
|
||||
function _decodeIP($ip)
|
||||
{
|
||||
return inet_ntop(Base64::decode($ip));
|
||||
return inet_ntop(base64_decode($ip));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2319,7 +2212,7 @@ class X509
|
||||
*/
|
||||
function _encodeIP($ip)
|
||||
{
|
||||
return Base64::encode(inet_pton($ip));
|
||||
return base64_encode(inet_pton($ip));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2406,9 +2299,6 @@ class X509
|
||||
case 'uniqueidentifier':
|
||||
case 'x500uniqueidentifier':
|
||||
return 'id-at-uniqueIdentifier';
|
||||
case 'postaladdress':
|
||||
case 'id-at-postaladdress':
|
||||
return 'id-at-postalAddress';
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -2498,38 +2388,25 @@ class X509
|
||||
return false;
|
||||
}
|
||||
|
||||
$asn1 = new ASN1();
|
||||
$asn1->loadOIDs($this->oids);
|
||||
$filters = array();
|
||||
$filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
|
||||
$asn1->loadFilters($filters);
|
||||
$this->_mapOutDNs($dn, 'rdnSequence', $asn1);
|
||||
$dn = $dn['rdnSequence'];
|
||||
$result = array();
|
||||
$asn1 = new ASN1();
|
||||
for ($i = 0; $i < count($dn); $i++) {
|
||||
if ($dn[$i][0]['type'] == $propName) {
|
||||
$v = $dn[$i][0]['value'];
|
||||
if (!$withType) {
|
||||
if (is_array($v)) {
|
||||
foreach ($v as $type => $s) {
|
||||
$type = array_search($type, $asn1->ANYmap, true);
|
||||
if ($type !== false && isset($asn1->stringTypeSize[$type])) {
|
||||
$s = $asn1->convert($s, $type);
|
||||
if ($s !== false) {
|
||||
$v = $s;
|
||||
break;
|
||||
}
|
||||
if (!$withType && is_array($v)) {
|
||||
foreach ($v as $type => $s) {
|
||||
$type = array_search($type, $asn1->ANYmap, true);
|
||||
if ($type !== false && isset($asn1->stringTypeSize[$type])) {
|
||||
$s = $asn1->convert($s, $type);
|
||||
if ($s !== false) {
|
||||
$v = $s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_array($v)) {
|
||||
$v = array_pop($v); // Always strip data type.
|
||||
}
|
||||
} elseif (is_object($v) && $v instanceof Element) {
|
||||
$map = $this->_getMapping($propName);
|
||||
if (!is_bool($map)) {
|
||||
$decoded = $asn1->decodeBER($v);
|
||||
$v = $asn1->asn1map($decoded[0], $map);
|
||||
}
|
||||
}
|
||||
if (is_array($v)) {
|
||||
$v = array_pop($v); // Always strip data type.
|
||||
}
|
||||
}
|
||||
$result[] = $v;
|
||||
@ -2570,7 +2447,7 @@ class X509
|
||||
}
|
||||
|
||||
// handles everything else
|
||||
$results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
for ($i = 1; $i < count($results); $i+=2) {
|
||||
$prop = trim($results[$i], ', =/');
|
||||
$value = $results[$i + 1];
|
||||
@ -2605,19 +2482,33 @@ class X509
|
||||
$filters = array();
|
||||
$filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
|
||||
$asn1->loadFilters($filters);
|
||||
$this->_mapOutDNs($dn, 'rdnSequence', $asn1);
|
||||
return $asn1->encodeDER($dn, $this->Name);
|
||||
case self::DN_OPENSSL:
|
||||
$dn = $this->getDN(self::DN_STRING, $dn);
|
||||
if ($dn === false) {
|
||||
return false;
|
||||
}
|
||||
$attrs = preg_split('#((?:^|, *|/)[a-z][a-z0-9]*=)#i', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$dn = array();
|
||||
for ($i = 1; $i < count($attrs); $i += 2) {
|
||||
$prop = trim($attrs[$i], ', =/');
|
||||
$value = $attrs[$i + 1];
|
||||
if (!isset($dn[$prop])) {
|
||||
$dn[$prop] = $value;
|
||||
} else {
|
||||
$dn[$prop] = array_merge((array) $dn[$prop], array($value));
|
||||
}
|
||||
}
|
||||
return $dn;
|
||||
case self::DN_CANON:
|
||||
// No SEQUENCE around RDNs and all string values normalized as
|
||||
// trimmed lowercase UTF-8 with all spacing as one blank.
|
||||
// constructed RDNs will not be canonicalized
|
||||
// trimmed lowercase UTF-8 with all spacing as one blank.
|
||||
$asn1 = new ASN1();
|
||||
$asn1->loadOIDs($this->oids);
|
||||
$filters = array();
|
||||
$filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
|
||||
$asn1->loadFilters($filters);
|
||||
$result = '';
|
||||
$this->_mapOutDNs($dn, 'rdnSequence', $asn1);
|
||||
foreach ($dn['rdnSequence'] as $rdn) {
|
||||
foreach ($rdn as $i => $attr) {
|
||||
$attr = &$rdn[$i];
|
||||
@ -2643,21 +2534,13 @@ class X509
|
||||
$hash = new Hash('sha1');
|
||||
$hash = $hash->hash($dn);
|
||||
extract(unpack('Vhash', $hash));
|
||||
return strtolower(Hex::encode(pack('N', $hash)));
|
||||
return strtolower(bin2hex(pack('N', $hash)));
|
||||
}
|
||||
|
||||
// Default is to return a string.
|
||||
$start = true;
|
||||
$output = '';
|
||||
|
||||
$result = array();
|
||||
$asn1 = new ASN1();
|
||||
$asn1->loadOIDs($this->oids);
|
||||
$filters = array();
|
||||
$filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
|
||||
$asn1->loadFilters($filters);
|
||||
$this->_mapOutDNs($dn, 'rdnSequence', $asn1);
|
||||
|
||||
foreach ($dn['rdnSequence'] as $field) {
|
||||
$prop = $field[0]['type'];
|
||||
$value = $field[0]['value'];
|
||||
@ -2665,37 +2548,33 @@ class X509
|
||||
$delim = ', ';
|
||||
switch ($prop) {
|
||||
case 'id-at-countryName':
|
||||
$desc = 'C';
|
||||
$desc = 'C=';
|
||||
break;
|
||||
case 'id-at-stateOrProvinceName':
|
||||
$desc = 'ST';
|
||||
$desc = 'ST=';
|
||||
break;
|
||||
case 'id-at-organizationName':
|
||||
$desc = 'O';
|
||||
$desc = 'O=';
|
||||
break;
|
||||
case 'id-at-organizationalUnitName':
|
||||
$desc = 'OU';
|
||||
$desc = 'OU=';
|
||||
break;
|
||||
case 'id-at-commonName':
|
||||
$desc = 'CN';
|
||||
$desc = 'CN=';
|
||||
break;
|
||||
case 'id-at-localityName':
|
||||
$desc = 'L';
|
||||
$desc = 'L=';
|
||||
break;
|
||||
case 'id-at-surname':
|
||||
$desc = 'SN';
|
||||
$desc = 'SN=';
|
||||
break;
|
||||
case 'id-at-uniqueIdentifier':
|
||||
$delim = '/';
|
||||
$desc = 'x500UniqueIdentifier';
|
||||
break;
|
||||
case 'id-at-postalAddress':
|
||||
$delim = '/';
|
||||
$desc = 'postalAddress';
|
||||
$desc = 'x500UniqueIdentifier=';
|
||||
break;
|
||||
default:
|
||||
$delim = '/';
|
||||
$desc = preg_replace('#.+-([^-]+)$#', '$1', $prop);
|
||||
$desc = preg_replace('#.+-([^-]+)$#', '$1', $prop) . '=';
|
||||
}
|
||||
|
||||
if (!$start) {
|
||||
@ -2715,18 +2594,12 @@ class X509
|
||||
if (is_array($value)) {
|
||||
$value = array_pop($value); // Always strip data type.
|
||||
}
|
||||
} elseif (is_object($value) && $value instanceof Element) {
|
||||
$callback = create_function('$x', 'return "\x" . bin2hex($x[0]);');
|
||||
$value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
|
||||
}
|
||||
$output.= $desc . '=' . $value;
|
||||
$result[$desc] = isset($result[$desc]) ?
|
||||
array_merge((array) $dn[$prop], array($value)) :
|
||||
$value;
|
||||
$output.= $desc . $value;
|
||||
$start = false;
|
||||
}
|
||||
|
||||
return $format == self::DN_OPENSSL ? $result : $output;
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2937,7 +2810,7 @@ class X509
|
||||
switch ($keyinfo['algorithm']['algorithm']) {
|
||||
case 'rsaEncryption':
|
||||
$publicKey = new RSA();
|
||||
$publicKey->load($key);
|
||||
$publicKey->loadKey($key);
|
||||
$publicKey->setPublicKey();
|
||||
break;
|
||||
default:
|
||||
@ -3001,10 +2874,8 @@ class X509
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_mapInAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
|
||||
$this->_mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
|
||||
|
||||
$this->dn = $csr['certificationRequestInfo']['subject'];
|
||||
$this->_mapInAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
|
||||
|
||||
$this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
||||
|
||||
@ -3015,7 +2886,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$this->publicKey = new RSA();
|
||||
$this->publicKey->load($key);
|
||||
$this->publicKey->loadKey($key);
|
||||
$this->publicKey->setPublicKey();
|
||||
break;
|
||||
default:
|
||||
@ -3050,10 +2921,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']
|
||||
= Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
|
||||
$csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['parameters'] = null;
|
||||
$csr['signatureAlgorithm']['parameters'] = null;
|
||||
$csr['certificationRequestInfo']['signature']['parameters'] = null;
|
||||
= base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3067,7 +2935,6 @@ class X509
|
||||
|
||||
$asn1->loadFilters($filters);
|
||||
|
||||
$this->_mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
|
||||
$this->_mapOutAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
|
||||
$csr = $asn1->encodeDER($csr, $this->CertificationRequest);
|
||||
|
||||
@ -3076,7 +2943,7 @@ class X509
|
||||
return $csr;
|
||||
// case self::FORMAT_PEM:
|
||||
default:
|
||||
return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Base64::encode($csr), 64) . '-----END CERTIFICATE REQUEST-----';
|
||||
return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----';
|
||||
}
|
||||
}
|
||||
|
||||
@ -3107,7 +2974,7 @@ class X509
|
||||
|
||||
// OpenSSL produces SPKAC's that are preceeded by the string SPKAC=
|
||||
$temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false;
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
|
||||
if ($temp != false) {
|
||||
$spkac = $temp;
|
||||
}
|
||||
@ -3142,7 +3009,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$this->publicKey = new RSA();
|
||||
$this->publicKey->load($key);
|
||||
$this->publicKey->loadKey($key);
|
||||
$this->publicKey->setPublicKey();
|
||||
break;
|
||||
default:
|
||||
@ -3178,7 +3045,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']
|
||||
= Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])));
|
||||
= base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3194,7 +3061,7 @@ class X509
|
||||
default:
|
||||
// OpenSSL's implementation of SPKAC requires the SPKAC be preceeded by SPKAC= and since there are pretty much
|
||||
// no other SPKAC decoders phpseclib will use that same format
|
||||
return 'SPKAC=' . Base64::encode($spkac);
|
||||
return 'SPKAC=' . base64_encode($spkac);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3245,19 +3112,11 @@ class X509
|
||||
|
||||
$this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
||||
|
||||
$this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
|
||||
if ($this->_isSubArrayValid($crl, 'tbsCertList/crlExtensions')) {
|
||||
$this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
|
||||
}
|
||||
if ($this->_isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) {
|
||||
$rclist_ref = &$this->_subArrayUnchecked($crl, 'tbsCertList/revokedCertificates');
|
||||
if ($rclist_ref) {
|
||||
$rclist = $crl['tbsCertList']['revokedCertificates'];
|
||||
foreach ($rclist as $i => $extension) {
|
||||
if ($this->_isSubArrayValid($rclist, "$i/crlEntryExtensions", $asn1)) {
|
||||
$this->_mapInExtensions($rclist_ref, "$i/crlEntryExtensions", $asn1);
|
||||
}
|
||||
}
|
||||
$this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
|
||||
$rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates');
|
||||
if (is_array($rclist)) {
|
||||
foreach ($rclist as $i => $extension) {
|
||||
$this->_mapInExtensions($rclist, "$i/crlEntryExtensions", $asn1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3305,7 +3164,6 @@ class X509
|
||||
|
||||
$asn1->loadFilters($filters);
|
||||
|
||||
$this->_mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
|
||||
$this->_mapOutExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
|
||||
$rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates');
|
||||
if (is_array($rclist)) {
|
||||
@ -3321,7 +3179,7 @@ class X509
|
||||
return $crl;
|
||||
// case self::FORMAT_PEM:
|
||||
default:
|
||||
return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Base64::encode($crl), 64) . '-----END X509 CRL-----';
|
||||
return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl), 64) . '-----END X509 CRL-----';
|
||||
}
|
||||
}
|
||||
|
||||
@ -3360,7 +3218,7 @@ class X509
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
function sign($issuer, $subject, $signatureAlgorithm = 'sha256WithRSAEncryption')
|
||||
function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption')
|
||||
{
|
||||
if (!is_object($issuer->privateKey) || empty($issuer->dn)) {
|
||||
return false;
|
||||
@ -3513,7 +3371,7 @@ class X509
|
||||
);
|
||||
|
||||
if (!isset($subject->currentKeyIdentifier)) {
|
||||
$this->setExtension('id-ce-subjectKeyIdentifier', Base64::encode($this->computeKeyIdentifier($this->currentCert)), false, false);
|
||||
$this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3546,7 +3404,7 @@ class X509
|
||||
$origPublicKey = $this->publicKey;
|
||||
$class = get_class($this->privateKey);
|
||||
$this->publicKey = new $class();
|
||||
$this->publicKey->load($this->privateKey->getPublicKey());
|
||||
$this->publicKey->loadKey($this->privateKey->getPublicKey());
|
||||
$this->publicKey->setPublicKey();
|
||||
if (!($publicKey = $this->_formatSubjectPublicKey())) {
|
||||
return false;
|
||||
@ -3604,7 +3462,7 @@ class X509
|
||||
$origPublicKey = $this->publicKey;
|
||||
$class = get_class($this->privateKey);
|
||||
$this->publicKey = new $class();
|
||||
$this->publicKey->load($this->privateKey->getPublicKey());
|
||||
$this->publicKey->loadKey($this->privateKey->getPublicKey());
|
||||
$this->publicKey->setPublicKey();
|
||||
$publicKey = $this->_formatSubjectPublicKey();
|
||||
if (!$publicKey) {
|
||||
@ -3792,7 +3650,6 @@ class X509
|
||||
* @param \phpseclib\File\X509 $subject
|
||||
* @param string $signatureAlgorithm
|
||||
* @access public
|
||||
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||
* @return mixed
|
||||
*/
|
||||
function _sign($key, $signatureAlgorithm)
|
||||
@ -3807,15 +3664,14 @@ class X509
|
||||
case 'sha384WithRSAEncryption':
|
||||
case 'sha512WithRSAEncryption':
|
||||
$key->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
|
||||
$key->setSignatureMode(RSA::SIGNATURE_PKCS1);
|
||||
|
||||
$this->currentCert['signature'] = Base64::encode("\0" . $key->sign($this->signatureSubject, RSA::PADDING_PKCS1));
|
||||
$this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject));
|
||||
return $this->currentCert;
|
||||
default:
|
||||
throw new UnsupportedAlgorithmException('Signature algorithm unsupported');
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnsupportedAlgorithmException('Unsupported public key algorithm');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3876,74 +3732,6 @@ class X509
|
||||
$this->caFlag = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for validity of subarray
|
||||
*
|
||||
* This is intended for use in conjunction with _subArrayUnchecked(),
|
||||
* implementing the checks included in _subArray() but without copying
|
||||
* a potentially large array by passing its reference by-value to is_array().
|
||||
*
|
||||
* @param array $root
|
||||
* @param string $path
|
||||
* @return boolean
|
||||
* @access private
|
||||
*/
|
||||
function _isSubArrayValid($root, $path)
|
||||
{
|
||||
if (!is_array($root)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (explode('/', $path) as $i) {
|
||||
if (!is_array($root)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($root[$i])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$root = $root[$i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to a subarray
|
||||
*
|
||||
* This variant of _subArray() does no is_array() checking,
|
||||
* so $root should be checked with _isSubArrayValid() first.
|
||||
*
|
||||
* This is here for performance reasons:
|
||||
* Passing a reference (i.e. $root) by-value (i.e. to is_array())
|
||||
* creates a copy. If $root is an especially large array, this is expensive.
|
||||
*
|
||||
* @param array $root
|
||||
* @param string $path absolute path with / as component separator
|
||||
* @param bool $create optional
|
||||
* @access private
|
||||
* @return array|false
|
||||
*/
|
||||
function &_subArrayUnchecked(&$root, $path, $create = false)
|
||||
{
|
||||
$false = false;
|
||||
|
||||
foreach (explode('/', $path) as $i) {
|
||||
if (!isset($root[$i])) {
|
||||
if (!$create) {
|
||||
return $false;
|
||||
}
|
||||
|
||||
$root[$i] = array();
|
||||
}
|
||||
|
||||
$root = &$root[$i];
|
||||
}
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to a subarray
|
||||
*
|
||||
@ -4389,7 +4177,7 @@ class X509
|
||||
if (empty($value)) {
|
||||
unset($this->currentKeyIdentifier);
|
||||
} else {
|
||||
$this->currentKeyIdentifier = Base64::encode($value);
|
||||
$this->currentKeyIdentifier = base64_encode($value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4437,10 +4225,10 @@ class X509
|
||||
if (empty($raw)) {
|
||||
return false;
|
||||
}
|
||||
$raw = Base64::decode($raw);
|
||||
$raw = base64_decode($raw);
|
||||
// If the key is private, compute identifier from its corresponding public key.
|
||||
$key = new RSA();
|
||||
if (!$key->load($raw)) {
|
||||
if (!$key->loadKey($raw)) {
|
||||
return false; // Not an unencrypted RSA key.
|
||||
}
|
||||
if ($key->getPrivateKey() !== false) { // If private.
|
||||
@ -4460,7 +4248,7 @@ class X509
|
||||
}
|
||||
return false;
|
||||
default: // Should be a key object (i.e.: \phpseclib\Crypt\RSA).
|
||||
$key = $key->getPublicKey('PKCS1');
|
||||
$key = $key->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4490,10 +4278,10 @@ class X509
|
||||
if ($this->publicKey instanceof RSA) {
|
||||
// the following two return statements do the same thing. i dunno.. i just prefer the later for some reason.
|
||||
// the former is a good example of how to do fuzzing on the public key
|
||||
//return new Element(Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey())));
|
||||
//return new Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey())));
|
||||
return array(
|
||||
'algorithm' => array('algorithm' => 'rsaEncryption'),
|
||||
'subjectPublicKey' => $this->publicKey->getPublicKey('PKCS1')
|
||||
'subjectPublicKey' => $this->publicKey->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1)
|
||||
);
|
||||
}
|
||||
|
||||
@ -4793,7 +4581,7 @@ class X509
|
||||
$temp = preg_replace('#-+[^-]+-+#', '', $temp);
|
||||
// remove new lines
|
||||
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false;
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
|
||||
return $temp != false ? $temp : $str;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
10
vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
vendored
10
vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
vendored
@ -32,8 +32,6 @@
|
||||
|
||||
namespace phpseclib\Net;
|
||||
|
||||
use phpseclib\Exception\FileNotFoundException;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of SCP.
|
||||
*
|
||||
@ -139,7 +137,6 @@ class SCP
|
||||
* @param string $data
|
||||
* @param int $mode
|
||||
* @param callable $callback
|
||||
* @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
@ -168,7 +165,8 @@ class SCP
|
||||
$size = strlen($data);
|
||||
} else {
|
||||
if (!is_file($data)) {
|
||||
throw new FileNotFoundException("$data is not a valid file");
|
||||
user_error("$data is not a valid file", E_USER_NOTICE);
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = @fopen($data, 'rb');
|
||||
@ -288,7 +286,6 @@ class SCP
|
||||
* Receives a packet from an SSH server
|
||||
*
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException on receipt of an unexpected packet
|
||||
* @access private
|
||||
*/
|
||||
function _receive()
|
||||
@ -314,7 +311,8 @@ class SCP
|
||||
$this->ssh->bitmap = 0;
|
||||
return false;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Unknown packet received');
|
||||
user_error('Unknown packet received', E_USER_NOTICE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
204
vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
vendored
204
vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
vendored
@ -37,9 +37,6 @@
|
||||
|
||||
namespace phpseclib\Net;
|
||||
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Exception\FileNotFoundException;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of SFTP.
|
||||
*
|
||||
@ -384,7 +381,6 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
@ -472,7 +468,8 @@ class SFTP extends SSH2
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_VERSION) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_VERSION');
|
||||
user_error('Expected SSH_FXP_VERSION');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Nversion', $this->_string_shift($response, 4)));
|
||||
@ -603,21 +600,6 @@ class SFTP extends SSH2
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns canonicalized absolute pathname
|
||||
*
|
||||
* realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input
|
||||
* path and returns the canonicalized absolute pathname.
|
||||
*
|
||||
* @param string $path
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function realpath($path)
|
||||
{
|
||||
return $this->_realpath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonicalize the Server-Side Path Name
|
||||
*
|
||||
@ -626,7 +608,6 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @see self::chdir()
|
||||
* @param string $path
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return mixed
|
||||
* @access private
|
||||
*/
|
||||
@ -651,7 +632,8 @@ class SFTP extends SSH2
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -682,7 +664,6 @@ class SFTP extends SSH2
|
||||
* Changes the current directory
|
||||
*
|
||||
* @param string $dir
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
@ -727,7 +708,8 @@ class SFTP extends SSH2
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->_close_handle($handle)) {
|
||||
@ -829,7 +811,6 @@ class SFTP extends SSH2
|
||||
* @param string $dir
|
||||
* @param bool $raw
|
||||
* @return mixed
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @access private
|
||||
*/
|
||||
function _list($dir, $raw = true)
|
||||
@ -861,7 +842,8 @@ class SFTP extends SSH2
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_update_stat_cache($dir, array());
|
||||
@ -915,7 +897,8 @@ class SFTP extends SSH2
|
||||
}
|
||||
break 2;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1274,7 +1257,6 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @param string $filename
|
||||
* @param int $type
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return mixed
|
||||
* @access private
|
||||
*/
|
||||
@ -1295,7 +1277,8 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1321,7 +1304,6 @@ class SFTP extends SSH2
|
||||
* @param string $filename
|
||||
* @param int $time
|
||||
* @param int $atime
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
@ -1358,7 +1340,8 @@ class SFTP extends SSH2
|
||||
$this->_logError($response);
|
||||
break;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->_setstat($filename, $attr, false);
|
||||
@ -1411,7 +1394,6 @@ class SFTP extends SSH2
|
||||
* @param int $mode
|
||||
* @param string $filename
|
||||
* @param bool $recursive
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
@ -1450,7 +1432,8 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1459,7 +1442,6 @@ class SFTP extends SSH2
|
||||
* @param string $filename
|
||||
* @param string $attr
|
||||
* @param bool $recursive
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
@ -1498,7 +1480,8 @@ class SFTP extends SSH2
|
||||
*/
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
@ -1586,7 +1569,6 @@ class SFTP extends SSH2
|
||||
* Return the target of a symbolic link
|
||||
*
|
||||
* @param string $link
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
@ -1610,7 +1592,8 @@ class SFTP extends SSH2
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
||||
@ -1630,7 +1613,6 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @param string $target
|
||||
* @param string $link
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
@ -1640,7 +1622,7 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
//$target = $this->_realpath($target);
|
||||
$target = $this->_realpath($target);
|
||||
$link = $this->_realpath($link);
|
||||
|
||||
$packet = pack('Na*Na*', strlen($target), $target, strlen($link), $link);
|
||||
@ -1650,7 +1632,8 @@ class SFTP extends SSH2
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
@ -1702,7 +1685,6 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @access private
|
||||
*/
|
||||
function _mkdir_helper($dir, $attr)
|
||||
@ -1713,7 +1695,8 @@ class SFTP extends SSH2
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
@ -1729,7 +1712,6 @@ class SFTP extends SSH2
|
||||
* Removes a directory.
|
||||
*
|
||||
* @param string $dir
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
@ -1750,7 +1732,8 @@ class SFTP extends SSH2
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
@ -1810,9 +1793,6 @@ class SFTP extends SSH2
|
||||
* @param int $start
|
||||
* @param int $local_start
|
||||
* @param callable|null $progressCallback
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid
|
||||
* @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist
|
||||
* @return bool
|
||||
* @access public
|
||||
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode().
|
||||
@ -1860,7 +1840,8 @@ class SFTP extends SSH2
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
||||
@ -1868,7 +1849,7 @@ class SFTP extends SSH2
|
||||
switch (true) {
|
||||
case $mode & self::SOURCE_CALLBACK:
|
||||
if (!is_callable($data)) {
|
||||
throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
|
||||
user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
|
||||
}
|
||||
$dataCallback = $data;
|
||||
// do nothing
|
||||
@ -1879,7 +1860,8 @@ class SFTP extends SSH2
|
||||
break;
|
||||
case $mode & self::SOURCE_LOCAL_FILE:
|
||||
if (!is_file($data)) {
|
||||
throw new FileNotFoundException("$data is not a valid file");
|
||||
user_error("$data is not a valid file");
|
||||
return false;
|
||||
}
|
||||
$fp = @fopen($data, 'rb');
|
||||
if (!$fp) {
|
||||
@ -1908,7 +1890,7 @@ class SFTP extends SSH2
|
||||
// make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
|
||||
$sftp_packet_size-= strlen($handle) + 25;
|
||||
$i = 0;
|
||||
while ($dataCallback || ($size === 0 || $sent < $size)) {
|
||||
while ($dataCallback || $sent < $size) {
|
||||
if ($dataCallback) {
|
||||
$temp = call_user_func($dataCallback, $sftp_packet_size);
|
||||
if (is_null($temp)) {
|
||||
@ -1916,11 +1898,7 @@ class SFTP extends SSH2
|
||||
}
|
||||
} else {
|
||||
$temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
|
||||
if ($temp === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$subtemp = $offset + $sent;
|
||||
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
|
||||
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
|
||||
@ -1968,7 +1946,6 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @param int $i
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @access private
|
||||
*/
|
||||
function _read_put_responses($i)
|
||||
@ -1976,7 +1953,8 @@ class SFTP extends SSH2
|
||||
while ($i--) {
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
@ -1994,7 +1972,6 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @param string $handle
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @access private
|
||||
*/
|
||||
function _close_handle($handle)
|
||||
@ -2007,7 +1984,8 @@ class SFTP extends SSH2
|
||||
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
@ -2032,7 +2010,6 @@ class SFTP extends SSH2
|
||||
* @param string $local_file
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
@ -2061,7 +2038,8 @@ class SFTP extends SSH2
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_resource($local_file)) {
|
||||
@ -2083,68 +2061,40 @@ class SFTP extends SSH2
|
||||
$fclose_check = $local_file !== false && !is_resource($local_file);
|
||||
|
||||
$start = $offset;
|
||||
$read = 0;
|
||||
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
|
||||
while (true) {
|
||||
$i = 0;
|
||||
$packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size);
|
||||
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
||||
if ($fclose_check) {
|
||||
fclose($fp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
|
||||
$tempoffset = $start + $read;
|
||||
|
||||
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
|
||||
|
||||
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
|
||||
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
||||
$response = $this->_get_sftp_packet();
|
||||
switch ($this->packet_type) {
|
||||
case NET_SFTP_DATA:
|
||||
$temp = substr($response, 4);
|
||||
$offset+= strlen($temp);
|
||||
if ($local_file === false) {
|
||||
$content.= $temp;
|
||||
} else {
|
||||
fputs($fp, $temp);
|
||||
}
|
||||
break;
|
||||
case NET_SFTP_STATUS:
|
||||
// could, in theory, return false if !strlen($content) but we'll hold off for the time being
|
||||
$this->_logError($response);
|
||||
break 2;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
|
||||
if ($fclose_check) {
|
||||
fclose($fp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$packet = null;
|
||||
$read+= $packet_size;
|
||||
$i++;
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
break;
|
||||
}
|
||||
|
||||
$clear_responses = false;
|
||||
while ($i > 0) {
|
||||
$i--;
|
||||
|
||||
if ($clear_responses) {
|
||||
$this->_get_sftp_packet();
|
||||
continue;
|
||||
} else {
|
||||
$response = $this->_get_sftp_packet();
|
||||
}
|
||||
|
||||
switch ($this->packet_type) {
|
||||
case NET_SFTP_DATA:
|
||||
$temp = substr($response, 4);
|
||||
$offset+= strlen($temp);
|
||||
if ($local_file === false) {
|
||||
$content.= $temp;
|
||||
} else {
|
||||
fputs($fp, $temp);
|
||||
}
|
||||
$temp = null;
|
||||
break;
|
||||
case NET_SFTP_STATUS:
|
||||
// could, in theory, return false if !strlen($content) but we'll hold off for the time being
|
||||
$this->_logError($response);
|
||||
$clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses
|
||||
break;
|
||||
default:
|
||||
if ($fclose_check) {
|
||||
fclose($fp);
|
||||
}
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
|
||||
}
|
||||
$response = null;
|
||||
}
|
||||
|
||||
if ($clear_responses) {
|
||||
if ($length > 0 && $length <= $offset - $start) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2175,7 +2125,6 @@ class SFTP extends SSH2
|
||||
* @param string $path
|
||||
* @param bool $recursive
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @access public
|
||||
*/
|
||||
function delete($path, $recursive = true)
|
||||
@ -2196,7 +2145,8 @@ class SFTP extends SSH2
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||
@ -2598,7 +2548,6 @@ class SFTP extends SSH2
|
||||
* @param string $oldname
|
||||
* @param string $newname
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @access public
|
||||
*/
|
||||
function rename($oldname, $newname)
|
||||
@ -2621,7 +2570,8 @@ class SFTP extends SSH2
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||
user_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||
@ -2663,7 +2613,7 @@ class SFTP extends SSH2
|
||||
// IEEE 754 binary64 "double precision" on such platforms and
|
||||
// as such can represent integers of at least 2^50 without loss
|
||||
// of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB.
|
||||
$attr['size'] = hexdec(Hex::encode($this->_string_shift($response, 8)));
|
||||
$attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8)));
|
||||
break;
|
||||
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
|
||||
$attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
|
||||
@ -2795,13 +2745,13 @@ class SFTP extends SSH2
|
||||
if (defined('NET_SFTP_LOGGING')) {
|
||||
$packet_type = '-> ' . $this->packet_types[$type] .
|
||||
' (' . round($stop - $start, 4) . 's)';
|
||||
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
|
||||
echo "<pre>\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n</pre>\r\n";
|
||||
flush();
|
||||
ob_flush();
|
||||
} else {
|
||||
$this->packet_type_log[] = $packet_type;
|
||||
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
|
||||
$this->packet_log[] = $data;
|
||||
}
|
||||
}
|
||||
@ -2871,13 +2821,13 @@ class SFTP extends SSH2
|
||||
if (defined('NET_SFTP_LOGGING')) {
|
||||
$packet_type = '<- ' . $this->packet_types[$this->packet_type] .
|
||||
' (' . round($stop - $start, 4) . 's)';
|
||||
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
|
||||
echo "<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n</pre>\r\n";
|
||||
flush();
|
||||
ob_flush();
|
||||
} else {
|
||||
$this->packet_type_log[] = $packet_type;
|
||||
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
|
||||
$this->packet_log[] = $packet;
|
||||
}
|
||||
}
|
||||
@ -2889,7 +2839,7 @@ class SFTP extends SSH2
|
||||
/**
|
||||
* Returns a log of the packets that have been sent and received.
|
||||
*
|
||||
* Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
|
||||
* Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
|
||||
*
|
||||
* @access public
|
||||
* @return string or Array
|
||||
@ -2901,10 +2851,10 @@ class SFTP extends SSH2
|
||||
}
|
||||
|
||||
switch (NET_SFTP_LOGGING) {
|
||||
case self::LOG_COMPLEX:
|
||||
case NET_SFTP_LOG_COMPLEX:
|
||||
return $this->_format_log($this->packet_log, $this->packet_type_log);
|
||||
break;
|
||||
//case self::LOG_SIMPLE:
|
||||
//case NET_SFTP_LOG_SIMPLE:
|
||||
default:
|
||||
return $this->packet_type_log;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ namespace phpseclib\Net\SFTP;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Net\SFTP;
|
||||
use phpseclib\Net\SSH2;
|
||||
|
||||
/**
|
||||
* SFTP Stream Wrapper
|
||||
@ -178,12 +177,13 @@ class Stream
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match('/^{[a-z0-9]+}$/i', $host)) {
|
||||
$host = SSH2::getConnectionByResourceId($host);
|
||||
if ($host === false) {
|
||||
if ($host[0] == '$') {
|
||||
$host = substr($host, 1);
|
||||
global $$host;
|
||||
if (($$host instanceof SFTP) === false) {
|
||||
return false;
|
||||
}
|
||||
$this->sftp = $host;
|
||||
$this->sftp = $$host;
|
||||
} else {
|
||||
if (isset($this->context)) {
|
||||
$context = stream_context_get_options($this->context);
|
||||
|
@ -48,7 +48,6 @@
|
||||
|
||||
namespace phpseclib\Net;
|
||||
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Crypt\TripleDES;
|
||||
@ -538,15 +537,14 @@ class SSH1
|
||||
* Connect to an SSHv1 server
|
||||
*
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @access private
|
||||
*/
|
||||
function _connect()
|
||||
{
|
||||
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout);
|
||||
if (!$this->fsock) {
|
||||
throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
||||
user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error $errno. $errstr"));
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->server_identification = $init_line = fgets($this->fsock, 255);
|
||||
@ -557,17 +555,20 @@ class SSH1
|
||||
}
|
||||
|
||||
if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {
|
||||
throw new \RuntimeException('Can only connect to SSH servers');
|
||||
user_error('Can only connect to SSH servers');
|
||||
return false;
|
||||
}
|
||||
if ($parts[1][0] != 1) {
|
||||
throw new \RuntimeException("Cannot connect to $parts[1] servers");
|
||||
user_error("Cannot connect to SSH $parts[1] servers");
|
||||
return false;
|
||||
}
|
||||
|
||||
fputs($this->fsock, $this->identifier."\r\n");
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_PUBLIC_KEY');
|
||||
user_error('Expected SSH_SMSG_PUBLIC_KEY');
|
||||
return false;
|
||||
}
|
||||
|
||||
$anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
|
||||
@ -610,7 +611,7 @@ class SSH1
|
||||
}
|
||||
}
|
||||
|
||||
$session_id = md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie, true);
|
||||
$session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));
|
||||
|
||||
$session_key = Random::string(32);
|
||||
$double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));
|
||||
@ -651,7 +652,8 @@ class SSH1
|
||||
$data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_SESSION_KEY');
|
||||
user_error('Error sending SSH_CMSG_SESSION_KEY');
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($cipher) {
|
||||
@ -659,20 +661,16 @@ class SSH1
|
||||
// $this->crypto = new \phpseclib\Crypt\Null();
|
||||
// break;
|
||||
case self::CIPHER_DES:
|
||||
$this->crypto = new DES(DES::MODE_CBC);
|
||||
$this->crypto = new DES();
|
||||
$this->crypto->disablePadding();
|
||||
$this->crypto->enableContinuousBuffer();
|
||||
$this->crypto->setKey(substr($session_key, 0, 8));
|
||||
// "The iv (initialization vector) is initialized to all zeroes."
|
||||
$this->crypto->setIV(str_repeat("\0", 8));
|
||||
break;
|
||||
case self::CIPHER_3DES:
|
||||
$this->crypto = new TripleDES(TripleDES::MODE_3CBC);
|
||||
$this->crypto->disablePadding();
|
||||
$this->crypto->enableContinuousBuffer();
|
||||
$this->crypto->setKey(substr($session_key, 0, 24));
|
||||
// "All three initialization vectors are initialized to zero."
|
||||
$this->crypto->setIV(str_repeat("\0", 8));
|
||||
break;
|
||||
//case self::CIPHER_RC4:
|
||||
// $this->crypto = new RC4();
|
||||
@ -684,7 +682,8 @@ class SSH1
|
||||
$response = $this->_get_binary_packet();
|
||||
|
||||
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS');
|
||||
user_error('Expected SSH_SMSG_SUCCESS');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->bitmap = self::MASK_CONNECTED;
|
||||
@ -698,8 +697,6 @@ class SSH1
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @access public
|
||||
*/
|
||||
function login($username, $password = '')
|
||||
@ -718,7 +715,8 @@ class SSH1
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_USER');
|
||||
user_error('Error sending SSH_CMSG_USER');
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
@ -730,13 +728,15 @@ class SSH1
|
||||
$this->bitmap |= self::MASK_LOGIN;
|
||||
return true;
|
||||
} elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_AUTH_PASSWORD');
|
||||
user_error('Error sending SSH_CMSG_AUTH_PASSWORD');
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove the username and password from the last logged packet
|
||||
@ -756,7 +756,8 @@ class SSH1
|
||||
} elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
|
||||
return false;
|
||||
} else {
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,19 +792,20 @@ class SSH1
|
||||
* @see self::interactiveWrite()
|
||||
* @param string $cmd
|
||||
* @return mixed
|
||||
* @throws \RuntimeException on error sending command
|
||||
* @access public
|
||||
*/
|
||||
function exec($cmd, $block = true)
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_EXEC_CMD');
|
||||
user_error('Error sending SSH_CMSG_EXEC_CMD');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$block) {
|
||||
@ -839,8 +841,6 @@ class SSH1
|
||||
* @see self::interactiveRead()
|
||||
* @see self::interactiveWrite()
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @access private
|
||||
*/
|
||||
function _initShell()
|
||||
@ -851,7 +851,8 @@ class SSH1
|
||||
$data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, self::TTY_OP_END);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_REQUEST_PTY');
|
||||
user_error('Error sending SSH_CMSG_REQUEST_PTY');
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
@ -860,13 +861,15 @@ class SSH1
|
||||
return false;
|
||||
}
|
||||
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS');
|
||||
user_error('Expected SSH_SMSG_SUCCESS');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_EXEC_SHELL');
|
||||
user_error('Error sending SSH_CMSG_EXEC_SHELL');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->bitmap |= self::MASK_SHELL;
|
||||
@ -899,17 +902,18 @@ class SSH1
|
||||
* @param string $expect
|
||||
* @param int $mode
|
||||
* @return bool
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function read($expect, $mode = self::READ__SIMPLE)
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
$match = $expect;
|
||||
@ -937,23 +941,25 @@ class SSH1
|
||||
* @see self::interactiveRead()
|
||||
* @param string $cmd
|
||||
* @return bool
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function interactiveWrite($cmd)
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_STDIN');
|
||||
user_error('Error sending SSH_CMSG_STDIN');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -970,17 +976,18 @@ class SSH1
|
||||
*
|
||||
* @see self::interactiveRead()
|
||||
* @return string
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function interactiveRead()
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
$read = array($this->fsock);
|
||||
@ -1306,9 +1313,9 @@ class SSH1
|
||||
{
|
||||
/*
|
||||
$rsa = new RSA();
|
||||
$rsa->load($key, 'raw');
|
||||
$rsa->setHash('sha1');
|
||||
return $rsa->encrypt($m, RSA::PADDING_PKCS1);
|
||||
$rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW);
|
||||
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
|
||||
return $rsa->encrypt($m);
|
||||
*/
|
||||
|
||||
// To quote from protocol-1.5.txt:
|
||||
|
378
vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
vendored
378
vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
vendored
@ -26,7 +26,7 @@
|
||||
*
|
||||
* $key = new \phpseclib\Crypt\RSA();
|
||||
* //$key->setPassword('whatever');
|
||||
* $key->load(file_get_contents('privatekey'));
|
||||
* $key->loadKey(file_get_contents('privatekey'));
|
||||
*
|
||||
* $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
|
||||
* if (!$ssh->login('username', $key)) {
|
||||
@ -49,7 +49,6 @@
|
||||
|
||||
namespace phpseclib\Net;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Crypt\Base;
|
||||
use phpseclib\Crypt\Blowfish;
|
||||
use phpseclib\Crypt\Hash;
|
||||
@ -61,7 +60,6 @@ use phpseclib\Crypt\TripleDES;
|
||||
use phpseclib\Crypt\Twofish;
|
||||
use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
|
||||
use phpseclib\System\SSH\Agent;
|
||||
use phpseclib\Exception\NoSupportedAlgorithmsException;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of SSHv2.
|
||||
@ -868,14 +866,6 @@ class SSH2
|
||||
*/
|
||||
var $agent;
|
||||
|
||||
/**
|
||||
* Connection storage to replicates ssh2 extension functionality:
|
||||
* {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
|
||||
*
|
||||
* @var SSH2[]
|
||||
*/
|
||||
static $connections;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@ -969,8 +959,6 @@ class SSH2
|
||||
31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY')
|
||||
);
|
||||
|
||||
self::$connections[$this->getResourceId()] = $this;
|
||||
|
||||
if (is_resource($host)) {
|
||||
$this->fsock = $host;
|
||||
return;
|
||||
@ -1001,8 +989,6 @@ class SSH2
|
||||
* Connect to an SSHv2 server
|
||||
*
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @access private
|
||||
*/
|
||||
function _connect()
|
||||
@ -1022,7 +1008,8 @@ class SSH2
|
||||
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
|
||||
if (!$this->fsock) {
|
||||
$host = $this->host . ':' . $this->port;
|
||||
throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
||||
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
||||
return false;
|
||||
}
|
||||
$elapsed = microtime(true) - $start;
|
||||
|
||||
@ -1041,74 +1028,70 @@ class SSH2
|
||||
Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
|
||||
in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients
|
||||
MUST be able to process such lines." */
|
||||
$data = '';
|
||||
while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) {
|
||||
$line = '';
|
||||
while (true) {
|
||||
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 = stream_get_line($this->fsock, 255, "\n");
|
||||
if (strlen($temp) == 255) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$line.= "$temp\n";
|
||||
if (substr($line, -2) == "\r\n") {
|
||||
break;
|
||||
}
|
||||
$temp = '';
|
||||
$extra = '';
|
||||
while (!feof($this->fsock) && !preg_match('#^SSH-(\d\.\d+)#', $temp, $matches)) {
|
||||
if (substr($temp, -2) == "\r\n") {
|
||||
$extra.= $temp;
|
||||
$temp = '';
|
||||
}
|
||||
$data.= $line;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (feof($this->fsock)) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
$extra = $matches[1];
|
||||
|
||||
$this->identifier = $this->_generate_identifier();
|
||||
|
||||
if (defined('NET_SSH2_LOGGING')) {
|
||||
$this->_append_log('<-', $matches[0]);
|
||||
$this->_append_log('<-', $extra . $temp);
|
||||
$this->_append_log('->', $this->identifier . "\r\n");
|
||||
}
|
||||
|
||||
$this->server_identifier = trim($temp, "\r\n");
|
||||
if (strlen($extra)) {
|
||||
$this->errors[] = utf8_decode($data);
|
||||
$this->errors[] = utf8_decode($extra);
|
||||
}
|
||||
|
||||
if ($matches[3] != '1.99' && $matches[3] != '2.0') {
|
||||
throw new \RuntimeException("Cannot connect to SSH $matches[1] servers");
|
||||
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
|
||||
user_error("Cannot connect to SSH $matches[1] servers");
|
||||
return false;
|
||||
}
|
||||
|
||||
fputs($this->fsock, $this->identifier . "\r\n");
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
||||
user_error('Expected SSH_MSG_KEXINIT');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->_key_exchange($response)) {
|
||||
@ -1160,9 +1143,6 @@ class SSH2
|
||||
* Key Exchange
|
||||
*
|
||||
* @param string $kexinit_payload_server
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @throws \phpseclib\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible
|
||||
* @access private
|
||||
*/
|
||||
function _key_exchange($kexinit_payload_server)
|
||||
@ -1374,28 +1354,27 @@ class SSH2
|
||||
// here ends the second place.
|
||||
|
||||
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
|
||||
|
||||
// we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
|
||||
// diffie-hellman key exchange as fast as possible
|
||||
$decrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_server_to_client);
|
||||
$decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
|
||||
if ($decryptKeyLength === null) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found');
|
||||
user_error('No compatible server to client encryption algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
$encrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_client_to_server);
|
||||
$encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
|
||||
if ($encryptKeyLength === null) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found');
|
||||
user_error('No compatible client to server encryption algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
// through diffie-hellman key exchange a symmetric key is obtained
|
||||
$kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
|
||||
if ($kex_algorithm === false) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found');
|
||||
user_error('No compatible key exchange algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
// Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty.
|
||||
@ -1504,7 +1483,7 @@ class SSH2
|
||||
$max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
|
||||
$max = $max->subtract($one);
|
||||
|
||||
$x = BigInteger::random($one, $max);
|
||||
$x = $one->random($one, $max);
|
||||
$e = $g->modPow($x, $prime);
|
||||
|
||||
$eBytes = $e->toBytes(true);
|
||||
@ -1512,17 +1491,20 @@ class SSH2
|
||||
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
|
||||
if ($type != $serverKexReplyMessage) {
|
||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXDH_REPLY');
|
||||
user_error('Expected SSH_MSG_KEXDH_REPLY');
|
||||
return false;
|
||||
}
|
||||
|
||||
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
||||
@ -1582,13 +1564,13 @@ class SSH2
|
||||
|
||||
$server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
|
||||
if ($server_host_key_algorithm === false) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found');
|
||||
user_error('No compatible server host key algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new \RuntimeException('Server Host Key Algorithm Mismatch');
|
||||
user_error('Server Host Key Algorithm Mismatch');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
$packet = pack(
|
||||
@ -1603,13 +1585,15 @@ class SSH2
|
||||
$response = $this->_get_binary_packet();
|
||||
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
|
||||
if ($type != NET_SSH2_MSG_NEWKEYS) {
|
||||
throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS');
|
||||
user_error('Expected SSH_MSG_NEWKEYS');
|
||||
return false;
|
||||
}
|
||||
|
||||
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
|
||||
@ -1625,13 +1609,11 @@ class SSH2
|
||||
$this->encrypt->enableContinuousBuffer();
|
||||
$this->encrypt->disablePadding();
|
||||
|
||||
if ($this->encrypt->usesIV()) {
|
||||
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
|
||||
while ($this->encrypt_block_size > strlen($iv)) {
|
||||
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
|
||||
}
|
||||
$this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
|
||||
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
|
||||
while ($this->encrypt_block_size > strlen($iv)) {
|
||||
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
|
||||
}
|
||||
$this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
|
||||
|
||||
$key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id);
|
||||
while ($encryptKeyLength > strlen($key)) {
|
||||
@ -1651,13 +1633,11 @@ class SSH2
|
||||
$this->decrypt->enableContinuousBuffer();
|
||||
$this->decrypt->disablePadding();
|
||||
|
||||
if ($this->decrypt->usesIV()) {
|
||||
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
|
||||
while ($this->decrypt_block_size > strlen($iv)) {
|
||||
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
|
||||
}
|
||||
$this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
|
||||
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
|
||||
while ($this->decrypt_block_size > strlen($iv)) {
|
||||
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
|
||||
}
|
||||
$this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
|
||||
|
||||
$key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id);
|
||||
while ($decryptKeyLength > strlen($key)) {
|
||||
@ -1682,8 +1662,8 @@ class SSH2
|
||||
|
||||
$mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_client_to_server);
|
||||
if ($mac_algorithm === false) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found');
|
||||
user_error('No compatible client to server message authentication algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
$createKeyLength = 0; // ie. $mac_algorithm == 'none'
|
||||
@ -1711,8 +1691,8 @@ class SSH2
|
||||
|
||||
$mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_server_to_client);
|
||||
if ($mac_algorithm === false) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found');
|
||||
user_error('No compatible server to client message authentication algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
$checkKeyLength = 0;
|
||||
@ -1758,15 +1738,15 @@ class SSH2
|
||||
|
||||
$compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_server_to_client);
|
||||
if ($compression_algorithm === false) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found');
|
||||
user_error('No compatible server to client compression algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
$this->decompress = $compression_algorithm == 'zlib';
|
||||
|
||||
$compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_client_to_server);
|
||||
if ($compression_algorithm === false) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found');
|
||||
user_error('No compatible client to server compression algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
$this->compress = $compression_algorithm == 'zlib';
|
||||
|
||||
@ -1824,26 +1804,26 @@ class SSH2
|
||||
{
|
||||
switch ($algorithm) {
|
||||
case '3des-cbc':
|
||||
return new TripleDES(Base::MODE_CBC);
|
||||
return new TripleDES();
|
||||
case '3des-ctr':
|
||||
return new TripleDES(Base::MODE_CTR);
|
||||
case 'aes256-cbc':
|
||||
case 'aes192-cbc':
|
||||
case 'aes128-cbc':
|
||||
return new Rijndael(Base::MODE_CBC);
|
||||
return new Rijndael();
|
||||
case 'aes256-ctr':
|
||||
case 'aes192-ctr':
|
||||
case 'aes128-ctr':
|
||||
return new Rijndael(Base::MODE_CTR);
|
||||
case 'blowfish-cbc':
|
||||
return new Blowfish(Base::MODE_CBC);
|
||||
return new Blowfish();
|
||||
case 'blowfish-ctr':
|
||||
return new Blowfish(Base::MODE_CTR);
|
||||
case 'twofish128-cbc':
|
||||
case 'twofish192-cbc':
|
||||
case 'twofish256-cbc':
|
||||
case 'twofish-cbc':
|
||||
return new Twofish(Base::MODE_CBC);
|
||||
return new Twofish();
|
||||
case 'twofish128-ctr':
|
||||
case 'twofish192-ctr':
|
||||
case 'twofish256-ctr':
|
||||
@ -1911,8 +1891,6 @@ class SSH2
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @access private
|
||||
* @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
|
||||
* by sending dummy SSH_MSG_IGNORE messages.
|
||||
@ -1937,13 +1915,15 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
|
||||
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
|
||||
throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT');
|
||||
user_error('Expected SSH_MSG_SERVICE_ACCEPT');
|
||||
return false;
|
||||
}
|
||||
$this->bitmap |= self::MASK_LOGIN_REQ;
|
||||
}
|
||||
@ -1984,7 +1964,8 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
@ -2038,7 +2019,8 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
@ -2114,7 +2096,6 @@ class SSH2
|
||||
*
|
||||
* @param string $responses...
|
||||
* @return bool
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access private
|
||||
*/
|
||||
function _keyboard_interactive_process()
|
||||
@ -2126,7 +2107,8 @@ class SSH2
|
||||
} else {
|
||||
$orig = $response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2250,7 +2232,6 @@ class SSH2
|
||||
* @param string $username
|
||||
* @param \phpseclib\Crypt\RSA $password
|
||||
* @return bool
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access private
|
||||
* @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
|
||||
* by sending dummy SSH_MSG_IGNORE messages.
|
||||
@ -2258,7 +2239,7 @@ class SSH2
|
||||
function _privatekey_login($username, $privatekey)
|
||||
{
|
||||
// see http://tools.ietf.org/html/rfc4253#page-15
|
||||
$publickey = $privatekey->getPublicKey('Raw');
|
||||
$publickey = $privatekey->getPublicKey(RSA::PUBLIC_FORMAT_RAW);
|
||||
if ($publickey === false) {
|
||||
return false;
|
||||
}
|
||||
@ -2296,7 +2277,8 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
@ -2319,8 +2301,8 @@ class SSH2
|
||||
}
|
||||
|
||||
$packet = $part1 . chr(1) . $part2;
|
||||
$privatekey->setHash('sha1');
|
||||
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet), RSA::PADDING_PKCS1);
|
||||
$privatekey->setSignatureMode(RSA::SIGNATURE_PKCS1);
|
||||
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
|
||||
$signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature);
|
||||
$packet.= pack('Na*', strlen($signature), $signature);
|
||||
|
||||
@ -2330,7 +2312,8 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
@ -2380,7 +2363,6 @@ class SSH2
|
||||
* @param string $command
|
||||
* @param Callback $callback
|
||||
* @return string
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function exec($command, $callback = null)
|
||||
@ -2448,7 +2430,8 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
list(, $type) = unpack('C', $this->_string_shift($response, 1));
|
||||
@ -2458,8 +2441,8 @@ class SSH2
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||
default:
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
throw new \RuntimeException('Unable to request pseudo-terminal');
|
||||
user_error('Unable to request pseudo-terminal');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
$this->in_request_pty_exec = true;
|
||||
}
|
||||
@ -2527,8 +2510,6 @@ class SSH2
|
||||
* @see self::read()
|
||||
* @see self::write()
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @access private
|
||||
*/
|
||||
function _initShell()
|
||||
@ -2585,7 +2566,8 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
list(, $type) = unpack('C', $this->_string_shift($response, 1));
|
||||
@ -2596,8 +2578,8 @@ class SSH2
|
||||
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||
break;
|
||||
default:
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
throw new \UnexpectedValueException('Unable to request pseudo-terminal');
|
||||
user_error('Unable to request pseudo-terminal');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
|
||||
$packet = pack(
|
||||
@ -2674,7 +2656,6 @@ class SSH2
|
||||
* @param string $expect
|
||||
* @param int $mode
|
||||
* @return string
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function read($expect = '', $mode = self::READ_SIMPLE)
|
||||
@ -2683,11 +2664,13 @@ class SSH2
|
||||
$this->is_timeout = false;
|
||||
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
$channel = $this->_get_interactive_channel();
|
||||
@ -2718,17 +2701,18 @@ class SSH2
|
||||
* @see self::read()
|
||||
* @param string $cmd
|
||||
* @return bool
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function write($cmd)
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd);
|
||||
@ -2852,7 +2836,6 @@ class SSH2
|
||||
if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) {
|
||||
fclose($this->realtime_log_file);
|
||||
}
|
||||
unset(self::$connections[$this->getResourceId()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2897,18 +2880,18 @@ class SSH2
|
||||
*
|
||||
* @see self::_send_binary_packet()
|
||||
* @return string
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @access private
|
||||
*/
|
||||
function _get_binary_packet()
|
||||
{
|
||||
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
||||
user_error('Connection closed prematurely');
|
||||
$this->bitmap = 0;
|
||||
throw new \RuntimeException('Connection closed prematurely');
|
||||
return false;
|
||||
}
|
||||
|
||||
$start = microtime(true);
|
||||
$raw = stream_get_contents($this->fsock, $this->decrypt_block_size);
|
||||
$raw = fread($this->fsock, $this->decrypt_block_size);
|
||||
|
||||
if (!strlen($raw)) {
|
||||
return '';
|
||||
@ -2918,7 +2901,8 @@ class SSH2
|
||||
$raw = $this->decrypt->decrypt($raw);
|
||||
}
|
||||
if ($raw === false) {
|
||||
throw new \RuntimeException('Unable to decrypt content');
|
||||
user_error('Unable to decrypt content');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));
|
||||
@ -2929,15 +2913,17 @@ class SSH2
|
||||
// "implementations SHOULD check that the packet length is reasonable"
|
||||
// PuTTY uses 0x9000 as the actual max packet size and so to shall we
|
||||
if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
|
||||
throw new \RuntimeException('Invalid size');
|
||||
user_error('Invalid size');
|
||||
return false;
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
while ($remaining_length > 0) {
|
||||
$temp = stream_get_contents($this->fsock, $remaining_length);
|
||||
$temp = fread($this->fsock, $remaining_length);
|
||||
if ($temp === false || feof($this->fsock)) {
|
||||
user_error('Error reading from socket');
|
||||
$this->bitmap = 0;
|
||||
throw new \RuntimeException('Error reading from socket');
|
||||
return false;
|
||||
}
|
||||
$buffer.= $temp;
|
||||
$remaining_length-= strlen($temp);
|
||||
@ -2951,12 +2937,14 @@ class SSH2
|
||||
$padding = $this->_string_shift($raw, $padding_length); // should leave $raw empty
|
||||
|
||||
if ($this->hmac_check !== false) {
|
||||
$hmac = stream_get_contents($this->fsock, $this->hmac_size);
|
||||
$hmac = fread($this->fsock, $this->hmac_size);
|
||||
if ($hmac === false || strlen($hmac) != $this->hmac_size) {
|
||||
user_error('Error reading socket');
|
||||
$this->bitmap = 0;
|
||||
throw new \RuntimeException('Error reading socket');
|
||||
return false;
|
||||
} elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
|
||||
throw new \RuntimeException('Invalid HMAC');
|
||||
user_error('Invalid HMAC');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3182,7 +3170,6 @@ class SSH2
|
||||
*
|
||||
* @param $client_channel
|
||||
* @return mixed
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access private
|
||||
*/
|
||||
function _get_channel_packet($client_channel, $skip_extended = false)
|
||||
@ -3215,7 +3202,8 @@ class SSH2
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
throw new \RuntimeException('Connection closed by server');
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
if ($client_channel == -1 && $response === true) {
|
||||
return true;
|
||||
@ -3264,8 +3252,8 @@ class SSH2
|
||||
return $result;
|
||||
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
|
||||
default:
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
throw new \RuntimeException('Unable to open channel');
|
||||
user_error('Unable to open channel');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
||||
@ -3275,8 +3263,8 @@ class SSH2
|
||||
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||
return false;
|
||||
default:
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
throw new \RuntimeException('Unable to fulfill channel request');
|
||||
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);
|
||||
@ -3381,14 +3369,12 @@ class SSH2
|
||||
}
|
||||
|
||||
$this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
|
||||
if ($client_channel == $channel) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
case NET_SSH2_MSG_CHANNEL_EOF:
|
||||
break;
|
||||
default:
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
throw new \RuntimeException('Error reading channel data');
|
||||
user_error('Error reading channel data');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3407,8 +3393,9 @@ class SSH2
|
||||
function _send_binary_packet($data, $logged = null)
|
||||
{
|
||||
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
||||
user_error('Connection closed prematurely');
|
||||
$this->bitmap = 0;
|
||||
throw new \RuntimeException('Connection closed prematurely');
|
||||
return false;
|
||||
}
|
||||
|
||||
//if ($this->compress) {
|
||||
@ -3499,14 +3486,14 @@ class SSH2
|
||||
@flush();
|
||||
@ob_flush();
|
||||
break;
|
||||
// basically the same thing as self::LOG_REALTIME with the caveat that NET_SFTP_LOG_REALTIME_FILENAME
|
||||
// basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE
|
||||
// needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE.
|
||||
// the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
|
||||
// at the beginning of the file
|
||||
case self::LOG_REALTIME_FILE:
|
||||
if (!isset($this->realtime_log_file)) {
|
||||
// PHP doesn't seem to like using constants in fopen()
|
||||
$filename = NET_SSH2_LOG_REALTIME_FILENAME;
|
||||
$filename = self::LOG_REALTIME_FILENAME;
|
||||
$fp = fopen($filename, 'w');
|
||||
$this->realtime_log_file = $fp;
|
||||
}
|
||||
@ -3971,8 +3958,6 @@ class SSH2
|
||||
* is recommended. Returns false if the server signature is not signed correctly with the public host key.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \RuntimeException on badly formatted keys
|
||||
* @throws \phpseclib\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format
|
||||
* @access public
|
||||
*/
|
||||
function getServerPublicHostKey()
|
||||
@ -3991,7 +3976,7 @@ class SSH2
|
||||
|
||||
if ($this->signature_validated) {
|
||||
return $this->bitmap ?
|
||||
$this->signature_format . ' ' . Base64::encode($this->server_public_host_key) :
|
||||
$this->signature_format . ' ' . base64_encode($this->server_public_host_key) :
|
||||
false;
|
||||
}
|
||||
|
||||
@ -4018,8 +4003,8 @@ class SSH2
|
||||
padding, unsigned, and in network byte order). */
|
||||
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
||||
if ($temp['length'] != 40) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new \RuntimeException('Invalid signature');
|
||||
user_error('Invalid signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
$r = new BigInteger($this->_string_shift($signature, 20), 256);
|
||||
@ -4030,8 +4015,8 @@ class SSH2
|
||||
case $r->compare($q) >= 0:
|
||||
case $s->equals($zero):
|
||||
case $s->compare($q) >= 0:
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new \RuntimeException('Invalid signature');
|
||||
user_error('Invalid signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
$w = $s->modInverse($q);
|
||||
@ -4050,7 +4035,7 @@ class SSH2
|
||||
list(, $v) = $v->divide($q);
|
||||
|
||||
if (!$v->equals($r)) {
|
||||
//user_error('Bad server signature');
|
||||
user_error('Bad server signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
|
||||
@ -4069,10 +4054,10 @@ class SSH2
|
||||
$signature = $this->_string_shift($signature, $temp['length']);
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load(array('e' => $e, 'n' => $n), 'raw');
|
||||
$rsa->setHash('sha1');
|
||||
if (!$rsa->verify($this->exchange_hash, $signature, RSA::PADDING_PKCS1)) {
|
||||
//user_error('Bad server signature');
|
||||
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
|
||||
$rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW);
|
||||
if (!$rsa->verify($this->exchange_hash, $signature)) {
|
||||
user_error('Bad server signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
*/
|
||||
@ -4087,8 +4072,8 @@ class SSH2
|
||||
// also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
|
||||
|
||||
if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
throw new \RuntimeException('Invalid signature');
|
||||
user_error('Invalid signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
$s = $s->modPow($e, $n);
|
||||
@ -4098,16 +4083,16 @@ class SSH2
|
||||
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
||||
|
||||
if ($s != $h) {
|
||||
//user_error('Bad server signature');
|
||||
user_error('Bad server signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
throw new NoSupportedAlgorithmsException('Unsupported signature format');
|
||||
user_error('Unsupported signature format');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
|
||||
return $this->signature_format . ' ' . Base64::encode($this->server_public_host_key);
|
||||
return $this->signature_format . ' ' . base64_encode($this->server_public_host_key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4180,47 +4165,4 @@ class SSH2
|
||||
$this->windowColumns = $columns;
|
||||
$this->windowRows = $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function __toString()
|
||||
{
|
||||
return $this->getResourceId();
|
||||
}
|
||||
|
||||
/**
|
||||
* We use {} because that symbols should not be in URL according to
|
||||
* {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}.
|
||||
* It will safe us from any conflicts, because otherwise regexp will
|
||||
* match all alphanumeric domains.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getResourceId()
|
||||
{
|
||||
return '{' . spl_object_hash($this) . '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return existing connection
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool|SSH2 will return false if no such connection
|
||||
*/
|
||||
static function getConnectionByResourceId($id)
|
||||
{
|
||||
return isset(self::$connections[$id]) ? self::$connections[$id] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all excising connections
|
||||
*
|
||||
* @return SSH2[]
|
||||
*/
|
||||
static function getConnections()
|
||||
{
|
||||
return self::$connections;
|
||||
}
|
||||
}
|
||||
|
@ -33,9 +33,7 @@
|
||||
|
||||
namespace phpseclib\System\SSH;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Exception\BadConfigurationException;
|
||||
use phpseclib\System\SSH\Agent\Identity;
|
||||
|
||||
/**
|
||||
@ -117,8 +115,6 @@ class Agent
|
||||
* Default Constructor
|
||||
*
|
||||
* @return \phpseclib\System\SSH\Agent
|
||||
* @throws \phpseclib\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
@ -131,12 +127,13 @@ class Agent
|
||||
$address = $_ENV['SSH_AUTH_SOCK'];
|
||||
break;
|
||||
default:
|
||||
throw new BadConfigurationException('SSH_AUTH_SOCK not found');
|
||||
user_error('SSH_AUTH_SOCK not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
||||
if (!$this->fsock) {
|
||||
throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)");
|
||||
user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +144,6 @@ class Agent
|
||||
* Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects
|
||||
*
|
||||
* @return array
|
||||
* @throws \RuntimeException on receipt of unexpected packets
|
||||
* @access public
|
||||
*/
|
||||
function requestIdentities()
|
||||
@ -158,13 +154,13 @@ class Agent
|
||||
|
||||
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
|
||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
||||
throw new \RuntimeException('Connection closed while requesting identities');
|
||||
user_error('Connection closed while requesting identities');
|
||||
}
|
||||
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
$type = ord(fread($this->fsock, 1));
|
||||
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
|
||||
throw new \RuntimeException('Unable to request identities');
|
||||
user_error('Unable to request identities');
|
||||
}
|
||||
|
||||
$identities = array();
|
||||
@ -172,7 +168,7 @@ class Agent
|
||||
for ($i = 0; $i < $keyCount; $i++) {
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
$key_blob = fread($this->fsock, $length);
|
||||
$key_str = 'ssh-rsa ' . Base64::encode($key_blob);
|
||||
$key_str = 'ssh-rsa ' . base64_encode($key_blob);
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
if ($length) {
|
||||
$key_str.= ' ' . fread($this->fsock, $length);
|
||||
@ -182,7 +178,7 @@ class Agent
|
||||
switch ($key_type) {
|
||||
case 'ssh-rsa':
|
||||
$key = new RSA();
|
||||
$key->load($key_str);
|
||||
$key->loadKey($key_str);
|
||||
break;
|
||||
case 'ssh-dss':
|
||||
// not currently supported
|
||||
@ -278,7 +274,6 @@ class Agent
|
||||
*
|
||||
* @param string $data
|
||||
* @return data from SSH Agent
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @access private
|
||||
*/
|
||||
function _forward_data($data)
|
||||
@ -297,7 +292,7 @@ class Agent
|
||||
}
|
||||
|
||||
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
|
||||
throw new \RuntimeException('Connection closed attempting to forward data to SSH agent');
|
||||
user_error('Connection closed attempting to forward data to SSH agent');
|
||||
}
|
||||
|
||||
$this->socket_buffer = '';
|
||||
|
@ -15,8 +15,6 @@
|
||||
|
||||
namespace phpseclib\System\SSH\Agent;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
use phpseclib\System\SSH\Agent;
|
||||
|
||||
/**
|
||||
@ -25,8 +23,9 @@ use phpseclib\System\SSH\Agent;
|
||||
* Instantiation should only be performed by \phpseclib\System\SSH\Agent class.
|
||||
* This could be thought of as implementing an interface that phpseclib\Crypt\RSA
|
||||
* implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
|
||||
* The methods in this interface would be getPublicKey and sign since those are the
|
||||
* methods phpseclib looks for to perform public key authentication.
|
||||
* The methods in this interface would be getPublicKey, setSignatureMode
|
||||
* and sign since those are the methods phpseclib looks for to perform
|
||||
* public key authentication.
|
||||
*
|
||||
* @package SSH\Agent
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
@ -106,29 +105,26 @@ class Identity
|
||||
*
|
||||
* Wrapper for $this->key->getPublicKey()
|
||||
*
|
||||
* @param int $type optional
|
||||
* @param int $format optional
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function getPublicKey($type = 'PKCS8')
|
||||
function getPublicKey($format = null)
|
||||
{
|
||||
return $this->key->getPublicKey($type);
|
||||
return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hash
|
||||
* Set Signature Mode
|
||||
*
|
||||
* ssh-agent only supports signatures with sha1 hashes but to maintain BC with RSA.php this function exists
|
||||
* Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
|
||||
* ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1
|
||||
*
|
||||
* @param string $hash optional
|
||||
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||
* @param int $mode
|
||||
* @access public
|
||||
*/
|
||||
function setHash($hash = 'sha1')
|
||||
function setSignatureMode($mode)
|
||||
{
|
||||
if ($hash != 'sha1') {
|
||||
throw new UnsupportedAlgorithmException('ssh-agent can only be used with the sha1 hash');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,29 +133,22 @@ class Identity
|
||||
* See "2.6.2 Protocol 2 private key signature request"
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $padding optional
|
||||
* @return string
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||
* @access public
|
||||
*/
|
||||
function sign($message, $padding = RSA::PADDING_PKCS1)
|
||||
function sign($message)
|
||||
{
|
||||
if ($padding != RSA::PADDING_PKCS1 && $padding != RSA::PADDING_RELAXED_PKCS1) {
|
||||
throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures');
|
||||
}
|
||||
|
||||
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
|
||||
$packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0);
|
||||
$packet = pack('Na*', strlen($packet), $packet);
|
||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
||||
throw new \RuntimeException('Connection closed during signing');
|
||||
user_error('Connection closed during signing');
|
||||
}
|
||||
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
$type = ord(fread($this->fsock, 1));
|
||||
if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
|
||||
throw new \RuntimeException('Unable to retreive signature');
|
||||
user_error('Unable to retreive signature');
|
||||
}
|
||||
|
||||
$signature_blob = fread($this->fsock, $length - 1);
|
||||
|
@ -1,18 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Bootstrapping File for phpseclib
|
||||
*
|
||||
* composer isn't a requirement for phpseclib 2.0 but this file isn't really required
|
||||
* either. it's a bonus for those using composer but if you're not phpseclib will
|
||||
* still work
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
if (extension_loaded('mbstring')) {
|
||||
// 2 - MB_OVERLOAD_STRING
|
||||
if (ini_get('mbstring.func_overload') & 2) {
|
||||
throw new UnexpectedValueException(
|
||||
throw new \UnexpectedValueException(
|
||||
'Overloading of string functions using mbstring.func_overload ' .
|
||||
'is not supported by phpseclib.'
|
||||
);
|
||||
|
21
vendor/phpseclib/phpseclib/phpunit.xml.dist
vendored
21
vendor/phpseclib/phpseclib/phpunit.xml.dist
vendored
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="tests/bootstrap.php"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="phpseclib Unit Test Suite">
|
||||
<directory>./tests/Unit/</directory>
|
||||
</testsuite>
|
||||
<testsuite name="phpseclib Functional Test Suite">
|
||||
<directory>./tests/Functional/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<!-- Code Coverage -->
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./phpseclib/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
@ -1,100 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Net\SCP;
|
||||
use phpseclib\Net\SSH2;
|
||||
|
||||
class Functional_Net_SCPSSH2UserStoryTest extends PhpseclibFunctionalTestCase
|
||||
{
|
||||
static protected $remoteFile;
|
||||
static protected $exampleData;
|
||||
static protected $exampleDataLength;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
self::$remoteFile = uniqid('phpseclib-scp-ssh2-') . '.txt';
|
||||
self::$exampleData = str_repeat('abscp12345', 1000);
|
||||
self::$exampleDataLength = 10000;
|
||||
}
|
||||
|
||||
public function testConstructSSH2()
|
||||
{
|
||||
$ssh = new SSH2($this->getEnv('SSH_HOSTNAME'));
|
||||
$this->assertTrue(
|
||||
$ssh->login(
|
||||
$this->getEnv('SSH_USERNAME'),
|
||||
$this->getEnv('SSH_PASSWORD')
|
||||
)
|
||||
);
|
||||
return $ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testConstructSSH2
|
||||
* @param \phpseclib\Net\SSH2 $ssh
|
||||
*/
|
||||
public function testConstructor($ssh)
|
||||
{
|
||||
$scp = new SCP($ssh);
|
||||
$this->assertTrue(
|
||||
is_object($scp),
|
||||
'Could not construct \phpseclib\Net\SCP object.'
|
||||
);
|
||||
return $scp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testConstructor
|
||||
* @param \phpseclib\Net\SCP $scp
|
||||
*/
|
||||
public function testPutGetString($scp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$scp->put(self::$remoteFile, self::$exampleData),
|
||||
'Failed asserting that data could successfully be put() into file.'
|
||||
);
|
||||
$content = $scp->get(self::$remoteFile);
|
||||
// TODO: Address https://github.com/phpseclib/phpseclib/issues/146
|
||||
$this->assertContains(
|
||||
strlen($content),
|
||||
array(self::$exampleDataLength, self::$exampleDataLength + 1),
|
||||
'Failed asserting that string length matches expected length.'
|
||||
);
|
||||
$this->assertContains(
|
||||
$content,
|
||||
array(self::$exampleData, self::$exampleData . "\0"),
|
||||
'Failed asserting that string content matches expected content.'
|
||||
);
|
||||
return $scp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPutGetString
|
||||
* @param \phpseclib\Net\SCP $scp
|
||||
*/
|
||||
public function testGetFile($scp)
|
||||
{
|
||||
$localFilename = $this->createTempFile();
|
||||
$this->assertTrue(
|
||||
$scp->get(self::$remoteFile, $localFilename),
|
||||
'Failed asserting that get() into file was successful.'
|
||||
);
|
||||
// TODO: Address https://github.com/phpseclib/phpseclib/issues/146
|
||||
$this->assertContains(
|
||||
filesize($localFilename),
|
||||
array(self::$exampleDataLength, self::$exampleDataLength + 1),
|
||||
'Failed asserting that filesize matches expected data size.'
|
||||
);
|
||||
$this->assertContains(
|
||||
file_get_contents($localFilename),
|
||||
array(self::$exampleData, self::$exampleData . "\0"),
|
||||
'Failed asserting that file content matches expected content.'
|
||||
);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
use phpseclib\Net\SFTP;
|
||||
|
||||
class Functional_Net_SFTPLargeFileTest extends Functional_Net_SFTPTestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!extension_loaded('mcrypt') && !extension_loaded('openssl')) {
|
||||
self::markTestSkipped('This test depends on mcrypt or openssl for performance.');
|
||||
}
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github298
|
||||
* @group github455
|
||||
* @group github457
|
||||
*/
|
||||
public function testPutSizeLocalFile()
|
||||
{
|
||||
$tmp_filename = $this->createTempFile(128, 1024 * 1024);
|
||||
$filename = 'file-large-from-local.txt';
|
||||
|
||||
$this->assertTrue(
|
||||
$this->sftp->put($filename, $tmp_filename, SFTP::SOURCE_LOCAL_FILE),
|
||||
'Failed asserting that local file could be successfully put().'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
128 * 1024 * 1024,
|
||||
$this->sftp->size($filename),
|
||||
'Failed asserting that uploaded local file has the expected length.'
|
||||
);
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2015 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Net\SFTP\Stream;
|
||||
|
||||
class Functional_Net_SFTPStreamTest extends Functional_Net_SFTPTestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
Stream::register();
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
public function testFopenFcloseCreatesFile()
|
||||
{
|
||||
$context = stream_context_create(array(
|
||||
'sftp' => array('session' => $this->sftp),
|
||||
));
|
||||
$fp = fopen($this->buildUrl('fooo.txt'), 'wb', false, $context);
|
||||
$this->assertTrue(is_resource($fp));
|
||||
fclose($fp);
|
||||
$this->assertSame(0, $this->sftp->size('fooo.txt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github778
|
||||
*/
|
||||
public function testFilenameWithHash()
|
||||
{
|
||||
$context = stream_context_create(array(
|
||||
'sftp' => array('session' => $this->sftp),
|
||||
));
|
||||
$fp = fopen($this->buildUrl('te#st.txt'), 'wb', false, $context);
|
||||
fputs($fp, 'zzzz');
|
||||
fclose($fp);
|
||||
|
||||
$this->assertTrue(in_array('te#st.txt', $this->sftp->nlist()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests connection reuse functionality same as ssh2 extension:
|
||||
* {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
|
||||
*/
|
||||
public function testConnectionReuse()
|
||||
{
|
||||
$originalConnectionsCount = count(\phpseclib\Net\SSH2::getConnections());
|
||||
$session = $this->sftp;
|
||||
$dirs = scandir("sftp://$session/");
|
||||
$this->assertCount($originalConnectionsCount, \phpseclib\Net\SSH2::getConnections());
|
||||
$this->assertEquals(array('.', '..'), array_slice($dirs, 0, 2));
|
||||
}
|
||||
|
||||
protected function buildUrl($suffix)
|
||||
{
|
||||
return sprintf(
|
||||
'sftp://via-context/%s/%s',
|
||||
$this->sftp->pwd(),
|
||||
$suffix
|
||||
);
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2015 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Net\SFTP;
|
||||
|
||||
/**
|
||||
* This class provides each test method with a new and empty $this->scratchDir.
|
||||
*/
|
||||
abstract class Functional_Net_SFTPTestCase extends PhpseclibFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* @var SFTP
|
||||
*/
|
||||
protected $sftp;
|
||||
protected $scratchDir;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->scratchDir = uniqid('phpseclib-sftp-scratch-');
|
||||
|
||||
$this->sftp = new SFTP($this->getEnv('SSH_HOSTNAME'));
|
||||
$this->assertTrue($this->sftp->login(
|
||||
$this->getEnv('SSH_USERNAME'),
|
||||
$this->getEnv('SSH_PASSWORD')
|
||||
));
|
||||
$this->assertTrue($this->sftp->mkdir($this->scratchDir));
|
||||
$this->assertTrue($this->sftp->chdir($this->scratchDir));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
if ($this->sftp) {
|
||||
$this->sftp->chdir($this->getEnv('SSH_HOME'));
|
||||
$this->sftp->delete($this->scratchDir);
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
@ -1,728 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Net\SFTP;
|
||||
|
||||
class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
|
||||
{
|
||||
static protected $scratchDir;
|
||||
static protected $exampleData;
|
||||
static protected $exampleDataLength;
|
||||
static protected $buffer;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::$scratchDir = uniqid('phpseclib-sftp-scratch-');
|
||||
|
||||
self::$exampleData = str_repeat('abcde12345', 1000);
|
||||
self::$exampleDataLength = 10000;
|
||||
}
|
||||
|
||||
public function testConstructor()
|
||||
{
|
||||
$sftp = new SFTP($this->getEnv('SSH_HOSTNAME'));
|
||||
|
||||
$this->assertTrue(
|
||||
is_object($sftp),
|
||||
'Could not construct NET_SFTP object.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testConstructor
|
||||
*/
|
||||
public function testPasswordLogin($sftp)
|
||||
{
|
||||
$username = $this->getEnv('SSH_USERNAME');
|
||||
$password = $this->getEnv('SSH_PASSWORD');
|
||||
$this->assertTrue(
|
||||
$sftp->login($username, $password),
|
||||
'SSH2/SFTP login using password failed.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPasswordLogin
|
||||
*/
|
||||
public function testPwdHome($sftp)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$this->getEnv('SSH_HOME'),
|
||||
$sftp->pwd(),
|
||||
'Failed asserting that pwd() returns home directory after login.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPwdHome
|
||||
*/
|
||||
public function testMkDirScratch($sftp)
|
||||
{
|
||||
$dirname = self::$scratchDir;
|
||||
|
||||
$this->assertTrue(
|
||||
$sftp->mkdir($dirname),
|
||||
"Failed asserting that a new scratch directory $dirname could " .
|
||||
'be created.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$sftp->mkdir($dirname),
|
||||
"Failed asserting that a new scratch directory $dirname could " .
|
||||
'not be created (because it already exists).'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testMkDirScratch
|
||||
*/
|
||||
public function testChDirScratch($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->chdir(self::$scratchDir),
|
||||
sprintf(
|
||||
'Failed asserting that working directory could be changed ' .
|
||||
'to scratch directory %s.',
|
||||
self::$scratchDir
|
||||
)
|
||||
);
|
||||
|
||||
$pwd = $sftp->pwd();
|
||||
|
||||
$this->assertStringStartsWith(
|
||||
$this->getEnv('SSH_HOME'),
|
||||
$pwd,
|
||||
'Failed asserting that the home directory is a prefix of the ' .
|
||||
'current working directory.'
|
||||
);
|
||||
|
||||
$this->assertStringEndsWith(
|
||||
self::$scratchDir,
|
||||
$pwd,
|
||||
'Failed asserting that the scratch directory name is a suffix ' .
|
||||
'of the current working directory.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testChDirScratch
|
||||
*/
|
||||
public function testStatOnDir($sftp)
|
||||
{
|
||||
$this->assertNotSame(
|
||||
array(),
|
||||
$sftp->stat('.'),
|
||||
'Failed asserting that the cwd has a non-empty stat.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStatOnDir
|
||||
*/
|
||||
public function testPutSizeGetFile($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->put('file1.txt', self::$exampleData),
|
||||
'Failed asserting that example data could be successfully put().'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
self::$exampleDataLength,
|
||||
$sftp->size('file1.txt'),
|
||||
'Failed asserting that put example data has the expected length'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
self::$exampleData,
|
||||
$sftp->get('file1.txt'),
|
||||
'Failed asserting that get() returns expected example data.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
static function callback($length)
|
||||
{
|
||||
$r = substr(self::$buffer, 0, $length);
|
||||
self::$buffer = substr(self::$buffer, $length);
|
||||
if (strlen($r)) {
|
||||
return $r;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStatOnDir
|
||||
*/
|
||||
public function testPutSizeGetFileCallback($sftp)
|
||||
{
|
||||
self::$buffer = self::$exampleData;
|
||||
$this->assertTrue(
|
||||
$sftp->put('file1.txt', array(__CLASS__, 'callback'), $sftp::SOURCE_CALLBACK),
|
||||
'Failed asserting that example data could be successfully put().'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
self::$exampleDataLength,
|
||||
$sftp->size('file1.txt'),
|
||||
'Failed asserting that put example data has the expected length'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
self::$exampleData,
|
||||
$sftp->get('file1.txt'),
|
||||
'Failed asserting that get() returns expected example data.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPutSizeGetFile
|
||||
*/
|
||||
public function testTouch($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->touch('file2.txt'),
|
||||
'Failed asserting that touch() successfully ran.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$sftp->file_exists('file2.txt'),
|
||||
'Failed asserting that touch()\'d file exists'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testTouch
|
||||
*/
|
||||
public function testTruncate($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->touch('file3.txt'),
|
||||
'Failed asserting that touch() successfully ran.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$sftp->truncate('file3.txt', 1024 * 1024),
|
||||
'Failed asserting that touch() successfully ran.'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
1024 * 1024,
|
||||
$sftp->size('file3.txt'),
|
||||
'Failed asserting that truncate()\'d file has the expected length'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testTruncate
|
||||
* @group github850
|
||||
*/
|
||||
public function testChModOnFile($sftp)
|
||||
{
|
||||
$this->assertNotFalse(
|
||||
$sftp->chmod(0755, 'file1.txt'),
|
||||
'Failed asserting that chmod() was successful.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testChModOnFile
|
||||
*/
|
||||
public function testChDirOnFile($sftp)
|
||||
{
|
||||
$this->assertFalse(
|
||||
$sftp->chdir('file1.txt'),
|
||||
'Failed to assert that the cwd cannot be changed to a file'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testChDirOnFile
|
||||
*/
|
||||
public function testFileExistsIsFileIsDirFile($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->file_exists('file1.txt'),
|
||||
'Failed asserting that file_exists() on example file returns true.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$sftp->is_file('file1.txt'),
|
||||
'Failed asserting that is_file() on example file returns true.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$sftp->is_dir('file1.txt'),
|
||||
'Failed asserting that is_dir() on example file returns false.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFileExistsIsFileIsDirFile
|
||||
*/
|
||||
public function testFileExistsIsFileIsDirFileNonexistent($sftp)
|
||||
{
|
||||
$this->assertFalse(
|
||||
$sftp->file_exists('file4.txt'),
|
||||
'Failed asserting that a nonexistent file does not exist.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$sftp->is_file('file4.txt'),
|
||||
'Failed asserting that is_file() on nonexistent file returns false.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$sftp->is_dir('file4.txt'),
|
||||
'Failed asserting that is_dir() on nonexistent file returns false.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFileExistsIsFileIsDirFileNonexistent
|
||||
*/
|
||||
public function testSortOrder($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->mkdir('temp'),
|
||||
"Failed asserting that a new scratch directory temp could " .
|
||||
'be created.'
|
||||
);
|
||||
|
||||
$sftp->setListOrder('filename', SORT_DESC);
|
||||
|
||||
$list = $sftp->nlist();
|
||||
$expected = array('.', '..', 'temp', 'file3.txt', 'file2.txt', 'file1.txt');
|
||||
|
||||
$this->assertSame(
|
||||
$list,
|
||||
$expected,
|
||||
'Failed asserting that list sorted correctly.'
|
||||
);
|
||||
|
||||
$sftp->setListOrder('filename', SORT_ASC);
|
||||
|
||||
$list = $sftp->nlist();
|
||||
$expected = array('.', '..', 'temp', 'file1.txt', 'file2.txt', 'file3.txt');
|
||||
|
||||
$this->assertSame(
|
||||
$list,
|
||||
$expected,
|
||||
'Failed asserting that list sorted correctly.'
|
||||
);
|
||||
|
||||
$sftp->setListOrder('size', SORT_DESC);
|
||||
|
||||
$files = $sftp->nlist();
|
||||
|
||||
$last_size = 0x7FFFFFFF;
|
||||
foreach ($files as $file) {
|
||||
if ($sftp->is_file($file)) {
|
||||
$cur_size = $sftp->size($file);
|
||||
$this->assertLessThanOrEqual(
|
||||
$last_size,
|
||||
$cur_size,
|
||||
'Failed asserting that nlist() is in descending order'
|
||||
);
|
||||
$last_size = $cur_size;
|
||||
}
|
||||
}
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSortOrder
|
||||
*/
|
||||
public function testResourceXfer($sftp)
|
||||
{
|
||||
$fp = fopen('res.txt', 'w+');
|
||||
$sftp->get('file1.txt', $fp);
|
||||
rewind($fp);
|
||||
$sftp->put('file4.txt', $fp);
|
||||
fclose($fp);
|
||||
|
||||
$this->assertSame(
|
||||
self::$exampleData,
|
||||
$sftp->get('file4.txt'),
|
||||
'Failed asserting that a file downloaded into a resource and reuploaded from a resource has the correct data'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testResourceXfer
|
||||
*/
|
||||
public function testSymlink($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->symlink('file3.txt', 'symlink'),
|
||||
'Failed asserting that a symlink could be created'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSymlink
|
||||
*/
|
||||
public function testStatLstatCache($sftp)
|
||||
{
|
||||
$stat = $sftp->stat('symlink');
|
||||
$lstat = $sftp->lstat('symlink');
|
||||
$this->assertNotEquals(
|
||||
$stat,
|
||||
$lstat,
|
||||
'Failed asserting that stat and lstat returned different output for a symlink'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStatLstatCache
|
||||
*/
|
||||
public function testLinkFile($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->is_link('symlink'),
|
||||
'Failed asserting that symlink is a link'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$sftp->is_file('symlink'),
|
||||
'Failed asserting that symlink is a file'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$sftp->is_dir('symlink'),
|
||||
'Failed asserting that symlink is not a directory'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testLinkFile
|
||||
*/
|
||||
public function testReadlink($sftp)
|
||||
{
|
||||
$this->assertInternalType(
|
||||
'string',
|
||||
$sftp->readlink('symlink'),
|
||||
'Failed asserting that a symlink\'s target could be read'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testReadlink
|
||||
* @group github716
|
||||
*/
|
||||
public function testStatOnCWD($sftp)
|
||||
{
|
||||
$stat = $sftp->stat('.');
|
||||
$this->assertInternalType(
|
||||
'array',
|
||||
$stat,
|
||||
'Failed asserting that stat on . returns an array'
|
||||
);
|
||||
$lstat = $sftp->lstat('.');
|
||||
$this->assertInternalType(
|
||||
'array',
|
||||
$lstat,
|
||||
'Failed asserting that lstat on . returns an array'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* on older versions this would result in a fatal error
|
||||
* @depends testStatOnCWD
|
||||
* @group github402
|
||||
*/
|
||||
public function testStatcacheFix($sftp)
|
||||
{
|
||||
// Name used for both directory and file.
|
||||
$name = 'stattestdir';
|
||||
$this->assertTrue($sftp->mkdir($name));
|
||||
$this->assertTrue($sftp->is_dir($name));
|
||||
$this->assertTrue($sftp->chdir($name));
|
||||
$this->assertStringEndsWith(self::$scratchDir . '/' . $name, $sftp->pwd());
|
||||
$this->assertFalse($sftp->file_exists($name));
|
||||
$this->assertTrue($sftp->touch($name));
|
||||
$this->assertTrue($sftp->is_file($name));
|
||||
$this->assertTrue($sftp->chdir('..'));
|
||||
$this->assertStringEndsWith(self::$scratchDir, $sftp->pwd());
|
||||
$this->assertTrue($sftp->is_dir($name));
|
||||
$this->assertTrue($sftp->is_file("$name/$name"));
|
||||
$this->assertTrue($sftp->delete($name, true));
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStatcacheFix
|
||||
*/
|
||||
public function testChDirUpHome($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->chdir('../'),
|
||||
'Failed asserting that directory could be changed one level up.'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$this->getEnv('SSH_HOME'),
|
||||
$sftp->pwd(),
|
||||
'Failed asserting that pwd() returns home directory.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testChDirUpHome
|
||||
*/
|
||||
public function testFileExistsIsFileIsDirDir($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->file_exists(self::$scratchDir),
|
||||
'Failed asserting that file_exists() on scratch dir returns true.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$sftp->is_file(self::$scratchDir),
|
||||
'Failed asserting that is_file() on example file returns false.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$sftp->is_dir(self::$scratchDir),
|
||||
'Failed asserting that is_dir() on example file returns true.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFileExistsIsFileIsDirDir
|
||||
*/
|
||||
public function testTruncateLargeFile($sftp)
|
||||
{
|
||||
$filesize = (4 * 1024 + 16) * 1024 * 1024;
|
||||
$filename = 'file-large-from-truncate-4112MiB.txt';
|
||||
$this->assertTrue($sftp->touch($filename));
|
||||
$this->assertTrue($sftp->truncate($filename, $filesize));
|
||||
$this->assertSame($filesize, $sftp->size($filename));
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testTruncateLargeFile
|
||||
*/
|
||||
public function testRmDirScratch($sftp)
|
||||
{
|
||||
$this->assertFalse(
|
||||
$sftp->rmdir(self::$scratchDir),
|
||||
'Failed asserting that non-empty scratch directory could ' .
|
||||
'not be deleted using rmdir().'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testRmDirScratch
|
||||
*/
|
||||
public function testDeleteRecursiveScratch($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->delete(self::$scratchDir),
|
||||
'Failed asserting that non-empty scratch directory could ' .
|
||||
'be deleted using recursive delete().'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testDeleteRecursiveScratch
|
||||
*/
|
||||
public function testRmDirScratchNonexistent($sftp)
|
||||
{
|
||||
$this->assertFalse(
|
||||
$sftp->rmdir(self::$scratchDir),
|
||||
'Failed asserting that nonexistent scratch directory could ' .
|
||||
'not be deleted using rmdir().'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testRmDirScratchNonexistent
|
||||
* @group github706
|
||||
*/
|
||||
public function testDeleteEmptyDir($sftp)
|
||||
{
|
||||
$this->assertTrue(
|
||||
$sftp->mkdir(self::$scratchDir),
|
||||
'Failed asserting that scratch directory could ' .
|
||||
'be created.'
|
||||
);
|
||||
$this->assertInternalType(
|
||||
'array',
|
||||
$sftp->stat(self::$scratchDir),
|
||||
'Failed asserting that stat on an existant empty directory returns an array'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$sftp->delete(self::$scratchDir),
|
||||
'Failed asserting that empty scratch directory could ' .
|
||||
'be deleted using recursive delete().'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$sftp->stat(self::$scratchDir),
|
||||
'Failed asserting that stat on a deleted directory returns false'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testDeleteEmptyDir
|
||||
* @group github735
|
||||
*/
|
||||
public function testStatVsLstat($sftp)
|
||||
{
|
||||
$this->assertTrue($sftp->mkdir(self::$scratchDir));
|
||||
$this->assertTrue($sftp->chdir(self::$scratchDir));
|
||||
$this->assertTrue($sftp->put('text.txt', 'zzzzz'));
|
||||
$this->assertTrue($sftp->symlink('text.txt', 'link.txt'));
|
||||
$this->assertTrue($sftp->mkdir('subdir'));
|
||||
$this->assertTrue($sftp->symlink('subdir', 'linkdir'));
|
||||
|
||||
$sftp->clearStatCache();
|
||||
|
||||
// pre-populate the stat cache
|
||||
$sftp->nlist();
|
||||
|
||||
$stat = $sftp->stat('link.txt');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_REGULAR);
|
||||
$stat = $sftp->lstat('link.txt');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
|
||||
|
||||
$stat = $sftp->stat('linkdir');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_DIRECTORY);
|
||||
$stat = $sftp->lstat('link.txt');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
|
||||
|
||||
$sftp->disableStatCache();
|
||||
|
||||
$sftp->nlist();
|
||||
|
||||
$stat = $sftp->stat('link.txt');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_REGULAR);
|
||||
$stat = $sftp->lstat('link.txt');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
|
||||
|
||||
$stat = $sftp->stat('linkdir');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_DIRECTORY);
|
||||
$stat = $sftp->lstat('link.txt');
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
|
||||
|
||||
$sftp->enableStatCache();
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStatVsLstat
|
||||
* @group github830
|
||||
*/
|
||||
public function testUploadOffsets($sftp)
|
||||
{
|
||||
$sftp->put('offset.txt', 'res.txt', SFTP::SOURCE_LOCAL_FILE, 0, 10);
|
||||
$this->assertSame(
|
||||
substr(self::$exampleData, 10),
|
||||
$sftp->get('offset.txt'),
|
||||
'Failed asserting that portions of a file could be uploaded.'
|
||||
);
|
||||
|
||||
$sftp->put('offset.txt', 'res.txt', SFTP::SOURCE_LOCAL_FILE, self::$exampleDataLength - 100);
|
||||
$this->assertSame(
|
||||
substr(self::$exampleData, 10, -90) . self::$exampleData,
|
||||
$sftp->get('offset.txt'),
|
||||
'Failed asserting that you could upload into the middle of a file.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUploadOffsets
|
||||
*/
|
||||
public function testReadableWritable($sftp)
|
||||
{
|
||||
$sftp->chmod(0000, 'offset.txt');
|
||||
$this->assertFalse($sftp->is_writable('offset.txt'));
|
||||
$this->assertFalse($sftp->is_writeable('offset.txt'));
|
||||
$this->assertFalse($sftp->is_readable('offset.txt'));
|
||||
|
||||
$sftp->chmod(0777, 'offset.txt');
|
||||
$this->assertTrue($sftp->is_writable('offset.txt'));
|
||||
$this->assertTrue($sftp->is_writeable('offset.txt'));
|
||||
$this->assertTrue($sftp->is_readable('offset.txt'));
|
||||
|
||||
$this->assertFalse($sftp->is_writable('nonexistantfile.ext'));
|
||||
$this->assertFalse($sftp->is_writeable('nonexistantfile.ext'));
|
||||
$this->assertFalse($sftp->is_readable('nonexistantfile.ext'));
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testReadableWritable
|
||||
* @group github999
|
||||
*/
|
||||
public function testExecNlist($sftp)
|
||||
{
|
||||
$sftp->enablePTY();
|
||||
$sftp->exec('ping google.com -c 5');
|
||||
sleep(5);
|
||||
$sftp->nlist();
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Net\SSH2;
|
||||
use phpseclib\System\SSH\Agent;
|
||||
|
||||
class Functional_Net_SSH2AgentTest extends PhpseclibFunctionalTestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!isset($_SERVER['SSH_AUTH_SOCK'])) {
|
||||
self::markTestSkipped(
|
||||
'This test requires an SSH Agent (SSH_AUTH_SOCK env variable).'
|
||||
);
|
||||
}
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
public function testAgentLogin()
|
||||
{
|
||||
$ssh = new SSH2($this->getEnv('SSH_HOSTNAME'));
|
||||
$agent = new Agent;
|
||||
|
||||
$this->assertTrue(
|
||||
$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;
|
||||
}
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Net\SSH2;
|
||||
|
||||
class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$ssh = new SSH2($this->getEnv('SSH_HOSTNAME'));
|
||||
|
||||
$this->assertTrue(
|
||||
is_object($ssh),
|
||||
'Could not construct NET_SSH2 object.'
|
||||
);
|
||||
|
||||
return $ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testConstructor
|
||||
* @group github408
|
||||
* @group github412
|
||||
*/
|
||||
public function testPreLogin($ssh)
|
||||
{
|
||||
$this->assertFalse(
|
||||
$ssh->isConnected(),
|
||||
'Failed asserting that SSH2 is not connected after construction.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$ssh->isAuthenticated(),
|
||||
'Failed asserting that SSH2 is not authenticated after construction.'
|
||||
);
|
||||
|
||||
$this->assertNotEmpty(
|
||||
$ssh->getServerPublicHostKey(),
|
||||
'Failed asserting that a non-empty public host key was fetched.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$ssh->isConnected(),
|
||||
'Failed asserting that SSH2 is connected after public key fetch.'
|
||||
);
|
||||
|
||||
$this->assertNotEmpty(
|
||||
$ssh->getServerIdentification(),
|
||||
'Failed asserting that the server identifier was set after connect.'
|
||||
);
|
||||
|
||||
return $ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPreLogin
|
||||
*/
|
||||
public function testBadPassword($ssh)
|
||||
{
|
||||
$username = $this->getEnv('SSH_USERNAME');
|
||||
$password = $this->getEnv('SSH_PASSWORD');
|
||||
$this->assertFalse(
|
||||
$ssh->login($username, 'zzz' . $password),
|
||||
'SSH2 login using password succeeded.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$ssh->isConnected(),
|
||||
'Failed asserting that SSH2 is connected after bad login attempt.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$ssh->isAuthenticated(),
|
||||
'Failed asserting that SSH2 is not authenticated after bad login attempt.'
|
||||
);
|
||||
|
||||
return $ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testBadPassword
|
||||
*/
|
||||
public function testPasswordLogin($ssh)
|
||||
{
|
||||
$username = $this->getEnv('SSH_USERNAME');
|
||||
$password = $this->getEnv('SSH_PASSWORD');
|
||||
$this->assertTrue(
|
||||
$ssh->login($username, $password),
|
||||
'SSH2 login using password failed.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$ssh->isAuthenticated(),
|
||||
'Failed asserting that SSH2 is authenticated after good login attempt.'
|
||||
);
|
||||
|
||||
return $ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPasswordLogin
|
||||
* @group github280
|
||||
*/
|
||||
public function testExecWithMethodCallback($ssh)
|
||||
{
|
||||
$callbackObject = $this->getMock('stdClass', array('callbackMethod'));
|
||||
$callbackObject
|
||||
->expects($this->atLeastOnce())
|
||||
->method('callbackMethod')
|
||||
->will($this->returnValue(true));
|
||||
$ssh->exec('pwd', array($callbackObject, 'callbackMethod'));
|
||||
}
|
||||
|
||||
public function testGetServerPublicHostKey()
|
||||
{
|
||||
$ssh = new SSH2($this->getEnv('SSH_HOSTNAME'));
|
||||
|
||||
$this->assertInternalType('string', $ssh->getServerPublicHostKey());
|
||||
}
|
||||
|
||||
public function testOpenSocketConnect()
|
||||
{
|
||||
$fsock = fsockopen($this->getEnv('SSH_HOSTNAME'), 22);
|
||||
$ssh = new SSH2($fsock);
|
||||
|
||||
$username = $this->getEnv('SSH_USERNAME');
|
||||
$password = $this->getEnv('SSH_PASSWORD');
|
||||
$this->assertTrue(
|
||||
$ssh->login($username, $password),
|
||||
'SSH2 login using an open socket failed.'
|
||||
);
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\Hash;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
abstract class PhpseclibFunctionalTestCase extends PhpseclibTestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (extension_loaded('runkit')) {
|
||||
if (extension_loaded('gmp')) {
|
||||
self::ensureConstant(
|
||||
'MATH_BIGINTEGER_MODE',
|
||||
BigInteger::MODE_GMP
|
||||
);
|
||||
} elseif (extension_loaded('bcmath')) {
|
||||
self::ensureConstant(
|
||||
'MATH_BIGINTEGER_MODE',
|
||||
BigInteger::MODE_BCMATH
|
||||
);
|
||||
} else {
|
||||
self::markTestSkipped(
|
||||
'Should have gmp or bcmath extension for functional test.'
|
||||
);
|
||||
}
|
||||
self::reRequireFile('Math/BigInteger.php');
|
||||
}
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $variable
|
||||
* @param string|null $message
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected function requireEnv($variable, $message = null)
|
||||
{
|
||||
if ($this->_getEnv($variable) === false) {
|
||||
$msg = $message ? $message : sprintf(
|
||||
"This test requires the '%s' environment variable.",
|
||||
$this->_prefixEnvVariable($variable)
|
||||
);
|
||||
$this->markTestSkipped($msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $variable
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEnv($variable)
|
||||
{
|
||||
$this->requireEnv($variable);
|
||||
return $this->_getEnv($variable);
|
||||
}
|
||||
|
||||
private function _getEnv($variable)
|
||||
{
|
||||
return getenv($this->_prefixEnvVariable($variable));
|
||||
}
|
||||
|
||||
private function _prefixEnvVariable($variable)
|
||||
{
|
||||
return 'PHPSECLIB_' . $variable;
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2013 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $tempFilesToUnlinkOnTearDown = array();
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
foreach ($this->tempFilesToUnlinkOnTearDown as $filename) {
|
||||
if (!file_exists($filename) || unlink($filename)) {
|
||||
unset($this->tempFilesToUnlinkOnTearDown[$filename]);
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a temporary file on the local filesystem and returns its path.
|
||||
* The $number_of_writes and $bytes_per_write parameters can be used to
|
||||
* write $number_of_writes * $bytes_per_write times the character 'a' to the
|
||||
* temporary file. All files created using this method will be deleted from
|
||||
* the filesystem on tearDown(), i.e. after each test method was run.
|
||||
*
|
||||
* @param int $number_of_writes
|
||||
* @param int $bytes_per_write
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function createTempFile($number_of_writes = 0, $bytes_per_write = 0)
|
||||
{
|
||||
$filename = tempnam(sys_get_temp_dir(), 'phpseclib-test-');
|
||||
$this->assertTrue(file_exists($filename));
|
||||
$this->tempFilesToUnlinkOnTearDown[] = $filename;
|
||||
if ($number_of_writes > 0 && $bytes_per_write > 0) {
|
||||
$fp = fopen($filename, 'wb');
|
||||
for ($i = 0; $i < $number_of_writes; ++$i) {
|
||||
fwrite($fp, str_repeat('a', $bytes_per_write));
|
||||
}
|
||||
fclose($fp);
|
||||
$this->assertSame($number_of_writes * $bytes_per_write, filesize($filename));
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $constant
|
||||
* @param mixed $expected
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function ensureConstant($constant, $expected)
|
||||
{
|
||||
if (defined($constant)) {
|
||||
$value = constant($constant);
|
||||
|
||||
if ($value !== $expected) {
|
||||
if (extension_loaded('runkit')) {
|
||||
if (!runkit_constant_redefine($constant, $expected)) {
|
||||
self::markTestSkipped(sprintf(
|
||||
"Failed to redefine constant %s to %s",
|
||||
$constant,
|
||||
$expected
|
||||
));
|
||||
}
|
||||
} else {
|
||||
self::markTestSkipped(sprintf(
|
||||
"Skipping test because constant %s is %s instead of %s",
|
||||
$constant,
|
||||
$value,
|
||||
$expected
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
define($constant, $expected);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename Filename relative to library directory.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function reRequireFile($filename)
|
||||
{
|
||||
if (extension_loaded('runkit')) {
|
||||
$result = runkit_import(
|
||||
sprintf('%s/../phpseclib/%s', __DIR__, $filename),
|
||||
RUNKIT_IMPORT_FUNCTIONS |
|
||||
RUNKIT_IMPORT_CLASS_METHODS |
|
||||
RUNKIT_IMPORT_OVERRIDE
|
||||
);
|
||||
|
||||
if (!$result) {
|
||||
self::markTestSkipped("Failed to reimport file $filename");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?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_InternalTest extends Unit_Crypt_AES_TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->engine = Base::ENGINE_INTERNAL;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?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_McryptTest extends Unit_Crypt_AES_TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->engine = Base::ENGINE_MCRYPT;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
@ -1,401 +0,0 @@
|
||||
<?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\AES;
|
||||
use phpseclib\Crypt\Base;
|
||||
use phpseclib\Crypt\Rijndael;
|
||||
|
||||
abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
{
|
||||
protected $engine;
|
||||
|
||||
private function _checkEngine($aes)
|
||||
{
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces all combinations of test values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function continuousBufferCombos()
|
||||
{
|
||||
$modes = array(
|
||||
Base::MODE_CTR,
|
||||
Base::MODE_OFB,
|
||||
Base::MODE_CFB,
|
||||
);
|
||||
$plaintexts = array(
|
||||
'',
|
||||
'12345678901234567', // https://github.com/phpseclib/phpseclib/issues/39
|
||||
"\xDE\xAD\xBE\xAF",
|
||||
':-):-):-):-):-):-)', // https://github.com/phpseclib/phpseclib/pull/43
|
||||
);
|
||||
$ivs = array(
|
||||
str_repeat("\0", 16),
|
||||
str_pad('test123', 16, "\0"),
|
||||
);
|
||||
$keys = array(
|
||||
str_repeat("\0", 16),
|
||||
str_pad(':-8', 16, "\0"), // https://github.com/phpseclib/phpseclib/pull/43
|
||||
str_pad('FOOBARZ', 16, "\0"),
|
||||
);
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($modes as $mode) {
|
||||
foreach ($plaintexts as $plaintext) {
|
||||
foreach ($ivs as $iv) {
|
||||
foreach ($keys as $key) {
|
||||
$result[] = array($mode, $plaintext, $iv, $key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider continuousBufferCombos
|
||||
*/
|
||||
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]));
|
||||
}
|
||||
|
||||
$this->assertEquals($plaintext, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github451
|
||||
*/
|
||||
public function testKeyPaddingRijndael()
|
||||
{
|
||||
// this test case is from the following URL:
|
||||
// https://web.archive.org/web/20070209120224/http://fp.gladman.plus.com/cryptography_technology/rijndael/aesdvec.zip
|
||||
|
||||
$aes = new Rijndael(Base::MODE_CBC);
|
||||
$aes->setPreferredEngine($this->engine);
|
||||
$aes->disablePadding();
|
||||
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael.
|
||||
$aes->setIV(str_repeat("\0", 16));
|
||||
//$this->_checkEngine($aes); // should only work in internal mode
|
||||
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
|
||||
$this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github451
|
||||
* @expectedException \LengthException
|
||||
*/
|
||||
public function testKeyPaddingAES()
|
||||
{
|
||||
// same as the above - just with a different ciphertext
|
||||
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$aes->setPreferredEngine($this->engine);
|
||||
$aes->disablePadding();
|
||||
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. supported by Rijndael - not AES
|
||||
$aes->setIV(str_repeat("\0", 16));
|
||||
$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();
|
||||
|
||||
foreach ($modes as $mode) {
|
||||
foreach ($combos as $combo) {
|
||||
foreach (array('encrypt', 'decrypt') as $op) {
|
||||
$result[] = array($op, $mode, $combo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty much the same as testContinuousBufferBattery with the caveat that continuous mode is not enabled.
|
||||
*
|
||||
* @dataProvider continuousBufferBatteryCombos
|
||||
*/
|
||||
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(Base::MODE_CBC);
|
||||
|
||||
$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(Base::MODE_CBC);
|
||||
|
||||
$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(Base::MODE_CBC);
|
||||
|
||||
$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');
|
||||
}
|
||||
|
||||
public function testGetKeyLengthDefault()
|
||||
{
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$this->assertSame($aes->getKeyLength(), 128);
|
||||
}
|
||||
|
||||
public function testGetKeyLengthWith192BitKey()
|
||||
{
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$aes->setKey(str_repeat('a', 24));
|
||||
$this->assertSame($aes->getKeyLength(), 192);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LengthException
|
||||
*/
|
||||
public function testSetKeyLengthWithLargerKey()
|
||||
{
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$aes->setKeyLength(128);
|
||||
$aes->setKey(str_repeat('a', 24));
|
||||
$aes->setIV(str_repeat("\0", 16));
|
||||
$this->assertSame($aes->getKeyLength(), 128);
|
||||
$ciphertext = bin2hex($aes->encrypt('a'));
|
||||
$this->assertSame($ciphertext, '82b7b068dfc60ed2a46893b69fecd6c2');
|
||||
$this->assertSame($aes->getKeyLength(), 128);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LengthException
|
||||
*/
|
||||
public function testSetKeyLengthWithSmallerKey()
|
||||
{
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$aes->setKeyLength(256);
|
||||
$aes->setKey(str_repeat('a', 16));
|
||||
$aes->setIV(str_repeat("\0", 16));
|
||||
$this->assertSame($aes->getKeyLength(), 256);
|
||||
$ciphertext = bin2hex($aes->encrypt('a'));
|
||||
$this->assertSame($ciphertext, 'fd4250c0d234aa7e1aa592820aa8406b');
|
||||
$this->assertSame($aes->getKeyLength(), 256);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github938
|
||||
*/
|
||||
public function testContinuousBuffer()
|
||||
{
|
||||
$aes = new AES(AES::MODE_CBC);
|
||||
$aes->disablePadding();
|
||||
$aes->enableContinuousBuffer();
|
||||
$aes->setIV(pack('H*', '0457bdb4a6712986688349a29eb82535'));
|
||||
$aes->setKey(pack('H*', '00d596e2c8189b2592fac358e7396ad2'));
|
||||
$aes->decrypt(pack('H*', '9aa234ea7c750a8109a0f32d768b964e'));
|
||||
$plaintext = $aes->decrypt(pack('H*', '0457bdb4a6712986688349a29eb82535'));
|
||||
$expected = pack('H*', '6572617574689e1be8d2d8d43c594cf3');
|
||||
$this->assertSame($plaintext, $expected);
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?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();
|
||||
|
||||
foreach ($engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
|
||||
{
|
||||
$bf = new Blowfish(Blowfish::MODE_CBC);
|
||||
$bf->setKey($key);
|
||||
$bf->setIV(str_repeat("\0", $bf->getBlockLength() >> 3));
|
||||
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");
|
||||
}
|
||||
}
|
@ -1,393 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2012 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\Hash;
|
||||
|
||||
class Unit_Crypt_HashTest extends PhpseclibTestCase
|
||||
{
|
||||
protected function assertHashesTo($hash, $message, $expected)
|
||||
{
|
||||
$hash = new Hash($hash);
|
||||
|
||||
$this->assertSame(
|
||||
strtolower($expected),
|
||||
bin2hex($hash->hash($message)),
|
||||
sprintf("Failed asserting that '%s' hashes to '%s'.", $message, $expected)
|
||||
);
|
||||
}
|
||||
|
||||
protected function assertHMACsTo($hash, $key, $message, $expected)
|
||||
{
|
||||
$hash = new Hash($hash);
|
||||
$hash->setKey($key);
|
||||
|
||||
$this->assertSame(
|
||||
strtolower($expected),
|
||||
bin2hex($hash->hash($message)),
|
||||
sprintf(
|
||||
"Failed asserting that '%s' HMACs to '%s' with key '%s'.",
|
||||
$message,
|
||||
$expected,
|
||||
$key
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static function hashData()
|
||||
{
|
||||
return array(
|
||||
array('md5', '', 'd41d8cd98f00b204e9800998ecf8427e'),
|
||||
array('md5', 'The quick brown fox jumps over the lazy dog', '9e107d9d372bb6826bd81d3542a419d6'),
|
||||
array('md5', 'The quick brown fox jumps over the lazy dog.', 'e4d909c290d0fb1ca068ffaddf22cbd0'),
|
||||
array('sha1', 'The quick brown fox jumps over the lazy dog', '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'),
|
||||
array('sha1', 'The quick brown fox jumps over the lazy dog.', '408d94384216f890ff7a0c3528e8bed1e0b01621'),
|
||||
array(
|
||||
'sha256',
|
||||
'',
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||
),
|
||||
array(
|
||||
'sha256',
|
||||
'The quick brown fox jumps over the lazy dog',
|
||||
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592',
|
||||
),
|
||||
array(
|
||||
'sha256',
|
||||
'The quick brown fox jumps over the lazy dog.',
|
||||
'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c',
|
||||
),
|
||||
array(
|
||||
'sha384',
|
||||
'',
|
||||
'38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b'
|
||||
),
|
||||
array(
|
||||
'sha384',
|
||||
'The quick brown fox jumps over the lazy dog',
|
||||
'ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1',
|
||||
),
|
||||
array(
|
||||
'sha512',
|
||||
'',
|
||||
'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
|
||||
),
|
||||
array(
|
||||
'sha512',
|
||||
'The quick brown fox jumps over the lazy dog',
|
||||
'07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6',
|
||||
),
|
||||
array(
|
||||
'sha512',
|
||||
'The quick brown fox jumps over the lazy dog.',
|
||||
'91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed',
|
||||
),
|
||||
// from http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA512_224.pdf
|
||||
array(
|
||||
'sha512/224',
|
||||
'abc',
|
||||
'4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa'
|
||||
),
|
||||
array(
|
||||
'sha512/224',
|
||||
'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu',
|
||||
'23fec5bb94d60b23308192640b0c453335d664734fe40e7268674af9'
|
||||
),
|
||||
// from http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA512_256.pdf
|
||||
array(
|
||||
'sha512/256',
|
||||
'abc',
|
||||
'53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23'
|
||||
),
|
||||
array(
|
||||
'sha512/256',
|
||||
'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu',
|
||||
'3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a'
|
||||
),
|
||||
// from http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf
|
||||
array(
|
||||
'sha224',
|
||||
'abc',
|
||||
'23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7'
|
||||
),
|
||||
array(
|
||||
'sha224',
|
||||
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
|
||||
'75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider hmacData()
|
||||
*/
|
||||
public function testHMAC($hash, $key, $message, $result)
|
||||
{
|
||||
$this->assertHMACsTo($hash, $key, $message, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider hmacData()
|
||||
*/
|
||||
public function testHMAC96($hash, $key, $message, $result)
|
||||
{
|
||||
$this->assertHMACsTo($hash . '-96', $key, $message, substr($result, 0, 24));
|
||||
}
|
||||
|
||||
public static function hmacData()
|
||||
{
|
||||
return array(
|
||||
array('md5', '', '', '74e6f7298a9c2d168935f58c001bad88'),
|
||||
array('md5', 'key', 'The quick brown fox jumps over the lazy dog', '80070713463e7749b90c2dc24911e275'),
|
||||
|
||||
// from https://tools.ietf.org/rfc/rfc4231.txt
|
||||
// test case 1
|
||||
array(
|
||||
'sha224',
|
||||
str_repeat("\x0b", 20),
|
||||
'Hi There',
|
||||
'896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22',
|
||||
),
|
||||
// test case 2
|
||||
array(
|
||||
'sha224',
|
||||
'Jefe',
|
||||
'what do ya want for nothing?',
|
||||
'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44',
|
||||
),
|
||||
// test case 3
|
||||
array(
|
||||
'sha224',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
|
||||
'7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea',
|
||||
),
|
||||
// test case 4
|
||||
array(
|
||||
'sha224',
|
||||
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
|
||||
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
|
||||
'6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a',
|
||||
),
|
||||
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
|
||||
// test case 6
|
||||
array(
|
||||
'sha224',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'Test Using Larger Than Block-Size Key - Hash Key First',
|
||||
'95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e',
|
||||
),
|
||||
// test case 7
|
||||
array(
|
||||
'sha224',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
|
||||
'3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1'
|
||||
),
|
||||
|
||||
// test case 1
|
||||
array(
|
||||
'sha256',
|
||||
str_repeat("\x0b", 20),
|
||||
'Hi There',
|
||||
'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7',
|
||||
),
|
||||
// test case 2
|
||||
array(
|
||||
'sha256',
|
||||
'Jefe',
|
||||
'what do ya want for nothing?',
|
||||
'5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843',
|
||||
),
|
||||
// test case 3
|
||||
array(
|
||||
'sha256',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
|
||||
'773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe',
|
||||
),
|
||||
// test case 4
|
||||
array(
|
||||
'sha256',
|
||||
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
|
||||
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
|
||||
'82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b',
|
||||
),
|
||||
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
|
||||
// test case 6
|
||||
array(
|
||||
'sha256',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'Test Using Larger Than Block-Size Key - Hash Key First',
|
||||
'60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54',
|
||||
),
|
||||
// test case 7
|
||||
array(
|
||||
'sha256',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
|
||||
'9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2'
|
||||
),
|
||||
|
||||
// test case 1
|
||||
array(
|
||||
'sha384',
|
||||
str_repeat("\x0b", 20),
|
||||
'Hi There',
|
||||
'afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6',
|
||||
),
|
||||
// test case 2
|
||||
array(
|
||||
'sha384',
|
||||
'Jefe',
|
||||
'what do ya want for nothing?',
|
||||
'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649',
|
||||
),
|
||||
// test case 3
|
||||
array(
|
||||
'sha384',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
|
||||
'88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27',
|
||||
),
|
||||
// test case 4
|
||||
array(
|
||||
'sha384',
|
||||
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
|
||||
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
|
||||
'3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb',
|
||||
),
|
||||
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
|
||||
// test case 6
|
||||
array(
|
||||
'sha384',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'Test Using Larger Than Block-Size Key - Hash Key First',
|
||||
'4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952',
|
||||
),
|
||||
// test case 7
|
||||
array(
|
||||
'sha384',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
|
||||
'6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e'
|
||||
),
|
||||
|
||||
// test case 1
|
||||
array(
|
||||
'sha512',
|
||||
str_repeat("\x0b", 20),
|
||||
'Hi There',
|
||||
'87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854',
|
||||
),
|
||||
// test case 2
|
||||
array(
|
||||
'sha512',
|
||||
'Jefe',
|
||||
'what do ya want for nothing?',
|
||||
'164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737',
|
||||
),
|
||||
// test case 3
|
||||
array(
|
||||
'sha512',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
|
||||
'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb',
|
||||
),
|
||||
// test case 4
|
||||
array(
|
||||
'sha512',
|
||||
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
|
||||
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
|
||||
'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd',
|
||||
),
|
||||
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
|
||||
// test case 6
|
||||
array(
|
||||
'sha512',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'Test Using Larger Than Block-Size Key - Hash Key First',
|
||||
'80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598',
|
||||
),
|
||||
// test case 7
|
||||
array(
|
||||
'sha512',
|
||||
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
||||
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
|
||||
'e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider hashData()
|
||||
*/
|
||||
public function testHash($hash, $message, $result)
|
||||
{
|
||||
$this->assertHashesTo($hash, $message, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider hashData()
|
||||
*/
|
||||
public function testHash96($hash, $message, $result)
|
||||
{
|
||||
$this->assertHashesTo($hash . '-96', $message, substr($result, 0, 24));
|
||||
}
|
||||
|
||||
public function testConstructorDefault()
|
||||
{
|
||||
$hash = new Hash();
|
||||
$this->assertSame($hash->getHash(), 'sha256');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \phpseclib\Exception\UnsupportedAlgorithmException
|
||||
*/
|
||||
public function testConstructorArgumentInvalid()
|
||||
{
|
||||
new Hash('abcdefghijklmnopqrst');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \phpseclib\Exception\UnsupportedAlgorithmException
|
||||
*/
|
||||
public function testSetHashInvalid()
|
||||
{
|
||||
$hash = new Hash('md5');
|
||||
$hash->setHash('abcdefghijklmnopqrst-96');
|
||||
}
|
||||
|
||||
public function testSetHashValid()
|
||||
{
|
||||
$hash = new Hash('md5');
|
||||
$this->assertSame($hash->getHash(), 'md5');
|
||||
$hash->setHash('sha1');
|
||||
$this->assertSame($hash->getHash(), 'sha1');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider lengths
|
||||
*/
|
||||
public function testGetLengthKnown($algorithm, $length)
|
||||
{
|
||||
$hash = new Hash($algorithm);
|
||||
$this->assertSame($hash->getLength(), $length);
|
||||
}
|
||||
|
||||
public function lengths()
|
||||
{
|
||||
return array(
|
||||
// known
|
||||
array('md5-96', 12),
|
||||
array('md5', 16),
|
||||
array('sha1', 20),
|
||||
array('sha256', 32),
|
||||
array('sha384', 48),
|
||||
array('sha512', 64),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
<?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();
|
||||
|
||||
foreach ($this->engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
|
||||
}
|
||||
}
|
||||
|
||||
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::MODE_CBC);
|
||||
$rc2->disablePadding();
|
||||
$rc2->setKeyLength($keyLen);
|
||||
$rc2->setKey(pack('H*', $key)); // could also do $rc2->setKey(pack('H*', $key), $keyLen)
|
||||
$rc2->setIV(str_repeat("\0", $rc2->getBlockLength() >> 3));
|
||||
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");
|
||||
|
||||
$result = bin2hex($rc2->decrypt(pack('H*', $ciphertext)));
|
||||
$this->assertEquals($result, $plaintext, "Failed asserting that decrypted result yielded $plaintext as a result in $engineName engine");
|
||||
}
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
<?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();
|
||||
|
||||
foreach ($engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
foreach ($test['output'] as $output) {
|
||||
$result[] = array($engine, $engineName, $test['key'], $output['offset'], $output['result']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
|
||||
class Unit_Crypt_RSA_CreateKeyTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testCreateKey()
|
||||
{
|
||||
extract(RSA::createKey(768));
|
||||
$this->assertInstanceOf('\phpseclib\Crypt\RSA', $privatekey);
|
||||
$this->assertInstanceOf('\phpseclib\Crypt\RSA', $publickey);
|
||||
$this->assertNotEmpty("$privatekey");
|
||||
$this->assertNotEmpty("$publickey");
|
||||
|
||||
return array($publickey, $privatekey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateKey
|
||||
*/
|
||||
public function testEncryptDecrypt($args)
|
||||
{
|
||||
list($publickey, $privatekey) = $args;
|
||||
$ciphertext = $publickey->encrypt('zzz');
|
||||
$this->assertInternalType('string', $ciphertext);
|
||||
$plaintext = $privatekey->decrypt($ciphertext);
|
||||
$this->assertSame($plaintext, 'zzz');
|
||||
}
|
||||
}
|
@ -1,557 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2013 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Crypt\RSA\PKCS1;
|
||||
use phpseclib\Crypt\RSA\PuTTY;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testBadKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = 'zzzzzzzzzzzzzz';
|
||||
|
||||
$this->assertFalse($rsa->load($key));
|
||||
}
|
||||
|
||||
public function testPKCS1Key()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testPKCS1SpacesKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$key = str_replace(array("\r", "\n", "\r\n"), ' ', $key);
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testPKCS1NoHeaderKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = 'MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testPKCS1NoWhitespaceNoHeaderKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = 'MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp' .
|
||||
'wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5' .
|
||||
'1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh' .
|
||||
'3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2' .
|
||||
'pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX' .
|
||||
'GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il' .
|
||||
'AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF' .
|
||||
'L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k' .
|
||||
'X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl' .
|
||||
'U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ' .
|
||||
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testRawPKCS1Key()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = 'MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp' .
|
||||
'wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5' .
|
||||
'1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh' .
|
||||
'3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2' .
|
||||
'pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX' .
|
||||
'GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il' .
|
||||
'AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF' .
|
||||
'L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k' .
|
||||
'X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl' .
|
||||
'U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ' .
|
||||
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
|
||||
$key = base64_decode($key);
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testLoadPKCS8PrivateKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$rsa->setPassword('password');
|
||||
|
||||
$key = '-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIE6TAbBgkqhkiG9w0BBQMwDgQIcWWgZeQYPTcCAggABIIEyLoa5b3ktcPmy4VB
|
||||
hHkpHzVSEsKJPmQTUaQvUwIp6+hYZeuOk78EPehrYJ/QezwJRdyBoD51oOxqWCE2
|
||||
fZ5Wf6Mi/9NIuPyqQccP2ouErcMAcDLaAx9C0Ot37yoG0S6hOZgaxqwnCdGYKHgS
|
||||
7cYUv40kLOJmTOJlHJbatfXHocrHcHkCBJ1q8wApA1KVQIZsqmyBUBuwbrfFwpC9
|
||||
d/R674XxCWJpXvU63VNZRFYUvd7YEWCrdSeleb99p0Vn1kxI5463PXurgs/7GPiO
|
||||
SLSdX44DESP9l7lXenC4gbuT8P0xQRDzGrB5l9HHoV3KMXFODWTMnLcp1nuhA0OT
|
||||
fPS2yzT9zJgqHiVKWgcUUJ5uDelVfnsmDhnh428p0GBFbniH07qREC9kq78UqQNI
|
||||
Kybp4jQ4sPs64zdYm/VyLWtAYz8QNAKHLcnPwmTPr/XlJmox8rlQhuSQTK8E+lDr
|
||||
TOKpydrijN3lF+pgyUuUj6Ha8TLMcOOwqcrpBig4SGYoB56gjAO0yTE9uCPdBakj
|
||||
yxi3ksn51ErigGM2pGMNcVdwkpJ/x+DEBBO0auy3t9xqM6LK8pwNcOT1EWO+16zY
|
||||
79LVSavc49t+XxMc3Xasz/G5xQgD1FBp6pEnsg5JhTTG/ih6Y/DQD8z3prjC3qKc
|
||||
rpL4NA9KBI/IF1iIXlrfmN/zCKbBuEOEGqwcHBDHPySZbhL2XLSpGcK/NBl1bo1Z
|
||||
G+2nUTauoC67Qb0+fnzTcvOiMNAbHMiqkirs4anHX33MKL2gR/3dp8ca9hhWWXZz
|
||||
Mkk2FK9sC/ord9F6mTtvTiOSDzpiEhb94uTxXqBhIbsrGXCUUd0QQN5s2dmW2MfS
|
||||
M35KeSv2rwDGzC1+Qf3MhHGIZDqoQwuZEzM5yHHafCatAbZd2sjaFWegg0r2ca7a
|
||||
eZkZFj3ZuDYXJFnL82guOASh7rElWO2Ys7ncXAKnaV3WkkF+JDv/CUHr+Q/h6Ae5
|
||||
qEvgubTCVSYHzRP37XJItlcdywTIcTY+t6jymmyEBJ66LmUoD47gt/vDUSbhT6Oa
|
||||
GlcZ+MZGlUnPOSq4YknOgwKH8izboY4UgVCrmXvlaZYQhZemNDkVbpYVDf+s6cPf
|
||||
tJwVoZf+qf2SsRTUsI10isoIzCyGw2ie8kmipdP434Z/99uVU3zxD6raNDlyp33q
|
||||
FWMgpr2JU6NVAla7N51g7Jk8VjIIn7SvCYyWkmvv4kLB1UHl3NFqYb9YuIZUaDyt
|
||||
j/NMcKMLLOaEorRZ2N2mDNoihMxMf8J3J9APnzUigAtaalGKNOrd2Fom5OVADePv
|
||||
Tb5sg1uVQzfcpFrjIlLVh+2cekX0JM84phbMpHmm5vCjjfYvUvcMy0clCf0x3jz6
|
||||
LZf5Fzc8xbZmpse5OnOrsDLCNh+SlcYOzsagSZq4TgvSeI9Tr4lv48dLJHCCcYKL
|
||||
eymS9nhlCFuuHbi7zI7edcI49wKUW1Sj+kvKq3LMIEkMlgzqGKA6JqSVxHP51VH5
|
||||
FqV4aKq70H6dNJ43bLVRPhtF5Bip5P7k/6KIsGTPUd54PHey+DuWRjitfheL0G2w
|
||||
GF/qoZyC1mbqdtyyeWgHtVbJVUORmpbNnXOII9duEqBUNDiO9VSZNn/8h/VsYeAB
|
||||
xryZaRDVmtMuf/OZBQ==
|
||||
-----END ENCRYPTED PRIVATE KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testSavePKCS8PrivateKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$rsa->setPassword('password');
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
|
||||
$key = $rsa->getPrivateKey('PKCS8');
|
||||
$this->assertInternalType('string', $key);
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
}
|
||||
|
||||
public function testPubKey1()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
|
||||
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
|
||||
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
|
||||
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
|
||||
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
|
||||
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
|
||||
-----END RSA PUBLIC KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPublicKey());
|
||||
$this->assertFalse($rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testPubKey2()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
|
||||
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
|
||||
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
|
||||
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
|
||||
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
|
||||
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
|
||||
ZQIDAQAB
|
||||
-----END PUBLIC KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPublicKey());
|
||||
$this->assertFalse($rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testSSHPubKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4e' .
|
||||
'CZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMS' .
|
||||
'GkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZw== ' .
|
||||
'phpseclib-generated-key';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPublicKey());
|
||||
$this->assertFalse($rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
public function testSSHPubKeyFingerprint()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD9K+ebJRMN10kGanhi6kDz6EYFqZttZWZh0'.
|
||||
'YoEbIbbere9N2Yvfc7oIoCTHYowhXND9WSJaIs1E4bx0085CZnofWaqf4NbZTzAh18iZup08ec'.
|
||||
'COB5gJVS1efpgVSviDF2L7jxMsBVoOBfqsmA8m0RwDDVezyWvw4y+STSuVzu2jI8EfwN7ZFGC6'.
|
||||
'Yo8m/Z94qIGzqPYGKJLuCeidB0TnUE0ZtzOJTiOc/WoTm/NOpCdfQZEJggd1MOTi+QUnqRu4Wu'.
|
||||
'b6wYtY/q/WtUFr3nK+x0lgOtokhnJfRR/6fnmC1CztPnIT4BWK81VGKWONAxuhMyQ5XChyu6S9'.
|
||||
'mWG5tUlUI/5';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertSame($rsa->getPublicKeyFingerprint('md5'), 'bd:2c:2f:31:b9:ef:b8:f8:ad:fc:40:a6:94:4f:28:82');
|
||||
$this->assertSame($rsa->getPublicKeyFingerprint('sha256'), 'N9sV2uSNZEe8TITODku0pRI27l+Zk0IY0TrRTw3ozwM');
|
||||
}
|
||||
|
||||
public function testSetPrivate()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
|
||||
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
|
||||
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
|
||||
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
|
||||
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
|
||||
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
|
||||
-----END RSA PUBLIC KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertTrue($rsa->setPrivateKey());
|
||||
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
|
||||
$this->assertFalse($rsa->getPublicKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* make phpseclib generated XML keys be unsigned. this may need to be reverted
|
||||
* if it is later learned that XML keys are, in fact, supposed to be signed
|
||||
* @group github468
|
||||
*/
|
||||
public function testUnsignedXML()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '<RSAKeyValue>
|
||||
<Modulus>v5OxcEgxPUfa701NpxnScCmlRkbwSGBiTWobHkIWZEB+AlRTHaVoZg/D8l6YzR7VdQidG6gF+nuUMjY75dBXgY/XcyVq0Hccf1jTfgARuNuq4GGG3hnCJVi2QsOgcf9R7TeXn+p1RKIhjQoWCiEQeEBTotNbJhcabNcPGSEJw+s=</Modulus>
|
||||
<Exponent>AQAB</Exponent>
|
||||
</RSAKeyValue>';
|
||||
|
||||
$rsa->load($key);
|
||||
$rsa->setPublicKey();
|
||||
$newkey = $rsa->getPublicKey('XML');
|
||||
|
||||
$this->assertSame(strtolower(preg_replace('#\s#', '', $key)), strtolower(preg_replace('#\s#', '', $newkey)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github468
|
||||
*/
|
||||
public function testSignedPKCS1()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/k7FwSDE9R9rvTU2nGdJwKaVG
|
||||
RvBIYGJNahseQhZkQH4CVFMdpWhmD8PyXpjNHtV1CJ0bqAX6e5QyNjvl0FeBj9dz
|
||||
JWrQdxx/WNN+ABG426rgYYbeGcIlWLZCw6Bx/1HtN5ef6nVEoiGNChYKIRB4QFOi
|
||||
01smFxps1w8ZIQnD6wIDAQAB
|
||||
-----END PUBLIC KEY-----';
|
||||
|
||||
$rsa->load($key);
|
||||
$rsa->setPublicKey();
|
||||
$newkey = $rsa->getPublicKey();
|
||||
|
||||
$this->assertSame(preg_replace('#\s#', '', $key), preg_replace('#\s#', '', $newkey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github861
|
||||
*/
|
||||
public function testPKCS8Only()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN PRIVATE KEY-----
|
||||
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKB0yPMAbUHKqJxP
|
||||
5sjG9AOrQSAYNDc34NsnZ1tsi7fZ9lHlBaKZ6gjm2U9q+/qCKv2BuGINxWo2CMJp
|
||||
DHNY0QTt7hThr3B4U62z1CWWGnfLhFtHKH6jNYYOGc4x0jgT88uSrKFvUOLhjkjW
|
||||
bURmJMpN+OjLJuZQZ7uwoqtT3IEDAgMBAAECgYBaElS/fEzYst/Fp2DA8lYGPTs4
|
||||
vf2JxbdWrp7phlxEH3mTbUGljkr/Jj90wnSiojFpz0jm2h4oyh5Oq9OOaJwkCYcu
|
||||
2lcHJvFlhR2XEJpd1bHHcvDwZHdUjSpnO8kvwQtjuTnho2ntRzAA4wIJVSd7Tynj
|
||||
0IFEKmzhSKIvIIeN8QJBANLa10R1vs+YqpLdpAuc6Z9GYhHuh1TysBPw2xNtw3Xf
|
||||
tGPx4/53eQ0RwiHdw9Opgt8CBHErD6KzziflfxUrIXkCQQDCz4t01qYWT43kxS6k
|
||||
TcnZb/obho6akGc8C1hSxFIIGUa9hAhMpY2W6GXeGpv5TZtEJZIJE1VHTLvcLSGm
|
||||
ILNbAkEAgq9mWqULxYket3Yt1ZDEb5Zk9C49rJXaMhHHBoyyZ51mJcfngnE0Erid
|
||||
9PWJCOf4GBYdALMqtrHwpWOlV05rKQJAd6Tz50w1MRqm8MvRe4Ny5qIJH4Kibncl
|
||||
kBD/q8V7BBJSCe7fEgPTU81jUudQx+pL46yXZg+DnoiYD/9/3QHUZQJBAMBiKiZ7
|
||||
qMnD/pkHR/NFcYSYShUJS0cHyryVl7/eCclsQlZTRdnVTtKF9xPGTQC8fK0G7BDN
|
||||
Z2sKniRCcDT1ZP4=
|
||||
-----END PRIVATE KEY-----';
|
||||
|
||||
$result = $rsa->load($key, 'PKCS8');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testPKCS1EncryptionChange()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = 'PuTTY-User-Key-File-2: ssh-rsa
|
||||
Encryption: none
|
||||
Comment: phpseclib-generated-key
|
||||
Public-Lines: 4
|
||||
AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4
|
||||
eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RK
|
||||
NUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDy
|
||||
R4e9T04ZZw==
|
||||
Private-Lines: 8
|
||||
AAAAgBYo5KOevqhsjfDNEVcmkQF8/vsU6hwS4d7ceFYDLa0PlhIAo4aE8KNtyjAQ
|
||||
LiRkmJ0ZqAWTN5TH0ynryJAInTxMb2AnZuXWKt106C5JC7+S9qSCFThTAxvihEpw
|
||||
BVe5dnPnJ80TFtPm+n/JkdQic2bsVSy+kNNn7y4uef5m0mMRAAAAQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJ
|
||||
rmfPwIGm63ilAAAAQQDEIvkdBvZtCvgHKitwxab+EQ/YxnNE5XvfIXjWE+xEL2br
|
||||
oquF470c9Mm6jf/2zmn6yobE6UUvQ0O3hKSiyOAbAAAAQBGoiuSoSjafUhV7i1cE
|
||||
Gpb88h5NBYZzWXGZ37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ
|
||||
4p0=
|
||||
Private-MAC: 03e2cb74e1d67652fbad063d2ed0478f31bdf256
|
||||
';
|
||||
$key = preg_replace('#(?<!\r)\n#', "\r\n", $key);
|
||||
$this->assertTrue($rsa->load($key));
|
||||
|
||||
PKCS1::setEncryptionAlgorithm('AES-256-CBC');
|
||||
$rsa->setPassword('demo');
|
||||
|
||||
$encryptedKey = (string) $rsa;
|
||||
|
||||
$this->assertRegExp('#AES-256-CBC#', $encryptedKey);
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->setPassword('demo');
|
||||
$this->assertTrue($rsa->load($encryptedKey));
|
||||
$rsa->setPassword();
|
||||
$rsa->setPrivateKeyFormat('PuTTY');
|
||||
$key2 = (string) $rsa;
|
||||
|
||||
$this->assertSame($key, $key2);
|
||||
}
|
||||
|
||||
public function testRawKey()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = array(
|
||||
'e' => new BigInteger('10001', 16),
|
||||
'n' => new BigInteger('aa18aba43b50deef38598faf87d2ab634e4571c130a9bca7b878267414faab8b471bd8965f5c9fc3' .
|
||||
'818485eaf529c26246f3055064a8de19c8c338be5496cbaeb059dc0b358143b44a35449eb2641131' .
|
||||
'21a455bd7fde3fac919e94b56fb9bb4f651cdb23ead439d6cd523eb08191e75b35fd13a7419b3090' .
|
||||
'f24787bd4f4e1967', 16)
|
||||
);
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$rsa->setPublicKeyFormat('raw');
|
||||
$this->assertEmpty("$rsa");
|
||||
}
|
||||
|
||||
public function testRawComment()
|
||||
{
|
||||
$key = 'PuTTY-User-Key-File-2: ssh-rsa
|
||||
Encryption: aes256-cbc
|
||||
Comment: phpseclib-generated-key
|
||||
Public-Lines: 4
|
||||
AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4
|
||||
eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RK
|
||||
NUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDy
|
||||
R4e9T04ZZw==
|
||||
Private-Lines: 8
|
||||
llx04QMegql0/nE5RvcJSrGrodxt6ytuv/JX2caeZBUyQwQc2WBNYagLHyHPM9jI
|
||||
9OUWz59FLhjFXZMDNMoUXxVmjwQpOAaVPYNxxFM9AF6/NXFji64K7huD9n4A+kLn
|
||||
sHwMLWPR5a/tZA0r05DZNz9ULA3mQu7Hz4EQ8ifu3uTPJuTmL51x6RmudYKysb20
|
||||
fM8VzC3ukvzzRh0pujUVTr/yQdmciASVFnZlt4xQy+ZEOVUAOfwjd//AFfXTvk6x
|
||||
7A45rNlU/uicHwLgoY1APvRHCFxw7F+uVW5L4mSX7NNzqBKkZ+1qpQTAfQvIfEIb
|
||||
444+CXsgIyOpqt6VxJH2u6elAtE1wau3YaFR8Alm8m97rFYzRi3oDP5NZYkTCWSV
|
||||
EOpSeghXSs7IilJu8I6/sB1w5dakdeBSFkIynrlFXkO0uUw+QJJWjxY8SypzgIuP
|
||||
DzduF6XsQrCyo6dnIpGQCQ==
|
||||
Private-MAC: 35134b7434bf828b21404099861d455e660e8740';
|
||||
$raw = PuTTY::load($key, 'password');
|
||||
$this->assertArrayHasKey('comment', $raw);
|
||||
$this->assertEquals($raw['comment'], 'phpseclib-generated-key');
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load($raw);
|
||||
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
|
||||
}
|
||||
|
||||
public function testPrivateMSBlob()
|
||||
{
|
||||
$key = 'BwIAAACkAABSU0EyAAQAAAEAAQAnh6FFs6kYe/gmb9dzqsQKmtjFE9mxNAe9mEU3OwOEEfyI' .
|
||||
'wkAx0/8dwh12fuP4wzNbdZAq4mmqCE6Lo8wTNNIJVNYEhKq5chHg1+hPDgfETFgtEO54JZSg' .
|
||||
'3cBZWEV/Tq3LHEX8CaLvHZxMEfFXbTfliFYMLoJ+YK1mpg9GYcmbrVmMAKSoOgETkkiJJzYm' .
|
||||
'XftO3KOveBtvkAzjHxxSS1yP/Ba10BzeIleH96SbTuQtQRLXwRykdX9uazK+YsiSud9/PyLb' .
|
||||
'gy5TI+o28OHq5P+0y5+a9IaAQ/92UwlrkHUYfhN/xTVlUIxKlTEdUQTIf+iHif8d4ABb3OdY' .
|
||||
'JXZOW6fGeUP10jMyvbnrEoPDsYy9qfNk++0/8UP2NeO1IATszuZYg1nEXOW/5jmUxMCdiFyd' .
|
||||
'p9ES211kpEZ4XcvjGaDlaQ+bLWj05i2m/9aHYcBrfcxxvlMa/9ZvrX4DfPWeydUDDDQ4+ntp' .
|
||||
'T50BunSvmyf7cUk76Bf2sPgLXUQFoufEQ5g1Qo/v1uyhWBJzh6OSUO/DDXN/s8ec/tN05RQQ' .
|
||||
'FZQ0na+v0hOCrV9IuRqtBuj4WAj1I/A1JjwyyP9Y/6yWFPM6EcS/6lyPy30lJPoULh7G29zk' .
|
||||
'n7NVdTEkDtthdDjtX7Qhgd9qWvm5ADlmnvsS9A5m7ToOgQyOxtJoSlLitLbf/09LRycl/cdI' .
|
||||
'zoMOCEdPe3DQcyEKqUPsghAq+DKw3uZpXwHzwTdfqlHSWAnHDggFKV1HZuWc1c4rV4k4b513TqE=';
|
||||
|
||||
$plaintext = 'zzz';
|
||||
|
||||
$privKey = new RSA();
|
||||
$privKey->load($key);
|
||||
|
||||
$this->assertSame($privKey->getLoadedFormat(), 'MSBLOB');
|
||||
|
||||
$this->assertGreaterThanOrEqual(1, strlen("$privKey"));
|
||||
|
||||
$pubKey = new RSA();
|
||||
$pubKey->load($privKey->getPublicKey('msblob'));
|
||||
|
||||
$this->assertGreaterThanOrEqual(1, strlen("$pubKey"));
|
||||
|
||||
$ciphertext = $pubKey->encrypt($plaintext);
|
||||
|
||||
$this->assertSame($privKey->decrypt($ciphertext), $plaintext);
|
||||
}
|
||||
|
||||
public function testNakedOpenSSHKey()
|
||||
{
|
||||
$key = 'AAAAB3NzaC1yc2EAAAABIwAAAIEA/NcGSQFZ0ZgN1EbDusV6LLwLnQjs05ljKcVVP7Z6aKIJUyhUDHE30uJa5XfwPPBsZ3L3Q7S0yycVcuuHjdauugmpn9xx+gyoYs7UiV5G5rvxNcA/Tc+MofGhAMiTmNicorNAs5mv6fRoVbkpIONRXPz6WK0kjx/X04EV42Vm9Qk=';
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load($key);
|
||||
|
||||
$this->assertSame($rsa->getLoadedFormat(), 'OpenSSH');
|
||||
|
||||
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
|
||||
}
|
||||
|
||||
public function testPuttyPublicKey()
|
||||
{
|
||||
$key = '---- BEGIN SSH2 PUBLIC KEY ----
|
||||
Comment: "rsa-key-20151023"
|
||||
AAAAB3NzaC1yc2EAAAABJQAAAIEAhC/CSqJ+8vgeQ4H7fJru29h/McqAC9zdGzw0
|
||||
9QsifLQ7s5MvXCavhjUPYIfV0KsdLQydNPLJcbKpXmpVD9azo61zLXwsYr8d1eHr
|
||||
C/EwUYl8b0fAwEsEF3myb+ryzgA9ihY08Zs9NZdmt1Maa+I7lQcLX9F/65YdcAch
|
||||
ILaEujU=
|
||||
---- END SSH2 PUBLIC KEY ----';
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load($key);
|
||||
|
||||
$this->assertSame($rsa->getLoadedFormat(), 'PuTTY');
|
||||
|
||||
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github960
|
||||
*/
|
||||
public function testSetLoad()
|
||||
{
|
||||
$key = 'PuTTY-User-Key-File-2: ssh-rsa
|
||||
Encryption: aes256-cbc
|
||||
Comment: phpseclib-generated-key
|
||||
Public-Lines: 4
|
||||
AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4
|
||||
eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RK
|
||||
NUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDy
|
||||
R4e9T04ZZw==
|
||||
Private-Lines: 8
|
||||
llx04QMegql0/nE5RvcJSrGrodxt6ytuv/JX2caeZBUyQwQc2WBNYagLHyHPM9jI
|
||||
9OUWz59FLhjFXZMDNMoUXxVmjwQpOAaVPYNxxFM9AF6/NXFji64K7huD9n4A+kLn
|
||||
sHwMLWPR5a/tZA0r05DZNz9ULA3mQu7Hz4EQ8ifu3uTPJuTmL51x6RmudYKysb20
|
||||
fM8VzC3ukvzzRh0pujUVTr/yQdmciASVFnZlt4xQy+ZEOVUAOfwjd//AFfXTvk6x
|
||||
7A45rNlU/uicHwLgoY1APvRHCFxw7F+uVW5L4mSX7NNzqBKkZ+1qpQTAfQvIfEIb
|
||||
444+CXsgIyOpqt6VxJH2u6elAtE1wau3YaFR8Alm8m97rFYzRi3oDP5NZYkTCWSV
|
||||
EOpSeghXSs7IilJu8I6/sB1w5dakdeBSFkIynrlFXkO0uUw+QJJWjxY8SypzgIuP
|
||||
DzduF6XsQrCyo6dnIpGQCQ==
|
||||
Private-MAC: 35134b7434bf828b21404099861d455e660e8740';
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->setPrivateKey($key);
|
||||
$rsa->load($key);
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load($key);
|
||||
$rsa->setPrivateKey();
|
||||
$rsa->load($rsa);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github980
|
||||
*/
|
||||
public function testZeroComponents()
|
||||
{
|
||||
$key = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIGaAgEAAkEAt5yrcHAAjhglnCEn6yecMWPeUXcMyo0+itXrLlkpcKIIyqPw546b
|
||||
GThhlb1ppX1ySX/OUA4jSakHekNP5eWPawIBAAJAW6/aVD05qbsZHMvZuS2Aa5Fp
|
||||
NNj0BDlf38hOtkhDzz/hkYb+EBYLLvldhgsD0OvRNy8yhz7EjaUqLCB0juIN4QIB
|
||||
AAIBAAIBAAIBAAIBAA==
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load($key);
|
||||
$rsa->setHash('md5');
|
||||
$rsa->setMGFHash('md5');
|
||||
|
||||
$rsa->sign('zzzz', RSA::PADDING_PKCS1);
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2013 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
class Unit_Crypt_RSA_ModeTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testEncryptionModeNone()
|
||||
{
|
||||
$plaintext = 'a';
|
||||
|
||||
$rsa = new RSA();
|
||||
|
||||
$privatekey = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$rsa->load($privatekey);
|
||||
$rsa->load($rsa->getPublicKey());
|
||||
|
||||
$expected = '105b92f59a87a8ad4da52c128b8c99491790ef5a54770119e0819060032fb9e772ed6772828329567f3d7e9472154c1530f8156ba7fd732f52ca1c06' .
|
||||
'5a3f5ed8a96c442e4662e0464c97f133aed31262170201993085a589565d67cc9e727e0d087e3b225c8965203b271e38a499c92fc0d6502297eca712' .
|
||||
'4d04bd467f6f1e7c';
|
||||
$expected = pack('H*', $expected);
|
||||
$result = $rsa->encrypt($plaintext, RSA::PADDING_NONE);
|
||||
|
||||
$this->assertEquals($result, $expected);
|
||||
|
||||
$rsa->load($privatekey);
|
||||
$this->assertEquals(trim($rsa->decrypt($result, RSA::PADDING_NONE), "\0"), $plaintext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github768
|
||||
*/
|
||||
public function testPSSSigs()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$rsa->setHash('sha1');
|
||||
$rsa->setMGFHash('sha1');
|
||||
$rsa->load('-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVx
|
||||
wTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFnc
|
||||
CzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0T
|
||||
p0GbMJDyR4e9T04ZZwIDAQAB
|
||||
-----END PUBLIC KEY-----');
|
||||
|
||||
$sig = pack('H*', '1bd29a1d704a906cd7f726370ce1c63d8fb7b9a620871a05f3141a311c0d6e75fefb5d36dfb50d3ea2d37cd67992471419bfadd35da6e13b494' .
|
||||
'058ddc9b568d4cfea13ddc3c62b86a6256f5f296980d1131d3eaec6089069a3de79983f73eae20198a18721338b4a66e9cfe80e4f8e4fcef7a5bead5cbb' .
|
||||
'b8ac4c76adffbc178c');
|
||||
|
||||
$this->assertTrue($rsa->verify('zzzz', $sig));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OutOfBoundsException
|
||||
*/
|
||||
public function testSmallModulo()
|
||||
{
|
||||
$plaintext = 'x';
|
||||
$n = new BigInteger(base64_decode('272435F22706FA96DE26E980D22DFF67'), 256);
|
||||
$e = new BigInteger(base64_decode('158753FF2AF4D1E5BBAB574D5AE6B54D'), 256);
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load(array('n' => $n, 'e' => $e));
|
||||
$rsa->encrypt($plaintext);
|
||||
}
|
||||
|
||||
public function testPKCS1LooseVerify()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$rsa->load('-----BEGIN RSA PUBLIC KEY-----
|
||||
MIGJAoGBAMuqkz8ij+ESAaNvgocVGmapjlrIldmhRo4h2NX4e6IXiCLTSxASQtY4
|
||||
iqRnmyxqQSfaan2okTfQ6sP95bl8Qz8lgneW3ClC6RXG/wpJgsx7TXQ2kodlcKBF
|
||||
m4k72G75QXhZ+I40ZG7cjBf1/9egakR0a0X0MpeOrKCzMBLv9+mpAgMBAAE=
|
||||
-----END RSA PUBLIC KEY-----');
|
||||
|
||||
$message = base64_decode('MYIBLjAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNDA1MTUxNDM4MzRaMC8GCSqGSIb3DQEJBDEiBCBLzLIBGdOf0L2WRrIY' .
|
||||
'9KTwiHnReBW48S9C7LNRaPp5mDCBwgYLKoZIhvcNAQkQAi8xgbIwga8wgawwgakEIJDB9ZGwihf+TaiwrHQNkNHkqbN8Nuws0e77QNObkvFZMIGEMHCkbjBs' .
|
||||
'MQswCQYDVQQGEwJJVDEYMBYGA1UECgwPQXJ1YmFQRUMgUy5wLkEuMSEwHwYDVQQLDBhDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eUMxIDAeBgNVBAMMF0FydWJh' .
|
||||
'UEVDIFMucC5BLiBORyBDQSAzAhAv4L3QcFssQNLDYN/Vu40R');
|
||||
|
||||
$sig = base64_decode('XDSZWw6IcUj8ICxRJf04HzF8stzoiFAZSR2a0Rw3ziZxTOT0/NVUYJO5+9TaaREXEgxuCLpgmA+6W2SWrrGoxbbNfaI90ZoKeOAws4IX+9RfiWuooibjKcvt' .
|
||||
'GJYVVOCcjvQYxUUNbQ4EjCUonk3h7ECXfCCmWqbeq2LsyXeeYGE=');
|
||||
|
||||
$this->assertTrue($rsa->verify($message, $sig, RSA::PADDING_RELAXED_PKCS1));
|
||||
}
|
||||
|
||||
public function testZeroLengthSalt()
|
||||
{
|
||||
$plaintext = 'a';
|
||||
|
||||
$rsa = new RSA();
|
||||
|
||||
$privatekey = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$rsa->load($privatekey);
|
||||
$rsa->setSaltLength(0);
|
||||
$rsa->setHash('sha1');
|
||||
$rsa->setMGFHash('sha1');
|
||||
|
||||
// Check we generate the correct signature.
|
||||
$sig = pack('H*', '0ddfc93548e21d015c0a289a640b3b79aecfdfae045f583c5925b91cc5c399bba181616ad6ae20d9662d966f0eb2fddb550f4733268e34d640f4c9dadcaf25b3c82c42130a5081c6ebad7883331c65b25b6a37ffa7c4233a468dae56180787e2718ed87c48d8d50b72f5850e4a40963b4f36710be250ecef6fe0bb91249261a3');
|
||||
$this->assertEquals($sig, $rsa->sign($plaintext));
|
||||
|
||||
// Check we can verify the signature correctly.
|
||||
$rsa->load($rsa->getPublicKey());
|
||||
$this->assertTrue($rsa->verify($plaintext, $sig));
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\Random;
|
||||
|
||||
class Unit_Crypt_RandomTest extends PhpseclibTestCase
|
||||
{
|
||||
public function stringLengthData()
|
||||
{
|
||||
return array_map(array($this, 'wrap'), array(
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 17, 19, 20, 23, 29, 31, 37,
|
||||
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 111, 128, 1000,
|
||||
1024, 10000, 12345, 100000, 123456
|
||||
));
|
||||
}
|
||||
|
||||
/** @dataProvider stringLengthData */
|
||||
public function testStringLength($length)
|
||||
{
|
||||
$this->assertSame(
|
||||
$length,
|
||||
strlen(Random::string($length)),
|
||||
'Failed asserting that a string of expected length was generated.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a set of random values of length 128 bits and asserts all taken
|
||||
* values are unique.
|
||||
*/
|
||||
public function testStringUniqueness()
|
||||
{
|
||||
$values = array();
|
||||
for ($i = 0; $i < 10000; ++$i) {
|
||||
$rand = Random::string(16);
|
||||
$this->assertSame(16, strlen($rand));
|
||||
$this->assertArrayNotHasKey(
|
||||
$rand,
|
||||
$values,
|
||||
'Failed asserting that generated value does not exist in set.'
|
||||
);
|
||||
$values[$rand] = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function wrap($x)
|
||||
{
|
||||
// array() is not a function, but $this->wrap() is.
|
||||
return array($x);
|
||||
}
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
<?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();
|
||||
|
||||
foreach ($this->engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
|
||||
{
|
||||
$des = new TripleDES(TripleDES::MODE_CBC);
|
||||
if (!$des->isValidEngine($engine)) {
|
||||
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
||||
}
|
||||
$des->setPreferredEngine($engine);
|
||||
$des->setKey($key);
|
||||
$des->setIV(str_repeat("\0", $des->getBlockLength() >> 3));
|
||||
$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();
|
||||
|
||||
foreach ($engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineIVVectors
|
||||
*/
|
||||
public function testVectorsWithIV($engine, $engineName, $key, $iv, $plaintext, $expected)
|
||||
{
|
||||
$des = new TripleDES(TripleDES::MODE_CBC);
|
||||
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');
|
||||
$des->setIV(str_repeat("\0", $des->getBlockLength() >> 3));
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
<?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(Twofish::MODE_CBC);
|
||||
$tf->setIV(str_repeat("\0", $tf->getBlockLength() >> 3));
|
||||
$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");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?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\ANSI;
|
||||
|
||||
class Unit_File_ANSITest extends PhpseclibTestCase
|
||||
{
|
||||
public function testCase1()
|
||||
{
|
||||
$str = "\x1B[07m"; // turn reverse video on
|
||||
$str.= "aaaaaaaaaaaaaaaaaa";
|
||||
$str.= "\x1B[10D"; // move cursor left 10 lines
|
||||
$str.= "\x1B[m"; // reset everything
|
||||
$str.= "bbb";
|
||||
|
||||
$ansi = new ANSI();
|
||||
$ansi->appendString($str);
|
||||
|
||||
$expected = '<pre width="80" style="color: white; background: black">';
|
||||
$expected.= '<span style="color: black"><span style="background: white">aaaaaaaa</span></span>';
|
||||
$expected.= 'bbb';
|
||||
$expected.= '<span style="color: black"><span style="background: white">aaaaaaa</span></span>';
|
||||
$expected.= '</pre>';
|
||||
|
||||
$this->assertSame($ansi->getScreen(), $expected);
|
||||
}
|
||||
}
|
Binary file not shown.
@ -1,292 +0,0 @@
|
||||
<?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;
|
||||
|
||||
class Unit_File_ASN1Test extends PhpseclibTestCase
|
||||
{
|
||||
/**
|
||||
* on older versions of \phpseclib\File\ASN1 this would yield a PHP Warning
|
||||
* @group github275
|
||||
*/
|
||||
public function testAnyString()
|
||||
{
|
||||
$KDC_REP = array(
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'pvno' => array(
|
||||
'constant' => 0,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY),
|
||||
'msg-type' => array(
|
||||
'constant' => 1,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY),
|
||||
'padata' => array(
|
||||
'constant' => 2,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY),
|
||||
'crealm' => array(
|
||||
'constant' => 3,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY),
|
||||
'cname' => array(
|
||||
'constant' => 4,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY),
|
||||
'ticket' => array(
|
||||
'constant' => 5,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY),
|
||||
'enc-part' => array(
|
||||
'constant' => 6,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY)
|
||||
)
|
||||
);
|
||||
|
||||
$AS_REP = array(
|
||||
'class' => ASN1::CLASS_APPLICATION,
|
||||
'cast' => 11,
|
||||
'optional' => true,
|
||||
'explicit' => true
|
||||
) + $KDC_REP;
|
||||
|
||||
$str = 'a4IC3jCCAtqgAwIBBaEDAgELoi8wLTAroQMCAROiJAQiMCAwHqADAgEXoRcbFUNSRUFUVUlUWS5ORVR0ZXN0dXNlcqMPGw' .
|
||||
'1DUkVBVFVJVFkuTkVUpBUwE6ADAgEBoQwwChsIdGVzdHVzZXKlggFOYYIBSjCCAUagAwIBBaEPGw1DUkVBVFVJVFkuTkVU' .
|
||||
'oiIwIKADAgECoRkwFxsGa3JidGd0Gw1DUkVBVFVJVFkuTkVUo4IBCDCCAQSgAwIBF6EDAgEBooH3BIH0AQlxgm/j4z74Ki' .
|
||||
'GsJJnROhh8JAiN7pdvlnkxCYKdG6UgdfK/K0NZ+yz+Xg4kgFO1cQ4XYT4Fm3MTmOHzlFmbzlVkUqBI/RnWA9YTREC9Q7Mf' .
|
||||
'PPYfRxRG/C6FlahxHCOKj9GUj7bXg7Oq3Sm+QsKTS2bZT05biNf1s7tPCkdIOO0AAd7hvTCpTNAKl+OLN4cpA6pwwk5c3h' .
|
||||
'58Ce5/Uri5yBmrfwgkCD5AJUAI/WH56SEEvpifLc6C96w/7y2krAiZm5PyEO0HVhTzUjKGSHoSMb+Z3HI/ul+G9z0Z4qDu' .
|
||||
'NjvgP0jKdrKiwWN00NjpiQ0byZd4y6aCASEwggEdoAMCAReiggEUBIIBEHyi8DIbdcfw2DpniBJ3Sh8dDaEbQx+gWx3omC' .
|
||||
'TBEyts4sQGTwgQcqkWfeer8M+SkZs/GGZq2YYkyeF+9b6TxlYuX145NuB3KcyzaS7VNrX37E5nGgG8K6r5gTFOhLCqsjjv' .
|
||||
'gPXXqLeJo5D1nV+c8BPIEVsu/bbBPgSqpDwUs2mX1WkEg5vfb7kZMC8+LHiRy+sItvIiTtxxEsQ/GEF/ono3hZrEnDa/C+' .
|
||||
'4P3wep6uNMLnLzXJmUaAMaopjE+MOcai/t6T9Vg4pERF5Waqwg5ibAbVGK19HuS4LiKiaY3JsyYBuNkEDwiqM7i1Ekw3V+' .
|
||||
'+zoEIxqgXjGgPdrWkzU/H6rnXiqMtiZZqUXwWY0zkCmy';
|
||||
|
||||
$asn1 = new ASN1();
|
||||
$decoded = $asn1->decodeBER(base64_decode($str));
|
||||
$result = $asn1->asn1map($decoded[0], $AS_REP);
|
||||
|
||||
$this->assertInternalType('array', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* on older versions of \phpseclib\File\ASN1 this would produce a null instead of an array
|
||||
* @group github275
|
||||
*/
|
||||
public function testIncorrectString()
|
||||
{
|
||||
$PA_DATA = array(
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'padata-type' => array(
|
||||
'constant' => 1,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_INTEGER
|
||||
),
|
||||
'padata-value' => array(
|
||||
'constant' => 2,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_OCTET_STRING
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$PrincipalName = array(
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'name-type' => array(
|
||||
'constant' => 0,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_INTEGER
|
||||
),
|
||||
'name-string' => array(
|
||||
'constant' => 1,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'min' => 0,
|
||||
'max' => -1,
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => array('type' => ASN1::TYPE_IA5_STRING) // should be \phpseclib\File\ASN1::TYPE_GENERAL_STRING
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$Ticket = array(
|
||||
'class' => ASN1::CLASS_APPLICATION,
|
||||
'cast' => 1,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'tkt-vno' => array(
|
||||
'constant' => 0,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_INTEGER
|
||||
),
|
||||
'realm' => array(
|
||||
'constant' => 1,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY
|
||||
),
|
||||
'sname' => array(
|
||||
'constant' => 2,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY
|
||||
),
|
||||
'enc-part' => array(
|
||||
'constant' => 3,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$KDC_REP = array(
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'pvno' => array(
|
||||
'constant' => 0,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_INTEGER),
|
||||
'msg-type' => array(
|
||||
'constant' => 1,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_INTEGER),
|
||||
'padata' => array(
|
||||
'constant' => 2,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'min' => 0,
|
||||
'max' => -1,
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => $PA_DATA),
|
||||
'crealm' => array(
|
||||
'constant' => 3,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_OCTET_STRING),
|
||||
'cname' => array(
|
||||
'constant' => 4,
|
||||
'optional' => true,
|
||||
'explicit' => true) + $PrincipalName,
|
||||
//'type' => ASN1::TYPE_ANY),
|
||||
'ticket' => array(
|
||||
'constant' => 5,
|
||||
'optional' => true,
|
||||
'implicit' => true,
|
||||
'min' => 0,
|
||||
'max' => 1,
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => $Ticket),
|
||||
'enc-part' => array(
|
||||
'constant' => 6,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
'type' => ASN1::TYPE_ANY)
|
||||
)
|
||||
);
|
||||
|
||||
$AS_REP = array(
|
||||
'class' => ASN1::CLASS_APPLICATION,
|
||||
'cast' => 11,
|
||||
'optional' => true,
|
||||
'explicit' => true
|
||||
) + $KDC_REP;
|
||||
|
||||
$str = 'a4IC3jCCAtqgAwIBBaEDAgELoi8wLTAroQMCAROiJAQiMCAwHqADAgEXoRcbFUNSRUFUVUlUWS5ORVR0ZXN0dXNlcqMPGw' .
|
||||
'1DUkVBVFVJVFkuTkVUpBUwE6ADAgEBoQwwChsIdGVzdHVzZXKlggFOYYIBSjCCAUagAwIBBaEPGw1DUkVBVFVJVFkuTkVU' .
|
||||
'oiIwIKADAgECoRkwFxsGa3JidGd0Gw1DUkVBVFVJVFkuTkVUo4IBCDCCAQSgAwIBF6EDAgEBooH3BIH0AQlxgm/j4z74Ki' .
|
||||
'GsJJnROhh8JAiN7pdvlnkxCYKdG6UgdfK/K0NZ+yz+Xg4kgFO1cQ4XYT4Fm3MTmOHzlFmbzlVkUqBI/RnWA9YTREC9Q7Mf' .
|
||||
'PPYfRxRG/C6FlahxHCOKj9GUj7bXg7Oq3Sm+QsKTS2bZT05biNf1s7tPCkdIOO0AAd7hvTCpTNAKl+OLN4cpA6pwwk5c3h' .
|
||||
'58Ce5/Uri5yBmrfwgkCD5AJUAI/WH56SEEvpifLc6C96w/7y2krAiZm5PyEO0HVhTzUjKGSHoSMb+Z3HI/ul+G9z0Z4qDu' .
|
||||
'NjvgP0jKdrKiwWN00NjpiQ0byZd4y6aCASEwggEdoAMCAReiggEUBIIBEHyi8DIbdcfw2DpniBJ3Sh8dDaEbQx+gWx3omC' .
|
||||
'TBEyts4sQGTwgQcqkWfeer8M+SkZs/GGZq2YYkyeF+9b6TxlYuX145NuB3KcyzaS7VNrX37E5nGgG8K6r5gTFOhLCqsjjv' .
|
||||
'gPXXqLeJo5D1nV+c8BPIEVsu/bbBPgSqpDwUs2mX1WkEg5vfb7kZMC8+LHiRy+sItvIiTtxxEsQ/GEF/ono3hZrEnDa/C+' .
|
||||
'4P3wep6uNMLnLzXJmUaAMaopjE+MOcai/t6T9Vg4pERF5Waqwg5ibAbVGK19HuS4LiKiaY3JsyYBuNkEDwiqM7i1Ekw3V+' .
|
||||
'+zoEIxqgXjGgPdrWkzU/H6rnXiqMtiZZqUXwWY0zkCmy';
|
||||
|
||||
$asn1 = new ASN1();
|
||||
$decoded = $asn1->decodeBER(base64_decode($str));
|
||||
$result = $asn1->asn1map($decoded[0], $AS_REP);
|
||||
|
||||
$this->assertInternalType('array', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* older versions of ASN1 didn't handle indefinite length tags very well
|
||||
*/
|
||||
public function testIndefiniteLength()
|
||||
{
|
||||
$asn1 = new ASN1();
|
||||
$decoded = $asn1->decodeBER(file_get_contents(dirname(__FILE__) . '/ASN1/FE.pdf.p7m'));
|
||||
$this->assertCount(5, $decoded[0]['content'][1]['content'][0]['content']); // older versions would have returned 3
|
||||
}
|
||||
|
||||
public function testDefiniteLength()
|
||||
{
|
||||
// the following base64-encoded string is the X.509 cert from <http://phpseclib.sourceforge.net/x509/decoder.php>
|
||||
$str = 'MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM' .
|
||||
'MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg' .
|
||||
'THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x' .
|
||||
'MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh' .
|
||||
'MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw' .
|
||||
'FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC' .
|
||||
'gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy' .
|
||||
'wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B' .
|
||||
'd3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM' .
|
||||
'BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl' .
|
||||
'LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF' .
|
||||
'BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw' .
|
||||
'Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0' .
|
||||
'ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF' .
|
||||
'AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp' .
|
||||
'ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le' .
|
||||
'IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==';
|
||||
$asn1 = new ASN1();
|
||||
$decoded = $asn1->decodeBER(base64_decode($str));
|
||||
$this->assertCount(3, $decoded[0]['content']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github477
|
||||
*/
|
||||
public function testContextSpecificNonConstructed()
|
||||
{
|
||||
$asn1 = new ASN1();
|
||||
$decoded = $asn1->decodeBER(base64_decode('MBaAFJtUo7c00HsI5EPZ4bkICfkOY2Pv'));
|
||||
$this->assertInternalType('string', $decoded[0]['content'][0]['content']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github602
|
||||
*/
|
||||
public function testEmptyContextTag()
|
||||
{
|
||||
$asn1 = new ASN1();
|
||||
$decoded = $asn1->decodeBER("\xa0\x00");
|
||||
$this->assertInternalType('array', $decoded);
|
||||
$this->assertCount(0, $decoded[0]['content']);
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
<?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\X509;
|
||||
use phpseclib\Crypt\RSA;
|
||||
|
||||
class Unit_File_X509_CSRTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testLoadCSR()
|
||||
{
|
||||
$test = '-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIBWzCBxQIBADAeMRwwGgYDVQQKDBNwaHBzZWNsaWIgZGVtbyBjZXJ0MIGdMAsG
|
||||
CSqGSIb3DQEBAQOBjQAwgYkCgYEAtHDb4zoUyiRYsJ5PZrF/IJKAF9ZoHRpTxMA8
|
||||
a7iyFdsl/vvZLNPsNnFTXXnGdvsyFDEsF7AubaIXw8UKFPYqQRTzSVsvnNgIoVYj
|
||||
tTAXlB4oHipr7Kxcn4CXfmR0TYogyLvVZSZJYxh+CAuG4V9XM4HqkeE5gyBOsKGy
|
||||
5FUU8zMCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAJjdaA9K9DN5xvSiOlCmmV1E
|
||||
npzHkI1Trraveu0gtRjT/EzHoqjCBI0ekCZ9+fhrex8Sm6Nsq9IgHYyrqnE+PQko
|
||||
4Nf2w2U3DWxU26D5E9DlI+bLyOCq4jqATLjHyyAsOZY/2+U73AZ82MJM/mGdh5fQ
|
||||
v5RwaQHmQEzHofTzF7I+
|
||||
-----END CERTIFICATE REQUEST-----';
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$spkac = $x509->loadCSR($test);
|
||||
|
||||
$this->assertInternalType('array', $spkac);
|
||||
}
|
||||
|
||||
public function testCSRWithAttributes()
|
||||
{
|
||||
$test = '-----BEGIN NEW CERTIFICATE REQUEST-----
|
||||
MIIFGDCCAwACAQAwOjEWMBQGCgmSJomT8ixkARkWBnNlY3VyZTEgMB4GA1UEAxMX
|
||||
LlNlY3VyZSBFbnRlcnByaXNlIENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQCzgEpL+Za7a3y7YpURDrxlGIBlks25fD0tHaZIYkBTaXA5h+9MWoXn
|
||||
FA7AlIUt8pbBvXdJbOCmGaeQmBfBH0Qy9vTbx/DR2IOwzqy2ZHuurI5bPL12ceE2
|
||||
Mxa9xgY/i7U6MAUtoA3amEd7cKj2fz9EWZruRladOX0DXv9KexSan+45QjCWH+u2
|
||||
Cxem2zH9ZDNPGBuAF9YsAvkdHdAoX8aSm05ZAjUiO2e/+L57whh7zZiDY3WIhin7
|
||||
N/2JNTKVO6lx50S8a34XUKBt3SKgSR941hcLrBYUNftUYsTPo40bzKKcWqemiH+w
|
||||
jQiDrln4V2b5EbVeoGWe4UDPXCVmC6UPklG7iYfF0eeK4ujV8uc9PtV2LvGLOFdm
|
||||
AYE3+FAba5byQATw/DY8EJKQ7ptPigJhVe47NNeJlsKwk1haJ9k8ZazjS+vT45B5
|
||||
pqe0yBFAEon8TFnOLnAOblmKO12i0zqMUNAAlmr1c8jNjLr+dhruS+QropZmzZ24
|
||||
mAnFG+Y0qpfhMzAxTGQyVjyGwDfRK/ARmtrGpmROjj5+6VuMmZ6Ljf3xN09epmtH
|
||||
gJe+lYNBlpfUYg16tm+OusnziYnXL6nIo2ChOY/7GNJJif9fjvvaPDCC98K64av5
|
||||
5rpIx7N/XH4hwHeQQkEQangExE+8UMyBNFNmvPnIHVHUZdYo4SLsYwIDAQABoIGY
|
||||
MBsGCisGAQQBgjcNAgMxDRYLNi4zLjk2MDAuMi4weQYJKoZIhvcNAQkOMWwwajAQ
|
||||
BgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU5nEIMEUT5mMd1WepmviwgK7dIzww
|
||||
GQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB
|
||||
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAKZl6bAeaID3b/ic4aztL8ZZI7vi
|
||||
D3A9otUKx6v1Xe63zDPR+DiWSnxb9m+l8OPtnWkcLkzEIM/IMWorHKUAJ/J871D0
|
||||
Qx+0/HbkcrjMtVu/dNrtb9Z9CXup66ZvxTPcpEziq0/n2yw8QdBaa+lli65Qcwcy
|
||||
tzMQK6WQTRYfvVCIX9AKcPKxwx1DLH+7hL/bERB1lUDu59Jx6fQfqJrFVOY2N8c0
|
||||
MGvurfoHGmEoyCMIyvmIMu4+/wSNEE/sSDp4lZ6zuF6rf1m0GiLdTX2XJE+gfvep
|
||||
JTFmp4S3WFqkszKvaxBIT+jV0XKTNDwnO+dpExwU4jZUh18CdEFkIUuQb0gFF8B7
|
||||
WJFVpNdsRqZRPBz83BW1Kjo0yAmaoTrGNmG0p6Qf3K2zbk1+Jik3VZq4rvKoTi20
|
||||
6RvLA2//cMNfkYPsuqvoHGe2e0GOLtIB63wJzloWROpb72ohEHsvCKullIJVSuiS
|
||||
9sfTBAenHCyndgAEd4T3npTUdaiNumVEm5ilZId7LAYekJhkgFu3vlcl8blBJKjE
|
||||
skVTp7JpBmdXCL/G/6H2SFjca4JMOAy3DxwlGdgneIaXazHs5nBK/BgKPIyPzZ4w
|
||||
secxBTTCNgI48YezK3GDkn65cmlnkt6F6Mf0MwoDaXTuB88Jycbwb5ihKnHEJIsO
|
||||
draiRBZruwMPwPIP
|
||||
-----END NEW CERTIFICATE REQUEST-----';
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$csr = $x509->loadCSR($test);
|
||||
|
||||
$this->assertInternalType('array', $csr);
|
||||
}
|
||||
|
||||
public function testCSRDER()
|
||||
{
|
||||
$csr = 'MIICdzCCAV8CAQEwDDEKMAgGA1UEAwwBeDCCASIwDQYJKoZIhvcNAQEBBQADggEP' .
|
||||
'ADCCAQoCggEBALtcrFDD2AHe3x2bR00wPDsPH6FJLxr5uc1ybb+ldDB5xNVImC8P' .
|
||||
'LU6VXDZ5z68KjSovs1q0OWJWfCjlAuGLzqO35s86LI1CFuTFdkScVHMwh8zUVFoP' .
|
||||
'pG7/9rKaNxCgaHs4evxjxQP2+Ny7tBqPLb/KV0exm6Twocf963jC/Tyn57G5erRf' .
|
||||
'zpFrfK7DozhxY7znumJ4FuSn0TVkD6PPwZFn9VoTjv2ZoJmacGK+0r5yNKG799F5' .
|
||||
'K8EgDrOCfbzCZjX6GJctyn2SNPTeBuXS9piH21FGnJAryv80zG+zUqFdEyoLUGJt' .
|
||||
'4Vy6+tDP9cW68fiwTZS1Oc1VeFdL1G/CrjkCAwEAAaAmMCQGCSqGSIb3DQEJDjEX' .
|
||||
'MBUwEwYKKwYBBAGCqlsBCQQFMAOCAQEwDQYJKoZIhvcNAQELBQADggEBAF4XOd+1' .
|
||||
'jkJOYRInNpHfhzSD/ktDY50gpLPuDvl4f/ZBlKrb1eDYQG5F3bnYzoZWHN4n+6Zs' .
|
||||
'CkljXs5ZPUZ5LuVpASumoG/aHXGz8c8NC3asJ1V73ljEPAfIXwqoIUoaP9jLL+Ee' .
|
||||
'zy/ZCi2NKWVo2D7ocnn79oblAem9ksSeQl4z3Gvhuug6MsMqn96NU/ZY/vjYzAjb' .
|
||||
'MAvJIVRY0rbCxbFa0K+XNJtF7GLyBxyPNFWCvADhvm9C4uPmoypYg7MY6EewJInN' .
|
||||
'xzMH7I4xDLjNu0VBa6lAxTvflp0joQHKlTYX0SDIKPbQivjZMuObPuxDtkVZ0rQl' .
|
||||
'AjmgMowaN5otTXM=';
|
||||
$csr = base64_decode($csr);
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$csr = $x509->loadCSR($csr);
|
||||
|
||||
$this->assertInternalType('array', $csr);
|
||||
}
|
||||
|
||||
// on PHP 7.1, with older versions of phpseclib, this would produce a "A non-numeric value encountered" warning
|
||||
public function testNewCSR()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$x509 = new X509();
|
||||
|
||||
$rsa->load('-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----');
|
||||
$x509->setPrivateKey($rsa);
|
||||
$x509->setDN(array('cn' => 'website.com'));
|
||||
$x509->saveCSR($x509->signCSR('sha256WithRSAEncryption'), X509::FORMAT_DER);
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
<?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\X509;
|
||||
use phpseclib\Crypt\RSA;
|
||||
|
||||
class Unit_File_X509_SPKACTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testLoadSPKAC()
|
||||
{
|
||||
$test = 'MIICQDCCASgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChgo9mWzQm3TSwGgpZnIc54' .
|
||||
'TZ8gYpfAO/AI0etvyWDqnFfdNCUQsqxTdSi6/rtrJdLGBsszRGrRIc/0JqmjM+jCHGYutLeo4xwgr' .
|
||||
'a3HAZrWDypL5IlRWnLmLA4U/qGXCXNSk+9NrJl39X3IDA8o/aOJyr9iMUJMvswcWjVjPom3NhAgmJ' .
|
||||
'ZwW0vUEMw9zszExpiRnGSO5XXntQW2qvfzo+J3NzS3BBbKxEmTsfOLHextcXeFQUaBQHXB/WOtweW' .
|
||||
'Y/Bd4iZ8ETmhal28g1HWVcTFPD+V+KPRFeARlVEW6JmcJucW2WdJlBGKXXXPEfdHrDS3OgD/eDWfM' .
|
||||
'JE4mChZ/icxAgMBAAEWADANBgkqhkiG9w0BAQQFAAOCAQEAUMvIKhlSgEgbC081b/FJwh6mbuVgYN' .
|
||||
'ZV37Ts2WjrHoDFlabu9WXU8xzgaXct3sO51vJM5I36rY4UPyc6w3y9dLaamEwKUoWnpHG8mlXs2JG' .
|
||||
'GEUOvxh5z9yfk/2ZmdCVBlKnU1LDB+ZDyNyNh5B0YULrJKw9e0jV+ymP7srwUSBcdUfZh1KEKGVIN' .
|
||||
'Uv4J3GuL8V63E2unWCHGRPw4EmFVTbWpgMx96XR7p/pMavu6/pVKgYQqWLOmEeOK+dmT/QVon28d5' .
|
||||
'dmeL7aWrpP+3x3L0A9cATksracQX676XogdAEXJ59fcr/S5AGw1TFErbyBbfyeAWvzDZIXeMXpb9h' .
|
||||
'yNtA==';
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$spkac = $x509->loadSPKAC($test);
|
||||
|
||||
$this->assertInternalType('array', $spkac);
|
||||
|
||||
$spkac = $x509->loadSPKAC('SPKAC=' . $test);
|
||||
|
||||
$this->assertInternalType('array', $spkac);
|
||||
|
||||
$this->assertTrue(
|
||||
$x509->validateSignature(),
|
||||
'Failed asserting that the signature is valid'
|
||||
);
|
||||
|
||||
$pubKey = $x509->getPublicKey();
|
||||
|
||||
$this->assertInternalType('string', "$pubKey");
|
||||
}
|
||||
|
||||
public function testSaveSPKAC()
|
||||
{
|
||||
$privKey = new RSA();
|
||||
extract($privKey->createKey());
|
||||
|
||||
$x509 = new X509();
|
||||
$x509->setPrivateKey($privatekey);
|
||||
$x509->setChallenge('...');
|
||||
|
||||
$spkac = $x509->signSPKAC();
|
||||
$this->assertInternalType('array', $spkac);
|
||||
|
||||
$this->assertInternalType('string', $x509->saveSPKAC($spkac));
|
||||
|
||||
$x509 = new X509();
|
||||
$x509->setPrivateKey($privKey);
|
||||
|
||||
$spkac = $x509->signSPKAC();
|
||||
$this->assertInternalType('array', $spkac);
|
||||
|
||||
$this->assertInternalType('string', $x509->saveSPKAC($spkac));
|
||||
}
|
||||
|
||||
public function testBadSignatureSPKAC()
|
||||
{
|
||||
$test = 'MIICQDCCASgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChgo9mWzQm3TSwGgpZnIc54' .
|
||||
'TZ8gYpfAO/AI0etvyWDqnFfdNCUQsqxTdSi6/rtrJdLGBsszRGrRIc/0JqmjM+jCHGYutLeo4xwgr' .
|
||||
'a3HAZrWDypL5IlRWnLmLA4U/qGXCXNSk+9NrJl39X3IDA8o/aOJyr9iMUJMvswcWjVjPom3NhAgmJ' .
|
||||
'ZwW0vUEMw9zszExpiRnGSO5XXntQW2qvfzo+J3NzS3BBbKxEmTsfOLHextcXeFQUaBQHXB/WOtweW' .
|
||||
'Y/Bd4iZ8ETmhal28g1HWVcTFPD+V+KPRFeARlVEW6JmcJucW2WdJlBGKXXXPEfdHrDS3OgD/eDWfM' .
|
||||
'JE4mChZ/icxAgMBAAEWADANBgkqhkiG9w0BAQQFAAOCAQEAUMvIKhlSgEgbC081b/FJwh6mbuVgYN' .
|
||||
'ZV37Ts2WjrHoDFlabu9WXU8xzgaXct3sO51vJM5I36rY4UPyc6w3y9dLaamEwKUoWnpHG8mlXs2JG' .
|
||||
'GEUOvxh5z9yfk/2ZmdCVBlKnU1LDB+ZDyNyNh5B0YULrJKw9e0jV+ymP7srwUSBcdUfZh1KEKGVIN' .
|
||||
'Uv4J3GuL8V63E2unWCHGRPw4EmFVTbWpgMx96XR7p/pMavu6/pVKgYQqWLOmEeOK+dmT/QVon28d5' .
|
||||
'dmeL7aWrpP+3x3L0A9cATksracQX676XogdAEXJ59fcr/S5AGw1TFErbyBbfyeAWvzDZIXeMXpb9h' .
|
||||
'yNtA==';
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$spkac = $x509->loadSPKAC($test);
|
||||
|
||||
$spkac['publicKeyAndChallenge']['challenge'] = 'zzzz';
|
||||
|
||||
$x509->loadSPKAC($x509->saveSPKAC($spkac));
|
||||
|
||||
$this->assertFalse(
|
||||
$x509->validateSignature(),
|
||||
'Failed asserting that the signature is invalid'
|
||||
);
|
||||
}
|
||||
}
|
@ -1,457 +0,0 @@
|
||||
<?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;
|
||||
use phpseclib\Crypt\RSA;
|
||||
|
||||
class Unit_File_X509_X509Test extends PhpseclibTestCase
|
||||
{
|
||||
public function testExtensionMapping()
|
||||
{
|
||||
$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->assertInternalType('array', $cert['tbsCertificate']['extensions'][3]['extnValue']);
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github705
|
||||
*/
|
||||
public function testSaveNullRSAParam()
|
||||
{
|
||||
$privKey = new RSA();
|
||||
$privKey->load('-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDMswfEpAgnUDWA74zZw5XcPsWh1ly1Vk99tsqwoFDkLF7jvXy1
|
||||
dDLHYfuquvfxCgcp8k/4fQhx4ubR8bbGgEq9B05YRnViK0R0iBB5Ui4IaxWYYhKE
|
||||
8xqAEH2fL+/7nsqqNFKkEN9KeFwc7WbMY49U2adlMrpBdRjk1DqIEW3QTwIDAQAB
|
||||
AoGBAJ+83cT/1DUJjJcPWLTeweVbPtJp+3Ku5d1OdaGbmURVs764scbP5Ihe2AuF
|
||||
V9LLZoe/RdS9jYeB72nJ3D3PA4JVYYgqMOnJ8nlUMNQ+p0yGl5TqQk6EKLI8MbX5
|
||||
kQEazNqFXsiWVQXubAd5wjtb6g0n0KD3zoT/pWLES7dtUFexAkEA89h5+vbIIl2P
|
||||
H/NnkPie2NWYDZ1YiMGHFYxPDwsd9KCZMSbrLwAhPg9bPgqIeVNfpwxrzeksS6D9
|
||||
P98tJt335QJBANbnCe+LhDSrkpHMy9aOG2IdbLGG63MSRUCPz8v2gKPq3kYXDxq6
|
||||
Y1iqF8N5g0k5iirHD2qlWV5Q+nuGvFTafCMCQQC1wQiC0IkyXEw/Q31RqI82Dlcs
|
||||
5rhEDwQyQof3LZEhcsdcxKaOPOmKSYX4A3/f9w4YBIEiVQfoQ1Ig1qfgDZklAkAT
|
||||
TQDJcOBY0qgBTEFqbazr7PScJR/0X8m0eLYS/XqkPi3kYaHLpr3RcsVbmwg9hVtx
|
||||
aBtsWpliLSex/HHhtRW9AkBGcq67zKmEpJ9kXcYLEjJii3flFS+Ct/rNm+Hhm1l7
|
||||
4vca9v/F2hGVJuHIMJ8mguwYlNYzh2NqoIDJTtgOkBmt
|
||||
-----END RSA PRIVATE KEY-----');
|
||||
|
||||
$pubKey = new RSA();
|
||||
$pubKey->load($privKey->getPublicKey());
|
||||
$pubKey->setPublicKey();
|
||||
|
||||
$subject = new X509();
|
||||
$subject->setDNProp('id-at-organizationName', 'phpseclib demo cert');
|
||||
$subject->setPublicKey($pubKey);
|
||||
|
||||
$issuer = new X509();
|
||||
$issuer->setPrivateKey($privKey);
|
||||
$issuer->setDN($subject->getDN());
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$result = $x509->sign($issuer, $subject);
|
||||
$cert = $x509->saveX509($result);
|
||||
$cert = $x509->loadX509($cert);
|
||||
|
||||
$this->assertArrayHasKey('parameters', $cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']);
|
||||
$this->assertArrayHasKey('parameters', $cert['signatureAlgorithm']);
|
||||
$this->assertArrayHasKey('parameters', $cert['tbsCertificate']['signature']);
|
||||
}
|
||||
|
||||
private 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;
|
||||
}
|
||||
|
||||
public function testGetOID()
|
||||
{
|
||||
$x509 = new X509();
|
||||
$this->assertEquals($x509->getOID('2.16.840.1.101.3.4.2.1'), '2.16.840.1.101.3.4.2.1');
|
||||
$this->assertEquals($x509->getOID('id-sha256'), '2.16.840.1.101.3.4.2.1');
|
||||
$this->assertEquals($x509->getOID('zzz'), 'zzz');
|
||||
}
|
||||
|
||||
public function testIPAddressSubjectAltNamesDecoding()
|
||||
{
|
||||
$test = '-----BEGIN CERTIFICATE-----
|
||||
MIIEcTCCAlmgAwIBAgIBDjANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBQuU2Vj
|
||||
dXJlIElzc3VpbmcgQ0EgMTAeFw0xNjAxMjUyMzIwMjZaFw0yMTAxMjYyMzIwMjZa
|
||||
MBoxGDAWBgNVBAMMDzIwNC4xNTIuMjAwLjI1MDCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBAM9lMPiYQ26L5qXR1rlUXM0Z3DeRhDsJ/9NadLFJnvxKCV5L
|
||||
M9rlrThpK6V5VbgPgEwKVLXGtJoGSEUkLd4roJ25ZTH08GcYszWyp8nLPQRovYnN
|
||||
+aeE1aefnHcpt524f0Es9NFXh0uwRWV3ZCWSwN+mo9Qo6507KZq+q34if7/q9+De
|
||||
O5RJumVQWc9OCjCt6pQBnBua9oCAca+SIHftOdgWXqVw+Xvl6/dLeF70jJD43P00
|
||||
+bdAnGDgBdgO+p+K+XrOCaCWMcCsRX5xiK4hUG54UM5ayBST+McyfjsKxpO2djPg
|
||||
FlSL0RLg+Nj8WehANUUuaNU874Pp3FV5GTI0ZbUCAwEAAaOBvDCBuTAMBgNVHRMB
|
||||
Af8EAjAAMAsGA1UdDwQEAwIF4DATBgNVHSUEDDAKBggrBgEFBQcDATAhBgNVHREE
|
||||
GjAYhwTMmMj6hxAgAQRw8wkACQAAAAAAAAADMEMGA1UdHwQ8MDowOKA2oDSGMmh0
|
||||
dHA6Ly9jcmwuc2VjdXJlb2JzY3VyZS5jb20vP2FjdGlvbj1jcmwmY2E9aXNzdWUx
|
||||
MB8GA1UdIwQYMBaAFOJWVCX4poZSBzemgihf9dAhFNHJMA0GCSqGSIb3DQEBCwUA
|
||||
A4ICAQAce9whx4InRtzk1to6oeRxTCbeNDjNFuTkotphSws4hDoaz3nyFLSYyMT4
|
||||
aKFnNP9AmMS5nEXphtP4HP9wAluTcAFMuip0rDJjiRA/khIE27KurO6cg1faFWHl
|
||||
6lh6xnEf9UFZZzTLsXt2miBiMb8olgPrBuVFWjPZ/ConesJRZRFqMd5mfntXC+2V
|
||||
zRcXdtwp9h/Am/WuvjsG/gBAPdeRNKffCokIcgfvffd2oklSDD0T9baG2MTgaxnX
|
||||
oG6e5saWjoN8bLWuCJpvjA7aErXQwXUyXx1nrTWQ1TCR2N+M62X7e07jZLKSAECP
|
||||
v6SqZ9/LDmCacVQbfg4wDC/gbpjDSKaD5fkusH6leXleWQ7X8Z03LsKvVq43a71z
|
||||
jO61kkiFAh3CegWsY+TSYjZxDq58xGMiE7y/fK+SHQXDLyY7HU4eky2l3DSy8bXQ
|
||||
p64vTJ/OmAcXVNUASfBCNw0kpxuFjlxers/+6zheowB1RIKo0xvSRC4cEDRl/jFA
|
||||
b7WUT/MIe6B1r0v1gxHnFG2bFI/MhTT9V+tICOLo7+69z4jf/OFkzjYvqq2QWPgc
|
||||
sE3f2TNnmKFRJx67bEMoaaWLIR94Yuq/TWB6dTiWwk9meZkGG3OjQg/YbO6vl/Am
|
||||
NDEuGt30Vl2de7G1glnhaceB6Q9KfH7p2gAwNP9JMTtx3PtEcA==
|
||||
-----END CERTIFICATE-----';
|
||||
|
||||
$x509 = new X509();
|
||||
$cert = $x509->loadX509($test);
|
||||
$this->assertEquals($cert['tbsCertificate']['extensions'][3]['extnValue'][0]['iPAddress'], '204.152.200.250');
|
||||
$this->assertEquals($cert['tbsCertificate']['extensions'][3]['extnValue'][1]['iPAddress'], '2001:470:f309:9::3');
|
||||
}
|
||||
|
||||
public function testPostalAddress()
|
||||
{
|
||||
$x509 = new X509();
|
||||
$decoded = $x509->loadX509('-----BEGIN CERTIFICATE-----
|
||||
MIIFzzCCBLegAwIBAgIDAfdlMA0GCSqGSIb3DQEBBQUAMHMxCzAJBgNVBAYTAlBM
|
||||
MSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYD
|
||||
VQQDDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdw
|
||||
aXN1OiA2MB4XDTExMTEwOTA2MDAwMFoXDTEzMTEwOTA2MDAwMFowgdkxCzAJBgNV
|
||||
BAYTAlBMMRwwGgYDVQQKDBNVcnrEhWQgTWlhc3RhIEdkeW5pMRswGQYDVQQFExJQ
|
||||
RVNFTDogNjEwNjA2MDMxMTgxGTAXBgNVBAMMEEplcnp5IFByemV3b3Jza2kxTzBN
|
||||
BgNVBBAwRgwiQWwuIE1hcnN6YcWCa2EgUGnFgnN1ZHNraWVnbyA1Mi81NAwNODEt
|
||||
MzgyIEdkeW5pYQwGUG9sc2thDAlwb21vcnNraWUxDjAMBgNVBCoMBUplcnp5MRMw
|
||||
EQYDVQQEDApQcnpld29yc2tpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCM
|
||||
m5vjGqHPthJCMqKpqssSISRos0PYDTcEQzyyurfX67EJWKtZj6HNwuDMEGJ02iBN
|
||||
ZfjUl7r8dIi28bSKhNlsfycXZKYRcIjp0+r5RqtR2auo9GQ6veKb61DEAGIqaR+u
|
||||
LLcJVTHCu0w9oXLGbRlGth5eNoj03CxXVAH2IfhbNwIDAQABo4IChzCCAoMwDAYD
|
||||
VR0TAQH/BAIwADCCAUgGA1UdIAEB/wSCATwwggE4MIIBNAYJKoRoAYb3IwEBMIIB
|
||||
JTCB3QYIKwYBBQUHAgIwgdAMgc1EZWtsYXJhY2phIHRhIGplc3Qgb8Wbd2lhZGN6
|
||||
ZW5pZW0gd3lkYXdjeSwgxbxlIHRlbiBjZXJ0eWZpa2F0IHpvc3RhxYIgd3lkYW55
|
||||
IGpha28gY2VydHlmaWthdCBrd2FsaWZpa293YW55IHpnb2RuaWUgeiB3eW1hZ2Fu
|
||||
aWFtaSB1c3Rhd3kgbyBwb2RwaXNpZSBlbGVrdHJvbmljem55bSBvcmF6IHRvd2Fy
|
||||
enlzesSFY3ltaSBqZWogcm96cG9yesSFZHplbmlhbWkuMEMGCCsGAQUFBwIBFjdo
|
||||
dHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9wb2xpdHlr
|
||||
YS5odG1sMAkGA1UdCQQCMAAwIQYDVR0RBBowGIEWai5wcnpld29yc2tpQGdkeW5p
|
||||
YS5wbDAOBgNVHQ8BAf8EBAMCBkAwgZ4GA1UdIwSBljCBk4AU3TGldJXipN4oGS3Z
|
||||
YmnBDMFs8gKhd6R1MHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6
|
||||
YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt3
|
||||
YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2ggJb9jBIBgNVHR8EQTA/
|
||||
MD2gO6A5hjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6
|
||||
eS9DUkxfT1pLMzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBYPIqnAreyeql7/opJ
|
||||
jcar/qWZy9ruhB2q0lZFsJOhwgMnbQXzp/4vv93YJqcHGAXdHP6EO8FQX47mjo2Z
|
||||
KQmi+cIHJHLONdX/3Im+M17V0iNAh7Z1lOSfTRT+iiwe/F8phcEaD5q2RmvYusR7
|
||||
zXZq/cLL0If0hXoPZ/EHQxjN8pxzxiUx6bJAgturnIMEfRNesxwghdr1dkUjOhGL
|
||||
f3kHVzgM6j3VAM7oFmMUb5y5s96Bzl10DodWitjOEH0vvnIcsppSxH1C1dCAi0o9
|
||||
f/1y2XuLNhBNHMAyTqpYPX8Yvav1c+Z50OMaSXHAnTa20zv8UtiHbaAhwlifCelU
|
||||
Mj93S
|
||||
-----END CERTIFICATE-----');
|
||||
$x509->loadX509($x509->saveX509($decoded));
|
||||
$expected = array(
|
||||
array(
|
||||
array('utf8String' => "Al. Marsza\xC5\x82ka Pi\xC5\x82sudskiego 52/54"),
|
||||
array('utf8String' => '81-382 Gdynia'),
|
||||
array('utf8String' => 'Polska'),
|
||||
array('utf8String' => 'pomorskie')
|
||||
)
|
||||
);
|
||||
$this->assertEquals($x509->getDNProp('id-at-postalAddress'), $expected);
|
||||
|
||||
$expected = "C=PL, O=Urz\xC4\x85d Miasta Gdyni/serialNumber=PESEL: 61060603118, CN=Jerzy Przeworski/postalAddress=" . '0F\X0C"AL. MARSZA\XC5\X82KA PI\XC5\X82SUDSKIEGO 52/54\X0C\X0D81-382 GDYNIA\X0C\X06POLSKA\X0C\X09POMORSKIE/givenName=Jerzy, SN=Przeworski';
|
||||
$this->assertEquals($x509->getDN(X509::DN_STRING), $expected);
|
||||
}
|
||||
|
||||
public function testStrictComparison()
|
||||
{
|
||||
$x509 = new X509();
|
||||
$x509->loadCA('-----BEGIN CERTIFICATE-----
|
||||
MIIEbDCCA1SgAwIBAgIUJguKOMpJm/yRMDlMOW04NV0YPXowDQYJKoZIhvcNAQEF
|
||||
BQAwYTELMAkGA1UEBhMCUEwxNzA1BgNVBAoTLkNaaUMgQ2VudHJhc3QgU0EgdyBp
|
||||
bWllbml1IE1pbmlzdHJhIEdvc3BvZGFya2kxGTAXBgNVBAMTEENaaUMgQ2VudHJh
|
||||
c3QgU0EwHhcNMDkwNDI5MTE1MzIxWhcNMTMxMjEzMjM1OTU5WjBzMQswCQYDVQQG
|
||||
EwJQTDEoMCYGA1UEChMfS3Jham93YSBJemJhIFJvemxpY3plbmlvd2EgUy5BLjEk
|
||||
MCIGA1UEAxMbQ09QRSBTWkFGSVIgLSBLd2FsaWZpa293YW55MRQwEgYDVQQFEwtO
|
||||
ciB3cGlzdTogNjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIjNy3EL
|
||||
oK0uKTqAJokiP8VIxER/0OfwhY4DBhJGW38W6Pfema8iUs4net0NgoIeDpMQ8IHj
|
||||
FDSKkSaRkyL5f7PgvqBwzKe0HD1Duf9G/Lr2lu/J4QUMF3rqKaMRipXKkkEoKrub
|
||||
Qe41/mPiPXeClNswNQUEyInqWpfWNncU8AIs2GKIFTfSNqK4PgWOY1kG9MYfoNVr
|
||||
74dhejv7yHexEw9eAIcM1fIkEEq0vWIOjRtBXBAuWtUyD8iSeBs4nIN+614pHIjv
|
||||
ncHxG7xTDbmOAVZFgGZ8Hk5CUseAtTpazQNdU66XRUuCj4km01L4wsfZ1X8tfYQA
|
||||
6msMRYj+F7hLtoECAwEAAaOCAQgwggEEMA8GA1UdEwEB/wQFMAMBAf8wgY4GA1Ud
|
||||
IwSBhjCBg4AU2a7r85Cp1iJNW0Ca1LR6VG3996ShZaRjMGExCzAJBgNVBAYTAlBM
|
||||
MTcwNQYDVQQKEy5DWmlDIENlbnRyYXN0IFNBIHcgaW1pZW5pdSBNaW5pc3RyYSBH
|
||||
b3Nwb2RhcmtpMRkwFwYDVQQDExBDWmlDIENlbnRyYXN0IFNBggQ9/0sQMDEGA1Ud
|
||||
IAEB/wQnMCUwIwYEVR0gADAbMBkGCCsGAQUFBwIBFg13d3cubmNjZXJ0LnBsMA4G
|
||||
A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU3TGldJXipN4oGS3ZYmnBDMFs8gIwDQYJ
|
||||
KoZIhvcNAQEFBQADggEBAJrkn3XycfimT5C6D+lYvQNB4/X44KZRhxhnplMOdr/V
|
||||
3O13oJA/G2SkVaRZS1Rqy01vC9H3YSFfYnjFXJTOXldzodwszHEcGLHF/3JazHI9
|
||||
BTpP1F4oFyd0Un/wkp1usGU4e1riU5RAlSp8YcMX3q+nOqyCh0JsxnP7LjauHkE3
|
||||
KZ1RuBDZYbsYOwkAKjHax8srKugdWtq4sMNcqpxGFUah/4uLQn6hD4jeRpP4VGDv
|
||||
HZDmxaIoJdmCxfn9XeIS5PcZR+mHHkUOIhYLnfdUp/T3Yxxo+XrrTckC6AjtsL5/
|
||||
OA0vBLngVqqeuzVf0tUhcrCwPKQo5rKoakbApeXrows=
|
||||
-----END CERTIFICATE-----');
|
||||
|
||||
$x509->loadX509('-----BEGIN CERTIFICATE-----
|
||||
MIIFzzCCBLegAwIBAgIDAfdlMA0GCSqGSIb3DQEBBQUAMHMxCzAJBgNVBAYTAlBM
|
||||
MSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYD
|
||||
VQQDDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdw
|
||||
aXN1OiA2MB4XDTExMTEwOTA2MDAwMFoXDTEzMTEwOTA2MDAwMFowgdkxCzAJBgNV
|
||||
BAYTAlBMMRwwGgYDVQQKDBNVcnrEhWQgTWlhc3RhIEdkeW5pMRswGQYDVQQFExJQ
|
||||
RVNFTDogNjEwNjA2MDMxMTgxGTAXBgNVBAMMEEplcnp5IFByemV3b3Jza2kxTzBN
|
||||
BgNVBBAwRgwiQWwuIE1hcnN6YcWCa2EgUGnFgnN1ZHNraWVnbyA1Mi81NAwNODEt
|
||||
MzgyIEdkeW5pYQwGUG9sc2thDAlwb21vcnNraWUxDjAMBgNVBCoMBUplcnp5MRMw
|
||||
EQYDVQQEDApQcnpld29yc2tpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCM
|
||||
m5vjGqHPthJCMqKpqssSISRos0PYDTcEQzyyurfX67EJWKtZj6HNwuDMEGJ02iBN
|
||||
ZfjUl7r8dIi28bSKhNlsfycXZKYRcIjp0+r5RqtR2auo9GQ6veKb61DEAGIqaR+u
|
||||
LLcJVTHCu0w9oXLGbRlGth5eNoj03CxXVAH2IfhbNwIDAQABo4IChzCCAoMwDAYD
|
||||
VR0TAQH/BAIwADCCAUgGA1UdIAEB/wSCATwwggE4MIIBNAYJKoRoAYb3IwEBMIIB
|
||||
JTCB3QYIKwYBBQUHAgIwgdAMgc1EZWtsYXJhY2phIHRhIGplc3Qgb8Wbd2lhZGN6
|
||||
ZW5pZW0gd3lkYXdjeSwgxbxlIHRlbiBjZXJ0eWZpa2F0IHpvc3RhxYIgd3lkYW55
|
||||
IGpha28gY2VydHlmaWthdCBrd2FsaWZpa293YW55IHpnb2RuaWUgeiB3eW1hZ2Fu
|
||||
aWFtaSB1c3Rhd3kgbyBwb2RwaXNpZSBlbGVrdHJvbmljem55bSBvcmF6IHRvd2Fy
|
||||
enlzesSFY3ltaSBqZWogcm96cG9yesSFZHplbmlhbWkuMEMGCCsGAQUFBwIBFjdo
|
||||
dHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9wb2xpdHlr
|
||||
YS5odG1sMAkGA1UdCQQCMAAwIQYDVR0RBBowGIEWai5wcnpld29yc2tpQGdkeW5p
|
||||
YS5wbDAOBgNVHQ8BAf8EBAMCBkAwgZ4GA1UdIwSBljCBk4AU3TGldJXipN4oGS3Z
|
||||
YmnBDMFs8gKhd6R1MHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6
|
||||
YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt3
|
||||
YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2ggJb9jBIBgNVHR8EQTA/
|
||||
MD2gO6A5hjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6
|
||||
eS9DUkxfT1pLMzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBYPIqnAreyeql7/opJ
|
||||
jcar/qWZy9ruhB2q0lZFsJOhwgMnbQXzp/4vv93YJqcHGAXdHP6EO8FQX47mjo2Z
|
||||
KQmi+cIHJHLONdX/3Im+M17V0iNAh7Z1lOSfTRT+iiwe/F8phcEaD5q2RmvYusR7
|
||||
zXZq/cLL0If0hXoPZ/EHQxjN8pxzxiUx6bJAgturnIMEfRNesxwghdr1dkUjOhGL
|
||||
f3kHVzgM6j3VAM7oFmMUb5y5s96Bzl10DodWitjOEH0vvnIcsppSxH1C1dCAi0o9
|
||||
f/1y2XuLNhBNHMAyTqpYPX8Yvav1c+Z50OMaSXHAnTa20zv8UtiHbaAhwlifCelU
|
||||
Mj93S
|
||||
-----END CERTIFICATE-----');
|
||||
$this->assertFalse($x509->validateSignature());
|
||||
}
|
||||
|
||||
public function testLooseComparison()
|
||||
{
|
||||
if (!extension_loaded('runkit')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
define('FILE_X509_IGNORE_TYPE', true);
|
||||
|
||||
$x509 = new X509();
|
||||
$x509->loadCA('-----BEGIN CERTIFICATE-----
|
||||
MIIEbDCCA1SgAwIBAgIUJguKOMpJm/yRMDlMOW04NV0YPXowDQYJKoZIhvcNAQEF
|
||||
BQAwYTELMAkGA1UEBhMCUEwxNzA1BgNVBAoTLkNaaUMgQ2VudHJhc3QgU0EgdyBp
|
||||
bWllbml1IE1pbmlzdHJhIEdvc3BvZGFya2kxGTAXBgNVBAMTEENaaUMgQ2VudHJh
|
||||
c3QgU0EwHhcNMDkwNDI5MTE1MzIxWhcNMTMxMjEzMjM1OTU5WjBzMQswCQYDVQQG
|
||||
EwJQTDEoMCYGA1UEChMfS3Jham93YSBJemJhIFJvemxpY3plbmlvd2EgUy5BLjEk
|
||||
MCIGA1UEAxMbQ09QRSBTWkFGSVIgLSBLd2FsaWZpa293YW55MRQwEgYDVQQFEwtO
|
||||
ciB3cGlzdTogNjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIjNy3EL
|
||||
oK0uKTqAJokiP8VIxER/0OfwhY4DBhJGW38W6Pfema8iUs4net0NgoIeDpMQ8IHj
|
||||
FDSKkSaRkyL5f7PgvqBwzKe0HD1Duf9G/Lr2lu/J4QUMF3rqKaMRipXKkkEoKrub
|
||||
Qe41/mPiPXeClNswNQUEyInqWpfWNncU8AIs2GKIFTfSNqK4PgWOY1kG9MYfoNVr
|
||||
74dhejv7yHexEw9eAIcM1fIkEEq0vWIOjRtBXBAuWtUyD8iSeBs4nIN+614pHIjv
|
||||
ncHxG7xTDbmOAVZFgGZ8Hk5CUseAtTpazQNdU66XRUuCj4km01L4wsfZ1X8tfYQA
|
||||
6msMRYj+F7hLtoECAwEAAaOCAQgwggEEMA8GA1UdEwEB/wQFMAMBAf8wgY4GA1Ud
|
||||
IwSBhjCBg4AU2a7r85Cp1iJNW0Ca1LR6VG3996ShZaRjMGExCzAJBgNVBAYTAlBM
|
||||
MTcwNQYDVQQKEy5DWmlDIENlbnRyYXN0IFNBIHcgaW1pZW5pdSBNaW5pc3RyYSBH
|
||||
b3Nwb2RhcmtpMRkwFwYDVQQDExBDWmlDIENlbnRyYXN0IFNBggQ9/0sQMDEGA1Ud
|
||||
IAEB/wQnMCUwIwYEVR0gADAbMBkGCCsGAQUFBwIBFg13d3cubmNjZXJ0LnBsMA4G
|
||||
A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU3TGldJXipN4oGS3ZYmnBDMFs8gIwDQYJ
|
||||
KoZIhvcNAQEFBQADggEBAJrkn3XycfimT5C6D+lYvQNB4/X44KZRhxhnplMOdr/V
|
||||
3O13oJA/G2SkVaRZS1Rqy01vC9H3YSFfYnjFXJTOXldzodwszHEcGLHF/3JazHI9
|
||||
BTpP1F4oFyd0Un/wkp1usGU4e1riU5RAlSp8YcMX3q+nOqyCh0JsxnP7LjauHkE3
|
||||
KZ1RuBDZYbsYOwkAKjHax8srKugdWtq4sMNcqpxGFUah/4uLQn6hD4jeRpP4VGDv
|
||||
HZDmxaIoJdmCxfn9XeIS5PcZR+mHHkUOIhYLnfdUp/T3Yxxo+XrrTckC6AjtsL5/
|
||||
OA0vBLngVqqeuzVf0tUhcrCwPKQo5rKoakbApeXrows=
|
||||
-----END CERTIFICATE-----');
|
||||
|
||||
$x509->loadX509('-----BEGIN CERTIFICATE-----
|
||||
MIIFzzCCBLegAwIBAgIDAfdlMA0GCSqGSIb3DQEBBQUAMHMxCzAJBgNVBAYTAlBM
|
||||
MSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYD
|
||||
VQQDDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdw
|
||||
aXN1OiA2MB4XDTExMTEwOTA2MDAwMFoXDTEzMTEwOTA2MDAwMFowgdkxCzAJBgNV
|
||||
BAYTAlBMMRwwGgYDVQQKDBNVcnrEhWQgTWlhc3RhIEdkeW5pMRswGQYDVQQFExJQ
|
||||
RVNFTDogNjEwNjA2MDMxMTgxGTAXBgNVBAMMEEplcnp5IFByemV3b3Jza2kxTzBN
|
||||
BgNVBBAwRgwiQWwuIE1hcnN6YcWCa2EgUGnFgnN1ZHNraWVnbyA1Mi81NAwNODEt
|
||||
MzgyIEdkeW5pYQwGUG9sc2thDAlwb21vcnNraWUxDjAMBgNVBCoMBUplcnp5MRMw
|
||||
EQYDVQQEDApQcnpld29yc2tpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCM
|
||||
m5vjGqHPthJCMqKpqssSISRos0PYDTcEQzyyurfX67EJWKtZj6HNwuDMEGJ02iBN
|
||||
ZfjUl7r8dIi28bSKhNlsfycXZKYRcIjp0+r5RqtR2auo9GQ6veKb61DEAGIqaR+u
|
||||
LLcJVTHCu0w9oXLGbRlGth5eNoj03CxXVAH2IfhbNwIDAQABo4IChzCCAoMwDAYD
|
||||
VR0TAQH/BAIwADCCAUgGA1UdIAEB/wSCATwwggE4MIIBNAYJKoRoAYb3IwEBMIIB
|
||||
JTCB3QYIKwYBBQUHAgIwgdAMgc1EZWtsYXJhY2phIHRhIGplc3Qgb8Wbd2lhZGN6
|
||||
ZW5pZW0gd3lkYXdjeSwgxbxlIHRlbiBjZXJ0eWZpa2F0IHpvc3RhxYIgd3lkYW55
|
||||
IGpha28gY2VydHlmaWthdCBrd2FsaWZpa293YW55IHpnb2RuaWUgeiB3eW1hZ2Fu
|
||||
aWFtaSB1c3Rhd3kgbyBwb2RwaXNpZSBlbGVrdHJvbmljem55bSBvcmF6IHRvd2Fy
|
||||
enlzesSFY3ltaSBqZWogcm96cG9yesSFZHplbmlhbWkuMEMGCCsGAQUFBwIBFjdo
|
||||
dHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9wb2xpdHlr
|
||||
YS5odG1sMAkGA1UdCQQCMAAwIQYDVR0RBBowGIEWai5wcnpld29yc2tpQGdkeW5p
|
||||
YS5wbDAOBgNVHQ8BAf8EBAMCBkAwgZ4GA1UdIwSBljCBk4AU3TGldJXipN4oGS3Z
|
||||
YmnBDMFs8gKhd6R1MHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6
|
||||
YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt3
|
||||
YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2ggJb9jBIBgNVHR8EQTA/
|
||||
MD2gO6A5hjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6
|
||||
eS9DUkxfT1pLMzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBYPIqnAreyeql7/opJ
|
||||
jcar/qWZy9ruhB2q0lZFsJOhwgMnbQXzp/4vv93YJqcHGAXdHP6EO8FQX47mjo2Z
|
||||
KQmi+cIHJHLONdX/3Im+M17V0iNAh7Z1lOSfTRT+iiwe/F8phcEaD5q2RmvYusR7
|
||||
zXZq/cLL0If0hXoPZ/EHQxjN8pxzxiUx6bJAgturnIMEfRNesxwghdr1dkUjOhGL
|
||||
f3kHVzgM6j3VAM7oFmMUb5y5s96Bzl10DodWitjOEH0vvnIcsppSxH1C1dCAi0o9
|
||||
f/1y2XuLNhBNHMAyTqpYPX8Yvav1c+Z50OMaSXHAnTa20zv8UtiHbaAhwlifCelU
|
||||
Mj93S
|
||||
-----END CERTIFICATE-----');
|
||||
$this->assertTrue($x509->validateSignature());
|
||||
|
||||
runkit_constant_remove('FILE_X509_IGNORE_TYPE');
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2013 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
class Unit_Math_BigInteger_BCMathTest extends Unit_Math_BigInteger_TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!extension_loaded('bcmath')) {
|
||||
self::markTestSkipped('BCMath extension is not available.');
|
||||
}
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::ensureConstant('MATH_BIGINTEGER_MODE', \phpseclib\Math\BigInteger::MODE_BCMATH);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2013 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
class Unit_Math_BigInteger_GMPTest extends Unit_Math_BigInteger_TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!extension_loaded('gmp')) {
|
||||
self::markTestSkipped('GNU Multiple Precision (GMP) extension is not available.');
|
||||
}
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::ensureConstant('MATH_BIGINTEGER_MODE', \phpseclib\Math\BigInteger::MODE_GMP);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2013 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
class Unit_Math_BigInteger_InternalOpenSSLTest extends Unit_Math_BigInteger_TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!extension_loaded('openssl')) {
|
||||
self::markTestSkipped('openssl_public_encrypt() function is not available.');
|
||||
}
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::ensureConstant('MATH_BIGINTEGER_MODE', \phpseclib\Math\BigInteger::MODE_INTERNAL);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2013 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
class Unit_Math_BigInteger_InternalTest extends Unit_Math_BigInteger_TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::ensureConstant('MATH_BIGINTEGER_MODE', \phpseclib\Math\BigInteger::MODE_INTERNAL);
|
||||
self::ensureConstant('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
|
||||
}
|
||||
|
||||
public function testInternalRepresentation()
|
||||
{
|
||||
$x = new \phpseclib\Math\BigInteger('FFFFFFFFFFFFFFFFC90FDA', 16);
|
||||
$y = new \phpseclib\Math\BigInteger("$x");
|
||||
$this->assertSame($x->value, $y->value);
|
||||
}
|
||||
}
|
@ -1,484 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2012 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
self::reRequireFile('Math/BigInteger.php');
|
||||
}
|
||||
|
||||
public function getInstance($x = 0, $base = 10)
|
||||
{
|
||||
return new \phpseclib\Math\BigInteger($x, $base);
|
||||
}
|
||||
|
||||
public function testConstructorBase2()
|
||||
{
|
||||
// 2**65 = 36893488147419103232
|
||||
$this->assertSame('36893488147419103232', (string) $this->getInstance('1' . str_repeat('0', 65), 2));
|
||||
}
|
||||
|
||||
public function testConstructorBase10()
|
||||
{
|
||||
$this->assertSame('18446744073709551616', (string) $this->getInstance('18446744073709551616'));
|
||||
}
|
||||
|
||||
public function testConstructorBase16()
|
||||
{
|
||||
$this->assertSame('50', (string) $this->getInstance('0x32', 16));
|
||||
$this->assertSame('12345678910', (string) $this->getInstance('0x2DFDC1C3E', 16));
|
||||
$this->assertSame('18446744073709551615', (string) $this->getInstance('0xFFFFFFFFFFFFFFFF', 16));
|
||||
$this->assertSame('18446744073709551616', (string) $this->getInstance('0x10000000000000000', 16));
|
||||
}
|
||||
|
||||
public function testToBytes()
|
||||
{
|
||||
$this->assertSame(chr(65), $this->getInstance('65')->toBytes());
|
||||
}
|
||||
|
||||
public function testToBytesTwosCompliment()
|
||||
{
|
||||
$this->assertSame(chr(126), $this->getInstance('01111110', 2)->toBytes(true));
|
||||
}
|
||||
|
||||
public function testToHex()
|
||||
{
|
||||
$this->assertSame('41', $this->getInstance('65')->toHex());
|
||||
}
|
||||
|
||||
public function testToBits()
|
||||
{
|
||||
$this->assertSame('1000001', $this->getInstance('65')->toBits());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$x = $this->getInstance('18446744073709551615');
|
||||
$y = $this->getInstance('100000000000');
|
||||
|
||||
$a = $x->add($y);
|
||||
$b = $y->add($x);
|
||||
|
||||
$this->assertTrue($a->equals($b));
|
||||
$this->assertTrue($b->equals($a));
|
||||
|
||||
$this->assertSame('18446744173709551615', (string) $a);
|
||||
$this->assertSame('18446744173709551615', (string) $b);
|
||||
}
|
||||
|
||||
public function testSubtract()
|
||||
{
|
||||
$x = $this->getInstance('18446744073709551618');
|
||||
$y = $this->getInstance('4000000000000');
|
||||
$this->assertSame('18446740073709551618', (string) $x->subtract($y));
|
||||
}
|
||||
|
||||
public function testMultiply()
|
||||
{
|
||||
$x = $this->getInstance('8589934592'); // 2**33
|
||||
$y = $this->getInstance('36893488147419103232'); // 2**65
|
||||
|
||||
$a = $x->multiply($y); // 2**98
|
||||
$b = $y->multiply($x); // 2**98
|
||||
|
||||
$this->assertTrue($a->equals($b));
|
||||
$this->assertTrue($b->equals($a));
|
||||
|
||||
$this->assertSame('316912650057057350374175801344', (string) $a);
|
||||
$this->assertSame('316912650057057350374175801344', (string) $b);
|
||||
}
|
||||
|
||||
public function testDivide()
|
||||
{
|
||||
$x = $this->getInstance('1180591620717411303425'); // 2**70 + 1
|
||||
$y = $this->getInstance('12345678910');
|
||||
|
||||
list($q, $r) = $x->divide($y);
|
||||
|
||||
$this->assertSame('95627922070', (string) $q);
|
||||
$this->assertSame('10688759725', (string) $r);
|
||||
}
|
||||
|
||||
public function testModPow()
|
||||
{
|
||||
$a = $this->getInstance('10');
|
||||
$b = $this->getInstance('20');
|
||||
$c = $this->getInstance('30');
|
||||
$d = $a->modPow($b, $c);
|
||||
|
||||
$this->assertSame('10', (string) $d);
|
||||
}
|
||||
|
||||
public function testModInverse()
|
||||
{
|
||||
$a = $this->getInstance(30);
|
||||
$b = $this->getInstance(17);
|
||||
|
||||
$c = $a->modInverse($b);
|
||||
$this->assertSame('4', (string) $c);
|
||||
|
||||
$d = $a->multiply($c);
|
||||
list($q, $r) = $d->divide($b);
|
||||
$this->assertSame('1', (string) $r);
|
||||
}
|
||||
|
||||
public function testExtendedGCD()
|
||||
{
|
||||
$a = $this->getInstance(693);
|
||||
$b = $this->getInstance(609);
|
||||
|
||||
$arr = $a->extendedGCD($b);
|
||||
|
||||
$this->assertSame('21', (string) $arr['gcd']);
|
||||
$this->assertSame(21, $a->toString() * $arr['x']->toString() + $b->toString() * $arr['y']->toString());
|
||||
}
|
||||
|
||||
public function testGCD()
|
||||
{
|
||||
$x = $this->getInstance(693);
|
||||
$y = $this->getInstance(609);
|
||||
$this->assertSame('21', (string) $x->gcd($y));
|
||||
}
|
||||
|
||||
public function testAbs()
|
||||
{
|
||||
$x = $this->getInstance('-18446744073709551617');
|
||||
$y = $x->abs();
|
||||
|
||||
$this->assertSame('-18446744073709551617', (string) $x);
|
||||
$this->assertSame('18446744073709551617', (string) $y);
|
||||
}
|
||||
|
||||
public function testEquals()
|
||||
{
|
||||
$x = $this->getInstance('18446744073709551616');
|
||||
$y = $this->getInstance('18446744073709551616');
|
||||
|
||||
$this->assertTrue($x->equals($y));
|
||||
$this->assertTrue($y->equals($x));
|
||||
}
|
||||
|
||||
public function testCompare()
|
||||
{
|
||||
$a = $this->getInstance('-18446744073709551616');
|
||||
$b = $this->getInstance('36893488147419103232');
|
||||
$c = $this->getInstance('36893488147419103232');
|
||||
$d = $this->getInstance('316912650057057350374175801344');
|
||||
|
||||
// a < b
|
||||
$this->assertLessThan(0, $a->compare($b));
|
||||
$this->assertGreaterThan(0, $b->compare($a));
|
||||
|
||||
// b = c
|
||||
$this->assertSame(0, $b->compare($c));
|
||||
$this->assertSame(0, $c->compare($b));
|
||||
|
||||
// c < d
|
||||
$this->assertLessThan(0, $c->compare($d));
|
||||
$this->assertGreaterThan(0, $d->compare($c));
|
||||
}
|
||||
|
||||
public function testBitwiseAND()
|
||||
{
|
||||
$x = $this->getInstance('66666666666666666666666', 16);
|
||||
$y = $this->getInstance('33333333333333333333333', 16);
|
||||
$z = $this->getInstance('22222222222222222222222', 16);
|
||||
|
||||
$this->assertSame($z->toHex(), $x->bitwise_AND($y)->toHex());
|
||||
}
|
||||
|
||||
public function testBitwiseOR()
|
||||
{
|
||||
$x = $this->getInstance('11111111111111111111111', 16);
|
||||
$y = $this->getInstance('EEEEEEEEEEEEEEEEEEEEEEE', 16);
|
||||
$z = $this->getInstance('FFFFFFFFFFFFFFFFFFFFFFF', 16);
|
||||
|
||||
$this->assertSame($z->toHex(), $x->bitwise_OR($y)->toHex());
|
||||
}
|
||||
|
||||
public function testBitwiseXOR()
|
||||
{
|
||||
$x = $this->getInstance('AFAFAFAFAFAFAFAFAFAFAFAF', 16);
|
||||
$y = $this->getInstance('133713371337133713371337', 16);
|
||||
$z = $this->getInstance('BC98BC98BC98BC98BC98BC98', 16);
|
||||
|
||||
$this->assertSame($z->toHex(), $x->bitwise_XOR($y)->toHex());
|
||||
}
|
||||
|
||||
public function testBitwiseNOT()
|
||||
{
|
||||
$x = $this->getInstance('EEEEEEEEEEEEEEEEEEEEEEE', 16);
|
||||
$z = $this->getInstance('11111111111111111111111', 16);
|
||||
|
||||
$this->assertSame($z->toHex(), $x->bitwise_NOT()->toHex());
|
||||
|
||||
$a = $this->getInstance(0);
|
||||
$a->bitwise_not();
|
||||
|
||||
$this->assertSame($a->toString(), '0');
|
||||
}
|
||||
|
||||
public function testBitwiseLeftShift()
|
||||
{
|
||||
$x = $this->getInstance('0x0000000FF0000000', 16);
|
||||
$y = $this->getInstance('0x000FF00000000000', 16);
|
||||
|
||||
$this->assertSame($y->toHex(), $x->bitwise_LeftShift(16)->toHex());
|
||||
}
|
||||
|
||||
public function testBitwiseRightShift()
|
||||
{
|
||||
$x = $this->getInstance('0x0000000FF0000000', 16);
|
||||
$y = $this->getInstance('0x00000000000FF000', 16);
|
||||
$z = $this->getInstance('0x000000000000000F', 16);
|
||||
$n = $this->getInstance(0);
|
||||
|
||||
$this->assertSame($y->toHex(), $x->bitwise_RightShift(16)->toHex());
|
||||
$this->assertSame($z->toHex(), $x->bitwise_RightShift(32)->toHex());
|
||||
$this->assertSame($n->toHex(), $x->bitwise_RightShift(36)->toHex());
|
||||
}
|
||||
|
||||
public function testSerializable()
|
||||
{
|
||||
$x = $this->getInstance('18446744073709551616');
|
||||
$y = unserialize(serialize($x));
|
||||
|
||||
$this->assertTrue($x->equals($y));
|
||||
$this->assertTrue($y->equals($x));
|
||||
|
||||
$this->assertSame('18446744073709551616', (string) $x);
|
||||
$this->assertSame('18446744073709551616', (string) $y);
|
||||
}
|
||||
|
||||
public function testClone()
|
||||
{
|
||||
$x = $this->getInstance('18446744073709551616');
|
||||
$y = clone $x;
|
||||
|
||||
$this->assertTrue($x->equals($y));
|
||||
$this->assertTrue($y->equals($x));
|
||||
|
||||
$this->assertSame('18446744073709551616', (string) $x);
|
||||
$this->assertSame('18446744073709551616', (string) $y);
|
||||
}
|
||||
|
||||
public function testRandomTwoArgument()
|
||||
{
|
||||
$min = $this->getInstance(0);
|
||||
$max = $this->getInstance('18446744073709551616');
|
||||
|
||||
$rand1 = \phpseclib\Math\BigInteger::random($min, $max);
|
||||
// technically $rand1 can equal $min but with the $min and $max we've
|
||||
// chosen it's just not that likely
|
||||
$this->assertTrue($rand1->compare($min) > 0);
|
||||
$this->assertTrue($rand1->compare($max) < 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github279
|
||||
*/
|
||||
public function testDiffieHellmanKeyAgreement()
|
||||
{
|
||||
if (getenv('TRAVIS') && PHP_VERSION === '5.3.3'
|
||||
&& MATH_BIGINTEGER_MODE === \phpseclib\Math\BigInteger::MODE_INTERNAL
|
||||
) {
|
||||
$this->markTestIncomplete(
|
||||
'This test hangs on PHP 5.3.3 using internal mode.'
|
||||
);
|
||||
}
|
||||
|
||||
// "Oakley Group 14" 2048-bit modular exponentiation group as used in
|
||||
// SSH2 diffie-hellman-group14-sha1
|
||||
$prime = $this->getInstance(
|
||||
'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' .
|
||||
'29024E088A67CC74020BBEA63B139B22514A08798E3404DD' .
|
||||
'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245' .
|
||||
'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
|
||||
'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D' .
|
||||
'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F' .
|
||||
'83655D23DCA3AD961C62F356208552BB9ED529077096966D' .
|
||||
'670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
|
||||
'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9' .
|
||||
'DE2BCBF6955817183995497CEA956AE515D2261898FA0510' .
|
||||
'15728E5A8AACAA68FFFFFFFFFFFFFFFF',
|
||||
16
|
||||
);
|
||||
$generator = $this->getInstance(2);
|
||||
|
||||
/*
|
||||
Code for generation of $alicePrivate and $bobPrivate.
|
||||
$one = $this->getInstance(1);
|
||||
$max = $one->bitwise_leftShift(512)->subtract($one);
|
||||
$alicePrivate = \phpseclib\Math\BigInteger::random($one, $max);
|
||||
$bobPrivate = \phpseclib\Math\BigInteger::random($one, $max);
|
||||
var_dump($alicePrivate->toHex(), $bobPrivate->toHex());
|
||||
*/
|
||||
|
||||
$alicePrivate = $this->getInstance(
|
||||
'22606EDA7960458BC9D65F46DD96F114F9A004F0493C1F26' .
|
||||
'2139D2C8063B733162E876182CA3BF063AB1A167ABDB7F03' .
|
||||
'E0A225A6205660439F6CE46D252069FF',
|
||||
16
|
||||
);
|
||||
$bobPrivate = $this->getInstance(
|
||||
'6E3EFA13A96025D63E4B0D88A09B3A46DDFE9DD3BC9D1655' .
|
||||
'4898C02B4AC181F0CEB4E818664B12F02C71A07215C400F9' .
|
||||
'88352A4779F3E88836F7C3D3B3C739DE',
|
||||
16
|
||||
);
|
||||
|
||||
$alicePublic = $generator->modPow($alicePrivate, $prime);
|
||||
$bobPublic = $generator->modPow($bobPrivate, $prime);
|
||||
|
||||
$aliceShared = $bobPublic->modPow($alicePrivate, $prime);
|
||||
$bobShared = $alicePublic->modPow($bobPrivate, $prime);
|
||||
|
||||
$this->assertTrue(
|
||||
$aliceShared->equals($bobShared),
|
||||
'Failed asserting that Alice and Bob share the same BigInteger.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
*/
|
||||
public function testDebugInfo()
|
||||
{
|
||||
$num = $this->getInstance(50);
|
||||
$str = print_r($num, true);
|
||||
$this->assertContains('[value] => 0x32', $str);
|
||||
}
|
||||
|
||||
public function testPrecision()
|
||||
{
|
||||
$a = $this->getInstance(51);
|
||||
$this->assertSame($a->getPrecision(), -1);
|
||||
$b = $a;
|
||||
$c = clone $a;
|
||||
$b->setPrecision(1);
|
||||
$this->assertSame($a->getPrecision(), 1);
|
||||
$this->assertSame("$a", '1');
|
||||
$this->assertSame($b->getPrecision(), 1);
|
||||
$this->assertSame("$b", '1');
|
||||
$this->assertSame($c->getPrecision(), -1);
|
||||
$this->assertSame("$c", '51');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github954
|
||||
*/
|
||||
public function testSlidingWindow()
|
||||
{
|
||||
$e = $this->getInstance(str_repeat('1', 1794), 2);
|
||||
$x = $this->getInstance(1);
|
||||
$n = $this->getInstance(2);
|
||||
$x->powMod($e, $n);
|
||||
}
|
||||
public function testRoot()
|
||||
{
|
||||
$bigInteger = new \phpseclib\Math\BigInteger('64000000'); // (20^2)^3
|
||||
$three = new \phpseclib\Math\BigInteger('3');
|
||||
$bigInteger = $bigInteger->root();
|
||||
$this->assertSame('8000', (string) $bigInteger);
|
||||
$bigInteger = $bigInteger->root($three);
|
||||
$this->assertSame('20', (string) $bigInteger);
|
||||
}
|
||||
|
||||
public function testPow()
|
||||
{
|
||||
$bigInteger = new \phpseclib\Math\BigInteger('20');
|
||||
$two = new \phpseclib\Math\BigInteger('2');
|
||||
$three = new \phpseclib\Math\BigInteger('3');
|
||||
$bigInteger = $bigInteger->pow($two);
|
||||
$this->assertSame('400', (string) $bigInteger);
|
||||
$bigInteger = $bigInteger->pow($three);
|
||||
$this->assertSame('64000000', (string) $bigInteger); // (20^2)^3
|
||||
}
|
||||
|
||||
public function testMax()
|
||||
{
|
||||
$min = new \phpseclib\Math\BigInteger('20');
|
||||
$max = new \phpseclib\Math\BigInteger('20000');
|
||||
$this->assertSame((string) $max, (string) $min->max($max));
|
||||
$this->assertSame((string) $max, (string) $max->max($min));
|
||||
}
|
||||
|
||||
public function testMin()
|
||||
{
|
||||
$min = new \phpseclib\Math\BigInteger('20');
|
||||
$max = new \phpseclib\Math\BigInteger('20000');
|
||||
$this->assertSame((string) $min, (string) $min->min($max));
|
||||
$this->assertSame((string) $min, (string) $max->min($min));
|
||||
}
|
||||
|
||||
public function testLoopForeach()
|
||||
{
|
||||
$maxBigInteger = new \phpseclib\Math\BigInteger('34');
|
||||
$one = new \phpseclib\Math\BigInteger('1');
|
||||
$vars = [];
|
||||
$maxBigInteger->loopforeach(
|
||||
function ($i, &$vars) {
|
||||
if ($i == 0) {
|
||||
$vars['first'] = $i;
|
||||
} else {
|
||||
$vars['last'] = $i;
|
||||
}
|
||||
},
|
||||
$vars
|
||||
);
|
||||
$this->assertSame(0, $vars['first']);
|
||||
$this->assertSame(33, $vars['last']);
|
||||
/* Nope, too slow
|
||||
$maxBigInteger = new \phpseclib\Math\BigInteger(PHP_INT_MAX);
|
||||
$maxBigInteger = $maxBigInteger->add($one);
|
||||
$maxBigInteger->loopforeach(
|
||||
function ($i, &$vars) {
|
||||
if ($i == 0) {
|
||||
$vars["first"] = $i;
|
||||
} else {
|
||||
$vars["last"] = $i;
|
||||
}
|
||||
},
|
||||
$vars
|
||||
);
|
||||
$this->assertSame("0", $vars["first"]);
|
||||
$this->assertSame((string)$maxBigInteger->subtract($one), $vars["last"]);*/
|
||||
|
||||
|
||||
$maxBigInteger = new \phpseclib\Math\BigInteger(-34);
|
||||
$maxBigInteger->loopforeach(
|
||||
function ($i, &$vars) {
|
||||
if ($i == 0) {
|
||||
$vars['first'] = $i;
|
||||
} else {
|
||||
$vars['last'] = $i;
|
||||
}
|
||||
},
|
||||
$vars
|
||||
);
|
||||
$this->assertSame(0, $vars['first']);
|
||||
$this->assertSame(-33, $vars['last']);
|
||||
/* Nope, too slow
|
||||
$maxBigInteger = new \phpseclib\Math\BigInteger(-PHP_INT_MAX - 1);
|
||||
$maxBigInteger = $maxBigInteger->subtract($one);
|
||||
|
||||
$maxBigInteger->loopforeach(
|
||||
function ($i, &$vars) {
|
||||
if ($i == 0) {
|
||||
$vars["first"] = $i;
|
||||
} else {
|
||||
$vars["last"] = $i;
|
||||
}
|
||||
},
|
||||
$vars
|
||||
);
|
||||
$this->assertSame("0", $vars["first"]);
|
||||
$this->assertSame((string)$maxBigInteger->add($one), $vars["last"]);*/
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2014 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Net\SFTP\Stream;
|
||||
|
||||
class Unit_Net_SFTPStreamTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testRegisterWithoutArgument()
|
||||
{
|
||||
$this->assertTrue(Stream::register());
|
||||
$this->assertContains('sftp', stream_get_wrappers());
|
||||
$this->assertTrue(stream_wrapper_unregister('sftp'));
|
||||
}
|
||||
|
||||
public function testRegisterWithArgument()
|
||||
{
|
||||
$protocol = 'sftptest';
|
||||
$this->assertTrue(Stream::register($protocol));
|
||||
$this->assertContains($protocol, stream_get_wrappers());
|
||||
$this->assertTrue(stream_wrapper_unregister($protocol));
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Marc Scholten <marc@pedigital.de>
|
||||
* @copyright 2013 Marc Scholten
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
class Unit_Net_SSH1Test extends PhpseclibTestCase
|
||||
{
|
||||
public function formatLogDataProvider()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array('hello world'),
|
||||
array('<--'),
|
||||
"<--\r\n00000000 68:65:6c:6c:6f:20:77:6f:72:6c:64 hello world\r\n\r\n"
|
||||
),
|
||||
array(
|
||||
array('hello', 'world'),
|
||||
array('<--', '<--'),
|
||||
"<--\r\n00000000 68:65:6c:6c:6f hello\r\n\r\n" .
|
||||
"<--\r\n00000000 77:6f:72:6c:64 world\r\n\r\n"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider formatLogDataProvider
|
||||
*/
|
||||
public function testFormatLog(array $message_log, array $message_number_log, $expected)
|
||||
{
|
||||
$ssh = $this->getMockBuilder('phpseclib\Net\SSH1')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(null)
|
||||
->getMock();
|
||||
|
||||
$result = $ssh->_format_log($message_log, $message_number_log);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Marc Scholten <marc@pedigital.de>
|
||||
* @copyright 2013 Marc Scholten
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
class Unit_Net_SSH2Test extends PhpseclibTestCase
|
||||
{
|
||||
public function formatLogDataProvider()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array('hello world'),
|
||||
array('<--'),
|
||||
"<--\r\n00000000 68:65:6c:6c:6f:20:77:6f:72:6c:64 hello world\r\n\r\n"
|
||||
),
|
||||
array(
|
||||
array('hello', 'world'),
|
||||
array('<--', '<--'),
|
||||
"<--\r\n00000000 68:65:6c:6c:6f hello\r\n\r\n" .
|
||||
"<--\r\n00000000 77:6f:72:6c:64 world\r\n\r\n"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider formatLogDataProvider
|
||||
*/
|
||||
public function testFormatLog(array $message_log, array $message_number_log, $expected)
|
||||
{
|
||||
$ssh = $this->createSSHMock();
|
||||
|
||||
$result = $ssh->_format_log($message_log, $message_number_log);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testGenerateIdentifier()
|
||||
{
|
||||
$identifier = $this->createSSHMock()->_generate_identifier();
|
||||
$this->assertStringStartsWith('SSH-2.0-phpseclib_2.0', $identifier);
|
||||
|
||||
if (extension_loaded('libsodium')) {
|
||||
$this->assertContains('libsodium', $identifier);
|
||||
}
|
||||
|
||||
if (extension_loaded('openssl')) {
|
||||
$this->assertContains('openssl', $identifier);
|
||||
$this->assertNotContains('mcrypt', $identifier);
|
||||
} elseif (extension_loaded('mcrypt')) {
|
||||
$this->assertNotContains('openssl', $identifier);
|
||||
$this->assertContains('mcrypt', $identifier);
|
||||
} else {
|
||||
$this->assertNotContains('openssl', $identifier);
|
||||
$this->assertNotContains('mcrypt', $identifier);
|
||||
}
|
||||
|
||||
if (extension_loaded('gmp')) {
|
||||
$this->assertContains('gmp', $identifier);
|
||||
$this->assertNotContains('bcmath', $identifier);
|
||||
} elseif (extension_loaded('bcmath')) {
|
||||
$this->assertNotContains('gmp', $identifier);
|
||||
$this->assertContains('bcmath', $identifier);
|
||||
} else {
|
||||
$this->assertNotContains('gmp', $identifier);
|
||||
$this->assertNotContains('bcmath', $identifier);
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetExitStatusIfNotConnected()
|
||||
{
|
||||
$ssh = $this->createSSHMock();
|
||||
|
||||
$this->assertFalse($ssh->getExitStatus());
|
||||
}
|
||||
|
||||
public function testPTYIDefaultValue()
|
||||
{
|
||||
$ssh = $this->createSSHMock();
|
||||
$this->assertFalse($ssh->isPTYEnabled());
|
||||
}
|
||||
|
||||
public function testEnablePTY()
|
||||
{
|
||||
$ssh = $this->createSSHMock();
|
||||
|
||||
$ssh->enablePTY();
|
||||
$this->assertTrue($ssh->isPTYEnabled());
|
||||
|
||||
$ssh->disablePTY();
|
||||
$this->assertFalse($ssh->isPTYEnabled());
|
||||
}
|
||||
|
||||
public function testQuietModeDefaultValue()
|
||||
{
|
||||
$ssh = $this->createSSHMock();
|
||||
|
||||
$this->assertFalse($ssh->isQuietModeEnabled());
|
||||
}
|
||||
|
||||
public function testEnableQuietMode()
|
||||
{
|
||||
$ssh = $this->createSSHMock();
|
||||
|
||||
$ssh->enableQuietMode();
|
||||
$this->assertTrue($ssh->isQuietModeEnabled());
|
||||
|
||||
$ssh->disableQuietMode();
|
||||
$this->assertFalse($ssh->isQuietModeEnabled());
|
||||
}
|
||||
|
||||
public function testGetConnectionByResourceId()
|
||||
{
|
||||
$ssh = new \phpseclib\Net\SSH2('localhost');
|
||||
$this->assertSame($ssh, \phpseclib\Net\SSH2::getConnectionByResourceId($ssh->getResourceId()));
|
||||
}
|
||||
|
||||
public function testGetResourceId()
|
||||
{
|
||||
$ssh = new \phpseclib\Net\SSH2('localhost');
|
||||
$this->assertSame('{' . spl_object_hash($ssh) . '}', $ssh->getResourceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \phpseclib\Net\SSH2
|
||||
*/
|
||||
protected function createSSHMock()
|
||||
{
|
||||
return $this->getMockBuilder('phpseclib\Net\SSH2')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('__destruct'))
|
||||
->getMock();
|
||||
}
|
||||
}
|
19
vendor/phpseclib/phpseclib/tests/bootstrap.php
vendored
19
vendor/phpseclib/phpseclib/tests/bootstrap.php
vendored
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Bootstrapping File for phpseclib Test Suite
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
$loader_path = __DIR__ . '/../vendor/autoload.php';
|
||||
if (!file_exists($loader_path)) {
|
||||
echo "Dependencies must be installed using composer:\n\n";
|
||||
echo "php composer.phar install\n\n";
|
||||
echo "See http://getcomposer.org for help with installing composer\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$loader = include $loader_path;
|
||||
$loader->add('', __DIR__);
|
@ -1,30 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,2F15FCF0B21FCFB5A37D709322F9B9EB
|
||||
|
||||
JpGgJqRnr0+3mHQoeYXXUzSWeA1wGwMzm6KOPnQLEmA9ztPlBQulzZRh6QJckCwy
|
||||
TC7BMo+XRnYVXF3e0rjji0k7cfEk5Gs8saNcxxOa0u0SUOCXelGnZeqzwiT0a6Fe
|
||||
qAc7NLgTEo9zul9s+MHsplkVk71Oke+1dL7kksMRT0TdXIaqSvk/+nyAeLzAot04
|
||||
wo61T3+Y7/v/8oVxlCbxI5YfYZkm/4jTy7AfbXZBvC0R+F0ZYvIDRCuBe6h6XvcH
|
||||
AiYtw5+Qek6FwIa2CFVxsefvsEnZQYaiJpEFAq2xVHlTjQHHYrfd5cgu1koUNsAt
|
||||
nX1zpsK7tIregXFa07KfDaBBPxfEBqVJQInzj0Rc8HUt0AZ+MrPldrZ28+YQ4RXk
|
||||
/qk5UyKkdHMSKBb4va3mxcpDq1As9HREfeUeOjjduRh1LnNQCJaOhydXBqCFvhFy
|
||||
+Q9utDXP6q4OUxeDHCPGQ7K1I7erwiwuTeSXB3BEDZyZywHXABvJpsidkDlD/aNo
|
||||
QmM19V8y0IAxEAZvc8N0MIOO8hmd8R9U1RK4S24o9M8mgRrmuXjViJjZd5E3h6tX
|
||||
Mgxm8dpOiT77i+NsJwyp2A+MhkAHg2ruwlCIrSCC81zvdphVTfuc/vx3JpXYvhTP
|
||||
Xf9R8ppGnDUFauroN7E7odJKDhLVuAbmU1lWwue2iaNEKZ3L/o9dpRz4Td4NzzSf
|
||||
HKvKbJR35FCsqZq2krmNVd6ynF5PzWfYmz850yn/qdU8zwnW0fV+iHKS2oXuH9X1
|
||||
ZW02/MDdCylpRftNJMntR4Yxim7WEZ5Dif9ZLj8IGRQdWbbIn0WjtiVrFrcUbIfk
|
||||
TCP/3GeEcUa/XbE9hO9APw+7rO3sOehGJ84n4tXxFTFSnOJ5ZxTKpLvxRrmC8DaD
|
||||
cvqy8bbjPfn1EjZmRpCjanLZ1UJbLitFfpUT55aTrcozS4FMHmFm74X2xZGeBhxC
|
||||
CpWQe/agxhWxG+ZXdxt9ExI78ftQCQoGE0Si1KZXH5KQ/xiGmebY9wbtEHWG+q25
|
||||
sKqvjQHQsE3NZq7kne3mnyvjzMDDFYPLDlQLgcKInNrLZ3GszyemtzqcVf3YVur4
|
||||
N+nN0gu6LCx0vtw3yNRqjjmGN1V6sKMCqmIAtFDh9zRTlDTs7ZUBGPgakmmJLLVM
|
||||
ESme0JrRxCP+eEU8JNti9pKlKPGOFVpu4shLjmnmKuDpOytFNpcB/NylkGwZCxvE
|
||||
1KI+EQMZOE5VROAfkvwBLE0SsVxMq7H87zSEOtOqr+QN8RoY1V6N/woBVWda9GFk
|
||||
HI44PM2ZywQbLGthaQV/Kxwf9YZruJdunNoTfEufZgv2Vp+3VAs+gCTGIsbblTnH
|
||||
J8QGfs/lHRBqK1pMZrYy0ubFqifA+b9Xa6VJWToCgcQuWbOVWn1zKQTTXZPksVbB
|
||||
qyE8BJkQCDGgoeq4kdxm0XUR5p3UZWQv0HoykQt33U06TCzU9HOcp0z+Glhrzsvd
|
||||
rbNBhRK0zXF/BFSNBHwKEg02TNlj7gSFJXmvZqvyCAFo5D6nSDbzqm6ARuscsrF0
|
||||
6Zd3toOZTWmrVsKvTlsNPfHXyoGqP3+0NXcTY+kKXG58u4TbEtw8pVyPikuVdh/m
|
||||
-----END RSA PRIVATE KEY-----
|
@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file is part of the phpseclib project.
|
||||
#
|
||||
# (c) Andreas Fischer <bantu@phpbb.com>
|
||||
#
|
||||
# For the full copyright and license information, please view the LICENSE
|
||||
# file that was distributed with this source code.
|
||||
#
|
||||
set -e
|
||||
|
||||
function install_php_extension
|
||||
{
|
||||
cd "$1"
|
||||
phpize
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
echo "extension=$1.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
|
||||
}
|
||||
|
||||
# runkit
|
||||
git clone https://github.com/zenovich/runkit.git
|
||||
install_php_extension 'runkit'
|
34
vendor/phpseclib/phpseclib/travis/run-phpunit.sh
vendored
34
vendor/phpseclib/phpseclib/travis/run-phpunit.sh
vendored
@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
export PHPSECLIB_SSH_HOSTNAME='localhost'
|
||||
export PHPSECLIB_SSH_USERNAME='phpseclib'
|
||||
export PHPSECLIB_SSH_PASSWORD='EePoov8po1aethu2kied1ne0'
|
||||
export PHPSECLIB_SSH_HOME='/home/phpseclib'
|
||||
|
||||
if [ "$TRAVIS_PHP_VERSION" = '5.2' ]
|
||||
then
|
||||
PHPUNIT="phpunit"
|
||||
else
|
||||
PHPUNIT="$(dirname "$0")/../vendor/bin/phpunit"
|
||||
fi
|
||||
|
||||
PHPUNIT_ARGS='--verbose'
|
||||
if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.4', '<');"` = "1" ]
|
||||
then
|
||||
PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0"
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_PHP_VERSION" = 'hhvm' -o "$TRAVIS_PHP_VERSION" = '7.0' ]
|
||||
then
|
||||
find tests -type f -name "*Test.php" | \
|
||||
parallel --gnu --keep-order \
|
||||
"echo '== {} =='; \"$PHPUNIT\" $PHPUNIT_ARGS {};"
|
||||
else
|
||||
"$PHPUNIT" \
|
||||
$PHPUNIT_ARGS \
|
||||
--coverage-text \
|
||||
--coverage-clover code_coverage/clover.xml \
|
||||
--coverage-html code_coverage/
|
||||
fi
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
composer self-update --no-interaction
|
||||
composer install --no-interaction
|
@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This file is part of the phpseclib project.
|
||||
#
|
||||
# (c) Andreas Fischer <bantu@phpbb.com>
|
||||
#
|
||||
# For the full copyright and license information, please view the LICENSE
|
||||
# file that was distributed with this source code.
|
||||
#
|
||||
set -e
|
||||
set -x
|
||||
|
||||
USERNAME='phpseclib'
|
||||
PASSWORD='EePoov8po1aethu2kied1ne0'
|
||||
|
||||
# Create phpseclib user and home directory
|
||||
sudo useradd --create-home --base-dir /home "$USERNAME"
|
||||
|
||||
# Set phpseclib user password
|
||||
echo "$USERNAME:$PASSWORD" | sudo chpasswd
|
||||
|
||||
# Create a 1024 bit RSA SSH key pair without passphrase for the travis user
|
||||
ssh-keygen -t rsa -b 1024 -f "$HOME/.ssh/id_rsa" -q -N ""
|
||||
|
||||
# Add the generated private key to SSH agent of travis user
|
||||
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
|
@ -1,50 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This file is part of the phpseclib project.
|
||||
#
|
||||
# (c) Andreas Fischer <bantu@phpbb.com>
|
||||
#
|
||||
# For the full copyright and license information, please view the LICENSE
|
||||
# file that was distributed with this source code.
|
||||
#
|
||||
|
||||
USERNAME='phpseclib'
|
||||
HOSTNAME='phpseclib.bantux.org'
|
||||
HOSTRSAF='09:40:96:14:6a:cd:67:46:17:e5:b4:39:24:24:6e:9d'
|
||||
LDIRNAME='code_coverage'
|
||||
RDIRNAME='code_coverage'
|
||||
ID_RSA='travis/code_coverage_id_rsa'
|
||||
|
||||
# Install expect if necessary
|
||||
if ! which expect > /dev/null
|
||||
then
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qq expect
|
||||
fi
|
||||
|
||||
# Workaround for rsync not creating target directories with depth > 1
|
||||
mv "$LDIRNAME" "x$LDIRNAME"
|
||||
RROOT="$RDIRNAME/$TRAVIS_BRANCH/$TRAVIS_BUILD_NUMBER"
|
||||
mkdir -p "$RROOT"
|
||||
mv "x$LDIRNAME" "$RROOT/PHP-$TRAVIS_PHP_VERSION/"
|
||||
|
||||
# Update latest symlink
|
||||
ln -s "$TRAVIS_BUILD_NUMBER" "$RDIRNAME/$TRAVIS_BRANCH/latest"
|
||||
|
||||
# Stop complaints about world-readable key file.
|
||||
chmod 600 "$ID_RSA"
|
||||
|
||||
export RSYNC_RSH="ssh -4 -i $ID_RSA -o ConnectTimeout=5"
|
||||
RSYNC_OPT="--recursive --times --links --progress"
|
||||
|
||||
expect << EOF
|
||||
spawn rsync $RSYNC_OPT "$RDIRNAME/" "$USERNAME@$HOSTNAME:$RDIRNAME/"
|
||||
|
||||
expect "RSA key fingerprint is $HOSTRSAF."
|
||||
send "yes\n"
|
||||
|
||||
expect "Enter passphrase for key '$ID_RSA':"
|
||||
send "$CODE_COVERAGE_PASSPHRASE\n"
|
||||
|
||||
expect eof
|
||||
EOF
|
Loading…
Reference in New Issue
Block a user