diff --git a/typo3/sysext/backend/Classes/Controller/BackendController.php b/typo3/sysext/backend/Classes/Controller/BackendController.php index a66ebeb600085c90897004aa922d727ec8a39e70..4823fe40dcb62368a1655d5a8f432428214365ff 100644 --- a/typo3/sysext/backend/Classes/Controller/BackendController.php +++ b/typo3/sysext/backend/Classes/Controller/BackendController.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Backend\Module\ModuleLoader; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; use TYPO3\CMS\Core\Utility\MathUtility; use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Rsaauth\RsaEncryptionEncoder; /** * Class for rendering the TYPO3 backend @@ -153,6 +154,10 @@ class BackendController { // load debug console $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DebugConsole'); + // Load RSA encryption + $rsaEncryptionEncoder = GeneralUtility::makeInstance(RsaEncryptionEncoder::class); + $rsaEncryptionEncoder->enableRsaEncryption(TRUE); + $this->pageRenderer->addInlineSetting('ShowItem', 'moduleUrl', BackendUtility::getModuleUrl('show_item')); $this->css = ''; diff --git a/typo3/sysext/backend/Classes/Http/AjaxRequestHandler.php b/typo3/sysext/backend/Classes/Http/AjaxRequestHandler.php index 554ad8fb2de0dc451d3d3c419beea9d7f5ba4a4b..0b7a4b04d953c8edadad9b9438d7189e807d75f5 100644 --- a/typo3/sysext/backend/Classes/Http/AjaxRequestHandler.php +++ b/typo3/sysext/backend/Classes/Http/AjaxRequestHandler.php @@ -46,7 +46,8 @@ class AjaxRequestHandler implements RequestHandlerInterface { 'BackendLogin::refreshLogin', 'BackendLogin::isTimedOut', 'BackendLogin::getChallenge', - 'BackendLogin::getRsaPublicKey' + 'BackendLogin::getRsaPublicKey', + 'RsaEncryption::getRsaPublicKey' ); /** diff --git a/typo3/sysext/backend/Resources/Private/Templates/UserPassLoginForm.html b/typo3/sysext/backend/Resources/Private/Templates/UserPassLoginForm.html index bccc96bbcd22a7de0a6f4aa3443327e23a011c34..f21e64b55a9118ed2deffccaea3a49e1941fa98c 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/UserPassLoginForm.html +++ b/typo3/sysext/backend/Resources/Private/Templates/UserPassLoginForm.html @@ -4,7 +4,7 @@ <div class="form-group t3js-login-username-section" id="t3-login-username-section"> <div class="form-control-wrap"> <div class="form-control-holder"> - <input type="text" id="t3-username" name="username" value="{presetUsername}" placeholder="{f:translate(key: 'login.username')}" class="form-control input-login t3js-clearable t3js-login-username-field" autofocus="autofocus" required="required"> + <input type="text" id="t3-username" name="username" value="{presetUsername}" placeholder="{f:translate(key: 'login.username')}" class="form-control input-login t3js-clearable t3js-login-username-field" autofocus="autofocus" required="required" /> <div class="form-notice-capslock hidden t3js-login-alert-capslock"> <img src="{images.capslock}" width="14" height="14" alt="{f:translate(key: 'login.error.capslock')}" title="{f:translate(key: 'login.error.capslock')}" /> </div> @@ -14,7 +14,7 @@ <div class="form-group t3js-login-password-section" id="t3-login-password-section"> <div class="form-control-wrap"> <div class="form-control-holder"> - <input type="password" id="t3-password" name="p_field" value="{presetPassword}" placeholder="{f:translate(key: 'login.password')}" class="form-control input-login t3js-clearable t3js-login-password-field" required="required"> + <input type="password" id="t3-password" name="p_field" value="{presetPassword}" placeholder="{f:translate(key: 'login.password')}" class="form-control input-login t3js-clearable t3js-login-password-field" required="required" data-rsa-encryption="t3-field-userident" /> <div class="form-notice-capslock hidden t3js-login-alert-capslock"> <img src="{images.capslock}" width="14" height="14" alt="{f:translate(key: 'login.error.capslock')}" title="{f:translate(key: 'login.error.capslock')}" /> </div> diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js b/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js index 2846cdb19e1381d07f6b60fe3c33ce6d378f1893..bf7f8dabb7c6ac617e50e02cd9386503886a1dfe 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js @@ -197,10 +197,10 @@ define('TYPO3/CMS/Backend/LoginRefresh', ['jquery', 'bootstrap'], function($) { $('<p />').text(TYPO3.LLL.core.login_expired), $('<form />', {id: 'beLoginRefresh', method: 'POST', action: TYPO3.settings.ajaxUrls['BackendLogin::login']}).append( $('<div />', {class: 'form-group'}).append( - $('<input />', {type: 'password', name: 'p_field', autofocus: 'autofocus', class: 'form-control', placeholder: TYPO3.LLL.core.refresh_login_password}) + $('<input />', {type: 'password', name: 'p_field', autofocus: 'autofocus', class: 'form-control', placeholder: TYPO3.LLL.core.refresh_login_password, 'data-rsa-encryption': 't3-loginrefres-userident'}) ), $('<input />', {type: 'hidden', name: 'username', value: TYPO3.configuration.username}), - $('<input />', {type: 'hidden', name: 'userident'}) + $('<input />', {type: 'hidden', name: 'userident', id: 't3-loginrefres-userident'}) ) ); LoginRefresh.$loginForm.find('.modal-footer').append( @@ -210,7 +210,7 @@ define('TYPO3/CMS/Backend/LoginRefresh', ['jquery', 'bootstrap'], function($) { }) ); - LoginRefresh.registerDefaultModalEvents(LoginRefresh.$loginForm).on('submit', LoginRefresh.triggerSubmitForm); + LoginRefresh.registerDefaultModalEvents(LoginRefresh.$loginForm).on('submit', LoginRefresh.submitForm); $('body').append(LoginRefresh.$loginForm); }; @@ -295,57 +295,28 @@ define('TYPO3/CMS/Backend/LoginRefresh', ['jquery', 'bootstrap'], function($) { }, 300); }; - /** - * Triggers the form submit based on the security level. - */ - LoginRefresh.triggerSubmitForm = function(e) { - e.preventDefault(); - - switch (TYPO3.configuration.securityLevel) { - case 'rsa': - $.ajax({ - url: TYPO3.settings.ajaxUrls['BackendLogin::getRsaPublicKey'], - method: 'GET', - data: { - skipSessionUpdate: 1 - }, - success: function(response) { - if (response.publicKeyModulus && response.exponent) { - LoginRefresh.submitForm(response); - } - } - }); - break; - default: - LoginRefresh.submitForm(); - } - }; - /** * Creates additional data based on the security level and "submits" the form * via an AJAX request. */ - LoginRefresh.submitForm = function(parameters) { + LoginRefresh.submitForm = function(event) { + event.preventDefault(); + var $form = LoginRefresh.$loginForm.find('form'), $passwordField = $form.find('input[name=p_field]'), $useridentField = $form.find('input[name=userident]'), passwordFieldValue = $passwordField.val(); - if (passwordFieldValue === '') { + if (passwordFieldValue === '' && $useridentField.val() === '') { top.TYPO3.Notification.error(TYPO3.LLL.core.refresh_login_failed, TYPO3.LLL.core.refresh_login_emptyPassword); $passwordField.focus(); return; } - if (TYPO3.configuration.securityLevel === 'rsa') { - var rsa = new RSAKey(); - rsa.setPublic(parameters.publicKeyModulus, parameters.exponent); - var encryptedPassword = rsa.encrypt(passwordFieldValue); - $useridentField.val('rsa:' + hex2b64(encryptedPassword)); - } else { + if (passwordFieldValue) { $useridentField.val(passwordFieldValue); + $passwordField.val(''); } - $passwordField.val(''); var postData = { login_status: 'login' diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/UserPassLogin.js b/typo3/sysext/backend/Resources/Public/JavaScript/UserPassLogin.js index 6261222dc276a5eafec0068c8ce53a1edf3f7658..cbe102a8aea613248d987afdc289578bc13feea5 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/UserPassLogin.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/UserPassLogin.js @@ -54,8 +54,10 @@ define('TYPO3/CMS/Backend/UserPassLogin', ['jquery', 'TYPO3/CMS/Backend/Login'], "use strict"; var $passwordField = $(UserPassLogin.options.passwordField); - $(Login.options.useridentField).val($passwordField.val()); - $passwordField.val(''); + if ($passwordField.val()) { + $(Login.options.useridentField).val($passwordField.val()); + $passwordField.val(''); + } }; /** diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-67932-DeprecatedOldRsaauthApi.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-67932-DeprecatedOldRsaauthApi.rst new file mode 100644 index 0000000000000000000000000000000000000000..1c1e903248ca5ef5a710f700e5a675bf15094b20 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-67932-DeprecatedOldRsaauthApi.rst @@ -0,0 +1,21 @@ +=========================================================== +Deprecation: #67932 - Deprecated old rsaauth encryption API +=========================================================== + +Description +=========== + +The rsaauth API was rebuilt to be more generic. Therefore the Ajax Handler ``BackendLogin::getRsaPublicKey`` and +the eID script ``FrontendLoginRsaPublicKey`` were marked as deprecated. + + +Affected Installations +====================== + +Any installation using one of the entry points above in a third-party extension. + + +Migration +========= + +There is no reason to use the entry points on your own anymore. Please update your scripts to use the new rsaauth API. diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-67932-RsaauthApiRewrite.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-67932-RsaauthApiRewrite.rst new file mode 100644 index 0000000000000000000000000000000000000000..f23db4a1a4e66932407c08f1f6e310800db1fdb7 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-67932-RsaauthApiRewrite.rst @@ -0,0 +1,71 @@ +================================= +Feature: #67932 - New rsaauth API +================================= + +Description +=========== + +The rsaauth API was rewritten to be more generic and can now be used easily in more +parts of the core as well as in third party extensions. + + +Impact +====== + +Form fields (e.g. password fields) can be encrypted before transmission. This helps to improve the security of +your and your user's data. + + +Examples +======== + +Encode +------ + +Encoding is done automatically via a JavaScript function which gets a public key and encrypts the data. + +1) Include JavaScript to parse form fields for encryption. You can either choose to include a RequireJS module or a +plain Javascript file. + +.. code-block:: php + + $rsaEncryptionEncoder = GeneralUtility::makeInstance(\TYPO3\CMS\Rsaauth\RsaEncryptionEncoder::class); + $rsaEncryptionEncoder->enableRsaEncryption(); // Adds plain JavaScript + $rsaEncryptionEncoder->enableRsaEncryption(TRUE); // Adds RequireJS module + +2) Activate encryption for your from fields with the data attribute ``data-rsa-encryption``. + +.. code-block:: html + + <input type="password" id="pass" name="pass" value="" data-rsa-encryption="" /> + +If you want the encrypted value to be stored in another field, you have to use the RequiredJS module and you can +pass the id of that form field as value to the data attribute. + +.. code-block:: html + + <input type="password" id="t3-password" name="p_field" value="" data-rsa-encryption="t3-field-userident" /> + <input type="hidden" name="userident" id="t3-field-userident" /> + +Decode +------ + +To decode your data you can use the method ``TYPO3\CMS\Rsaauth\RsaEncryptionDecoder::decrypt`` which can +either handle a string or an array as parameter. + +Notice: A RSA public key can only be used once to decrypt data. If you encrypt multiple fields in your form +you have to pass an array to the decrypt function with all data you want to decrypt. The function parses the +values for a ``rsa:`` prefix so you can be sure that non-matching data will not be changed. + +.. code-block:: php + + $rsaEncryptionDecoder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Rsaauth\RsaEncryptionDecoder::class); + + // Decrypt a single string + $password = $loginData['uident']; + $decryptedPassword = $rsaEncryptionDecoder->decrypt($password); + + // Decrypt an array + if ($this->isRsaAvailable()) { + $parameters['be_user_data'] = $this->getRsaEncryptionDecoder()->decrypt($parameters['be_user_data']); + } diff --git a/typo3/sysext/felogin/template.html b/typo3/sysext/felogin/template.html index b90e6e34186dc7c25fb8f21ae93162ba9a0b62f4..90d53053713a9e00dc48375bf23f029505b1a090 100644 --- a/typo3/sysext/felogin/template.html +++ b/typo3/sysext/felogin/template.html @@ -56,7 +56,7 @@ </div> <div> <label for="pass">###PASSWORD_LABEL###</label> - <input type="password" id="pass" name="pass" value="" /> + <input type="password" id="pass" name="pass" value="" data-rsa-encryption="" /> </div> <!--###PERMALOGIN_VALID###--> diff --git a/typo3/sysext/rsaauth/Classes/Backend/AjaxLoginHandler.php b/typo3/sysext/rsaauth/Classes/Backend/AjaxLoginHandler.php index 6e2b4f210672f4cb37e873bf5d87af5aea4d5127..f12cc3c117ec5b2aac727d88c6c48a0bfea3f3e7 100644 --- a/typo3/sysext/rsaauth/Classes/Backend/AjaxLoginHandler.php +++ b/typo3/sysext/rsaauth/Classes/Backend/AjaxLoginHandler.php @@ -24,21 +24,12 @@ class AjaxLoginHandler { * * @param array $parameters Parameters (not used) * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $parent The calling parent AJAX object - * @return void + * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. Please use RsaEncryption::getRsaPublicKey as ajax handler instead. */ public function getRsaPublicKey(array $parameters, \TYPO3\CMS\Core\Http\AjaxRequestHandler $parent) { - $backend = BackendFactory::getBackend(); - if ($backend !== NULL) { - $keyPair = $backend->createNewKeyPair(); - $storage = \TYPO3\CMS\Rsaauth\Storage\StorageFactory::getStorage(); - $storage->put($keyPair->getPrivateKey()); - session_commit(); - $parent->addContent('publicKeyModulus', $keyPair->getPublicKeyModulus()); - $parent->addContent('exponent', sprintf('%x', $keyPair->getExponent())); - $parent->setContentFormat('json'); - } else { - $parent->setError('No OpenSSL backend could be obtained for rsaauth.'); - } + \TYPO3\CMS\Core\Utility\GeneralUtility::logDeprecatedFunction(); + $rsaEncryptionEncoder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Rsaauth\RsaEncryptionEncoder::class); + $rsaEncryptionEncoder->getRsaPublicKeyAjaxHandler($parameters, $parent); } } \ No newline at end of file diff --git a/typo3/sysext/rsaauth/Classes/Hook/BackendHookForAjaxLogin.php b/typo3/sysext/rsaauth/Classes/Hook/BackendHookForAjaxLogin.php deleted file mode 100644 index 60f4b46a5ca29fa4b23e2f584b2844d25219c9e1..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Classes/Hook/BackendHookForAjaxLogin.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -namespace TYPO3\CMS\Rsaauth\Hook; - -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -/** - * This class adds RSA JavaScript to the backend - */ -class BackendHookForAjaxLogin { - - /** - * Adds RSA-specific JavaScript - * - * @param array $configuration - * @param \TYPO3\CMS\Backend\Controller\BackendController $backendController - * @return void - */ - public function addRsaJsLibraries(array $configuration, \TYPO3\CMS\Backend\Controller\BackendController $backendController) { - $javascriptPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('rsaauth') . 'Resources/Public/JavaScript/'; - $files = array( - 'jsbn/jsbn.js', - 'jsbn/prng4.js', - 'jsbn/rng.js', - 'jsbn/rsa.js', - 'jsbn/base64.js' - ); - foreach ($files as $file) { - $backendController->getPageRenderer()->addJsLibrary($file, $javascriptPath . $file); - } - } - -} diff --git a/typo3/sysext/rsaauth/Classes/Hook/FrontendLoginHook.php b/typo3/sysext/rsaauth/Classes/Hook/FrontendLoginHook.php index 5a2b7ddf600c3cf76789469e3807f8036d29c876..367bab63c009aa4424556b4192dfed02c75cdc13 100644 --- a/typo3/sysext/rsaauth/Classes/Hook/FrontendLoginHook.php +++ b/typo3/sysext/rsaauth/Classes/Hook/FrontendLoginHook.php @@ -14,6 +14,9 @@ namespace TYPO3\CMS\Rsaauth\Hook; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Rsaauth\RsaEncryptionEncoder; + /** * This class contains a hook to implement RSA authentication for the TYPO3 * Frontend. Warning: felogin must be USER_INT for this to work! @@ -28,29 +31,13 @@ class FrontendLoginHook { * @return array 0 => onSubmit function, 1 => extra fields and required files */ public function loginFormHook() { - $result = array(0 => '', 1 => ''); - if (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['loginSecurityLevel']) === 'rsa') { - $backend = \TYPO3\CMS\Rsaauth\Backend\BackendFactory::getBackend(); - if ($backend) { - $result[0] = 'return TYPO3FrontendLoginFormRsaEncryption.submitForm(this, TYPO3FrontendLoginFormRsaEncryptionPublicKeyUrl);'; - $javascriptPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath('rsaauth') . 'Resources/Public/JavaScript/'; - $files = array( - 'jsbn/jsbn.js', - 'jsbn/prng4.js', - 'jsbn/rng.js', - 'jsbn/rsa.js', - 'jsbn/base64.js', - 'FrontendLoginFormRsaEncryption.min.js' - ); - $eIdUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($GLOBALS['TSFE']->absRefPrefix . 'index.php?eID=FrontendLoginRsaPublicKey'); - $additionalHeader = '<script type="text/javascript">var TYPO3FrontendLoginFormRsaEncryptionPublicKeyUrl = ' . $eIdUrl . ';</script>'; - foreach ($files as $file) { - $additionalHeader .= '<script type="text/javascript" src="' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $javascriptPath . $file . '"></script>'; - } - $GLOBALS['TSFE']->additionalHeaderData['rsaauth_js'] = $additionalHeader; - } + /** @var RsaEncryptionEncoder $rsaEncryptionEncoder */ + $rsaEncryptionEncoder = GeneralUtility::makeInstance(RsaEncryptionEncoder::class); + if ($rsaEncryptionEncoder->isAvailable()) { + $rsaEncryptionEncoder->enableRsaEncryption(); } - return $result; + + return array(0 => '', 1 => ''); } } diff --git a/typo3/sysext/rsaauth/Classes/Hook/UserSetupHook.php b/typo3/sysext/rsaauth/Classes/Hook/UserSetupHook.php index 814aa91c98a0e15d1f5add61c728ec30a5003f8f..6bc81f3bacfd5adb621a39732e326297d193b42b 100644 --- a/typo3/sysext/rsaauth/Classes/Hook/UserSetupHook.php +++ b/typo3/sysext/rsaauth/Classes/Hook/UserSetupHook.php @@ -14,6 +14,11 @@ namespace TYPO3\CMS\Rsaauth\Hook; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Rsaauth\RsaEncryptionDecoder; +use TYPO3\CMS\Rsaauth\RsaEncryptionEncoder; +use TYPO3\CMS\Setup\Controller\SetupModuleController; + /** * This class provides a hook to the login form to add extra javascript code * and supply a proper form tag. @@ -23,68 +28,33 @@ namespace TYPO3\CMS\Rsaauth\Hook; class UserSetupHook { /** - * Decrypt the password fields if they are filled. + * @var RsaEncryptionDecoder + */ + protected $rsaEncryptionDecoder = NULL; + + /** + * Decrypt all password fields which were encrypted. * * @param array $parameters Parameters to the script - * @return void */ public function decryptPassword(array $parameters) { if ($this->isRsaAvailable()) { - $be_user_data = &$parameters['be_user_data']; - if (substr($be_user_data['password'], 0, 4) === 'rsa:' && substr($be_user_data['password2'], 0, 4) === 'rsa:') { - $backend = \TYPO3\CMS\Rsaauth\Backend\BackendFactory::getBackend(); - /** @var $storage \TYPO3\CMS\Rsaauth\Storage\AbstractStorage */ - $storage = \TYPO3\CMS\Rsaauth\Storage\StorageFactory::getStorage(); - $key = $storage->get(); - $password = $backend->decrypt($key, substr($be_user_data['password'], 4)); - $password2 = $backend->decrypt($key, substr($be_user_data['password2'], 4)); - $passwordCurrent = $backend->decrypt($key, substr($be_user_data['passwordCurrent'], 4)); - $be_user_data['password'] = $password ?: $be_user_data['password']; - $be_user_data['password2'] = $password2 ?: $be_user_data['password2']; - $be_user_data['passwordCurrent'] = $passwordCurrent ?: $be_user_data['passwordCurrent']; - } + // Note: although $parameters is not passed by reference, the 'be_user_data' is a reference + $parameters['be_user_data'] = $this->getRsaEncryptionDecoder()->decrypt($parameters['be_user_data']); } } /** - * Provides form code and javascript for the user setup. + * Includes rsa libraries * * @param array $parameters Parameters to the script - * @param \TYPO3\CMS\Setup\Controller\SetupModuleController $userSetupObject Calling object: user setup module - * @return string The code for the user setup + * @param SetupModuleController $userSetupObject Calling object: user setup module + * @return string */ - public function getLoginScripts(array $parameters, \TYPO3\CMS\Setup\Controller\SetupModuleController $userSetupObject) { - $content = ''; - if ($this->isRsaAvailable()) { - // If we can get the backend, we can proceed - $backend = \TYPO3\CMS\Rsaauth\Backend\BackendFactory::getBackend(); - $javascriptPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath('rsaauth') . 'Resources/Public/JavaScript/'; - $files = array( - 'jsbn/jsbn.js', - 'jsbn/prng4.js', - 'jsbn/rng.js', - 'jsbn/rsa.js', - 'jsbn/base64.js', - 'rsaauth_min.js' - ); - $content = ''; - foreach ($files as $file) { - $content .= '<script type="text/javascript" src="' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $javascriptPath . $file . '"></script>'; - } - // Generate a new key pair - $keyPair = $backend->createNewKeyPair(); - // Save private key - $storage = \TYPO3\CMS\Rsaauth\Storage\StorageFactory::getStorage(); - /** @var $storage \TYPO3\CMS\Rsaauth\Storage\AbstractStorage */ - $storage->put($keyPair->getPrivateKey()); - // Add form tag - $form = '<form action="' . \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('user_setup') . '" method="post" name="usersetup" enctype="application/x-www-form-urlencoded" onsubmit="tx_rsaauth_encryptUserSetup();">'; - // Add RSA hidden fields - $form .= '<input type="hidden" id="rsa_n" name="n" value="' . htmlspecialchars($keyPair->getPublicKeyModulus()) . '" />'; - $form .= '<input type="hidden" id="rsa_e" name="e" value="' . sprintf('%x', $keyPair->getExponent()) . '" />'; - $userSetupObject->doc->form = $form; - } - return $content; + public function getLoginScripts(array $parameters, SetupModuleController $userSetupObject) { + $rsaEncryptionEncoder = GeneralUtility::makeInstance(RsaEncryptionEncoder::class); + $rsaEncryptionEncoder->enableRsaEncryption(TRUE); + return ''; } /** @@ -93,7 +63,18 @@ class UserSetupHook { * @return bool */ protected function isRsaAvailable() { - return trim($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) === 'rsa' && \TYPO3\CMS\Rsaauth\Backend\BackendFactory::getBackend() !== NULL; + return trim($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) === 'rsa' && $this->getRsaEncryptionDecoder()->isAvailable(); + } + + /** + * @return RsaEncryptionDecoder + */ + protected function getRsaEncryptionDecoder() { + if ($this->rsaEncryptionDecoder === NULL) { + $this->rsaEncryptionDecoder = GeneralUtility::makeInstance(RsaEncryptionDecoder::class); + } + + return $this->rsaEncryptionDecoder; } } diff --git a/typo3/sysext/rsaauth/Classes/RsaAuthService.php b/typo3/sysext/rsaauth/Classes/RsaAuthService.php index 491430849959dc887227711878f090100ca4045d..0ac402eba5ab7f126c5cc42e410660287e0ebc1a 100644 --- a/typo3/sysext/rsaauth/Classes/RsaAuthService.php +++ b/typo3/sysext/rsaauth/Classes/RsaAuthService.php @@ -14,6 +14,8 @@ namespace TYPO3\CMS\Rsaauth; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Utility\GeneralUtility; + /** * Service "RSA authentication" for the "rsaauth" extension. This service will * authenticate a user using hos password encoded with one time public key. It @@ -26,11 +28,9 @@ namespace TYPO3\CMS\Rsaauth; class RsaAuthService extends \TYPO3\CMS\Sv\AuthenticationService { /** - * An RSA backend. - * - * @var \TYPO3\CMS\Rsaauth\Backend\AbstractBackend + * @var RsaEncryptionDecoder */ - protected $backend = NULL; + protected $rsaEncryptionDecoder = NULL; /** * Standard extension key for the service @@ -54,7 +54,7 @@ class RsaAuthService extends \TYPO3\CMS\Sv\AuthenticationService { * * @var string */ - public $scriptRelPath = 'sv1/class.tx_rsaauth_sv1.php'; + public $scriptRelPath = 'Classes/RsaAuthService.php'; /** * Process the submitted credentials. @@ -67,27 +67,20 @@ class RsaAuthService extends \TYPO3\CMS\Sv\AuthenticationService { public function processLoginData(array &$loginData, $passwordTransmissionStrategy) { $isProcessed = FALSE; if ($passwordTransmissionStrategy === 'rsa') { - $storage = \TYPO3\CMS\Rsaauth\Storage\StorageFactory::getStorage(); - /** @var $storage \TYPO3\CMS\Rsaauth\Storage\AbstractStorage */ - // Decrypt the password $password = $loginData['uident']; - $key = $storage->get(); - if ($key !== NULL && substr($password, 0, 4) === 'rsa:') { - // Decode password and store it in loginData - $decryptedPassword = $this->backend->decrypt($key, substr($password, 4)); - if ($decryptedPassword !== NULL) { + if (substr($password, 0, 4) === 'rsa:') { + $decryptedPassword = $this->getRsaEncryptionDecoder()->decrypt($password); + if ($decryptedPassword !== $password) { $loginData['uident_text'] = $decryptedPassword; $isProcessed = TRUE; } else { if ($this->pObj->writeDevLog) { - \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('Process login data: Failed to RSA decrypt password', \TYPO3\CMS\Rsaauth\RsaAuthService::class); + GeneralUtility::devLog('Process login data: Failed to RSA decrypt password', RsaAuthService::class); } } - // Remove the key - $storage->put(NULL); } else { if ($this->pObj->writeDevLog) { - \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('Process login data: passwordTransmissionStrategy has been set to "rsa" but no rsa encrypted password has been found.', \TYPO3\CMS\Rsaauth\RsaAuthService::class); + GeneralUtility::devLog('Process login data: passwordTransmissionStrategy has been set to "rsa" but no rsa encrypted password has been found.', RsaAuthService::class); } } } @@ -100,15 +93,18 @@ class RsaAuthService extends \TYPO3\CMS\Sv\AuthenticationService { * @return bool */ public function init() { - $available = parent::init(); - if ($available) { - // Get the backend - $this->backend = \TYPO3\CMS\Rsaauth\Backend\BackendFactory::getBackend(); - if ($this->backend === NULL) { - $available = FALSE; - } + return parent::init() && $this->getRsaEncryptionDecoder()->isAvailable(); + } + + /** + * @return RsaEncryptionDecoder + */ + protected function getRsaEncryptionDecoder() { + if ($this->rsaEncryptionDecoder === NULL) { + $this->rsaEncryptionDecoder = GeneralUtility::makeInstance(RsaEncryptionDecoder::class); } - return $available; + + return $this->rsaEncryptionDecoder; } } diff --git a/typo3/sysext/rsaauth/Classes/RsaEncryptionDecoder.php b/typo3/sysext/rsaauth/Classes/RsaEncryptionDecoder.php new file mode 100644 index 0000000000000000000000000000000000000000..0ad0cf96c2c72caf5998743c58908b0fbdb07a9e --- /dev/null +++ b/typo3/sysext/rsaauth/Classes/RsaEncryptionDecoder.php @@ -0,0 +1,107 @@ +<?php +namespace TYPO3\CMS\Rsaauth; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * This class decodes rsa protected data + */ +class RsaEncryptionDecoder implements \TYPO3\CMS\Core\SingletonInterface { + + /** + * @var Backend\AbstractBackend + */ + protected $backend = NULL; + + /** + * @var Storage\AbstractStorage + */ + protected $storage = NULL; + + /** + * @var string + */ + protected $key = NULL; + + /** + * @param string|array $data + * @return string|array + */ + public function decrypt($data) { + if ($this->getKey() === '' || !$this->isAvailable()) { + return $data; + } + + $decryptedData = is_array($data) ? $data : array($data); + + foreach ($decryptedData as $key => $value) { + if (substr($value, 0, 4) !== 'rsa:') { + continue; + } + + $decryptedValue = $this->getBackend()->decrypt($this->getKey(), substr($value, 4)); + if ($decryptedValue !== NULL) { + $decryptedData[$key] = $decryptedValue; + } + } + $this->getStorage()->put(NULL); + + return is_array($data) ? $decryptedData : $decryptedData[0]; + } + + /** + * @return bool + */ + public function isAvailable() { + return $this->getBackend() instanceof Backend\AbstractBackend; + } + + /** + * @return string + */ + protected function getKey() { + if ($this->key === NULL) { + $this->key = $this->getStorage()->get(); + + if ($this->key === NULL) { + $this->key = ''; + } + } + + return $this->key; + } + + /** + * @return Backend\AbstractBackend|NULL + */ + protected function getBackend() { + if ($this->backend === NULL) { + $this->backend = Backend\BackendFactory::getBackend(); + } + + return $this->backend; + } + + /** + * @return Storage\AbstractStorage + */ + protected function getStorage() { + if ($this->storage === NULL) { + $this->storage = Storage\StorageFactory::getStorage(); + } + + return $this->storage; + } + +} diff --git a/typo3/sysext/rsaauth/Classes/RsaEncryptionEncoder.php b/typo3/sysext/rsaauth/Classes/RsaEncryptionEncoder.php new file mode 100644 index 0000000000000000000000000000000000000000..69332cfbb6345942fc87708c139b3919a8dee8bb --- /dev/null +++ b/typo3/sysext/rsaauth/Classes/RsaEncryptionEncoder.php @@ -0,0 +1,115 @@ +<?php +namespace TYPO3\CMS\Rsaauth; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Http\AjaxRequestHandler; +use TYPO3\CMS\Core\Page\PageRenderer; +use TYPO3\CMS\Core\SingletonInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; + +/** + * This class adds necessary Javascript code to encrypt fields in a form + */ +class RsaEncryptionEncoder implements SingletonInterface { + + /** + * @var bool + */ + protected $moduleLoaded = FALSE; + + /** + * @var PageRenderer + */ + protected $pageRenderer = NULL; + + /** + * Load all necessary Javascript files + * + * @param bool $useRequireJsModule + */ + public function enableRsaEncryption($useRequireJsModule = FALSE) { + if ($this->moduleLoaded || !$this->isAvailable()) { + return; + } + $this->moduleLoaded = TRUE; + $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); + // Include necessary javascript files + if ($useRequireJsModule) { + $pageRenderer->loadRequireJsModule('TYPO3/CMS/Rsaauth/RsaEncryptionModule'); + } else { + // Register ajax handler url + $code = 'var TYPO3RsaEncryptionPublicKeyUrl = ' . GeneralUtility::quoteJSvalue(BackendUtility::getAjaxUrl('RsaEncryption::getRsaPublicKey')) . ';'; + $pageRenderer->addJsInlineCode('TYPO3RsaEncryptionPublicKeyUrl', $code); + $javascriptPath = ExtensionManagementUtility::siteRelPath('rsaauth') . 'Resources/Public/JavaScript/'; + if (!$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['debug']) { + $files = array('RsaEncryptionWithLib.min.js'); + } else { + $files = array( + 'RsaLibrary.js', + 'RsaEncryption.js', + ); + } + foreach ($files as $file) { + $pageRenderer->addJsFile($javascriptPath . $file); + } + } + } + + /** + * @return bool + */ + public function isAvailable() { + return trim($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['loginSecurityLevel']) === 'rsa'; + } + + /** + * Gets RSA Public Key. + * + * @return Keypair|NULL + */ + public function getRsaPublicKey() { + $keyPair = NULL; + $backend = Backend\BackendFactory::getBackend(); + if ($backend !== NULL) { + $keyPair = $backend->createNewKeyPair(); + $storage = Storage\StorageFactory::getStorage(); + $storage->put($keyPair->getPrivateKey()); + session_commit(); + } + + return $keyPair; + } + + /** + * Ajax handler to return a RSA public key. + * + * @param array $parameters Parameters (not used) + * @param AjaxRequestHandler $parent The calling parent AJAX object + */ + public function getRsaPublicKeyAjaxHandler(array $parameters, AjaxRequestHandler $parent) { + $keyPair = $this->getRsaPublicKey(); + if ($keyPair !== NULL) { + $parent->addContent('publicKeyModulus', $keyPair->getPublicKeyModulus()); + $parent->addContent('spacer', ':'); + $parent->addContent('exponent', sprintf('%x', $keyPair->getExponent())); + $parent->setContentFormat('plain'); + } else { + $parent->setError('No OpenSSL backend could be obtained for rsaauth.'); + } + } + +} diff --git a/typo3/sysext/rsaauth/Classes/Slot/UsernamePasswordProviderSlot.php b/typo3/sysext/rsaauth/Classes/Slot/UsernamePasswordProviderSlot.php index e6b962dbaafc9408d9b5db0680a151eaf3e11fcb..e98bb3834d726c01fa1e221a7ef1a86a670b761e 100644 --- a/typo3/sysext/rsaauth/Classes/Slot/UsernamePasswordProviderSlot.php +++ b/typo3/sysext/rsaauth/Classes/Slot/UsernamePasswordProviderSlot.php @@ -14,9 +14,9 @@ namespace TYPO3\CMS\Rsaauth\Slot; * The TYPO3 project - inspiring people to share! */ -use TYPO3\CMS\Backend\Controller\LoginController; use TYPO3\CMS\Core\Page\PageRenderer; -use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Rsaauth\RsaEncryptionEncoder; /** * Class UsernamePasswordProviderSlot @@ -27,21 +27,7 @@ class UsernamePasswordProviderSlot { * @param PageRenderer $pageRenderer */ public function getPageRenderer(PageRenderer $pageRenderer) { - $loginSecurityLevel = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) ?: 'normal'; - if ($loginSecurityLevel === 'rsa') { - $javascriptPath = '../' . ExtensionManagementUtility::siteRelPath('rsaauth') . 'Resources/Public/JavaScript/'; - $files = array( - 'jsbn/jsbn.js', - 'jsbn/prng4.js', - 'jsbn/rng.js', - 'jsbn/rsa.js', - 'jsbn/base64.js' - ); - foreach ($files as $file) { - $pageRenderer->addJsFile($javascriptPath . $file); - } - - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Rsaauth/BackendLoginFormRsaEncryption'); - } + $rsaEncryptionEncoder = GeneralUtility::makeInstance(RsaEncryptionEncoder::class); + $rsaEncryptionEncoder->enableRsaEncryption(TRUE); } } diff --git a/typo3/sysext/rsaauth/Resources/PHP/FrontendLoginRsaPublicKey.php b/typo3/sysext/rsaauth/Resources/PHP/FrontendLoginRsaPublicKey.php index 9abb815a92d286d1a40b6e3ea1fc6a115dc14294..73288b3a335c6b64d2ec6e587271d52a68ddcc10 100644 --- a/typo3/sysext/rsaauth/Resources/PHP/FrontendLoginRsaPublicKey.php +++ b/typo3/sysext/rsaauth/Resources/PHP/FrontendLoginRsaPublicKey.php @@ -14,6 +14,10 @@ defined('TYPO3_MODE') or die(); * The TYPO3 project - inspiring people to share! */ +\TYPO3\CMS\Core\Utility\GeneralUtility::deprecationLog( + 'The generation of the RSA public key was moved to the ajax handler \'RsaEncryptionEncoder::getRsaPublicKey\'. Please use the rsaauth api to encrypt your form fields. This script will be removed in TYPO3 CMS 8.' +); + /** @var \TYPO3\CMS\Rsaauth\Backend\AbstractBackend $backend */ $backend = \TYPO3\CMS\Rsaauth\Backend\BackendFactory::getBackend(); if ($backend !== NULL) { diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/BackendLoginFormRsaEncryption.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/BackendLoginFormRsaEncryption.js deleted file mode 100644 index 5b9b63c38a7fed45692690bc1bb59ab5cc348329..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/BackendLoginFormRsaEncryption.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -/** - * Object that handles RSA encryption and submission of the form - */ -define( - 'TYPO3/CMS/Rsaauth/BackendLoginFormRsaEncryption', - ['jquery', 'TYPO3/CMS/Backend/Login', 'TYPO3/CMS/Backend/UserPassLogin'], - function($, Login, UserPassLogin) { - - var RsaBackendLogin = { - - /** - * Field in which users enter their password - */ - userPasswordField: false, - - /** - * Field that is used by TYPO3 to evaluate the password during login process - */ - typo3PasswordField: false, - - /** - * Remember if we fetched the RSA key already - */ - fetchedRsaKey: false, - - /** - * Replace event handler of submit button - */ - initialize: function() { - this.userPasswordField = UserPassLogin.options.passwordField; - this.typo3PasswordField = Login.options.useridentField; - this.loginForm = Login.options.loginForm; - - Login.options.submitHandler = this.handleFormSubmitRequest; - }, - - /** - * Fetches a new public key by Ajax and encrypts the password for transmission - * - * @param event - */ - handleFormSubmitRequest: function(event) { - if (!RsaBackendLogin.fetchedRsaKey) { - RsaBackendLogin.fetchedRsaKey = true; - - event.preventDefault(); - - $.ajax({ - url: TYPO3.settings.ajaxUrls['BackendLogin::getRsaPublicKey'], - data: {'skipSessionUpdate': 1}, - success: RsaBackendLogin.handlePublicKeyResponse, - dataType: 'json' - }); - } else { - // we come here again when the submit is triggered below - // reset the variable to fetch a new key for next attempt - RsaBackendLogin.fetchedRsaKey = false; - } - }, - - /** - * Parses the Json response and triggers submission of the form - * - * @param publicKey Ajax response object - */ - handlePublicKeyResponse: function(publicKey) { - if (!publicKey.publicKeyModulus || !publicKey.exponent) { - alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.'); - return; - } - - var rsa = new RSAKey(); - rsa.setPublic(publicKey.publicKeyModulus, publicKey.exponent); - var encryptedPassword = rsa.encrypt($(RsaBackendLogin.userPasswordField).val()); - - // Reset user password field to prevent it from being submitted - $(RsaBackendLogin.userPasswordField).val(''); - $(RsaBackendLogin.typo3PasswordField).val('rsa:' + hex2b64(encryptedPassword)); - - var $formElement = $(RsaBackendLogin.loginForm); - - // Create a hidden input field to fake pressing the submit button - $formElement.append('<input type="hidden" name="commandLI" value="Submit">'); - - // Submit the form - $formElement.trigger('submit'); - } - }; - - RsaBackendLogin.initialize(); -}); diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/FrontendLoginFormRsaEncryption.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/FrontendLoginFormRsaEncryption.js deleted file mode 100644 index 95d36b3b32a9b899b334f4fad5de35b3583afa84..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/FrontendLoginFormRsaEncryption.js +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -/** - * Object that handles RSA encryption and submission of the FE login form - */ -TYPO3FrontendLoginFormRsaEncryption = function() { - - var rsaFrontendLogin = function(form, publicKeyEndpointUrl) { - - /** - * Submitted form element - */ - this.form = form; - - /** - * XMLHttpRequest - */ - this.xhr = null; - - /** - * Endpoint URL to fetch the public key for encryption - */ - this.publicKeyEndpointUrl = publicKeyEndpointUrl; - - /** - * Field in which users enter their password - */ - this.userPasswordField = form.pass; - - /** - * Fetches a new public key by Ajax and encrypts the password for transmission - */ - this.handleFormSubmitRequest = function() { - var rsaFrontendLogin = this; - this.ajaxCall( - this.publicKeyEndpointUrl, - function(response) { - rsaFrontendLogin.handlePublicKeyResponse(response, rsaFrontendLogin); - } - ); - }; - - /** - * Do Ajax call to fetch RSA public key - */ - this.ajaxCall = function(url, callback) { - - // abort previous request, only last request/generated key pair can be used - if (this.xhr) { - this.xhr.abort(); - } - - if (typeof XMLHttpRequest !== 'undefined') { - this.xhr = new XMLHttpRequest(); - } else { - var versions = [ - "MSXML2.XmlHttp.5.0", - "MSXML2.XmlHttp.4.0", - "MSXML2.XmlHttp.3.0", - "MSXML2.XmlHttp.2.0", - "Microsoft.XmlHttp" - ]; - for (var i = 0, len = versions.length; i < len; i++) { - try { - this.xhr = new ActiveXObject(versions[i]); - break; - } catch(e) {} - } - } - - this.xhr.onreadystatechange = function() { - // only process requests that are ready and have a status (not aborted) - if (this.readyState === 4 && this.status > 0) { - callback(this); - } - }; - - this.xhr.open('GET', url, true); - this.xhr.send(''); - }; - - /** - * Parses the response and triggers submission of the form - * - * @param response Ajax response object - * @param rsaFrontendLogin current processed object - */ - this.handlePublicKeyResponse = function(response, rsaFrontendLogin) { - var publicKey = response.responseText.split(':'); - if (publicKey[0] && publicKey[1]) { - rsaFrontendLogin.encryptPasswordAndSubmitForm(publicKey[0], publicKey[1]); - } else { - alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.'); - } - }; - - /** - * Uses the public key with the RSA library to encrypt the password. - * - * @param publicKeyModulus - * @param exponent - */ - this.encryptPasswordAndSubmitForm = function(publicKeyModulus, exponent) { - var rsa, encryptedPassword; - - rsa = new RSAKey(); - rsa.setPublic(publicKeyModulus, exponent); - encryptedPassword = rsa.encrypt(this.userPasswordField.value); - - // replace password value with encrypted password - this.userPasswordField.value = 'rsa:' + hex2b64(encryptedPassword); - - // Submit the form again but now with encrypted pass - document.createElement("form").submit.call(this.form); - }; - }; - - /** - * Encrypt password on submit - * - * @param form - * @param publicKeyEndpointUrl - * @return boolean - */ - this.submitForm = function(form, publicKeyEndpointUrl) { - - if (!form.rsaFrontendLogin) { - form.rsaFrontendLogin = new rsaFrontendLogin(form, publicKeyEndpointUrl); - } - - // if pass is not encrypted yet fetch public key and encrypt pass - if (!form.pass.value.match(/^rsa:/) ) { - form.rsaFrontendLogin.handleFormSubmitRequest(); - return false; - - // pass is encrypted so form can be submitted - } else { - return true; - } - }; - - return this; -}(); diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/FrontendLoginFormRsaEncryption.min.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/FrontendLoginFormRsaEncryption.min.js deleted file mode 100644 index 700e1bbd1d7b132774903dc9951b1f5e63a6194b..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/FrontendLoginFormRsaEncryption.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -/** Object that handles RSA encryption and submission of the FE login form */ -TYPO3FrontendLoginFormRsaEncryption=function(){var e=function(e,t){this.form=e;this.xhr=null;this.publicKeyEndpointUrl=t;this.userPasswordField=e.pass;this.handleFormSubmitRequest=function(){var e=this;this.ajaxCall(this.publicKeyEndpointUrl,function(t){e.handlePublicKeyResponse(t,e)})};this.ajaxCall=function(e,t){if(this.xhr){this.xhr.abort()}if(typeof XMLHttpRequest!=="undefined"){this.xhr=new XMLHttpRequest}else{var n=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"];for(var r=0,i=n.length;r<i;r++){try{this.xhr=new ActiveXObject(n[r]);break}catch(s){}}}this.xhr.onreadystatechange=function(){if(this.readyState===4&&this.status>0){t(this)}};this.xhr.open("GET",e,true);this.xhr.send("")};this.handlePublicKeyResponse=function(e,t){var n=e.responseText.split(":");if(n[0]&&n[1]){t.encryptPasswordAndSubmitForm(n[0],n[1])}else{alert("No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.")}};this.encryptPasswordAndSubmitForm=function(e,t){var n,r;n=new RSAKey;n.setPublic(e,t);r=n.encrypt(this.userPasswordField.value);this.userPasswordField.value="rsa:"+hex2b64(r);document.createElement("form").submit.call(this.form)}};this.submitForm=function(t,n){if(!t.rsaFrontendLogin){t.rsaFrontendLogin=new e(t,n)}if(!t.pass.value.match(/^rsa:/)){t.rsaFrontendLogin.handleFormSubmitRequest();return false}else{return true}};return this}() \ No newline at end of file diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryption.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryption.js new file mode 100644 index 0000000000000000000000000000000000000000..75c5426fd3fbdfef79e190054ce87b91e37cee72 --- /dev/null +++ b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryption.js @@ -0,0 +1,180 @@ +(function() { + 'use strict'; + + /** + * Prevent calling the function multiple times + */ + var documentReadyFunctionCalled = false; + + var rsaEncryption = function(form) { + + /** + * Submitted form element + */ + this.form = form; + + /** + * Store found fields in an array + */ + this.fields = []; + + /** + * XMLHttpRequest + */ + this.xhr = null; + + /** + * Remember if we fetched the RSA key already + */ + this.fetchedRsaKey = false; + + /** + * Fetches a new public key by Ajax and encrypts the password for transmission + */ + this.handleFormSubmitRequest = function(event) { + var rsaEncryption = this.rsaEncryption || event.srcElement.rsaEncryption; + if (!rsaEncryption) { + return; + } + if (rsaEncryption.fields.length && !rsaEncryption.fetchedRsaKey) { + rsaEncryption.fetchedRsaKey = true; + rsaEncryption.ajaxCall( + TYPO3RsaEncryptionPublicKeyUrl, // defined in PHP + rsaEncryption, + function(response) { + rsaEncryption.handlePublicKeyResponse(response, rsaEncryption); + } + ); + + if (event.preventDefault) { + event.preventDefault(); + } else if (window.event) { + window.event.returnValue = false; + } + } + }; + + this.ajaxCall = function(url, rsaEncryption, callback) { + // Abort previous request, only last request/generated key pair can be used + if (rsaEncryption.xhr) { + rsaEncryption.xhr.abort(); + } + + if (typeof XMLHttpRequest !== 'undefined') { + rsaEncryption.xhr = new XMLHttpRequest(); + } else { + var versions = [ + 'MSXML2.XmlHttp.5.0', + 'MSXML2.XmlHttp.4.0', + 'MSXML2.XmlHttp.3.0', + 'MSXML2.XmlHttp.2.0', + 'Microsoft.XmlHttp' + ]; + for (var i = 0, count = versions.length; i < count; i++) { + try { + rsaEncryption.xhr = new ActiveXObject(versions[i]); + break; + } catch (e) { + } + } + } + + rsaEncryption.xhr.onreadystatechange = function() { + // Only process requests that are ready and have a status (not aborted) + if (rsaEncryption.xhr.readyState === 4 && rsaEncryption.xhr.status > 0) { + callback(rsaEncryption.xhr); + } + }; + + rsaEncryption.xhr.open('GET', url, true); + rsaEncryption.xhr.send(''); + }; + + this.handlePublicKeyResponse = function(response, rsaEncryption) { + var publicKey = response.responseText.split(':'); + if (!publicKey[0] || !publicKey[1]) { + alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.'); + return false; + } + + var rsa = new RSAKey(); + rsa.setPublic(publicKey[0], publicKey[1]); + for (var i = rsaEncryption.fields.length; i--;) { + var field = rsaEncryption.fields[i]; + var encryptedValue = rsa.encrypt(field.value); + // Replace value with encrypted value + field.value = 'rsa:' + hex2b64(encryptedValue); + } + + // Submit the form again but now with encrypted values + var form = document.createElement('form'); + if (form.submit.call) { + form.submit.call(rsaEncryption.form); + } else { + var fields = rsaEncryption.form.getElementsByTagName('*'); + for (var j = fields.length; j--;) { + var submitField = fields[j]; + if (submitField.nodeName.toLowerCase() === 'input' && submitField.type === "submit") { + submitField.click(); + } + } + } + }; + }; + + /** + * Bind submit handler to all forms with input:data-rsa-encryption fields + */ + function ready() { + if (documentReadyFunctionCalled) { + return; + } + + documentReadyFunctionCalled = true; + rng_seed_time(); + var forms = document.getElementsByTagName('form'); + for (var i = forms.length; i--;) { + var form = forms[i]; + var fields = form.getElementsByTagName('*'); + for (var j = fields.length; j--;) { + var field = fields[j]; + if (field.nodeName.toLowerCase() === 'input') { + var dataAttribute = field.getAttribute('data-rsa-encryption'); + if (dataAttribute || dataAttribute === '' && field.outerHTML.match(/ data-rsa-encryption=""/)) { + if (!form.rsaEncryption) { + form.rsaEncryption = new rsaEncryption(form); + if (form.addEventListener) { + form.addEventListener('submit', form.rsaEncryption.handleFormSubmitRequest, false); + } else if (form.attachEvent) { + form.attachEvent('onsubmit', form.rsaEncryption.handleFormSubmitRequest); + } + } + form.rsaEncryption.fields.push(field); + } + } + } + } + } + + // If the document is ready, callback function can be called + if (document.readyState === 'complete') { + setTimeout(ready, 1); + } else { + // Install event handlers for older browsers + if (document.addEventListener) { + // First register DOMContentLoaded event + document.addEventListener('DOMContentLoaded', ready, false); + // Register backup on windows object + window.addEventListener('load', ready, false); + } else { + // Fallback for Internet Explorer + document.attachEvent('onreadystatechange', function() { + if (document.readyState === 'complete') { + ready(); + } + }); + window.attachEvent('onload', ready); + } + } + +})(); diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionModule.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionModule.js new file mode 100644 index 0000000000000000000000000000000000000000..c16e732a837bf64829666c4333f61136db2e6e00 --- /dev/null +++ b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionModule.js @@ -0,0 +1,113 @@ +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Object that handles RSA encryption and submission of the form + */ +define('TYPO3/CMS/Rsaauth/RsaEncryptionModule', ['jquery', './RsaLibrary'], function($) { + 'use strict'; + + var RsaEncryption = { + + /** + * Remember the form which was submitted + */ + $currentForm: null, + + /** + * Remember if we fetched the RSA key already + */ + fetchedRsaKey: false, + + /** + * Replace event handler of submit button + */ + initialize: function() { + $(':input[data-rsa-encryption]').closest('form').each(function() { + var $this = $(this); + $this.on('submit', RsaEncryption.handleFormSubmitRequest); + // Bind submit event first (this is a dirty hack with jquery internals, but there is no way around that) + var handlers = $._data(this, 'events').submit; + var handler = handlers.pop(); + handlers.unshift(handler); + }); + rng_seed_time(); + }, + + /** + * Fetches a new public key by Ajax and encrypts the password for transmission + * + * @param event + */ + handleFormSubmitRequest: function(event) { + if (!RsaEncryption.fetchedRsaKey) { + event.stopImmediatePropagation(); + + RsaEncryption.fetchedRsaKey = true; + RsaEncryption.$currentForm = $(this); + + $.ajax({ + url: TYPO3.settings.ajaxUrls['RsaEncryption::getRsaPublicKey'], + data: {'skipSessionUpdate': 1}, + success: RsaEncryption.handlePublicKeyResponse + }); + + return false; + } else { + // we come here again when the submit is triggered below + // reset the variable to fetch a new key for next attempt + RsaEncryption.fetchedRsaKey = false; + } + }, + + /** + * Parses the Json response and triggers submission of the form + * + * @param response Ajax response object + */ + handlePublicKeyResponse: function(response) { + var publicKey = response.split(':'); + if (!publicKey[0] || !publicKey[1]) { + alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.'); + return; + } + + var rsa = new RSAKey(); + rsa.setPublic(publicKey[0], publicKey[1]); + RsaEncryption.$currentForm.find(':input[data-rsa-encryption]').each(function() { + var $this = $(this); + var encryptedPassword = rsa.encrypt($this.val()); + var dataAttribute = $this.data('rsa-encryption'); + + if (!dataAttribute) { + $this.val('rsa:' + hex2b64(encryptedPassword)); + } else { + var $typo3Field = $('#' + dataAttribute); + $typo3Field.val('rsa:' + hex2b64(encryptedPassword)); + // Reset user password field to prevent it from being submitted + $this.val(''); + } + }); + + // Create a hidden input field to fake pressing the submit button + RsaEncryption.$currentForm.append('<input type="hidden" name="commandLI" value="Submit">'); + + // Submit the form + RsaEncryption.$currentForm.trigger('submit'); + } + }; + + $(document).ready(RsaEncryption.initialize); + + return RsaEncryption; +}); diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionWithLib.min.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionWithLib.min.js new file mode 100644 index 0000000000000000000000000000000000000000..3a4f961ee3a4da40d0e2942964ef9fb22a58dd21 --- /dev/null +++ b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionWithLib.min.js @@ -0,0 +1 @@ +function hex2b64(t){var r,n,e="";for(r=0;r+3<=t.length;r+=3)n=parseInt(t.substring(r,r+3),16),e+=b64map.charAt(n>>6)+b64map.charAt(63&n);for(r+1==t.length?(n=parseInt(t.substring(r,r+1),16),e+=b64map.charAt(n<<2)):r+2==t.length&&(n=parseInt(t.substring(r,r+2),16),e+=b64map.charAt(n>>2)+b64map.charAt((3&n)<<4));(3&e.length)>0;)e+=b64padchar;return e}function b64tohex(t){var r,n,e="",i=0;for(r=0;r<t.length&&t.charAt(r)!=b64padchar;++r)v=b64map.indexOf(t.charAt(r)),v<0||(0==i?(e+=int2char(v>>2),n=3&v,i=1):1==i?(e+=int2char(n<<2|v>>4),n=15&v,i=2):2==i?(e+=int2char(n),e+=int2char(v>>2),n=3&v,i=3):(e+=int2char(n<<2|v>>4),e+=int2char(15&v),i=0));return 1==i&&(e+=int2char(n<<2)),e}function b64toBA(t){var r,n=b64tohex(t),e=new Array;for(r=0;2*r<n.length;++r)e[r]=parseInt(n.substring(2*r,2*r+2),16);return e}function BigInteger(t,r,n){null!=t&&("number"==typeof t?this.fromNumber(t,r,n):null==r&&"string"!=typeof t?this.fromString(t,256):this.fromString(t,r))}function nbi(){return new BigInteger(null)}function am1(t,r,n,e,i,o){for(;--o>=0;){var s=r*this[t++]+n[e]+i;i=Math.floor(s/67108864),n[e++]=67108863&s}return i}function am2(t,r,n,e,i,o){for(var s=32767&r,h=r>>15;--o>=0;){var a=32767&this[t],p=this[t++]>>15,u=h*a+p*s;a=s*a+((32767&u)<<15)+n[e]+(1073741823&i),i=(a>>>30)+(u>>>15)+h*p+(i>>>30),n[e++]=1073741823&a}return i}function am3(t,r,n,e,i,o){for(var s=16383&r,h=r>>14;--o>=0;){var a=16383&this[t],p=this[t++]>>14,u=h*a+p*s;a=s*a+((16383&u)<<14)+n[e]+i,i=(a>>28)+(u>>14)+h*p,n[e++]=268435455&a}return i}function int2char(t){return BI_RM.charAt(t)}function intAt(t,r){var n=BI_RC[t.charCodeAt(r)];return null==n?-1:n}function bnpCopyTo(t){for(var r=this.t-1;r>=0;--r)t[r]=this[r];t.t=this.t,t.s=this.s}function bnpFromInt(t){this.t=1,this.s=0>t?-1:0,t>0?this[0]=t:-1>t?this[0]=t+this.DV:this.t=0}function nbv(t){var r=nbi();return r.fromInt(t),r}function bnpFromString(t,r){var n;if(16==r)n=4;else if(8==r)n=3;else if(256==r)n=8;else if(2==r)n=1;else if(32==r)n=5;else{if(4!=r)return void this.fromRadix(t,r);n=2}this.t=0,this.s=0;for(var e=t.length,i=!1,o=0;--e>=0;){var s=8==n?255&t[e]:intAt(t,e);0>s?"-"==t.charAt(e)&&(i=!0):(i=!1,0==o?this[this.t++]=s:o+n>this.DB?(this[this.t-1]|=(s&(1<<this.DB-o)-1)<<o,this[this.t++]=s>>this.DB-o):this[this.t-1]|=s<<o,o+=n,o>=this.DB&&(o-=this.DB))}8==n&&0!=(128&t[0])&&(this.s=-1,o>0&&(this[this.t-1]|=(1<<this.DB-o)-1<<o)),this.clamp(),i&&BigInteger.ZERO.subTo(this,this)}function bnpClamp(){for(var t=this.s&this.DM;this.t>0&&this[this.t-1]==t;)--this.t}function bnToString(t){if(this.s<0)return"-"+this.negate().toString(t);var r;if(16==t)r=4;else if(8==t)r=3;else if(2==t)r=1;else if(32==t)r=5;else{if(4!=t)return this.toRadix(t);r=2}var n,e=(1<<r)-1,i=!1,o="",s=this.t,h=this.DB-s*this.DB%r;if(s-->0)for(h<this.DB&&(n=this[s]>>h)>0&&(i=!0,o=int2char(n));s>=0;)r>h?(n=(this[s]&(1<<h)-1)<<r-h,n|=this[--s]>>(h+=this.DB-r)):(n=this[s]>>(h-=r)&e,0>=h&&(h+=this.DB,--s)),n>0&&(i=!0),i&&(o+=int2char(n));return i?o:"0"}function bnNegate(){var t=nbi();return BigInteger.ZERO.subTo(this,t),t}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(t){var r=this.s-t.s;if(0!=r)return r;var n=this.t;if(r=n-t.t,0!=r)return this.s<0?-r:r;for(;--n>=0;)if(0!=(r=this[n]-t[n]))return r;return 0}function nbits(t){var r,n=1;return 0!=(r=t>>>16)&&(t=r,n+=16),0!=(r=t>>8)&&(t=r,n+=8),0!=(r=t>>4)&&(t=r,n+=4),0!=(r=t>>2)&&(t=r,n+=2),0!=(r=t>>1)&&(t=r,n+=1),n}function bnBitLength(){return this.t<=0?0:this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(t,r){var n;for(n=this.t-1;n>=0;--n)r[n+t]=this[n];for(n=t-1;n>=0;--n)r[n]=0;r.t=this.t+t,r.s=this.s}function bnpDRShiftTo(t,r){for(var n=t;n<this.t;++n)r[n-t]=this[n];r.t=Math.max(this.t-t,0),r.s=this.s}function bnpLShiftTo(t,r){var n,e=t%this.DB,i=this.DB-e,o=(1<<i)-1,s=Math.floor(t/this.DB),h=this.s<<e&this.DM;for(n=this.t-1;n>=0;--n)r[n+s+1]=this[n]>>i|h,h=(this[n]&o)<<e;for(n=s-1;n>=0;--n)r[n]=0;r[s]=h,r.t=this.t+s+1,r.s=this.s,r.clamp()}function bnpRShiftTo(t,r){r.s=this.s;var n=Math.floor(t/this.DB);if(n>=this.t)return void(r.t=0);var e=t%this.DB,i=this.DB-e,o=(1<<e)-1;r[0]=this[n]>>e;for(var s=n+1;s<this.t;++s)r[s-n-1]|=(this[s]&o)<<i,r[s-n]=this[s]>>e;e>0&&(r[this.t-n-1]|=(this.s&o)<<i),r.t=this.t-n,r.clamp()}function bnpSubTo(t,r){for(var n=0,e=0,i=Math.min(t.t,this.t);i>n;)e+=this[n]-t[n],r[n++]=e&this.DM,e>>=this.DB;if(t.t<this.t){for(e-=t.s;n<this.t;)e+=this[n],r[n++]=e&this.DM,e>>=this.DB;e+=this.s}else{for(e+=this.s;n<t.t;)e-=t[n],r[n++]=e&this.DM,e>>=this.DB;e-=t.s}r.s=0>e?-1:0,-1>e?r[n++]=this.DV+e:e>0&&(r[n++]=e),r.t=n,r.clamp()}function bnpMultiplyTo(t,r){var n=this.abs(),e=t.abs(),i=n.t;for(r.t=i+e.t;--i>=0;)r[i]=0;for(i=0;i<e.t;++i)r[i+n.t]=n.am(0,e[i],r,i,0,n.t);r.s=0,r.clamp(),this.s!=t.s&&BigInteger.ZERO.subTo(r,r)}function bnpSquareTo(t){for(var r=this.abs(),n=t.t=2*r.t;--n>=0;)t[n]=0;for(n=0;n<r.t-1;++n){var e=r.am(n,r[n],t,2*n,0,1);(t[n+r.t]+=r.am(n+1,2*r[n],t,2*n+1,e,r.t-n-1))>=r.DV&&(t[n+r.t]-=r.DV,t[n+r.t+1]=1)}t.t>0&&(t[t.t-1]+=r.am(n,r[n],t,2*n,0,1)),t.s=0,t.clamp()}function bnpDivRemTo(t,r,n){var e=t.abs();if(!(e.t<=0)){var i=this.abs();if(i.t<e.t)return null!=r&&r.fromInt(0),void(null!=n&&this.copyTo(n));null==n&&(n=nbi());var o=nbi(),s=this.s,h=t.s,a=this.DB-nbits(e[e.t-1]);a>0?(e.lShiftTo(a,o),i.lShiftTo(a,n)):(e.copyTo(o),i.copyTo(n));var p=o.t,u=o[p-1];if(0!=u){var g=u*(1<<this.F1)+(p>1?o[p-2]>>this.F2:0),c=this.FV/g,f=(1<<this.F1)/g,l=1<<this.F2,m=n.t,v=m-p,b=null==r?nbi():r;for(o.dlShiftTo(v,b),n.compareTo(b)>=0&&(n[n.t++]=1,n.subTo(b,n)),BigInteger.ONE.dlShiftTo(p,b),b.subTo(o,o);o.t<p;)o[o.t++]=0;for(;--v>=0;){var d=n[--m]==u?this.DM:Math.floor(n[m]*c+(n[m-1]+l)*f);if((n[m]+=o.am(0,d,n,v,0,p))<d)for(o.dlShiftTo(v,b),n.subTo(b,n);n[m]<--d;)n.subTo(b,n)}null!=r&&(n.drShiftTo(p,r),s!=h&&BigInteger.ZERO.subTo(r,r)),n.t=p,n.clamp(),a>0&&n.rShiftTo(a,n),0>s&&BigInteger.ZERO.subTo(n,n)}}}function bnMod(t){var r=nbi();return this.abs().divRemTo(t,null,r),this.s<0&&r.compareTo(BigInteger.ZERO)>0&&t.subTo(r,r),r}function Classic(t){this.m=t}function cConvert(t){return t.s<0||t.compareTo(this.m)>=0?t.mod(this.m):t}function cRevert(t){return t}function cReduce(t){t.divRemTo(this.m,null,t)}function cMulTo(t,r,n){t.multiplyTo(r,n),this.reduce(n)}function cSqrTo(t,r){t.squareTo(r),this.reduce(r)}function bnpInvDigit(){if(this.t<1)return 0;var t=this[0];if(0==(1&t))return 0;var r=3&t;return r=r*(2-(15&t)*r)&15,r=r*(2-(255&t)*r)&255,r=r*(2-((65535&t)*r&65535))&65535,r=r*(2-t*r%this.DV)%this.DV,r>0?this.DV-r:-r}function Montgomery(t){this.m=t,this.mp=t.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<<t.DB-15)-1,this.mt2=2*t.t}function montConvert(t){var r=nbi();return t.abs().dlShiftTo(this.m.t,r),r.divRemTo(this.m,null,r),t.s<0&&r.compareTo(BigInteger.ZERO)>0&&this.m.subTo(r,r),r}function montRevert(t){var r=nbi();return t.copyTo(r),this.reduce(r),r}function montReduce(t){for(;t.t<=this.mt2;)t[t.t++]=0;for(var r=0;r<this.m.t;++r){var n=32767&t[r],e=n*this.mpl+((n*this.mph+(t[r]>>15)*this.mpl&this.um)<<15)&t.DM;for(n=r+this.m.t,t[n]+=this.m.am(0,e,t,r,0,this.m.t);t[n]>=t.DV;)t[n]-=t.DV,t[++n]++}t.clamp(),t.drShiftTo(this.m.t,t),t.compareTo(this.m)>=0&&t.subTo(this.m,t)}function montSqrTo(t,r){t.squareTo(r),this.reduce(r)}function montMulTo(t,r,n){t.multiplyTo(r,n),this.reduce(n)}function bnpIsEven(){return 0==(this.t>0?1&this[0]:this.s)}function bnpExp(t,r){if(t>4294967295||1>t)return BigInteger.ONE;var n=nbi(),e=nbi(),i=r.convert(this),o=nbits(t)-1;for(i.copyTo(n);--o>=0;)if(r.sqrTo(n,e),(t&1<<o)>0)r.mulTo(e,i,n);else{var s=n;n=e,e=s}return r.revert(n)}function bnModPowInt(t,r){var n;return n=256>t||r.isEven()?new Classic(r):new Montgomery(r),this.exp(t,n)}function Arcfour(){this.i=0,this.j=0,this.S=new Array}function ARC4init(t){var r,n,e;for(r=0;256>r;++r)this.S[r]=r;for(n=0,r=0;256>r;++r)n=n+this.S[r]+t[r%t.length]&255,e=this.S[r],this.S[r]=this.S[n],this.S[n]=e;this.i=0,this.j=0}function ARC4next(){var t;return this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255,t=this.S[this.i],this.S[this.i]=this.S[this.j],this.S[this.j]=t,this.S[t+this.S[this.i]&255]}function prng_newstate(){return new Arcfour}function rng_seed_int(t){rng_pool[rng_pptr++]^=255&t,rng_pool[rng_pptr++]^=t>>8&255,rng_pool[rng_pptr++]^=t>>16&255,rng_pool[rng_pptr++]^=t>>24&255,rng_pptr>=rng_psize&&(rng_pptr-=rng_psize)}function rng_seed_time(){rng_seed_int((new Date).getTime())}function rng_get_byte(){if(null==rng_state){for(rng_seed_time(),rng_state=prng_newstate(),rng_state.init(rng_pool),rng_pptr=0;rng_pptr<rng_pool.length;++rng_pptr)rng_pool[rng_pptr]=0;rng_pptr=0}return rng_state.next()}function rng_get_bytes(t){var r;for(r=0;r<t.length;++r)t[r]=rng_get_byte()}function SecureRandom(){}function parseBigInt(t,r){return new BigInteger(t,r)}function linebrk(t,r){for(var n="",e=0;e+r<t.length;)n+=t.substring(e,e+r)+"\n",e+=r;return n+t.substring(e,t.length)}function byte2Hex(t){return 16>t?"0"+t.toString(16):t.toString(16)}function pkcs1pad2(t,r){if(r<t.length+11)return alert("Message too long for RSA"),null;for(var n=new Array,e=t.length-1;e>=0&&r>0;){var i=t.charCodeAt(e--);128>i?n[--r]=i:i>127&&2048>i?(n[--r]=63&i|128,n[--r]=i>>6|192):(n[--r]=63&i|128,n[--r]=i>>6&63|128,n[--r]=i>>12|224)}n[--r]=0;for(var o=new SecureRandom,s=new Array;r>2;){for(s[0]=0;0==s[0];)o.nextBytes(s);n[--r]=s[0]}return n[--r]=2,n[--r]=0,new BigInteger(n)}function RSAKey(){this.n=null,this.e=0,this.d=null,this.p=null,this.q=null,this.dmp1=null,this.dmq1=null,this.coeff=null}function RSASetPublic(t,r){null!=t&&null!=r&&t.length>0&&r.length>0?(this.n=parseBigInt(t,16),this.e=parseInt(r,16)):alert("Invalid RSA public key")}function RSADoPublic(t){return t.modPowInt(this.e,this.n)}function RSAEncrypt(t){var r=pkcs1pad2(t,this.n.bitLength()+7>>3);if(null==r)return null;var n=this.doPublic(r);if(null==n)return null;var e=n.toString(16);return 0==(1&e.length)?e:"0"+e}var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",b64padchar="=",dbits,canary=0xdeadbeefcafe,j_lm=15715070==(16777215&canary);j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28),BigInteger.prototype.DB=dbits,BigInteger.prototype.DM=(1<<dbits)-1,BigInteger.prototype.DV=1<<dbits;var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP),BigInteger.prototype.F1=BI_FP-dbits,BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz",BI_RC=new Array,rr,vv;for(rr="0".charCodeAt(0),vv=0;9>=vv;++vv)BI_RC[rr++]=vv;for(rr="a".charCodeAt(0),vv=10;36>vv;++vv)BI_RC[rr++]=vv;for(rr="A".charCodeAt(0),vv=10;36>vv;++vv)BI_RC[rr++]=vv;Classic.prototype.convert=cConvert,Classic.prototype.revert=cRevert,Classic.prototype.reduce=cReduce,Classic.prototype.mulTo=cMulTo,Classic.prototype.sqrTo=cSqrTo,Montgomery.prototype.convert=montConvert,Montgomery.prototype.revert=montRevert,Montgomery.prototype.reduce=montReduce,Montgomery.prototype.mulTo=montMulTo,Montgomery.prototype.sqrTo=montSqrTo,BigInteger.prototype.copyTo=bnpCopyTo,BigInteger.prototype.fromInt=bnpFromInt,BigInteger.prototype.fromString=bnpFromString,BigInteger.prototype.clamp=bnpClamp,BigInteger.prototype.dlShiftTo=bnpDLShiftTo,BigInteger.prototype.drShiftTo=bnpDRShiftTo,BigInteger.prototype.lShiftTo=bnpLShiftTo,BigInteger.prototype.rShiftTo=bnpRShiftTo,BigInteger.prototype.subTo=bnpSubTo,BigInteger.prototype.multiplyTo=bnpMultiplyTo,BigInteger.prototype.squareTo=bnpSquareTo,BigInteger.prototype.divRemTo=bnpDivRemTo,BigInteger.prototype.invDigit=bnpInvDigit,BigInteger.prototype.isEven=bnpIsEven,BigInteger.prototype.exp=bnpExp,BigInteger.prototype.toString=bnToString,BigInteger.prototype.negate=bnNegate,BigInteger.prototype.abs=bnAbs,BigInteger.prototype.compareTo=bnCompareTo,BigInteger.prototype.bitLength=bnBitLength,BigInteger.prototype.mod=bnMod,BigInteger.prototype.modPowInt=bnModPowInt,BigInteger.ZERO=nbv(0),BigInteger.ONE=nbv(1),Arcfour.prototype.init=ARC4init,Arcfour.prototype.next=ARC4next;var rng_psize=256,rng_state,rng_pool,rng_pptr;if(null==rng_pool){rng_pool=new Array,rng_pptr=0;var t;if(window.crypto&&window.crypto.getRandomValues){var ua=new Uint8Array(32);for(window.crypto.getRandomValues(ua),t=0;32>t;++t)rng_pool[rng_pptr++]=ua[t]}if("Netscape"==navigator.appName&&navigator.appVersion<"5"&&window.crypto){var z=window.crypto.random(32);for(t=0;t<z.length;++t)rng_pool[rng_pptr++]=255&z.charCodeAt(t)}for(;rng_psize>rng_pptr;)t=Math.floor(65536*Math.random()),rng_pool[rng_pptr++]=t>>>8,rng_pool[rng_pptr++]=255&t;rng_pptr=0,rng_seed_time()}SecureRandom.prototype.nextBytes=rng_get_bytes,RSAKey.prototype.doPublic=RSADoPublic,RSAKey.prototype.setPublic=RSASetPublic,RSAKey.prototype.encrypt=RSAEncrypt,function(){"use strict";function t(){if(!r){r=!0,rng_seed_time();for(var t=document.getElementsByTagName("form"),e=t.length;e--;)for(var i=t[e],o=i.getElementsByTagName("*"),s=o.length;s--;){var h=o[s];if("input"===h.nodeName.toLowerCase()){var a=h.getAttribute("data-rsa-encryption");(a||""===a&&h.outerHTML.match(/ data-rsa-encryption=""/))&&(i.rsaEncryption||(i.rsaEncryption=new n(i),i.addEventListener?i.addEventListener("submit",i.rsaEncryption.handleFormSubmitRequest,!1):i.attachEvent&&i.attachEvent("onsubmit",i.rsaEncryption.handleFormSubmitRequest)),i.rsaEncryption.fields.push(h))}}}}var r=!1,n=function(t){this.form=t,this.fields=[],this.xhr=null,this.fetchedRsaKey=!1,this.handleFormSubmitRequest=function(t){var r=this.rsaEncryption||t.srcElement.rsaEncryption;r&&r.fields.length&&!r.fetchedRsaKey&&(r.fetchedRsaKey=!0,r.ajaxCall(TYPO3RsaEncryptionPublicKeyUrl,r,function(t){r.handlePublicKeyResponse(t,r)}),t.preventDefault?t.preventDefault():window.event&&(window.event.returnValue=!1))},this.ajaxCall=function(t,r,n){if(r.xhr&&r.xhr.abort(),"undefined"!=typeof XMLHttpRequest)r.xhr=new XMLHttpRequest;else for(var e=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"],i=0,o=e.length;o>i;i++)try{r.xhr=new ActiveXObject(e[i]);break}catch(s){}r.xhr.onreadystatechange=function(){4===r.xhr.readyState&&r.xhr.status>0&&n(r.xhr)},r.xhr.open("GET",t,!0),r.xhr.send("")},this.handlePublicKeyResponse=function(t,r){var n=t.responseText.split(":");if(!n[0]||!n[1])return alert("No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings."),!1;var e=new RSAKey;e.setPublic(n[0],n[1]);for(var i=r.fields.length;i--;){var o=r.fields[i],s=e.encrypt(o.value);o.value="rsa:"+hex2b64(s)}var h=document.createElement("form");if(h.submit.call)h.submit.call(r.form);else for(var a=r.form.getElementsByTagName("*"),p=a.length;p--;){var u=a[p];"input"===u.nodeName.toLowerCase()&&"submit"===u.type&&u.click()}}};"complete"===document.readyState?setTimeout(t,1):document.addEventListener?(document.addEventListener("DOMContentLoaded",t,!1),window.addEventListener("load",t,!1)):(document.attachEvent("onreadystatechange",function(){"complete"===document.readyState&&t()}),window.attachEvent("onload",t))}(); diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaLibrary.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaLibrary.js new file mode 100644 index 0000000000000000000000000000000000000000..96244d0412cc74e4f3755807d8fcfc08b2aa8a49 --- /dev/null +++ b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaLibrary.js @@ -0,0 +1,884 @@ +// +// base64.js +// +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64padchar="="; + +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64padchar; + return ret; +} + +// convert a base64 string to hex +function b64tohex(s) { + var ret = ""; + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64padchar) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} + +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} + +// +// jsbn.js +// + +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<<dbits)-1); +BigInteger.prototype.DV = (1<<dbits); + +var BI_FP = 52; +BigInteger.prototype.FV = Math.pow(2,BI_FP); +BigInteger.prototype.F1 = BI_FP-dbits; +BigInteger.prototype.F2 = 2*dbits-BI_FP; + +// Digit conversions +var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; +var BI_RC = new Array(); +var rr,vv; +rr = "0".charCodeAt(0); +for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; +rr = "a".charCodeAt(0); +for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; +rr = "A".charCodeAt(0); +for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + +function int2char(n) { return BI_RM.charAt(n); } +function intAt(s,i) { + var c = BI_RC[s.charCodeAt(i)]; + return (c==null)?-1:c; +} + +// (protected) copy this to r +function bnpCopyTo(r) { + for(var i = this.t-1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh; + this[this.t++] = (x>>(this.DB-sh)); + } + else + this[this.t-1] |= x<<sh; + sh += k; + if(sh >= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh; + } + this.clamp(); + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) clamp off excess high words +function bnpClamp() { + var c = this.s&this.DM; + while(this.t > 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1<<k)-1, d, m = false, r = "", i = this.t; + var p = this.DB-(i*this.DB)%k; + if(i-- > 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<<p)-1))<<(k-p); + d |= this[--i]>>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<<cbs)-1; + var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i; + for(i = this.t-1; i >= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<<bs; + } + for(i = ds-1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<<bs)-1; + r[0] = this[ds]>>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<<cbs; + r[i-ds] = this[i]>>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs; + r.t = this.t-ds; + r.clamp(); +} + +// (protected) r = this - a +function bnpSubTo(a,r) { + var i = 0, c = 0, m = Math.min(a.t,this.t); + while(i < m) { + c += this[i]-a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2; + var i = r.t, j = i-ys, t = (q==null)?nbi():q; + y.dlShiftTo(j,t); + if(r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1<<i)) > 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// +// prng4.js - uses Arcfour as a PRNG +// + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + + +// +// rng.js +// + +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'> +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(window.crypto && window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; + + +// +// rsa.js +// +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/LICENSE b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/LICENSE deleted file mode 100644 index 24502a9cf7483647d0e4e5b35396082b1295d9c3..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/LICENSE +++ /dev/null @@ -1,40 +0,0 @@ -Licensing ---------- - -This software is covered under the following copyright: - -/* - * Copyright (c) 2003-2005 Tom Wu - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ - -Address all questions regarding this license to: - - Tom Wu - tjw@cs.Stanford.EDU diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/base64.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/base64.js deleted file mode 100644 index f5b168c4c30666737e048f55c2fa24c70b0e023b..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/base64.js +++ /dev/null @@ -1,71 +0,0 @@ -var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var b64pad="="; - -function hex2b64(h) { - var i; - var c; - var ret = ""; - for(i = 0; i+3 <= h.length; i+=3) { - c = parseInt(h.substring(i,i+3),16); - ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); - } - if(i+1 == h.length) { - c = parseInt(h.substring(i,i+1),16); - ret += b64map.charAt(c << 2); - } - else if(i+2 == h.length) { - c = parseInt(h.substring(i,i+2),16); - ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); - } - while((ret.length & 3) > 0) ret += b64pad; - return ret; -} - -// convert a base64 string to hex -function b64tohex(s) { - var ret = "" - var i; - var k = 0; // b64 state, 0-3 - var slop; - for(i = 0; i < s.length; ++i) { - if(s.charAt(i) == b64pad) break; - v = b64map.indexOf(s.charAt(i)); - if(v < 0) continue; - if(k == 0) { - ret += int2char(v >> 2); - slop = v & 3; - k = 1; - } - else if(k == 1) { - ret += int2char((slop << 2) | (v >> 4)); - slop = v & 0xf; - k = 2; - } - else if(k == 2) { - ret += int2char(slop); - ret += int2char(v >> 2); - slop = v & 3; - k = 3; - } - else { - ret += int2char((slop << 2) | (v >> 4)); - ret += int2char(v & 0xf); - k = 0; - } - } - if(k == 1) - ret += int2char(slop << 2); - return ret; -} - -// convert a base64 string to a byte/number array -function b64toBA(s) { - //piggyback on b64tohex for now, optimize later - var h = b64tohex(s); - var i; - var a = new Array(); - for(i = 0; 2*i < h.length; ++i) { - a[i] = parseInt(h.substring(2*i,2*i+2),16); - } - return a; -} diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/jsbn.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/jsbn.js deleted file mode 100644 index 928cc4f7bd56a8526c98bc240f9431f74be36564..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/jsbn.js +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (c) 2005 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Basic JavaScript BN library - subset useful for RSA encryption. - -// Bits per digit -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); - -// (public) Constructor -function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); -} - -// return new, unset BigInteger -function nbi() { return new BigInteger(null); } - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; -} -if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} -else if(j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; -} -else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -} - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<<dbits)-1); -BigInteger.prototype.DV = (1<<dbits); - -var BI_FP = 52; -BigInteger.prototype.FV = Math.pow(2,BI_FP); -BigInteger.prototype.F1 = BI_FP-dbits; -BigInteger.prototype.F2 = 2*dbits-BI_FP; - -// Digit conversions -var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; -var BI_RC = new Array(); -var rr,vv; -rr = "0".charCodeAt(0); -for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; -rr = "a".charCodeAt(0); -for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; -rr = "A".charCodeAt(0); -for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; - -function int2char(n) { return BI_RM.charAt(n); } -function intAt(s,i) { - var c = BI_RC[s.charCodeAt(i)]; - return (c==null)?-1:c; -} - -// (protected) copy this to r -function bnpCopyTo(r) { - for(var i = this.t-1; i >= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+DV; - else this.t = 0; -} - -// return bigint initialized to value -function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - -// (protected) set from string and radix -function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh; - this[this.t++] = (x>>(this.DB-sh)); - } - else - this[this.t-1] |= x<<sh; - sh += k; - if(sh >= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh; - } - this.clamp(); - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) clamp off excess high words -function bnpClamp() { - var c = this.s&this.DM; - while(this.t > 0 && this[this.t-1] == c) --this.t; -} - -// (public) return string representation in given radix -function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1<<k)-1, d, m = false, r = "", i = this.t; - var p = this.DB-(i*this.DB)%k; - if(i-- > 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<<p)-1))<<(k-p); - d |= this[--i]>>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; -} - -// (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - -// (public) |this| -function bnAbs() { return (this.s<0)?this.negate():this; } - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; -} - -// (protected) r = this << n -function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<<cbs)-1; - var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i; - for(i = this.t-1; i >= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<<bs; - } - for(i = ds-1; i >= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n -function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<<bs)-1; - r[0] = this[ds]>>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<<cbs; - r[i-ds] = this[i]>>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs; - r.t = this.t-ds; - r.clamp(); -} - -// (protected) r = this - a -function bnpSubTo(a,r) { - var i = 0, c = 0, m = Math.min(a.t,this.t); - while(i < m) { - c += this[i]-a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2; - var i = r.t, j = i-ys, t = (q==null)?nbi():q; - y.dlShiftTo(j,t); - if(r.compareTo(t) >= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); -} - -// (public) this mod a -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; -} - -// Modular reduction using "classic" algorithm -function Classic(m) { this.m = m; } -function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} -function cRevert(x) { return x; } -function cReduce(x) { x.divRemTo(this.m,null,x); } -function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } -function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; -} - -// xR mod m -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; -} - -// x/R mod m -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = "xy/R mod m"; x,y != r -function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even -function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1<<i)) > 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/jsbn2.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/jsbn2.js deleted file mode 100644 index e53e00b49808a4afe2285369c2644dab30c269e4..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/jsbn2.js +++ /dev/null @@ -1,648 +0,0 @@ -// Copyright (c) 2005-2009 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Extended JavaScript BN functions, required for RSA private ops. - -// Version 1.1: new BigInteger("0", 10) returns "proper" zero - -// (public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -// (public) return value as integer -function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0]; -} - -// (public) return value as byte -function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; } - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string -function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0; - this.fromString(x,256); - } -} - -// (public) convert to bigendian byte array -function bnToByteArray() { - var i = this.t, r = new Array(); - r[0] = this.s; - var p = this.DB-(i*this.DB)%8, d, k = 0; - if(i-- > 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<<p)-1))<<(8-p); - d |= this[--i]>>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); -} - -// (public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -// (public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -// (public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -// (public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -// (public) ~this -function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n -function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; -} - -// (public) this >> n -function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); -} - -// (protected) this op (1<<n) -function bnpChangeBit(n,op) { - var r = BigInteger.ONE.shiftLeft(n); - this.bitwiseTo(r,op,r); - return r; -} - -// (public) this | (1<<n) -function bnSetBit(n) { return this.changeBit(n,op_or); } - -// (public) this & ~(1<<n) -function bnClearBit(n) { return this.changeBit(n,op_andnot); } - -// (public) this ^ (1<<n) -function bnFlipBit(n) { return this.changeBit(n,op_xor); } - -// (protected) r = this + a -function bnpAddTo(a,r) { - var i = 0, c = 0, m = Math.min(a.t,this.t); - while(i < m) { - c += this[i]+a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); -} - -// (public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -// (public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -// (public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -// (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -// (public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) -function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1; - g[1] = z.convert(this); - if(k > 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1<<i)) == 0) { - z.sqrTo(r,r2); t = r; r = r2; r2 = t; - if(--i < 0) { i = this.DB-1; --j; } - } - } - return z.revert(r); -} - -// (public) gcd(this,a) (HAC 14.54) -function bnGCD(a) { - var x = (this.s<0)?this.negate():this.clone(); - var y = (a.s<0)?a.negate():a.clone(); - if(x.compareTo(y) < 0) { var t = x; x = y; y = t; } - var i = x.getLowestSetBit(), g = y.getLowestSetBit(); - if(g < 0) return x; - if(i < g) g = i; - if(g > 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; -} - -var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - a.fromInt(lowprimes[i]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; -} - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - -// BigInteger interfaces not implemented in jsbn: - -// BigInteger(int signum, byte[] magnitude) -// double doubleValue() -// float floatValue() -// int hashCode() -// long longValue() -// static BigInteger valueOf(long val) diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/prng4.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/prng4.js deleted file mode 100644 index 3034f3f1158d536a866314f279e2c637d0c0a1f2..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/prng4.js +++ /dev/null @@ -1,45 +0,0 @@ -// prng4.js - uses Arcfour as a PRNG - -function Arcfour() { - this.i = 0; - this.j = 0; - this.S = new Array(); -} - -// Initialize arcfour context from key, an array of ints, each from [0..255] -function ARC4init(key) { - var i, j, t; - for(i = 0; i < 256; ++i) - this.S[i] = i; - j = 0; - for(i = 0; i < 256; ++i) { - j = (j + this.S[i] + key[i % key.length]) & 255; - t = this.S[i]; - this.S[i] = this.S[j]; - this.S[j] = t; - } - this.i = 0; - this.j = 0; -} - -function ARC4next() { - var t; - this.i = (this.i + 1) & 255; - this.j = (this.j + this.S[this.i]) & 255; - t = this.S[this.i]; - this.S[this.i] = this.S[this.j]; - this.S[this.j] = t; - return this.S[(t + this.S[this.i]) & 255]; -} - -Arcfour.prototype.init = ARC4init; -Arcfour.prototype.next = ARC4next; - -// Plug in your RNG constructor here -function prng_newstate() { - return new Arcfour(); -} - -// Pool size must be a multiple of 4 and greater than 32. -// An array of bytes the size of the pool will be passed to init() -var rng_psize = 256; diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rng.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rng.js deleted file mode 100644 index 03afc3a9fe75be37cfa45fa510bf31399496db2d..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rng.js +++ /dev/null @@ -1,68 +0,0 @@ -// Random number generator - requires a PRNG backend, e.g. prng4.js - -// For best results, put code like -// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'> -// in your main HTML document. - -var rng_state; -var rng_pool; -var rng_pptr; - -// Mix in a 32-bit integer into the pool -function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; -} - -// Mix in the current time (w/milliseconds) into the pool -function rng_seed_time() { - rng_seed_int(new Date().getTime()); -} - -// Initialize the pool with junk if needed. -if(rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for(t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - while(rng_pptr < rng_psize) { // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); -} - -function rng_get_byte() { - if(rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); -} - -function rng_get_bytes(ba) { - var i; - for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); -} - -function SecureRandom() {} - -SecureRandom.prototype.nextBytes = rng_get_bytes; diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rsa.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rsa.js deleted file mode 100644 index 9f8664037c4e499d250a7b93b8a726766836ad9f..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rsa.js +++ /dev/null @@ -1,112 +0,0 @@ -// Depends on jsbn.js and rng.js - -// Version 1.1: support utf-8 encoding in pkcs1pad2 - -// convert a (hex) string to a bignum object -function parseBigInt(str,r) { - return new BigInteger(str,r); -} - -function linebrk(s,n) { - var ret = ""; - var i = 0; - while(i + n < s.length) { - ret += s.substring(i,i+n) + "\n"; - i += n; - } - return ret + s.substring(i,s.length); -} - -function byte2Hex(b) { - if(b < 0x10) - return "0" + b.toString(16); - else - return b.toString(16); -} - -// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint -function pkcs1pad2(s,n) { - if(n < s.length + 11) { // TODO: fix for utf-8 - alert("Message too long for RSA"); - return null; - } - var ba = new Array(); - var i = s.length - 1; - while(i >= 0 && n > 0) { - var c = s.charCodeAt(i--); - if(c < 128) { // encode using utf-8 - ba[--n] = c; - } - else if((c > 127) && (c < 2048)) { - ba[--n] = (c & 63) | 128; - ba[--n] = (c >> 6) | 192; - } - else { - ba[--n] = (c & 63) | 128; - ba[--n] = ((c >> 6) & 63) | 128; - ba[--n] = (c >> 12) | 224; - } - } - ba[--n] = 0; - var rng = new SecureRandom(); - var x = new Array(); - while(n > 2) { // random non-zero pad - x[0] = 0; - while(x[0] == 0) rng.nextBytes(x); - ba[--n] = x[0]; - } - ba[--n] = 2; - ba[--n] = 0; - return new BigInteger(ba); -} - -// "empty" RSA key constructor -function RSAKey() { - this.n = null; - this.e = 0; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.coeff = null; -} - -// Set the public key fields N and e from hex strings -function RSASetPublic(N,E) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - } - else - alert("Invalid RSA public key"); -} - -// Perform raw public operation on "x": return x^e (mod n) -function RSADoPublic(x) { - return x.modPowInt(this.e, this.n); -} - -// Return the PKCS#1 RSA encryption of "text" as an even-length hex string -function RSAEncrypt(text) { - var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); - if(m == null) return null; - var c = this.doPublic(m); - if(c == null) return null; - var h = c.toString(16); - if((h.length & 1) == 0) return h; else return "0" + h; -} - -// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string -//function RSAEncryptB64(text) { -// var h = this.encrypt(text); -// if(h) return hex2b64(h); else return null; -//} - -// protected -RSAKey.prototype.doPublic = RSADoPublic; - -// public -RSAKey.prototype.setPublic = RSASetPublic; -RSAKey.prototype.encrypt = RSAEncrypt; -//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rsa2.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rsa2.js deleted file mode 100644 index 1dfdb701f75d348630ff2e1e374f9ea2b032c35c..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/jsbn/rsa2.js +++ /dev/null @@ -1,132 +0,0 @@ -// Depends on rsa.js and jsbn2.js - -// Version 1.1: support utf-8 decoding in pkcs1unpad2 - -// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext -function pkcs1unpad2(d,n) { - var b = d.toByteArray(); - var i = 0; - while(i < b.length && b[i] == 0) ++i; - if(b.length-i != n-1 || b[i] != 2) - return null; - ++i; - while(b[i] != 0) - if(++i >= b.length) return null; - var ret = ""; - while(++i < b.length) { - var c = b[i] & 255; - if(c < 128) { // utf-8 decode - ret += String.fromCharCode(c); - } - else if((c > 191) && (c < 224)) { - ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63)); - ++i; - } - else { - ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63)); - i += 2; - } - } - return ret; -} - -// Set the private key fields N, e, and d from hex strings -function RSASetPrivate(N,E,D) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - } - else - alert("Invalid RSA private key"); -} - -// Set the private key fields N, e, d and CRT params from hex strings -function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - this.p = parseBigInt(P,16); - this.q = parseBigInt(Q,16); - this.dmp1 = parseBigInt(DP,16); - this.dmq1 = parseBigInt(DQ,16); - this.coeff = parseBigInt(C,16); - } - else - alert("Invalid RSA private key"); -} - -// Generate a new random private key B bits long, using public expt E -function RSAGenerate(B,E) { - var rng = new SecureRandom(); - var qs = B>>1; - this.e = parseInt(E,16); - var ee = new BigInteger(E,16); - for(;;) { - for(;;) { - this.p = new BigInteger(B-qs,1,rng); - if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break; - } - for(;;) { - this.q = new BigInteger(qs,1,rng); - if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break; - } - if(this.p.compareTo(this.q) <= 0) { - var t = this.p; - this.p = this.q; - this.q = t; - } - var p1 = this.p.subtract(BigInteger.ONE); - var q1 = this.q.subtract(BigInteger.ONE); - var phi = p1.multiply(q1); - if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { - this.n = this.p.multiply(this.q); - this.d = ee.modInverse(phi); - this.dmp1 = this.d.mod(p1); - this.dmq1 = this.d.mod(q1); - this.coeff = this.q.modInverse(this.p); - break; - } - } -} - -// Perform raw private operation on "x": return x^d (mod n) -function RSADoPrivate(x) { - if(this.p == null || this.q == null) - return x.modPow(this.d, this.n); - - // TODO: re-calculate any missing CRT params - var xp = x.mod(this.p).modPow(this.dmp1, this.p); - var xq = x.mod(this.q).modPow(this.dmq1, this.q); - - while(xp.compareTo(xq) < 0) - xp = xp.add(this.p); - return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is an even-length hex string and the output is a plain string. -function RSADecrypt(ctext) { - var c = parseBigInt(ctext, 16); - var m = this.doPrivate(c); - if(m == null) return null; - return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is a Base64-encoded string and the output is a plain string. -//function RSAB64Decrypt(ctext) { -// var h = b64tohex(ctext); -// if(h) return this.decrypt(h); else return null; -//} - -// protected -RSAKey.prototype.doPrivate = RSADoPrivate; - -// public -RSAKey.prototype.setPrivate = RSASetPrivate; -RSAKey.prototype.setPrivateEx = RSASetPrivateEx; -RSAKey.prototype.generate = RSAGenerate; -RSAKey.prototype.decrypt = RSADecrypt; -//RSAKey.prototype.b64_decrypt = RSAB64Decrypt; diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/rsaauth.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/rsaauth.js deleted file mode 100644 index caeb3091e7d2bcc8249cf0eb3b67b603f09bf81d..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/rsaauth.js +++ /dev/null @@ -1,23 +0,0 @@ -function tx_rsaauth_encryptUserSetup() { - - var rsa = new RSAKey(); - rsa.setPublic(document.usersetup.n.value, document.usersetup.e.value); - - var password = document.getElementById('field_password').value; - var password2 = document.getElementById('field_password2').value; - var passwordCurrent = document.getElementById('field_passwordCurrent').value; - - if (password || password2 || passwordCurrent) { - var res; - if (res = rsa.encrypt(password)) { - document.getElementById('field_password').value = 'rsa:' + hex2b64(res); - } - if (res = rsa.encrypt(password2)) { - document.getElementById('field_password2').value = 'rsa:' + hex2b64(res); - } - if (res = rsa.encrypt(passwordCurrent)) { - document.getElementById('field_passwordCurrent').value = 'rsa:' + hex2b64(res); - } - } - return false; -} diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/rsaauth_min.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/rsaauth_min.js deleted file mode 100644 index fe707d9472349c2b71a4aa252eac7cf4cf0fa3ac..0000000000000000000000000000000000000000 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/rsaauth_min.js +++ /dev/null @@ -1 +0,0 @@ -function tx_rsaauth_encryptUserSetup(){var e=new RSAKey;e.setPublic(document.usersetup.n.value,document.usersetup.e.value);var t=document.getElementById("field_password").value;var n=document.getElementById("field_password2").value;var r=document.getElementById("field_passwordCurrent").value;if(t||n||r){var i;if(i=e.encrypt(t)){document.getElementById("field_password").value="rsa:"+hex2b64(i)}if(i=e.encrypt(n)){document.getElementById("field_password2").value="rsa:"+hex2b64(i)}if(i=e.encrypt(r)){document.getElementById("field_passwordCurrent").value="rsa:"+hex2b64(i)}}return false} diff --git a/typo3/sysext/rsaauth/ext_localconf.php b/typo3/sysext/rsaauth/ext_localconf.php index d3ba763c0d740c793dd78c21b8719f1a4bf39531..ea37b58d475965bd1e0594b649de25d44733b150 100644 --- a/typo3/sysext/rsaauth/ext_localconf.php +++ b/typo3/sysext/rsaauth/ext_localconf.php @@ -31,11 +31,15 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['displ FALSE ); +\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerAjaxHandler( + 'RsaEncryption::getRsaPublicKey', + \TYPO3\CMS\Rsaauth\RsaEncryptionEncoder::class . '->getRsaPublicKeyAjaxHandler', + FALSE +); + // eID for FrontendLoginRsaPublicKey $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['FrontendLoginRsaPublicKey'] = 'EXT:rsaauth/Resources/PHP/FrontendLoginRsaPublicKey.php'; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/backend.php']['constructPostProcess'][] = \TYPO3\CMS\Rsaauth\Hook\BackendHookForAjaxLogin::class . '->addRsaJsLibraries'; - \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class)->connect( \TYPO3\CMS\Backend\LoginProvider\UsernamePasswordLoginProvider::class, \TYPO3\CMS\Backend\LoginProvider\UsernamePasswordLoginProvider::SIGNAL_getPageRenderer, diff --git a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php index f22f537dee5f4484adb57f362f12312c96f0a7ab..73a1abd70c287639b04dc894b97a718bf05bda75 100644 --- a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php +++ b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php @@ -538,6 +538,7 @@ class SetupModuleController { if ($type === 'password') { $value = ''; $noAutocomplete = 'autocomplete="off" '; + $more .= ' data-rsa-encryption=""'; } $html = '<input id="field_' . $fieldName . '" type="' . $type . '"