Viel neues
This commit is contained in:
130
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/JWK.php
Normal file
130
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/JWK.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* JSON Web Key (RFC7517) Formatted RSA Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* JWK Formatted RSA Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class JWK extends Progenitor
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
*/
|
||||
public static function load($key, ?string $password = null): array
|
||||
{
|
||||
$key = parent::loadHelper($key);
|
||||
|
||||
if ($key->kty != 'RSA') {
|
||||
throw new \RuntimeException('Only RSA JWK keys are supported');
|
||||
}
|
||||
|
||||
$count = $publicCount = 0;
|
||||
$vars = ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi'];
|
||||
foreach ($vars as $var) {
|
||||
if (!isset($key->$var) || !is_string($key->$var)) {
|
||||
continue;
|
||||
}
|
||||
$count++;
|
||||
$value = new BigInteger(Strings::base64url_decode($key->$var), 256);
|
||||
switch ($var) {
|
||||
case 'n':
|
||||
$publicCount++;
|
||||
$components['modulus'] = $value;
|
||||
break;
|
||||
case 'e':
|
||||
$publicCount++;
|
||||
$components['publicExponent'] = $value;
|
||||
break;
|
||||
case 'd':
|
||||
$components['privateExponent'] = $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 'qi':
|
||||
$components['coefficients'][2] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($count == count($vars)) {
|
||||
return $components + ['isPublicKey' => false];
|
||||
}
|
||||
|
||||
if ($count == 2 && $publicCount == 2) {
|
||||
return $components + ['isPublicKey' => true];
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('Key does not have an appropriate number of RSA parameters');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @param string $password optional
|
||||
* @param array $options optional
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
throw new \InvalidArgumentException('JWK does not support multi-prime RSA keys');
|
||||
}
|
||||
|
||||
$key = [
|
||||
'kty' => 'RSA',
|
||||
'n' => Strings::base64url_encode($n->toBytes()),
|
||||
'e' => Strings::base64url_encode($e->toBytes()),
|
||||
'd' => Strings::base64url_encode($d->toBytes()),
|
||||
'p' => Strings::base64url_encode($primes[1]->toBytes()),
|
||||
'q' => Strings::base64url_encode($primes[2]->toBytes()),
|
||||
'dp' => Strings::base64url_encode($exponents[1]->toBytes()),
|
||||
'dq' => Strings::base64url_encode($exponents[2]->toBytes()),
|
||||
'qi' => Strings::base64url_encode($coefficients[2]->toBytes()),
|
||||
];
|
||||
|
||||
return self::wrapKey($key, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []): string
|
||||
{
|
||||
$key = [
|
||||
'kty' => 'RSA',
|
||||
'n' => Strings::base64url_encode($n->toBytes()),
|
||||
'e' => Strings::base64url_encode($e->toBytes()),
|
||||
];
|
||||
|
||||
return self::wrapKey($key, $options);
|
||||
}
|
||||
}
|
||||
210
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php
Normal file
210
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?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
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Exception\InvalidArgumentException;
|
||||
use phpseclib3\Exception\UnexpectedValueException;
|
||||
use phpseclib3\Exception\UnsupportedFormatException;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Microsoft BLOB Formatted RSA Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class MSBLOB
|
||||
{
|
||||
/**
|
||||
* Public/Private Key Pair
|
||||
*/
|
||||
public const PRIVATEKEYBLOB = 0x7;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
public const PUBLICKEYBLOB = 0x6;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
public const PUBLICKEYBLOBEX = 0xA;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
public const CALG_RSA_KEYX = 0x0000A400;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
public const CALG_RSA_SIGN = 0x00002400;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
public const RSA1 = 0x31415352;
|
||||
/**
|
||||
* Private Key
|
||||
*/
|
||||
public const RSA2 = 0x32415352;
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
*/
|
||||
public static function load($key, ?string $password = null): array
|
||||
{
|
||||
if (!Strings::is_stringable($key)) {
|
||||
throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
|
||||
}
|
||||
|
||||
$key = Strings::base64_decode($key);
|
||||
|
||||
if (!is_string($key)) {
|
||||
throw new UnexpectedValueException('Base64 decoding produced an error');
|
||||
}
|
||||
if (strlen($key) < 20) {
|
||||
throw new UnexpectedValueException('Key appears to be malformed');
|
||||
}
|
||||
|
||||
// PUBLICKEYSTRUC publickeystruc
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
|
||||
extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8)));
|
||||
/**
|
||||
* @var string $type
|
||||
* @var string $version
|
||||
* @var integer $reserved
|
||||
* @var integer $algo
|
||||
*/
|
||||
switch (ord($type)) {
|
||||
case self::PUBLICKEYBLOB:
|
||||
case self::PUBLICKEYBLOBEX:
|
||||
$publickey = true;
|
||||
break;
|
||||
case self::PRIVATEKEYBLOB:
|
||||
$publickey = false;
|
||||
break;
|
||||
default:
|
||||
throw new UnexpectedValueException('Key appears to be malformed');
|
||||
}
|
||||
|
||||
$components = ['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:
|
||||
throw new UnexpectedValueException('Key appears to be malformed');
|
||||
}
|
||||
|
||||
// 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', Strings::shift($key, 12)));
|
||||
/**
|
||||
* @var integer $magic
|
||||
* @var integer $bitlen
|
||||
* @var string $pubexp
|
||||
*/
|
||||
switch ($magic) {
|
||||
case self::RSA2:
|
||||
$components['isPublicKey'] = false;
|
||||
// fall-through
|
||||
case self::RSA1:
|
||||
break;
|
||||
default:
|
||||
throw new UnexpectedValueException('Key appears to be malformed');
|
||||
}
|
||||
|
||||
$baseLength = $bitlen / 16;
|
||||
if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
|
||||
throw new UnexpectedValueException('Key appears to be malformed');
|
||||
}
|
||||
|
||||
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
|
||||
// BYTE modulus[rsapubkey.bitlen/8]
|
||||
$components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256);
|
||||
|
||||
if ($publickey) {
|
||||
return $components;
|
||||
}
|
||||
|
||||
$components['isPublicKey'] = false;
|
||||
|
||||
// BYTE prime1[rsapubkey.bitlen/16]
|
||||
$components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
|
||||
// BYTE prime2[rsapubkey.bitlen/16]
|
||||
$components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256);
|
||||
// BYTE exponent1[rsapubkey.bitlen/16]
|
||||
$components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
|
||||
// BYTE exponent2[rsapubkey.bitlen/16]
|
||||
$components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256);
|
||||
// BYTE coefficient[rsapubkey.bitlen/16]
|
||||
$components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)];
|
||||
if (isset($components['privateExponent'])) {
|
||||
$components['publicExponent'] = $components['privateExponent'];
|
||||
}
|
||||
// BYTE privateExponent[rsapubkey.bitlen/8]
|
||||
$components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null): string
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
throw new InvalidArgumentException('MSBLOB does not support multi-prime RSA keys');
|
||||
}
|
||||
|
||||
if (!empty($password) && is_string($password)) {
|
||||
throw new UnsupportedFormatException('MSBLOB private keys do not support encryption');
|
||||
}
|
||||
|
||||
$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[2]->toBytes());
|
||||
$key .= strrev($d->toBytes());
|
||||
|
||||
return Strings::base64_encode($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e): string
|
||||
{
|
||||
$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 Strings::base64_encode($key);
|
||||
}
|
||||
}
|
||||
120
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php
Normal file
120
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Place in $HOME/.ssh/authorized_keys
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor;
|
||||
use phpseclib3\Exception\RuntimeException;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class OpenSSH extends Progenitor
|
||||
{
|
||||
/**
|
||||
* Supported Key Types
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $types = ['ssh-rsa'];
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
*/
|
||||
public static function load($key, ?string $password = null): array
|
||||
{
|
||||
static $one;
|
||||
if (!isset($one)) {
|
||||
$one = new BigInteger(1);
|
||||
}
|
||||
|
||||
$parsed = parent::load($key, $password);
|
||||
|
||||
if (isset($parsed['paddedKey'])) {
|
||||
[$type] = Strings::unpackSSH2('s', $parsed['paddedKey']);
|
||||
if ($type != $parsed['type']) {
|
||||
throw new RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])");
|
||||
}
|
||||
|
||||
$primes = $coefficients = [];
|
||||
|
||||
[
|
||||
$modulus,
|
||||
$publicExponent,
|
||||
$privateExponent,
|
||||
$coefficients[2],
|
||||
$primes[1],
|
||||
$primes[2],
|
||||
$comment,
|
||||
] = Strings::unpackSSH2('i6s', $parsed['paddedKey']);
|
||||
|
||||
$temp = $primes[1]->subtract($one);
|
||||
$exponents = [1 => $publicExponent->modInverse($temp)];
|
||||
$temp = $primes[2]->subtract($one);
|
||||
$exponents[] = $publicExponent->modInverse($temp);
|
||||
|
||||
$isPublicKey = false;
|
||||
|
||||
return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey');
|
||||
}
|
||||
|
||||
[$publicExponent, $modulus] = Strings::unpackSSH2('ii', $parsed['publicKey']);
|
||||
|
||||
return [
|
||||
'isPublicKey' => true,
|
||||
'modulus' => $modulus,
|
||||
'publicExponent' => $publicExponent,
|
||||
'comment' => $parsed['comment'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @param array $options optional
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []): string
|
||||
{
|
||||
$RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n);
|
||||
|
||||
if ($options['binary'] ?? self::$binary) {
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
|
||||
$comment = $options['comment'] ?? self::$comment;
|
||||
$RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment;
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
|
||||
{
|
||||
$publicKey = self::savePublicKey($n, $e, ['binary' => true]);
|
||||
$privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]);
|
||||
|
||||
return self::wrapPrivateKey($publicKey, $privateKey, $password, $options);
|
||||
}
|
||||
}
|
||||
152
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php
Normal file
152
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by File/X509.php
|
||||
*
|
||||
* Processes keys with the following headers:
|
||||
*
|
||||
* -----BEGIN RSA PRIVATE KEY-----
|
||||
* -----BEGIN RSA PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to ssh-keygen's pem format (as specified by -m)
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor;
|
||||
use phpseclib3\Exception\RuntimeException;
|
||||
use phpseclib3\Exception\UnexpectedValueException;
|
||||
use phpseclib3\File\ASN1;
|
||||
use phpseclib3\File\ASN1\Maps;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class PKCS1 extends Progenitor
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param string|false $password
|
||||
*/
|
||||
public static function load($key, ?string $password = null): array
|
||||
{
|
||||
if (!Strings::is_stringable($key)) {
|
||||
throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
|
||||
}
|
||||
|
||||
if (str_contains($key, 'PUBLIC')) {
|
||||
$components = ['isPublicKey' => true];
|
||||
} elseif (str_contains($key, 'PRIVATE')) {
|
||||
$components = ['isPublicKey' => false];
|
||||
} else {
|
||||
$components = [];
|
||||
}
|
||||
|
||||
$key = parent::load($key, $password);
|
||||
|
||||
$decoded = ASN1::decodeBER($key);
|
||||
if (!$decoded) {
|
||||
throw new RuntimeException('Unable to decode BER');
|
||||
}
|
||||
|
||||
$key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP);
|
||||
if (is_array($key)) {
|
||||
$components += [
|
||||
'modulus' => $key['modulus'],
|
||||
'publicExponent' => $key['publicExponent'],
|
||||
'privateExponent' => $key['privateExponent'],
|
||||
'primes' => [1 => $key['prime1'], $key['prime2']],
|
||||
'exponents' => [1 => $key['exponent1'], $key['exponent2']],
|
||||
'coefficients' => [2 => $key['coefficient']],
|
||||
];
|
||||
if ($key['version'] == 'multi') {
|
||||
foreach ($key['otherPrimeInfos'] as $primeInfo) {
|
||||
$components['primes'][] = $primeInfo['prime'];
|
||||
$components['exponents'][] = $primeInfo['exponent'];
|
||||
$components['coefficients'][] = $primeInfo['coefficient'];
|
||||
}
|
||||
}
|
||||
if (!isset($components['isPublicKey'])) {
|
||||
$components['isPublicKey'] = false;
|
||||
}
|
||||
return $components;
|
||||
}
|
||||
|
||||
$key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP);
|
||||
|
||||
if (!is_array($key)) {
|
||||
throw new RuntimeException('Unable to perform ASN1 mapping');
|
||||
}
|
||||
|
||||
if (!isset($components['isPublicKey'])) {
|
||||
$components['isPublicKey'] = true;
|
||||
}
|
||||
|
||||
return $components + $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @param string|false $password
|
||||
* @param array $options optional
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
|
||||
{
|
||||
$num_primes = count($primes);
|
||||
$key = [
|
||||
'version' => $num_primes == 2 ? 'two-prime' : 'multi',
|
||||
'modulus' => $n,
|
||||
'publicExponent' => $e,
|
||||
'privateExponent' => $d,
|
||||
'prime1' => $primes[1],
|
||||
'prime2' => $primes[2],
|
||||
'exponent1' => $exponents[1],
|
||||
'exponent2' => $exponents[2],
|
||||
'coefficient' => $coefficients[2],
|
||||
];
|
||||
for ($i = 3; $i <= $num_primes; $i++) {
|
||||
$key['otherPrimeInfos'][] = [
|
||||
'prime' => $primes[$i],
|
||||
'exponent' => $exponents[$i],
|
||||
'coefficient' => $coefficients[$i],
|
||||
];
|
||||
}
|
||||
|
||||
$key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP);
|
||||
|
||||
return self::wrapPrivateKey($key, 'RSA', $password, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e): string
|
||||
{
|
||||
$key = [
|
||||
'modulus' => $n,
|
||||
'publicExponent' => $e,
|
||||
];
|
||||
|
||||
$key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP);
|
||||
|
||||
return self::wrapPublicKey($key, 'RSA');
|
||||
}
|
||||
}
|
||||
109
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php
Normal file
109
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?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)
|
||||
*
|
||||
* Processes keys with the following headers:
|
||||
*
|
||||
* -----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
* -----BEGIN PRIVATE KEY-----
|
||||
* -----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)
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
|
||||
use phpseclib3\File\ASN1;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#8 Formatted RSA Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class PKCS8 extends Progenitor
|
||||
{
|
||||
/**
|
||||
* OID Name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const OID_NAME = 'rsaEncryption';
|
||||
|
||||
/**
|
||||
* OID Value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const OID_VALUE = '1.2.840.113549.1.1.1';
|
||||
|
||||
/**
|
||||
* Child OIDs loaded
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $childOIDsLoaded = false;
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
*/
|
||||
public static function load($key, ?string $password = null): array
|
||||
{
|
||||
$key = parent::load($key, $password);
|
||||
|
||||
if (isset($key['privateKey'])) {
|
||||
$components['isPublicKey'] = false;
|
||||
$type = 'private';
|
||||
} else {
|
||||
$components['isPublicKey'] = true;
|
||||
$type = 'public';
|
||||
}
|
||||
|
||||
$result = $components + PKCS1::load($key[$type . 'Key']);
|
||||
|
||||
if (isset($key['meta'])) {
|
||||
$result['meta'] = $key['meta'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
|
||||
{
|
||||
$key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients);
|
||||
$key = ASN1::extractBER($key);
|
||||
return self::wrapPrivateKey($key, [], null, $password, null, '', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @param array $options optional
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []): string
|
||||
{
|
||||
$key = PKCS1::savePublicKey($n, $e);
|
||||
$key = ASN1::extractBER($key);
|
||||
return self::wrapPublicKey($key, null);
|
||||
}
|
||||
}
|
||||
225
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PSS.php
Normal file
225
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PSS.php
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PKCS#8 Formatted RSA-PSS Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
|
||||
*
|
||||
* Processes keys with the following headers:
|
||||
*
|
||||
* -----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
* -----BEGIN PRIVATE KEY-----
|
||||
* -----BEGIN PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to "openssl genpkey -algorithm rsa-pss".
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
|
||||
use phpseclib3\Exception\UnexpectedValueException;
|
||||
use phpseclib3\File\ASN1;
|
||||
use phpseclib3\File\ASN1\Maps;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#8 Formatted RSA-PSS Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class PSS extends Progenitor
|
||||
{
|
||||
/**
|
||||
* OID Name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const OID_NAME = 'id-RSASSA-PSS';
|
||||
|
||||
/**
|
||||
* OID Value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const OID_VALUE = '1.2.840.113549.1.1.10';
|
||||
|
||||
/**
|
||||
* OIDs loaded
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $oidsLoaded = false;
|
||||
|
||||
/**
|
||||
* Child OIDs loaded
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $childOIDsLoaded = false;
|
||||
|
||||
/**
|
||||
* Initialize static variables
|
||||
*/
|
||||
private static function initialize_static_variables(): void
|
||||
{
|
||||
if (!self::$oidsLoaded) {
|
||||
ASN1::loadOIDs([
|
||||
'md2' => '1.2.840.113549.2.2',
|
||||
'md4' => '1.2.840.113549.2.4',
|
||||
'md5' => '1.2.840.113549.2.5',
|
||||
'id-sha1' => '1.3.14.3.2.26',
|
||||
'id-sha256' => '2.16.840.1.101.3.4.2.1',
|
||||
'id-sha384' => '2.16.840.1.101.3.4.2.2',
|
||||
'id-sha512' => '2.16.840.1.101.3.4.2.3',
|
||||
'id-sha224' => '2.16.840.1.101.3.4.2.4',
|
||||
'id-sha512/224' => '2.16.840.1.101.3.4.2.5',
|
||||
'id-sha512/256' => '2.16.840.1.101.3.4.2.6',
|
||||
|
||||
'id-mgf1' => '1.2.840.113549.1.1.8',
|
||||
]);
|
||||
self::$oidsLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
*/
|
||||
public static function load($key, ?string $password = null): array
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
if (!Strings::is_stringable($key)) {
|
||||
throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
|
||||
}
|
||||
|
||||
$components = ['isPublicKey' => str_contains($key, 'PUBLIC')];
|
||||
|
||||
$key = parent::load($key, $password);
|
||||
|
||||
$type = isset($key['privateKey']) ? 'private' : 'public';
|
||||
|
||||
$result = $components + PKCS1::load($key[$type . 'Key']);
|
||||
|
||||
if (isset($key[$type . 'KeyAlgorithm']['parameters'])) {
|
||||
$decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']);
|
||||
if ($decoded === false) {
|
||||
throw new UnexpectedValueException('Unable to decode parameters');
|
||||
}
|
||||
$params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP);
|
||||
} else {
|
||||
$params = [];
|
||||
}
|
||||
|
||||
if (isset($params['maskGenAlgorithm']['parameters'])) {
|
||||
$decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']);
|
||||
if ($decoded === false) {
|
||||
throw new UnexpectedValueException('Unable to decode parameters');
|
||||
}
|
||||
$params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP);
|
||||
} else {
|
||||
$params['maskGenAlgorithm'] = [
|
||||
'algorithm' => 'id-mgf1',
|
||||
'parameters' => ['algorithm' => 'id-sha1'],
|
||||
];
|
||||
}
|
||||
|
||||
if (!isset($params['hashAlgorithm']['algorithm'])) {
|
||||
$params['hashAlgorithm']['algorithm'] = 'id-sha1';
|
||||
}
|
||||
|
||||
$result['hash'] = str_replace('id-', '', $params['hashAlgorithm']['algorithm']);
|
||||
$result['MGFHash'] = str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']);
|
||||
if (isset($params['saltLength'])) {
|
||||
$result['saltLength'] = (int) $params['saltLength']->toString();
|
||||
}
|
||||
|
||||
if (isset($key['meta'])) {
|
||||
$result['meta'] = $key['meta'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
$key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients);
|
||||
$key = ASN1::extractBER($key);
|
||||
$params = self::savePSSParams($options);
|
||||
return self::wrapPrivateKey($key, [], $params, $password, null, '', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @param array $options optional
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []): string
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
$key = PKCS1::savePublicKey($n, $e);
|
||||
$key = ASN1::extractBER($key);
|
||||
$params = self::savePSSParams($options);
|
||||
return self::wrapPublicKey($key, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes PSS parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function savePSSParams(array $options)
|
||||
{
|
||||
/*
|
||||
The trailerField field is an integer. It provides
|
||||
compatibility with IEEE Std 1363a-2004 [P1363A]. The value
|
||||
MUST be 1, which represents the trailer field with hexadecimal
|
||||
value 0xBC. Other trailer fields, including the trailer field
|
||||
composed of HashID concatenated with 0xCC that is specified in
|
||||
IEEE Std 1363a, are not supported. Implementations that
|
||||
perform signature generation MUST omit the trailerField field,
|
||||
indicating that the default trailer field value was used.
|
||||
Implementations that perform signature validation MUST
|
||||
recognize both a present trailerField field with value 1 and an
|
||||
absent trailerField field.
|
||||
|
||||
source: https://tools.ietf.org/html/rfc4055#page-9
|
||||
*/
|
||||
$params = [
|
||||
'trailerField' => new BigInteger(1),
|
||||
];
|
||||
if (isset($options['hash'])) {
|
||||
$params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash'];
|
||||
}
|
||||
if (isset($options['MGFHash'])) {
|
||||
$temp = ['algorithm' => 'id-' . $options['MGFHash']];
|
||||
$temp = ASN1::encodeDER($temp, Maps\HashAlgorithm::MAP);
|
||||
$params['maskGenAlgorithm'] = [
|
||||
'algorithm' => 'id-mgf1',
|
||||
'parameters' => new ASN1\Element($temp),
|
||||
];
|
||||
}
|
||||
if (isset($options['saltLength'])) {
|
||||
$params['saltLength'] = new BigInteger($options['saltLength']);
|
||||
}
|
||||
|
||||
return new ASN1\Element(ASN1::encodeDER($params, Maps\RSASSA_PSS_params::MAP));
|
||||
}
|
||||
}
|
||||
111
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php
Normal file
111
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor;
|
||||
use phpseclib3\Exception\InvalidArgumentException;
|
||||
use phpseclib3\Exception\UnexpectedValueException;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class PuTTY extends Progenitor
|
||||
{
|
||||
/**
|
||||
* Public Handler
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH';
|
||||
|
||||
/**
|
||||
* Algorithm Identifier
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $types = ['ssh-rsa'];
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param string|false $password
|
||||
* @return array|false
|
||||
*/
|
||||
public static function load($key, $password)
|
||||
{
|
||||
static $one;
|
||||
if (!isset($one)) {
|
||||
$one = new BigInteger(1);
|
||||
}
|
||||
|
||||
$components = parent::load($key, $password);
|
||||
if (!isset($components['private'])) {
|
||||
return $components;
|
||||
}
|
||||
extract($components);
|
||||
unset($components['public'], $components['private']);
|
||||
|
||||
$isPublicKey = false;
|
||||
|
||||
$result = Strings::unpackSSH2('ii', $public);
|
||||
if ($result === false) {
|
||||
throw new UnexpectedValueException('Key appears to be malformed');
|
||||
}
|
||||
[$publicExponent, $modulus] = $result;
|
||||
|
||||
$result = Strings::unpackSSH2('iiii', $private);
|
||||
if ($result === false) {
|
||||
throw new UnexpectedValueException('Key appears to be malformed');
|
||||
}
|
||||
$primes = $coefficients = [];
|
||||
[$privateExponent, $primes[1], $primes[2], $coefficients[2]] = $result;
|
||||
|
||||
$temp = $primes[1]->subtract($one);
|
||||
$exponents = [1 => $publicExponent->modInverse($temp)];
|
||||
$temp = $primes[2]->subtract($one);
|
||||
$exponents[] = $publicExponent->modInverse($temp);
|
||||
|
||||
return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
throw new InvalidArgumentException('PuTTY does not support multi-prime RSA keys');
|
||||
}
|
||||
|
||||
$public = Strings::packSSH2('ii', $e, $n);
|
||||
$private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]);
|
||||
|
||||
return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e): string
|
||||
{
|
||||
return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa');
|
||||
}
|
||||
}
|
||||
166
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/Raw.php
Normal file
166
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/Raw.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* An array containing two \phpseclib3\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
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Exception\UnexpectedValueException;
|
||||
use phpseclib3\Exception\UnsupportedFormatException;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class Raw
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
*/
|
||||
public static function load($key, ?string $password = null): array
|
||||
{
|
||||
if (!is_array($key)) {
|
||||
throw new UnexpectedValueException('Key should be a array - not a ' . gettype($key));
|
||||
}
|
||||
|
||||
$key = array_change_key_case($key, CASE_LOWER);
|
||||
|
||||
$components = ['isPublicKey' => false];
|
||||
|
||||
foreach (['e', 'exponent', 'publicexponent', 0, 'privateexponent', 'd'] as $index) {
|
||||
if (isset($key[$index])) {
|
||||
$components['publicExponent'] = $key[$index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (['n', 'modulo', 'modulus', 1] as $index) {
|
||||
if (isset($key[$index])) {
|
||||
$components['modulus'] = $key[$index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($components['publicExponent']) || !isset($components['modulus'])) {
|
||||
throw new UnexpectedValueException('Modulus / exponent not present');
|
||||
}
|
||||
|
||||
if (isset($key['primes'])) {
|
||||
$components['primes'] = $key['primes'];
|
||||
} elseif (isset($key['p']) && isset($key['q'])) {
|
||||
$indices = [
|
||||
['p', 'q'],
|
||||
['prime1', 'prime2'],
|
||||
];
|
||||
foreach ($indices as $index) {
|
||||
[$i0, $i1] = $index;
|
||||
if (isset($key[$i0]) && isset($key[$i1])) {
|
||||
$components['primes'] = [1 => $key[$i0], $key[$i1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($key['exponents'])) {
|
||||
$components['exponents'] = $key['exponents'];
|
||||
} else {
|
||||
$indices = [
|
||||
['dp', 'dq'],
|
||||
['exponent1', 'exponent2'],
|
||||
];
|
||||
foreach ($indices as $index) {
|
||||
[$i0, $i1] = $index;
|
||||
if (isset($key[$i0]) && isset($key[$i1])) {
|
||||
$components['exponents'] = [1 => $key[$i0], $key[$i1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($key['coefficients'])) {
|
||||
$components['coefficients'] = $key['coefficients'];
|
||||
} else {
|
||||
foreach (['inverseq', 'q\'', 'coefficient'] as $index) {
|
||||
if (isset($key[$index])) {
|
||||
$components['coefficients'] = [2 => $key[$index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($components['primes'])) {
|
||||
$components['isPublicKey'] = true;
|
||||
return $components;
|
||||
}
|
||||
|
||||
if (!isset($components['exponents'])) {
|
||||
$one = new BigInteger(1);
|
||||
$temp = $components['primes'][1]->subtract($one);
|
||||
$exponents = [1 => $components['publicExponent']->modInverse($temp)];
|
||||
$temp = $components['primes'][2]->subtract($one);
|
||||
$exponents[] = $components['publicExponent']->modInverse($temp);
|
||||
$components['exponents'] = $exponents;
|
||||
}
|
||||
|
||||
if (!isset($components['coefficients'])) {
|
||||
$components['coefficients'] = [2 => $components['primes'][2]->modInverse($components['primes'][1])];
|
||||
}
|
||||
|
||||
foreach (['privateexponent', 'd'] as $index) {
|
||||
if (isset($key[$index])) {
|
||||
$components['privateExponent'] = $key[$index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
|
||||
{
|
||||
if (!empty($password) && is_string($password)) {
|
||||
throw new UnsupportedFormatException('Raw private keys do not support encryption');
|
||||
}
|
||||
|
||||
return serialize([
|
||||
'e' => clone $e,
|
||||
'n' => clone $n,
|
||||
'd' => clone $d,
|
||||
'primes' => array_map(fn ($var) => clone $var, $primes),
|
||||
'exponents' => array_map(fn ($var) => clone $var, $exponents),
|
||||
'coefficients' => array_map(fn ($var) => clone $var, $coefficients),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e): array
|
||||
{
|
||||
return ['e' => clone $e, 'n' => clone $n];
|
||||
}
|
||||
}
|
||||
162
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/XML.php
Normal file
162
qa-tool/htdocs/oidc/phpseclib/Crypt/RSA/Formats/Keys/XML.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* More info:
|
||||
*
|
||||
* http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
|
||||
* http://www.w3.org/TR/xkms2/#XKMS_2_0_Paragraph_269
|
||||
* http://en.wikipedia.org/wiki/XML_Signature
|
||||
* http://en.wikipedia.org/wiki/XKMS
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpseclib3\Crypt\RSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Exception\BadConfigurationException;
|
||||
use phpseclib3\Exception\InvalidArgumentException;
|
||||
use phpseclib3\Exception\UnexpectedValueException;
|
||||
use phpseclib3\Exception\UnsupportedFormatException;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
abstract class XML
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @param string|array $key
|
||||
*/
|
||||
public static function load($key): array
|
||||
{
|
||||
if (!Strings::is_stringable($key)) {
|
||||
throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
|
||||
}
|
||||
|
||||
if (!class_exists('DOMDocument')) {
|
||||
throw new BadConfigurationException('The dom extension is not setup correctly on this system');
|
||||
}
|
||||
|
||||
$components = [
|
||||
'isPublicKey' => false,
|
||||
'primes' => [],
|
||||
'exponents' => [],
|
||||
'coefficients' => [],
|
||||
];
|
||||
|
||||
$use_errors = libxml_use_internal_errors(true);
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
if (substr($key, 0, 5) != '<?xml') {
|
||||
$key = '<xml>' . $key . '</xml>';
|
||||
}
|
||||
if (!$dom->loadXML($key)) {
|
||||
libxml_use_internal_errors($use_errors);
|
||||
throw new UnexpectedValueException('Key does not appear to contain XML');
|
||||
}
|
||||
$xpath = new \DOMXPath($dom);
|
||||
$keys = ['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(Strings::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);
|
||||
|
||||
foreach ($components as $key => $value) {
|
||||
if (is_array($value) && !count($value)) {
|
||||
unset($components[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($components['modulus']) && isset($components['publicExponent'])) {
|
||||
if (count($components) == 3) {
|
||||
$components['isPublicKey'] = true;
|
||||
}
|
||||
return $components;
|
||||
}
|
||||
|
||||
throw new UnexpectedValueException('Modulus / exponent not present');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @param string $password optional
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, string $password = ''): string
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
throw new InvalidArgumentException('XML does not support multi-prime RSA keys');
|
||||
}
|
||||
|
||||
if (!empty($password) && is_string($password)) {
|
||||
throw new UnsupportedFormatException('XML private keys do not support encryption');
|
||||
}
|
||||
|
||||
return "<RSAKeyPair>\r\n" .
|
||||
' <Modulus>' . Strings::base64_encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Strings::base64_encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
' <P>' . Strings::base64_encode($primes[1]->toBytes()) . "</P>\r\n" .
|
||||
' <Q>' . Strings::base64_encode($primes[2]->toBytes()) . "</Q>\r\n" .
|
||||
' <DP>' . Strings::base64_encode($exponents[1]->toBytes()) . "</DP>\r\n" .
|
||||
' <DQ>' . Strings::base64_encode($exponents[2]->toBytes()) . "</DQ>\r\n" .
|
||||
' <InverseQ>' . Strings::base64_encode($coefficients[2]->toBytes()) . "</InverseQ>\r\n" .
|
||||
' <D>' . Strings::base64_encode($d->toBytes()) . "</D>\r\n" .
|
||||
'</RSAKeyPair>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*/
|
||||
public static function savePublicKey(BigInteger $n, BigInteger $e): string
|
||||
{
|
||||
return "<RSAKeyValue>\r\n" .
|
||||
' <Modulus>' . Strings::base64_encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Strings::base64_encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
'</RSAKeyValue>';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user