diff --git a/Bootstrap.php b/Bootstrap.php
index 64c96da..74a198f 100644
--- a/Bootstrap.php
+++ b/Bootstrap.php
@@ -177,6 +177,8 @@ public function boot(Dispatcher $dispatcher): void
// Backend Hooks
if (!Shop::isFrontend()) {
+ $this->deactivateDeprecatedPaymentMethods();
+
/**
* !FIX ISSUES WITH getHelpDesc:
* - Description not being translated
@@ -242,21 +244,7 @@ public function installed()
$seeder->run();
}
- // Deactivate Invoice Factoring Payment Method by setting nNutzbar to 0
- foreach ($this->getPlugin()->getPaymentMethods()->getMethods() as $method) {
- if (
- ($method->getActive() || $method->getUsable()) &&
- in_array($method->getClassName(), self::getDeprecatedPaymentMethods())
- ) {
- $this->getDB()->update(
- 'tzahlungsart',
- 'kZahlungsart',
- $method->getMethodID(),
- (object) ['nNutzbar' => 0, 'nActive' => 0]
- );
- }
- }
-
+ $this->deactivateDeprecatedPaymentMethods();
$this->addApplePayVerification();
Shop::Container()->getCache()->flushTags([
@@ -273,22 +261,7 @@ public function installed()
*/
public function updated($oldVersion, $newVersion)
{
- // Deactivate Invoice Factoring Payment Method by setting nNutzbar to 0
- foreach ($this->getPlugin()->getPaymentMethods()->getMethods() as $method) {
- if (
- ($method->getActive() || $method->getUsable()) &&
- in_array($method->getClassName(), self::getDeprecatedPaymentMethods())
- ) {
- $this->getDB()->update(
- 'tzahlungsart',
- 'kZahlungsart',
- $method->getMethodID(),
- (object) ['nNutzbar' => 0, 'nActive' => 0]
- );
- $this->getDB()->delete('tversandartzahlungsart', 'kZahlungsart', $method->getMethodID());
- }
- }
-
+ $this->deactivateDeprecatedPaymentMethods();
$this->addApplePayVerification();
Shop::Container()->getCache()->flushTags([
@@ -404,6 +377,24 @@ private function addApplePayVerification()
}
}
+ private function deactivateDeprecatedPaymentMethods(): void
+ {
+ foreach ($this->getPlugin()->getPaymentMethods()->getMethods() as $method) {
+ if (
+ ($method->getActive() || $method->getUsable()) &&
+ in_array($method->getClassName(), self::getDeprecatedPaymentMethods(), true)
+ ) {
+ $this->getDB()->update(
+ 'tzahlungsart',
+ 'kZahlungsart',
+ $method->getMethodID(),
+ (object) ['nNutzbar' => 0, 'nActive' => 0]
+ );
+
+ $this->getDB()->delete('tversandartzahlungsart', 'kZahlungsart', $method->getMethodID());
+ }
+ }
+ }
private function registerSmartyPhpFunctions(JTLSmarty $smarty): void
{
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c32ed6f..888e67d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [2.0.4] (June 2026)
+### Added
+- support for **JTL 5.7** and **PHP 8.5**
+- added support for 2FA redirects for *Invoice*, *Installments*, and *Direct Debit*
+
+### Changed
+- updated plugin documentation requirements
+- remove *Merchant ID for Insight Portal* from settings as it is not needed anymore
+
+### Fixed
+- updated order status logic for *Direct Bank Transfer* due to updated flow where payment status AND transaction status must be considered
+- added missing error message after canceling card payments on 3DS redirect page
+- added missing "language" to customer object for B2B customers for *Google Pay*
+- handle error after canceling *Wero* payment
+- issue with customer name being taken from the shipping address instead of the billing address
+- issue with B2B customer object for non-UPL payment methods (missing *company* field in address, missing *companyInfo* field)
+
## [2.0.3] (April 2026)
### Changed
- basket metadata is now set for all payment methods
diff --git a/README.md b/README.md
index 4dbaf6e..defaf70 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Dieses Plugin integriert die folgenden Unzer-Zahlungsarten im JTL Shop:
## Installation / Update
### Systemvoraussetzungen
- JTL-Shop 5.0.0+ und dessen Vorraussetzungen
-- PHP Version: 7.4 - 8.4
+- PHP Version: 7.4 - 8.5
- Die folgenden PHP Erweiterungen
- ext-json
- ext-curl
@@ -80,7 +80,7 @@ This plugin integrates the following Unzer payment methods into the JTL Shop:
## Installation/update
### System requirements
- JTL-Shop 5.0.0+ and its requirements
-- PHP version: 7.4 - 8.4
+- PHP version: 7.4 - 8.5
- The following PHP extensions
- ext-json
- ext-curl
diff --git a/adminmenu/template/partials/_order_detail.tpl b/adminmenu/template/partials/_order_detail.tpl
index cc366ae..0ccb312 100644
--- a/adminmenu/template/partials/_order_detail.tpl
+++ b/adminmenu/template/partials/_order_detail.tpl
@@ -1,25 +1,5 @@
{strip}
- {*
*}
-
diff --git a/adminmenu/template/partials/_order_item.tpl b/adminmenu/template/partials/_order_item.tpl
index 6e16e3b..4045284 100644
--- a/adminmenu/template/partials/_order_item.tpl
+++ b/adminmenu/template/partials/_order_item.tpl
@@ -99,9 +99,6 @@
diff --git a/adminmenu/template/settings.tpl b/adminmenu/template/settings.tpl
index 1e3a6f7..404d47a 100644
--- a/adminmenu/template/settings.tpl
+++ b/adminmenu/template/settings.tpl
@@ -40,17 +40,6 @@
{__('hpSettingsPublicKeyHelp')}
-
- {* hIP / Insight Merchant ID *}
-
-
-
-
-
-
- {__('hpSettingsMerchantIdHelp')}
-
-
diff --git a/checksums.csv b/checksums.csv
index 1e7396e..2e4c2ab 100644
--- a/checksums.csv
+++ b/checksums.csv
@@ -1,12 +1,12 @@
145536c4c9441cf9505709d27d9ace95;vendor/autoload.php
42215678dd84b72ae4592d6ff273a5a4;vendor/unzerdev/php-sdk/.gitignore
-5b1d4c545c4730184ee6d31e1b62d6d9;vendor/unzerdev/php-sdk/composer.json
+91f38bd3958dc339911e610cab558dc1;vendor/unzerdev/php-sdk/composer.json
d045397c5fda276eb286c147ceb74ee4;vendor/unzerdev/php-sdk/.php-cs-fixer.php
2a835730131c1caf9963f59289b389bb;vendor/unzerdev/php-sdk/unzer_logo.svg
82e474803328bb1afbfaf2b535683353;vendor/unzerdev/php-sdk/README.md
-a4af7012fda92d785800fc2b39554efa;vendor/unzerdev/php-sdk/src/Adapter/ApplepayAdapter.php
-b3cc767aacbb53771524c28679417389;vendor/unzerdev/php-sdk/src/Adapter/CurlAdapter.php
-88f296c8dfdf09a9458bb75157cc5c3d;vendor/unzerdev/php-sdk/src/Adapter/HttpAdapterInterface.php
+9f49625409c8562dc5da83096fd8a2e9;vendor/unzerdev/php-sdk/src/Adapter/ApplepayAdapter.php
+552058cd99a7a6fd1834483e38f98858;vendor/unzerdev/php-sdk/src/Adapter/CurlAdapter.php
+eb44b2c3c837196f74cc8faea5bb31a0;vendor/unzerdev/php-sdk/src/Adapter/HttpAdapterInterface.php
aa58f837939ad64accce276415d6f06e;vendor/unzerdev/php-sdk/src/Apis/PaymentApiConfigBearerAuth.php
2cc971984b5e289b35fd1d0cf521d3ec;vendor/unzerdev/php-sdk/src/Apis/ApiRequest.php
30626969f60f4698d5f563f170049344;vendor/unzerdev/php-sdk/src/Apis/PaymentApiConfig.php
@@ -16,11 +16,11 @@ a9e0cee672d89f960dd976da3c6ad9ee;vendor/unzerdev/php-sdk/src/Apis/PaypageAPIConf
75c5a444fb0c4ab0a80aed8d2e2967bc;vendor/unzerdev/php-sdk/src/Apis/TokenApiConfig.php
a4d2fcde4cc90b1e230d3a3297b5d6f8;vendor/unzerdev/php-sdk/src/Exceptions/ApplepayMerchantValidationException.php
5f5e379cbf764b6e85a55d4894b17741;vendor/unzerdev/php-sdk/src/Exceptions/UnzerApiException.php
-4c2df74677faf75d3a102b4a29114152;vendor/unzerdev/php-sdk/src/Services/PaymentService.php
+686a2beca8f8aa446327477d76db9b21;vendor/unzerdev/php-sdk/src/Services/PaymentService.php
71d63712f7831a18ceb6285a4668c11a;vendor/unzerdev/php-sdk/src/Services/JwtService.php
ce9878fd925c1e5e1569c27f121cf994;vendor/unzerdev/php-sdk/src/Services/ResourceNameService.php
-852732451b4c657778f8b3a36b2106ce;vendor/unzerdev/php-sdk/src/Services/ResourceService.php
-3125b48394c6d38da644ac8d39c95c13;vendor/unzerdev/php-sdk/src/Services/HttpService.php
+caff8c617fe1670be57c779068a4e74f;vendor/unzerdev/php-sdk/src/Services/ResourceService.php
+770fc43a506087f04287c82f786ca213;vendor/unzerdev/php-sdk/src/Services/HttpService.php
ae5f057b154780300a9d422e51267c47;vendor/unzerdev/php-sdk/src/Services/ValueService.php
4dc8957cf26214316b9dbf19e9624570;vendor/unzerdev/php-sdk/src/Services/EnvironmentService.php
f49941ac10f5c4493af0711ad48ce056;vendor/unzerdev/php-sdk/src/Services/WebhookService.php
@@ -30,14 +30,15 @@ ef551bd65236c93d95854665fe9671f2;vendor/unzerdev/php-sdk/src/Services/IdService.
a7ca6bddd5964f87f73beaa4c48cb9e1;vendor/unzerdev/php-sdk/src/Resources/Webhooks.php
e8072c55c5894fe4cb8df5773da221be;vendor/unzerdev/php-sdk/src/Resources/PaylaterInstallmentPlans.php
595c41677b4b4e225d2af3e87fc5abe2;vendor/unzerdev/php-sdk/src/Resources/Config.php
-e0a74d283a2169dbfeeb1143a44259d5;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Authorization.php
-b906ccbb36133becfb879319a254d1a9;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Cancellation.php
-7930009039dd07900eff065e29c246ee;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/AbstractTransactionType.php
-a152d436db1db5a5c73f8e6a056b5ef0;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Chargeback.php
-0aae277cba417d984000ed45a632ec2d;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Payout.php
-c980f0dd8167b419e3b16f6a5f065de9;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Shipment.php
+222875e3341c7255dcb12146c6c13eee;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Authorization.php
+734cdc8b48aa8ebd6d52a465f01136a6;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Sca.php
+2b1de8d68da8fa5a9296e16940325c01;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Cancellation.php
+1ca23a6063572f7131f0ba4f75c4ce2c;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/AbstractTransactionType.php
+3af79cec09dcc1d19d176019ba93673e;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Chargeback.php
+d41239bda7030d30f68a4a5e396ea6d6;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Payout.php
+3d5871fbf83878e82786067d8bf94321;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Shipment.php
838230dff07bf7f53ce1d1624e181ba4;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/PreAuthorization.php
-b85f24ac5ffd4d18d3e7402c9b137ad4;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Charge.php
+67df9a096e11bd79af51ce8f8ea53548;vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Charge.php
80aba343a244782d1083deecceb47716;vendor/unzerdev/php-sdk/src/Resources/Keypair.php
c2d7dea4481042090695eb953609149b;vendor/unzerdev/php-sdk/src/Resources/CustomerFactory.php
a7d177281187488e329194e8a03f3648;vendor/unzerdev/php-sdk/src/Resources/Recurring.php
@@ -62,16 +63,16 @@ a6707cb0803758888a636a27bda62484;vendor/unzerdev/php-sdk/src/Resources/EmbeddedR
817f0f9895c40818f33d68450acfb8dd;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Payment.php
6f87064d204f19090cea2a076047fc9c;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/PaymentMethodConfig.php
f6fd7cc64eb7683f8c744d48c3624d2d;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Resources.php
-e640841cde29c0d4f41b39e0f49cdd9b;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Urls.php
+06b1081477352a826b00b46ccd5d4090;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Urls.php
abb9026bf13603593ef7ed6b36a20b6e;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/WeroEventDependentPayment.php
991b1745a5e85730edd024799da8e016;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Amount.php
-4c5ae19b086aa7ba6487d9538b3d034e;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Address.php
+a3d6bdf35f37070274e485a9c1a13952;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Address.php
d078edc8bc6f4252e14bb3ee1beeb7b7;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/WeroTransactionData.php
49dbf6c8a912cc4f2038282435e4e953;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/CardTransactionData.php
cbf16109faff0b644e54275047af86a9;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/RiskData.php
8a44e7b39b46559b0a6a665ca64c50e0;vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/CardDetails.php
89e657fa872ca0c6a816fe7b78cf7947;vendor/unzerdev/php-sdk/src/Resources/InstalmentPlans.php
-c39894f511400c81c0eab4137fdd9495;vendor/unzerdev/php-sdk/src/Resources/Payment.php
+f6e11fded1b16b2730fc0ab8eae719ef;vendor/unzerdev/php-sdk/src/Resources/Payment.php
9882f597bd321facccdf64f059f3f00d;vendor/unzerdev/php-sdk/src/Resources/Authentication/Token.php
ddfd5bb7fd8a51627555ea5848042df9;vendor/unzerdev/php-sdk/src/Resources/Basket.php
dd622d8ec6f7c8e4dd46e9d546907d47;vendor/unzerdev/php-sdk/src/Resources/ExternalResources/ApplepaySession.php
@@ -95,7 +96,7 @@ caeb3b948944a85c95b0484d8218c175;vendor/unzerdev/php-sdk/src/Resources/PaymentTy
04aa677940d068649579dc0d64e4e197;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Wero.php
202e427f0c83e6e1c07c2b88a63b9ffd;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Prepayment.php
aeef0a128d084d193928963672d3c8c1;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/PayU.php
-ef86892e52f66de6cee3d0f30fa9128a;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Giropay.php
+e853c117069976d374373ff92d4de8cf;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Giropay.php
fc44edd342dfa869073c5046d0ad57ef;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/PaylaterInstallment.php
c24930d176f6feb44ebdd8667b78d2a9;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Paypage.php
3969c1660e11ad35f9725e6c0dd12ff1;vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Paypal.php
@@ -124,11 +125,11 @@ f8404409d255be6044ca17101d30c3f1;vendor/unzerdev/php-sdk/src/Constants/WeroCaptu
d6ce87c1b1074bd214c33a699dda1ba4;vendor/unzerdev/php-sdk/src/Constants/PaypageCheckoutTypes.php
0e200a50be01534d35527c06939d1721;vendor/unzerdev/php-sdk/src/Constants/RecurrenceTypes.php
c8cd2db011dac68e7b0b34fbc2834cd3;vendor/unzerdev/php-sdk/src/Constants/CompanyCommercialSectorItems.php
-e3d540435791c183ea9b85c4dfe068aa;vendor/unzerdev/php-sdk/src/Constants/ApiResponseCodes.php
+2adaf19318b19c5894ac92ebe422d6f3;vendor/unzerdev/php-sdk/src/Constants/ApiResponseCodes.php
48c8611e7a204fbcdc8305f7bd77fd94;vendor/unzerdev/php-sdk/src/Constants/ApiVersions.php
98b1a747a7cf8967723484dc357435f3;vendor/unzerdev/php-sdk/src/Constants/BasketItemTypes.php
24fd3dfe4fb5793d8e18d49146c1aba2;vendor/unzerdev/php-sdk/src/Constants/CompanyRegistrationTypes.php
-2f146fe88f6e1fc021fd221e0520dbfc;vendor/unzerdev/php-sdk/src/Constants/TransactionTypes.php
+dd77648e7995d9b66e179747f30b6163;vendor/unzerdev/php-sdk/src/Constants/TransactionTypes.php
1c9d020ce65ee798772ca615b738ef11;vendor/unzerdev/php-sdk/src/Constants/WeroAmountPaymentTypes.php
3566859c7e75857511595a9f0525bd45;vendor/unzerdev/php-sdk/src/Constants/TransactionStatus.php
86812143071f5cf885cef4d0bb79309a;vendor/unzerdev/php-sdk/src/Constants/ExemptionType.php
@@ -138,13 +139,13 @@ afcfc9d1619fec0c54b2c3a208cdaa39;vendor/unzerdev/php-sdk/src/Constants/ApplepayV
dc551df19569c288082c989c2bbf3e85;vendor/unzerdev/php-sdk/src/Constants/ShippingTypes.php
e9f968341351755f055d926c21f05adc;vendor/unzerdev/php-sdk/src/Constants/Salutations.php
5984d0444c09208017ef39cf46347aea;vendor/unzerdev/php-sdk/src/Constants/CustomerGroups.php
-2d47ffdbaeeea41d28d88aa3695c5067;vendor/unzerdev/php-sdk/src/Constants/IdStrings.php
+a87e48ce2925af0df9e27be25dfc7c0d;vendor/unzerdev/php-sdk/src/Constants/IdStrings.php
a67c8a544a6760a9f5e8a490dae004ca;vendor/unzerdev/php-sdk/src/Constants/AdditionalAttributes.php
36d1a80f7177ac150fc5762078ddb55e;vendor/unzerdev/php-sdk/src/Constants/PaymentState.php
e648bfec127404941a0a104ac0320272;vendor/unzerdev/php-sdk/src/Validators/PrivateKeyValidator.php
c62a9f0b3664502a49fd27f6cd6919b3;vendor/unzerdev/php-sdk/src/Validators/PublicKeyValidator.php
aaf5ac4b651d570ea067cd78ab596e96;vendor/unzerdev/php-sdk/src/Validators/ExpiryDateValidator.php
-77fe01270009288a8ac9f84d89a503ad;vendor/unzerdev/php-sdk/src/Unzer.php
+ea43bc5e8e2842df517ac7ad2a975943;vendor/unzerdev/php-sdk/src/Unzer.php
58dccf5766f3619b338dd4f8803fae4c;vendor/unzerdev/php-sdk/src/Traits/HasUniqueAndShortId.php
e032a9a2cc661550726c2f898f983682;vendor/unzerdev/php-sdk/src/Traits/HasAdditionalTransactionData.php
84e1de89b2385e79556c2ec21ba086f3;vendor/unzerdev/php-sdk/src/Traits/HasCustomerMessage.php
@@ -172,8 +173,8 @@ f0a492f8bfbdff8718ae4c0c5571790b;vendor/unzerdev/php-sdk/src/Traits/HasAccountIn
454557a6a894225ddf5912e990e8f19e;vendor/unzerdev/php-sdk/src/Interfaces/DebugHandlerInterface.php
90d968a7c087f103a1b627f1346622ed;vendor/unzerdev/php-sdk/src/Interfaces/WebhookServiceInterface.php
89d011fdc511aeb3f0b3dd3936f28d75;vendor/unzerdev/php-sdk/src/Interfaces/CancelServiceInterface.php
-6c31c5fde8540d9e40a29590a4ea737f;vendor/unzerdev/php-sdk/src/Interfaces/PaymentServiceInterface.php
-c05113458aca974c27fc8b748d7b7ef8;vendor/unzerdev/php-sdk/src/Interfaces/ResourceServiceInterface.php
+db3d2e1b5409735acf0fed6c07fb3c81;vendor/unzerdev/php-sdk/src/Interfaces/PaymentServiceInterface.php
+e9c317d65ba22f6f7c59ee6fd6e329d4;vendor/unzerdev/php-sdk/src/Interfaces/ResourceServiceInterface.php
86d3f3a95c324c9479bd8986968f4327;vendor/unzerdev/php-sdk/LICENSE
9e9f49ec809ad456b453410ef1785548;vendor/unzerdev/php-sdk/.codacy.yml
3acde2e3165b3bc005591d39f205b73d;vendor/unzerdev/php-sdk/examples/ExampleDebugHandler.php
@@ -292,10 +293,10 @@ c1c5a14b36b9d911f5a0e978556dc71c;vendor/unzerdev/php-sdk/examples/Card/index.php
91c640a180c6a402db48711a0c99aed4;vendor/unzerdev/php-sdk/examples/EPSCharge/Controller.php
29a32449df2a240cad460522a386570b;vendor/unzerdev/php-sdk/examples/EPSCharge/Constants.php
4a03f03080b4c42e66111dd0d47e590f;vendor/unzerdev/php-sdk/examples/EPSCharge/index.php
-89ebe697baeeb27174bdca3648ef1f3f;vendor/unzerdev/php-sdk/phpunit.xml
+9188d01a5a66261215c8dbc4ebddc2e4;vendor/unzerdev/php-sdk/phpunit.xml
417e6e42dee83ba2011090b70c0cd90c;vendor/unzerdev/php-sdk/.travis.yml
cdbe7e4fb996b050423c7232a71bff67;vendor/unzerdev/php-sdk/NOTICE
-6758028fe0caf5928bd44c405aa08596;vendor/unzerdev/php-sdk/CHANGELOG.md
+017585f45b04774ea8e4cb0c1ebd96cc;vendor/unzerdev/php-sdk/CHANGELOG.md
4d30b8fd445b436492aa726177b2f3be;vendor/unzerdev/php-sdk/test/BaseIntegrationTest.php
500708d41b270db56199238ec7a678ff;vendor/unzerdev/php-sdk/test/unit/DummyResource.php
2326f4bd5d26ead1710d780114fe9ffb;vendor/unzerdev/php-sdk/test/unit/Adapter/ApplepaySessionTest.php
@@ -304,18 +305,18 @@ ac839c86ae72500cc78d6b746c841d27;vendor/unzerdev/php-sdk/test/unit/Exceptions/Un
9b86dd7a5798109211e4bba3eb70c5e7;vendor/unzerdev/php-sdk/test/unit/Services/DummyDebugHandler.php
828450cf3e68bc204d592b1b41dd2246;vendor/unzerdev/php-sdk/test/unit/Services/PaymentServiceTest.php
3c6fab6f8e2b1ba3e056779a8e8278a5;vendor/unzerdev/php-sdk/test/unit/Services/JwtServiceTest.php
-19faed6f4d6d88ab787808229a7a0d7e;vendor/unzerdev/php-sdk/test/unit/Services/WebhooksServiceTest.php
-1eff3cfce97848172d9e7666ce75aba5;vendor/unzerdev/php-sdk/test/unit/Services/DummyAdapter.php
-4d8a94a1783075d3193ef964874711dd;vendor/unzerdev/php-sdk/test/unit/Services/CancelServiceTest.php
-dc0ccf9224c7cbfd6256cd902e8a7014;vendor/unzerdev/php-sdk/test/unit/Services/ResourceServiceTest.php
+3606ddd2612a90895b9dc2378eccadb1;vendor/unzerdev/php-sdk/test/unit/Services/WebhooksServiceTest.php
+949702b3d491fa8920936fad49487928;vendor/unzerdev/php-sdk/test/unit/Services/DummyAdapter.php
+4d019ea5ac8ff292b44b8972b89a3944;vendor/unzerdev/php-sdk/test/unit/Services/CancelServiceTest.php
+c07aa855ebeba0a69bbe0d707a0f9eae;vendor/unzerdev/php-sdk/test/unit/Services/ResourceServiceTest.php
66acfe236eb7dcb1b2fa73c70b3d7ca5;vendor/unzerdev/php-sdk/test/unit/Services/ResourceNameServiceTest.php
-5fb399f6993314066a7fb99bd6158b03;vendor/unzerdev/php-sdk/test/unit/Services/HttpServiceTest.php
+dfba206be238951a73882d433fe9deb8;vendor/unzerdev/php-sdk/test/unit/Services/HttpServiceTest.php
04033672568687db6ff4937d891caa9f;vendor/unzerdev/php-sdk/test/unit/Services/IdServiceTest.php
-3506ff4007bb51bf218ac7fd08160564;vendor/unzerdev/php-sdk/test/unit/UnzerTest.php
+011ec356390f2c13158ef3d03fad5be7;vendor/unzerdev/php-sdk/test/unit/UnzerTest.php
9305a2c9ec330ae8e730116239710828;vendor/unzerdev/php-sdk/test/unit/Resources/KeypairTest.php
55c8f63568b8a95322e9f8c62c2c80d9;vendor/unzerdev/php-sdk/test/unit/Resources/InstalmentPlanTest.php
db440982ec14bd99d4ba4a746fd7e554;vendor/unzerdev/php-sdk/test/unit/Resources/PaymentTest.php
-8e1b69587751e684d738b537f3b9f4c7;vendor/unzerdev/php-sdk/test/unit/Resources/CustomerTest.php
+6abd3bb4eb734944729720941db5aeb5;vendor/unzerdev/php-sdk/test/unit/Resources/CustomerTest.php
fac208735ce2184117af0cbf4c677215;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/ShipmentTest.php
036e99aad2e09e82c96c9d2de1183535;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/PayoutTest.php
5f9b74b9a50978fc421f62ed6177e98d;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/AbstractTransactionTypeTest.php
@@ -323,6 +324,7 @@ c95c7d800a8d15fb66277cbfeb21b220;vendor/unzerdev/php-sdk/test/unit/Resources/Tra
0d6708b71d9c8575ba182a054d76f2d7;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/ChargeTest.php
45cd24b6560bc2f4e403c2cc5dbd9473;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/DummyTransactionType.php
fcaa8b37f1a82ceb6dba3d6b58b01a41;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/AuthorizationTest.php
+eba02cd6f41fbb67869425352abe824c;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/ScaTest.php
855505d7d60059ccae8ce92062bcd9a5;vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/CancellationTest.php
8e49881a9046c585465771123c43de0f;vendor/unzerdev/php-sdk/test/unit/Resources/PaylaterInstallmentPlansTest.php
64764b6899b8aa3780df619a670f3a42;vendor/unzerdev/php-sdk/test/unit/Resources/WebhookTest.php
@@ -401,15 +403,16 @@ a95799f26594e269182ddea7e3c084b5;vendor/unzerdev/php-sdk/test/integration/Transa
40893d16f3c3cda0d1d4dc10ecce933b;vendor/unzerdev/php-sdk/test/integration/TransactionTypes/CancelTest.php
2f64cf368a9b25f7a40300359aa69087;vendor/unzerdev/php-sdk/test/integration/TransactionTypes/ChargeTest.php
a82ed165d0b3ee08c60f73be0a3cdea2;vendor/unzerdev/php-sdk/test/integration/TransactionTypes/AuthorizationTest.php
+ba60f31732a6a69c1a96199d51f07345;vendor/unzerdev/php-sdk/test/integration/TransactionTypes/ScaTest.php
d7a1322927ca7755d0f5e49540540e13;vendor/unzerdev/php-sdk/test/integration/TransactionTypes/PreAuthorizationTest.php
-ec49c19bbe0ac1c76444f14a39ce91f3;vendor/unzerdev/php-sdk/test/integration/WebhookTest.php
+a2945a7614063d49bbb39eda237e6138;vendor/unzerdev/php-sdk/test/integration/WebhookTest.php
c05be2f170488399917d1163f7b320e2;vendor/unzerdev/php-sdk/test/integration/Resources/BasketV2Test.php
85c232a1b8a7ef9ddb25ff8486d58f97;vendor/unzerdev/php-sdk/test/integration/Resources/KeypairTest.php
ee8dd89cf6b958dfb375a12de69d585a;vendor/unzerdev/php-sdk/test/integration/Resources/BasketV3Test.php
281b8567daa5fb185052501ea191bdac;vendor/unzerdev/php-sdk/test/integration/Resources/AuthTokenTest.php
c316f310519ecb2042832a8c9b1ceb45;vendor/unzerdev/php-sdk/test/integration/Resources/CustomerTest.php
a66a6f07314de8a6963cf0dc6546d49a;vendor/unzerdev/php-sdk/test/integration/Resources/LinkpayV2Test.php
-944338aacaf487be6f86c66e720ffc3d;vendor/unzerdev/php-sdk/test/integration/Resources/PaypageV2Test.php
+92c9f9a30dbe08e4534de30543c2a162;vendor/unzerdev/php-sdk/test/integration/Resources/PaypageV2Test.php
939f400632308f5bc47403c704c74dfb;vendor/unzerdev/php-sdk/test/integration/Resources/CustomerV2Test.php
1d3f9ae6c57d57fff67ad8e665a48fe6;vendor/unzerdev/php-sdk/test/integration/Resources/ConfigTest.php
2f61e94cd276a0e8134f180240b394c5;vendor/unzerdev/php-sdk/test/integration/Resources/BasketTest.php
@@ -431,7 +434,6 @@ c7b76e5bb76f092d28414526cff6296f;vendor/unzerdev/php-sdk/test/integration/Paymen
68e14fbe9ec515539fc605fe7f0301c5;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/HirePurchaseTest.php
c313889561db37bb58b1e12f8e5a2d5c;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/PostFinanceEfinanceTest.php
e05854b48b714df0bdc0cf23f4933e39;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/Przelewy24Test.php
-c579a34b18cb399d3dc245510033ae4f;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/GiropayTest.php
3e33484f5d4a6ceeee0e9e2fdcf33f6e;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/OpenBankingTest.php
32f07cd5dd649448e750cfeb87b3a115;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/SepaDirectDebitTest.php
c56b45988630951dcfc0c8a69fe46983;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/SepaDirectDebitSecuredTest.php
@@ -449,9 +451,9 @@ be8d81d889f66425c9b3df8aaa308aab;vendor/unzerdev/php-sdk/test/integration/Paymen
4d0568fc244daf8c175c51843823a24d;vendor/unzerdev/php-sdk/test/integration/PaymentTypes/WechatpayTest.php
b5cd4812669a03576f47293ff8c93208;vendor/unzerdev/php-sdk/test/integration/ExceptionTest.php
30f2e8cb9ff544ae1b23029783424b16;vendor/unzerdev/php-sdk/test/TestDebugHandler.php
-f8f15b6e3f16a292aec754dd2f758ae7;vendor/unzerdev/php-sdk/test/Helper/TestEnvironmentService.php
+81ba407b450b7dd51dc1d81897b5179a;vendor/unzerdev/php-sdk/test/Helper/TestEnvironmentService.php
7e38b5a3118a4d3c48875bdd5951e9f1;vendor/unzerdev/php-sdk/test/Fixtures/DummyPaypageResource.php
-f3f5137c2d3e4e8e67a64cd049628d4f;vendor/unzerdev/php-sdk/test/Fixtures/CustomerFixtureTrait.php
+1d777fcf089b0f25e2003643723f817a;vendor/unzerdev/php-sdk/test/Fixtures/CustomerFixtureTrait.php
a345f9cd02ebbed4a0389b6e7f0e3423;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/paymentWithMultipleChargebacks.json
a8441a121efba5227555da6e57398674;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/sofortResponseWithIban.json
bc03ca4a157c1385fbb2beb0479866db;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/googlePay/fetchResponse.json
@@ -460,6 +462,8 @@ dd56c7e88804f2352c1dcdd889e024e3;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/
0b13de4b63f5cbcc258f65201874860d;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/paymentWithDirectChargeback.json
76a1641ff2bef335125ca6d8e38e4565;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/openBanking/fetchResponse.json
ac2e9e419384b726bad7428cc133ef96;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/openBanking/createRequest.json
+fa8d2dcb99e3573025c4adf2621626f3;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaResponse.json
+fa8d2dcb99e3573025c4adf2621626f3;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaPaymentResponse.json
b0833d74dd2e9cf65ef75fb25be5d638;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/chargeback.json
479257fe263661437ba83428b5eacea4;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/paylaterPlansResponse.json
5d8230cbfdfba058282fb1dbfbb1671c;vendor/unzerdev/php-sdk/test/Fixtures/jsonData/clicktopay/fetchResponse.json
@@ -472,13 +476,13 @@ e774a6ac03dc87705a34dd6d7f3c12a5;vendor/unzerdev/php-sdk/.github/workflows/relea
fcaa877ac215df25e0d42b84944bebfb;vendor/unzerdev/php-sdk/.github/workflows/test-group.yml
d51675285e38b187ec6501184c62e639;vendor/unzerdev/php-sdk/.github/workflows/validate-pull-request.yaml
46d029825edf473241d92ecac3c3c99f;vendor/unzerdev/php-sdk/.github/workflows/pre-release.yml
-334bdebaaac275bb9e6d71b7fec6ffd6;vendor/unzerdev/php-sdk/.github/workflows/integration-tests.yml
-fa04e71dfaaf414b6cfb5346dfa90dbe;vendor/unzerdev/php-sdk/.github/workflows/unit-tests.yml
+75838ebe2f7d3bf2f532b52d5ffdd0da;vendor/unzerdev/php-sdk/.github/workflows/integration-tests.yml
+0fe235db894f6e6f84da29f5c75bf13c;vendor/unzerdev/php-sdk/.github/workflows/unit-tests.yml
285a85e6e41f2280105391b2c2eb419a;vendor/unzerdev/php-sdk/.github/CODEOWNERS
dd08d7ce34d93812b90e0c83b0830e8e;vendor/phpseclib/phpseclib/composer.json
-7c4783c1028e43311e7cf8b23c24e04d;vendor/phpseclib/phpseclib/README.md
+e2a1eb9143daf9f081f5084edcb058e1;vendor/phpseclib/phpseclib/README.md
af7368297e479652e6ef808a77702c02;vendor/phpseclib/phpseclib/LICENSE
-280193e7acc99cbd28d43ebacd2fd641;vendor/phpseclib/phpseclib/BACKERS.md
+c0ee803794670f39215eed46917d433e;vendor/phpseclib/phpseclib/BACKERS.md
1fb9bc73e302ba9f215d86d67b3b5d73;vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php
8e0f3772662114a3962313d5db474e6e;vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php
042e8e610407b41b8a04e2872dedccbb;vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php
@@ -495,29 +499,30 @@ d8f32f01017420777ca33c5ab42d198d;vendor/phpseclib/phpseclib/phpseclib/Math/BigIn
b0bdb15defb90d6831c4fe93304b77f2;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php
d47eb0d3141be93cd6922acb835490cd;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php
4cbcdafb51c872cba4056acc5f6eac8b;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php
-6332016312d1d3953c80fb455f58f408;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php
+0cfc7293113928a788661fd5f9af7c93;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php
49b1796260911082f7161693e98f85dd;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php
1c15632b86b84f479562355f5bd64508;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php
c9d1fa5d368cb1c02419385af1f53682;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php
ff90ba3a9f0c50437fb28123c299f54b;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php
015ff4bbf9f1f1a7ff93ce629d26e526;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php
069ab262e56cb04c8e98f984990c0c33;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php
-e631a19bb6a96bdc18adf2403a2d56eb;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php
+980b079f85d93d1b4b2e6975b9e86c30;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php
cbd9ba4467f0da947945995a321edd21;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php
0aa26e7824ba2a16a70c86b75c841457;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php
f7b341f7c554b4e54f171e2422fa8b5e;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php
cd487f310c02e392196943e546884f8e;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php
4c97fb94f7ece153860c64e23ab23a4c;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php
-62f752aa06fad549c4d1cb42f867615e;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
+5ca3190b44646deae3acd42118e1a6cf;vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
36512abd6cdfe352f637cb76498735b8;vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php
-198e01f56568a15f8974b3a6b6f0ccd9;vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
+ba1d4ac9deaeab29eb0ecb68b253f7b5;vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
+729ff7444a2fd7e4b9f97e8764aaf98e;vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
c539ce0c2ace26e54f815dc528ad2d11;vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
-94ee2a235b1662100d5a2304d8996ebf;vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
-e210be3ac52737cd128b7b3a06b01eb5;vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php
+f869da816440163ccd245c3f1697f200;vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
+0883155c763939fd885c577e110e2c83;vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php
0c054287acdbdda2d6244fc5ade26b95;vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php
36cc261390c51c0fa66f632955b0dab9;vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
41b9b94bdfd534ab6ebfb7d0bf8a549a;vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php
-61bbb04b8162a956e98bb7ccc1fe0586;vendor/phpseclib/phpseclib/phpseclib/File/X509.php
+25600dbef9f25b058af6b58c2de0c320;vendor/phpseclib/phpseclib/phpseclib/File/X509.php
018bd58600c2545f967ada149fdc68ca;vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php
166dfc573923b7344b378c9206e740e3;vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php
13d1f23144be3bc417b9bd3be4fc2e49;vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php
@@ -644,7 +649,7 @@ e903157db0864e0e9d0eb218fe7cee40;vendor/phpseclib/phpseclib/phpseclib/File/ASN1/
3f7317e790640697bfb4bf94a90ab5af;vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php
64c983e5d1708fe24f8846e2ebbec7ed;vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php
be01c1e368e54acfcae749bb5adbec11;vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
-bb23f25797936751ad5a0bafbca14e72;vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
+f6b9807b84219280f9ad3f0ffa014f8f;vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
f4c5e01e7cb2909f26413f789ed81397;vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php
e1e2e5e0b7e8cc03abe3ff1acabd24a3;vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php
fb3bcd58ba318d74117a7c3e05edc63b;vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php
@@ -661,23 +666,23 @@ cf8e7671e5079a6774c35202ae5ff4b4;vendor/phpseclib/phpseclib/phpseclib/Exception/
0b7d8e736a24ddedf5ed00d3484c8975;vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php
6601a8131d3fa88b4f1ecf2ae6f9a08b;vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php
87189e47473849d93fabe1d4fd321afb;vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php
-08f1c224f83cb895ccfcbf19fb533d77;vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
-83ca72d0fc0877c6b83d4ef9012c081b;vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php
+6b921084db11ad69e05e2bd4511e5e13;vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
+50a9970abe5d79864ed0c2a07a9e3d2a;vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php
63ad81d212055e6f7cb2a7b4fd3dec45;vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
-94de83bbcb9b5dc37a31dc88601f2a61;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
-a8f255a935d49125b9b5fd2203acadef;vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php
+a2927cb3a950e3134205973d39e7ff60;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
+c240cb99074591033cb4b315adeaf14b;vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php
bf244e3a321ca4b5ff3a7fd6124d890f;vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php
543a0fad2f9537141cf01ea1e20bea7f;vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php
a65e06350f5c66ead4851267d6fe8691;vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php
9088f575e0a162a7ea204b0096ba203d;vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php
69f80949b9a90d0cc5e0cf85a3cc6410;vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php
-9413e5062c393230ba5864b0e0c8c846;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php
+e95a3979cdf515ccab79d1a7187b7e09;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php
fd01c80ae620ff944ad224694f7929a1;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php
e2a29c354145d8d4a02f7fd90a9a51ec;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php
28c57580625b4396514c8b6fd6afda6a;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php
1cd0dcbf16bd2e409de781bada186d38;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php
-dec9bf7e379ae4691a569535e30d2a2a;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php
-00a43339931458efdcf9b0f35aca57b8;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
+46ef6859c4e069274e8f543c6d8848ac;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php
+22b1cf15eacbaade6e7f9802796a9ace;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
fec521301d5d0c69fc1e507c13443437;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php
8e36169ff0be06f0fde8dcdaec6631ec;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php
0ce1b5e4f8296fd1de88185604288aee;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php
@@ -685,20 +690,20 @@ be5ec9615271e674d660a46dab540f31;vendor/phpseclib/phpseclib/phpseclib/Crypt/Comm
448c1f9a32d7d769cc24abf4b906888f;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php
13e51444d2a368f6f325cd1bc9daa75c;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php
cdf03f8e50e4baf4dde4d86f80b8cf08;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php
-365e89f10135eb4e3f448e37418a7778;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php
+241ba2de0c2de36b0781d7b949b1ba7c;vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php
3fdd8c95b7cffb0e9985d338090b2ba0;vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
2523c7f8b512e8cbf08806f4afcd33be;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php
300c092291bcb0f9810bdfcb03bca8ac;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php
bd1be69d327c3385d54fbb4be12a8c49;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php
-35dd7d5ab9f357186aab27fa4b5adaec;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php
+b52a5943e684cf304ce1967831867225;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php
5aee20c33f0c4e3152db822c0ff3ad19;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php
4ceeb99d0ec6988cf1e38b5677190eb0;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php
83aeef91fc41a7d310184a2f6f3dc00a;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php
dce1fa9b37bace1cfea1e59fff413c07;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php
e6b34e419e1f9c283afed8e127186177;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php
-573ebd3d7592f942607f0f863047a8ec;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php
-cc9c52e18a5bdd5accd3b0342688316a;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php
-faae4fd5334a06dd045f5ea9f24c4a82;vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
+79ecf54c314660b58d5d6883dcf1ff6f;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php
+95a09d38570dbbf9f8e632966f8925b4;vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php
+640faa0a1e72f908c93b6f5c2622e534;vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
be41f929cc2e3f28ab1ced739e90dd83;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php
9d94fcf7c2c31ac144ecdcf399122454;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php
d99fdeeb603fdfdaf88ac1ff319ee8bd;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php
@@ -708,13 +713,13 @@ cef2fcfeacae8f8b58037115d3596960;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/
3f7cc67bf4baee83664bb5067d309790;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php
3cb89b48d5d9cee6514ff83cfbec5c1d;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php
544d3076a0df77855ea438bd94495b05;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php
-344f0386bf46c3a802d3c9dc77c7b71a;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php
-62858ce67a39c0f860f65e1745ea7945;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php
-4d357430f1fbfa1a94da864bf86e7c7b;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php
-20841644093a890e427d544bce7f0085;vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php
-6700600289fca3163991c7c720be22f0;vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
-aadf4bea69438b0df5df383db2bf7edd;vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
-85da87aa04d087e7fd547519ce46719b;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php
+c5371cebe32400e7d65b7a40f0ef5b57;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php
+6817ebec3db96a793044009dcedbf75c;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php
+35ca39bc46aef2a3928a7f6861434309;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php
+5c456d0cee3ba0e790973f05c78c0f50;vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php
+c1382fc196af5bacbbc85c45addb0e2c;vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
+5a9c3a3562a2bfff76fb9fb180b7c201;vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
+c6917bd420a67b6288203cc69f359bd7;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php
8c0d2120d75748c1877e858264ed2eed;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php
c15814b88489f84bc7eeafdea9559978;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php
243a88eea5b939ace6db9da70b3ebd6f;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php
@@ -724,13 +729,13 @@ c3d6cdb76651ffbc8162f66e0efb393b;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/F
6e0f3ae71aa2f4211949e8396c4378b8;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php
9c43bd7d84ea054a996736bf1e06439c;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php
e627a2980cb53542b64b6d9a234ae083;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php
-4cc7ff2b22efc1d251b589c270f31d82;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php
-80c8c62adea3c913d884a75a74d3c42b;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php
+671756f559702c1b58b99df92d24d239;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php
+c2368b4f6953a813b53fb06ac8b69dc3;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php
3f209c71eca69afcf9f2eef5bc13eaf8;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php
-68746f75dd0f9511fed627f2f63c54f3;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
+ca8b73f15338fc565d374f41c71d4efd;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
323faab72989033c47475e558f680dc7;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php
-0e4c5a8eaf9cc097a7c6ddf571d7eed3;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php
-6697227426fca966edc9500319899eac;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php
+fca70c4e6ad0b092f8dfbe10bbdab41b;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php
+fc7577ccecb0411ed3262f8c399a6bb0;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php
1fcd67e0de877b8e8f004478eb00eda3;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php
9a15efda0ba337785d71f9969f835474;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php
e948f4a79170fb2d8fb3d3d1f2349cb9;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php
@@ -759,7 +764,7 @@ f7c40494abfbc18d7918089bb492a3f8;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/C
24284308da3c26af6d6fd576feddfeea;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php
f79737664973102e8272ef2c11b7e974;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php
706c4f2d8efdbc0f83676ee608e56d96;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php
-2e808c3ad853412ea67d11dc495ba179;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php
+8b9d1c1f83aab1e6ae7a83859eb6b708;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php
f99b47e07072dbec9de6e1b9d612c129;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php
44b9ff1e875f430237714e3a11fa21fc;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php
2982b9b3a7534834c313f10ff71e5b22;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php
@@ -773,7 +778,7 @@ f6fb7890cc2d544e5d438c9e34912a16;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/C
3e9a642ffccc5aba7e3b139ee02c1fa4;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php
dbece4a6c174eca6fa98c08855c8a9b3;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php
e99d7c70670820a38b271d734c961341;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php
-617693d0796bcdc00a0687b6e9a266a8;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php
+a4a24cd2880e8af5d32f5df0caa764a9;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php
203955d4495b242e33d26ef526627424;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php
8519adac393dd5ac2c0654ac581c86cf;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php
351072838aa7a4696e8e27d517773060;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php
@@ -807,28 +812,29 @@ af1aafd7e929c39c243eab4db3f764a8;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/C
857030d72a730339bee1d71f16e0a840;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php
3a98aff9b0e7c041d9f50a957d3d2620;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php
d359cd5abfdd829af67316589817ec49;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php
-fafe0bc6b12ba296e5d5fe11a4f0183c;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php
+e86354e3df7fea997ecb6c46654cfe05;vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php
af21a780fc59992b916b419d9e40b2db;vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
-2a53b02f538e9b20e8cfe9255a1e6db7;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php
-8edfbdc34195bbc3645b0ec19f828646;vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
+79d7650ddcc9ef3482c4572abac1affe;vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php
+f1d053c03b8f535d41d7281e3c6a742b;vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
daaf4a58012b688e8550ffa25ba9c8b0;vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
8150e3db849c87d46626a8ba78de6076;vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
242ed95eb90447e56daaa42c7d23ff9b;vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php
-b4409823562c617107907cd04d67c8fa;vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
+f064875346b0ec5f714384018db4199f;vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
fa4bab04703bfcb560be4489526b0991;vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
+77b63f58b245c8e6e90643e727d04fb0;vendor/phpseclib/phpseclib/SECURITY.md
3012f773b400715a955cffa18c8016e0;vendor/phpseclib/phpseclib/AUTHORS
182d5924ff0b528f008a83d1f5809d02;vendor/composer/InstalledVersions.php
-8dd932a7a65010dd3e49368bb2dea609;vendor/composer/platform_check.php
+77536de43a8cfa1daaca6a8542f5f27f;vendor/composer/platform_check.php
ab90ab9876b52e0fe15a5e5ec32e25b7;vendor/composer/autoload_files.php
955d5fe58c231244f6b49000f383b5e2;vendor/composer/LICENSE
-c8b92c5114ddd48a1451674cbf3c2081;vendor/composer/installed.php
+f27965fa157808b53d5c03969a3948b9;vendor/composer/installed.php
631b00271668b14aee0447e8e8947507;vendor/composer/autoload_static.php
5615b29a1f5688414d56a1515d954a91;vendor/composer/autoload_classmap.php
79512e55245b2a8b64e60c3c1d05ab0e;vendor/composer/autoload_psr4.php
224007c97efb82c7b45b0e92f240af41;vendor/composer/autoload_namespaces.php
824e49753cf879aa756c9d6fbfe0c863;vendor/composer/autoload_real.php
c02be6d96671f88d28aad3ffa134c8ae;vendor/composer/ClassLoader.php
-778f43e9d652a98ae4dbbce0f4d4c81c;vendor/composer/installed.json
+7915cbe05ec329969d43acfa054b12d6;vendor/composer/installed.json
784efccde8a58c8491c20ef0eca6bf87;vendor/paragonie/random_compat/composer.json
4b54cbf6ccb77afb7ade42183affc554;vendor/paragonie/random_compat/lib/random.php
8eb7e9dc637fb48d8bddfb470e370f42;vendor/paragonie/random_compat/build-phar.sh
@@ -852,9 +858,9 @@ c979337b7229f44f958eeb7ecdc43f52;vendor/paragonie/constant_time_encoding/src/RFC
70ca37cf7170c539a0d65bd2e4591b91;vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php
d74ee339a9008b6c184705dcf20536ee;vendor/paragonie/constant_time_encoding/src/Hex.php
71cf58b32ec1818382729a499503af82;vendor/paragonie/constant_time_encoding/src/Base32.php
-a761dc4a6a7338866116567ae11c4368;composer.lock
+97657ac60f240bd9b6180524914c1c02;composer.lock
0a7ea3bc84eaecb910b6cb1b6f474db5;apple-developer-merchantid-domain-association
-c466bfceae7a1c850f00a4bd2c8400db;composer.json
+56f3882df96a1eb54693b8e937c58c45;composer.json
23ada647e7af4c86e7388b6b74efca32;frontend/js/unzer-ui-components.js
35aa90abd4f87d672b078fe554d61349;frontend/js/unzer-ui-components.min.js.map
86efdfbb532c2954668d7cfa59d645f2;frontend/js/unzer-ui-components.js.map
@@ -866,8 +872,8 @@ d5de3c2637eb45440c212d9a0824ee18;frontend/src/js/components/index.js
2292f0faa91e69e2fbcfcb332e7e9bce;frontend/src/js/components/base.js
15112aab51c1133c80096c05759e4008;frontend/src/js/utils/errors.js
cf44e5fa2ae44e1a9756651963bfe755;frontend/src/js/utils/debugging.js
-280b9703c8fd488aebf961bd9a721cd0;frontend/sync-workflow.php
-780b2b8990e8dba5534b2d1fa468c6f3;frontend/webhook.php
+2204ebc7811216c1eb4536b186659f24;frontend/sync-workflow.php
+def2542a414de4f29475714497739318;frontend/webhook.php
824c7c0e6cf814a4e52b7a45d26a657e;frontend/template/google_pay_button.tpl
3e34c443a1d94d22322bdd82673d0dd6;frontend/template/hire_purchase_direct_debit.tpl
ca79740c158847ad33410b9f2d9746c0;frontend/template/partials/_threatMetrix.tpl
@@ -887,9 +893,9 @@ c2405627e35992f208ba7281a6490256;adminmenu/scss/admin.scss
746bd73bf157393d5d55f4b559a8c6e5;adminmenu/css/admin.css.map
ea5a5b2dc793ab305fe96a7822ba667d;adminmenu/template/applepay.tpl
bd1dee2d300e99d194c69dfb1693075e;adminmenu/template/keypairs.tpl
-910a55e93d804f4f24251c5b197893e9;adminmenu/template/settings.tpl
-34e0beaa04e4bef9d55c15dc6b4a1f0d;adminmenu/template/partials/_order_item.tpl
-c973e777d822dfcc69c48771aee4ab72;adminmenu/template/partials/_order_detail.tpl
+95efa85cfe5a32efc50029500c50c4dc;adminmenu/template/settings.tpl
+a5e7815bcaa04b15bd90e93f6967f223;adminmenu/template/partials/_order_item.tpl
+9a66253251d74318da9f8208d577f9be;adminmenu/template/partials/_order_detail.tpl
94692a0334d6eeefe4b4806fc5832914;adminmenu/template/partials/_includes.tpl
50329cc04d18170a2e8f086579a67366;adminmenu/template/partials/_keypair_list.tpl
e68888b6874c60a42db48e2ead9dba40;adminmenu/template/partials/_keypair_item.tpl
@@ -897,7 +903,7 @@ e0b9e6894421345360862d2571283a23;adminmenu/template/partials/_header.tpl
dad4062692dbd99b16ae3233b36ec1ec;adminmenu/template/orders.tpl
30e621c301583a4e13928bd8b9a09a9d;.jshintrc
2c62fe5947e6614a783d78e29f531d00;phpmd-ruleset.xml
-6a4b7de12703b622853d4aa40dac6a7a;README.md
+528204be7bd0de771948370416c804dc;README.md
767ba442de91503e5b6245c2d114a5c7;src/ApplePay/CertificatesResource.php
6703c52f0190cd22bfa1f72d7930fce1;src/ApplePay/CertificationService.php
4ad80bac1bc3c0c244426c6dd6279a96;src/ApplePay/CertificateException.php
@@ -905,7 +911,7 @@ dad4062692dbd99b16ae3233b36ec1ec;adminmenu/template/orders.tpl
a3255fc904b7509e171553ea009c9c82;src/ApplePay/ActivateCertificateResource.php
4ba10c90d08b3f639e188c332647e1c5;src/Payments/PaymentMethodModuleFactory.php
b7d6a5dab057b0bb5bb42c02456aedf7;src/Payments/HeidelpayApiAdapter.php
-d7d9c9455ae5943a40596d3d170c3c39;src/Payments/HeidelpayPaymentMethod.php
+621352b49a860be17d65273dab104dde;src/Payments/HeidelpayPaymentMethod.php
85dadc4e055384cf11546247308921f5;src/Payments/Traits/PriceCurrencyConverter.php
54f0fff5386a4145ce981a2c4e24d576;src/Payments/Traits/SupportsB2B.php
ad359a50ddb9c76117d5941d75617fc8;src/Payments/Traits/HasSavedPaymentData.php
@@ -914,7 +920,7 @@ d78c74c0918be9b079a8cf4655446589;src/Payments/Traits/HasState.php
3324fa5c40887fa065d5357432fd1e52;src/Payments/Traits/HasBasket.php
aa1212a34a1c3b4f1475e6b439603404;src/Payments/Traits/HasMetadata.php
9f5c6070edc5f2c82560e28fd47a66ac;src/Payments/Traits/CancelPaymentTransaction.php
-c2632abd856021c7b0cdef9f8f6f0fca;src/Payments/Traits/HasCustomer.php
+9028032cf7c16f02894e42d0494b158c;src/Payments/Traits/HasCustomer.php
eafbb3fd550ede774e80f963759e71ea;src/Payments/Traits/HasPayStatus.php
8922f3e4843d3879c6c01d6da80166d1;src/Payments/Traits/HasDirectCharge.php
f64f8fbc30450ccafaa26deee7e4fb9e;src/Payments/PaymentHandler.php
@@ -926,7 +932,7 @@ d98195f0c1485f6412b599b3f1581902;src/Payments/Interfaces/HasPayButton.php
04525b7293527904b5c527dd5aecbd9b;src/Payments/Interfaces/HandleStepReviewOrderInterface.php
ab1b1e5c0f257e793786fd8f49b3a9b7;src/Payments/Interfaces/NotificationInterface.php
24bea0a602bf575ea6c7d432587c4fba;src/Charges/ChargeMappingModel.php
-9e1567a3d74129750aa8bd161d51f8fc;src/Charges/ChargeHandler.php
+4f9b1f1b1decd27496236d9634b77012;src/Charges/ChargeHandler.php
20db0d8770933362b0b8b7fa32c18494;src/Charges/ChargeMappingEntity.php
cc1c780662e1a85826bafc4dbfef25fc;src/Controllers/Controller.php
6b557d2f5af216698fad3cbb233f211e;src/Controllers/AjaxResponse.php
@@ -940,8 +946,8 @@ ac4c5cefb686188aaf1b69f99f3ba4ae;src/Controllers/PaymentController.php
e990705d5e8da7895d4460e98f516ec3;src/Controllers/Admin/AdminController.php
1902987773d5d5f5582f0c90198628fd;src/Controllers/Admin/AdminApplePayController.php
47d5c9582887c2d15265d9ef572b9b8d;src/Controllers/Admin/AdminKeyPairsController.php
-5827d6899028ef0919847b0fdaafcee0;src/Controllers/Admin/AdminOrdersController.php
-8a9dc40409220ffb905b588d056d2427;src/Controllers/Admin/AdminSettingsController.php
+283b307a5a04db56ba03fe1bd73f89cc;src/Controllers/Admin/AdminOrdersController.php
+bdcf3b5e6d2e5d639454d5921b557a07;src/Controllers/Admin/AdminSettingsController.php
8296f8b464c72e7441c7dedec8159728;src/Orders/OrderMappingModel.php
3da45aa29a08f869b95627a6e46e5f9a;src/Orders/OrderViewStruct.php
c1f8da0ce57d62d455c5e259c24685d0;src/Orders/OrderMappingEntity.php
@@ -949,16 +955,16 @@ f8bcecf005718c0af3412829d40aa63b;src/Services/SavedPaymentDataService.php
521e61755ca1485bfe834b40a50ac426;src/Utils/Logger.php
ff2e8ea1952f33020fe432ab359624d6;src/Utils/JtlLinkHelper.php
3f168e1ffb14560bed4eb5d301c8f748;src/Utils/SessionHelper.php
-d8659e8d6c1850a787285eb36967e3f1;src/Utils/Config.php
+d6d21974f88ddeca3f6798d2b5ff53f8;src/Utils/Config.php
d5d5d79ab6d86b5a965cf17240ff601e;src/Utils/JtlLoggerTrait.php
45d77592d5be177698832b19d2f84b78;src/Utils/Compatibility.php
48830baed39f5710178337ad6d6f8444;src/Utils/TranslatorTrait.php
-82c185d48308e87dd3f586a6b4e3261e;src/Webhooks/PaymentEventSubscriber.php
+3419a6978403bd64af2e33b5bd2fee77;src/Webhooks/PaymentEventSubscriber.php
4a6bd5f25d0487b44b664403d6b0315c;src/KeyPairs/KeyPairModel.php
8e0682ac5c506aa7ed6bc23a06970633;src/KeyPairs/KeyPairService.php
02ead16397ed114e97dc4a017cf2b30e;src/KeyPairs/KeyPairEntity.php
07e542740aeb10d40b387b86ff17ca15;src/Foundation/Struct.php
-b93684508161f05d1e5ab245170921cf;src/Foundation/EventSubscriber.php
+0b060144734e56201d155a5033a6aa8c;src/Foundation/EventSubscriber.php
a78e5bba0c2635642ab607fbf73b0cea;src/Foundation/EventPayload.php
666e75baf5eddfcf0c50e83a5386bb5d;src/Foundation/ServiceProvider.php
fda45f203428056c6676cf83a15b4387;src/Foundation/Seeder.php
@@ -966,28 +972,28 @@ fda45f203428056c6676cf83a15b4387;src/Foundation/Seeder.php
a09b4b6da00f1cd498ddbac5b8c4d051;src/Foundation/Entity.php
97287cd9117f7b341aefb53cfe00ac64;src/Foundation/Model.php
ea7aa4025fd765d650d31bf1c60e768f;LICENSE
-38a3fc22572cdee9a3885683bf3b007c;paymentmethod/UnzerPaylaterDirectDebit.php
-3ca7967b1966f2fda5a4732d0779aeb8;paymentmethod/HeidelpayPrepayment.php
-ec0675d513fe14aa3766347ab3fe45ba;paymentmethod/UnzerDirectBankTransfer.php
+64661598b36332415395dff9b8f74e61;paymentmethod/UnzerPaylaterDirectDebit.php
+a0fc97ff7e8358583001981b629fa534;paymentmethod/HeidelpayPrepayment.php
+07c86fb1d16b73504525fac000fc49a0;paymentmethod/UnzerDirectBankTransfer.php
cdf083b85ad47dd962fb7223301609c3;paymentmethod/UnzerWero.php
4704fb5d3c5b2581977682c705979bf0;paymentmethod/HeidelpayInvoiceGuaranteed.php
9e34f11f989a7ec68c9e4cc9c8a380d2;paymentmethod/UnzerKlarna.php
-7101d4748dff19c48223d84a112339db;paymentmethod/UnzerBancontact.php
-936e2ea3fec93fc4498132b81ec8f4f1;paymentmethod/HeidelpayPayPal.php
-c33ab12c2ff6b0a4be832b1fd5ccc258;paymentmethod/UnzerTwint.php
+9682bc83999be093f4420cbbcd23563d;paymentmethod/UnzerBancontact.php
+8d1312e7a3c4e06ae02e31324ddc5b77;paymentmethod/HeidelpayPayPal.php
+b32231d6b79eb98c9eeb6848e8a97d8d;paymentmethod/UnzerTwint.php
bc6a8299df4b8de3e0b2743ed860d61f;paymentmethod/UnzerApplePay.php
-75d281c904425534046164df12e3d1f5;paymentmethod/HeidelpayWeChatPay.php
-2cde4fb87f7ba1ccd21abbac226d75eb;paymentmethod/UnzerApplePayV2.php
-d6e6fa5c751565b83ebc6c2c3676cc94;paymentmethod/HeidelpayEPS.php
-321b61e4a93e0d0860f9dd8404ebf377;paymentmethod/HeidelpaySEPADirectDebit.php
+214d39a989b4d2c6e6837a66278d0d7e;paymentmethod/HeidelpayWeChatPay.php
+95768e6ccbdefc78512188cb14009e26;paymentmethod/UnzerApplePayV2.php
+17e7f2366570a8c2e881a2a02b652cbf;paymentmethod/HeidelpayEPS.php
+c1de49d54966ebd793ca4e1d9e7acea7;paymentmethod/HeidelpaySEPADirectDebit.php
04f239d9194556e5a43ef6c6b6168f43;paymentmethod/HeidelpayGiropay.php
3aea69ee54494a9981058e8f84be502e;paymentmethod/HeidelpayFlexiPayDirect.php
b80ab88d008319b39cba524bf2bd1b11;paymentmethod/HeidelpayInvoiceFactoring.php
58dae7c0526e2464e276aba8f326a7e0;paymentmethod/HeidelpaySEPADirectDebitGuaranteed.php
-524d91a283d4adcd7b18466d25fe9ae1;paymentmethod/HeidelpayiDEAL.php
-91aff68f9cc80451feb3b05f9f435d20;paymentmethod/UnzerPaylaterInstallment.php
+8edb53e2702f483105dcc644374562bf;paymentmethod/HeidelpayiDEAL.php
+abab7196c5cf41e5889ea8fdf2aba7ca;paymentmethod/UnzerPaylaterInstallment.php
76aac63ba26683b03f88e06311db677e;paymentmethod/HeidelpayInvoice.php
-4bc389fe7847acb688edcd86bf0b9b81;paymentmethod/UnzerPaylaterInvoice.php
+8d3c93ba2fca9823da97f7276406e609;paymentmethod/UnzerPaylaterInvoice.php
b2b5981cdb3060854934a7a4ddd86352;paymentmethod/HeidelpaySofort.php
405ab8956305746a8bfe2f10955d367a;paymentmethod/images/Default.svg
e9b9822db699305c6f9210f7a3296d99;paymentmethod/images/Bancontact.svg
@@ -1028,10 +1034,10 @@ d2198616c50a0ffd907e94a2f42c5f8b;paymentmethod/images/iDeal_WERO.svg
a25d1f684f60c0372468352a886400d5;paymentmethod/images/DirectDebitSecuredWL.svg
36dc54e9a212afc559462b482399025c;paymentmethod/images/Ideal.svg
97301dfb7f296851b5c3d01f5f1459ce;paymentmethod/images/Discover.svg
-96277ca6f92c342d9667542213dd903f;paymentmethod/HeidelpayPrzelewy24.php
+860263e3116bce01d76f07ee11fad24c;paymentmethod/HeidelpayPrzelewy24.php
4c63e15cb4148ac8d76fead03e93f5e1;paymentmethod/HeidelpayHirePurchaseDirectDebit.php
-4c97bb9c40d73235c899b707e60c4a0c;paymentmethod/HeidelpayAlipay.php
-608e304f236b8f85fca13d8cf4069077;paymentmethod/UnzerGooglePay.php
+ab8cff88f42842b133ba3428f7798641;paymentmethod/HeidelpayAlipay.php
+a8dbcbd62cd37fbe7861c946552acee9;paymentmethod/UnzerGooglePay.php
43aa1ac4c28b351cdb5c54656b0586b5;paymentmethod/template/hire_purchase_direct_debit_form.tpl
e8405d784f1b577d8332cfd9f2702587;paymentmethod/template/sepa_form.tpl
43aa1ac4c28b351cdb5c54656b0586b5;paymentmethod/template/sepa_guaranteed_form.tpl
@@ -1063,15 +1069,15 @@ a60e1531064c14507ae0429e123a1112;paymentmethod/template/ideal_form.tpl
ddaaceadd4366b7aa7aaa82ae405c821;paymentmethod/template/alipay_form.tpl
43aa1ac4c28b351cdb5c54656b0586b5;paymentmethod/template/invoice_guaranteed_form.tpl
54fd30a2872c9c7223da7c93d746029b;paymentmethod/template/prepayment_form.tpl
-c6212be984396ea5ae48880b371e2c61;paymentmethod/HeidelpayCreditCard.php
-ee72586bef75c15d1d06a437e4354ec8;info.xml
+85235d75531f240854aa4dc572d22c71;paymentmethod/HeidelpayCreditCard.php
+fd2b479e304868f66a918983ec309b79;info.xml
c237fcf06c9da2f07028932e8eb8aa36;Migrations/Migration20230925100000.php
686b3eec05aa867a757aa916dd50b50a;Migrations/Migration20260303100000.php
55ccfd103771065e96f3e482ee49499e;Migrations/Migration20220511114913.php
cd6d409b4fbd95d76bfe82ab4805a17b;Migrations/Migration20230919100000.php
166d9346b496a3a2a2332586e8dcfa44;Migrations/Migration20221006103000.php
3faed6c0507c6f399d352282db7c777b;Migrations/Migration20201027083900.php
-3457b9fdf3d1762d3fdc8a2d2a10cacf;Bootstrap.php
+ffbf0093371c992e85e607cf44fbcc18;Bootstrap.php
c9f6e33220cf462393c7070cffcfff1a;NOTICE
4db0ef5803b943bc62cf9a6e0f7b40b5;Seeders/Shop4PluginMigrationSeeder.php
24c7b7d22435a4e5efc810d505d146cb;locale/de-DE/base.po
@@ -1079,4 +1085,4 @@ c9f6e33220cf462393c7070cffcfff1a;NOTICE
778e8c29f694bc2c9902c04ed686ac0b;locale/en-GB/base.po
a1f17490d317c9c3c41322d96a75daa4;locale/en-GB/base.mo
e73740baa8bcab9ac6d47b2a95daa826;jsconfig.json
-835d1c9f49afcc380506604e594054fb;CHANGELOG.md
+fde39680b5cf2c49ad1ba41f97ecbe58;CHANGELOG.md
diff --git a/composer.json b/composer.json
index 2241463..ce1301e 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,7 @@
}
],
"require": {
- "unzerdev/php-sdk": "^3.7.0",
+ "unzerdev/php-sdk": "^4.0.0",
"phpseclib/phpseclib": "~3.0"
}
}
diff --git a/composer.lock b/composer.lock
index 71c9713..78e35f7 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "c6d741e7e3704870a751bd9c4903681d",
+ "content-hash": "4396889dd3a0348ff4a2b3eb3cec8fd6",
"packages": [
{
"name": "paragonie/constant_time_encoding",
@@ -127,16 +127,16 @@
},
{
"name": "phpseclib/phpseclib",
- "version": "3.0.46",
+ "version": "3.0.53",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
- "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6"
+ "reference": "511ddc8e352d5d1f1e33bea468b6f4ef48438cf9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
- "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/511ddc8e352d5d1f1e33bea468b6f4ef48438cf9",
+ "reference": "511ddc8e352d5d1f1e33bea468b6f4ef48438cf9",
"shasum": ""
},
"require": {
@@ -217,7 +217,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
- "source": "https://github.com/phpseclib/phpseclib/tree/3.0.46"
+ "source": "https://github.com/phpseclib/phpseclib/tree/3.0.53"
},
"funding": [
{
@@ -233,29 +233,29 @@
"type": "tidelift"
}
],
- "time": "2025-06-26T16:29:55+00:00"
+ "time": "2026-06-09T18:08:26+00:00"
},
{
"name": "unzerdev/php-sdk",
- "version": "3.13.1",
+ "version": "4.0.1",
"source": {
"type": "git",
"url": "https://github.com/unzerdev/php-sdk.git",
- "reference": "0a26d70b33185d52e49b06cb500a6e01bb6f1087"
+ "reference": "a9344b823fbf5374cd49e07ab6352d385578299e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/unzerdev/php-sdk/zipball/0a26d70b33185d52e49b06cb500a6e01bb6f1087",
- "reference": "0a26d70b33185d52e49b06cb500a6e01bb6f1087",
+ "url": "https://api.github.com/repos/unzerdev/php-sdk/zipball/a9344b823fbf5374cd49e07ab6352d385578299e",
+ "reference": "a9344b823fbf5374cd49e07ab6352d385578299e",
"shasum": ""
},
"require": {
"ext-json": "*",
- "php": "~7.4.0|~8.0.0|~8.1.0|~8.2.0|~8.3.0|~8.4.0"
+ "php": "~8.1.0|~8.2.0|~8.3.0|~8.4.0|~8.5.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
- "phpunit/phpunit": ">6.5 <10.0"
+ "phpunit/phpunit": "^9.6"
},
"suggest": {
"ext-curl": "*"
@@ -274,9 +274,9 @@
"description": "This is the php sdk to connect to the Unzer rest API.",
"support": {
"email": "support@unzer.com",
- "source": "https://github.com/unzerdev/php-sdk/tree/3.13.1"
+ "source": "https://github.com/unzerdev/php-sdk/tree/4.0.1"
},
- "time": "2025-09-23T14:21:50+00:00"
+ "time": "2026-05-15T13:48:06+00:00"
}
],
"packages-dev": [],
diff --git a/frontend/sync-workflow.php b/frontend/sync-workflow.php
index 3758e66..587ea5d 100644
--- a/frontend/sync-workflow.php
+++ b/frontend/sync-workflow.php
@@ -8,7 +8,7 @@
try {
$controller = new SyncWorkflowController(Shop::Container()->get(Config::PLUGIN_ID));
$controller->handle();
-} catch (Exception $exc) {
+} catch (Throwable $exc) {
Logger::error(
$exc->getCode() . ':' . $exc->getMessage() . ', Exception in FRONTEND_LINK sync-workflow.php'
);
diff --git a/frontend/webhook.php b/frontend/webhook.php
index 149c97a..850824c 100644
--- a/frontend/webhook.php
+++ b/frontend/webhook.php
@@ -8,9 +8,9 @@
try {
$controller = new WebhookController(Shop::Container()->get(Config::PLUGIN_ID));
$controller->handle();
-} catch (Exception $exc) {
+} catch (Throwable $exc) {
Logger::error(
- $exc->getCode() . ':' . $exc->getMessage() . ', Exception in FRONTEND_LINK webhook.php'
+ 'Exception in FRONTEND_LINK webhook.php: ' . $exc->getMessage() . PHP_EOL . $exc->getTraceAsString()
);
http_response_code(403);
}
diff --git a/info.xml b/info.xml
index ef98a98..7bbda96 100644
--- a/info.xml
+++ b/info.xml
@@ -6,7 +6,7 @@
http://www.solution360.de
100
5.0.0
- 2.0.3
+ 2.0.4
s360_unzer_shop5
2020-10-27
@@ -116,6 +116,18 @@
+
+ s360_hp_cancel_by_user
+
+
+
+
+
+
+
+
+
+
s360_hp_error_validating_merchant
diff --git a/paymentmethod/HeidelpayAlipay.php b/paymentmethod/HeidelpayAlipay.php
index 1ca94ee..f3d64bf 100644
--- a/paymentmethod/HeidelpayAlipay.php
+++ b/paymentmethod/HeidelpayAlipay.php
@@ -5,6 +5,7 @@
namespace Plugin\s360_unzer_shop5\paymentmethod;
use JTL\Checkout\Bestellung;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -29,6 +30,7 @@
*/
class HeidelpayAlipay extends HeidelpayPaymentMethod implements RedirectPaymentInterface
{
+ use SupportsB2B;
use HasBasket;
use HasMetadata;
use HasCustomer;
@@ -45,10 +47,10 @@ protected function getAllowedCurrencies(): array
protected function performTransaction(BasePaymentType $payment, Bestellung $order): AbstractTransactionType
{
// Create / Update existing customer resource if needed
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
if ($customer->getId()) {
diff --git a/paymentmethod/HeidelpayCreditCard.php b/paymentmethod/HeidelpayCreditCard.php
index e90c15a..1171654 100644
--- a/paymentmethod/HeidelpayCreditCard.php
+++ b/paymentmethod/HeidelpayCreditCard.php
@@ -7,6 +7,7 @@
use Exception;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasSavedPaymentData;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\PaymentTypes\Card;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
@@ -52,6 +53,7 @@ class HeidelpayCreditCard extends HeidelpayPaymentMethod implements
HandleStepAdditionalInterface
{
use CancelPaymentTransaction;
+ use SupportsB2B;
use HasBasket;
use HasMetadata;
use HasAuthorization;
@@ -155,12 +157,11 @@ protected function performTransaction(BasePaymentType $payment, Bestellung $orde
$customer = $this->createOrFetchHeidelpayCustomer(
$this->adapter,
$this->sessionHelper,
- false
+ $this->isB2BCustomer($shopCustomer)
);
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
// Update existing customer resource if needed
diff --git a/paymentmethod/HeidelpayEPS.php b/paymentmethod/HeidelpayEPS.php
index ddcfebb..2ab919f 100644
--- a/paymentmethod/HeidelpayEPS.php
+++ b/paymentmethod/HeidelpayEPS.php
@@ -6,6 +6,7 @@
use JTL\Checkout\Bestellung;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -32,6 +33,7 @@ class HeidelpayEPS extends HeidelpayPaymentMethod implements RedirectPaymentInte
use HasBasket;
use HasMetadata;
use HasCustomer;
+ use SupportsB2B;
protected function getAllowedCountries(): array
{
@@ -50,10 +52,10 @@ protected function getAllowedCurrencies(): array
protected function performTransaction(BasePaymentType $payment, Bestellung $order): AbstractTransactionType
{
// Create / Update existing customer resource if needed
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
if ($customer->getId()) {
diff --git a/paymentmethod/HeidelpayPayPal.php b/paymentmethod/HeidelpayPayPal.php
index 998c5af..c2a8761 100644
--- a/paymentmethod/HeidelpayPayPal.php
+++ b/paymentmethod/HeidelpayPayPal.php
@@ -7,6 +7,7 @@
use JTL\Checkout\Bestellung;
use JTL\Shop;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasSavedPaymentData;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -44,6 +45,7 @@ class HeidelpayPayPal extends HeidelpayPaymentMethod implements RedirectPaymentI
use HasDirectCharge;
use HasMetadata;
use HasSavedPaymentData;
+ use SupportsB2B;
/**
* Although Paypal support both auth as well as charge calls, we only support Direct Charge.
@@ -63,7 +65,7 @@ protected function performTransaction(BasePaymentType $payment, Bestellung $orde
// Create a customer with shipping address for Paypal's Buyer Protection
$shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
diff --git a/paymentmethod/HeidelpayPrepayment.php b/paymentmethod/HeidelpayPrepayment.php
index e8a696a..814e163 100644
--- a/paymentmethod/HeidelpayPrepayment.php
+++ b/paymentmethod/HeidelpayPrepayment.php
@@ -4,7 +4,9 @@
namespace Plugin\s360_unzer_shop5\paymentmethod;
+use Plugin\s360_unzer_shop5\src\Payments\Interfaces\RedirectPaymentInterface;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -29,11 +31,12 @@
*
* @see https://docs.heidelpay.com/docs/prepayment-payment
*/
-class HeidelpayPrepayment extends HeidelpayPaymentMethod
+class HeidelpayPrepayment extends HeidelpayPaymentMethod implements RedirectPaymentInterface
{
use HasBasket;
use HasMetadata;
use HasCustomer;
+ use SupportsB2B;
protected function getAllowedCountries(): array
{
@@ -91,10 +94,10 @@ public function getOrderAttributes(Bestellung $order, AbstractTransactionType $t
protected function performTransaction(BasePaymentType $payment, Bestellung $order): AbstractTransactionType
{
// Create / Update existing customer resource if needed
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
if ($customer->getId()) {
diff --git a/paymentmethod/HeidelpayPrzelewy24.php b/paymentmethod/HeidelpayPrzelewy24.php
index 7fa9d1a..9505de4 100644
--- a/paymentmethod/HeidelpayPrzelewy24.php
+++ b/paymentmethod/HeidelpayPrzelewy24.php
@@ -6,6 +6,7 @@
use JTL\Checkout\Bestellung;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -30,6 +31,7 @@ class HeidelpayPrzelewy24 extends HeidelpayPaymentMethod implements RedirectPaym
use HasBasket;
use HasMetadata;
use HasCustomer;
+ use SupportsB2B;
protected function getAllowedCountries(): array
{
@@ -48,10 +50,10 @@ protected function getAllowedCurrencies(): array
protected function performTransaction(BasePaymentType $payment, Bestellung $order): AbstractTransactionType
{
// Create / Update existing customer resource if needed
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
if ($customer->getId()) {
diff --git a/paymentmethod/HeidelpaySEPADirectDebit.php b/paymentmethod/HeidelpaySEPADirectDebit.php
index abdcf80..b503bc7 100644
--- a/paymentmethod/HeidelpaySEPADirectDebit.php
+++ b/paymentmethod/HeidelpaySEPADirectDebit.php
@@ -7,6 +7,7 @@
use JTL\Checkout\Bestellung;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasSavedPaymentData;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -43,6 +44,7 @@ class HeidelpaySEPADirectDebit extends HeidelpayPaymentMethod implements
use HasMetadata;
use HasCustomer;
use TranslatorTrait;
+ use SupportsB2B;
protected function getAllowedCountries(): array
{
@@ -85,10 +87,10 @@ protected function performTransaction(BasePaymentType $payment, Bestellung $orde
}
// Create / Update existing customer resource if needed
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
if ($customer->getId()) {
diff --git a/paymentmethod/HeidelpayWeChatPay.php b/paymentmethod/HeidelpayWeChatPay.php
index 94acb62..d9b447c 100644
--- a/paymentmethod/HeidelpayWeChatPay.php
+++ b/paymentmethod/HeidelpayWeChatPay.php
@@ -6,6 +6,7 @@
use JTL\Checkout\Bestellung;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -29,6 +30,7 @@ class HeidelpayWeChatPay extends HeidelpayPaymentMethod implements RedirectPayme
use HasBasket;
use HasMetadata;
use HasCustomer;
+ use SupportsB2B;
protected function getAllowedCountries(): array
{
@@ -47,10 +49,10 @@ protected function getAllowedCurrencies(): array
protected function performTransaction(BasePaymentType $payment, Bestellung $order): AbstractTransactionType
{
// Create / Update existing customer resource if needed
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
if ($customer->getId()) {
diff --git a/paymentmethod/HeidelpayiDEAL.php b/paymentmethod/HeidelpayiDEAL.php
index ae74e55..7499583 100644
--- a/paymentmethod/HeidelpayiDEAL.php
+++ b/paymentmethod/HeidelpayiDEAL.php
@@ -6,6 +6,7 @@
use JTL\Checkout\Bestellung;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -35,6 +36,7 @@ class HeidelpayiDEAL extends HeidelpayPaymentMethod implements RedirectPaymentIn
use HasBasket;
use HasMetadata;
use HasCustomer;
+ use SupportsB2B;
protected function getAllowedCountries(): array
{
@@ -53,10 +55,10 @@ protected function getAllowedCurrencies(): array
protected function performTransaction(BasePaymentType $payment, Bestellung $order): AbstractTransactionType
{
// Create / Update existing customer resource if needed
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
if ($customer->getId()) {
diff --git a/paymentmethod/UnzerApplePayV2.php b/paymentmethod/UnzerApplePayV2.php
index cec60bd..98ade68 100644
--- a/paymentmethod/UnzerApplePayV2.php
+++ b/paymentmethod/UnzerApplePayV2.php
@@ -11,23 +11,26 @@
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\CancelableInterface;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\HasPayButton;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\NotificationInterface;
+use Plugin\s360_unzer_shop5\src\Payments\Interfaces\RedirectPaymentInterface;
use Plugin\s360_unzer_shop5\src\Payments\Traits\CancelPaymentTransaction;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasAuthorization;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasCustomer;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasMetadata;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use Plugin\s360_unzer_shop5\src\Utils\Config;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
-class UnzerApplePayV2 extends HeidelpayPaymentMethod implements HasPayButton, NotificationInterface, CancelableInterface
+class UnzerApplePayV2 extends HeidelpayPaymentMethod implements HasPayButton, NotificationInterface, CancelableInterface, RedirectPaymentInterface
{
use HasAuthorization;
use HasCustomer;
use HasMetadata;
use HasBasket;
use CancelPaymentTransaction;
+ use SupportsB2B;
public function addPayButton(JTLSmarty $view): ?string
{
@@ -86,14 +89,10 @@ protected function performTransaction(BasePaymentType $payment, Bestellung $orde
$config = Shop::Container()->get(Config::class);
// Create or fetch customer resource
- $customer = $this->createOrFetchHeidelpayCustomer(
- $this->adapter,
- $this->sessionHelper,
- false
- );
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
// Update existing customer resource if needed
diff --git a/paymentmethod/UnzerBancontact.php b/paymentmethod/UnzerBancontact.php
index 547a426..6d4f52a 100644
--- a/paymentmethod/UnzerBancontact.php
+++ b/paymentmethod/UnzerBancontact.php
@@ -7,6 +7,7 @@
use JTL\Shop;
use JTL\Smarty\JTLSmarty;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
+use Plugin\s360_unzer_shop5\src\Payments\Traits\SupportsB2B;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Resources\TransactionTypes\Charge;
@@ -27,6 +28,7 @@ class UnzerBancontact extends HeidelpayPaymentMethod implements RedirectPaymentI
use HasBasket;
use HasCustomer;
use HasMetadata;
+ use SupportsB2B;
protected function getAllowedCountries(): array
{
@@ -66,7 +68,8 @@ public function handleStepAdditional(JTLSmarty $view): void
protected function performTransaction(BasePaymentType $payment, $order): AbstractTransactionType
{
// Create a customer with shipping address for Paypal's Buyer Protection
- $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, false);
+ $shopCustomer = $this->sessionHelper->getFrontendSession()->getCustomer();
+ $customer = $this->createOrFetchHeidelpayCustomer($this->adapter, $this->sessionHelper, $this->isB2BCustomer($shopCustomer));
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
diff --git a/paymentmethod/UnzerDirectBankTransfer.php b/paymentmethod/UnzerDirectBankTransfer.php
index 5b81c58..fa56b4d 100644
--- a/paymentmethod/UnzerDirectBankTransfer.php
+++ b/paymentmethod/UnzerDirectBankTransfer.php
@@ -47,7 +47,6 @@ protected function performTransaction(BasePaymentType $payment, Bestellung $orde
);
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
// Update existing customer resource if needed
diff --git a/paymentmethod/UnzerGooglePay.php b/paymentmethod/UnzerGooglePay.php
index 71af85e..3c79eca 100644
--- a/paymentmethod/UnzerGooglePay.php
+++ b/paymentmethod/UnzerGooglePay.php
@@ -194,7 +194,6 @@ protected function performTransaction(BasePaymentType $payment, Bestellung $orde
);
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
// Update existing customer resource if needed
diff --git a/paymentmethod/UnzerPaylaterDirectDebit.php b/paymentmethod/UnzerPaylaterDirectDebit.php
index 018e711..5508e5b 100644
--- a/paymentmethod/UnzerPaylaterDirectDebit.php
+++ b/paymentmethod/UnzerPaylaterDirectDebit.php
@@ -10,6 +10,7 @@
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\CancelableInterface;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\HandleStepAdditionalInterface;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\HandleStepReviewOrderInterface;
+use Plugin\s360_unzer_shop5\src\Payments\Interfaces\RedirectPaymentInterface;
use Plugin\s360_unzer_shop5\src\Payments\Traits\CancelPaymentTransaction;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasAuthorization;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
@@ -22,6 +23,7 @@
use UnzerSDK\Resources\TransactionTypes\Authorization;
class UnzerPaylaterDirectDebit extends HeidelpayPaymentMethod implements
+ RedirectPaymentInterface,
HandleStepAdditionalInterface,
HandleStepReviewOrderInterface,
CancelableInterface
diff --git a/paymentmethod/UnzerPaylaterInstallment.php b/paymentmethod/UnzerPaylaterInstallment.php
index cef2a89..1ef2a5a 100644
--- a/paymentmethod/UnzerPaylaterInstallment.php
+++ b/paymentmethod/UnzerPaylaterInstallment.php
@@ -15,6 +15,7 @@
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\CancelableInterface;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\HandleStepAdditionalInterface;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\HandleStepReviewOrderInterface;
+use Plugin\s360_unzer_shop5\src\Payments\Interfaces\RedirectPaymentInterface;
use Plugin\s360_unzer_shop5\src\Payments\PaymentHandler;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasAuthorization;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
@@ -30,6 +31,7 @@
use UnzerSDK\Resources\TransactionTypes\Cancellation;
class UnzerPaylaterInstallment extends HeidelpayPaymentMethod implements
+ RedirectPaymentInterface,
HandleStepAdditionalInterface,
HandleStepReviewOrderInterface,
CancelableInterface
diff --git a/paymentmethod/UnzerPaylaterInvoice.php b/paymentmethod/UnzerPaylaterInvoice.php
index d054654..b3dc7ab 100644
--- a/paymentmethod/UnzerPaylaterInvoice.php
+++ b/paymentmethod/UnzerPaylaterInvoice.php
@@ -13,6 +13,7 @@
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\CancelableInterface;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\HandleStepAdditionalInterface;
use Plugin\s360_unzer_shop5\src\Payments\Interfaces\HandleStepReviewOrderInterface;
+use Plugin\s360_unzer_shop5\src\Payments\Interfaces\RedirectPaymentInterface;
use Plugin\s360_unzer_shop5\src\Payments\Traits\CancelPaymentTransaction;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasAuthorization;
use Plugin\s360_unzer_shop5\src\Payments\Traits\HasBasket;
@@ -31,6 +32,7 @@
use UnzerSDK\Resources\TransactionTypes\Authorization;
class UnzerPaylaterInvoice extends HeidelpayPaymentMethod implements
+ RedirectPaymentInterface,
HandleStepAdditionalInterface,
HandleStepReviewOrderInterface,
CancelableInterface
diff --git a/paymentmethod/UnzerTwint.php b/paymentmethod/UnzerTwint.php
index 145881e..d292eba 100644
--- a/paymentmethod/UnzerTwint.php
+++ b/paymentmethod/UnzerTwint.php
@@ -47,7 +47,6 @@ protected function performTransaction(BasePaymentType $payment, Bestellung $orde
);
$customer->setShippingAddress($this->createHeidelpayAddress($order->Lieferadresse));
$customer->setBillingAddress($this->createHeidelpayAddress($order->oRechnungsadresse));
- $customer->setCompanyInfo(null);
$this->debugLog('Customer Resource: ' . $customer->jsonSerialize(), static::class);
// Update existing customer resource if needed
diff --git a/src/Charges/ChargeHandler.php b/src/Charges/ChargeHandler.php
index 7c14bfc..88bff5d 100644
--- a/src/Charges/ChargeHandler.php
+++ b/src/Charges/ChargeHandler.php
@@ -179,6 +179,8 @@ public function addCharge(
Bestellung $order,
?int $deliveryId = null
): void {
+ $this->debugLog("Trying to add charge " . print_r($charge->jsonSerialize(), true) . " for order {$order->cBestellNr}", self::class);
+
// Charge is already marked as incoming payment -> skip!
if ($this->model->getChargeForOrder((int) $order->kBestellung, $charge->getId())) {
$paymentMethod->doLog(
@@ -191,7 +193,7 @@ public function addCharge(
if ($charge->isSuccess()) {
// Add Incoming Payment
- if ($this->config->get(Config::ADD_INCOMING_PAYMENTS, true)) {
+ if ($this->config->get(Config::ADD_INCOMING_PAYMENTS, 'on') === 'on') {
$paymentMethod->addIncomingPayment($order, (object) [
'fBetrag' => $charge->getAmount(),
'cISO' => $charge->getCurrency(),
@@ -245,7 +247,7 @@ public function markAsPaid(Payment $payment, HeidelpayPaymentMethod $paymentMeth
{
$this->debugLog(
"Check if order {$order->cBestellNr} should be marked as paid." .
- "Status: {$order->cStatus} | Add Incoming Payment: {$this->config->get(Config::ADD_INCOMING_PAYMENTS, true)}",
+ "Status: {$order->cStatus} | Add Incoming Payment: {$this->config->get(Config::ADD_INCOMING_PAYMENTS, true)} | Payment {$payment->jsonSerialize()}",
static::class
);
diff --git a/src/Controllers/Admin/AdminOrdersController.php b/src/Controllers/Admin/AdminOrdersController.php
index df63d4c..38ec58b 100644
--- a/src/Controllers/Admin/AdminOrdersController.php
+++ b/src/Controllers/Admin/AdminOrdersController.php
@@ -233,7 +233,6 @@ private function handleGetOrderDetails(): void
$this->model->save($orderMapping);
// Load View
- $url = $this->config->getInsightPortalUrl($orderMapping);
$orderMapping->setOrder(null);
$this->jsonResponse([
@@ -244,7 +243,6 @@ private function handleGetOrderDetails(): void
'hpOrderMapping' => $orderMapping,
'hpOrder' => $order,
'hpPayment' => $payment,
- 'hpPortalUrl' => $url,
'hpCancellations' => $cancellations
])
)
@@ -271,12 +269,10 @@ private function handleLoadOrders(): void
$order->getOrder()->Waehrung = new Currency((int)$order->getOrder()->kWaehrung);
}
- $url = $this->config->getInsightPortalUrl($order);
$data[] = new OrderViewStruct(
$order,
$this->view(self::TEMPLATE_ID_ORDER_ITEM, [
'hpOrder' => $order,
- 'hpPortalUrl' => $url
])
);
}
diff --git a/src/Controllers/Admin/AdminSettingsController.php b/src/Controllers/Admin/AdminSettingsController.php
index 4a5c744..967250d 100644
--- a/src/Controllers/Admin/AdminSettingsController.php
+++ b/src/Controllers/Admin/AdminSettingsController.php
@@ -97,7 +97,6 @@ protected function handleSaveRequest(): void
}
// Set Config
- $this->config->set(Config::MERCHANT_ID, Request::postVar('merchantId'));
$this->config->set(Config::FONT_SIZE, Request::postVar('fontSize'));
$this->config->set(Config::FONT_COLOR, Request::postVar('fontColor'));
$this->config->set(Config::FONT_FAMILY, Request::postVar('fontFamily'));
@@ -157,7 +156,7 @@ protected function handleSaveRequest(): void
if (empty($publicKey)) {
$this->addError(__('Ungültiger Public Key - eine leere Zeichenfolge ist nicht zulässig.'));
$valid = false;
- } elseif(!PublicKeyValidator::validate($publicKey)) {
+ } elseif (!PublicKeyValidator::validate($publicKey)) {
$this->addError(
__('Ungültiger Public Key. Bitte stellen Sie sicher, dass sie hier Ihren Public Key und nicht Ihren Private Key angeben!')
);
@@ -207,19 +206,15 @@ protected function saveChannelId(?string $channelId = null): void
*/
protected function registerWebhooks(HeidelpayApiAdapter $adapter): void
{
- $newEvents = array_keys(PaymentEventSubscriber::getSubscribedEvents());
-
- if (empty($newEvents)) {
- return;
- }
+ $newEvents = ['payment', 'charge'];
// Register for all keyparis + default
- try {
- $linkHelper = new JtlLinkHelper();
- $model = new KeyPairModel(Shop::Container()->getDB());
- $keypairs = $model->all();
+ $linkHelper = new JtlLinkHelper();
+ $model = new KeyPairModel(Shop::Container()->getDB());
+ $keypairs = $model->all();
- foreach ($keypairs as $keypair) {
+ foreach ($keypairs as $keypair) {
+ try {
$adapter->setCurrentConnection(
$keypair->isB2B(),
$keypair->getCurrencyId(),
@@ -228,8 +223,12 @@ protected function registerWebhooks(HeidelpayApiAdapter $adapter): void
$linkHelper->getFullFrontendFileUrl(JtlLinkHelper::FRONTEND_FILE_WEBHOOKS),
$newEvents
);
+ } catch (Exception $exc) {
+ $this->errorLog('Could not register webhook: ' . $exc->getMessage(), static::class);
}
+ }
+ try {
$adapter->getDefaultConnection()->registerMultipleWebhooks(
$linkHelper->getFullFrontendFileUrl(JtlLinkHelper::FRONTEND_FILE_WEBHOOKS),
$newEvents
diff --git a/src/Foundation/EventSubscriber.php b/src/Foundation/EventSubscriber.php
index d79cb9f..153ca88 100644
--- a/src/Foundation/EventSubscriber.php
+++ b/src/Foundation/EventSubscriber.php
@@ -37,14 +37,8 @@ public function handleEvent(EventPayload $payload): void
$events = static::getSubscribedEvents();
$event = $payload->getEvent();
- if (!array_key_exists($event, $events)) {
- throw new InvalidArgumentException('There is no event listener subscribed for event: ' . $event);
- }
-
- if (!method_exists($this, $events[$event])) {
- throw new InvalidArgumentException(
- 'The registered event listener ' . $events[$event] . ' for the event ' . $event . ' does not exist!'
- );
+ if (!array_key_exists($event, $events) || !method_exists($this, $events[$event])) {
+ return;
}
call_user_func([$this, $events[$event]], $payload);
diff --git a/src/Payments/HeidelpayPaymentMethod.php b/src/Payments/HeidelpayPaymentMethod.php
index fd78248..aba5b9b 100644
--- a/src/Payments/HeidelpayPaymentMethod.php
+++ b/src/Payments/HeidelpayPaymentMethod.php
@@ -6,6 +6,7 @@
use Exception;
use JTL\Alert\Alert;
use Plugin\s360_unzer_shop5\src\Foundation\ServiceProvider;
+use Plugin\s360_unzer_shop5\src\Utils\Logger;
use UnzerSDK\Exceptions\UnzerApiException;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
@@ -386,8 +387,22 @@ public function finalizeOrder(Bestellung $order, string $hash, array $args): boo
{
// Validate Payment Request (check: currency changed, order amount, cart checksum)
if (isset($args['state']) && $args['state'] == self::STATE_DURING_CHECKOUT) {
- $this->adapter->getConnectionForOrder($order);
- $payment = $this->adapter->fetchPayment();
+ try {
+ $this->adapter->getConnectionForOrder($order);
+ $payment = $this->adapter->fetchPayment();
+ } catch(Throwable $err) {
+ // For some reason we could not fetch the payment -> abort
+ Shop::Container()->getAlertService()->addError(
+ $this->plugin->getLocalization()->getTranslation(Config::LANG_CANCEL_BY_USER) ?? Config::LANG_CANCEL_BY_USER,
+ 'transactionError',
+ ['saveInSession' => true]
+ );
+
+ $this->setPayStatus(self::PAYSTATUS_FAILED);
+ $this->deletePaymentHash($hash);
+
+ return false;
+ }
// Invalid Request (basket, currency mismatch)
if (!$this->handler->validatePaymentRequest($payment)) {
@@ -403,13 +418,8 @@ public function finalizeOrder(Bestellung $order, string $hash, array $args): boo
$this->deletePaymentHash($hash);
$transaction = $this->adapter->getPaymentTransaction($payment);
- $this->sessionHelper->addErrorAlert(
- Text::convertUTF8($transaction->getMessage()->getMerchant()),
- Text::convertUTF8($transaction->getMessage()->getCustomer()),
- 'transactionError',
- null,
- static::class
- );
+ Shop::Container()->getAlertService()->addError(Text::convertUTF8($transaction->getMessage()->getCustomer()), 'transactionError', ['saveInSession' => true]);
+ Logger::error($transaction->getMessage()->getMerchant());
return false;
}
diff --git a/src/Payments/Traits/HasCustomer.php b/src/Payments/Traits/HasCustomer.php
index 07bbfb0..7602674 100644
--- a/src/Payments/Traits/HasCustomer.php
+++ b/src/Payments/Traits/HasCustomer.php
@@ -4,6 +4,10 @@
namespace Plugin\s360_unzer_shop5\src\Payments\Traits;
+use JTL\Shop;
+use UnzerSDK\Constants\CompanyCommercialSectorItems;
+use UnzerSDK\Constants\CompanyRegistrationTypes;
+use UnzerSDK\Constants\CompanyTypes;
use UnzerSDK\Resources\Customer;
use UnzerSDK\Resources\CustomerFactory;
use UnzerSDK\Resources\EmbeddedResources\Address;
@@ -18,6 +22,8 @@
use UnzerSDK\Constants\ShippingTypes;
use UnzerSDK\Exceptions\UnzerApiException;
+use UnzerSDK\Resources\EmbeddedResources\CompanyInfo;
+use UnzerSDK\Resources\EmbeddedResources\CompanyOwner;
use function Functional\first;
/**
@@ -61,32 +67,29 @@ protected function createOrFetchHeidelpayCustomer(
$customer->setCompany(Text::convertUTF8(html_entity_decode($frontSession->getCustomer()->cFirma)));
}
- $language = first(
- $this->sessionHelper->getFrontendSession()->getLanguages(),
- fn (LanguageModel $lang) => $lang->id === $this->sessionHelper->getFrontendSession()->getCustomer()->kSprache
- )?->getIso639();
-
- $customer->setLanguage(strtolower($language ?? $customer->getLanguage() ?? 'en'));
+ $this->setCustomerLanguage($customer);
// Update names as they might have changed (but not on B2B so that we do not overwrite the B2B Form changes)
if (!$isB2B) {
$customer->setFirstname(Text::convertUTF8(html_entity_decode($frontSession->getCustomer()->cVorname)));
$customer->setLastname(Text::convertUTF8(html_entity_decode($frontSession->getCustomer()->cNachname)));
- if ($customer->getShippingAddress()->getShippingType() === ShippingTypes::DIFFERENT_ADDRESS) {
- $customer->setFirstname(
- Text::convertUTF8(html_entity_decode($frontSession->getDeliveryAddress()->cVorname))
- );
- $customer->setLastname(
- Text::convertUTF8(html_entity_decode($frontSession->getDeliveryAddress()->cNachname))
- );
- }
-
// Remove Company Infomartion as we do not want to be treated as a B2B User
$customer->setCompany(null);
// $customer->setCompanyInfo(new CompanyInfo());
}
+ // UOPP-91: Set company info for b2b customers
+ if ($isB2B && $customer->getCompanyInfo() === null) {
+ $customer->setCompanyInfo(new CompanyInfo());
+ $customer->getCompanyInfo()
+ ->setRegistrationType(CompanyRegistrationTypes::REGISTRATION_TYPE_NOT_REGISTERED)
+ ->setFunction('OWNER')
+ ->setCommercialSector(CompanyCommercialSectorItems::OTHER)
+ ->setOwner((new CompanyOwner())->setFirstname($customer->getFirstname())->setLastname($customer->getLastname()))
+ ->setCompanyType(CompanyTypes::OTHER);
+ }
+
return $customer;
}
@@ -133,12 +136,7 @@ protected function createHeidelpayCustomer(ShopCustomer $customer): Customer
}
// Set user language
- $language = first(
- $this->sessionHelper->getFrontendSession()->getLanguages(),
- fn (LanguageModel $lang) => $lang->id === $this->sessionHelper->getFrontendSession()->getCustomer()->kSprache
- )?->getIso639();
-
- $customerObj->setLanguage(strtolower($language ?? 'en'));
+ $this->setCustomerLanguage($customerObj);
// Set external customer so we do not have to map it ourself.
if (!empty($customer->kKunde)) {
@@ -165,7 +163,8 @@ protected function createHeidelpayAddress($address): Address
->setStreet(Text::convertUTF8(html_entity_decode($address->cStrasse . ' ' . $address->cHausnummer)))
->setZip(Text::convertUTF8(html_entity_decode($address->cPLZ)))
->setCity(Text::convertUTF8(html_entity_decode($address->cOrt)))
- ->setCountry(Text::convertUTF8(html_entity_decode($address->cLand)));
+ ->setCountry(Text::convertUTF8(html_entity_decode($address->cLand)))
+ ->setCompany(!empty($address->cFirma) ? Text::convertUTF8(html_entity_decode($address->cFirma)) : null);
if (! $address instanceof \JTL\Customer\Customer) {
$address->setShippingType($type);
@@ -182,12 +181,18 @@ protected function createHeidelpayAddress($address): Address
*/
protected function createHeidelpayB2BCustomer(ShopCustomer $customer): Customer
{
+ // UOPP-91
+ $companyOwner = (new CompanyOwner())
+ ->setFirstname(Text::convertUTF8(html_entity_decode($customer->cVorname)))
+ ->setLastname(Text::convertUTF8(html_entity_decode($customer->cNachname)));
+
$address = (new Address())
->setName(Text::convertUTF8(html_entity_decode($customer->cVorname . ' ' . $customer->cNachname)))
->setStreet(Text::convertUTF8(html_entity_decode($customer->cStrasse . ' ' . $customer->cHausnummer)))
->setZip(Text::convertUTF8(html_entity_decode($customer->cPLZ)))
->setCity(Text::convertUTF8(html_entity_decode($customer->cOrt)))
- ->setCountry(Text::convertUTF8(html_entity_decode($customer->cLand)));
+ ->setCountry(Text::convertUTF8(html_entity_decode($customer->cLand)))
+ ->setCompany(!empty($customer->cFirma) ? Text::convertUTF8(html_entity_decode($customer->cFirma)) : null);
// Registered = registered in the commercial register with a commercial register number
if ($customer->cUSTID) {
@@ -201,11 +206,15 @@ protected function createHeidelpayB2BCustomer(ShopCustomer $customer): Customer
$obj->setLastname(Text::convertUTF8(html_entity_decode($customer->cNachname)));
$obj->setEmail($customer->cMail);
$obj->setCustomerId((string) $customer->kKunde);
+ $obj->getCompanyInfo()?->setOwner($companyOwner);
+ $obj->getCompanyInfo()?->setCompanyType(CompanyTypes::OTHER);
if (!empty($customer->cAnrede)) {
$obj->setSalutation($customer->cAnrede == 'm' ? 'mr' : ($customer->cAnrede == 'w' ? 'mrs' : null));
}
+ $this->setCustomerLanguage($obj);
+
return $obj;
}
@@ -224,6 +233,9 @@ protected function createHeidelpayB2BCustomer(ShopCustomer $customer): Customer
Text::convertUTF8(html_entity_decode($customer->cFirma))
);
$obj->setCustomerId((string) $customer->kKunde);
+ $obj->getCompanyInfo()?->setOwner($companyOwner);
+ $obj->getCompanyInfo()?->setCompanyType(CompanyTypes::OTHER);
+ $this->setCustomerLanguage($obj);
if (!empty($customer->cAnrede)) {
$obj->setSalutation($customer->cAnrede == 'm' ? 'mr' : ($customer->cAnrede == 'w' ? 'mrs' : null));
@@ -272,4 +284,14 @@ protected function getStreetFromAddress(Address $address): array
return $data;
}
+
+ private function setCustomerLanguage(Customer $customer): void
+ {
+ $language = first(
+ $this->sessionHelper->getFrontendSession()->getLanguages(),
+ fn (LanguageModel $lang) => $lang->id === ($this->sessionHelper->getFrontendSession()->getCustomer()->kSprache ?? Shop::getLanguageID())
+ )?->getIso639();
+
+ $customer->setLanguage(strtolower($language ?? 'en'));
+ }
}
diff --git a/src/Utils/Config.php b/src/Utils/Config.php
index 04ffdcc..cec9364 100644
--- a/src/Utils/Config.php
+++ b/src/Utils/Config.php
@@ -22,10 +22,6 @@ class Config
public const TABLE = 'xplugin_s360_unzer_shop5_config';
public const PLUGIN_ID = 's360_unzer_shop5';
public const PLUGIN_SESSION = 's360_heidelpay';
- public const HIP_URL = 'https://insights.unzer.com/merchant/{merchantId}/order/{id}';
- public const HIP_URL_SANDBOX = 'https://sbx-insights.unzer.com/merchant/{merchantId}/order/{id}';
- public const PAYLATER_PORTAL_URL = 'https://merchant.payolution.com/';
- public const PAYLATER_PORTAL_URL_SANDBOX = 'https://test-merchant.paylater.unzer.com/';
// Lang Var Keys
public const LANG_INVALID_TOKEN = 's360_hp_invalid_form_token';
@@ -44,6 +40,7 @@ class Config
public const LANG_ERROR_VALIDATING_MERCHANT = 's360_hp_error_validating_merchant';
public const LANG_APPLE_PAY_NOT_SUPPORTED = 's360_hp_apple_pay_not_supported';
public const LANG_APPLE_PAY_CANCEL_BY_USER = 's360_hp_apple_pay_cancel_by_user';
+ public const LANG_CANCEL_BY_USER = 's360_hp_cancel_by_user';
public const LANG_CANCEL_PAYMENT_REFERENCE = 's360_hp_cancel_payment_reference';
public const LANG_INSTLAMENT_INFO = 's360_hp_instalment_info';
public const LANG_COMPANY_TYPE_MISSING = 's360_hp_company_type_missing';
@@ -52,7 +49,6 @@ class Config
// Config Keys
public const PRIVATE_KEY = 'privateKey';
public const PUBLIC_KEY = 'publicKey';
- public const MERCHANT_ID = 'merchantId';
public const FONT_SIZE = 'fontSize';
public const FONT_COLOR = 'fontColor';
public const FONT_FAMILY = 'fontFamily';
@@ -259,31 +255,6 @@ public function getPaymentSetting(string $key, string $moduleId, ?PluginInterfac
return $plugin->getConfig()->getValue($moduleId . '_' . $key);
}
- /**
- * Get Insight Portal URL if merchant id is configured
- *
- * @param OrderMappingEntity|null $orderMapping
- * @return string|null
- */
- public function getInsightPortalUrl(?OrderMappingEntity $orderMapping): ?string
- {
- $merchantId = $this->get(self::MERCHANT_ID);
-
- if ($orderMapping->getPaymentTypeName() === 'paylater-invoice') {
- return $this->isSandbox() ? self::PAYLATER_PORTAL_URL_SANDBOX : self::PAYLATER_PORTAL_URL;
- }
-
- if (!empty($merchantId) && !empty($orderMapping->getTransactionUniqueId())) {
- return str_replace(
- ['{merchantId}', '{id}'],
- [$merchantId, $orderMapping->getTransactionUniqueId()],
- $this->isSandbox() ? self::HIP_URL_SANDBOX : self::HIP_URL
- );
- }
-
- return null;
- }
-
/**
* Check if api is in sandbox mode based on api keys
*
diff --git a/src/Webhooks/PaymentEventSubscriber.php b/src/Webhooks/PaymentEventSubscriber.php
index 876e944..3958844 100644
--- a/src/Webhooks/PaymentEventSubscriber.php
+++ b/src/Webhooks/PaymentEventSubscriber.php
@@ -4,6 +4,7 @@
namespace Plugin\s360_unzer_shop5\src\Webhooks;
+use Throwable;
use UnzerSDK\Constants\WebhookEvents;
use UnzerSDK\Resources\Payment;
use JTL\Shop;
@@ -15,6 +16,7 @@
use Plugin\s360_unzer_shop5\src\Payments\PaymentMethodModuleFactory;
use Plugin\s360_unzer_shop5\src\Utils\JtlLoggerTrait;
use RuntimeException;
+use UnzerSDK\Resources\TransactionTypes\Charge;
/**
* Heidelpay Payment Webhooks Event Subscriber
@@ -42,7 +44,8 @@ public static function getSubscribedEvents(): array
{
return [
WebhookEvents::PAYMENT_COMPLETED => 'onHandleIncomingPayment',
- WebhookEvents::PAYMENT_PARTLY => 'onHandleIncomingPayment'
+ WebhookEvents::PAYMENT_PARTLY => 'onHandleIncomingPayment',
+ WebhookEvents::CHARGE_SUCCEEDED => 'onHandleIncomingPayment',
];
}
@@ -66,20 +69,28 @@ public static function getSubscribedEvents(): array
*/
public function onHandleIncomingPayment(EventPayload $payload)
{
- /** @var Payment $payment */
- $payment = $payload->getResource();
- $this->debugLog('Handling incoming event ' . $payload->getEvent() . ' with: ' . $payment->jsonSerialize());
+ /** @var Payment|Charge $resource */
+ $payment = null;
+ $resource = $payload->getResource();
+ $this->debugLog('Handling incoming event ' . $payload->getEvent() . ' with: ' . $resource->jsonSerialize());
- $orderMapping = $this->model->findByPayment($payment->getId());
- $paymentMethod = $this->paymentMethodFactory->createForType(
- $payment->getPaymentType(),
- ['id-string' => $orderMapping->getPaymentTypeId()]
- );
+ if ($resource instanceof Charge) {
+ $payment = $resource->getPayment();
+ } elseif ($resource instanceof Payment) {
+ $payment = $resource;
+ }
+
+ if ($payment === null) {
+ $this->debugLog('Handling incoming event ' . $payload->getEvent() . ' without payment');
+ return;
+ }
- if (empty($orderMapping)) {
- throw new RuntimeException(
+ $orderMapping = $this->model->findByPayment($payment->getId());
+ if ($orderMapping === null) {
+ $this->debugLog(
'Cannot find order for payment ' . $payment->getId() . '. Maybe it is not mapped yet.'
);
+ return;
}
// The payment is completed, which means that a pending order can now be released.
@@ -96,11 +107,20 @@ public function onHandleIncomingPayment(EventPayload $payload)
$adapter = Shop::Container()->get(HeidelpayApiAdapter::class);
$api = $adapter->getConnectionForPublicKey($payload->getPublicKey());
+ $paymentMethod = $this->paymentMethodFactory->createForType(
+ $payment->getPaymentType(),
+ ['id-string' => $orderMapping->getPaymentTypeId()]
+ );
+
foreach ($payment->getCharges() as $charge) {
// we need to fetch the charge because the charge in the payment object might not contain all information.
// Especially the isError, isPending, isSuccess flags
- $charge = $api->fetchCharge($charge);
- $this->charges->addCharge($charge, $paymentMethod, $orderMapping->getOrder());
+ try {
+ $charge = $api->fetchCharge($charge);
+ $this->charges->addCharge($charge, $paymentMethod, $orderMapping->getOrder());
+ } catch (Throwable $exc) {
+ $this->errorLog("Could not handle charge {$charge->getId()} for order {$orderMapping->getJtlOrderNumber()}: " . $exc->getMessage());
+ }
}
// Mark order as paid if there is no remaining amount on the payment.
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 294ea2b..b1e497a 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -127,17 +127,17 @@
},
{
"name": "phpseclib/phpseclib",
- "version": "3.0.46",
- "version_normalized": "3.0.46.0",
+ "version": "3.0.53",
+ "version_normalized": "3.0.53.0",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
- "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6"
+ "reference": "511ddc8e352d5d1f1e33bea468b6f4ef48438cf9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
- "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/511ddc8e352d5d1f1e33bea468b6f4ef48438cf9",
+ "reference": "511ddc8e352d5d1f1e33bea468b6f4ef48438cf9",
"shasum": ""
},
"require": {
@@ -155,7 +155,7 @@
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
},
- "time": "2025-06-26T16:29:55+00:00",
+ "time": "2026-06-09T18:08:26+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -220,7 +220,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
- "source": "https://github.com/phpseclib/phpseclib/tree/3.0.46"
+ "source": "https://github.com/phpseclib/phpseclib/tree/3.0.53"
},
"funding": [
{
@@ -240,31 +240,31 @@
},
{
"name": "unzerdev/php-sdk",
- "version": "3.13.1",
- "version_normalized": "3.13.1.0",
+ "version": "4.0.1",
+ "version_normalized": "4.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/unzerdev/php-sdk.git",
- "reference": "0a26d70b33185d52e49b06cb500a6e01bb6f1087"
+ "reference": "a9344b823fbf5374cd49e07ab6352d385578299e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/unzerdev/php-sdk/zipball/0a26d70b33185d52e49b06cb500a6e01bb6f1087",
- "reference": "0a26d70b33185d52e49b06cb500a6e01bb6f1087",
+ "url": "https://api.github.com/repos/unzerdev/php-sdk/zipball/a9344b823fbf5374cd49e07ab6352d385578299e",
+ "reference": "a9344b823fbf5374cd49e07ab6352d385578299e",
"shasum": ""
},
"require": {
"ext-json": "*",
- "php": "~7.4.0|~8.0.0|~8.1.0|~8.2.0|~8.3.0|~8.4.0"
+ "php": "~8.1.0|~8.2.0|~8.3.0|~8.4.0|~8.5.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
- "phpunit/phpunit": ">6.5 <10.0"
+ "phpunit/phpunit": "^9.6"
},
"suggest": {
"ext-curl": "*"
},
- "time": "2025-09-23T14:21:50+00:00",
+ "time": "2026-05-15T13:48:06+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -280,7 +280,7 @@
"description": "This is the php sdk to connect to the Unzer rest API.",
"support": {
"email": "support@unzer.com",
- "source": "https://github.com/unzerdev/php-sdk/tree/3.13.1"
+ "source": "https://github.com/unzerdev/php-sdk/tree/4.0.1"
},
"install-path": "../unzerdev/php-sdk"
}
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index 07f5e42..dca2f4d 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 's360/s360_unzer_shop5',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
- 'reference' => '7003c4acea1ff6298834f293122048fcffe8814b',
+ 'reference' => 'ccda2fb95972aba588f2547b863c10d710c83457',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -29,9 +29,9 @@
'dev_requirement' => false,
),
'phpseclib/phpseclib' => array(
- 'pretty_version' => '3.0.46',
- 'version' => '3.0.46.0',
- 'reference' => '56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6',
+ 'pretty_version' => '3.0.53',
+ 'version' => '3.0.53.0',
+ 'reference' => '511ddc8e352d5d1f1e33bea468b6f4ef48438cf9',
'type' => 'library',
'install_path' => __DIR__ . '/../phpseclib/phpseclib',
'aliases' => array(),
@@ -40,16 +40,16 @@
's360/s360_unzer_shop5' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
- 'reference' => '7003c4acea1ff6298834f293122048fcffe8814b',
+ 'reference' => 'ccda2fb95972aba588f2547b863c10d710c83457',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'unzerdev/php-sdk' => array(
- 'pretty_version' => '3.13.1',
- 'version' => '3.13.1.0',
- 'reference' => '0a26d70b33185d52e49b06cb500a6e01bb6f1087',
+ 'pretty_version' => '4.0.1',
+ 'version' => '4.0.1.0',
+ 'reference' => 'a9344b823fbf5374cd49e07ab6352d385578299e',
'type' => 'library',
'install_path' => __DIR__ . '/../unzerdev/php-sdk',
'aliases' => array(),
diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php
index adfb472..4c3a5d6 100644
--- a/vendor/composer/platform_check.php
+++ b/vendor/composer/platform_check.php
@@ -4,8 +4,8 @@
$issues = array();
-if (!(PHP_VERSION_ID >= 80000)) {
- $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.';
+if (!(PHP_VERSION_ID >= 80100)) {
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
diff --git a/vendor/phpseclib/phpseclib/BACKERS.md b/vendor/phpseclib/phpseclib/BACKERS.md
index cafcf60..d9406b2 100644
--- a/vendor/phpseclib/phpseclib/BACKERS.md
+++ b/vendor/phpseclib/phpseclib/BACKERS.md
@@ -16,4 +16,5 @@ phpseclib ongoing development is made possible by [Tidelift](https://tidelift.co
- [istiak-tridip](https://github.com/istiak-tridip)
- [Anna Filina](https://github.com/afilina)
- [blakemckeeby](https://github.com/blakemckeeby)
-- [ssddanbrown](https://github.com/ssddanbrown)
\ No newline at end of file
+- [ssddanbrown](https://github.com/ssddanbrown)
+- Stefan Beck
\ No newline at end of file
diff --git a/vendor/phpseclib/phpseclib/README.md b/vendor/phpseclib/phpseclib/README.md
index 37cbcb9..1a7e3c7 100644
--- a/vendor/phpseclib/phpseclib/README.md
+++ b/vendor/phpseclib/phpseclib/README.md
@@ -29,6 +29,17 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 /
* Unstable API
* Do not use in production
+### 4.0
+
+* Expected Release Date: September 2026
+* Long term support (LTS) release
+* X509 split into separate X509, CRL, CSR and SPKAC classes
+* PFX and CMS classes added
+* All ASN1 classes are lazy loaded by default
+* Minimum PHP version: 8.1.0
+* PSR-4 autoloading with namespace rooted at `\phpseclib4`
+* Install via Composer: `composer require phpseclib/phpseclib:4.0.x-dev`
+
### 3.0
* Long term support (LTS) release
@@ -51,7 +62,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 /
* PHP4 compatible
* Composer compatible (PSR-0 autoloading)
* Install using Composer: `composer require phpseclib/phpseclib:~1.0`
-* [Download 1.0.23 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.23.zip/download)
+* [Download 1.0.25 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.25.zip/download)
## Security contact information
@@ -63,14 +74,22 @@ Need Support?
* [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib)
* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new)
-* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use)
## Special Thanks
-Special Thanks to our $50+ sponsors!:
+
+
+
+
+
+
+## Additional Thanks
- Allan Simon
+- [Anna Filina](https://afilina.com/)
+- delovelady
- [ChargeOver](https://chargeover.com/)
+-
## Contributing
diff --git a/vendor/phpseclib/phpseclib/SECURITY.md b/vendor/phpseclib/phpseclib/SECURITY.md
new file mode 100644
index 0000000..f8368b6
--- /dev/null
+++ b/vendor/phpseclib/phpseclib/SECURITY.md
@@ -0,0 +1,13 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| ------- | ------------------ |
+| 1.0.x | :white_check_mark: |
+| 2.0.x | :white_check_mark: |
+| 3.0.x | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
\ No newline at end of file
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php b/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php
index ad8f63b..7a56f7c 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php
@@ -356,9 +356,11 @@ public static function switchEndianness($x)
// from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
$p1 = ($b * 0x0802) & 0x22110;
$p2 = ($b * 0x8020) & 0x88440;
- $r .= chr(
- (($p1 | $p2) * 0x10101) >> 16
- );
+ $temp = ($p1 | $p2) * 0x10101;
+ if (is_float($temp)) {
+ $temp = (int) fmod($temp, 0x7FFFFFFF);
+ }
+ $r .= chr(($temp >> 16) & 0xFF);
}
}
return $r;
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
index 998cf8b..38df513 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
@@ -448,8 +448,8 @@ protected function setupKey()
protected static function initialize_static_variables()
{
if (is_float(self::$sbox[0x200])) {
- self::$sbox = array_map('intval', self::$sbox);
- self::$parray = array_map('intval', self::$parray);
+ self::$sbox = array_map([self::class, 'safe_intval'], self::$sbox);
+ self::$parray = array_map([self::class, 'safe_intval'], self::$parray);
}
parent::initialize_static_variables();
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php
index b2691b5..dc365aa 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php
@@ -279,10 +279,10 @@ protected static function quarterRound(&$a, &$b, &$c, &$d)
// xor'ing and rotation are all on the same line so i'm keeping it on the same
// line here as well
// @codingStandardsIgnoreStart
- $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 16);
- $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 12);
- $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 8);
- $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 7);
+ $a+= $b; $d = self::leftRotate(self::safe_intval($d) ^ self::safe_intval($a), 16);
+ $c+= $d; $b = self::leftRotate(self::safe_intval($b) ^ self::safe_intval($c), 12);
+ $a+= $b; $d = self::leftRotate(self::safe_intval($d) ^ self::safe_intval($a), 8);
+ $c+= $d; $b = self::leftRotate(self::safe_intval($b) ^ self::safe_intval($c), 7);
// @codingStandardsIgnoreEnd
}
@@ -357,424 +357,424 @@ protected static function salsa20($x)
// @codingStandardsIgnoreStart
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// columnRound
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12);
- $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8);
- $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7);
-
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12);
- $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8);
- $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7);
-
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12);
- $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8);
- $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7);
-
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12);
- $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8);
- $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 16);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 12);
+ $x0+= $x4; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x0), 8);
+ $x8+= $x12; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x8), 7);
+
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 16);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 12);
+ $x1+= $x5; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x1), 8);
+ $x9+= $x13; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x9), 7);
+
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 16);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 12);
+ $x2+= $x6; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x2), 8);
+ $x10+= $x14; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x10), 7);
+
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 16);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 12);
+ $x3+= $x7; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x3), 8);
+ $x11+= $x15; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x11), 7);
// rowRound
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12);
- $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8);
- $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7);
-
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12);
- $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8);
- $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7);
-
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12);
- $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8);
- $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7);
-
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12);
- $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8);
- $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 16);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 12);
+ $x0+= $x5; $x15 = self::leftRotate(self::safe_intval($x15) ^ self::safe_intval($x0), 8);
+ $x10+= $x15; $x5 = self::leftRotate(self::safe_intval($x5) ^ self::safe_intval($x10), 7);
+
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 16);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 12);
+ $x1+= $x6; $x12 = self::leftRotate(self::safe_intval($x12) ^ self::safe_intval($x1), 8);
+ $x11+= $x12; $x6 = self::leftRotate(self::safe_intval($x6) ^ self::safe_intval($x11), 7);
+
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 16);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 12);
+ $x2+= $x7; $x13 = self::leftRotate(self::safe_intval($x13) ^ self::safe_intval($x2), 8);
+ $x8+= $x13; $x7 = self::leftRotate(self::safe_intval($x7) ^ self::safe_intval($x8), 7);
+
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 16);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 12);
+ $x3+= $x4; $x14 = self::leftRotate(self::safe_intval($x14) ^ self::safe_intval($x3), 8);
+ $x9+= $x14; $x4 = self::leftRotate(self::safe_intval($x4) ^ self::safe_intval($x9), 7);
// @codingStandardsIgnoreEnd
$x0 += $z0;
@@ -794,6 +794,6 @@ protected static function salsa20($x)
$x14 += $z14;
$x15 += $z15;
- return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15);
+ return pack('V*', self::safe_intval($x0), self::safe_intval($x1), self::safe_intval($x2), self::safe_intval($x3), self::safe_intval($x4), self::safe_intval($x5), self::safe_intval($x6), self::safe_intval($x7), self::safe_intval($x8), self::safe_intval($x9), self::safe_intval($x10), self::safe_intval($x11), self::safe_intval($x12), self::safe_intval($x13), self::safe_intval($x14), self::safe_intval($x15));
}
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php
index a380e43..a8074cb 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php
@@ -79,18 +79,19 @@ abstract class AsymmetricKey
private static $invisiblePlugins = [];
/**
- * Available Engines
+ * Key Comment
*
- * @var boolean[]
+ * @var null|string
*/
- protected static $engines = [];
+ private $comment;
/**
- * Key Comment
+ * OpenSSL configuration file name.
*
- * @var null|string
+ * @see self::createKey()
+ * @var ?string
*/
- private $comment;
+ protected static $configFile;
/**
* @param string $type
@@ -119,6 +120,10 @@ protected static function initialize_static_variables()
self::$one = new BigInteger(1);
}
+ if (!isset(self::$configFile)) {
+ self::$configFile = dirname(__FILE__) . '/../../openssl.cnf';
+ }
+
self::loadPlugins('Keys');
if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') {
self::loadPlugins('Signature');
@@ -363,6 +368,18 @@ public static function getSupportedKeyFormats()
return self::$plugins[static::ALGORITHM]['Keys'];
}
+ /**
+ * Sets the OpenSSL config file path
+ *
+ * Set to the empty string to use the default config file
+ *
+ * @param string $val
+ */
+ public static function setOpenSSLConfigPath($val)
+ {
+ self::$configFile = $val;
+ }
+
/**
* Add a fileformat plugin
*
@@ -419,34 +436,28 @@ public function getComment()
}
/**
- * Tests engine validity
- *
+ * Force engine (useful for unit testing)
*/
- public static function useBestEngine()
+ public static function forceEngine($engine = null)
{
- static::$engines = [
- 'PHP' => true,
- 'OpenSSL' => extension_loaded('openssl'),
- // this test can be satisfied by either of the following:
- // http://php.net/manual/en/book.sodium.php
- // https://github.com/paragonie/sodium_compat
- 'libsodium' => function_exists('sodium_crypto_sign_keypair')
- ];
-
- return static::$engines;
+ if (!isset($engine)) {
+ static::$forcedEngine = null;
+ return;
+ }
+ switch ($engine) {
+ case 'PHP':
+ case 'OpenSSL':
+ case 'libsodium':
+ static::$forcedEngine = $engine;
+ break;
+ default:
+ throw new \InvalidArgumentException('Valid engines are null, PHP, OpenSSL or libsodium');
+ }
}
- /**
- * Flag to use internal engine only (useful for unit testing)
- *
- */
- public static function useInternalEngine()
+ public static function getForcedEngine()
{
- static::$engines = [
- 'PHP' => true,
- 'OpenSSL' => false,
- 'libsodium' => false
- ];
+ return static::$forcedEngine;
}
/**
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php
index ab7f050..6673ac5 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php
@@ -118,7 +118,7 @@ public static function load($key, $password = '')
return compact('type', 'publicKey', 'paddedKey');
}
- $parts = explode(' ', $key, 3);
+ $parts = preg_split("#[\t ]+#", $key, 3);
if (!isset($parts[1])) {
$key = base64_decode($parts[0]);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
index 2211a87..8971a80 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
@@ -565,7 +565,7 @@ protected static function wrapPrivateKey($key, $attr, $params, $password, $oid =
],
'privateKey' => $key
];
- if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') {
+ if ($oid != 'id-Ed25519' && $oid != 'id-Ed448' && $oid != 'id-X25519' && $oid != 'id-X448') {
$key['privateKeyAlgorithm']['parameters'] = $params;
}
if (!empty($attr)) {
@@ -682,7 +682,7 @@ protected static function wrapPublicKey($key, $params, $oid = null, array $optio
'publicKey' => "\0" . $key
];
- if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') {
+ if ($oid != 'id-Ed25519' && $oid != 'id-Ed448' && $oid != 'id-X25519' && $oid != 'id-X448') {
$key['publicKeyAlgorithm']['parameters'] = $params;
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php
index 35d7a7d..6e70be4 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php
@@ -666,6 +666,11 @@ protected static function initialize_static_variables()
{
if (!isset(self::$use_reg_intval)) {
switch (true) {
+ // PHP 8.5, per https://www.php.net/manual/en/migration85.incompatible.php, now emits a warning
+ // "when casting floats (or strings that look like floats) to int if they cannot be represented as one"
+ case PHP_VERSION_ID >= 80500 && PHP_INT_SIZE == 4:
+ self::$use_reg_intval = false;
+ break;
// PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
case !function_exists('php_uname'):
@@ -2591,7 +2596,7 @@ protected function unpad($text)
$length = ord($text[strlen($text) - 1]);
- if (!$length || $length > $this->block_size) {
+ if (!$length | ($length > $this->block_size)) {
throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})");
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
index 93d7ad2..d02d29e 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
@@ -673,14 +673,14 @@ private function processBlock($block, $mode)
{
static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
if (!$sbox1) {
- $sbox1 = array_map('intval', self::$sbox1);
- $sbox2 = array_map('intval', self::$sbox2);
- $sbox3 = array_map('intval', self::$sbox3);
- $sbox4 = array_map('intval', self::$sbox4);
- $sbox5 = array_map('intval', self::$sbox5);
- $sbox6 = array_map('intval', self::$sbox6);
- $sbox7 = array_map('intval', self::$sbox7);
- $sbox8 = array_map('intval', self::$sbox8);
+ $sbox1 = array_map([self::class, 'safe_intval'], self::$sbox1);
+ $sbox2 = array_map([self::class, 'safe_intval'], self::$sbox2);
+ $sbox3 = array_map([self::class, 'safe_intval'], self::$sbox3);
+ $sbox4 = array_map([self::class, 'safe_intval'], self::$sbox4);
+ $sbox5 = array_map([self::class, 'safe_intval'], self::$sbox5);
+ $sbox6 = array_map([self::class, 'safe_intval'], self::$sbox6);
+ $sbox7 = array_map([self::class, 'safe_intval'], self::$sbox7);
+ $sbox8 = array_map([self::class, 'safe_intval'], self::$sbox8);
/* Merge $shuffle with $[inv]ipmap */
for ($i = 0; $i < 256; ++$i) {
$shuffleip[] = self::$shuffle[self::$ipmap[$i]];
@@ -1243,9 +1243,9 @@ protected function setupKey()
$pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF];
// Reorder: odd bytes/even bytes. Push the result in key schedule.
- $val1 = ( $cp & intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) |
+ $val1 = ( $cp & self::safe_intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) |
(($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
- $val2 = (($cp << 8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) |
+ $val2 = (($cp << 8) & self::safe_intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) |
(($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
$keys[$des_round][self::ENCRYPT][ ] = $val1;
$keys[$des_round][self::DECRYPT][$ki - 1] = $val1;
@@ -1292,14 +1292,14 @@ protected function setupInlineCrypt()
$init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
if (!$sbox1) {
- $sbox1 = array_map("intval", self::$sbox1);
- $sbox2 = array_map("intval", self::$sbox2);
- $sbox3 = array_map("intval", self::$sbox3);
- $sbox4 = array_map("intval", self::$sbox4);
- $sbox5 = array_map("intval", self::$sbox5);
- $sbox6 = array_map("intval", self::$sbox6);
- $sbox7 = array_map("intval", self::$sbox7);
- $sbox8 = array_map("intval", self::$sbox8);'
+ $sbox1 = array_map(["' . self::class . '", "safe_intval"], self::$sbox1);
+ $sbox2 = array_map(["' . self::class . '", "safe_intval"], self::$sbox2);
+ $sbox3 = array_map(["' . self::class . '", "safe_intval"], self::$sbox3);
+ $sbox4 = array_map(["' . self::class .'", "safe_intval"], self::$sbox4);
+ $sbox5 = array_map(["' . self::class . '", "safe_intval"], self::$sbox5);
+ $sbox6 = array_map(["' . self::class . '", "safe_intval"], self::$sbox6);
+ $sbox7 = array_map(["' . self::class . '", "safe_intval"], self::$sbox7);
+ $sbox8 = array_map(["' . self::class . '", "safe_intval"], self::$sbox8);'
/* Merge $shuffle with $[inv]ipmap */ . '
for ($i = 0; $i < 256; ++$i) {
$shuffleip[] = self::$shuffle[self::$ipmap[$i]];
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php
index b230198..bab2e9a 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php
@@ -28,8 +28,14 @@
use phpseclib3\Crypt\DH\Parameters;
use phpseclib3\Crypt\DH\PrivateKey;
use phpseclib3\Crypt\DH\PublicKey;
+use phpseclib3\Crypt\EC\Curves\Curve25519;
+use phpseclib3\Crypt\EC\Curves\Curve448;
+use phpseclib3\Crypt\EC\Formats\Keys\PKCS1;
+use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\NoKeyLoadedException;
use phpseclib3\Exception\UnsupportedOperationException;
+use phpseclib3\File\ASN1;
+use phpseclib3\File\ASN1\Maps;
use phpseclib3\Math\BigInteger;
/**
@@ -295,21 +301,51 @@ public static function computeSecret($private, $public)
}
if ($private instanceof EC\PrivateKey) {
+ $privateCurve = $private->getCurve();
switch (true) {
case $public instanceof EC\PublicKey:
+ if ($privateCurve !== $public->getCurve()) {
+ throw new \InvalidArgumentException("The public key curve (" . $public->getCurve() . ") and private key curve ($privateCurve) need to match");
+ }
+ $orig = $public;
$public = $public->getEncodedCoordinates();
// fall-through
case is_string($public):
- $point = $private->multiply($public);
- switch ($private->getCurve()) {
- case 'Curve25519':
- case 'Curve448':
- $secret = $point;
- break;
- default:
- // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned
- $secret = substr($point, 1, (strlen($point) - 1) >> 1);
+ $forcedEngine = EC::getForcedEngine();
+ if ($forcedEngine === 'libsodium' && $privateCurve !== 'Curve25519') {
+ throw new BadConfigurationException('Engine libsodium is forced but can only used with Curve25519 for ECDH');
+ }
+ if (!isset($forcedEngine) || $forcedEngine === 'OpenSSL') {
+ // PHP 7.3.0 introduced the openssl_pkey_derive() function
+ // openssl_dh_computee_key() has been around since PHP 5.3.0+ BUT it did not support ECDH
+ // until PHP 8.1.0 / OpenSSL 3.0.0
+ if ($forcedEngine === 'OpenSSL' && !function_exists('openssl_pkey_derive')) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for ECDH');
+ }
+ if (function_exists('openssl_pkey_derive')) {
+ $privateStr = (string) $private->withPassword();
+ $publicStr = (string) (isset($orig) ? $orig : EC::convertPointToPublicKey($private->getCurve(), $public));
+ $result = openssl_pkey_derive($publicStr, $privateStr);
+ if ($result) {
+ return $result;
+ }
+ if ($forcedEngine === 'OpenSSL') {
+ // i suppose we _could_ try openssl_dh_compute_key() at this point
+ // quoting https://www.php.net/openssl-dh-compute-key "ECDH is only supported as of PHP 8.1.0 and OpenSSL 3.0.0". ie.
+ // PHP_VERSION_ID >= 80100 && OPENSSL_VERSION_NUMBER >= 0x3000000f
+ // but i think that's overkill. if openssl_pkey_derive() doesn't work it seems doubtful to me that openssl_dh_compute_key() would
+ throw new BadConfigurationException('Engine OpenSSL is forced but was unable to perform ECDH because of ' . openssl_error_string());
+ }
+ }
}
+ $curveName = $private->getCurve();
+ $isMontgomeryCurve = $curveName == 'Curve25519' || $curveName == 'Curve448';
+ if (!$isMontgomeryCurve) {
+ $public = EC::convertPointToPublicKey($curveName, $public, false);
+ }
+ $point = $private->multiply($public);
+ // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned
+ $secret = $isMontgomeryCurve ? $point : substr($point, 1, (strlen($point) - 1) >> 1);
/*
if (($secret[0] & "\x80") === "\x80") {
$secret = "\0$secret";
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php
index 92c777d..23c54df 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php
@@ -33,6 +33,7 @@
use phpseclib3\Crypt\DSA\Parameters;
use phpseclib3\Crypt\DSA\PrivateKey;
use phpseclib3\Crypt\DSA\PublicKey;
+use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Math\BigInteger;
@@ -87,6 +88,14 @@ abstract class DSA extends AsymmetricKey
*/
protected $sigFormat;
+ /**
+ * Forced Engine
+ *
+ * @var ?string
+ * @see parent::forceEngine()
+ */
+ protected static $forcedEngine = null;
+
/**
* Signature Format (Short)
*
@@ -110,10 +119,6 @@ public static function createParameters($L = 2048, $N = 224)
throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')');
}
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
-
switch (true) {
case $N == 160:
/*
@@ -185,15 +190,19 @@ public static function createKey(...$args)
{
self::initialize_static_variables();
+ if (self::$forcedEngine == 'libsodium') {
+ throw new BadConfigurationException('Engine ' . self::$forcedEngine . ' is forced but unsupported for DSA');
+ }
+
+ if (self::$forcedEngine == 'OpenSSL' && !defined('OPENSSL_KEYTYPE_DSA')) {
+ throw new BadConfigurationException("Engine OpenSSL is forced but unsupported for DSA");
+ }
+
$class = new \ReflectionClass(static::class);
if ($class->isFinal()) {
throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')');
}
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
-
if (count($args) == 2 && is_int($args[0]) && is_int($args[1])) {
$params = self::createParameters($args[0], $args[1]);
} elseif (count($args) == 1 && $args[0] instanceof Parameters) {
@@ -204,6 +213,33 @@ public static function createKey(...$args)
throw new InsufficientSetupException('Valid parameters are either two integers (L and N), a single DSA object or no parameters at all.');
}
+ // at this point the only two supported values for self::$forcedEngine are OpenSSL, PHP and null
+ // if it's either OpenSSL or null we'll use OpenSSL (if it's available)
+ if (self::$forcedEngine !== 'PHP' && defined('OPENSSL_KEYTYPE_DSA')) {
+ $config = [];
+ if (self::$configFile) {
+ $config['config'] = self::$configFile;
+ }
+ $dsa = openssl_pkey_new($config + [
+ 'private_key_type' => OPENSSL_KEYTYPE_DSA,
+ 'p' => $params->p,
+ 'q' => $params->q,
+ 'g' => $params->g,
+ ]);
+ if ($dsa && openssl_pkey_export($dsa, $privatekeystr, null, $config)) {
+ // clear the buffer of error strings stemming from a minimalistic openssl.cnf
+ // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up
+ while (openssl_error_string() !== false) {
+ }
+
+ return DSA::load($privatekeystr)
+ ->withHash($params->hash->getHash())
+ ->withSignatureFormat($params->shortFormat);
+ } elseif (isset(self::$forcedEngine)) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for DSA');
+ }
+ }
+
$private = new PrivateKey();
$private->p = $params->p;
$private->q = $params->q;
@@ -227,10 +263,6 @@ public static function createKey(...$args)
*/
protected static function onLoad(array $components)
{
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
-
if (!isset($components['x']) && !isset($components['y'])) {
$new = new Parameters();
} elseif (isset($components['x'])) {
@@ -276,22 +308,6 @@ public function getLength()
return ['L' => $this->p->getLength(), 'N' => $this->q->getLength()];
}
- /**
- * Returns the current engine being used
- *
- * @see self::useInternalEngine()
- * @see self::useBestEngine()
- * @return string
- */
- public function getEngine()
- {
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
- return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ?
- 'OpenSSL' : 'PHP';
- }
-
/**
* Returns the parameters
*
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php
index 800cfb3..77faff9 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php
@@ -66,10 +66,22 @@ public static function load($key, $password = '')
return $key;
}
- $key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP);
- if (is_array($key)) {
- return $key;
- }
+ // PKCS1 DSA public keys are not supported by phpseclib since they can't be used to do
+ // anything on their own. in order to verify a signature with DSA you need p, q, g and y.
+ // a PKCS1 DSA public key only has y. to verify a signature with a PKCS1 DSA public key
+ // you'd also need to load a PKCS1 DSA parameters file separately. like you'd need to
+ // load two files instead of just one. there's no other key format that phpseclib supports
+ // that has that requirement so building it in for PKCS1 DSA public keys seems excessive.
+ //
+ // the whole thing would be rather like an RSA public key having the modulo live in
+ // a separate file than the exponent.
+ //
+ // this isn't an issue for PKCS8 DSA public keys because those keys have the parameters
+ // included. eg. \phpseclib3\File\ASN1\Maps\SubjectPublicKeyInfo has "algorithm" and
+ // "subjectPublicKey" and "algorithm", in turn, has "algorithm" and "parameters". y
+ // is saved as "subjectPublicKey" and p, q and g are saved as "parameters".
+
+ //$key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP);
throw new \RuntimeException('Unable to perform ASN1 mapping');
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php
index 9025213..b30d913 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php
@@ -15,6 +15,7 @@
use phpseclib3\Crypt\DSA;
use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature;
use phpseclib3\Math\BigInteger;
+use phpseclib3\Exception\BadConfigurationException;
/**
* DSA Private Key
@@ -79,20 +80,34 @@ public function sign($message)
{
$format = $this->sigFormat;
- if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
- $signature = '';
- $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash());
+ if (self::$forcedEngine === 'libsodium') {
+ throw new BadConfigurationException('Engine libsodium is forced but unsupported for DSA');
+ }
- if ($result) {
- if ($this->shortFormat == 'ASN1') {
- return $signature;
- }
+ if (self::$forcedEngine === 'OpenSSL' && !function_exists('openssl_get_md_methods')) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for DSA');
+ }
- $loaded = ASN1Signature::load($signature);
- $r = $loaded['r'];
- $s = $loaded['s'];
+ if (function_exists('openssl_get_md_methods') && self::$forcedEngine !== 'PHP') {
+ if (in_array($this->hash->getHash(), openssl_get_md_methods())) {
+ $signature = '';
+ $result = openssl_sign($message, $signature, $this->withPassword()->toString('PKCS8'), $this->hash->getHash());
- return $format::save($r, $s);
+ if ($result) {
+ if ($this->shortFormat == 'ASN1') {
+ return $signature;
+ }
+
+ $loaded = ASN1Signature::load($signature);
+ $r = $loaded['r'];
+ $s = $loaded['s'];
+
+ return $format::save($r, $s);
+ } elseif (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but was unable to create signature because of ' . openssl_error_string());
+ }
+ } elseif (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for DSA / ' . $this->hash->getHash());
}
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php
index 3e16762..e7e7d7e 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php
@@ -14,6 +14,7 @@
use phpseclib3\Crypt\Common;
use phpseclib3\Crypt\DSA;
use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature;
+use phpseclib3\Exception\BadConfigurationException;
/**
* DSA Public Key
@@ -34,6 +35,14 @@ final class PublicKey extends DSA implements Common\PublicKey
*/
public function verify($message, $signature)
{
+ if (self::$forcedEngine === 'libsodium') {
+ throw new BadConfigurationException('Engine libsodium is forced but unsupported for DSA');
+ }
+
+ if (self::$forcedEngine === 'OpenSSL' && !function_exists('openssl_get_md_methods')) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for DSA');
+ }
+
$format = $this->sigFormat;
$params = $format::load($signature);
@@ -43,13 +52,17 @@ public function verify($message, $signature)
$r = $params['r'];
$s = $params['s'];
- if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
- $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature;
+ if (function_exists('openssl_get_md_methods') && self::$forcedEngine !== 'PHP') {
+ if (in_array($this->hash->getHash(), openssl_get_md_methods())) {
+ $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature;
- $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash());
+ $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash());
- if ($result != -1) {
- return (bool) $result;
+ if ($result != -1) {
+ return (bool) $result;
+ }
+ } elseif (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for DSA / ' . $this->hash->getHash());
}
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php
index dc82dd0..fa4d91a 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php
@@ -33,12 +33,15 @@
use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Crypt\EC\Curves\Curve25519;
+use phpseclib3\Crypt\EC\Curves\Curve448;
use phpseclib3\Crypt\EC\Curves\Ed25519;
use phpseclib3\Crypt\EC\Curves\Ed448;
use phpseclib3\Crypt\EC\Formats\Keys\PKCS1;
+use phpseclib3\Crypt\EC\Formats\Keys\PKCS8;
use phpseclib3\Crypt\EC\Parameters;
use phpseclib3\Crypt\EC\PrivateKey;
use phpseclib3\Crypt\EC\PublicKey;
+use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\Exception\UnsupportedOperationException;
@@ -74,13 +77,6 @@ abstract class EC extends AsymmetricKey
*/
protected $curve;
- /**
- * Signature Format
- *
- * @var string
- */
- protected $format;
-
/**
* Signature Format (Short)
*
@@ -130,6 +126,14 @@ abstract class EC extends AsymmetricKey
*/
protected $sigFormat;
+ /**
+ * Forced Engine
+ *
+ * @var ?string
+ * @see parent::forceEngine()
+ */
+ protected static $forcedEngine = null;
+
/**
* Create public / private key pair.
*
@@ -145,31 +149,7 @@ public static function createKey($curve)
throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')');
}
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
-
- $curve = strtolower($curve);
- if (self::$engines['libsodium'] && $curve == 'ed25519' && function_exists('sodium_crypto_sign_keypair')) {
- $kp = sodium_crypto_sign_keypair();
-
- $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp));
- //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp));
-
- $privatekey->curveName = 'Ed25519';
- //$publickey->curveName = $curve;
-
- return $privatekey;
- }
-
- $privatekey = new PrivateKey();
-
- $curveName = $curve;
- if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) {
- $curveName = ucfirst($curveName);
- } elseif (substr($curveName, 0, 10) == 'brainpoolp') {
- $curveName = 'brainpoolP' . substr($curveName, 10);
- }
+ $curveName = self::getCurveCase($curve);
$curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName;
if (!class_exists($curve)) {
@@ -180,6 +160,54 @@ public static function createKey($curve)
$curveName = $reflect->isFinal() ?
$reflect->getParentClass()->getShortName() :
$reflect->getShortName();
+ $curveEngineName = self::getOpenSSLCurveName(strtolower($curveName));
+
+ switch ($curveName) {
+ case 'Ed25519':
+ $providers = [
+ 'libsodium' => function_exists('sodium_crypto_sign_keypair'),
+ // OPENSSL_KEYTYPE_ED25519 introduced in PHP 8.4.0
+ 'OpenSSL' => defined('OPENSSL_KEYTYPE_ED25519'),
+ ];
+ break;
+ case 'Ed448':
+ // OPENSSL_KEYTYPE_ED448 introduced in PHP 8.4.0
+ $providers = ['OpenSSL' => defined('OPENSSL_KEYTYPE_ED448')];
+ break;
+ case 'Curve25519':
+ $providers = [
+ 'libsodium' => function_exists('sodium_crypto_box_publickey_from_secretkey'),
+ // OPENSSL_KEYTYPE_X25519 introduced in PHP 8.4.0
+ 'OpenSSL' => defined('OPENSSL_KEYTYPE_X25519'),
+ ];
+ break;
+ // OPENSSL_KEYTYPE_X448 introduced in PHP 8.4.0
+ case 'Curve448':
+ $providers = ['OpenSSL' => defined('OPENSSL_KEYTYPE_X448')];
+ break;
+ default:
+ // openssl_get_curve_names() was introduced in PHP 7.1.0
+ // exclude curve25519 and curve448 from testing
+ $providers = ['OpenSSL' => function_exists('openssl_get_curve_names') && substr($curveEngineName, 0, 5) != 'curve' && in_array($curveEngineName, openssl_get_curve_names())];
+ };
+
+ foreach ($providers as $engine => $isSupported) {
+ // if an engine is being forced and the forced engine doesn't match $engine, skip it
+ if (isset(self::$forcedEngine) && self::$forcedEngine !== $engine) {
+ continue;
+ }
+ if ($isSupported) {
+ $result = self::generateWithEngine($engine, $curveEngineName);
+ if (isset($result)) {
+ return $result;
+ }
+ }
+ if (self::$forcedEngine === $engine) {
+ throw new BadConfigurationException("EC::createKey: Engine $engine is forced but unsupported for $curve");
+ }
+ }
+
+ $privatekey = new PrivateKey();
$curve = new $curve();
if ($curve instanceof TwistedEdwardsCurve) {
@@ -189,21 +217,14 @@ public static function createKey($curve)
} else {
$privatekey->dA = $dA = $curve->createRandomMultiplier();
}
- if ($curve instanceof Curve25519 && self::$engines['libsodium']) {
- //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000');
- //$QA = sodium_crypto_scalarmult($dA->toBytes(), $r);
- $QA = sodium_crypto_box_publickey_from_secretkey($dA->toBytes());
- $privatekey->QA = [$curve->convertInteger(new BigInteger(strrev($QA), 256))];
- } else {
- $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA);
- }
$privatekey->curve = $curve;
+ $privatekey->curveName = $curveName;
+ $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA);
//$publickey = clone $privatekey;
//unset($publickey->dA);
//unset($publickey->x);
- $privatekey->curveName = $curveName;
//$publickey->curveName = $curveName;
if ($privatekey->curve instanceof TwistedEdwardsCurve) {
@@ -213,6 +234,130 @@ public static function createKey($curve)
return $privatekey;
}
+ /**
+ * Returns the actual case of the curve
+ *
+ * Useful for initializing the curve class
+ *
+ * @param string $curveName
+ * @return string
+ */
+ private static function getCurveCase($curveName)
+ {
+ $curveName = strtolower($curveName);
+ if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) {
+ return ucfirst($curveName);
+ }
+ if (substr($curveName, 0, 10) == 'brainpoolp') {
+ return 'brainpoolP' . substr($curveName, 10);
+ }
+ return $curveName;
+ }
+
+ /**
+ * Return the OpenSSL name for a curve
+ *
+ * @param string $curve
+ * @return string
+ */
+ private static function getOpenSSLCurveName($curve)
+ {
+ switch ($curve) {
+ case 'secp256r1':
+ return 'prime256v1';
+ case 'secp192r1':
+ return 'prime192v1';
+ }
+ return $curve;
+ }
+
+ /**
+ * Generate the key for a given curve / engine combo
+ *
+ * @param string $engine
+ * @param string $curve
+ * @return ?PrivateKey
+ */
+ private static function generateWithEngine($engine, $curve)
+ {
+ if ($engine == 'libsodium') {
+ if ($curve == 'ed25519') {
+ $kp = sodium_crypto_sign_keypair();
+
+ $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp));
+ //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp));
+
+ $privatekey->curveName = 'Ed25519';
+ //$publickey->curveName = $curve;
+
+ return $privatekey;
+ } else { // $curve == 'curve25519
+ $privatekey = new PrivateKey();
+ $privatekey->curve = new Curve25519();
+ $privatekey->curveName = 'Curve25519';
+ $privatekey->dA = $privatekey->curve->createRandomMultiplier();
+ $dA = str_pad($privatekey->dA->toBytes(), 32, "\0", STR_PAD_LEFT);
+ //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000');
+ //$QA = sodium_crypto_scalarmult($dA, $r);
+ $QA = sodium_crypto_box_publickey_from_secretkey($dA);
+ $privatekey->QA = [$privatekey->curve->convertInteger(new BigInteger(strrev($QA), 256))];
+ return $privatekey;
+ }
+ }
+
+ // at this point $engine == 'OpenSSL'
+
+ $curveName = self::getCurveCase($curve);
+
+ $config = [];
+ if (self::$configFile) {
+ $config['config'] = self::$configFile;
+ }
+ $params = $config;
+ switch ($curve) {
+ case 'ed25519':
+ $params['private_key_type'] = OPENSSL_KEYTYPE_ED25519;
+ break;
+ case 'ed448':
+ $params['private_key_type'] = OPENSSL_KEYTYPE_ED448;
+ break;
+ case 'curve25519':
+ $params['private_key_type'] = OPENSSL_KEYTYPE_X25519;
+ break;
+ case 'curve448':
+ $params['private_key_type'] = OPENSSL_KEYTYPE_X448;
+ break;
+ default:
+ $params['private_key_type'] = OPENSSL_KEYTYPE_EC;
+ $params['curve_name'] = $curveName;
+ }
+
+ $key = openssl_pkey_new($params);
+ if (!$key) {
+ return null;
+ }
+ $privateKeyStr = '';
+ if (!openssl_pkey_export($key, $privateKeyStr, null, $config)) {
+ return null;
+ }
+ // clear the buffer of error strings
+ while (openssl_error_string() !== false) {
+ }
+ // some versions of OpenSSL / PHP return PKCS1 keys, others return PKCS8 keys
+ $privatekey = EC::load($privateKeyStr);
+ switch ($curveName) {
+ case 'prime256v1':
+ $privatekey->curveName = 'secp256r1';
+ break;
+ case 'prime192v1':
+ $privatekey->curveName = 'secp192r1';
+ break;
+ default:
+ $privatekey->curveName = $curveName;
+ }
+ return $privatekey;
+ }
+
/**
* OnLoad Handler
*
@@ -220,10 +365,6 @@ public static function createKey($curve)
*/
protected static function onLoad(array $components)
{
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
-
if (!isset($components['dA']) && !isset($components['QA'])) {
$new = new Parameters();
$new->curve = $components['curve'];
@@ -321,42 +462,63 @@ public function getLength()
}
/**
- * Returns the current engine being used
+ * Returns the public key coordinates as a string
+ *
+ * Used by ECDH
*
- * @see self::useInternalEngine()
- * @see self::useBestEngine()
* @return string
*/
- public function getEngine()
+ public function getEncodedCoordinates()
{
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
+ if ($this->curve instanceof MontgomeryCurve) {
+ return strrev($this->QA[0]->toBytes(true));
}
if ($this->curve instanceof TwistedEdwardsCurve) {
- return $this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context) ?
- 'libsodium' : 'PHP';
+ return $this->curve->encodePoint($this->QA);
}
-
- return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ?
- 'OpenSSL' : 'PHP';
+ return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true);
}
/**
- * Returns the public key coordinates as a string
+ * Convert point to public key
*
- * Used by ECDH
+ * For Weierstrass curves, if only the x coordinate is present (as is the case after doing a round of ECDH)
+ * then we'll guess at the y coordinate. There are only two possible y values and, atleast in-so-far as
+ * multiplication is concerned, neither value affects the resultant x value
*
- * @return string
+ * If $toPublicKey is set to false then a string will be returned - a kind of public key precursor
+ *
+ * @param string $curveName
+ * @param string $secret
+ * @param bool $toPublicKey optional
+ * @return PublicKey|string
*/
- public function getEncodedCoordinates()
+ public static function convertPointToPublicKey($curveName, $secret, $toPublicKey = true)
{
- if ($this->curve instanceof MontgomeryCurve) {
- return strrev($this->QA[0]->toBytes(true));
+ $curveName = self::getCurveCase($curveName);
+ $curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName;
+
+ if (!class_exists($curve)) {
+ throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported');
}
- if ($this->curve instanceof TwistedEdwardsCurve) {
- return $this->curve->encodePoint($this->QA);
+
+ $curve = new $curve();
+ if (!$curve instanceof TwistedEdwardsCurve) {
+ if ($curve instanceof MontgomeryCurve) {
+ $secret = strrev($secret);
+ } elseif ($curve->getLengthInBytes() == strlen($secret)) {
+ $secret = "\3$secret";
+ }
+ if (!$toPublicKey) {
+ return $secret;
+ }
+ $secret = "\0$secret";
+ } elseif (!$toPublicKey) {
+ return $secret;
}
- return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true);
+ $QA = PKCS8::extractPoint($secret, $curve);
+ $key = PKCS8::savePublicKey($curve, $QA);
+ return EC::loadFormat('PKCS8', $key);
}
/**
@@ -463,18 +625,4 @@ public function withHash($hash)
return parent::withHash($hash);
}
-
- /**
- * __toString() magic method
- *
- * @return string
- */
- public function __toString()
- {
- if ($this->curve instanceof MontgomeryCurve) {
- return '';
- }
-
- return parent::__toString();
- }
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php
index 0f3f4d8..0aa81c8 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php
@@ -18,6 +18,8 @@
class Curve25519 extends Montgomery
{
+ const SIZE = 32;
+
public function __construct()
{
// 2^255 - 19
@@ -47,10 +49,12 @@ public function __construct()
*/
public function multiplyPoint(array $p, BigInteger $d)
{
- //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes())));
+ $d = $d->toBytes();
+ $d = str_pad($d, 32, "\0", STR_PAD_LEFT);
+
+ //$r = strrev(sodium_crypto_scalarmult($d, strrev($p[0]->toBytes())));
//return [$this->factory->newInteger(new BigInteger($r, 256))];
- $d = $d->toBytes();
$d &= "\xF8" . str_repeat("\xFF", 30) . "\x7F";
$d = strrev($d);
$d |= "\x40";
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php
index f4a4423..3a042e5 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php
@@ -18,6 +18,8 @@
class Curve448 extends Montgomery
{
+ const SIZE = 56;
+
public function __construct()
{
// 2^448 - 2^224 - 1
@@ -58,10 +60,12 @@ public function __construct()
*/
public function multiplyPoint(array $p, BigInteger $d)
{
- //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes())));
+ $d = $d->toBytes();
+ $d = str_pad($d, 56, "\0", STR_PAD_LEFT);
+
+ //$r = strrev(sodium_crypto_scalarmult($d, strrev($p[0]->toBytes())));
//return [$this->factory->newInteger(new BigInteger($r, 256))];
- $d = $d->toBytes();
$d[0] = $d[0] & "\xFC";
$d = strrev($d);
$d |= "\x80";
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php
index 743c07c..bf62d63 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php
@@ -16,6 +16,7 @@
use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve;
+use phpseclib3\Crypt\EC\BaseCurves\Montgomery;
use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Exception\UnsupportedCurveException;
@@ -274,6 +275,9 @@ protected static function loadCurveByParam(array $params)
*/
public static function extractPoint($str, BaseCurve $curve)
{
+ if ($curve instanceof Montgomery) {
+ return [new BigInteger($str, 256)];
+ }
if ($curve instanceof TwistedEdwardsCurve) {
// first step of point deciding as discussed at the following URL's:
// https://tools.ietf.org/html/rfc8032#section-5.1.3
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php
index aa64f79..533259d 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php
@@ -96,6 +96,6 @@ public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $c
throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption');
}
- return $privateKey->toBytes();
+ return str_pad($privateKey->toBytes(), $curve::SIZE, "\0", STR_PAD_RIGHT);
}
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php
index 0ef1160..5310d5a 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php
@@ -111,6 +111,9 @@ private static function getAlias(BaseCurve $curve)
$reflect = new \ReflectionClass($curve);
$name = $reflect->getShortName();
+ if (!isset(self::$curveOIDs[$name])) {
+ throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports');
+ }
$oid = self::$curveOIDs[$name];
$aliases = array_filter(self::$curveOIDs, function ($v) use ($oid) {
return $v == $oid;
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
index 9fc8405..c25d5a6 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
@@ -23,10 +23,13 @@
namespace phpseclib3\Crypt\EC\Formats\Keys;
+use phpseclib3\Math\Common\FiniteField\Integer;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
+use phpseclib3\Crypt\EC\Curves\Curve25519;
+use phpseclib3\Crypt\EC\Curves\Curve448;
use phpseclib3\Crypt\EC\Curves\Ed25519;
use phpseclib3\Crypt\EC\Curves\Ed448;
use phpseclib3\Exception\UnsupportedCurveException;
@@ -48,14 +51,14 @@ abstract class PKCS8 extends Progenitor
*
* @var array
*/
- const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448'];
+ const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448', 'id-X25519', 'id-X448'];
/**
* OID Value
*
* @var string
*/
- const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113'];
+ const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113', '1.3.101.110', '1.3.101.111'];
/**
* Break a public or private key down into its constituent components
@@ -81,6 +84,9 @@ public static function load($key, $password = '')
case 'id-Ed25519':
case 'id-Ed448':
return self::loadEdDSA($key);
+ case 'id-X25519':
+ case 'id-X448':
+ return self::loadECDH($key);
}
$decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element);
@@ -158,20 +164,64 @@ private static function loadEdDSA(array $key)
return $components;
}
+ private static function loadECDH(array $key)
+ {
+ $components = [];
+
+ if (isset($key['privateKey'])) {
+ $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-X25519' ? new Curve25519() : new Curve448();
+ $expected = chr(ASN1::TYPE_OCTET_STRING) . ASN1::encodeLength($components['curve']::SIZE);
+ $privateKey = (string) $key['privateKey'];
+ if (substr($privateKey, 0, 2) != $expected) {
+ throw new \RuntimeException(
+ 'The first two bytes of the ' .
+ $key['privateKeyAlgorithm']['algorithm'] .
+ ' private key field should be 0x' . bin2hex($expected)
+ );
+ }
+ $components['dA'] = new BigInteger(substr($privateKey, 2), 256);
+ }
+
+ if (isset($key['publicKey'])) {
+ if (!isset($components['curve'])) {
+ $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-X25519' ? new Curve25519() : new Curve448();
+ }
+
+ $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($key['publicKey']), 256))];
+ }
+
+ if (isset($key['privateKey']) && !isset($components['QA'])) {
+ if ($components['curve'] instanceof Curve25519 && function_exists('sodium_crypto_box_publickey_from_secretkey')) {
+ //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000');
+ //$QA = sodium_crypto_scalarmult($components['dA']->toBytes(), $r);
+ $QA = sodium_crypto_box_publickey_from_secretkey(str_pad($components['dA']->toBytes(), 32, chr(0), STR_PAD_LEFT));
+ $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($QA), 256))];
+ } else {
+ $components['QA'] = [$components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA'])[0]];
+ }
+ }
+
+ return $components;
+ }
+
/**
* Convert an EC public key to the appropriate format
*
* @param BaseCurve $curve
- * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
+ * @param Integer[] $publicKey
* @param array $options optional
* @return string
*/
public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = [])
{
self::initialize_static_variables();
-
if ($curve instanceof MontgomeryCurve) {
- throw new UnsupportedCurveException('Montgomery Curves are not supported');
+ return self::wrapPublicKey(
+ str_pad(strrev($publicKey[0]->toBytes()), $curve::SIZE, "\0", STR_PAD_RIGHT),
+ null,
+ $curve instanceof Curve25519 ? 'id-X25519' : 'id-X448',
+ $options
+ );
}
if ($curve instanceof TwistedEdwardsCurve) {
@@ -206,7 +256,13 @@ public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve,
self::initialize_static_variables();
if ($curve instanceof MontgomeryCurve) {
- throw new UnsupportedCurveException('Montgomery Curves are not supported');
+ return self::wrapPrivateKey(
+ chr(ASN1::TYPE_OCTET_STRING) . ASN1::encodeLength($curve::SIZE) . str_pad($privateKey->toBytes(), $curve::SIZE, "\0", STR_PAD_LEFT),
+ [],
+ null,
+ $password,
+ $curve instanceof Curve25519 ? 'id-X25519' : 'id-X448'
+ );
}
if ($curve instanceof TwistedEdwardsCurve) {
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php
index 9947bb7..383e8e0 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php
@@ -21,6 +21,7 @@
use phpseclib3\Crypt\EC\Formats\Keys\PKCS1;
use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature;
use phpseclib3\Crypt\Hash;
+use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\UnsupportedOperationException;
use phpseclib3\Math\BigInteger;
@@ -59,18 +60,34 @@ final class PrivateKey extends EC implements Common\PrivateKey
*/
public function multiply($coordinates)
{
- if ($this->curve instanceof MontgomeryCurve) {
- if ($this->curve instanceof Curve25519 && self::$engines['libsodium']) {
- return sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates);
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is not supported for the multiplication operation');
+ }
+
+ if (self::$forcedEngine === 'libsodium' && !$this->curve instanceof Curve25519) {
+ throw new BadConfigurationException('Engine libsodium is only supported for Curve25519');
+ }
+
+ if ($this->curve instanceof Curve25519 && self::$forcedEngine !== 'PHP') {
+ if (self::$forcedEngine === 'libsodium' && !function_exists('sodium_crypto_scalarmult')) {
+ throw new BadConfigurationException('Engine libsodium is forced but unsupported for Curve25519');
+ }
+ if (function_exists('sodium_crypto_scalarmult')) {
+ $dA = str_pad($this->dA->toBytes(), 32, "\0", STR_PAD_LEFT);
+ return sodium_crypto_scalarmult($dA, $coordinates);
}
+ }
+ if ($this->curve instanceof MontgomeryCurve) {
$point = [$this->curve->convertInteger(new BigInteger(strrev($coordinates), 256))];
$point = $this->curve->multiplyPoint($point, $this->dA);
return strrev($point[0]->toBytes(true));
}
+
if (!$this->curve instanceof TwistedEdwardsCurve) {
$coordinates = "\0$coordinates";
}
+
$point = PKCS1::extractPoint($coordinates, $this->curve);
$point = $this->curve->multiplyPoint($point, $this->dA);
if ($this->curve instanceof TwistedEdwardsCurve) {
@@ -104,11 +121,56 @@ public function sign($message)
return false;
}
- if ($this->curve instanceof TwistedEdwardsCurve) {
- if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) {
+ if (self::$forcedEngine === 'libsodium' && !$this->curve instanceof Ed25519) {
+ throw new BadConfigurationException('Engine libsodium is only supported for Ed25519');
+ }
+
+ // at this point either self::$forcedEngine is NOT libsodium or the curve is Ed25519
+
+ if ($this->curve instanceof Ed25519 && self::$forcedEngine !== 'PHP' && self::$forcedEngine !== 'OpenSSL') {
+ if (self::$forcedEngine === 'libsodium') {
+ if (!function_exists('sodium_crypto_sign_detached')) {
+ throw new BadConfigurationException('Engine libsodium is forced but unsupported for Ed25519 / Ed448');
+ }
+ if (isset($this->context)) {
+ throw new BadConfigurationException('Engine libsodium is forced but unsupported for Ed25519ctx (context)');
+ }
+ }
+ if (function_exists('sodium_crypto_sign_detached') && !isset($this->context)) {
$result = sodium_crypto_sign_detached($message, $this->withPassword()->toString('libsodium'));
return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result) : $result;
}
+ }
+
+ // at this point self::$forcedEngine CAN'T be libsodium so we won't check for it henceforth
+
+ if ($this->curve instanceof TwistedEdwardsCurve) {
+ if (self::$forcedEngine !== 'PHP') {
+ $keyTypeConstant = $this->curve instanceof Ed25519 ? 'OPENSSL_KEYTYPE_ED25519' : 'OPENSSL_KEYTYPE_ED448';
+ if (self::$forcedEngine === 'OpenSSL') {
+ if (!defined($keyTypeConstant)) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for Ed25519 / Ed448');
+ }
+ // OpenSSL supports Ed25519/Ed448 but not Ed25519ctx (context), so skip if context is set
+ if (isset($this->context)) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for Ed25519 / Ed448 curves with context\'s');
+ }
+ }
+ if (defined($keyTypeConstant) && !isset($this->context)) {
+ $result = '';
+ // algorithm 0 is used because EdDSA has a built-in hash
+ openssl_sign($message, $result, $this->withPassword()->toString('PKCS8'), 0);
+ if ($result) {
+ $signature = $shortFormat == 'SSH2'
+ ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result)
+ : $result;
+ return $signature;
+ }
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but was unable to create signature because of ' . openssl_error_string());
+ }
+ }
+ }
// contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not.
// quoting https://tools.ietf.org/html/rfc8032#section-8.5 ,
@@ -143,26 +205,37 @@ public function sign($message)
return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $R . $S) : $R . $S;
}
- if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
- $signature = '';
- // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long
- // supported signing / verification
- // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve;
- // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even
- // has curve-specific optimizations
- $result = openssl_sign($message, $signature, $this->withPassword()->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash());
-
- if ($result) {
- if ($shortFormat == 'ASN1') {
- return $signature;
- }
-
- $loaded = ASN1Signature::load($signature);
- $r = $loaded['r'];
- $s = $loaded['s'];
-
+ if (self::$forcedEngine === 'OpenSSL' && !function_exists('openssl_get_md_methods')) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for ECDSA');
+ }
- return $this->formatSignature($r, $s);
+ // at this point $forcedEngine is either PHP or null. either that OR openssl_get_md_methods() exists
+
+ if (self::$forcedEngine !== 'PHP') {
+ if (in_array($this->hash->getHash(), openssl_get_md_methods())) {
+ $signature = '';
+ // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long
+ // supported signing / verification
+ // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve;
+ // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even
+ // has curve-specific optimizations
+ $result = openssl_sign($message, $signature, $this->withPassword()->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash());
+
+ if ($result) {
+ if ($shortFormat == 'ASN1') {
+ return $signature;
+ }
+
+ $loaded = ASN1Signature::load($signature);
+ $r = $loaded['r'];
+ $s = $loaded['s'];
+
+ return $this->formatSignature($r, $s);
+ } elseif (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but was unable to create signature because of ' . openssl_error_string());
+ }
+ } elseif (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for ECDSA / ' . $this->hash->getHash());
}
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php
index d34c6c4..2201497 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php
@@ -20,6 +20,7 @@
use phpseclib3\Crypt\EC\Formats\Keys\PKCS1;
use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature;
use phpseclib3\Crypt\Hash;
+use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\UnsupportedOperationException;
use phpseclib3\Math\BigInteger;
@@ -52,17 +53,62 @@ public function verify($message, $signature)
return false;
}
- $order = $this->curve->getOrder();
+ if (self::$forcedEngine === 'libsodium' && !$this->curve instanceof Ed25519) {
+ throw new BadConfigurationException('Engine libsodium is only supported for Ed25519');
+ }
+
+ // at this point either self::$forcedEngine is NOT libsodium or the curve is Ed25519
+
+ if ($this->curve instanceof Ed25519 && self::$forcedEngine !== 'PHP' && self::$forcedEngine !== 'OpenSSL') {
+ if (self::$forcedEngine === 'libsodium') {
+ if (!function_exists('sodium_crypto_sign_verify_detached')) {
+ throw new BadConfigurationException('Engine libsodium is forced but unsupported for Ed25519 / Ed448');
+ }
+ if (isset($this->context)) {
+ throw new BadConfigurationException('Engine libsodium is forced but unsupported for Ed25519ctx (context)');
+ }
+ }
+ if (function_exists('sodium_crypto_sign_verify_detached') && !isset($this->context)) {
+ if ($shortFormat == 'SSH2') {
+ list(, $signature) = Strings::unpackSSH2('ss', $signature);
+ }
+
+ return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium'));
+ }
+ }
+
+ // at this point self::$forcedEngine CAN'T be libsodium so we won't check for it henceforth
if ($this->curve instanceof TwistedEdwardsCurve) {
if ($shortFormat == 'SSH2') {
list(, $signature) = Strings::unpackSSH2('ss', $signature);
}
- if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) {
- return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium'));
+ if (self::$forcedEngine !== 'PHP') {
+ $keyTypeConstant = $this->curve instanceof Ed25519 ? 'OPENSSL_KEYTYPE_ED25519' : 'OPENSSL_KEYTYPE_ED448';
+ if (self::$forcedEngine === 'OpenSSL') {
+ if (!defined($keyTypeConstant)) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for Ed25519 / Ed448');
+ }
+ // OpenSSL supports Ed25519/Ed448 but not Ed25519ctx (context), so skip if context is set
+ if (isset($this->context)) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for Ed25519 / Ed448 curves with context\'s');
+ }
+ }
+ if (defined($keyTypeConstant) && !isset($this->context)) {
+ // algorithm 0 is used because EdDSA has a built-in hash
+ $result = openssl_verify($message, $signature, $this->toString('PKCS8'), 0) === 1;
+ if ($result !== -1 && $result !== false) {
+ return (bool) $result;
+ }
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but was unable to create signature because of ' . openssl_error_string());
+ }
+ }
}
+ $order = $this->curve->getOrder();
+
$curve = $this->curve;
if (strlen($signature) != 2 * $curve::SIZE) {
return false;
@@ -118,16 +164,31 @@ public function verify($message, $signature)
$r = $params['r'];
$s = $params['s'];
- if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
- $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature;
+ if (self::$forcedEngine === 'OpenSSL' && !function_exists('openssl_get_md_methods')) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for ECDSA');
+ }
+
+ // at this point $forcedEngine is either PHP or null. either that OR openssl_get_md_methods() exists
+
+ if (self::$forcedEngine !== 'PHP') {
+ if (in_array($this->hash->getHash(), openssl_get_md_methods())) {
+ $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature;
- $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash());
+ $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash());
- if ($result != -1) {
- return (bool) $result;
+ if ($result !== -1 && $result !== false) {
+ return (bool) $result;
+ }
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but was unable to verify signature because of ' . openssl_error_string());
+ }
+ } elseif (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unsupported for ECDSA / ' . $this->hash->getHash());
}
}
+ $order = $this->curve->getOrder();
+
$n_1 = $order->subtract(self::$one);
if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) {
return false;
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
index cc5b42c..f1105ca 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
@@ -295,7 +295,7 @@ public function getHash()
public function setHash($hash)
{
$oldHash = $this->hashParam;
- $this->hashParam = $hash = strtolower($hash);
+ $this->hashParam = $hash = strtolower(str_replace('/', '-', $hash));
switch ($hash) {
case 'umac-32':
case 'umac-64':
@@ -323,8 +323,8 @@ public function setHash($hash)
case 'sha256-96':
case 'sha384-96':
case 'sha512-96':
- case 'sha512/224-96':
- case 'sha512/256-96':
+ case 'sha512-224-96':
+ case 'sha512-256-96':
$hash = substr($hash, 0, -3);
$this->length = 12; // 96 / 8 = 12
break;
@@ -336,7 +336,7 @@ public function setHash($hash)
$this->length = 20;
break;
case 'sha224':
- case 'sha512/224':
+ case 'sha512-224':
case 'sha3-224':
$this->length = 28;
break;
@@ -344,7 +344,7 @@ public function setHash($hash)
$this->paddingType = self::PADDING_KECCAK;
// fall-through
case 'sha256':
- case 'sha512/256':
+ case 'sha512-256':
case 'sha3-256':
$this->length = 32;
break;
@@ -424,12 +424,12 @@ public function setHash($hash)
}
}
- if ($hash == 'sha512/224' || $hash == 'sha512/256') {
+ if ($hash == 'sha512-224' || $hash == 'sha512-256') {
// PHP 7.1.0 introduced sha512/224 and sha512/256 support:
// http://php.net/ChangeLog-7.php#7.1.0
if (version_compare(PHP_VERSION, '7.1.0') < 0) {
// from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24
- $initial = $hash == 'sha512/256' ?
+ $initial = $hash == 'sha512-256' ?
[
'22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD',
'96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2'
@@ -459,6 +459,15 @@ public function setHash($hash)
$this->opad = str_repeat(chr(0x5C), $b);
}
+ // PHP's built in hash function does sha3-256 but sha512/256 so we'll update those accordingly
+ switch ($hash) {
+ case 'sha512-224':
+ $hash = 'sha512/224';
+ break;
+ case 'sha512-256':
+ $hash = 'sha512/256';
+ }
+
$this->algo = $hash;
$this->computeKey();
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
index 0a11957..2961501 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
@@ -57,6 +57,7 @@
use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
use phpseclib3\Crypt\RSA\PrivateKey;
use phpseclib3\Crypt\RSA\PublicKey;
+use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\InconsistentSetupException;
use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Math\BigInteger;
@@ -227,14 +228,6 @@ abstract class RSA extends AsymmetricKey
*/
protected static $enableBlinding = true;
- /**
- * OpenSSL configuration file name.
- *
- * @see self::createKey()
- * @var ?string
- */
- protected static $configFile;
-
/**
* Smallest Prime
*
@@ -256,6 +249,14 @@ abstract class RSA extends AsymmetricKey
*/
protected $publicExponent;
+ /**
+ * Forced Engine
+ *
+ * @var ?string
+ * @see parent::forceEngine()
+ */
+ protected static $forcedEngine = null;
+
/**
* Sets the public exponent for key generation
*
@@ -280,18 +281,6 @@ public static function setSmallestPrime($val)
self::$smallestPrime = $val;
}
- /**
- * Sets the OpenSSL config file path
- *
- * Set to the empty string to use the default config file
- *
- * @param string $val
- */
- public static function setOpenSSLConfigPath($val)
- {
- self::$configFile = $val;
- }
-
/**
* Create a private key
*
@@ -309,6 +298,10 @@ public static function createKey($bits = 2048)
throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')');
}
+ if (self::$forcedEngine == 'libsodium' || (self::$forcedEngine == 'OpenSSL' && !function_exists('openssl_pkey_new'))) {
+ throw new BadConfigurationException('Engine ' . self::$forcedEngine . ' is forced but unsupported for RSA');
+ }
+
$regSize = $bits >> 1; // divide by two to see how many bits P and Q would be
if ($regSize > self::$smallestPrime) {
$num_primes = floor($bits / self::$smallestPrime);
@@ -318,25 +311,27 @@ public static function createKey($bits = 2048)
}
if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) {
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
-
- // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
- if (self::$engines['OpenSSL']) {
+ // at this point the only two supported values for self::$forcedEngine are OpenSSL, PHP and null
+ // if it's either OpenSSL or null we'll use OpenSSL (if it's available)
+ if (self::$forcedEngine !== 'PHP' && function_exists('openssl_pkey_new')) {
$config = [];
if (self::$configFile) {
$config['config'] = self::$configFile;
}
+ // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
$rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config);
- openssl_pkey_export($rsa, $privatekeystr, null, $config);
+ if (!$rsa || !openssl_pkey_export($rsa, $privatekeystr, null, $config)) {
+ if (isset(self::$forcedEngine)) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but produced an error - ' . openssl_error_string());
+ }
+ } else {
+ // clear the buffer of error strings stemming from a minimalistic openssl.cnf
+ // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up
+ while (openssl_error_string() !== false) {
+ }
- // clear the buffer of error strings stemming from a minimalistic openssl.cnf
- // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up
- while (openssl_error_string() !== false) {
+ return RSA::load($privatekeystr);
}
-
- return RSA::load($privatekeystr);
}
}
@@ -478,18 +473,6 @@ protected static function onLoad(array $components)
return $key;
}
- /**
- * Initialize static variables
- */
- protected static function initialize_static_variables()
- {
- if (!isset(self::$configFile)) {
- self::$configFile = dirname(__FILE__) . '/../openssl.cnf';
- }
-
- parent::initialize_static_variables();
- }
-
/**
* Constructor
*
@@ -581,6 +564,22 @@ protected function emsa_pkcs1_v1_5_encode($m, $emLen)
break;
case 'sha512/256':
$t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20";
+ break;
+ // the following 3x algorithms are not specified in PKCS1 v2.2, however, some standards none-the-less do use them:
+ // https://sk-eid.github.io/smart-id-documentation/rp-api/changes.html#_security_enhancements
+ // the OIDs are from this URL:
+ // https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration#Hash
+ case 'sha3/224':
+ $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x07\x05\x00\x04\x1c";
+ break;
+ case 'sha3/256':
+ $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x08\x05\x00\x04\x20";
+ break;
+ case 'sha3/384':
+ $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x09\x05\x00\x04\x30";
+ break;
+ case 'sha3/512':
+ $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0A\x05\x00\x04\x40";
}
$t .= $h;
$tLen = strlen($t);
@@ -638,6 +637,22 @@ protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen)
case 'sha512/256':
$t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20";
break;
+ // the following 3x algorithms are not specified in PKCS1 v2.2, however, some standards none-the-less do use them:
+ // https://sk-eid.github.io/smart-id-documentation/rp-api/changes.html#_security_enhancements
+ // the OIDs are from this URL:
+ // https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration#Hash
+ case 'sha3/224':
+ $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x07\x04\x1c";
+ break;
+ case 'sha3/256':
+ $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x08\x04\x20";
+ break;
+ case 'sha3/384':
+ $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x09\x04\x30";
+ break;
+ case 'sha3/512':
+ $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0A\x04\x40";
+ break;
default:
throw new UnsupportedAlgorithmException('md2 and md5 require NULLs');
}
@@ -713,11 +728,15 @@ public function withHash($hash)
case 'sha224':
case 'sha512/224':
case 'sha512/256':
+ case 'sha3/224':
+ case 'sha3/256':
+ case 'sha3/384':
+ case 'sha3/512':
$new->hash = new Hash($hash);
break;
default:
throw new UnsupportedAlgorithmException(
- 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
+ "The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256 - $hash provided"
);
}
$new->hLen = $new->hash->getLengthInBytes();
@@ -748,11 +767,15 @@ public function withMGFHash($hash)
case 'sha224':
case 'sha512/224':
case 'sha512/256':
+ case 'sha3/224':
+ case 'sha3/256':
+ case 'sha3/384':
+ case 'sha3/512':
$new->mgfHash = new Hash($hash);
break;
default:
throw new UnsupportedAlgorithmException(
- 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
+ "The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256 - $hash provided"
);
}
$new->mgfHLen = $new->mgfHash->getLengthInBytes();
@@ -891,28 +914,6 @@ public function getPadding()
return $this->signaturePadding | $this->encryptionPadding;
}
- /**
- * Returns the current engine being used
- *
- * OpenSSL is only used in this class (and it's subclasses) for key generation
- * Even then it depends on the parameters you're using. It's not used for
- * multi-prime RSA nor is it used if the key length is outside of the range
- * supported by OpenSSL
- *
- * @see self::useInternalEngine()
- * @see self::useBestEngine()
- * @return string
- */
- public function getEngine()
- {
- if (!isset(self::$engines['PHP'])) {
- self::useBestEngine();
- }
- return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ?
- 'OpenSSL' :
- 'PHP';
- }
-
/**
* Enable RSA Blinding
*
@@ -930,4 +931,180 @@ public static function disableBlinding()
{
static::$enableBlinding = false;
}
+
+ /**
+ * Handles OpenSSL encryption / decryption / signature creation / verification
+ *
+ * @param string $func
+ * @param string $message
+ * @param ?string $signature
+ * @return bool|string|null
+ */
+ protected function handleOpenSSL($func, $message, $signature = null)
+ {
+ switch ($func) {
+ case 'openssl_verify':
+ case 'openssl_sign':
+ $paddingType = 'signaturePadding';
+ break;
+ case 'openssl_public_encrypt':
+ case 'openssl_private_decrypt':
+ $paddingType = 'encryptionPadding';
+ }
+
+ if (self::$forcedEngine === 'libsodium') {
+ throw new BadConfigurationException('Engine libsodium is not supported for RSA');
+ }
+
+ if ((isset(self::$forcedEngine) && self::$forcedEngine !== 'PHP') && $this->$paddingType === self::SIGNATURE_RELAXED_PKCS1) {
+ throw new BadConfigurationException('Only the PHP engine can be used with relaxed PKCS1 padding');
+ }
+
+ if (self::$forcedEngine !== 'PHP') {
+ if (self::$forcedEngine === 'OpenSSL' && !function_exists($func)) {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unavailable for RSA');
+ }
+ if ($this->$paddingType === self::SIGNATURE_PSS) {
+ switch (true) {
+ case !defined('OPENSSL_PKCS1_PSS_PADDING'):
+ $error = 'Engine OpenSSL is forced but PSS encryption requires PHP >= 8.5.0';
+ break;
+ case $this->hash->getHash() !== $this->mgfHash->getHash():
+ $error = 'Engine OpenSSL is forced but can\'t be used because the Hash and MGF Hash do not match';
+ break;
+ case $this->getSaltLength() !== $this->hLen:
+ $error = 'Engine OpenSSL is forced but can\'t be used because the salt length doesn\'t match the hash length';
+ }
+ }
+ if ($this->$paddingType === self::ENCRYPTION_OAEP) {
+ switch (true) {
+ case $this->hash->getHash() !== $this->mgfHash->getHash():
+ $error = 'Engine OpenSSL is forced but can\'t be used because the Hash and MGF Hash do not match';
+ break;
+ case $this->hash->getHash() !== 'sha1' && PHP_VERSION_ID < 80500:
+ $error = 'Engine OpenSSL is forced but non-sha1 hashes are only supported on PHP 8.5.0+';
+ break;
+ case strlen($this->label):
+ $error = 'Engine OpenSSL is forced but can\'t be used because the label is not the empty string';
+ }
+ }
+ if (isset($error)) {
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException($error);
+ }
+ } elseif ($paddingType === 'signaturePadding') {
+ switch (true) {
+ case $this->signaturePadding === self::SIGNATURE_PSS && defined('OPENSSL_PKCS1_PSS_PADDING'):
+ case $this->signaturePadding !== self::SIGNATURE_PSS && function_exists($func):
+ $key = $this instanceof PrivateKey ?
+ $this->withPassword()->toString('PKCS8') :
+ $this->toString('PKCS8');
+ if ($func === 'openssl_sign' && strpos($key, 'PUBLIC') !== false) {
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but cannot be used because the private key does not have the prime components within it');
+ }
+ break;
+ }
+ $hash = $this->hash->getHash();
+
+ // on github actions, php 7.0 and 7.1 on windows emit the following warning:
+ // openssl_sign(): supplied key param cannot be coerced into a private key
+ set_error_handler(function ($errno, $errstr) {
+ throw new BadConfigurationException("Engine OpenSSL is forced but got error: $errstr");
+ });
+ try {
+ $result = $this->signaturePadding === self::SIGNATURE_PSS ?
+ $func($message, $signature, $key, $hash, OPENSSL_PKCS1_PSS_PADDING) :
+ $func($message, $signature, $key, $hash);
+ } catch (BadConfigurationException $e) {
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw $e;
+ }
+ $result = false;
+ } finally {
+ restore_error_handler();
+ }
+
+ if ($func === 'openssl_verify' && $result !== -1 && $result !== false) {
+ return (bool) $result;
+ }
+ if ($result) {
+ return $signature;
+ }
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but was unable to create signature because of ' . openssl_error_string());
+ }
+ }
+ } else {
+ if ($this->encryptionPadding !== self::ENCRYPTION_OAEP || PHP_VERSION_ID >= 80500) {
+ $key = $this instanceof PrivateKey ?
+ $this->withPassword()->toString('PKCS8') :
+ $this->toString('PKCS8');
+ if ($func === 'openssl_private_decrypt' && strpos($key, 'PUBLIC') !== false) {
+ if ($this->encryptionPadding === self::ENCRYPTION_OAEP) {
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but cannot be used because openssl_public_decrypt() doesn\'t have a hash parameter like openssl_private_decrypt() does');
+ }
+ return null;
+ }
+ $func = 'openssl_public_decrypt';
+ }
+ if ($this->encryptionPadding === self::ENCRYPTION_PKCS1 && OPENSSL_VERSION_NUMBER >= 0x30200000) {
+ // quoting https://docs.openssl.org/3.4/man3/RSA_public_encrypt/#return-values :
+ //
+ // "Since version 3.2.0, the default provider in OpenSSL does not return an error when padding checks fail.
+ // Instead it generates a random message"
+ //
+ // the idea is that even a perfect implementation of PKCS1 padding can be used to conduct a Bleichenbacher
+ // padding oracle attack.
+ //
+ // so like if $rsa->decrypt() doesn't throw an exception it's liable to run additional code that'll take
+ // longer to run than it'd take if an exception would be thrown and in theory, with PKCS1, in particular,
+ // you can use that fact to guess at successive bits of the private key until you've figured it out. it's
+ // why you should use OAEP padding vs PKCS1 padding BUT if you need PKCS1 padding for interoperability then
+ // you're stuck with it.
+ //
+ // with the OpenSSL 3.2.0+ behavior they're making it harder to do the attack by making it harder to use PKCS1
+ // in the real world. this isn't a design philosophy i agree with. like phpseclib lets you DES encryption. you
+ // shouldn't use DES encryption but if you need to you need to and phpseclib isn't here to judge. that's a big
+ // difference between phpseclib and stuff like libsodium.
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but cannot be used to decrypt PKCS1 encrypted strings with OpenSSL 3.2.0+');
+ }
+ return null;
+ }
+ $hash = $this->hash->getHash();
+ $output = '';
+ switch ($this->encryptionPadding) {
+ case self::ENCRYPTION_NONE:
+ case self::ENCRYPTION_PKCS1:
+ $padding = $this->encryptionPadding === self::ENCRYPTION_NONE ? OPENSSL_NO_PADDING : OPENSSL_PKCS1_PADDING;
+ // on github actions, php 7.0 and 7.1 on windows emit the following warning:
+ // openssl_private_decrypt(): key parameter is not a valid private key
+ set_error_handler(function ($errno, $errstr) {
+ throw new BadConfigurationException("Engine OpenSSL is forced but got error: $errstr");
+ });
+ try {
+ $result = $func($message, $output, $key, $padding);
+ } catch (BadConfigurationException $e) {
+ if (self::$forcedEngine === 'OpenSSL') {
+ throw $e;
+ }
+ $result = false;
+ } finally {
+ restore_error_handler();
+ }
+ break;
+ //case self::ENCRYPTION_OAEP:
+ default:
+ $result = $func($message, $output, $key, OPENSSL_PKCS1_OAEP_PADDING, $hash);
+ }
+ if ($result) {
+ return $output;
+ }
+ }
+ }
+ return null;
+ }
+ }
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php
index bf51bcf..ee9b992 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php
@@ -141,7 +141,7 @@ public static function load($key, $password = '')
$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();
+ $result['saltLength'] = (int) "$params[saltLength]";
}
if (isset($key['meta'])) {
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php
index 8c828b3..62a13a4 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php
@@ -216,7 +216,7 @@ private function emsa_pss_encode($m, $emBits)
$db = $ps . chr(1) . $salt;
$dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); // ie. stlren($db)
$maskedDB = $db ^ $dbMask;
- $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];
+ $maskedDB[0] = ~chr(256 - (1 << ($emBits & 7))) & $maskedDB[0];
$em = $maskedDB . $h . chr(0xBC);
return $em;
@@ -288,6 +288,11 @@ private function rsassa_pkcs1_v1_5_sign($m)
*/
public function sign($message)
{
+ $result = $this->handleOpenSSL('openssl_sign', $message);
+ if ($result !== null) {
+ return $result;
+ }
+
switch ($this->signaturePadding) {
case self::SIGNATURE_PKCS1:
case self::SIGNATURE_RELAXED_PKCS1:
@@ -434,6 +439,11 @@ private function raw_encrypt($m)
*/
public function decrypt($ciphertext)
{
+ $result = $this->handleOpenSSL('openssl_private_decrypt', $ciphertext);
+ if ($result !== null) {
+ return $result;
+ }
+
switch ($this->encryptionPadding) {
case self::ENCRYPTION_NONE:
return $this->raw_encrypt($ciphertext);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php
index ff80ae7..07ee1e7 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php
@@ -17,6 +17,7 @@
use phpseclib3\Crypt\Random;
use phpseclib3\Crypt\RSA;
use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
+use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\File\ASN1;
@@ -116,7 +117,7 @@ private function rsassa_pkcs1_v1_5_verify($m, $s)
}
// Compare
- return $r1 || $r2;
+ return boolval($r1 | $r2);
}
/**
@@ -241,13 +242,13 @@ private function emsa_pss_verify($m, $em, $emBits)
$maskedDB = substr($em, 0, -$this->hLen - 1);
$h = substr($em, -$this->hLen - 1, $this->hLen);
- $temp = chr(0xFF << ($emBits & 7));
+ $temp = chr(256 - (1 << ($emBits & 7)));
if ((~$maskedDB[0] & $temp) != $temp) {
return false;
}
$dbMask = $this->mgf1($h, $emLen - $this->hLen - 1);
$db = $maskedDB ^ $dbMask;
- $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
+ $db[0] = ~chr(256 - (1 << ($emBits & 7))) & $db[0];
$temp = $emLen - $this->hLen - $sLen - 2;
if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {
return false;
@@ -301,6 +302,49 @@ private function rsassa_pss_verify($m, $s)
*/
public function verify($message, $signature)
{
+ /*
+ https://datatracker.ietf.org/doc/html/rfc4055#page-6 says the following:
+
+ There are two possible encodings for the AlgorithmIdentifier
+ parameters field associated with these object identifiers. The two
+ alternatives arise from the loss of the OPTIONAL associated with the
+ algorithm identifier parameters when the 1988 syntax for
+ AlgorithmIdentifier was translated into the 1997 syntax. Later the
+ OPTIONAL was recovered via a defect report, but by then many people
+ thought that algorithm parameters were mandatory. Because of this
+ history some implementations encode parameters as a NULL element
+ while others omit them entirely. The correct encoding is to omit the
+ parameters field; however, when RSASSA-PSS and RSAES-OAEP were
+ defined, it was done using the NULL parameters rather than absent
+ parameters.
+
+ All implementations MUST accept both NULL and absent parameters as
+ legal and equivalent encodings.
+
+ OpenSSL does NOT accept both - it REQUIRES NULL be present. phpseclib, however,
+ DOES accept both. at first, it didn't. at first, not knowing why some small number
+ of PKCS1 signatures ommitted NULL, i added the SIGNATURE_RELAXED_PKCS1 mode on
+ 2015-08-26. https://phpseclib.com/docs/rsa#rsasignature_relaxed_pkcs1 talks more
+ about that mode. later, on 2021-04-05, there was CVE-2021-30130. consequently,
+ the SIGNATURE_PKCS1 mode was updated to accept either NULL or non-NULL.
+
+ because phpseclib accepts PKCS1 signatures that OpenSSL doesn't, OpenSSL isn't
+ used for PKCS1. if the OpenSSL extension is installed then it'll be used to perform
+ unpadded RSA (ie. modular exponentation), however, the actual PKCS1 construction
+ takes place in PHP code vs OpenSSL.
+
+ see https://security.stackexchange.com/questions/110330/encoding-of-optional-null-in-der
+ for an additional reference
+ */
+ if ($this->signaturePadding === self::SIGNATURE_PKCS1 && isset(self::$forcedEngine) && self::$forcedEngine !== 'PHP') {
+ throw new BadConfigurationException('Engine OpenSSL is forced but unavailable for RSA PKCS1 signature verification');
+ }
+
+ $result = $this->handleOpenSSL('openssl_verify', $message, $signature);
+ if ($result !== null) {
+ return $result;
+ }
+
switch ($this->signaturePadding) {
case self::SIGNATURE_RELAXED_PKCS1:
return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature);
@@ -450,6 +494,11 @@ private function raw_encrypt($m)
*/
public function encrypt($plaintext)
{
+ $result = $this->handleOpenSSL('openssl_public_encrypt', $plaintext);
+ if ($result !== null) {
+ return $result;
+ }
+
switch ($this->encryptionPadding) {
case self::ENCRYPTION_NONE:
return $this->raw_encrypt($plaintext);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
index 5ba7cf7..07b196d 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
@@ -378,7 +378,7 @@ protected function encryptBlock($in)
$k = $c[2];
$l = $c[3];
while ($i < $Nb) {
- $temp[$i] = ($state[$i] & intval(0xFF000000)) ^
+ $temp[$i] = ($state[$i] & (PHP_INT_SIZE == 8 ? 0xFF000000 : -16777216)) ^
($state[$j] & 0x00FF0000) ^
($state[$k] & 0x0000FF00) ^
($state[$l] & 0x000000FF) ^
@@ -452,7 +452,7 @@ protected function decryptBlock($in)
$l = $Nb - $c[3];
while ($i < $Nb) {
- $word = ($state[$i] & intval(0xFF000000)) |
+ $word = ($state[$i] & (PHP_INT_SIZE == 8 ? 0xFF000000 : -16777216)) |
($state[$j] & 0x00FF0000) |
($state[$k] & 0x0000FF00) |
($state[$l] & 0x000000FF);
@@ -528,7 +528,7 @@ protected function setupKey()
0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
];
- $rcon = array_map('intval', $rcon);
+ $rcon = array_map([self::class, 'safe_intval'], $rcon);
}
if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
@@ -568,7 +568,9 @@ protected function setupKey()
// on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
// 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
// with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
- $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord
+ $temp = PHP_INT_SIZE == 8 ? // rotWord
+ (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF) :
+ ($temp << 8) | (($temp >> 24) & 0x000000FF);
$temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk];
} elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
$temp = $this->subWord($temp);
@@ -659,7 +661,7 @@ protected function &getTables()
// according to (section 5.2.1),
// precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
// those are the names we'll use.
- $t3 = array_map('intval', [
+ $t3 = array_map([self::class, 'safe_intval'], [
// with array_map('intval', ...) we ensure we have only int's and not
// some slower floats converted by php automatically on high values
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
@@ -697,9 +699,9 @@ protected function &getTables()
]);
foreach ($t3 as $t3i) {
- $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF);
- $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF);
- $t2[] = (($t3i << 8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF);
+ $t0[] = (($t3i << 24) & self::safe_intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF);
+ $t1[] = (($t3i << 16) & self::safe_intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF);
+ $t2[] = (($t3i << 8) & self::safe_intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF);
}
$tables = [
@@ -744,7 +746,7 @@ protected function &getInvTables()
{
static $tables;
if (empty($tables)) {
- $dt3 = array_map('intval', [
+ $dt3 = array_map([self::class, 'safe_intval'], [
0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
@@ -779,11 +781,19 @@ protected function &getInvTables()
0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
]);
- foreach ($dt3 as $dt3i) {
- $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >> 8) & 0x00FFFFFF);
- $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF);
- $dt2[] = (($dt3i << 8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF);
- };
+ if (PHP_INT_SIZE === 8) {
+ foreach ($dt3 as $dt3i) {
+ $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF);
+ $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
+ $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
+ };
+ } else {
+ foreach ($dt3 as $dt3i) {
+ $dt0[] = ($dt3i << 24) | (($dt3i >> 8) & 0x00FFFFFF);
+ $dt1[] = ($dt3i << 16) | (($dt3i >> 16) & 0x0000FFFF);
+ $dt2[] = ($dt3i << 8) | (($dt3i >> 24) & 0x000000FF);
+ };
+ }
$tables = [
// The Precomputed inverse mixColumns tables dt0 - dt3
@@ -879,7 +889,7 @@ protected function setupInlineCrypt()
$encrypt_block .= '$in = pack("N*"' . "\n";
for ($i = 0; $i < $Nb; ++$i) {
$encrypt_block .= ',
- ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^
+ ($' . $e . $i . ' & ' . (PHP_INT_SIZE == 8 ? 0xFF000000 : -16777216) . ') ^
($' . $e . (($i + $c[1]) % $Nb) . ' & 0x00FF0000 ) ^
($' . $e . (($i + $c[2]) % $Nb) . ' & 0x0000FF00 ) ^
($' . $e . (($i + $c[3]) % $Nb) . ' & 0x000000FF ) ^
@@ -935,7 +945,7 @@ protected function setupInlineCrypt()
$decrypt_block .= '$in = pack("N*"' . "\n";
for ($i = 0; $i < $Nb; ++$i) {
$decrypt_block .= ',
- ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^
+ ($' . $e . $i . ' & ' . (PHP_INT_SIZE == 8 ? 0xFF000000 : -16777216) . ') ^
($' . $e . (($Nb + $i - $c[1]) % $Nb) . ' & 0x00FF0000 ) ^
($' . $e . (($Nb + $i - $c[2]) % $Nb) . ' & 0x0000FF00 ) ^
($' . $e . (($Nb + $i - $c[3]) % $Nb) . ' & 0x000000FF ) ^
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php
index 785e7aa..78c3000 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php
@@ -411,7 +411,7 @@ protected static function leftRotate($x, $n)
$r1 &= 0xFFFFFFFF;
$r2 = ($x & 0xFFFFFFFF) >> (32 - $n);
} else {
- $x = (int) $x;
+ $x = self::safe_intval($x);
$r1 = $x << $n;
$r2 = $x >> (32 - $n);
$r2 &= (1 << $n) - 1;
@@ -482,7 +482,7 @@ protected static function salsa20($x)
}
for ($i = 1; $i <= 16; $i++) {
- $x[$i] += $z[$i];
+ $x[$i] = self::safe_intval($x[$i] + $z[$i]);
}
return pack('V*', ...$x);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
index 141ad01..e89a776 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
@@ -373,12 +373,12 @@ public function __construct($mode)
protected static function initialize_static_variables()
{
if (is_float(self::$m3[0])) {
- self::$m0 = array_map('intval', self::$m0);
- self::$m1 = array_map('intval', self::$m1);
- self::$m2 = array_map('intval', self::$m2);
- self::$m3 = array_map('intval', self::$m3);
- self::$q0 = array_map('intval', self::$q0);
- self::$q1 = array_map('intval', self::$q1);
+ self::$m0 = array_map([self::class, 'safe_intval'], self::$m0);
+ self::$m1 = array_map([self::class, 'safe_intval'], self::$m1);
+ self::$m2 = array_map([self::class, 'safe_intval'], self::$m2);
+ self::$m3 = array_map([self::class, 'safe_intval'], self::$m3);
+ self::$q0 = array_map([self::class, 'safe_intval'], self::$q0);
+ self::$q1 = array_map([self::class, 'safe_intval'], self::$q1);
}
parent::initialize_static_variables();
diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
index 2f1fb8a..b2a7c12 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
@@ -131,6 +131,8 @@ abstract class ASN1
*/
private static $encoded;
+ private static $use64BitOIDHandling;
+
/**
* Type mapping table for the ANY type.
*
@@ -190,6 +192,7 @@ abstract class ASN1
*
* @param Element|string $encoded
* @return ?array
+ * @changed in phpseclib 4.0.0
*/
public static function decodeBER($encoded)
{
@@ -514,6 +517,7 @@ private static function decode_ber($encoded, $start = 0, $encoded_pos = 0)
* @param array $mapping
* @param array $special
* @return array|bool|Element|string|null
+ * @changed in phpseclib 4.0.0
*/
public static function asn1map(array $decoded, $mapping, $special = [])
{
@@ -789,10 +793,17 @@ public static function asn1map(array $decoded, $mapping, $special = [])
case self::TYPE_ENUMERATED:
$temp = $decoded['content'];
if (isset($mapping['implicit'])) {
- $temp = new BigInteger($decoded['content'], -256);
+ $temp = new BigInteger($temp, -256);
+ }
+ if (!$temp instanceof BigInteger) {
+ return false;
}
if (isset($mapping['mapping'])) {
- $temp = (int) $temp->toString();
+ $temp = $temp->toString();
+ if (strlen($temp) > 1) {
+ return false;
+ }
+ $temp = (int) $temp;
return isset($mapping['mapping'][$temp]) ?
$mapping['mapping'][$temp] :
false;
@@ -833,6 +844,7 @@ public static function decodeLength(&$string)
* @param array $mapping
* @param array $special
* @return string
+ * @changed in phpseclib 4.0.0
*/
public static function encodeDER($source, $mapping, $special = [])
{
@@ -1141,6 +1153,19 @@ private static function encode_der($source, array $mapping, $idx = null, array $
return chr($tag) . self::encodeLength(strlen($value)) . $value;
}
+ public static function enable64BitOIDHandling()
+ {
+ if (PHP_INT_SIZE === 4) {
+ throw new \RuntimeException('64-bit OID handling is unavailable on 32-bit PHP installs');
+ }
+ self::$use64BitOIDHandling = true;
+ }
+
+ public static function disable64BitOIDHandling()
+ {
+ self::$use64BitOIDHandling = false;
+ }
+
/**
* BER-decode the OID
*
@@ -1148,6 +1173,7 @@ private static function encode_der($source, array $mapping, $idx = null, array $
*
* @param string $content
* @return string
+ * @changed in phpseclib 4.0.0
*/
public static function decodeOID($content)
{
@@ -1158,12 +1184,16 @@ public static function decodeOID($content)
$eighty = new BigInteger(80);
}
+ if (!isset(self::$use64BitOIDHandling)) {
+ self::$use64BitOIDHandling = PHP_INT_SIZE === 8;
+ }
+
$oid = [];
$pos = 0;
$len = strlen($content);
// see https://github.com/openjdk/jdk/blob/2deb318c9f047ec5a4b160d66a4b52f93688ec42/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java#L55
- if ($len > 4096) {
- //throw new \RuntimeException("Object identifier size is limited to 4096 bytes ($len bytes present)");
+ if ($len > 128) {
+ //throw new \RuntimeException("Object identifier size is limited to 128 bytes ($len bytes present)");
return false;
}
@@ -1172,13 +1202,50 @@ public static function decodeOID($content)
}
$n = new BigInteger();
- while ($pos < $len) {
- $temp = ord($content[$pos++]);
- $n = $n->bitwise_leftShift(7);
- $n = $n->bitwise_or(new BigInteger($temp & 0x7F));
- if (~$temp & 0x80) {
- $oid[] = $n;
- $n = new BigInteger();
+ $subn = $numBytes = 0;
+ if (self::$use64BitOIDHandling) {
+ $prefix = '';
+ while ($pos < $len) {
+ $temp = ord($content[$pos++]);
+ $subn <<= 7;
+ $subn |= ($temp & 0x7F);
+ $numBytes++;
+ $endByte = ~$temp & 0x80;
+ if ($numBytes === PHP_INT_SIZE) {
+ $prefix .= substr(pack('J', $subn), 1); // we're basically left shifting by 7 bytes
+ $subn = $numBytes = 0;
+ if ($endByte) {
+ $oid[] = new BigInteger($prefix, 256);
+ $prefix = '';
+ }
+ } elseif ($endByte) {
+ if (strlen($prefix)) {
+ $arc = new BigInteger($prefix, 256);
+ $arc = $arc->bitwise_leftShift($numBytes * 7);
+ $oid[] = $arc->bitwise_or(new BigInteger($subn));
+ $prefix = '';
+ } else {
+ $oid[] = new BigInteger($subn);
+ }
+ $subn = $numBytes = 0;
+ }
+ }
+ } else {
+ while ($pos < $len) {
+ $temp = ord($content[$pos++]);
+ $subn <<= 7;
+ $subn |= ($temp & 0x7F);
+ $numBytes++;
+ $endByte = ~$temp & 0x80;
+ if ($numBytes === PHP_INT_SIZE || $endByte) {
+ $n = $n->bitwise_leftShift($numBytes * 7);
+ $n = $n->bitwise_or(new BigInteger($subn));
+ $subn = $numBytes = 0;
+ if ($endByte) {
+ $oid[] = $n;
+ $n = new BigInteger();
+ }
+ }
}
}
$part1 = array_shift($oid);
@@ -1265,6 +1332,7 @@ public static function encodeOID($source)
* @param string $content
* @param int $tag
* @return \DateTime|false
+ * @changed in phpseclib 4.0.0
*/
private static function decodeTime($content, $tag)
{
@@ -1310,6 +1378,7 @@ private static function decodeTime($content, $tag)
* Sets the time / date format for asn1map().
*
* @param string $format
+ * @removed in phpseclib 4.0.0
*/
public static function setTimeFormat($format)
{
@@ -1323,6 +1392,7 @@ public static function setTimeFormat($format)
* Previously loaded OIDs are retained.
*
* @param array $oids
+ * @changed in phpseclib 4.0.0
*/
public static function loadOIDs(array $oids)
{
@@ -1337,6 +1407,7 @@ public static function loadOIDs(array $oids)
* Previously loaded filters are not retained.
*
* @param array $filters
+ * @removed in phpseclib 4.0.0
*/
public static function setFilters(array $filters)
{
@@ -1353,6 +1424,7 @@ public static function setFilters(array $filters)
* @param int $from
* @param int $to
* @return string
+ * @removed in phpseclib 4.0.0
*/
public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING)
{
@@ -1518,6 +1590,7 @@ public static function encodeLength($length)
*
* @param string $name
* @return string
+ * @removed in phpseclib 4.0.0
*/
public static function getOID($name)
{
diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
index 80e0bab..813282b 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
@@ -273,6 +273,7 @@ class X509
* Default Constructor.
*
* @return X509
+ * @changed in phpseclib 4.0.0
*/
public function __construct()
{
@@ -315,6 +316,7 @@ public function __construct()
'id-at-uniqueIdentifier' => '2.5.4.45',
'id-at-role' => '2.5.4.72',
'id-at-postalAddress' => '2.5.4.16',
+ 'id-at-organizationIdentifier' => '2.5.4.97',
'jurisdictionOfIncorporationCountryName' => '1.3.6.1.4.1.311.60.2.1.3',
'jurisdictionOfIncorporationStateOrProvinceName' => '1.3.6.1.4.1.311.60.2.1.2',
'jurisdictionLocalityName' => '1.3.6.1.4.1.311.60.2.1.1',
@@ -428,6 +430,7 @@ public function __construct()
* @param array|string $cert
* @param int $mode
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT)
{
@@ -501,6 +504,7 @@ public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT)
* @param array $cert
* @param int $format optional
* @return string
+ * @removed in phpseclib 4.0.0
*/
public function saveX509(array $cert, $format = self::FORMAT_PEM)
{
@@ -958,6 +962,7 @@ private function getMapping($extnId)
*
* @param string $cert
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function loadCA($cert)
{
@@ -1084,6 +1089,7 @@ public function validateURL($url)
*
* @param \DateTimeInterface|string $date optional
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function validateDate($date = null)
{
@@ -1241,6 +1247,7 @@ private function testForIntermediate($caonly, $count)
*
* @param bool $caonly optional
* @return mixed
+ * @changed in phpseclib 4.0.0
*/
public function validateSignature($caonly = true)
{
@@ -1471,7 +1478,6 @@ public static function setRecurLimit($count)
/**
* Prevents URIs from being automatically retrieved
- *
*/
public static function disableURLFetch()
{
@@ -1480,7 +1486,6 @@ public static function disableURLFetch()
/**
* Allows URIs to be automatically retrieved
- *
*/
public static function enableURLFetch()
{
@@ -1494,6 +1499,7 @@ public static function enableURLFetch()
*
* @param string $ip
* @return string
+ * @removed in phpseclib 4.0.0
*/
public static function decodeIP($ip)
{
@@ -1507,6 +1513,7 @@ public static function decodeIP($ip)
*
* @param string $ip
* @return array
+ * @removed in phpseclib 4.0.0
*/
public static function decodeNameConstraintIP($ip)
{
@@ -1523,6 +1530,7 @@ public static function decodeNameConstraintIP($ip)
*
* @param string|array $ip
* @return string
+ * @removed in phpseclib 4.0.0
*/
public static function encodeIP($ip)
{
@@ -1612,6 +1620,9 @@ private function translateDNProp($propName)
case 'organizationalunitname':
case 'ou':
return 'id-at-organizationalUnitName';
+ case 'id-at-organizationidentifier':
+ case 'organizationIdentifier':
+ return 'id-at-organizationIdentifier';
case 'id-at-pseudonym':
case 'pseudonym':
return 'id-at-pseudonym';
@@ -1643,6 +1654,7 @@ private function translateDNProp($propName)
* @param mixed $propValue
* @param string $type optional
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function setDNProp($propName, $propValue, $type = 'utf8String')
{
@@ -1673,6 +1685,7 @@ public function setDNProp($propName, $propValue, $type = 'utf8String')
* Remove Distinguished Name properties
*
* @param string $propName
+ * @removed in phpseclib 4.0.0
*/
public function removeDNProp($propName)
{
@@ -1706,6 +1719,7 @@ public function removeDNProp($propName)
* @param array $dn optional
* @param bool $withType optional
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getDNProp($propName, $dn = null, $withType = false)
{
@@ -1770,6 +1784,7 @@ public function getDNProp($propName, $dn = null, $withType = false)
* @param bool $merge optional
* @param string $type optional
* @return bool
+ * @changed in phpseclib 4.0.0
*/
public function setDN($dn, $merge = false, $type = 'utf8String')
{
@@ -1811,6 +1826,7 @@ public function setDN($dn, $merge = false, $type = 'utf8String')
* @param mixed $format optional
* @param array $dn optional
* @return array|bool|string
+ * @changed in phpseclib 4.0.0
*/
public function getDN($format = self::DN_ARRAY, $dn = null)
{
@@ -1952,6 +1968,7 @@ public function getDN($format = self::DN_ARRAY, $dn = null)
*
* @param int $format optional
* @return mixed
+ * @changed in phpseclib 4.0.0
*/
public function getIssuerDN($format = self::DN_ARRAY)
{
@@ -1973,6 +1990,7 @@ public function getIssuerDN($format = self::DN_ARRAY)
*
* @param int $format optional
* @return mixed
+ * @changed in phpseclib 4.0.0
*/
public function getSubjectDN($format = self::DN_ARRAY)
{
@@ -1996,6 +2014,7 @@ public function getSubjectDN($format = self::DN_ARRAY)
* @param string $propName
* @param bool $withType optional
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getIssuerDNProp($propName, $withType = false)
{
@@ -2017,6 +2036,7 @@ public function getIssuerDNProp($propName, $withType = false)
* @param string $propName
* @param bool $withType optional
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getSubjectDNProp($propName, $withType = false)
{
@@ -2038,6 +2058,7 @@ public function getSubjectDNProp($propName, $withType = false)
* Get the certificate chain for the current cert
*
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getChain()
{
@@ -2079,6 +2100,7 @@ public function getChain()
* Returns the current cert
*
* @return array|bool
+ * @removed in phpseclib 4.0.0
*/
public function &getCurrentCert()
{
@@ -2104,6 +2126,7 @@ public function setPublicKey(PublicKey $key)
* Key needs to be a \phpseclib3\Crypt\RSA object
*
* @param PrivateKey $key
+ * @removed in phpseclib 4.0.0
*/
public function setPrivateKey(PrivateKey $key)
{
@@ -2116,6 +2139,7 @@ public function setPrivateKey(PrivateKey $key)
* Used for SPKAC CSR's
*
* @param string $challenge
+ * @removed in phpseclib 4.0.0
*/
public function setChallenge($challenge)
{
@@ -2176,6 +2200,7 @@ public function getPublicKey()
* @param string $csr
* @param int $mode
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT)
{
@@ -2250,6 +2275,7 @@ public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT)
* @param array $csr
* @param int $format optional
* @return string
+ * @removed in phpseclib 4.0.0
*/
public function saveCSR(array $csr, $format = self::FORMAT_PEM)
{
@@ -2295,6 +2321,7 @@ public function saveCSR(array $csr, $format = self::FORMAT_PEM)
*
* @param string $spkac
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function loadSPKAC($spkac)
{
@@ -2359,6 +2386,7 @@ public function loadSPKAC($spkac)
* @param array $spkac
* @param int $format optional
* @return string
+ * @removed in phpseclib 4.0.0
*/
public function saveSPKAC(array $spkac, $format = self::FORMAT_PEM)
{
@@ -2396,6 +2424,7 @@ public function saveSPKAC(array $spkac, $format = self::FORMAT_PEM)
* @param string $crl
* @param int $mode
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT)
{
@@ -2462,6 +2491,7 @@ public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT)
* @param array $crl
* @param int $format optional
* @return string
+ * @removed in phpseclib 4.0.0
*/
public function saveCRL(array $crl, $format = self::FORMAT_PEM)
{
@@ -2542,6 +2572,7 @@ private function timeField($date)
* a CSR or something with the DN and public key explicitly set.
*
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function sign(X509 $issuer, X509 $subject)
{
@@ -2724,6 +2755,7 @@ public function sign(X509 $issuer, X509 $subject)
* Sign a CSR
*
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function signCSR()
{
@@ -2779,6 +2811,7 @@ public function signCSR()
* Sign a SPKAC
*
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function signSPKAC()
{
@@ -2841,6 +2874,7 @@ public function signSPKAC()
* $issuer's private key needs to be loaded.
*
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function signCRL(X509 $issuer, X509 $crl)
{
@@ -3391,6 +3425,7 @@ public function getExtension($id, $cert = null, $path = null)
* @param array $cert optional
* @param string $path optional
* @return array
+ * @removed in phpseclib 4.0.0
*/
public function getExtensions($cert = null, $path = null)
{
@@ -3417,6 +3452,7 @@ public function setExtension($id, $value, $critical = false, $replace = true)
* @param string $id
* @param int $disposition optional
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function removeAttribute($id, $disposition = self::ATTR_ALL)
{
@@ -3467,6 +3503,7 @@ public function removeAttribute($id, $disposition = self::ATTR_ALL)
* @param int $disposition optional
* @param array $csr optional
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null)
{
@@ -3508,6 +3545,7 @@ public function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null)
*
* @param array $csr optional
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getRequestedCertificateExtensions($csr = null)
{
@@ -3528,6 +3566,7 @@ public function getRequestedCertificateExtensions($csr = null)
*
* @param array $csr optional
* @return array
+ * @removed in phpseclib 4.0.0
*/
public function getAttributes($csr = null)
{
@@ -3554,6 +3593,7 @@ public function getAttributes($csr = null)
* @param mixed $value
* @param int $disposition optional
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function setAttribute($id, $value, $disposition = self::ATTR_ALL)
{
@@ -3635,6 +3675,7 @@ public function setKeyIdentifier($value)
* @param mixed $key optional
* @param int $method optional
* @return string binary key identifier
+ * @removed in phpseclib 4.0.0
*/
public function computeKeyIdentifier($key = null, $method = 1)
{
@@ -3731,6 +3772,7 @@ private function formatSubjectPublicKey()
*
* @param mixed ...$domains
* @return void
+ * @removed in phpseclib 4.0.0
*/
public function setDomain(...$domains)
{
@@ -3743,6 +3785,7 @@ public function setDomain(...$domains)
* Set the IP Addresses's which the cert is to be valid for
*
* @param mixed[] ...$ipAddresses
+ * @removed in phpseclib 4.0.0
*/
public function setIPAddress(...$ipAddresses)
{
@@ -3839,6 +3882,7 @@ public function revoke($serial, $date = null)
*
* @param string $serial
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function unrevoke($serial)
{
@@ -3858,6 +3902,7 @@ public function unrevoke($serial)
*
* @param string $serial
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getRevoked($serial)
{
@@ -3875,6 +3920,7 @@ public function getRevoked($serial)
*
* @param array $crl optional
* @return array|bool
+ * @removed in phpseclib 4.0.0
*/
public function listRevoked($crl = null)
{
@@ -3903,6 +3949,7 @@ public function listRevoked($crl = null)
* @param string $serial
* @param string $id
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function removeRevokedCertificateExtension($serial, $id)
{
@@ -3924,6 +3971,7 @@ public function removeRevokedCertificateExtension($serial, $id)
* @param string $id
* @param array $crl optional
* @return mixed
+ * @removed in phpseclib 4.0.0
*/
public function getRevokedCertificateExtension($serial, $id, $crl = null)
{
@@ -3971,6 +4019,7 @@ public function getRevokedCertificateExtensions($serial, $crl = null)
* @param bool $critical optional
* @param bool $replace optional
* @return bool
+ * @removed in phpseclib 4.0.0
*/
public function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true)
{
@@ -4021,6 +4070,7 @@ public static function getRegisteredExtension($id)
* @param mixed $value
* @param bool $critical
* @param bool $replace
+ * @removed in phpseclib 4.0.0
*/
public function setExtensionValue($id, $value, $critical = false, $replace = false)
{
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
index 965d7ff..e6d420d 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
@@ -322,6 +322,7 @@ public function divide(BigInteger $y)
*
* @param BigInteger $n
* @return BigInteger
+ * @changed in phpseclib 4.0.0
*/
public function modInverse(BigInteger $n)
{
@@ -402,7 +403,7 @@ public function getPrecision()
*
* Will be called, automatically, when serialize() is called on a BigInteger object.
*
- * __sleep() / __wakeup() have been around since PHP 4.0
+ * __sleep() / __wakeup() have been around since PHP 4.0 but were deprecated in PHP 8.5
*
* \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1:
* https://wiki.php.net/rfc/phase_out_serializable
@@ -437,6 +438,38 @@ public function __wakeup()
}
}
+ /**
+ * __serialize() magic method
+ *
+ * @see self::__unserialize()
+ * @return array
+ * @access public
+ */
+ public function __serialize()
+ {
+ $result = ['hex' => $this->toHex(true)];
+ if ($this->getPrecision() > 0) {
+ $result['precision'] = $this->getPrecision();
+ }
+ return $result;
+ }
+
+ /**
+ * __unserialize() magic method
+ *
+ * @see self::__serialize()
+ * @access public
+ */
+ public function __unserialize(array $data)
+ {
+ $temp = new static($data['hex'], -16);
+ $this->value = $temp->value;
+ if (isset($data['precision']) && $data['precision'] > 0) {
+ // recalculate $this->bitmask
+ $this->setPrecision($data['precision']);
+ }
+ }
+
/**
* JSON Serialize
*
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php
index 7b62830..5fd78ec 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php
@@ -154,7 +154,7 @@ public function toBytes($twos_compliment = false)
while (bccomp($current, '0', 0) > 0) {
$temp = self::BCMOD_THREE_PARAMS ? bcmod($current, '16777216', 0) : bcmod($current, '16777216');
- $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;
+ $value = chr($temp >> 16) . chr(($temp >> 8) & 0xFF) . chr($temp & 0xFF) . $value;
$current = bcdiv($current, '16777216', 0);
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php
index 1892042..e845acf 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php
@@ -364,6 +364,44 @@ public function __wakeup()
}
}
+ /**
+ * __serialize() magic method
+ *
+ * __sleep / __wakeup were depreciated in PHP 8.5
+ * Will be called, automatically, when serialize() is called on a Math_BigInteger object.
+ *
+ * @see self::__unserialize()
+ * @access public
+ */
+ public function __serialize()
+ {
+ $result = ['hex' => $this->toHex(true)];
+ if ($this->precision > 0) {
+ $result['precision'] = $this->precision;
+ }
+ return $result;
+ }
+
+ /**
+ * __unserialize() magic method
+ *
+ * __sleep / __wakeup were depreciated in PHP 8.5
+ * Will be called, automatically, when unserialize() is called on a Math_BigInteger object.
+ *
+ * @see self::__serialize()
+ * @access public
+ */
+ public function __unserialize(array $data)
+ {
+ $temp = new static($data['hex'], -16);
+ $this->value = $temp->value;
+ $this->is_negative = $temp->is_negative;
+ if (isset($data['precision']) && $data['precision'] > 0) {
+ // recalculate $this->bitmask
+ $this->setPrecision($data['precision']);
+ }
+ }
+
/**
* JSON Serialize
*
@@ -511,8 +549,8 @@ protected static function base256_lshift(&$x, $shift)
$carry = 0;
for ($i = strlen($x) - 1; $i >= 0; --$i) {
- $temp = ord($x[$i]) << $shift | $carry;
- $x[$i] = chr($temp);
+ $temp = (ord($x[$i]) << $shift) | $carry;
+ $x[$i] = chr($temp & 0xFF);
$carry = $temp >> 8;
}
$carry = ($carry != 0) ? chr($carry) : '';
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
new file mode 100644
index 0000000..ae5c8ec
--- /dev/null
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
@@ -0,0 +1,303 @@
+
+ * login('username', 'password')) {
+ * exit('Login Failed');
+ * }
+ *
+ * echo $scp->exec('pwd') . "\r\n";
+ * $scp->put('filename.ext', 'hello, world!');
+ * echo $scp->exec('ls -latr');
+ * ?>
+ *
+ *
+ * @author Jim Wigginton
+ * @copyright 2009 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib3\Net;
+
+use phpseclib3\Common\Functions\Strings;
+use phpseclib3\Exception\FileNotFoundException;
+
+/**
+ * Pure-PHP implementations of SCP.
+ *
+ * @author Jim Wigginton
+ */
+class SCP extends SSH2
+{
+ /**
+ * Reads data from a local file.
+ *
+ * @see \phpseclib3\Net\SCP::put()
+ */
+ const SOURCE_LOCAL_FILE = 1;
+ /**
+ * Reads data from a string.
+ *
+ * @see \phpseclib3\Net\SCP::put()
+ */
+ // this value isn't really used anymore but i'm keeping it reserved for historical reasons
+ const SOURCE_STRING = 2;
+ /**
+ * SCP.php doesn't support SOURCE_CALLBACK because, with that one, we don't know the size, in advance
+ */
+ //const SOURCE_CALLBACK = 16;
+
+ /**
+ * Error information
+ *
+ * @see self::getSCPErrors()
+ * @see self::getLastSCPError()
+ * @var array
+ */
+ private $scp_errors = [];
+
+ /**
+ * Uploads a file to the SCP server.
+ *
+ * By default, \phpseclib\Net\SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
+ * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SCP::get(), you will get a file, twelve bytes
+ * long, containing 'filename.ext' as its contents.
+ *
+ * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will
+ * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
+ * large $remote_file will be, as well.
+ *
+ * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
+ * care of that, yourself.
+ *
+ * @param string $remote_file
+ * @param string $data
+ * @param int $mode
+ * @param callable $callback
+ * @return bool
+ * @access public
+ */
+ public function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null)
+ {
+ if (!($this->bitmap & self::MASK_LOGIN)) {
+ return false;
+ }
+
+ if (empty($remote_file)) {
+ // remote file cannot be blank
+ return false;
+ }
+
+ if (!$this->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
+ return false;
+ }
+
+ $temp = $this->get_channel_packet(self::CHANNEL_EXEC, true);
+ if ($temp !== chr(0)) {
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ return false;
+ }
+
+ $packet_size = $this->packet_size_client_to_server[self::CHANNEL_EXEC] - 4;
+
+ $remote_file = basename($remote_file);
+
+ $dataCallback = false;
+ switch (true) {
+ case is_resource($data):
+ $mode = $mode & ~self::SOURCE_LOCAL_FILE;
+ $info = stream_get_meta_data($data);
+ if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') {
+ $fp = fopen('php://memory', 'w+');
+ stream_copy_to_stream($data, $fp);
+ rewind($fp);
+ } else {
+ $fp = $data;
+ }
+ break;
+ case $mode & self::SOURCE_LOCAL_FILE:
+ if (!is_file($data)) {
+ throw new FileNotFoundException("$data is not a valid file");
+ }
+ $fp = @fopen($data, 'rb');
+ if (!$fp) {
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ return false;
+ }
+ }
+
+ if (isset($fp)) {
+ $stat = fstat($fp);
+ $size = !empty($stat) ? $stat['size'] : 0;
+ } else {
+ $size = strlen($data);
+ }
+
+ $sent = 0;
+ $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
+
+ $temp = 'C0644 ' . $size . ' ' . $remote_file . "\n";
+ $this->send_channel_packet(self::CHANNEL_EXEC, $temp);
+
+ $temp = $this->get_channel_packet(self::CHANNEL_EXEC, true);
+ if ($temp !== chr(0)) {
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ return false;
+ }
+
+ $sent = 0;
+ while ($sent < $size) {
+ $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $packet_size) : fread($fp, $packet_size);
+ $this->send_channel_packet(self::CHANNEL_EXEC, $temp);
+ $sent += strlen($temp);
+
+ if (is_callable($callback)) {
+ call_user_func($callback, $sent);
+ }
+ }
+ $this->close_channel(self::CHANNEL_EXEC, true);
+
+ if ($mode != self::SOURCE_STRING) {
+ fclose($fp);
+ }
+
+ return true;
+ }
+
+ /**
+ * Downloads a file from the SCP server.
+ *
+ * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
+ * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
+ * operation
+ *
+ * @param string $remote_file
+ * @param string $local_file
+ * @return mixed
+ * @access public
+ */
+ public function get($remote_file, $local_file = null, $progressCallback = null)
+ {
+ if (!($this->bitmap & self::MASK_LOGIN)) {
+ return false;
+ }
+
+ if (!$this->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from
+ return false;
+ }
+
+ $this->send_channel_packet(self::CHANNEL_EXEC, chr(0));
+
+ $info = $this->get_channel_packet(self::CHANNEL_EXEC, true);
+ // per https://goteleport.com/blog/scp-familiar-simple-insecure-slow/ non-zero responses mean there are errors
+ if ($info[0] === chr(1) || $info[0] == chr(2)) {
+ $type = $info[0] === chr(1) ? 'warning' : 'error';
+ $this->scp_errors[] = "$type: " . substr($info, 1);
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ return false;
+ }
+
+ $this->send_channel_packet(self::CHANNEL_EXEC, chr(0));
+
+ if (!preg_match('#(?[^ ]+) (?\d+) (?.+)#', rtrim($info), $info)) {
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ return false;
+ }
+
+ $fclose_check = false;
+ if (is_resource($local_file)) {
+ $fp = $local_file;
+ } elseif (!is_null($local_file)) {
+ $fp = @fopen($local_file, 'wb');
+ if (!$fp) {
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ return false;
+ }
+ $fclose_check = true;
+ } else {
+ $content = '';
+ }
+
+ $size = 0;
+ while (true) {
+ $data = $this->get_channel_packet(self::CHANNEL_EXEC, true);
+ // Terminate the loop in case the server repeatedly sends an empty response
+ if ($data === false) {
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ // no data received from server
+ return false;
+ }
+ // SCP usually seems to split stuff out into 16k chunks
+ $length = strlen($data);
+ $size += $length;
+ $end = $size > $info['size'];
+ if ($end) {
+ $diff = $size - $info['size'];
+ $offset = $length - $diff;
+ if ($data[$offset] === chr(0)) {
+ $data = substr($data, 0, -$diff);
+ } else {
+ $type = $data[$offset] === chr(1) ? 'warning' : 'error';
+ $this->scp_errors[] = "$type: " . substr($data, 1);
+ $this->close_channel(self::CHANNEL_EXEC, true);
+ return false;
+ }
+ }
+
+ if (is_null($local_file)) {
+ $content .= $data;
+ } else {
+ fputs($fp, $data);
+ }
+
+ if (is_callable($progressCallback)) {
+ call_user_func($progressCallback, $size);
+ }
+
+ if ($end) {
+ break;
+ }
+ }
+
+ $this->close_channel(self::CHANNEL_EXEC, true);
+
+ if ($fclose_check) {
+ fclose($fp);
+ }
+
+ // if $content isn't set that means a file was written to
+ return isset($content) ? $content : true;
+ }
+
+ /**
+ * Returns all errors on the SCP layer
+ *
+ * @return array
+ */
+ public function getSCPErrors()
+ {
+ return $this->scp_errors;
+ }
+
+ /**
+ * Returns the last error on the SCP layer
+ *
+ * @return string
+ */
+ public function getLastSCPError()
+ {
+ return count($this->scp_errors) ? $this->scp_errors[count($this->scp_errors) - 1] : '';
+ }
+}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
index 7e25544..ddc6715 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
@@ -936,6 +936,9 @@ public function chdir($dir)
}
$dir = $this->realpath($dir);
+ if ($dir === false) {
+ return false;
+ }
// confirm that $dir is, in fact, a valid directory
if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) {
@@ -1678,6 +1681,7 @@ public function chgrp($filename, $gid, $recursive = false)
* @param bool $recursive
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return mixed
+ * @changed in phpseclib 4.0.0
*/
public function chmod($mode, $filename, $recursive = false)
{
@@ -3459,11 +3463,11 @@ public function getSFTPLog()
return $this->packet_type_log;
}
}
-
/**
* Returns all errors on the SFTP layer
*
* @return array
+ * @removed in phpseclib 4.0.0
*/
public function getSFTPErrors()
{
@@ -3474,6 +3478,7 @@ public function getSFTPErrors()
* Returns the last error on the SFTP layer
*
* @return string
+ * @removed in phpseclib 4.0.0
*/
public function getLastSFTPError()
{
@@ -3562,7 +3567,6 @@ protected function disconnect_helper($reason)
/**
* Enable Date Preservation
- *
*/
public function enableDatePreservation()
{
@@ -3571,13 +3575,101 @@ public function enableDatePreservation()
/**
* Disable Date Preservation
- *
*/
public function disableDatePreservation()
{
$this->preserveTime = false;
}
+ /**
+ * Copy
+ *
+ * This method (currently) only works if the copy-data extension is available
+ *
+ * @param string $oldname
+ * @param string $newname
+ * @return bool
+ */
+ public function copy($oldname, $newname)
+ {
+ if (!$this->precheck()) {
+ return false;
+ }
+
+ $oldname = $this->realpath($oldname);
+ $newname = $this->realpath($newname);
+ if ($oldname === false || $newname === false) {
+ return false;
+ }
+
+ if (!isset($this->extensions['copy-data']) || $this->extensions['copy-data'] !== '1') {
+ throw new \RuntimeException(
+ "Extension 'copy-data' is not supported by the server. " .
+ "Call getSupportedVersions() to see a list of supported extension"
+ );
+ }
+
+ $size = $this->filesize($oldname);
+
+ $packet = Strings::packSSH2('s', $oldname);
+ $packet .= $this->version >= 5 ?
+ pack('N3', 0, NET_SFTP_OPEN_OPEN_EXISTING, 0) :
+ pack('N2', NET_SFTP_OPEN_READ, 0);
+ $this->send_sftp_packet(NET_SFTP_OPEN, $packet);
+
+ $response = $this->get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ $oldhandle = substr($response, 4);
+ break;
+ case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ $this->logError($response);
+ return false;
+ default:
+ throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. '
+ . 'Got packet type: ' . $this->packet_type);
+ }
+
+ if ($this->version >= 5) {
+ $flags = NET_SFTP_OPEN_OPEN_OR_CREATE;
+ } else {
+ $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE;
+ }
+
+ $packet = Strings::packSSH2('s', $newname);
+ $packet .= $this->version >= 5 ?
+ pack('N3', 0, $flags, 0) :
+ pack('N2', $flags, 0);
+ $this->send_sftp_packet(NET_SFTP_OPEN, $packet);
+
+ $response = $this->get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ $newhandle = substr($response, 4);
+ break;
+ case NET_SFTP_STATUS:
+ $this->logError($response);
+ return false;
+ default:
+ throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. '
+ . 'Got packet type: ' . $this->packet_type);
+ }
+
+ $packet = Strings::packSSH2('ssQQsQ', 'copy-data', $oldhandle, 0, $size, $newhandle, 0);
+ $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet);
+
+ $response = $this->get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. '
+ . 'Got packet type: ' . $this->packet_type);
+ }
+
+ $this->close_handle($oldhandle);
+ $this->close_handle($newhandle);
+
+ return true;
+ }
+
/**
* POSIX Rename
*
@@ -3697,4 +3789,50 @@ public function statvfs($path)
Strings::unpackSSH2('QQQQQQQQQQQ', $response)
);
}
+
+ public function hardlink($oldpath, $newpath)
+ {
+ if (!$this->precheck()) {
+ return false;
+ }
+
+ if (!isset($this->extensions['hardlink@openssh.com']) || $this->extensions['hardlink@openssh.com'] !== '1') {
+ throw new \RuntimeException(
+ "Extension 'hardlink@openssh.com' is not supported by the server. " .
+ "Call getSupportedVersions() to see a list of supported extension"
+ );
+ }
+
+ $oldpath = $this->realpath($oldpath);
+ $newpath = $this->realpath($newpath);
+ if ($oldpath === false || $newpath === false) {
+ return false;
+ }
+
+ $packet = Strings::packSSH2('sss', 'hardlink@openssh.com', $oldpath, $newpath);
+ $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet);
+
+ $response = $this->get_sftp_packet();
+ if ($this->packet_type !== NET_SFTP_STATUS) {
+ throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. '
+ . 'Got packet type: ' . $this->packet_type);
+ }
+
+ // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ list($status) = Strings::unpackSSH2('N', $response);
+ if ($status !== NET_SFTP_STATUS_OK) {
+ $this->logError($response, $status);
+ return false;
+ }
+
+ // this operation will change the ctime and link-count attributes
+ // which could be cached depending on sftp version
+ $this->remove_from_stat_cache($oldpath);
+
+ // hardlink creation should fail if $newpath exists;
+ // removing it from the cache anyway, just to be sure
+ $this->remove_from_stat_cache($newpath);
+
+ return true;
+ }
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
index 1c8a0e2..6f844e1 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
@@ -679,7 +679,7 @@ class SSH2
* @see self::send_channel_packet()
* @var array
*/
- private $packet_size_client_to_server = [];
+ protected $packet_size_client_to_server = [];
/**
* Message Number Log
@@ -2941,6 +2941,9 @@ public function exec($command, $callback = null)
$this->channel_id_last_interactive = self::CHANNEL_EXEC;
return true;
}
+ if ($callback === false) {
+ return true;
+ }
$output = '';
while (true) {
@@ -3735,12 +3738,12 @@ private function get_binary_packet()
substr($packet->raw, 0, -$this->hmac_size);
if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') {
$this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no));
- if ($hmac != $this->hmac_check->hash($reconstructed)) {
+ if (!hash_equals($hmac, $this->hmac_check->hash($reconstructed))) {
$this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR);
throw new ConnectionClosedException('Invalid UMAC');
}
} else {
- if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) {
+ if (!hash_equals($hmac, $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed)))) {
$this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR);
throw new ConnectionClosedException('Invalid HMAC');
}
@@ -3997,9 +4000,11 @@ private function filter($payload)
break;
case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
Strings::shift($payload, 1);
- list($request_name) = Strings::unpackSSH2('s', $payload);
+ list($request_name, $want_reply) = Strings::unpackSSH2('sb', $payload);
$this->errors[] = "SSH_MSG_GLOBAL_REQUEST: $request_name";
- $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE));
+ if ($want_reply) {
+ $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE));
+ }
$payload = $this->get_binary_packet();
break;
case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
@@ -4236,7 +4241,6 @@ protected function get_channel_packet($client_channel, $skip_extended = false)
if (strlen($error_message)) {
$this->errors[count($this->errors) - 1] .= "\r\n$error_message";
}
-
if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_CLOSE) {
if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) {
$this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$channel]));
@@ -4245,7 +4249,6 @@ protected function get_channel_packet($client_channel, $skip_extended = false)
$this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
}
-
continue 3;
case 'exit-status':
list(, $this->exit_status) = Strings::unpackSSH2('CN', $response);
@@ -4255,8 +4258,13 @@ protected function get_channel_packet($client_channel, $skip_extended = false)
continue 3;
default:
- // "Some systems may not implement signals, in which case they SHOULD ignore this message."
- // -- http://tools.ietf.org/html/rfc4254#section-6.9
+ list($want_reply) = Strings::unpackSSH2('b', $response);
+ if ($want_reply) {
+ // "If the request is not recognized or is not supported for the channel,
+ // SSH_MSG_CHANNEL_FAILURE is returned."
+ // -- https://datatracker.ietf.org/doc/html/rfc4254#page-10
+ $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_FAILURE, $this->server_channels[$channel]));
+ }
continue 3;
}
}
@@ -4714,7 +4722,7 @@ protected function send_channel_packet($client_channel, $data)
* @param bool $want_reply
* @return void
*/
- private function close_channel($client_channel)
+ protected function close_channel($client_channel)
{
// see http://tools.ietf.org/html/rfc4254#section-5.3
@@ -4905,6 +4913,7 @@ private static function array_intersect_first(array $array1, array $array2)
* If you are looking for messages from the SFTP layer, please see SFTP::getSFTPErrors()
*
* @return string[]
+ * @removed in phpseclib 4.0.0
*/
public function getErrors()
{
@@ -4917,6 +4926,7 @@ public function getErrors()
* If you are looking for messages from the SFTP layer, please see SFTP::getLastSFTPError()
*
* @return string
+ * @removed in phpseclib 4.0.0
*/
public function getLastError()
{
diff --git a/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf b/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
index 2b8b52f..6a5c0f5 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
+++ b/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
@@ -2,5 +2,8 @@
HOME = .
RANDFILE = $ENV::HOME/.rnd
+# without this line you'll get this error with openssl_pkey_new():
+# Warning: openssl_pkey_new(): Private key length must be at least 384 bits, configured to 0
+default_bits = 384
[ v3_ca ]
diff --git a/vendor/unzerdev/php-sdk/CHANGELOG.md b/vendor/unzerdev/php-sdk/CHANGELOG.md
index 468e50c..1e63b31 100644
--- a/vendor/unzerdev/php-sdk/CHANGELOG.md
+++ b/vendor/unzerdev/php-sdk/CHANGELOG.md
@@ -5,6 +5,60 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres
to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [4.0.1](https://github.com/unzerdev/php-sdk/compare/4.0.0..4.0.1)
+
+### Changed
+
+* `\UnzerSDK\Unzer` can now be initialised with a public key (`s-pub-*` / `p-pub-*`), enabling `fetchConfig()` to be called without a private key.
+
+## [4.0.0](https://github.com/unzerdev/php-sdk/compare/3.15.0..4.0.0)
+
+### Added
+
+* Add `company` field to `\UnzerSDK\Resources\EmbeddedResources\Address` class.
+* Add PHP 8.5 to supported versions in `composer.json`.
+
+### Changed
+
+* Allow `null` return for `getCompany()` in `\UnzerSDK\Resources\EmbeddedResources\Address`.
+* Remove deprecated `curl_close` and `\ReflectionMethod::setAccessible` calls to address PHP 8.5 deprecation warnings.
+* Drop support for PHP 7.4 and PHP 8.0.
+
+### Deprecated
+
+* Mark `\UnzerSDK\Resources\PaymentTypes\Giropay` as deprecated.
+
+## [3.15.0](https://github.com/unzerdev/php-sdk/compare/3.14.0..3.15.0)
+
+### Added
+
+* Add the SCA (Strong Customer Authentication) transaction type.
+ * Add class `\UnzerSDK\Resources\TransactionTypes\Sca`.
+ * Add methods in `\UnzerSDK\Unzer` class:
+ * `performSca(Sca $sca, $paymentType, $customer = null, ?Metadata $metadata = null, ?Basket $basket = null): Sca` -
+ Perform an SCA transaction.
+ * `fetchSca(Sca $sca): Sca` - Fetch an SCA transaction.
+ * `fetchScaById($payment, string $scaId): Sca` - Fetch an SCA transaction by ID.
+ * `chargeScaTransaction($payment, Charge $charge, $customer = null, ?Metadata $metadata = null, ?Basket $basket = null): Charge` -
+ Charge an SCA transaction.
+ * `authorizeScaTransaction($payment, Authorization $authorization, $customer = null, ?Metadata $metadata = null, ?Basket $basket = null): Authorization` -
+ Authorize an SCA transaction.
+ * Add methods in `\UnzerSDK\Resources\Payment` class:
+ * `getSca(bool $lazy = false): ?Sca` - Get the SCA transaction.
+ * `setSca(Sca $sca): self` - Set the SCA transaction.
+
+## [3.14.0](https://github.com/unzerdev/php-sdk/compare/3.13.2..3.14.0)
+
+### Changed
+
+* Add `subscriptionAgreement` property for v2 Paypage creation to `\UnzerSDK\Resources\EmbeddedResources\Paypage\Urls`
+
+## [3.13.2](https://github.com/unzerdev/php-sdk/compare/3.13.1..3.13.2)
+
+### Changed
+
+* Added chargeback handling for `fetchResourceFromEvent()` method.
+
## [3.13.1](https://github.com/unzerdev/php-sdk/compare/3.13.0..3.13.1)
### Added
diff --git a/vendor/unzerdev/php-sdk/composer.json b/vendor/unzerdev/php-sdk/composer.json
index 91dee32..7a6a2a7 100644
--- a/vendor/unzerdev/php-sdk/composer.json
+++ b/vendor/unzerdev/php-sdk/composer.json
@@ -4,11 +4,11 @@
"minimum-stability": "stable",
"license": "Apache-2.0",
"require": {
- "php": "~7.4.0|~8.0.0|~8.1.0|~8.2.0|~8.3.0|~8.4.0",
+ "php": "~8.1.0|~8.2.0|~8.3.0|~8.4.0|~8.5.0",
"ext-json": "*"
},
"require-dev": {
- "phpunit/phpunit": ">6.5 <10.0",
+ "phpunit/phpunit": "^9.6",
"friendsofphp/php-cs-fixer": "^3.0"
},
"suggest": {
diff --git a/vendor/unzerdev/php-sdk/phpunit.xml b/vendor/unzerdev/php-sdk/phpunit.xml
index df90057..b89b9dd 100644
--- a/vendor/unzerdev/php-sdk/phpunit.xml
+++ b/vendor/unzerdev/php-sdk/phpunit.xml
@@ -7,6 +7,7 @@
convertErrorsToExceptions="true"
convertNoticesToExceptions="false"
convertWarningsToExceptions="false"
+ convertDeprecationsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
verbose="true"
diff --git a/vendor/unzerdev/php-sdk/src/Adapter/ApplepayAdapter.php b/vendor/unzerdev/php-sdk/src/Adapter/ApplepayAdapter.php
index b23a463..820655c 100644
--- a/vendor/unzerdev/php-sdk/src/Adapter/ApplepayAdapter.php
+++ b/vendor/unzerdev/php-sdk/src/Adapter/ApplepayAdapter.php
@@ -42,7 +42,6 @@ public function validateApplePayMerchant(
$this->setOption(CURLOPT_POSTFIELDS, $payload);
$sessionResponse = $this->execute();
- $this->close();
return $sessionResponse;
}
@@ -131,14 +130,6 @@ public function execute(): ?string
throw new ApplepayMerchantValidationException($errorMessage);
}
- /**
- * @inheritDoc
- */
- public function close(): void
- {
- curl_close($this->request);
- }
-
/**
* @inheritDoc
*/
diff --git a/vendor/unzerdev/php-sdk/src/Adapter/CurlAdapter.php b/vendor/unzerdev/php-sdk/src/Adapter/CurlAdapter.php
index 5535eb4..43a781e 100644
--- a/vendor/unzerdev/php-sdk/src/Adapter/CurlAdapter.php
+++ b/vendor/unzerdev/php-sdk/src/Adapter/CurlAdapter.php
@@ -95,14 +95,6 @@ public function getResponseCode(): string
return curl_getinfo($this->request, CURLINFO_HTTP_CODE);
}
- /**
- * {@inheritDoc}
- */
- public function close(): void
- {
- curl_close($this->request);
- }
-
/**
* {@inheritDoc}
*/
diff --git a/vendor/unzerdev/php-sdk/src/Adapter/HttpAdapterInterface.php b/vendor/unzerdev/php-sdk/src/Adapter/HttpAdapterInterface.php
index 2e2bd0a..be80576 100644
--- a/vendor/unzerdev/php-sdk/src/Adapter/HttpAdapterInterface.php
+++ b/vendor/unzerdev/php-sdk/src/Adapter/HttpAdapterInterface.php
@@ -43,11 +43,6 @@ public function execute(): ?string;
*/
public function getResponseCode(): string;
- /**
- * Closes the connection of the request.
- */
- public function close(): void;
-
/**
* Sets the headers for the request.
* Expects an associative array with $key being the header name and $value being the header value.
diff --git a/vendor/unzerdev/php-sdk/src/Constants/ApiResponseCodes.php b/vendor/unzerdev/php-sdk/src/Constants/ApiResponseCodes.php
index 38c943f..c25d8aa 100644
--- a/vendor/unzerdev/php-sdk/src/Constants/ApiResponseCodes.php
+++ b/vendor/unzerdev/php-sdk/src/Constants/ApiResponseCodes.php
@@ -41,6 +41,7 @@ class ApiResponseCodes
public const API_ERROR_CUSTOMER_DOES_NOT_EXIST = 'API.410.100.100';
public const API_ERROR_CUSTOMER_ID_ALREADY_EXISTS = 'API.410.200.010';
public const API_ERROR_ADDRESS_NAME_TO_LONG = 'API.410.200.031';
+ public const API_CANNOT_CHARGE_UNSUCCESSFUL_SCA_TRANSACTION = 'API.500.100.060';
public const API_ERROR_CUSTOMER_CAN_NOT_BE_FOUND = 'API.500.100.100';
public const API_ERROR_REQUEST_DATA_IS_INVALID = 'API.500.300.999';
public const API_ERROR_RECURRING_PAYMENT_NOT_SUPPORTED = 'API.500.550.004';
diff --git a/vendor/unzerdev/php-sdk/src/Constants/IdStrings.php b/vendor/unzerdev/php-sdk/src/Constants/IdStrings.php
index 662c9ea..4634335 100644
--- a/vendor/unzerdev/php-sdk/src/Constants/IdStrings.php
+++ b/vendor/unzerdev/php-sdk/src/Constants/IdStrings.php
@@ -16,6 +16,7 @@ class IdStrings
public const CHARGEBACK = 'cbk';
public const PAYOUT = 'out';
public const PREAUTHORIZE = 'preaut';
+ public const SCA = 'sca';
public const SHIPMENT = 'shp';
// Payment Types
diff --git a/vendor/unzerdev/php-sdk/src/Constants/TransactionTypes.php b/vendor/unzerdev/php-sdk/src/Constants/TransactionTypes.php
index 3a4721b..e2ce38a 100644
--- a/vendor/unzerdev/php-sdk/src/Constants/TransactionTypes.php
+++ b/vendor/unzerdev/php-sdk/src/Constants/TransactionTypes.php
@@ -18,4 +18,5 @@ class TransactionTypes
public const SHIPMENT = 'shipment';
public const PAYOUT = 'payout';
public const CHARGEBACK = 'chargeback';
+ public const SCA = 'strong_customer_authentication';
}
diff --git a/vendor/unzerdev/php-sdk/src/Interfaces/PaymentServiceInterface.php b/vendor/unzerdev/php-sdk/src/Interfaces/PaymentServiceInterface.php
index d461397..ad05a50 100644
--- a/vendor/unzerdev/php-sdk/src/Interfaces/PaymentServiceInterface.php
+++ b/vendor/unzerdev/php-sdk/src/Interfaces/PaymentServiceInterface.php
@@ -24,6 +24,7 @@
use UnzerSDK\Resources\TransactionTypes\Authorization;
use UnzerSDK\Resources\TransactionTypes\Charge;
use UnzerSDK\Resources\TransactionTypes\Payout;
+use UnzerSDK\Resources\TransactionTypes\Sca;
use UnzerSDK\Resources\TransactionTypes\Shipment;
interface PaymentServiceInterface
@@ -389,4 +390,20 @@ public function fetchInstallmentPlans(
* @return PaylaterInstallmentPlans
*/
public function fetchPaylaterInstallmentPlans(InstallmentPlansQuery $plansRequest): PaylaterInstallmentPlans;
+
+ /**
+ * Perform an SCA transaction.
+ *
+ * @param Sca $sca The SCA object.
+ * @param BasePaymentType|string $paymentType The payment type object or ID.
+ * @param Customer|string|null $customer The customer object or ID.
+ * @param Metadata|null $metadata The metadata object.
+ * @param Basket|null $basket The basket object.
+ *
+ * @return Sca The resulting SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function performSca(Sca $sca, $paymentType, $customer = null, ?Metadata $metadata = null, ?Basket $basket = null): Sca;
}
diff --git a/vendor/unzerdev/php-sdk/src/Interfaces/ResourceServiceInterface.php b/vendor/unzerdev/php-sdk/src/Interfaces/ResourceServiceInterface.php
index 6f26b0a..22c752c 100644
--- a/vendor/unzerdev/php-sdk/src/Interfaces/ResourceServiceInterface.php
+++ b/vendor/unzerdev/php-sdk/src/Interfaces/ResourceServiceInterface.php
@@ -25,6 +25,7 @@
use UnzerSDK\Resources\TransactionTypes\Charge;
use UnzerSDK\Resources\TransactionTypes\Chargeback;
use UnzerSDK\Resources\TransactionTypes\Payout;
+use UnzerSDK\Resources\TransactionTypes\Sca;
use UnzerSDK\Resources\TransactionTypes\Shipment;
interface ResourceServiceInterface
@@ -452,4 +453,29 @@ public function fetchShipment($payment, string $shipmentId): Shipment;
* @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
*/
public function fetchConfig(BasePaymentType $paymentType, ?Config $config = null): Config;
+
+ /**
+ * Fetches an SCA transaction.
+ *
+ * @param Sca $sca The SCA object to fetch.
+ *
+ * @return Sca The fetched SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function fetchSca(Sca $sca): Sca;
+
+ /**
+ * Fetches an SCA transaction by payment ID and SCA ID.
+ *
+ * @param Payment|string $payment The payment object or payment ID.
+ * @param string $scaId The SCA transaction ID.
+ *
+ * @return Sca The fetched SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function fetchScaById($payment, string $scaId): Sca;
}
diff --git a/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Address.php b/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Address.php
index 48e3b6f..a86a76e 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Address.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Address.php
@@ -30,6 +30,9 @@ class Address extends AbstractUnzerResource
/** @var string country */
protected $country;
+ /** @var string company */
+ protected $company;
+
/** @var string|null shippingType */
protected $shippingType;
@@ -165,4 +168,15 @@ public function setShippingType(?string $shippingType): Address
$this->shippingType = $shippingType;
return $this;
}
+
+ public function getCompany(): ?string
+ {
+ return $this->company;
+ }
+
+ public function setCompany(?string $company): Address
+ {
+ $this->company = $company;
+ return $this;
+ }
}
diff --git a/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Urls.php b/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Urls.php
index 5437d33..5796b00 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Urls.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/EmbeddedResources/Paypage/Urls.php
@@ -11,11 +11,15 @@ class Urls extends AbstractUnzerResource
protected ?string $imprint = null;
protected ?string $help = null;
protected ?string $contact = null;
+ /** @deprecated Use Style::$favicon instead.
+ * @see Style::$favicon
+ */
protected ?string $favicon = null;
protected ?string $returnSuccess = null;
protected ?string $returnPending = null;
protected ?string $returnFailure = null;
protected ?string $returnCancel = null;
+ protected ?string $subscriptionAgreement = null;
public function getTermsAndCondition(): ?string
{
@@ -126,4 +130,15 @@ public function setReturnCancel(?string $returnCancel): Urls
$this->returnCancel = $returnCancel;
return $this;
}
+
+ public function getSubscriptionAgreement(): ?string
+ {
+ return $this->subscriptionAgreement;
+ }
+
+ public function setSubscriptionAgreement(?string $subscriptionAgreement): Urls
+ {
+ $this->subscriptionAgreement = $subscriptionAgreement;
+ return $this;
+ }
}
\ No newline at end of file
diff --git a/vendor/unzerdev/php-sdk/src/Resources/Payment.php b/vendor/unzerdev/php-sdk/src/Resources/Payment.php
index 4a75656..80c49a1 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/Payment.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/Payment.php
@@ -19,6 +19,7 @@
use UnzerSDK\Resources\TransactionTypes\Chargeback;
use UnzerSDK\Resources\TransactionTypes\Payout;
use UnzerSDK\Resources\TransactionTypes\PreAuthorization;
+use UnzerSDK\Resources\TransactionTypes\Sca;
use UnzerSDK\Resources\TransactionTypes\Shipment;
use UnzerSDK\Services\IdService;
use UnzerSDK\Traits\HasInvoiceId;
@@ -58,6 +59,9 @@ class Payment extends AbstractUnzerResource
/** @var Chargeback[] $chargebacks */
private $chargebacks = [];
+ /** @var Sca|null $sca */
+ private $sca;
+
/**
* Associative array using the ID of the cancellations as the key.
@@ -337,6 +341,33 @@ public function getChargeByIndex(int $index, bool $lazy = false)
return $resource;
}
+ /**
+ * Returns the SCA transaction of this Payment.
+ */
+ public function getSca(bool $lazy = false): ?Sca
+ {
+ $sca = $this->sca;
+ if (!$lazy && $sca !== null) {
+ /** @var Sca */
+ return $this->getResource($sca);
+ }
+ return $sca;
+ }
+
+ /**
+ * Adds an SCA object to this Payment.
+ *
+ * @param Sca $sca
+ *
+ * @return $this
+ */
+ public function setSca(Sca $sca): self
+ {
+ $sca->setPayment($this);
+ $this->sca = $sca;
+ return $this;
+ }
+
/**
* Reference this payment object to the passed Customer resource.
* The Customer resource can be passed as Customer object or the Id of a Customer resource.
@@ -924,6 +955,9 @@ private function updateResponseTransactions(array $transactions = []): void
case TransactionTypes::CHARGEBACK:
$this->updateChargebackTransaction($transaction);
break;
+ case TransactionTypes::SCA:
+ $this->updateScaTransaction($transaction);
+ break;
default:
// skip
break;
@@ -1191,4 +1225,25 @@ private function updateChargebackTransaction(stdClass $transaction): void
$chargeback->handleResponse($transaction);
}
+
+ /**
+ * This updates the local SCA object referenced by this Payment with the given SCA transaction
+ * from the Payment response.
+ *
+ * @param stdClass $transaction The transaction from the Payment response containing the SCA data.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ private function updateScaTransaction(stdClass $transaction): void
+ {
+ $transactionId = IdService::getResourceIdFromUrl($transaction->url, IdStrings::SCA);
+ $sca = $this->sca;
+ if (!$sca instanceof Sca) {
+ $sca = (new Sca())->setPayment($this)->setId($transactionId);
+ $this->setSca($sca);
+ }
+
+ $sca->handleResponse($transaction);
+ }
}
diff --git a/vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Giropay.php b/vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Giropay.php
index 9d2a6f2..975fea6 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Giropay.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/PaymentTypes/Giropay.php
@@ -4,6 +4,7 @@
use UnzerSDK\Traits\CanDirectCharge;
+/** @deprecated Giropay payment type is no longer supported and will be removed in a future version. */
class Giropay extends BasePaymentType
{
use CanDirectCharge;
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/AbstractTransactionType.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/AbstractTransactionType.php
index 70bd080..c15adfe 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/AbstractTransactionType.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/AbstractTransactionType.php
@@ -39,6 +39,9 @@ abstract class AbstractTransactionType extends AbstractUnzerResource
use HasAdditionalTransactionData;
use HasDate;
+ /** @var float $amount */
+ protected $amount;
+
/** @var Payment $payment */
private $payment;
@@ -242,4 +245,23 @@ protected function handleWeroTransactionData(stdClass $additionalTransactionData
$this->setWeroTransactionData($weroTransactionData);
}
}
+
+ /**
+ * @param float|null $amount
+ *
+ * @return self
+ */
+ public function setAmount(?float $amount): self
+ {
+ $this->amount = $amount !== null ? round($amount, 4) : null;
+ return $this;
+ }
+
+ /**
+ * @return float|null
+ */
+ public function getAmount(): ?float
+ {
+ return $this->amount;
+ }
}
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Authorization.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Authorization.php
index 6936b8b..4df8d11 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Authorization.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Authorization.php
@@ -62,25 +62,6 @@ public function __construct(?float $amount = null, ?string $currency = null, ?st
$this->setReturnUrl($returnUrl);
}
- /**
- * @return float|null
- */
- public function getAmount(): ?float
- {
- return $this->amount;
- }
-
- /**
- * @param float|null $amount
- *
- * @return self
- */
- public function setAmount(?float $amount): self
- {
- $this->amount = $amount !== null ? round($amount, 4) : null;
- return $this;
- }
-
/**
* @return float|null
*/
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Cancellation.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Cancellation.php
index ad41d1c..51f0d86 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Cancellation.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Cancellation.php
@@ -16,13 +16,6 @@
*/
class Cancellation extends AbstractTransactionType
{
- /**
- * The cancellation amount will be transferred as grossAmount in case of Installment Secured payment type.
- *
- * @var float $amount
- */
- protected $amount;
-
/** @var string $reasonCode */
protected $reasonCode;
@@ -53,29 +46,6 @@ public function __construct(?float $amount = null)
$this->setAmount($amount);
}
- /**
- * Returns the cancellationAmount (equals grossAmount in case of Installment Secured).
- *
- * @return float|null
- */
- public function getAmount(): ?float
- {
- return $this->amount;
- }
-
- /**
- * Sets the cancellationAmount (equals grossAmount in case of Installment Secured).
- *
- * @param float|null $amount
- *
- * @return Cancellation
- */
- public function setAmount(?float $amount): self
- {
- $this->amount = $amount !== null ? round($amount, 4) : null;
- return $this;
- }
-
/**
* Returns the reason code of the cancellation if set.
*
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Charge.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Charge.php
index 278cc9c..338bca7 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Charge.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Charge.php
@@ -25,9 +25,6 @@ class Charge extends AbstractTransactionType
use HasDescriptor;
use HasChargebacks;
- /** @var float $amount */
- protected $amount;
-
/** @var string $currency */
protected $currency;
@@ -54,25 +51,6 @@ public function __construct(?float $amount = null, ?string $currency = null, ?st
$this->setReturnUrl($returnUrl);
}
- /**
- * @return float|null
- */
- public function getAmount(): ?float
- {
- return $this->amount;
- }
-
- /**
- * @param float|null $amount
- *
- * @return self
- */
- public function setAmount(?float $amount): self
- {
- $this->amount = $amount !== null ? round($amount, 4) : null;
- return $this;
- }
-
/**
* @return float|null
*/
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Chargeback.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Chargeback.php
index 2ef22d0..607ebe7 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Chargeback.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Chargeback.php
@@ -12,9 +12,6 @@
*/
class Chargeback extends AbstractTransactionType
{
- /** @var float $amount */
- protected $amount;
-
/** @var string $currency */
protected $currency;
@@ -29,27 +26,6 @@ public function __construct(?float $amount = null)
$this->setAmount($amount);
}
- /**
- * @return float|null
- */
- public function getAmount(): ?float
- {
- return $this->amount;
- }
-
- /**
- * Sets the cancellationAmount (equals grossAmount in case of Installment Secured).
- *
- * @param float|null $amount
- *
- * @return Cancellation
- */
- public function setAmount(?float $amount): self
- {
- $this->amount = $amount !== null ? round($amount, 4) : null;
- return $this;
- }
-
/**
* @return string
*/
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Payout.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Payout.php
index 15f0767..2f39d5a 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Payout.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Payout.php
@@ -12,9 +12,6 @@
*/
class Payout extends AbstractTransactionType
{
- /** @var float|null $amount */
- protected $amount;
-
/** @var string|null $currency */
protected $currency;
@@ -31,25 +28,6 @@ public function __construct(?float $amount = null, ?string $currency = null, $re
$this->setReturnUrl($returnUrl);
}
- /**
- * @return float|null
- */
- public function getAmount(): ?float
- {
- return $this->amount;
- }
-
- /**
- * @param float|null $amount
- *
- * @return self
- */
- public function setAmount(?float $amount): self
- {
- $this->amount = $amount !== null ? round($amount, 4) : null;
- return $this;
- }
-
/**
* @return string|null
*/
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Sca.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Sca.php
new file mode 100644
index 0000000..b9119d7
--- /dev/null
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Sca.php
@@ -0,0 +1,107 @@
+setAmount($amount);
+ $this->setCurrency($currency);
+ $this->setReturnUrl($returnUrl);
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getCurrency(): ?string
+ {
+ return $this->currency;
+ }
+
+ /**
+ * @param string|null $currency
+ *
+ * @return self
+ */
+ public function setCurrency(?string $currency): self
+ {
+ $this->currency = $currency;
+ return $this;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getReturnUrl(): ?string
+ {
+ return $this->returnUrl;
+ }
+
+ /**
+ * @param string|null $returnUrl
+ *
+ * @return self
+ */
+ public function setReturnUrl(?string $returnUrl): self
+ {
+ $this->returnUrl = $returnUrl;
+ return $this;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getPaymentReference(): ?string
+ {
+ return $this->paymentReference;
+ }
+
+ /**
+ * @param string|null $referenceText
+ *
+ * @return Sca
+ */
+ public function setPaymentReference(?string $referenceText): Sca
+ {
+ $this->paymentReference = $referenceText;
+ return $this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::REQUEST_GET): string
+ {
+ return 'sca';
+ }
+}
diff --git a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Shipment.php b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Shipment.php
index 55dfbc7..d29e09c 100644
--- a/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Shipment.php
+++ b/vendor/unzerdev/php-sdk/src/Resources/TransactionTypes/Shipment.php
@@ -12,28 +12,6 @@
*/
class Shipment extends AbstractTransactionType
{
- /** @var float|null $amount */
- protected $amount;
-
- /**
- * @return float|null
- */
- public function getAmount(): ?float
- {
- return $this->amount;
- }
-
- /**
- * @param float|null $amount
- *
- * @return Shipment
- */
- public function setAmount(?float $amount): self
- {
- $this->amount = $amount !== null ? round($amount, 4) : null;
- return $this;
- }
-
/**
* {@inheritDoc}
*/
diff --git a/vendor/unzerdev/php-sdk/src/Services/HttpService.php b/vendor/unzerdev/php-sdk/src/Services/HttpService.php
index cce644c..68bcdc0 100644
--- a/vendor/unzerdev/php-sdk/src/Services/HttpService.php
+++ b/vendor/unzerdev/php-sdk/src/Services/HttpService.php
@@ -135,7 +135,6 @@ public function sendRequest(ApiRequest $request): string
$httpAdapter = $this->getAdapter();
$response = $httpAdapter->execute();
$responseCode = $httpAdapter->getResponseCode();
- $httpAdapter->close();
// handle response
try {
diff --git a/vendor/unzerdev/php-sdk/src/Services/PaymentService.php b/vendor/unzerdev/php-sdk/src/Services/PaymentService.php
index 8eefc35..e05dd4c 100644
--- a/vendor/unzerdev/php-sdk/src/Services/PaymentService.php
+++ b/vendor/unzerdev/php-sdk/src/Services/PaymentService.php
@@ -22,6 +22,7 @@
use UnzerSDK\Resources\TransactionTypes\Authorization;
use UnzerSDK\Resources\TransactionTypes\Charge;
use UnzerSDK\Resources\TransactionTypes\Payout;
+use UnzerSDK\Resources\TransactionTypes\Sca;
use UnzerSDK\Resources\TransactionTypes\Shipment;
use UnzerSDK\Unzer;
@@ -87,7 +88,10 @@ public function performAuthorization(
$paymentType = $payment->getPaymentType();
$authorization->setSpecialParams($paymentType !== null ? $paymentType->getTransactionParams() : []);
- $payment->setAuthorization($authorization)->setCustomer($customer)->setMetadata($metadata)->setBasket($basket);
+ $payment->setAuthorization($authorization)
+ ->setCustomer($customer)
+ ->setMetadata($metadata)
+ ->setBasket($basket);
$this->getResourceService()->createResource($authorization);
return $authorization;
@@ -392,4 +396,32 @@ private function createPayment($paymentType): AbstractUnzerResource
{
return (new Payment($this->unzer))->setPaymentType($paymentType);
}
+
+ /**
+ * Perform an SCA transaction.
+ *
+ * @param Sca $sca The SCA object to be executed.
+ * @param BasePaymentType|string $paymentType The payment type object or its ID.
+ * @param Customer|string|null $customer The customer object or ID.
+ * @param Metadata|null $metadata The metadata object.
+ * @param Basket|null $basket The basket object.
+ *
+ * @return Sca The resulting SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function performSca(Sca $sca, $paymentType, $customer = null, ?Metadata $metadata = null, ?Basket $basket = null): Sca
+ {
+ $payment = $this->createPayment($paymentType);
+ $paymentType = $payment->getPaymentType();
+
+ /** @var Sca $sca */
+ $sca->setSpecialParams($paymentType->getTransactionParams() ?? []);
+ $payment->setSca($sca)->setCustomer($customer)->setMetadata($metadata)->setBasket($basket);
+
+ $this->getResourceService()->createResource($sca);
+
+ return $sca;
+ }
}
diff --git a/vendor/unzerdev/php-sdk/src/Services/ResourceService.php b/vendor/unzerdev/php-sdk/src/Services/ResourceService.php
index b4bedfe..90b0957 100644
--- a/vendor/unzerdev/php-sdk/src/Services/ResourceService.php
+++ b/vendor/unzerdev/php-sdk/src/Services/ResourceService.php
@@ -59,6 +59,7 @@
use UnzerSDK\Resources\TransactionTypes\Charge;
use UnzerSDK\Resources\TransactionTypes\Chargeback;
use UnzerSDK\Resources\TransactionTypes\Payout;
+use UnzerSDK\Resources\TransactionTypes\Sca;
use UnzerSDK\Resources\TransactionTypes\Shipment;
use UnzerSDK\Resources\V2\Customer as CustomerV2;
use UnzerSDK\Resources\V2\Paypage as PaypageV2;
@@ -209,9 +210,25 @@ public function fetchResourceByUrl($url)
}
$resource = $unzer->fetchReversal($paymentId, $resourceId);
break;
+ case $resourceType === IdStrings::CHARGEBACK:
+ $paymentId = IdService::getResourceIdFromUrl($url, IdStrings::PAYMENT);
+ $chargeId = IdService::getResourceIdOrNullFromUrl($url, IdStrings::CHARGE);
+
+ $resource = $this->fetchChargebackById(
+ $paymentId,
+ $resourceId,
+ $chargeId
+ );
+ break;
case $resourceType === IdStrings::PAYOUT:
$resource = $unzer->fetchPayout(IdService::getResourceIdFromUrl($url, IdStrings::PAYMENT));
break;
+ case $resourceType === IdStrings::SCA:
+ $resource = $unzer->fetchScaById(
+ IdService::getResourceIdFromUrl($url, IdStrings::PAYMENT),
+ $resourceId
+ );
+ break;
case $resourceType === IdStrings::PAYMENT:
$resource = $unzer->fetchPayment($resourceId);
break;
@@ -970,4 +987,44 @@ public static function getTypeInstanceFromIdString($typeId): BasePaymentType
}
return $paymentType;
}
+
+ /**
+ * Fetches an SCA transaction.
+ *
+ * @param Sca $sca The SCA object to fetch.
+ *
+ * @return Sca The fetched SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function fetchSca(Sca $sca): Sca
+ {
+ $this->fetchResource($sca);
+ return $sca;
+ }
+
+ /**
+ * Fetches an SCA transaction by payment ID and SCA ID.
+ *
+ * @param Payment|string $payment The payment object or payment ID.
+ * @param string $scaId The SCA transaction ID.
+ *
+ * @return Sca The fetched SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function fetchScaById($payment, string $scaId): Sca
+ {
+ $paymentObject = $this->fetchPayment($payment);
+ $sca = $paymentObject->getSca($scaId, true);
+
+ if (!$sca instanceof Sca) {
+ throw new RuntimeException('The SCA object could not be found.');
+ }
+
+ $this->fetchResource($sca);
+ return $sca;
+ }
}
diff --git a/vendor/unzerdev/php-sdk/src/Unzer.php b/vendor/unzerdev/php-sdk/src/Unzer.php
index b4dc186..b34caf1 100644
--- a/vendor/unzerdev/php-sdk/src/Unzer.php
+++ b/vendor/unzerdev/php-sdk/src/Unzer.php
@@ -33,6 +33,7 @@
use UnzerSDK\Resources\TransactionTypes\Charge;
use UnzerSDK\Resources\TransactionTypes\Chargeback;
use UnzerSDK\Resources\TransactionTypes\Payout;
+use UnzerSDK\Resources\TransactionTypes\Sca;
use UnzerSDK\Resources\TransactionTypes\Shipment;
use UnzerSDK\Resources\V2\Paypage as PaypageV2;
use UnzerSDK\Resources\Webhook;
@@ -43,6 +44,7 @@
use UnzerSDK\Services\ResourceService;
use UnzerSDK\Services\WebhookService;
use UnzerSDK\Validators\PrivateKeyValidator;
+use UnzerSDK\Validators\PublicKeyValidator;
/**
* This is the Unzer object which is the base object providing all functionalities needed to
@@ -58,7 +60,7 @@ class Unzer implements
public const BASE_URL = 'api.unzer.com';
public const API_VERSION = ApiVersions::V1;
public const SDK_TYPE = 'UnzerPHP';
- public const SDK_VERSION = '3.13.1';
+ public const SDK_VERSION = '4.0.1';
/** @var string $key */
private $key;
@@ -94,10 +96,10 @@ class Unzer implements
/**
* Construct a new Unzer object.
*
- * @param string $key The private key your received from your Unzer contact person.
+ * @param string $key The private or public key your received from your Unzer contact person.
* @param string|null $locale The locale of the customer defining defining the translation (e.g. 'en-GB' or 'de-DE').
*
- * @throws RuntimeException A RuntimeException will be thrown if the key is not of type private.
+ * @throws RuntimeException A RuntimeException will be thrown if the key is not a valid private or public key.
*
* @link https://docs.unzer.com/integrate/web-integration/#section-localization-and-languages
*
@@ -115,7 +117,7 @@ public function __construct(string $key, ?string $locale = '')
}
/**
- * Returns the set private key used to connect to the API.
+ * Returns the set key used to connect to the API.
*
* @return string The key that is currently set.
*/
@@ -125,9 +127,9 @@ public function getKey(): string
}
/**
- * Sets your private key used to connect to the API.
+ * Sets your private or public key used to connect to the API.
*
- * @param string $key The private key.
+ * @param string $key The private or public key.
*
* @return Unzer This Unzer object.
*
@@ -137,8 +139,8 @@ public function getKey(): string
*/
public function setKey(string $key): Unzer
{
- if (!PrivateKeyValidator::validate($key)) {
- throw new RuntimeException('Illegal key: Use a valid private key with this SDK!');
+ if (!PrivateKeyValidator::validate($key) && !PublicKeyValidator::validate($key)) {
+ throw new RuntimeException('Illegal key: Use a valid private or public key with this SDK!');
}
$this->key = $key;
@@ -812,6 +814,146 @@ public function performChargeOnPayment($payment, Charge $charge): Charge
return $this->paymentService->performChargeOnPayment($payment, $charge);
}
+ /**
+ * Perform an SCA transaction.
+ *
+ * @param Sca $sca The SCA object.
+ * @param BasePaymentType|string $paymentType The payment type object or ID.
+ * @param Customer|string|null $customer The customer object or ID.
+ * @param Metadata|null $metadata The metadata object.
+ * @param Basket|null $basket The basket object.
+ *
+ * @return Sca The resulting SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function performSca(Sca $sca, $paymentType, $customer = null, ?Metadata $metadata = null, ?Basket $basket = null): Sca
+ {
+ return $this->paymentService->performSca($sca, $paymentType, $customer, $metadata, $basket);
+ }
+
+ /**
+ * Fetch an SCA transaction.
+ *
+ * @param Sca $sca The SCA object to fetch.
+ *
+ * @return Sca The fetched SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function fetchSca(Sca $sca): Sca
+ {
+ return $this->resourceService->fetchSca($sca);
+ }
+
+ /**
+ * Fetch an SCA transaction by payment ID and SCA ID.
+ *
+ * @param Payment|string $payment The payment object or payment ID.
+ * @param string $scaId The SCA transaction ID.
+ *
+ * @return Sca The fetched SCA object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function fetchScaById($payment, string $scaId): Sca
+ {
+ return $this->resourceService->fetchScaById($payment, $scaId);
+ }
+
+ /**
+ * Charge an SCA transaction.
+ *
+ * @param Payment|string $payment The payment object or payment ID.
+ * @param Charge $charge The Charge object to process.
+ * @param Customer|string|null $customer The customer object or customer ID.
+ * @param Metadata|null $metadata The metadata object.
+ * @param Basket|null $basket The basket object.
+ *
+ * @return Charge The resulting Charge object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function chargeScaTransaction(
+ $payment,
+ Charge $charge,
+ $customer = null,
+ ?Metadata $metadata = null,
+ ?Basket $basket = null): Charge
+ {
+ $paymentObject = $this->resourceService->getPaymentResource($payment);
+ $sca = $paymentObject->getSca(true);
+
+ if (!$sca instanceof Sca) {
+ throw new RuntimeException('SCA transaction not found.');
+ }
+
+ // Set Sca object without id as a parent to match the URI path.
+ $scaParent = new Sca();
+ $scaParent->setParentResource($paymentObject);
+
+ $paymentObject->addCharge($charge)
+ ->setCustomer($customer)
+ ->setMetadata($metadata)
+ ->setBasket($basket);
+
+ $charge->setPayment($paymentObject);
+ $charge->setParentResource($scaParent);
+
+ $this->resourceService->createResource($charge);
+
+ return $charge;
+ }
+
+ /**
+ * Authorize an SCA transaction.
+ *
+ * @param Payment|string $payment The payment object or payment ID.
+ * @param Authorization $authorization The Authorization object to process.
+ * @param Customer|string|null $customer The customer object or customer ID.
+ * @param Metadata|null $metadata The metadata object.
+ * @param Basket|null $basket The basket object.
+ *
+ * @return Authorization The resulting Authorization object.
+ *
+ * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request.
+ * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK.
+ */
+ public function authorizeScaTransaction(
+ $payment,
+ Authorization $authorization,
+ $customer = null,
+ ?Metadata $metadata = null,
+ ?Basket $basket = null): Authorization
+ {
+ $paymentObject = $this->resourceService->getPaymentResource($payment);
+ $sca = $paymentObject->getSca(true);
+
+ if (!$sca instanceof Sca) {
+ throw new RuntimeException('SCA transaction not found.');
+ }
+
+ // Set Sca object without id as a parent to match the URI path.
+ $scaParent = new Sca();
+ $scaParent->setParentResource($paymentObject);
+
+ $paymentObject->setAuthorization($authorization)
+ ->setCustomer($customer)
+ ->setMetadata($metadata)
+ ->setBasket($basket);
+
+ $authorization->setPayment($paymentObject);
+ $authorization->setParentResource($scaParent);
+
+ $this->resourceService->createResource($authorization);
+
+ return $authorization;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/vendor/unzerdev/php-sdk/test/Fixtures/CustomerFixtureTrait.php b/vendor/unzerdev/php-sdk/test/Fixtures/CustomerFixtureTrait.php
index 6055e81..5fe4ca2 100644
--- a/vendor/unzerdev/php-sdk/test/Fixtures/CustomerFixtureTrait.php
+++ b/vendor/unzerdev/php-sdk/test/Fixtures/CustomerFixtureTrait.php
@@ -153,6 +153,7 @@ public function getBillingAddress(): Address
->setZip('60386')
->setCity('Frankfurt am Main')
->setCountry('DE')
+ ->setCompany('Your Company Name')
->setState('DE-BO');
}
@@ -170,6 +171,7 @@ public function getShippingAddress(): Address
->setCity('Frankfurt am Main')
->setCountry('DE')
->setState('DE-BO')
+ ->setCompany('Your Company Name')
->setShippingType(ShippingTypes::EQUALS_BILLING);
}
}
diff --git a/vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaPaymentResponse.json b/vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaPaymentResponse.json
new file mode 100644
index 0000000..f897f5a
--- /dev/null
+++ b/vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaPaymentResponse.json
@@ -0,0 +1,33 @@
+{
+ "id": "s-sca-1",
+ "isSuccess": true,
+ "isPending": false,
+ "isResumed": false,
+ "isError": false,
+ "card3ds": true,
+ "redirectUrl": "",
+ "message": {
+ "code": "COR.000.100.200",
+ "merchant": "Transaction succeeded",
+ "customer": "Your payments have been successfully processed."
+ },
+ "amount": "119.0000",
+ "currency": "EUR",
+ "date": "2023-02-28 08:00:00",
+ "resources": {
+ "customerId": "",
+ "paymentId": "s-pay-123",
+ "basketId": "",
+ "metadataId": "",
+ "payPageId": "",
+ "traceId": "trace-123",
+ "typeId": "s-crd-123"
+ },
+ "paymentReference": "",
+ "processing": {
+ "uniqueId": "31HA0xyz",
+ "shortId": "1234.1234.1234",
+ "3dsEci": "3DS_SUCCESS",
+ "traceId": "trace-123"
+ }
+}
\ No newline at end of file
diff --git a/vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaResponse.json b/vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaResponse.json
new file mode 100644
index 0000000..f897f5a
--- /dev/null
+++ b/vendor/unzerdev/php-sdk/test/Fixtures/jsonData/scaResponse.json
@@ -0,0 +1,33 @@
+{
+ "id": "s-sca-1",
+ "isSuccess": true,
+ "isPending": false,
+ "isResumed": false,
+ "isError": false,
+ "card3ds": true,
+ "redirectUrl": "",
+ "message": {
+ "code": "COR.000.100.200",
+ "merchant": "Transaction succeeded",
+ "customer": "Your payments have been successfully processed."
+ },
+ "amount": "119.0000",
+ "currency": "EUR",
+ "date": "2023-02-28 08:00:00",
+ "resources": {
+ "customerId": "",
+ "paymentId": "s-pay-123",
+ "basketId": "",
+ "metadataId": "",
+ "payPageId": "",
+ "traceId": "trace-123",
+ "typeId": "s-crd-123"
+ },
+ "paymentReference": "",
+ "processing": {
+ "uniqueId": "31HA0xyz",
+ "shortId": "1234.1234.1234",
+ "3dsEci": "3DS_SUCCESS",
+ "traceId": "trace-123"
+ }
+}
\ No newline at end of file
diff --git a/vendor/unzerdev/php-sdk/test/Helper/TestEnvironmentService.php b/vendor/unzerdev/php-sdk/test/Helper/TestEnvironmentService.php
index 755eaa5..5267475 100644
--- a/vendor/unzerdev/php-sdk/test/Helper/TestEnvironmentService.php
+++ b/vendor/unzerdev/php-sdk/test/Helper/TestEnvironmentService.php
@@ -16,6 +16,10 @@ class TestEnvironmentService extends EnvironmentService
public const ENV_VAR_TEST_PRIVATE_KEY_DEFAULT = 'UNZER_PAPI_TEST_PRIVATE_KEY_DEFAULT';
public const ENV_VAR_TEST_PUBLIC_KEY_DEFAULT = 'UNZER_PAPI_TEST_PUBLIC_KEY_DEFAULT';
+ /** Primary testing Keypair used as default for most payment types. */
+ public const ENV_VAR_TEST_PRIVATE_KEY_UNZER_ONE = 'UNZER_PAPI_TEST_PRIVATE_KEY_UNZER_ONE';
+ public const ENV_VAR_TEST_PUBLIC_KEY_UNZER_ONE = 'UNZER_PAPI_TEST_PUBLIC_KEY_UNZER_ONE';
+
/** Secondary keypair mainly used for payment methods that need a second configuration to be tested. */
public const ENV_VAR_TEST_PRIVATE_KEY_ALTERNATIVE = 'UNZER_PAPI_TEST_PRIVATE_KEY_ALTERNATIVE';
public const ENV_VAR_TEST_PUBLIC_KEY_ALTERNATIVE = 'UNZER_PAPI_TEST_PUBLIC_KEY_ALTERNATIVE';
@@ -106,4 +110,9 @@ public static function getLegacyTestPrivateKey(): string
{
return stripslashes($_SERVER[self::ENV_VAR_TEST_PRIVATE_KEY_LEGACY] ?? '');
}
+
+ public static function getUnzerOneTestPrivateKey(): string
+ {
+ return stripslashes($_SERVER[self::ENV_VAR_TEST_PRIVATE_KEY_UNZER_ONE] ?? '');
+ }
}
diff --git a/vendor/unzerdev/php-sdk/test/integration/PaymentTypes/GiropayTest.php b/vendor/unzerdev/php-sdk/test/integration/PaymentTypes/GiropayTest.php
deleted file mode 100644
index c6b5351..0000000
--- a/vendor/unzerdev/php-sdk/test/integration/PaymentTypes/GiropayTest.php
+++ /dev/null
@@ -1,79 +0,0 @@
-unzer->createPaymentType($giropay);
- $this->assertInstanceOf(Giropay::class, $giropay);
- $this->assertNotNull($giropay->getId());
- }
-
- /**
- * Verify that an exception is thrown when giropay authorize is called.
- *
- * @test
- */
- public function giroPayShouldThrowExceptionOnAuthorize(): void
- {
- $this->expectException(UnzerApiException::class);
- $this->expectExceptionCode(ApiResponseCodes::API_ERROR_TRANSACTION_AUTHORIZE_NOT_ALLOWED);
-
- $giropay = $this->unzer->createPaymentType(new Giropay());
- $this->unzer->authorize(1.0, 'EUR', $giropay, self::RETURN_URL);
- }
-
- /**
- * Verify that GiroPay is chargeable.
- *
- * @test
- */
- public function giroPayShouldBeChargeable(): void
- {
- /** @var Giropay $giropay */
- $giropay = $this->unzer->createPaymentType(new Giropay());
- $charge = $giropay->charge(1.0, 'EUR', self::RETURN_URL);
- $this->assertNotNull($charge);
- $this->assertNotNull($charge->getId());
- $this->assertNotEmpty($charge->getRedirectUrl());
-
- $fetchCharge = $this->unzer->fetchChargeById($charge->getPayment()->getId(), $charge->getId());
- $this->assertEquals($charge->setCard3ds(false)->expose(), $fetchCharge->expose());
- }
-
- /**
- * Verify a GiroPay object can be fetched from the api.
- *
- * @test
- */
- public function giroPayCanBeFetched(): void
- {
- $giropay = $this->unzer->createPaymentType(new Giropay());
- $fetchedGiropay = $this->unzer->fetchPaymentType($giropay->getId());
- $this->assertInstanceOf(Giropay::class, $fetchedGiropay);
- $this->assertEquals($giropay->getId(), $fetchedGiropay->getId());
- }
-}
diff --git a/vendor/unzerdev/php-sdk/test/integration/Resources/PaypageV2Test.php b/vendor/unzerdev/php-sdk/test/integration/Resources/PaypageV2Test.php
index 18ca4ac..73c4fd0 100644
--- a/vendor/unzerdev/php-sdk/test/integration/Resources/PaypageV2Test.php
+++ b/vendor/unzerdev/php-sdk/test/integration/Resources/PaypageV2Test.php
@@ -146,7 +146,6 @@ public function createPaypageWithOptionalStringProperties()
/**
* @test
- * @group skip
*/
public function createPaypageWithUrls()
{
@@ -156,11 +155,11 @@ public function createPaypageWithUrls()
$urls->setImprint('https://imprint.com');
$urls->setHelp('https://help.com');
$urls->setContact('https://contact.com');
- $urls->setFavicon('https://favicon.com');
$urls->setReturnSuccess('https://returnsuccess.com');
$urls->setReturnPending('https://returnpending.com');
$urls->setReturnFailure('https://returnfailure.com');
$urls->setReturnCancel('https://returncancel.com');
+ $urls->setSubscriptionAgreement('https://subscriptionagreement.com');
$paypage = new Paypage(9.99, 'EUR', 'charge');
$paypage->setUrls($urls);
diff --git a/vendor/unzerdev/php-sdk/test/integration/TransactionTypes/ScaTest.php b/vendor/unzerdev/php-sdk/test/integration/TransactionTypes/ScaTest.php
new file mode 100644
index 0000000..1e76cc4
--- /dev/null
+++ b/vendor/unzerdev/php-sdk/test/integration/TransactionTypes/ScaTest.php
@@ -0,0 +1,191 @@
+getUnzerObject(TestEnvironmentService::getUnzerOneTestPrivateKey());
+ }
+ /**
+ * Verify SCA transaction can be performed using the id of a payment type.
+ *
+ * @test
+ */
+ public function scaShouldWorkWithTypeId(): Sca
+ {
+ /** @var Card $paymentType */
+ $paymentType = $this->unzer->createPaymentType($this->createCardObject());
+ $sca = new Sca(100.0, 'EUR', self::RETURN_URL);
+ $sca = $this->unzer->performSca($sca, $paymentType->getId());
+
+ $this->assertTransactionResourceHasBeenCreated($sca);
+ $this->assertInstanceOf(Payment::class, $sca->getPayment());
+ $this->assertNotEmpty($sca->getPayment()->getId());
+ $this->assertEquals(self::RETURN_URL, $sca->getReturnUrl());
+
+ return $sca;
+ }
+
+ /**
+ * Verify SCA transaction can be performed with payment type object.
+ *
+ * @test
+ */
+ public function scaShouldWorkWithTypeObject(): Sca
+ {
+ /** @var Card $paymentType */
+ $paymentType = $this->unzer->createPaymentType($this->createCardObject());
+ $sca = new Sca(100.0, 'EUR', self::RETURN_URL);
+ $sca = $this->unzer->performSca($sca, $paymentType);
+
+ $this->assertTransactionResourceHasBeenCreated($sca);
+ $this->assertInstanceOf(Payment::class, $sca->getPayment());
+ $this->assertNotEmpty($sca->getPayment()->getId());
+ $this->assertEquals(self::RETURN_URL, $sca->getReturnUrl());
+
+ return $sca;
+ }
+
+ /**
+ * Verify SCA transaction accepts all parameters.
+ *
+ * @test
+ */
+ public function scaShouldAcceptAllParameters(): Sca
+ {
+ // prepare test data
+ /** @var Card $paymentType */
+ $paymentType = $this->unzer->createPaymentType($this->createCardObject());
+ $customer = $this->getMinimalCustomer();
+ $metadata = (new Metadata())->addMetadata('key', 'value');
+ $basket = $this->createBasket();
+ $paymentReference = 'scaPaymentReference';
+
+ // perform request
+ $sca = new Sca(119.0, 'EUR', self::RETURN_URL);
+ $sca->setPaymentReference($paymentReference);
+
+ $sca = $this->unzer->performSca($sca, $paymentType, $customer, $metadata, $basket);
+
+ // verify the data sent and received match
+ $payment = $sca->getPayment();
+ $this->assertSame($paymentType, $payment->getPaymentType());
+ $this->assertEquals(119.0, $sca->getAmount());
+ $this->assertEquals('EUR', $sca->getCurrency());
+ $this->assertEquals(self::RETURN_URL, $sca->getReturnUrl());
+ $this->assertSame($customer, $payment->getCustomer());
+ $this->assertSame($metadata, $payment->getMetadata());
+ $this->assertSame($basket, $payment->getBasket());
+ $this->assertEquals($paymentReference, $sca->getPaymentReference());
+
+ return $sca;
+ }
+
+ /**
+ * Verify SCA transaction can be fetched.
+ *
+ * @test
+ * @depends scaShouldWorkWithTypeId
+ */
+ public function scaTransactionCanBeFetched($sca): void
+ {
+ $this->assertTransactionResourceHasBeenCreated($sca);
+
+ // Fetch the SCA transaction
+ $fetchedSca = $this->unzer->fetchScaById($sca->getPaymentId(), $sca->getId());
+
+ // Verify the fetched transaction matches the initial transaction
+ $this->assertEquals($sca->getId(), $fetchedSca->getId());
+ $this->assertEquals($sca->getPaymentId(), $fetchedSca->getPaymentId());
+ $this->assertEquals($sca->getAmount(), $fetchedSca->getAmount());
+ $this->assertEquals($sca->getCurrency(), $fetchedSca->getCurrency());
+ }
+
+ /**
+ * Verify SCA transaction can be fetched using Sca object.
+ *
+ * @test
+ *
+ * @depends scaShouldWorkWithTypeId
+ */
+ public function scaTransactionCanBeFetchedUsingSca($sca): void
+ {
+ $this->assertTransactionResourceHasBeenCreated($sca);
+
+ // Fetch the SCA transaction using the Sca object
+ $fetchedSca = $this->unzer->fetchSca($sca);
+
+ // Verify the fetched transaction matches the initial transaction
+ $this->assertEquals($sca->getId(), $fetchedSca->getId());
+ $this->assertEquals($sca->getAmount(), $fetchedSca->getAmount());
+ $this->assertEquals($sca->getCurrency(), $fetchedSca->getCurrency());
+ }
+
+ /**
+ * Verify charge can be performed on SCA transaction.
+ *
+ * @test
+ *
+ * @depends scaShouldWorkWithTypeId
+ */
+ public function chargeFailsOnPendingSCATransactionWithErrorCode($sca): void
+ {
+ $charge = new Charge(100, "EUR");
+
+ // Expect charge to fail on pending transaction with error code
+ $this->expectException(UnzerApiException::class);
+ $this->expectExceptionCode(ApiResponseCodes::API_CANNOT_CHARGE_UNSUCCESSFUL_SCA_TRANSACTION);
+ $this->expectExceptionMessage('Cannot perform payment on an unsuccessful strong customer authentication.');
+
+ $this->unzer->chargeScaTransaction($sca->getPayment(), $charge);
+ }
+
+ /**
+ * Verify authorize can be performed on SCA transaction.
+ *
+ * @test
+ *
+ * @depends scaShouldWorkWithTypeObject
+ */
+ public function authorizeCanBePerformedOnScaTransaction($sca): void
+ {
+ $authorization = new Authorization(100, "EUR");
+
+ // Expect authorization to fail on pending transaction with error code
+ $this->expectException(UnzerApiException::class);
+ $this->expectExceptionCode(ApiResponseCodes::API_CANNOT_CHARGE_UNSUCCESSFUL_SCA_TRANSACTION);
+ $this->expectExceptionMessage('Cannot perform payment on an unsuccessful strong customer authentication.');
+
+ // Perform an authorize on SCA transaction
+ $authorization = $this->unzer->authorizeScaTransaction($sca->getPayment(), $authorization);
+ }
+}
diff --git a/vendor/unzerdev/php-sdk/test/integration/WebhookTest.php b/vendor/unzerdev/php-sdk/test/integration/WebhookTest.php
index beeb0f5..bdae8ad 100644
--- a/vendor/unzerdev/php-sdk/test/integration/WebhookTest.php
+++ b/vendor/unzerdev/php-sdk/test/integration/WebhookTest.php
@@ -14,6 +14,7 @@
use UnzerSDK\Constants\ApiResponseCodes;
use UnzerSDK\Constants\WebhookEvents;
use UnzerSDK\Exceptions\UnzerApiException;
+use UnzerSDK\Resources\TransactionTypes\Chargeback;
use UnzerSDK\Resources\Webhook;
use UnzerSDK\test\BaseIntegrationTest;
use function count;
@@ -22,6 +23,7 @@
class WebhookTest extends BaseIntegrationTest
{
//
+ const CHARGEDBACK_PAYMENT_ID = 's-pay-341196';
/**
* Verify Webhook resource can be registered and fetched.
@@ -221,6 +223,27 @@ public function bulkSettingOnlyOneWebhookShouldBePossible(): void
$this->assertEquals($url, $webhook->getUrl());
}
+ /**
+ * @test
+ */
+ public function testFetchResourceFromEvent(): void
+ {
+ $webhookNotification = [
+ 'event' => 'chargebacks',
+ 'publicKey' => 's-pub-xyz',
+ 'retrieveUrl' => 'https://sbx-api.unzer.com/v1/payments/' . self::CHARGEDBACK_PAYMENT_ID . '/charges/s-chg-1/chargebacks/s-cbk-1',
+ 'paymentId' => self::CHARGEDBACK_PAYMENT_ID
+ ];
+
+ // when
+ $chargeback = $this->unzer->fetchResourceFromEvent(json_encode($webhookNotification));
+
+ // then
+ $this->assertInstanceOf(Chargeback::class, $chargeback);
+ $this->assertNotNull($chargeback);
+ $this->assertEquals('s-cbk-1', $chargeback->getId());
+ }
+
//
//
diff --git a/vendor/unzerdev/php-sdk/test/unit/Resources/CustomerTest.php b/vendor/unzerdev/php-sdk/test/unit/Resources/CustomerTest.php
index 0f11b1f..7b17d3c 100644
--- a/vendor/unzerdev/php-sdk/test/unit/Resources/CustomerTest.php
+++ b/vendor/unzerdev/php-sdk/test/unit/Resources/CustomerTest.php
@@ -14,15 +14,15 @@
use UnzerSDK\Constants\CompanyCommercialSectorItems;
use UnzerSDK\Constants\CompanyRegistrationTypes;
use UnzerSDK\Constants\Salutations;
-use UnzerSDK\Resources\EmbeddedResources\CompanyOwner;
-use UnzerSDK\Unzer;
use UnzerSDK\Interfaces\ResourceServiceInterface;
use UnzerSDK\Resources\Customer;
use UnzerSDK\Resources\EmbeddedResources\Address;
use UnzerSDK\Resources\EmbeddedResources\CompanyInfo;
+use UnzerSDK\Resources\EmbeddedResources\CompanyOwner;
use UnzerSDK\Resources\EmbeddedResources\GeoLocation;
use UnzerSDK\Services\ResourceService;
use UnzerSDK\test\BasePaymentTest;
+use UnzerSDK\Unzer;
class CustomerTest extends BasePaymentTest
{
@@ -121,6 +121,7 @@ public function settersAndGettersOfShippingAddressShouldWork(): void
->setCity('shipping_city')
->setZip('shipping_zip')
->setStreet('shipping_street')
+ ->setCompany('shipping_company')
->setShippingType('shipping_type');
$customer = new Customer();
@@ -132,6 +133,7 @@ public function settersAndGettersOfShippingAddressShouldWork(): void
$this->assertNull($shippingAddress->getZip());
$this->assertNull($shippingAddress->getStreet());
$this->assertNull($shippingAddress->getShippingType());
+ $this->assertNull($shippingAddress->getCompany());
$customer->setShippingAddress($address);
$shippingAddress = $customer->getShippingAddress();
@@ -142,6 +144,7 @@ public function settersAndGettersOfShippingAddressShouldWork(): void
$this->assertEquals('shipping_zip', $shippingAddress->getZip());
$this->assertEquals('shipping_street', $shippingAddress->getStreet());
$this->assertEquals('shipping_type', $shippingAddress->getShippingType());
+ $this->assertEquals('shipping_company', $shippingAddress->getCompany());
}
/**
diff --git a/vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/ScaTest.php b/vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/ScaTest.php
new file mode 100644
index 0000000..40ee6e5
--- /dev/null
+++ b/vendor/unzerdev/php-sdk/test/unit/Resources/TransactionTypes/ScaTest.php
@@ -0,0 +1,42 @@
+assertEquals(99.99, $sca->getAmount());
+ $this->assertEquals("EUR", $sca->getCurrency());
+ $this->assertEquals("https://return-url.com", $sca->getReturnUrl());
+ }
+
+ /**
+ * @test
+ */
+ public function getterSetterTest()
+ {
+ $sca = new Sca(99.99, "EUR", "https://return-url.com");
+ $sca->setPaymentReference('reference');
+ $this->assertEquals(99.99, $sca->getAmount());
+ $this->assertEquals("EUR", $sca->getCurrency());
+ $this->assertEquals("reference", $sca->getPaymentReference());
+ $this->assertEquals("https://return-url.com", $sca->getReturnUrl());
+ }
+}
diff --git a/vendor/unzerdev/php-sdk/test/unit/Services/CancelServiceTest.php b/vendor/unzerdev/php-sdk/test/unit/Services/CancelServiceTest.php
index 8b56bfd..a2a6ab6 100644
--- a/vendor/unzerdev/php-sdk/test/unit/Services/CancelServiceTest.php
+++ b/vendor/unzerdev/php-sdk/test/unit/Services/CancelServiceTest.php
@@ -11,6 +11,7 @@
namespace UnzerSDK\test\unit\Services;
+use PHPUnit\Framework\MockObject\MockObject;
use UnzerSDK\Constants\ApiResponseCodes;
use UnzerSDK\Exceptions\UnzerApiException;
use UnzerSDK\Resources\EmbeddedResources\Amount;
@@ -24,7 +25,6 @@
use UnzerSDK\Services\CancelService;
use UnzerSDK\Services\ResourceService;
use UnzerSDK\test\BasePaymentTest;
-use PHPUnit\Framework\MockObject\MockObject;
class CancelServiceTest extends BasePaymentTest
{
@@ -119,7 +119,6 @@ public function maxCancelAmountShouldBeRoundedCorrectly(): void
$cancelSrvMock = new CancelService($this->unzer);
$reflection = new \ReflectionClass(get_class($cancelSrvMock));
$method = $reflection->getMethod('calculateMaxReversalAmount');
- $method->setAccessible(true);
$chargeAmount = 12.3;
$receiptAmount = 10.0;
diff --git a/vendor/unzerdev/php-sdk/test/unit/Services/DummyAdapter.php b/vendor/unzerdev/php-sdk/test/unit/Services/DummyAdapter.php
index a377870..7ed18f2 100644
--- a/vendor/unzerdev/php-sdk/test/unit/Services/DummyAdapter.php
+++ b/vendor/unzerdev/php-sdk/test/unit/Services/DummyAdapter.php
@@ -39,14 +39,6 @@ public function getResponseCode(): string
return 'responseCode';
}
- /**
- * {@inheritDoc}
- */
- public function close(): void
- {
- // do nothing
- }
-
/**
* {@inheritDoc}
*/
diff --git a/vendor/unzerdev/php-sdk/test/unit/Services/HttpServiceTest.php b/vendor/unzerdev/php-sdk/test/unit/Services/HttpServiceTest.php
index 8892f32..816b43f 100644
--- a/vendor/unzerdev/php-sdk/test/unit/Services/HttpServiceTest.php
+++ b/vendor/unzerdev/php-sdk/test/unit/Services/HttpServiceTest.php
@@ -112,7 +112,6 @@ static function ($url) {
$adapterMock->expects($this->once())->method('setHeaders')->with($headers);
$adapterMock->expects($this->once())->method('execute')->willReturn('myResponseString');
$adapterMock->expects($this->once())->method('getResponseCode')->willReturn('399');
- $adapterMock->expects($this->once())->method('close');
$httpServiceMock->method('getAdapter')->willReturn($adapterMock);
diff --git a/vendor/unzerdev/php-sdk/test/unit/Services/ResourceServiceTest.php b/vendor/unzerdev/php-sdk/test/unit/Services/ResourceServiceTest.php
index 1bcc708..6cb6de5 100644
--- a/vendor/unzerdev/php-sdk/test/unit/Services/ResourceServiceTest.php
+++ b/vendor/unzerdev/php-sdk/test/unit/Services/ResourceServiceTest.php
@@ -1391,7 +1391,8 @@ public function fetchResourceByUrlShouldFetchTheDesiredResourceDP(): array
'v2Customer' => ['fetchCustomer', ['s-cst-123e4567-e89b-12d3-a456-426614174000'], 'https://api.unzer.com/v2/customers/s-cst-123e4567-e89b-12d3-a456-426614174000'],
'v1Basket' => ['fetchBasket', ['s-bsk-1254'], 'https://api.unzer.com/v1/baskets/s-bsk-1254/'],
'v2Basket' => ['fetchBasket', ['s-bsk-1254'], 'https://api.unzer.com/v2/baskets/s-bsk-1254/'],
- 'Payout' => ['fetchPayout', ['s-pay-100746'], 'https://api.unzer.com/v1/payments/s-pay-100746/payout/s-out-1/']
+ 'Payout' => ['fetchPayout', ['s-pay-100746'], 'https://api.unzer.com/v1/payments/s-pay-100746/payout/s-out-1/'],
+ 'Sca' => ['fetchScaById', ['s-pay-100746', 's-sca-1'], 'https://api.unzer.com/v1/payments/s-pay-100746/sca/s-sca-1/']
];
}
diff --git a/vendor/unzerdev/php-sdk/test/unit/Services/WebhooksServiceTest.php b/vendor/unzerdev/php-sdk/test/unit/Services/WebhooksServiceTest.php
index b21f940..df5519c 100644
--- a/vendor/unzerdev/php-sdk/test/unit/Services/WebhooksServiceTest.php
+++ b/vendor/unzerdev/php-sdk/test/unit/Services/WebhooksServiceTest.php
@@ -11,16 +11,18 @@
namespace UnzerSDK\test\unit\Services;
-use UnzerSDK\Unzer;
+use RuntimeException;
+use stdClass;
use UnzerSDK\Interfaces\ResourceServiceInterface;
+use UnzerSDK\Resources\TransactionTypes\Charge;
+use UnzerSDK\Resources\TransactionTypes\Chargeback;
use UnzerSDK\Resources\Webhook;
use UnzerSDK\Resources\Webhooks;
use UnzerSDK\Services\ResourceService;
use UnzerSDK\Services\WebhookService;
use UnzerSDK\test\BasePaymentTest;
use UnzerSDK\test\unit\DummyResource;
-use RuntimeException;
-use stdClass;
+use UnzerSDK\Unzer;
class WebhooksServiceTest extends BasePaymentTest
{
@@ -328,6 +330,54 @@ public function fetchResourceByEventWithEmptyRetrieveUrlShouldThrowException():
$webhookService->fetchResourceFromEvent();
}
+ /**
+ * Verify that a chargeback is returned from a webhook event.
+ *
+ * @test
+ */
+ public function fetchChargebackByEventShouldReturnChargeback(): void
+ {
+ // given
+ $unzer = new Unzer('s-priv-1234');
+ $webhookService = new WebhookService($unzer);
+
+ $paymentId = 's-pay-42';
+ $chargeId = 's-chg-1';
+ $chargebackId = 's-cbk-1';
+ $retrieveUrl = "https://api.unzer.com/v1/payments/{$paymentId}/charges/{$chargeId}/chargebacks/{$chargebackId}";
+
+ // Partial mock: keep original behavior except fetchChargebackById which we want to intercept
+ $resourceServiceMock = $this->getMockBuilder(ResourceService::class)
+ ->setConstructorArgs([$unzer])
+ ->setMethods(['fetchChargebackById'])
+ ->getMock();
+
+ $chargeback = (new Chargeback(10.0))
+ ->setId($chargebackId)
+ ->setParentResource((new Charge())->setId($chargeId));
+
+ $resourceServiceMock->expects($this->once())
+ ->method('fetchChargebackById')
+ ->with($paymentId, $chargebackId, $chargeId)
+ ->willReturn($chargeback);
+
+ $webhookService->setResourceService($resourceServiceMock);
+
+ $eventJson = json_encode([
+ 'event' => 'chargeback',
+ 'publicKey' => 's-pub-xyz',
+ 'retrieveUrl' => $retrieveUrl,
+ 'paymentId' => $paymentId
+ ]);
+
+ // when
+ $fetchedChargeback = $webhookService->fetchResourceFromEvent($eventJson);
+
+ // then
+ $this->assertSame($chargeback, $fetchedChargeback);
+ $this->assertNotNull($fetchedChargeback);
+ }
+
/**
* Verify exception is thrown if the retrieveURL is empty.
*
diff --git a/vendor/unzerdev/php-sdk/test/unit/UnzerTest.php b/vendor/unzerdev/php-sdk/test/unit/UnzerTest.php
index 771196b..c9c2248 100644
--- a/vendor/unzerdev/php-sdk/test/unit/UnzerTest.php
+++ b/vendor/unzerdev/php-sdk/test/unit/UnzerTest.php
@@ -12,7 +12,8 @@
namespace UnzerSDK\test\unit;
use DateTime;
-use UnzerSDK\Unzer;
+use PHPUnit\Framework\MockObject\MockObject;
+use RuntimeException;
use UnzerSDK\Resources\Basket;
use UnzerSDK\Resources\Customer;
use UnzerSDK\Resources\Metadata;
@@ -30,8 +31,7 @@
use UnzerSDK\Services\WebhookService;
use UnzerSDK\test\BasePaymentTest;
use UnzerSDK\test\unit\Services\DummyDebugHandler;
-use PHPUnit\Framework\MockObject\MockObject;
-use RuntimeException;
+use UnzerSDK\Unzer;
class UnzerTest extends BasePaymentTest
{
@@ -56,6 +56,12 @@ public function constructorShouldInitPropertiesProperly(): void
$unzerGerman = new Unzer('s-priv-1234', 'de-DE');
$this->assertEquals('de-DE', $unzerGerman->getLocale());
+
+ $unzerPub = new Unzer('s-pub-1234');
+ $this->assertEquals('s-pub-1234', $unzerPub->getKey());
+
+ $unzerProdPub = new Unzer('p-pub-1234');
+ $this->assertEquals('p-pub-1234', $unzerProdPub->getKey());
}
/**
@@ -75,9 +81,14 @@ public function gettersAndSettersShouldWorkProperly(): void
$unzer->setKey('this is not a valid key');
$this->assertTrue(false, 'This exception should have been thrown');
} catch (RuntimeException $e) {
- $this->assertEquals('Illegal key: Use a valid private key with this SDK!', $e->getMessage());
+ $this->assertEquals('Illegal key: Use a valid private or public key with this SDK!', $e->getMessage());
}
+ $unzer->setKey('s-pub-1234');
+ $this->assertEquals('s-pub-1234', $unzer->getKey());
+ $unzer->setKey('p-pub-1234');
+ $this->assertEquals('p-pub-1234', $unzer->getKey());
+
$httpService = new HttpService();
$this->assertNotSame($httpService, $unzer->getHttpService());
$unzer->setHttpService($httpService);