updated plugin WP-WebAuthn version 1.3.1

This commit is contained in:
2023-10-22 22:21:36 +00:00
committed by Gitium
parent 959829cf69
commit c7746517a0
931 changed files with 5408 additions and 1937 deletions

View File

@ -0,0 +1,4 @@
# Contributing
This repository is a sub repository of [the JWT Framework](https://github.com/web-token/jwt-framework) project and is READ ONLY.
Please do not submit any Pull Requests here. It will be automatically closed.

View File

@ -0,0 +1 @@
patreon: FlorentMorselli

View File

@ -0,0 +1,3 @@
Please do not submit any Pull Requests here. It will be automatically closed.
You should submit it here: https://github.com/web-token/jwt-framework/pulls

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2019 Spomky-Labs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class PS256 extends RSAPSS
{
public function name(): string
{
return 'PS256';
}
protected function getAlgorithm(): string
{
return 'sha256';
}
}

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class PS384 extends RSAPSS
{
public function name(): string
{
return 'PS384';
}
protected function getAlgorithm(): string
{
return 'sha384';
}
}

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class PS512 extends RSAPSS
{
public function name(): string
{
return 'PS512';
}
protected function getAlgorithm(): string
{
return 'sha512';
}
}

View File

@ -0,0 +1,15 @@
RSA Based Signature Algorithms For JWT-Framework
================================================
This repository is a sub repository of [the JWT Framework](https://github.com/web-token/jwt-framework) project and is READ ONLY.
**Please do not submit any Pull Request here.**
You should go to [the main repository](https://github.com/web-token/jwt-framework) instead.
# Documentation
The official documentation is available as https://web-token.spomky-labs.com/
# Licence
This software is release under [MIT licence](LICENSE).

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class RS256 extends RSAPKCS1
{
public function name(): string
{
return 'RS256';
}
protected function getAlgorithm(): string
{
return 'sha256';
}
}

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class RS384 extends RSAPKCS1
{
public function name(): string
{
return 'RS384';
}
protected function getAlgorithm(): string
{
return 'sha384';
}
}

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class RS512 extends RSAPKCS1
{
public function name(): string
{
return 'RS512';
}
protected function getAlgorithm(): string
{
return 'sha512';
}
}

View File

@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
use function in_array;
use InvalidArgumentException;
use Jose\Component\Core\JWK;
use Jose\Component\Core\Util\RSAKey;
use Jose\Component\Signature\Algorithm\Util\RSA as JoseRSA;
/**
* @deprecated Please use either RSAPSS or RSAPKCS1 depending on the padding mode
*/
abstract class RSA implements SignatureAlgorithm
{
public function allowedKeyTypes(): array
{
return ['RSA'];
}
public function verify(JWK $key, string $input, string $signature): bool
{
$this->checkKey($key);
$pub = RSAKey::createFromJWK($key->toPublic());
return JoseRSA::verify($pub, $input, $signature, $this->getAlgorithm(), $this->getSignatureMethod());
}
/**
* @throws InvalidArgumentException if the key is not private
*/
public function sign(JWK $key, string $input): string
{
$this->checkKey($key);
if (!$key->has('d')) {
throw new InvalidArgumentException('The key is not a private key.');
}
$priv = RSAKey::createFromJWK($key);
return JoseRSA::sign($priv, $input, $this->getAlgorithm(), $this->getSignatureMethod());
}
abstract protected function getAlgorithm(): string;
abstract protected function getSignatureMethod(): int;
/**
* @throws InvalidArgumentException if the key type is not allowed
* @throws InvalidArgumentException if the key is invalid
*/
private function checkKey(JWK $key): void
{
if (!in_array($key->get('kty'), $this->allowedKeyTypes(), true)) {
throw new InvalidArgumentException('Wrong key type.');
}
foreach (['n', 'e'] as $k) {
if (!$key->has($k)) {
throw new InvalidArgumentException(sprintf('The key parameter "%s" is missing.', $k));
}
}
}
}

View File

@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
use function in_array;
use InvalidArgumentException;
use Jose\Component\Core\JWK;
use Jose\Component\Core\Util\RSAKey;
use RuntimeException;
abstract class RSAPKCS1 implements SignatureAlgorithm
{
public function allowedKeyTypes(): array
{
return ['RSA'];
}
public function verify(JWK $key, string $input, string $signature): bool
{
$this->checkKey($key);
$pub = RSAKey::createFromJWK($key->toPublic());
return 1 === openssl_verify($input, $signature, $pub->toPEM(), $this->getAlgorithm());
}
/**
* @throws InvalidArgumentException if the key is not private
* @throws InvalidArgumentException if the data cannot be signed
*/
public function sign(JWK $key, string $input): string
{
$this->checkKey($key);
if (!$key->has('d')) {
throw new InvalidArgumentException('The key is not a private key.');
}
$priv = RSAKey::createFromJWK($key);
$result = openssl_sign($input, $signature, $priv->toPEM(), $this->getAlgorithm());
if (true !== $result) {
throw new RuntimeException('Unable to sign');
}
return $signature;
}
abstract protected function getAlgorithm(): string;
/**
* @throws InvalidArgumentException if the key type is not allowed
* @throws InvalidArgumentException if the key is not valid
*/
private function checkKey(JWK $key): void
{
if (!in_array($key->get('kty'), $this->allowedKeyTypes(), true)) {
throw new InvalidArgumentException('Wrong key type.');
}
foreach (['n', 'e'] as $k) {
if (!$key->has($k)) {
throw new InvalidArgumentException(sprintf('The key parameter "%s" is missing.', $k));
}
}
}
}

View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
use function in_array;
use InvalidArgumentException;
use Jose\Component\Core\JWK;
use Jose\Component\Core\Util\RSAKey;
use Jose\Component\Signature\Algorithm\Util\RSA as JoseRSA;
abstract class RSAPSS implements SignatureAlgorithm
{
public function allowedKeyTypes(): array
{
return ['RSA'];
}
public function verify(JWK $key, string $input, string $signature): bool
{
$this->checkKey($key);
$pub = RSAKey::createFromJWK($key->toPublic());
return JoseRSA::verify($pub, $input, $signature, $this->getAlgorithm(), JoseRSA::SIGNATURE_PSS);
}
/**
* @throws InvalidArgumentException if the key is not private
*/
public function sign(JWK $key, string $input): string
{
$this->checkKey($key);
if (!$key->has('d')) {
throw new InvalidArgumentException('The key is not a private key.');
}
$priv = RSAKey::createFromJWK($key);
return JoseRSA::sign($priv, $input, $this->getAlgorithm(), JoseRSA::SIGNATURE_PSS);
}
abstract protected function getAlgorithm(): string;
/**
* @throws InvalidArgumentException if the key type is not allowed
* @throws InvalidArgumentException if the key is not valid
*/
private function checkKey(JWK $key): void
{
if (!in_array($key->get('kty'), $this->allowedKeyTypes(), true)) {
throw new InvalidArgumentException('Wrong key type.');
}
foreach (['n', 'e'] as $k) {
if (!$key->has($k)) {
throw new InvalidArgumentException(sprintf('The key parameter "%s" is missing.', $k));
}
}
}
}

View File

@ -0,0 +1,251 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm\Util;
use function chr;
use InvalidArgumentException;
use Jose\Component\Core\Util\BigInteger;
use Jose\Component\Core\Util\Hash;
use Jose\Component\Core\Util\RSAKey;
use function ord;
use RuntimeException;
/**
* @internal
*/
class RSA
{
/**
* Probabilistic Signature Scheme.
*/
public const SIGNATURE_PSS = 1;
/**
* Use the PKCS#1.
*/
public const SIGNATURE_PKCS1 = 2;
/**
* @throws RuntimeException if the data cannot be signed
* @throws InvalidArgumentException if the signature mode is not supported
*/
public static function sign(RSAKey $key, string $message, string $hash, int $mode): string
{
switch ($mode) {
case self::SIGNATURE_PSS:
return self::signWithPSS($key, $message, $hash);
case self::SIGNATURE_PKCS1:
$result = openssl_sign($message, $signature, $key->toPEM(), $hash);
if (true !== $result) {
throw new RuntimeException('Unable to sign the data');
}
return $signature;
default:
throw new InvalidArgumentException('Unsupported mode.');
}
}
/**
* Create a signature.
*/
public static function signWithPSS(RSAKey $key, string $message, string $hash): string
{
$em = self::encodeEMSAPSS($message, 8 * $key->getModulusLength() - 1, Hash::$hash());
$message = BigInteger::createFromBinaryString($em);
$signature = RSAKey::exponentiate($key, $message);
return self::convertIntegerToOctetString($signature, $key->getModulusLength());
}
/**
* Create a signature.
*
* @deprecated Please use openssl_sign
*/
public static function signWithPKCS15(RSAKey $key, string $message, string $hash): string
{
$em = self::encodeEMSA15($message, $key->getModulusLength(), Hash::$hash());
$message = BigInteger::createFromBinaryString($em);
$signature = RSAKey::exponentiate($key, $message);
return self::convertIntegerToOctetString($signature, $key->getModulusLength());
}
/**
* @throws InvalidArgumentException if the signature mode is not supported
*/
public static function verify(RSAKey $key, string $message, string $signature, string $hash, int $mode): bool
{
switch ($mode) {
case self::SIGNATURE_PSS:
return self::verifyWithPSS($key, $message, $signature, $hash);
case self::SIGNATURE_PKCS1:
return 1 === openssl_verify($message, $signature, $key->toPEM(), $hash);
default:
throw new InvalidArgumentException('Unsupported mode.');
}
}
/**
* Verifies a signature.
*
* @throws RuntimeException if the signature cannot be verified
*/
public static function verifyWithPSS(RSAKey $key, string $message, string $signature, string $hash): bool
{
if (mb_strlen($signature, '8bit') !== $key->getModulusLength()) {
throw new RuntimeException();
}
$s2 = BigInteger::createFromBinaryString($signature);
$m2 = RSAKey::exponentiate($key, $s2);
$em = self::convertIntegerToOctetString($m2, $key->getModulusLength());
$modBits = 8 * $key->getModulusLength();
return self::verifyEMSAPSS($message, $em, $modBits - 1, Hash::$hash());
}
/**
* Verifies a signature.
*
* @deprecated Please use openssl_sign
*
* @throws RuntimeException if the signature cannot be verified
*/
public static function verifyWithPKCS15(RSAKey $key, string $message, string $signature, string $hash): bool
{
if (mb_strlen($signature, '8bit') !== $key->getModulusLength()) {
throw new RuntimeException();
}
$signature = BigInteger::createFromBinaryString($signature);
$m2 = RSAKey::exponentiate($key, $signature);
$em = self::convertIntegerToOctetString($m2, $key->getModulusLength());
return hash_equals($em, self::encodeEMSA15($message, $key->getModulusLength(), Hash::$hash()));
}
/**
* @throws RuntimeException if the value cannot be converted
*/
private static function convertIntegerToOctetString(BigInteger $x, int $xLen): string
{
$x = $x->toBytes();
if (mb_strlen($x, '8bit') > $xLen) {
throw new RuntimeException();
}
return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
}
/**
* MGF1.
*/
private static function getMGF1(string $mgfSeed, int $maskLen, Hash $mgfHash): string
{
$t = '';
$count = ceil($maskLen / $mgfHash->getLength());
for ($i = 0; $i < $count; ++$i) {
$c = pack('N', $i);
$t .= $mgfHash->hash($mgfSeed.$c);
}
return mb_substr($t, 0, $maskLen, '8bit');
}
/**
* EMSA-PSS-ENCODE.
*
* @throws RuntimeException if the message length is invalid
*/
private static function encodeEMSAPSS(string $message, int $modulusLength, Hash $hash): string
{
$emLen = ($modulusLength + 1) >> 3;
$sLen = $hash->getLength();
$mHash = $hash->hash($message);
if ($emLen <= $hash->getLength() + $sLen + 2) {
throw new RuntimeException();
}
$salt = random_bytes($sLen);
$m2 = "\0\0\0\0\0\0\0\0".$mHash.$salt;
$h = $hash->hash($m2);
$ps = str_repeat(chr(0), $emLen - $sLen - $hash->getLength() - 2);
$db = $ps.chr(1).$salt;
$dbMask = self::getMGF1($h, $emLen - $hash->getLength() - 1, $hash);
$maskedDB = $db ^ $dbMask;
$maskedDB[0] = ~chr(0xFF << ($modulusLength & 7)) & $maskedDB[0];
$em = $maskedDB.$h.chr(0xBC);
return $em;
}
/**
* EMSA-PSS-VERIFY.
*
* @throws InvalidArgumentException if the signature cannot be verified
*/
private static function verifyEMSAPSS(string $m, string $em, int $emBits, Hash $hash): bool
{
$emLen = ($emBits + 1) >> 3;
$sLen = $hash->getLength();
$mHash = $hash->hash($m);
if ($emLen < $hash->getLength() + $sLen + 2) {
throw new InvalidArgumentException();
}
if ($em[mb_strlen($em, '8bit') - 1] !== chr(0xBC)) {
throw new InvalidArgumentException();
}
$maskedDB = mb_substr($em, 0, -$hash->getLength() - 1, '8bit');
$h = mb_substr($em, -$hash->getLength() - 1, $hash->getLength(), '8bit');
$temp = chr(0xFF << ($emBits & 7));
if ((~$maskedDB[0] & $temp) !== $temp) {
throw new InvalidArgumentException();
}
$dbMask = self::getMGF1($h, $emLen - $hash->getLength() - 1, $hash/*MGF*/);
$db = $maskedDB ^ $dbMask;
$db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
$temp = $emLen - $hash->getLength() - $sLen - 2;
if (mb_substr($db, 0, $temp, '8bit') !== str_repeat(chr(0), $temp)) {
throw new InvalidArgumentException();
}
if (1 !== ord($db[$temp])) {
throw new InvalidArgumentException();
}
$salt = mb_substr($db, $temp + 1, null, '8bit'); // should be $sLen long
$m2 = "\0\0\0\0\0\0\0\0".$mHash.$salt;
$h2 = $hash->hash($m2);
return hash_equals($h, $h2);
}
/**
* @throws RuntimeException if the value cannot be encoded
*/
private static function encodeEMSA15(string $m, int $emBits, Hash $hash): string
{
$h = $hash->hash($m);
$t = $hash->t();
$t .= $h;
$tLen = mb_strlen($t, '8bit');
if ($emBits < $tLen + 11) {
throw new RuntimeException();
}
$ps = str_repeat(chr(0xFF), $emBits - $tLen - 3);
return "\0\1{$ps}\0{$t}";
}
}

View File

@ -0,0 +1,31 @@
{
"name": "web-token/jwt-signature-algorithm-rsa",
"description": "RSA Based Signature Algorithms the JWT Framework.",
"type": "library",
"license": "MIT",
"keywords": ["JWS", "JWT", "JWE", "JWA", "JWK", "JWKSet", "Jot", "Jose", "RFC7515", "RFC7516", "RFC7517", "RFC7518", "RFC7519", "RFC7520", "Bundle", "Symfony"],
"homepage": "https://github.com/web-token",
"authors": [
{
"name": "Florent Morselli",
"homepage": "https://github.com/Spomky"
},{
"name": "All contributors",
"homepage": "https://github.com/web-token/jwt-framework/contributors"
}
],
"autoload": {
"psr-4": {
"Jose\\Component\\Signature\\Algorithm\\": ""
}
},
"require": {
"brick/math": "^0.8.17|^0.9",
"ext-openssl": "*",
"web-token/jwt-signature": "^2.1"
},
"suggest": {
"ext-gmp": "GMP or BCMath is highly recommended to improve the library performance",
"ext-bcmath": "GMP or BCMath is highly recommended to improve the library performance"
}
}